From 4924a2143470af4f7802230a3875e2cf3ddb9a53 Mon Sep 17 00:00:00 2001 From: Wilson Date: Fri, 9 Mar 2018 23:12:15 -0800 Subject: [PATCH 0001/2143] 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 0002/2143] 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 b473c72854f1e26ac5794cdceb3fcc717bcc8735 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 17 Aug 2018 14:27:02 -0700 Subject: [PATCH 0003/2143] initial commit --- .../chttp2/transport/chttp2_transport.cc | 2 +- .../transport/chttp2/transport/context_list.h | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/core/ext/transport/chttp2/transport/context_list.h diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 027a57d606d..ff955b5e1e1 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015 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/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h new file mode 100644 index 00000000000..a98d9ad639e --- /dev/null +++ b/src/core/ext/transport/chttp2/transport/context_list.h @@ -0,0 +1,66 @@ +/* + * + * 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_TRANSPORT_CONTEXT_LIST_H +#define GRPC_CORE_EXT_TRANSPORT_CONTEXT_LIST_H + +#include + +/** A list of RPC Contexts */ +class ContextList { + struct ContextListElement { + void *context; + ContextListElement *next; + }; + + public: + ContextList() : head_(nullptr); + + /* Creates a new element with \a context as the value and appends it to the + * list. */ + void Append(void *context) { + ContextListElement *elem = static_cast(gpr_malloc(sizeof(ContextlistELement))); + elem->context = context; + elem->next = nullptr; + if(head_ == nullptr) { + head = elem; + return; + } + ContextListElement *ptr = head_; + while(ptr->next != nullptr) { + ptr = ptr->next; + } + ptr->next = elem; + } + + /* Executes a function \a fn with each context in the list and \a arg. It also + * frees up the entire list after this operation. */ + void Execute(void (*fn)(void *context, void *arg)) { + ContextListElement *ptr; + while(head_ != nullptr){ + fn(head->context, arg); + ptr = head_; + head_ = head_->next; + gpr_free(ptr); + } + } + private: + ContextListElement *head_; +}; + +#endif /* GRPC_CORE_EXT_TRANSPORT_CONTEXT_LIST_H */ From 1e21f68149053f514eb1255b802df901b3d03f4e Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 24 Aug 2018 09:42:38 -0700 Subject: [PATCH 0004/2143] more stuff --- .../chttp2/transport/chttp2_transport.cc | 8 +++- .../chttp2/transport/context_list.cc | 42 ++++++++++++++++++ .../transport/chttp2/transport/context_list.h | 44 +++++++++---------- .../ext/transport/chttp2/transport/internal.h | 2 + .../ext/transport/chttp2/transport/writing.cc | 1 + 5 files changed, 71 insertions(+), 26 deletions(-) create mode 100644 src/core/ext/transport/chttp2/transport/context_list.cc diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index ff955b5e1e1..e24e19d9035 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -236,6 +236,7 @@ static void init_transport(grpc_chttp2_transport* t, size_t i; int j; + grpc_tcp_set_write_timestamps_callback(ContextList::Execute); GPR_ASSERT(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) == GRPC_CHTTP2_CLIENT_CONNECT_STRLEN); @@ -1026,11 +1027,13 @@ static void write_action_begin_locked(void* gt, grpc_error* error_ignored) { static void write_action(void* gt, grpc_error* error) { GPR_TIMER_SCOPE("write_action", 0); grpc_chttp2_transport* t = static_cast(gt); + void *cl = t->cl; + t->cl = nullptr; grpc_endpoint_write( t->ep, &t->outbuf, GRPC_CLOSURE_INIT(&t->write_action_end_locked, write_action_end_locked, t, - grpc_combiner_scheduler(t->combiner)), - nullptr); + grpc_combiner_scheduler(t->combiner)), cl + ); } /* Callback from the grpc_endpoint after bytes have been written by calling @@ -1354,6 +1357,7 @@ static void perform_stream_op_locked(void* stream_op, GRPC_STATS_INC_HTTP2_OP_BATCHES(); + s->context = op->context; if (grpc_http_trace.enabled()) { char* str = grpc_transport_stream_op_batch_string(op); gpr_log(GPR_INFO, "perform_stream_op_locked: %s; on_complete = %p", str, diff --git a/src/core/ext/transport/chttp2/transport/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc new file mode 100644 index 00000000000..69ecca09ab9 --- /dev/null +++ b/src/core/ext/transport/chttp2/transport/context_list.cc @@ -0,0 +1,42 @@ +/* + * + * 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/transport/chttp2/transport/context_list.h" + +namespace { +void (*cb)(void *, grpc_core::Timestamps*); +} + +void ContextList::Execute(ContextList *head, grpc_core::Timestamps *ts, grpc_error* error) { + ContextList *ptr; + while(head != nullptr) { + if(error == GRPC_ERROR_NONE) { + cb(head->context, ts); + } + ptr = head; + head_ = head->next; + gpr_free(ptr); + } +} + + +grpc_http2_set_write_timestamps_callback(void (*fn)(void *, grpc_core::Timestamps *)) { + cb = fn; +} diff --git a/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h index a98d9ad639e..a9af701b651 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.h +++ b/src/core/ext/transport/chttp2/transport/context_list.h @@ -22,26 +22,26 @@ #include /** A list of RPC Contexts */ -class ContextList { - struct ContextListElement { - void *context; - ContextListElement *next; - }; - +class ContextList {\ public: - ContextList() : head_(nullptr); - - /* Creates a new element with \a context as the value and appends it to the + /* Creates a new element with \a context as the value and appends it to the * list. */ - void Append(void *context) { - ContextListElement *elem = static_cast(gpr_malloc(sizeof(ContextlistELement))); + void Append(ContextList **head, void *context) { + /* Make sure context is not already present */ + ContextList *ptr = *head; + while(ptr != nullptr) { + if(ptr->context == context) { + GPR_ASSERT(false); + } + } + ContextList *elem = static_cast(gpr_malloc(sizeof(ContextList))); elem->context = context; elem->next = nullptr; - if(head_ == nullptr) { - head = elem; + if(*head_ == nullptr) { + *head = elem; return; } - ContextListElement *ptr = head_; + ptr = *head; while(ptr->next != nullptr) { ptr = ptr->next; } @@ -50,17 +50,13 @@ class ContextList { /* Executes a function \a fn with each context in the list and \a arg. It also * frees up the entire list after this operation. */ - void Execute(void (*fn)(void *context, void *arg)) { - ContextListElement *ptr; - while(head_ != nullptr){ - fn(head->context, arg); - ptr = head_; - head_ = head_->next; - gpr_free(ptr); - } - } + void Execute(ContextList *head, grpc_core::Timestamps *ts, grpc_error* error); + private: - ContextListElement *head_; + void *context; + ContextListElement *next; }; +grpc_http2_set_write_timestamps_callback(void (*fn)(void *, grpc_core::Timestamps*)); + #endif /* GRPC_CORE_EXT_TRANSPORT_CONTEXT_LIST_H */ diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index ca6e7159787..78595a6a4a3 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -469,6 +469,7 @@ struct grpc_chttp2_transport { bool keepalive_permit_without_calls; /** keep-alive state machine state */ grpc_chttp2_keepalive_state keepalive_state; + ContextList *cl; }; typedef enum { @@ -479,6 +480,7 @@ typedef enum { } grpc_published_metadata_method; struct grpc_chttp2_stream { + void *context; grpc_chttp2_transport* t; grpc_stream_refcount* refcount; diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index 8b73b01dea2..51d62f4f601 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -487,6 +487,7 @@ class StreamWriteContext { return; // early out: nothing to do } + ContextList::Append(&t_->cl, s_->context); while ((s_->flow_controlled_buffer.length > 0 || s_->compressed_data_buffer.length > 0) && data_send_context.max_outgoing() > 0) { From f71fd84e42cd8053de35df7d6137f7c2e2407ce3 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 24 Aug 2018 17:05:30 -0700 Subject: [PATCH 0005/2143] more stuff --- BUILD | 2 ++ CMakeLists.txt | 6 ++++++ Makefile | 6 ++++++ build.yaml | 2 ++ config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 3 +++ grpc.gemspec | 2 ++ grpc.gyp | 4 ++++ package.xml | 2 ++ src/core/ext/transport/chttp2/transport/context_list.h | 2 ++ src/python/grpcio/grpc_core_dependencies.py | 1 + tools/doxygen/Doxyfile.core.internal | 2 ++ tools/run_tests/generated/sources_and_headers.json | 3 +++ 15 files changed, 38 insertions(+) diff --git a/BUILD b/BUILD index c01b971281d..b38e598ea4c 100644 --- a/BUILD +++ b/BUILD @@ -1564,6 +1564,7 @@ grpc_cc_library( "src/core/ext/transport/chttp2/transport/bin_encoder.cc", "src/core/ext/transport/chttp2/transport/chttp2_plugin.cc", "src/core/ext/transport/chttp2/transport/chttp2_transport.cc", + "src/core/ext/transport/chttp2/transport/context_list.cc", "src/core/ext/transport/chttp2/transport/flow_control.cc", "src/core/ext/transport/chttp2/transport/frame_data.cc", "src/core/ext/transport/chttp2/transport/frame_goaway.cc", @@ -1587,6 +1588,7 @@ grpc_cc_library( "src/core/ext/transport/chttp2/transport/bin_decoder.h", "src/core/ext/transport/chttp2/transport/bin_encoder.h", "src/core/ext/transport/chttp2/transport/chttp2_transport.h", + "src/core/ext/transport/chttp2/transport/context_list.h", "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.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 3895d4c0f17..da55713062a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1095,6 +1095,7 @@ add_library(grpc src/core/ext/transport/chttp2/transport/bin_encoder.cc src/core/ext/transport/chttp2/transport/chttp2_plugin.cc src/core/ext/transport/chttp2/transport/chttp2_transport.cc + src/core/ext/transport/chttp2/transport/context_list.cc src/core/ext/transport/chttp2/transport/flow_control.cc src/core/ext/transport/chttp2/transport/frame_data.cc src/core/ext/transport/chttp2/transport/frame_goaway.cc @@ -1506,6 +1507,7 @@ add_library(grpc_cronet src/core/ext/transport/chttp2/transport/bin_encoder.cc src/core/ext/transport/chttp2/transport/chttp2_plugin.cc src/core/ext/transport/chttp2/transport/chttp2_transport.cc + src/core/ext/transport/chttp2/transport/context_list.cc src/core/ext/transport/chttp2/transport/flow_control.cc src/core/ext/transport/chttp2/transport/frame_data.cc src/core/ext/transport/chttp2/transport/frame_goaway.cc @@ -1919,6 +1921,7 @@ add_library(grpc_test_util src/core/ext/transport/chttp2/transport/bin_encoder.cc src/core/ext/transport/chttp2/transport/chttp2_plugin.cc src/core/ext/transport/chttp2/transport/chttp2_transport.cc + src/core/ext/transport/chttp2/transport/context_list.cc src/core/ext/transport/chttp2/transport/flow_control.cc src/core/ext/transport/chttp2/transport/frame_data.cc src/core/ext/transport/chttp2/transport/frame_goaway.cc @@ -2229,6 +2232,7 @@ add_library(grpc_test_util_unsecure src/core/ext/transport/chttp2/transport/bin_encoder.cc src/core/ext/transport/chttp2/transport/chttp2_plugin.cc src/core/ext/transport/chttp2/transport/chttp2_transport.cc + src/core/ext/transport/chttp2/transport/context_list.cc src/core/ext/transport/chttp2/transport/flow_control.cc src/core/ext/transport/chttp2/transport/frame_data.cc src/core/ext/transport/chttp2/transport/frame_goaway.cc @@ -2497,6 +2501,7 @@ add_library(grpc_unsecure src/core/ext/transport/chttp2/transport/bin_encoder.cc src/core/ext/transport/chttp2/transport/chttp2_plugin.cc src/core/ext/transport/chttp2/transport/chttp2_transport.cc + src/core/ext/transport/chttp2/transport/context_list.cc src/core/ext/transport/chttp2/transport/flow_control.cc src/core/ext/transport/chttp2/transport/frame_data.cc src/core/ext/transport/chttp2/transport/frame_goaway.cc @@ -3163,6 +3168,7 @@ add_library(grpc++_cronet src/core/ext/transport/chttp2/transport/bin_encoder.cc src/core/ext/transport/chttp2/transport/chttp2_plugin.cc src/core/ext/transport/chttp2/transport/chttp2_transport.cc + src/core/ext/transport/chttp2/transport/context_list.cc src/core/ext/transport/chttp2/transport/flow_control.cc src/core/ext/transport/chttp2/transport/frame_data.cc src/core/ext/transport/chttp2/transport/frame_goaway.cc diff --git a/Makefile b/Makefile index 7caf585ee9e..4976d7eb6f5 100644 --- a/Makefile +++ b/Makefile @@ -3597,6 +3597,7 @@ LIBGRPC_SRC = \ src/core/ext/transport/chttp2/transport/bin_encoder.cc \ src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \ src/core/ext/transport/chttp2/transport/chttp2_transport.cc \ + src/core/ext/transport/chttp2/transport/context_list.cc \ src/core/ext/transport/chttp2/transport/flow_control.cc \ src/core/ext/transport/chttp2/transport/frame_data.cc \ src/core/ext/transport/chttp2/transport/frame_goaway.cc \ @@ -4007,6 +4008,7 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/transport/chttp2/transport/bin_encoder.cc \ src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \ src/core/ext/transport/chttp2/transport/chttp2_transport.cc \ + src/core/ext/transport/chttp2/transport/context_list.cc \ src/core/ext/transport/chttp2/transport/flow_control.cc \ src/core/ext/transport/chttp2/transport/frame_data.cc \ src/core/ext/transport/chttp2/transport/frame_goaway.cc \ @@ -4418,6 +4420,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/transport/chttp2/transport/bin_encoder.cc \ src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \ src/core/ext/transport/chttp2/transport/chttp2_transport.cc \ + src/core/ext/transport/chttp2/transport/context_list.cc \ src/core/ext/transport/chttp2/transport/flow_control.cc \ src/core/ext/transport/chttp2/transport/frame_data.cc \ src/core/ext/transport/chttp2/transport/frame_goaway.cc \ @@ -4719,6 +4722,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/transport/chttp2/transport/bin_encoder.cc \ src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \ src/core/ext/transport/chttp2/transport/chttp2_transport.cc \ + src/core/ext/transport/chttp2/transport/context_list.cc \ src/core/ext/transport/chttp2/transport/flow_control.cc \ src/core/ext/transport/chttp2/transport/frame_data.cc \ src/core/ext/transport/chttp2/transport/frame_goaway.cc \ @@ -4965,6 +4969,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/transport/chttp2/transport/bin_encoder.cc \ src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \ src/core/ext/transport/chttp2/transport/chttp2_transport.cc \ + src/core/ext/transport/chttp2/transport/context_list.cc \ src/core/ext/transport/chttp2/transport/flow_control.cc \ src/core/ext/transport/chttp2/transport/frame_data.cc \ src/core/ext/transport/chttp2/transport/frame_goaway.cc \ @@ -5619,6 +5624,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/transport/chttp2/transport/bin_encoder.cc \ src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \ src/core/ext/transport/chttp2/transport/chttp2_transport.cc \ + src/core/ext/transport/chttp2/transport/context_list.cc \ src/core/ext/transport/chttp2/transport/flow_control.cc \ src/core/ext/transport/chttp2/transport/frame_data.cc \ src/core/ext/transport/chttp2/transport/frame_goaway.cc \ diff --git a/build.yaml b/build.yaml index a7ebee7572e..5dcbce1df89 100644 --- a/build.yaml +++ b/build.yaml @@ -927,6 +927,7 @@ filegroups: - src/core/ext/transport/chttp2/transport/bin_decoder.h - src/core/ext/transport/chttp2/transport/bin_encoder.h - src/core/ext/transport/chttp2/transport/chttp2_transport.h + - src/core/ext/transport/chttp2/transport/context_list.h - 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.h @@ -949,6 +950,7 @@ filegroups: - src/core/ext/transport/chttp2/transport/bin_encoder.cc - src/core/ext/transport/chttp2/transport/chttp2_plugin.cc - src/core/ext/transport/chttp2/transport/chttp2_transport.cc + - src/core/ext/transport/chttp2/transport/context_list.cc - src/core/ext/transport/chttp2/transport/flow_control.cc - src/core/ext/transport/chttp2/transport/frame_data.cc - src/core/ext/transport/chttp2/transport/frame_goaway.cc diff --git a/config.m4 b/config.m4 index af3624cdd1b..4f1405e2351 100644 --- a/config.m4 +++ b/config.m4 @@ -241,6 +241,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/transport/chttp2/transport/bin_encoder.cc \ src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \ src/core/ext/transport/chttp2/transport/chttp2_transport.cc \ + src/core/ext/transport/chttp2/transport/context_list.cc \ src/core/ext/transport/chttp2/transport/flow_control.cc \ src/core/ext/transport/chttp2/transport/frame_data.cc \ src/core/ext/transport/chttp2/transport/frame_goaway.cc \ diff --git a/config.w32 b/config.w32 index ad91ee40bd7..9bd2e238f83 100644 --- a/config.w32 +++ b/config.w32 @@ -216,6 +216,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\transport\\chttp2\\transport\\bin_encoder.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\chttp2_plugin.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\chttp2_transport.cc " + + "src\\core\\ext\\transport\\chttp2\\transport\\context_list.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\flow_control.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\frame_data.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\frame_goaway.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index a387794f579..758717a0d20 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -242,6 +242,7 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/bin_decoder.h', 'src/core/ext/transport/chttp2/transport/bin_encoder.h', 'src/core/ext/transport/chttp2/transport/chttp2_transport.h', + 'src/core/ext/transport/chttp2/transport/context_list.h', '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.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 9832283e5c9..1bd0dc1b529 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -254,6 +254,7 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/bin_decoder.h', 'src/core/ext/transport/chttp2/transport/bin_encoder.h', 'src/core/ext/transport/chttp2/transport/chttp2_transport.h', + 'src/core/ext/transport/chttp2/transport/context_list.h', '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.h', @@ -673,6 +674,7 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', 'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc', 'src/core/ext/transport/chttp2/transport/chttp2_transport.cc', + 'src/core/ext/transport/chttp2/transport/context_list.cc', 'src/core/ext/transport/chttp2/transport/flow_control.cc', 'src/core/ext/transport/chttp2/transport/frame_data.cc', 'src/core/ext/transport/chttp2/transport/frame_goaway.cc', @@ -857,6 +859,7 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/bin_decoder.h', 'src/core/ext/transport/chttp2/transport/bin_encoder.h', 'src/core/ext/transport/chttp2/transport/chttp2_transport.h', + 'src/core/ext/transport/chttp2/transport/context_list.h', '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.h', diff --git a/grpc.gemspec b/grpc.gemspec index c8e58faec9e..9a8d80823ac 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -186,6 +186,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/bin_decoder.h ) s.files += %w( src/core/ext/transport/chttp2/transport/bin_encoder.h ) s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_transport.h ) + s.files += %w( src/core/ext/transport/chttp2/transport/context_list.h ) s.files += %w( src/core/ext/transport/chttp2/transport/flow_control.h ) s.files += %w( src/core/ext/transport/chttp2/transport/frame.h ) s.files += %w( src/core/ext/transport/chttp2/transport/frame_data.h ) @@ -609,6 +610,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/bin_encoder.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_plugin.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_transport.cc ) + s.files += %w( src/core/ext/transport/chttp2/transport/context_list.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/flow_control.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/frame_data.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/frame_goaway.cc ) diff --git a/grpc.gyp b/grpc.gyp index 654a5310923..8229b9689b5 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -433,6 +433,7 @@ 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', 'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc', 'src/core/ext/transport/chttp2/transport/chttp2_transport.cc', + 'src/core/ext/transport/chttp2/transport/context_list.cc', 'src/core/ext/transport/chttp2/transport/flow_control.cc', 'src/core/ext/transport/chttp2/transport/frame_data.cc', 'src/core/ext/transport/chttp2/transport/frame_goaway.cc', @@ -817,6 +818,7 @@ 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', 'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc', 'src/core/ext/transport/chttp2/transport/chttp2_transport.cc', + 'src/core/ext/transport/chttp2/transport/context_list.cc', 'src/core/ext/transport/chttp2/transport/flow_control.cc', 'src/core/ext/transport/chttp2/transport/frame_data.cc', 'src/core/ext/transport/chttp2/transport/frame_goaway.cc', @@ -1052,6 +1054,7 @@ 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', 'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc', 'src/core/ext/transport/chttp2/transport/chttp2_transport.cc', + 'src/core/ext/transport/chttp2/transport/context_list.cc', 'src/core/ext/transport/chttp2/transport/flow_control.cc', 'src/core/ext/transport/chttp2/transport/frame_data.cc', 'src/core/ext/transport/chttp2/transport/frame_goaway.cc', @@ -1244,6 +1247,7 @@ 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', 'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc', 'src/core/ext/transport/chttp2/transport/chttp2_transport.cc', + 'src/core/ext/transport/chttp2/transport/context_list.cc', 'src/core/ext/transport/chttp2/transport/flow_control.cc', 'src/core/ext/transport/chttp2/transport/frame_data.cc', 'src/core/ext/transport/chttp2/transport/frame_goaway.cc', diff --git a/package.xml b/package.xml index 537c5404e7e..901c22c1ead 100644 --- a/package.xml +++ b/package.xml @@ -191,6 +191,7 @@ + @@ -614,6 +615,7 @@ + diff --git a/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h index a9af701b651..5411cf6bd85 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.h +++ b/src/core/ext/transport/chttp2/transport/context_list.h @@ -21,6 +21,7 @@ #include +namespace grpc_core { /** A list of RPC Contexts */ class ContextList {\ public: @@ -58,5 +59,6 @@ class ContextList {\ }; grpc_http2_set_write_timestamps_callback(void (*fn)(void *, grpc_core::Timestamps*)); +} /* namespace grpc_core */ #endif /* GRPC_CORE_EXT_TRANSPORT_CONTEXT_LIST_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 0f68e823d79..38f6b4d24c1 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -215,6 +215,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', 'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc', 'src/core/ext/transport/chttp2/transport/chttp2_transport.cc', + 'src/core/ext/transport/chttp2/transport/context_list.cc', 'src/core/ext/transport/chttp2/transport/flow_control.cc', 'src/core/ext/transport/chttp2/transport/frame_data.cc', 'src/core/ext/transport/chttp2/transport/frame_goaway.cc', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 7cd1dc7bf37..bfdb356c763 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -996,6 +996,8 @@ 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 \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8ea5126fdef..7a679aa3b92 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10652,6 +10652,7 @@ "src/core/ext/transport/chttp2/transport/bin_decoder.h", "src/core/ext/transport/chttp2/transport/bin_encoder.h", "src/core/ext/transport/chttp2/transport/chttp2_transport.h", + "src/core/ext/transport/chttp2/transport/context_list.h", "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.h", @@ -10681,6 +10682,8 @@ "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", From 9c5bde5e4e2cc0c81c3c6411b3aa922d3e995a54 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Sun, 26 Aug 2018 03:50:39 -0700 Subject: [PATCH 0006/2143] More commits --- CMakeLists.txt | 28 ++++++++ Makefile | 36 ++++++++++ build.yaml | 9 +++ .../chttp2/transport/chttp2_transport.cc | 17 +++-- .../chttp2/transport/context_list.cc | 28 +++++--- .../transport/chttp2/transport/context_list.h | 39 +++++++---- .../ext/transport/chttp2/transport/internal.h | 8 ++- .../ext/transport/chttp2/transport/writing.cc | 6 +- src/core/lib/iomgr/buffer_list.cc | 15 ++-- src/core/lib/iomgr/buffer_list.h | 2 +- src/core/lib/iomgr/endpoint.cc | 7 ++ src/core/lib/iomgr/endpoint.h | 3 + src/core/lib/iomgr/endpoint_pair_posix.cc | 4 +- src/core/lib/iomgr/tcp_custom.cc | 5 +- src/core/lib/iomgr/tcp_posix.cc | 68 +++++++++++++++++-- .../lib/security/transport/secure_endpoint.cc | 8 ++- test/core/iomgr/buffer_list_test.cc | 4 +- test/core/transport/chttp2/BUILD | 13 ++++ .../transport/chttp2/context_list_test.cc | 64 +++++++++++++++++ test/core/util/mock_endpoint.cc | 1 + test/core/util/passthru_endpoint.cc | 1 + test/core/util/trickle_endpoint.cc | 3 +- .../generated/sources_and_headers.json | 15 ++++ tools/run_tests/generated/tests.json | 24 +++++++ 24 files changed, 361 insertions(+), 47 deletions(-) create mode 100644 test/core/transport/chttp2/context_list_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index da55713062a..af2341c2992 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,6 +242,7 @@ add_dependencies(buildtests_c combiner_test) add_dependencies(buildtests_c compression_test) add_dependencies(buildtests_c concurrent_connectivity_test) add_dependencies(buildtests_c connection_refused_test) +add_dependencies(buildtests_c context_list_test) add_dependencies(buildtests_c dns_resolver_connectivity_test) add_dependencies(buildtests_c dns_resolver_cooldown_test) add_dependencies(buildtests_c dns_resolver_test) @@ -6175,6 +6176,33 @@ target_link_libraries(connection_refused_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(context_list_test + test/core/transport/chttp2/context_list_test.cc +) + + +target_include_directories(context_list_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(context_list_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc +) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(dns_resolver_connectivity_test test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc ) diff --git a/Makefile b/Makefile index 4976d7eb6f5..a4755683f0c 100644 --- a/Makefile +++ b/Makefile @@ -990,6 +990,7 @@ combiner_test: $(BINDIR)/$(CONFIG)/combiner_test compression_test: $(BINDIR)/$(CONFIG)/compression_test concurrent_connectivity_test: $(BINDIR)/$(CONFIG)/concurrent_connectivity_test connection_refused_test: $(BINDIR)/$(CONFIG)/connection_refused_test +context_list_test: $(BINDIR)/$(CONFIG)/context_list_test dns_resolver_connectivity_test: $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test dns_resolver_cooldown_test: $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test dns_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_test @@ -1445,6 +1446,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/compression_test \ $(BINDIR)/$(CONFIG)/concurrent_connectivity_test \ $(BINDIR)/$(CONFIG)/connection_refused_test \ + $(BINDIR)/$(CONFIG)/context_list_test \ $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test \ $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test \ $(BINDIR)/$(CONFIG)/dns_resolver_test \ @@ -1972,6 +1974,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/concurrent_connectivity_test || ( echo test concurrent_connectivity_test failed ; exit 1 ) $(E) "[RUN] Testing connection_refused_test" $(Q) $(BINDIR)/$(CONFIG)/connection_refused_test || ( echo test connection_refused_test failed ; exit 1 ) + $(E) "[RUN] Testing context_list_test" + $(Q) $(BINDIR)/$(CONFIG)/context_list_test || ( echo test context_list_test failed ; exit 1 ) $(E) "[RUN] Testing dns_resolver_connectivity_test" $(Q) $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test || ( echo test dns_resolver_connectivity_test failed ; exit 1 ) $(E) "[RUN] Testing dns_resolver_cooldown_test" @@ -11107,6 +11111,38 @@ endif endif +CONTEXT_LIST_TEST_SRC = \ + test/core/transport/chttp2/context_list_test.cc \ + +CONTEXT_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CONTEXT_LIST_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/context_list_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/context_list_test: $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/context_list_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a + +deps_context_list_test: $(CONTEXT_LIST_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(CONTEXT_LIST_TEST_OBJS:.o=.dep) +endif +endif + + DNS_RESOLVER_CONNECTIVITY_TEST_SRC = \ test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc \ diff --git a/build.yaml b/build.yaml index 5dcbce1df89..47a75d23c17 100644 --- a/build.yaml +++ b/build.yaml @@ -2280,6 +2280,15 @@ targets: - grpc - gpr_test_util - gpr +- name: context_list_test + build: test + language: c + src: + - test/core/transport/chttp2/context_list_test.cc + deps: + - grpc_test_util + - grpc + uses_polling: false - name: dns_resolver_connectivity_test cpu_cost: 0.1 build: test diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index e24e19d9035..f0dccefeeee 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -31,6 +31,7 @@ #include #include +#include "src/core/ext/transport/chttp2/transport/context_list.h" #include "src/core/ext/transport/chttp2/transport/frame_data.h" #include "src/core/ext/transport/chttp2/transport/internal.h" #include "src/core/ext/transport/chttp2/transport/varint.h" @@ -155,6 +156,7 @@ bool g_flow_control_enabled = true; */ static void destruct_transport(grpc_chttp2_transport* t) { + gpr_log(GPR_INFO, "destruct transport %p", t); size_t i; grpc_endpoint_destroy(t->ep); @@ -164,6 +166,8 @@ static void destruct_transport(grpc_chttp2_transport* t) { grpc_slice_buffer_destroy_internal(&t->outbuf); grpc_chttp2_hpack_compressor_destroy(&t->hpack_compressor); + grpc_core::ContextList::Execute(t->cl, nullptr, GRPC_ERROR_NONE); + grpc_slice_buffer_destroy_internal(&t->read_buffer); grpc_chttp2_hpack_parser_destroy(&t->hpack_parser); grpc_chttp2_goaway_parser_destroy(&t->goaway_parser); @@ -236,7 +240,7 @@ static void init_transport(grpc_chttp2_transport* t, size_t i; int j; - grpc_tcp_set_write_timestamps_callback(ContextList::Execute); + grpc_tcp_set_write_timestamps_callback(grpc_core::ContextList::Execute); GPR_ASSERT(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) == GRPC_CHTTP2_CLIENT_CONNECT_STRLEN); @@ -1027,13 +1031,16 @@ static void write_action_begin_locked(void* gt, grpc_error* error_ignored) { static void write_action(void* gt, grpc_error* error) { GPR_TIMER_SCOPE("write_action", 0); grpc_chttp2_transport* t = static_cast(gt); - void *cl = t->cl; + void* cl = t->cl; t->cl = nullptr; + if (cl) { + gpr_log(GPR_INFO, "cleared for write"); + } grpc_endpoint_write( t->ep, &t->outbuf, GRPC_CLOSURE_INIT(&t->write_action_end_locked, write_action_end_locked, t, - grpc_combiner_scheduler(t->combiner)), cl - ); + grpc_combiner_scheduler(t->combiner)), + cl); } /* Callback from the grpc_endpoint after bytes have been written by calling @@ -1357,7 +1364,7 @@ static void perform_stream_op_locked(void* stream_op, GRPC_STATS_INC_HTTP2_OP_BATCHES(); - s->context = op->context; + s->context = op->payload->context; if (grpc_http_trace.enabled()) { char* str = grpc_transport_stream_op_batch_string(op); gpr_log(GPR_INFO, "perform_stream_op_locked: %s; on_complete = %p", str, diff --git a/src/core/ext/transport/chttp2/transport/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc index 69ecca09ab9..7bfc947ebbf 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.cc +++ b/src/core/ext/transport/chttp2/transport/context_list.cc @@ -21,22 +21,32 @@ #include "src/core/ext/transport/chttp2/transport/context_list.h" namespace { -void (*cb)(void *, grpc_core::Timestamps*); +void (*cb)(void*, grpc_core::Timestamps*) = nullptr; } -void ContextList::Execute(ContextList *head, grpc_core::Timestamps *ts, grpc_error* error) { - ContextList *ptr; - while(head != nullptr) { - if(error == GRPC_ERROR_NONE) { - cb(head->context, ts); +namespace grpc_core { +void ContextList::Execute(void* arg, grpc_core::Timestamps* ts, + grpc_error* error) { + gpr_log(GPR_INFO, "execute"); + ContextList* head = static_cast(arg); + ContextList* ptr; + while (head != nullptr) { + if (error == GRPC_ERROR_NONE && ts != nullptr) { + if (cb) { + cb(head->s->context, ts); + } } + gpr_log(GPR_INFO, "one iteration %p %p", head, arg); + // GRPC_CHTTP2_STREAM_UNREF(static_cast(head->s), + // "timestamp exec"); ptr = head; - head_ = head->next; + head = head->next; gpr_free(ptr); } } - -grpc_http2_set_write_timestamps_callback(void (*fn)(void *, grpc_core::Timestamps *)) { +void grpc_http2_set_write_timestamps_callback( + void (*fn)(void*, grpc_core::Timestamps*)) { cb = fn; } +} /* namespace grpc_core */ diff --git a/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h index 5411cf6bd85..26b8da413ee 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.h +++ b/src/core/ext/transport/chttp2/transport/context_list.h @@ -21,44 +21,55 @@ #include +#include "src/core/lib/iomgr/buffer_list.h" + +#include "src/core/ext/transport/chttp2/transport/internal.h" + namespace grpc_core { /** A list of RPC Contexts */ -class ContextList {\ +class ContextList { public: /* Creates a new element with \a context as the value and appends it to the * list. */ - void Append(ContextList **head, void *context) { + static void Append(ContextList** head, grpc_chttp2_stream* s) { /* Make sure context is not already present */ - ContextList *ptr = *head; - while(ptr != nullptr) { - if(ptr->context == context) { + ContextList* ptr = *head; + // GRPC_CHTTP2_STREAM_REF(s, "timestamp"); + while (ptr != nullptr) { + if (ptr->s == s) { GPR_ASSERT(false); } + ptr = ptr->next; } - ContextList *elem = static_cast(gpr_malloc(sizeof(ContextList))); - elem->context = context; + ContextList* elem = + static_cast(gpr_malloc(sizeof(ContextList))); + elem->s = s; elem->next = nullptr; - if(*head_ == nullptr) { + if (*head == nullptr) { *head = elem; + gpr_log(GPR_INFO, "new head"); + gpr_log(GPR_INFO, "append %p %p", elem, *head); return; } + gpr_log(GPR_INFO, "append %p %p", elem, *head); ptr = *head; - while(ptr->next != nullptr) { + while (ptr->next != nullptr) { ptr = ptr->next; } ptr->next = elem; } - /* Executes a function \a fn with each context in the list and \a arg. It also + /* Executes a function \a fn with each context in the list and \a ts. It also * frees up the entire list after this operation. */ - void Execute(ContextList *head, grpc_core::Timestamps *ts, grpc_error* error); + static void Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error); private: - void *context; - ContextListElement *next; + grpc_chttp2_stream* s; + ContextList* next; }; -grpc_http2_set_write_timestamps_callback(void (*fn)(void *, grpc_core::Timestamps*)); +void grpc_http2_set_write_timestamps_callback( + void (*fn)(void*, grpc_core::Timestamps*)); } /* namespace grpc_core */ #endif /* GRPC_CORE_EXT_TRANSPORT_CONTEXT_LIST_H */ diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 78595a6a4a3..32a13df48ce 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -44,6 +44,10 @@ #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/transport_impl.h" +namespace grpc_core { +class ContextList; +} + /* streams are kept in various linked lists depending on what things need to happen to them... this enum labels each list */ typedef enum { @@ -469,7 +473,7 @@ struct grpc_chttp2_transport { bool keepalive_permit_without_calls; /** keep-alive state machine state */ grpc_chttp2_keepalive_state keepalive_state; - ContextList *cl; + grpc_core::ContextList* cl; }; typedef enum { @@ -480,7 +484,7 @@ typedef enum { } grpc_published_metadata_method; struct grpc_chttp2_stream { - void *context; + void* context; grpc_chttp2_transport* t; grpc_stream_refcount* refcount; diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index 51d62f4f601..c9273f7e390 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -18,6 +18,7 @@ #include +#include "src/core/ext/transport/chttp2/transport/context_list.h" #include "src/core/ext/transport/chttp2/transport/internal.h" #include @@ -487,7 +488,10 @@ class StreamWriteContext { return; // early out: nothing to do } - ContextList::Append(&t_->cl, s_->context); + if (/* traced && */ grpc_endpoint_can_track_err(t_->ep)) { + gpr_log(GPR_INFO, "for transport %p", t_); + grpc_core::ContextList::Append(&t_->cl, s_); + } while ((s_->flow_controlled_buffer.length > 0 || s_->compressed_data_buffer.length > 0) && data_send_context.max_outgoing() > 0) { diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index 6ada23db1c2..d7884a59657 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -31,6 +31,7 @@ namespace grpc_core { void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, void* arg) { + gpr_log(GPR_INFO, "new entry %u", seq_no); GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* new_elem = New(seq_no, arg); /* Store the current time as the sendmsg time. */ @@ -64,6 +65,7 @@ void (*timestamps_callback)(void*, grpc_core::Timestamps*, void TracedBuffer::ProcessTimestamp(TracedBuffer** head, struct sock_extended_err* serr, struct scm_timestamping* tss) { + gpr_log(GPR_INFO, "process timestamp %u", serr->ee_data); GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* elem = *head; TracedBuffer* next = nullptr; @@ -85,6 +87,7 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head, /* 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. */ + gpr_log(GPR_INFO, "calling"); timestamps_callback(elem->arg_, &(elem->ts_), GRPC_ERROR_NONE); next = elem->next_; Delete(elem); @@ -99,18 +102,22 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head, } } -void TracedBuffer::Shutdown(TracedBuffer** head, grpc_error* shutdown_err) { +void TracedBuffer::Shutdown(TracedBuffer** head, void* remaining, + grpc_error* shutdown_err) { GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* elem = *head; + gpr_log(GPR_INFO, "shutdown"); while (elem != nullptr) { - if (timestamps_callback) { - timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err); - } + timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err); + gpr_log(GPR_INFO, "iter"); auto* next = elem->next_; Delete(elem); elem = next; } *head = nullptr; + if (remaining != nullptr) { + timestamps_callback(remaining, nullptr, shutdown_err); + } GRPC_ERROR_UNREF(shutdown_err); } diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index cbbf50a6575..f7d2f6c3701 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -67,7 +67,7 @@ class TracedBuffer { /** Cleans the list by calling the callback for each traced buffer in the list * with timestamps that it has. */ - static void Shutdown(grpc_core::TracedBuffer** head, + static void Shutdown(grpc_core::TracedBuffer** head, void* remaining, grpc_error* shutdown_err); private: diff --git a/src/core/lib/iomgr/endpoint.cc b/src/core/lib/iomgr/endpoint.cc index 44fb47e19d9..5e5effb2f13 100644 --- a/src/core/lib/iomgr/endpoint.cc +++ b/src/core/lib/iomgr/endpoint.cc @@ -61,3 +61,10 @@ int grpc_endpoint_get_fd(grpc_endpoint* ep) { return ep->vtable->get_fd(ep); } grpc_resource_user* grpc_endpoint_get_resource_user(grpc_endpoint* ep) { return ep->vtable->get_resource_user(ep); } + +bool grpc_endpoint_can_track_err(grpc_endpoint* ep) { + if (ep->vtable->can_track_err != nullptr) { + return ep->vtable->can_track_err(ep); + } + return false; +} diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h index 1f590a80cae..79c8ece263a 100644 --- a/src/core/lib/iomgr/endpoint.h +++ b/src/core/lib/iomgr/endpoint.h @@ -47,6 +47,7 @@ struct grpc_endpoint_vtable { grpc_resource_user* (*get_resource_user)(grpc_endpoint* ep); char* (*get_peer)(grpc_endpoint* ep); int (*get_fd)(grpc_endpoint* ep); + bool (*can_track_err)(grpc_endpoint* ep); }; /* When data is available on the connection, calls the callback with slices. @@ -95,6 +96,8 @@ void grpc_endpoint_delete_from_pollset_set(grpc_endpoint* ep, grpc_resource_user* grpc_endpoint_get_resource_user(grpc_endpoint* endpoint); +bool grpc_endpoint_can_track_err(grpc_endpoint* ep); + struct grpc_endpoint { const grpc_endpoint_vtable* vtable; }; diff --git a/src/core/lib/iomgr/endpoint_pair_posix.cc b/src/core/lib/iomgr/endpoint_pair_posix.cc index 3afbfd72543..5c5c246f998 100644 --- a/src/core/lib/iomgr/endpoint_pair_posix.cc +++ b/src/core/lib/iomgr/endpoint_pair_posix.cc @@ -59,11 +59,11 @@ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char* name, grpc_core::ExecCtx exec_ctx; gpr_asprintf(&final_name, "%s:client", name); - p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, true), args, + p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, false), args, "socketpair-server"); gpr_free(final_name); gpr_asprintf(&final_name, "%s:server", name); - p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, true), args, + p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, false), args, "socketpair-client"); gpr_free(final_name); diff --git a/src/core/lib/iomgr/tcp_custom.cc b/src/core/lib/iomgr/tcp_custom.cc index e02a1898f25..f7a5f36cdcd 100644 --- a/src/core/lib/iomgr/tcp_custom.cc +++ b/src/core/lib/iomgr/tcp_custom.cc @@ -326,6 +326,8 @@ static grpc_resource_user* endpoint_get_resource_user(grpc_endpoint* ep) { static int endpoint_get_fd(grpc_endpoint* ep) { return -1; } +static bool endpoint_can_track_err(grpc_endpoint* ep) { return false; } + static grpc_endpoint_vtable vtable = {endpoint_read, endpoint_write, endpoint_add_to_pollset, @@ -335,7 +337,8 @@ static grpc_endpoint_vtable vtable = {endpoint_read, endpoint_destroy, endpoint_get_resource_user, endpoint_get_peer, - endpoint_get_fd}; + endpoint_get_fd, + endpoint_can_track_err}; grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket, grpc_resource_quota* resource_quota, diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 1db2790265e..23cbc20910c 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -375,8 +375,15 @@ static void tcp_ref(grpc_tcp* tcp) { gpr_ref(&tcp->refcount); } static void tcp_destroy(grpc_endpoint* ep) { grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = reinterpret_cast(ep); + gpr_log(GPR_INFO, "tcp destroy %p %p", ep, tcp->outgoing_buffer_arg); 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); } @@ -578,6 +585,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, ssize_t* sent_length, grpc_error** error) { if (!tcp->socket_ts_enabled) { + gpr_log(GPR_INFO, "set timestamps"); uint32_t opt = grpc_core::kTimestampingSocketOptions; if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING, static_cast(&opt), sizeof(opt)) != 0) { @@ -610,6 +618,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, *sent_length = length; /* Only save timestamps if all the bytes were taken by sendmsg. */ if (sending_length == static_cast(length)) { + gpr_log(GPR_INFO, "tcp new entry %p %p", tcp, tcp->outgoing_buffer_arg); gpr_mu_lock(&tcp->tb_mu); grpc_core::TracedBuffer::AddNewEntry( &tcp->tb_head, static_cast(tcp->bytes_counter + length), @@ -668,6 +677,7 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, * non-linux platforms, error processing is not used/enabled currently. */ static bool process_errors(grpc_tcp* tcp) { + gpr_log(GPR_INFO, "process errors"); while (true) { struct iovec iov; iov.iov_base = nullptr; @@ -730,6 +740,8 @@ static bool process_errors(grpc_tcp* tcp) { } static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { + gpr_log(GPR_INFO, "handle error %p", arg); + GRPC_LOG_IF_ERROR("handle error", GRPC_ERROR_REF(error)); grpc_tcp* tcp = static_cast(arg); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p got_error: %s", tcp, grpc_error_string(error)); @@ -739,7 +751,8 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { static_cast(gpr_atm_acq_load(&tcp->stop_error_notification))) { /* We aren't going to register to hear on error anymore, so it is safe to * unref. */ - grpc_core::TracedBuffer::Shutdown(&tcp->tb_head, GRPC_ERROR_REF(error)); + gpr_log(GPR_INFO, "%p %d early return", error, + static_cast(gpr_atm_acq_load(&tcp->stop_error_notification))); TCP_UNREF(tcp, "error-tracking"); return; } @@ -774,6 +787,17 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { } #endif /* GRPC_LINUX_ERRQUEUE */ +void tcp_shutdown_buffer_list(grpc_tcp* tcp) { + if (tcp->outgoing_buffer_arg) { + 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; + } +} + /* returns true if done, false if pending; if returning true, *error is set */ #if defined(IOV_MAX) && IOV_MAX < 1000 #define MAX_WRITE_IOVEC IOV_MAX @@ -821,8 +845,11 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { msg.msg_flags = 0; if (tcp->outgoing_buffer_arg != nullptr) { if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length, - error)) + error)) { + gpr_log(GPR_INFO, "something went wrong"); + tcp_shutdown_buffer_list(tcp); return true; /* something went wrong with timestamps */ + } } else { msg.msg_control = nullptr; msg.msg_controllen = 0; @@ -844,12 +871,16 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { } return false; } else if (errno == EPIPE) { + gpr_log(GPR_INFO, "something went wrong"); *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp); grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); + tcp_shutdown_buffer_list(tcp); return true; } else { + gpr_log(GPR_INFO, "something went wrong"); *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp); grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); + tcp_shutdown_buffer_list(tcp); return true; } } @@ -910,6 +941,7 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) { static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, grpc_closure* cb, void* arg) { GPR_TIMER_SCOPE("tcp_write", 0); + gpr_log(GPR_INFO, "tcp_write %p %p", ep, arg); grpc_tcp* tcp = reinterpret_cast(ep); grpc_error* error = GRPC_ERROR_NONE; @@ -926,17 +958,18 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, GPR_ASSERT(tcp->write_cb == nullptr); + tcp->outgoing_buffer_arg = arg; if (buf->length == 0) { GRPC_CLOSURE_SCHED( cb, grpc_fd_is_shutdown(tcp->em_fd) ? tcp_annotate_error( GRPC_ERROR_CREATE_FROM_STATIC_STRING("EOF"), tcp) : GRPC_ERROR_NONE); + tcp_shutdown_buffer_list(tcp); return; } tcp->outgoing_buffer = buf; tcp->outgoing_byte_idx = 0; - tcp->outgoing_buffer_arg = arg; if (arg) { GPR_ASSERT(grpc_event_engine_can_track_errors()); } @@ -949,6 +982,7 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, } notify_on_write(tcp); } else { + gpr_log(GPR_INFO, "imm sched"); if (grpc_tcp_trace.enabled()) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "write: %s", str); @@ -989,6 +1023,23 @@ static grpc_resource_user* tcp_get_resource_user(grpc_endpoint* ep) { return tcp->resource_user; } +static bool tcp_can_track_err(grpc_endpoint* ep) { + grpc_tcp* tcp = reinterpret_cast(ep); + if (!grpc_event_engine_can_track_errors()) { + return false; + } + struct sockaddr addr; + socklen_t len = sizeof(addr); + if (getsockname(tcp->fd, &addr, &len) < 0) { + gpr_log(GPR_ERROR, "getsockname"); + return false; + } + if (addr.sa_family == AF_INET || addr.sa_family == AF_INET6) { + return true; + } + return false; +} + static const grpc_endpoint_vtable vtable = {tcp_read, tcp_write, tcp_add_to_pollset, @@ -998,7 +1049,8 @@ static const grpc_endpoint_vtable vtable = {tcp_read, tcp_destroy, tcp_get_resource_user, tcp_get_peer, - tcp_get_fd}; + tcp_get_fd, + tcp_can_track_err}; #define MAX_CHUNK_SIZE 32 * 1024 * 1024 @@ -1059,6 +1111,7 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->is_first_read = true; tcp->bytes_counter = -1; tcp->socket_ts_enabled = false; + tcp->outgoing_buffer_arg = nullptr; /* paired with unref in grpc_tcp_destroy */ gpr_ref_init(&tcp->refcount, 1); gpr_atm_no_barrier_store(&tcp->shutdown_count, 0); @@ -1097,12 +1150,19 @@ 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_log(GPR_INFO, "destroy and release %p %p", ep, tcp->outgoing_buffer_arg); GPR_ASSERT(ep->vtable == &vtable); tcp->release_fd = fd; tcp->release_fd_cb = done; 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); } diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc index f40f969bb7f..9b103834e1d 100644 --- a/src/core/lib/security/transport/secure_endpoint.cc +++ b/src/core/lib/security/transport/secure_endpoint.cc @@ -389,6 +389,11 @@ static grpc_resource_user* endpoint_get_resource_user( return grpc_endpoint_get_resource_user(ep->wrapped_ep); } +static bool endpoint_can_track_err(grpc_endpoint* secure_ep) { + secure_endpoint* ep = reinterpret_cast(secure_ep); + return grpc_endpoint_can_track_err(ep->wrapped_ep); +} + static const grpc_endpoint_vtable vtable = {endpoint_read, endpoint_write, endpoint_add_to_pollset, @@ -398,7 +403,8 @@ static const grpc_endpoint_vtable vtable = {endpoint_read, endpoint_destroy, endpoint_get_resource_user, endpoint_get_peer, - endpoint_get_fd}; + endpoint_get_fd, + endpoint_can_track_err}; grpc_endpoint* grpc_secure_endpoint_create( struct tsi_frame_protector* protector, diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc index f1773580bd2..1086e42fccd 100644 --- a/test/core/iomgr/buffer_list_test.cc +++ b/test/core/iomgr/buffer_list_test.cc @@ -50,7 +50,7 @@ static void TestShutdownFlushesList() { grpc_core::TracedBuffer::AddNewEntry( &list, i, static_cast(&verifier_called[i])); } - grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE); + grpc_core::TracedBuffer::Shutdown(&list, nullptr, GRPC_ERROR_NONE); GPR_ASSERT(list == nullptr); for (auto i = 0; i < NUM_ELEM; i++) { GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) == @@ -88,7 +88,7 @@ static void TestVerifierCalledOnAck() { grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, &tss); GPR_ASSERT(gpr_atm_acq_load(&verifier_called) == static_cast(1)); GPR_ASSERT(list == nullptr); - grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE); + grpc_core::TracedBuffer::Shutdown(&list, nullptr, GRPC_ERROR_NONE); } static void TestTcpBufferList() { diff --git a/test/core/transport/chttp2/BUILD b/test/core/transport/chttp2/BUILD index 6eff716b01c..c7bfa1ec09e 100644 --- a/test/core/transport/chttp2/BUILD +++ b/test/core/transport/chttp2/BUILD @@ -66,6 +66,19 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "context_list_test", + srcs = ["context_list_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + + grpc_cc_test( name = "hpack_encoder_test", srcs = ["hpack_encoder_test.cc"], diff --git a/test/core/transport/chttp2/context_list_test.cc b/test/core/transport/chttp2/context_list_test.cc new file mode 100644 index 00000000000..1f7a38a107c --- /dev/null +++ b/test/core/transport/chttp2/context_list_test.cc @@ -0,0 +1,64 @@ +/* + * + * 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 "src/core/lib/iomgr/port.h" + +#include "src/core/ext/transport/chttp2/transport/context_list.h" + +#include + +#include "test/core/util/test_config.h" + +static void TestExecuteFlushesListVerifier(void* arg, + grpc_core::Timestamps* ts) { + GPR_ASSERT(arg != nullptr); + gpr_atm* done = reinterpret_cast(arg); + gpr_atm_rel_store(done, static_cast(1)); +} + +/** Tests that all ContextList elements in the list are flushed out on + * execute. + * Also tests that arg is passed correctly. + */ +static void TestExecuteFlushesList() { + grpc_core::ContextList* list = nullptr; + grpc_http2_set_write_timestamps_callback(TestExecuteFlushesListVerifier); +#define NUM_ELEM 5 + grpc_chttp2_stream s[NUM_ELEM]; + gpr_atm verifier_called[NUM_ELEM]; + for (auto i = 0; i < NUM_ELEM; i++) { + s[i].context = &verifier_called[i]; + gpr_atm_rel_store(&verifier_called[i], static_cast(0)); + grpc_core::ContextList::Append(&list, &s[i]); + } + grpc_core::Timestamps ts; + grpc_core::ContextList::Execute(list, &ts, GRPC_ERROR_NONE); + for (auto i = 0; i < NUM_ELEM; i++) { + GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) == + static_cast(1)); + } +} + +static void TestContextList() { TestExecuteFlushesList(); } + +int main(int argc, char** argv) { + grpc_init(); + TestContextList(); + grpc_shutdown(); + return 0; +} diff --git a/test/core/util/mock_endpoint.cc b/test/core/util/mock_endpoint.cc index ef6fd62b516..570edf18e55 100644 --- a/test/core/util/mock_endpoint.cc +++ b/test/core/util/mock_endpoint.cc @@ -114,6 +114,7 @@ static const grpc_endpoint_vtable vtable = { me_get_resource_user, me_get_peer, me_get_fd, + nullptr, }; grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice), diff --git a/test/core/util/passthru_endpoint.cc b/test/core/util/passthru_endpoint.cc index 3cc8ad6fe14..835a39394c5 100644 --- a/test/core/util/passthru_endpoint.cc +++ b/test/core/util/passthru_endpoint.cc @@ -171,6 +171,7 @@ static const grpc_endpoint_vtable vtable = { me_get_resource_user, me_get_peer, me_get_fd, + nullptr, }; static void half_init(half* m, passthru_endpoint* parent, diff --git a/test/core/util/trickle_endpoint.cc b/test/core/util/trickle_endpoint.cc index 62ed72a6295..8d93db05e6c 100644 --- a/test/core/util/trickle_endpoint.cc +++ b/test/core/util/trickle_endpoint.cc @@ -148,7 +148,8 @@ static const grpc_endpoint_vtable vtable = {te_read, te_destroy, te_get_resource_user, te_get_peer, - te_get_fd}; + te_get_fd, + nullptr}; grpc_endpoint* grpc_trickle_endpoint_create(grpc_endpoint* wrap, double bytes_per_second) { diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 7a679aa3b92..eb5e10abacc 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -364,6 +364,21 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "context_list_test", + "src": [ + "test/core/transport/chttp2/context_list_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 fba76d69d1e..bda78360b10 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -433,6 +433,30 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "context_list_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, From 16af7fe9361f7a3bd0450e20702473fdadb2ecf5 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Sun, 26 Aug 2018 21:35:36 -0700 Subject: [PATCH 0007/2143] more stuff --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 1 - src/core/ext/transport/chttp2/transport/context_list.cc | 5 +++-- src/core/ext/transport/chttp2/transport/context_list.h | 3 ++- src/core/lib/iomgr/iomgr.cc | 3 +++ 4 files changed, 8 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 f0dccefeeee..8e07e3e4f93 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -240,7 +240,6 @@ static void init_transport(grpc_chttp2_transport* t, size_t i; int j; - grpc_tcp_set_write_timestamps_callback(grpc_core::ContextList::Execute); GPR_ASSERT(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) == GRPC_CHTTP2_CLIENT_CONNECT_STRLEN); diff --git a/src/core/ext/transport/chttp2/transport/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc index 7bfc947ebbf..9c46418ffd0 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.cc +++ b/src/core/ext/transport/chttp2/transport/context_list.cc @@ -37,8 +37,9 @@ void ContextList::Execute(void* arg, grpc_core::Timestamps* ts, } } gpr_log(GPR_INFO, "one iteration %p %p", head, arg); - // GRPC_CHTTP2_STREAM_UNREF(static_cast(head->s), - // "timestamp exec"); + GRPC_CHTTP2_STREAM_UNREF(static_cast(head->s), + "timestamp exec"); + //grpc_stream_unref(head->s->refcount); ptr = head; head = head->next; gpr_free(ptr); diff --git a/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h index 26b8da413ee..8058bcde7cd 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.h +++ b/src/core/ext/transport/chttp2/transport/context_list.h @@ -34,7 +34,8 @@ class ContextList { static void Append(ContextList** head, grpc_chttp2_stream* s) { /* Make sure context is not already present */ ContextList* ptr = *head; - // GRPC_CHTTP2_STREAM_REF(s, "timestamp"); + GRPC_CHTTP2_STREAM_REF(s, "timestamp"); + //grpc_stream_ref(s->refcount); while (ptr != nullptr) { if (ptr->s == s) { GPR_ASSERT(false); diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index 46afda17742..7c0f19d0dd3 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -33,6 +33,8 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/thd.h" +#include "src/core/ext/transport/chttp2/transport/context_list.h" +#include "src/core/lib/iomgr/buffer_list.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr_internal.h" @@ -57,6 +59,7 @@ void grpc_iomgr_init() { g_root_object.name = (char*)"root"; grpc_network_status_init(); grpc_iomgr_platform_init(); + grpc_tcp_set_write_timestamps_callback(grpc_core::ContextList::Execute); } void grpc_iomgr_start() { grpc_timer_manager_init(); } From 0eb9a3e783237cd46c8ba6d3b33228f537cafbfc Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 27 Aug 2018 15:00:03 -0700 Subject: [PATCH 0008/2143] more stuff --- src/core/ext/transport/chttp2/transport/context_list.cc | 4 ++-- src/core/ext/transport/chttp2/transport/context_list.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc index 9c46418ffd0..91c26a5bca0 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.cc +++ b/src/core/ext/transport/chttp2/transport/context_list.cc @@ -21,7 +21,7 @@ #include "src/core/ext/transport/chttp2/transport/context_list.h" namespace { -void (*cb)(void*, grpc_core::Timestamps*) = nullptr; +void (*cb)(void*, const char*) = nullptr; } namespace grpc_core { @@ -47,7 +47,7 @@ void ContextList::Execute(void* arg, grpc_core::Timestamps* ts, } void grpc_http2_set_write_timestamps_callback( - void (*fn)(void*, grpc_core::Timestamps*)) { + void (*fn)(void*, const char*)) { cb = fn; } } /* namespace grpc_core */ diff --git a/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h index 8058bcde7cd..23a49d5b320 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.h +++ b/src/core/ext/transport/chttp2/transport/context_list.h @@ -70,7 +70,7 @@ class ContextList { }; void grpc_http2_set_write_timestamps_callback( - void (*fn)(void*, grpc_core::Timestamps*)); + void (*fn)(void*, const char*)); } /* namespace grpc_core */ #endif /* GRPC_CORE_EXT_TRANSPORT_CONTEXT_LIST_H */ From 4c356fd0229757586109821da41c18dd47796370 Mon Sep 17 00:00:00 2001 From: Jason Mobarak Date: Thu, 30 Aug 2018 17:34:02 -0700 Subject: [PATCH 0009/2143] Don't overwrite HOST_* make variables --- Makefile | 10 +++++----- templates/Makefile.template | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 3454ef85870..79ab41e295b 100644 --- a/Makefile +++ b/Makefile @@ -455,11 +455,11 @@ LDFLAGS += $(EXTRA_LDFLAGS) DEFINES += $(EXTRA_DEFINES) LDLIBS += $(EXTRA_LDLIBS) -HOST_CPPFLAGS = $(CPPFLAGS) -HOST_CFLAGS = $(CFLAGS) -HOST_CXXFLAGS = $(CXXFLAGS) -HOST_LDFLAGS = $(LDFLAGS) -HOST_LDLIBS = $(LDLIBS) +HOST_CPPFLAGS += $(CPPFLAGS) +HOST_CFLAGS += $(CFLAGS) +HOST_CXXFLAGS += $(CXXFLAGS) +HOST_LDFLAGS += $(LDFLAGS) +HOST_LDLIBS += $(LDLIBS) # These are automatically computed variables. # There shouldn't be any need to change anything from now on. diff --git a/templates/Makefile.template b/templates/Makefile.template index 2e3d75d819e..6958c6382d5 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -323,11 +323,11 @@ ${arg} += $(EXTRA_${arg}) % endfor - HOST_CPPFLAGS = $(CPPFLAGS) - HOST_CFLAGS = $(CFLAGS) - HOST_CXXFLAGS = $(CXXFLAGS) - HOST_LDFLAGS = $(LDFLAGS) - HOST_LDLIBS = $(LDLIBS) + HOST_CPPFLAGS += $(CPPFLAGS) + HOST_CFLAGS += $(CFLAGS) + HOST_CXXFLAGS += $(CXXFLAGS) + HOST_LDFLAGS += $(LDFLAGS) + HOST_LDLIBS += $(LDLIBS) # These are automatically computed variables. # There shouldn't be any need to change anything from now on. From 118e69a48449b17a5c1fa0d660c119380528c190 Mon Sep 17 00:00:00 2001 From: David Hoover Date: Wed, 12 Sep 2018 13:15:44 -0700 Subject: [PATCH 0010/2143] 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 39eb19ed3572749add957f8f980f4b50549192a2 Mon Sep 17 00:00:00 2001 From: Gleb Popov <6yearold@gmail.com> Date: Sat, 22 Sep 2018 22:36:40 +0300 Subject: [PATCH 0011/2143] Fix various tests on FreeBSD. --- test/core/iomgr/socket_utils_test.cc | 1 + test/cpp/interop/interop_test.cc | 4 ---- test/cpp/naming/address_sorting_test.cc | 1 + test/cpp/naming/resolver_component_tests_runner_invoker.cc | 4 ++++ test/cpp/qps/json_run_localhost.cc | 4 ++++ 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/test/core/iomgr/socket_utils_test.cc b/test/core/iomgr/socket_utils_test.cc index a21f3fac62e..8c5b6f3db9f 100644 --- a/test/core/iomgr/socket_utils_test.cc +++ b/test/core/iomgr/socket_utils_test.cc @@ -24,6 +24,7 @@ #include "src/core/lib/iomgr/socket_utils_posix.h" #include +#include #include #include diff --git a/test/cpp/interop/interop_test.cc b/test/cpp/interop/interop_test.cc index ae155b65f95..8e45b877212 100644 --- a/test/cpp/interop/interop_test.cc +++ b/test/cpp/interop/interop_test.cc @@ -16,10 +16,6 @@ * */ -#ifndef _POSIX_SOURCE -#define _POSIX_SOURCE -#endif - #include #include #include diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index fc6721d0ba8..37fd408cc7a 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -51,6 +51,7 @@ #ifndef GPR_WINDOWS #include +#include #include #endif diff --git a/test/cpp/naming/resolver_component_tests_runner_invoker.cc b/test/cpp/naming/resolver_component_tests_runner_invoker.cc index 68be00a67d6..d8f7100a284 100644 --- a/test/cpp/naming/resolver_component_tests_runner_invoker.cc +++ b/test/cpp/naming/resolver_component_tests_runner_invoker.cc @@ -29,6 +29,10 @@ #include #include +#ifdef __FreeBSD__ +#include +#endif + #include "test/cpp/util/subprocess.h" #include "test/cpp/util/test_config.h" diff --git a/test/cpp/qps/json_run_localhost.cc b/test/cpp/qps/json_run_localhost.cc index 948c3088e67..42cc9e0ed76 100644 --- a/test/cpp/qps/json_run_localhost.cc +++ b/test/cpp/qps/json_run_localhost.cc @@ -24,6 +24,10 @@ #include #include +#ifdef __FreeBSD__ +#include +#endif + #include #include "src/core/lib/gpr/env.h" From 9fbc9105a62e5ca309d5152407dea0db86cc1709 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 8 Oct 2018 15:47:22 -0700 Subject: [PATCH 0012/2143] Update tests --- .../tests/ChannelTests/ChannelPoolTest.m | 164 ++++ .../tests/ChannelTests/ChannelTests.m | 93 ++ src/objective-c/tests/ChannelTests/Info.plist | 22 + src/objective-c/tests/GRPCClientTests.m | 291 ++++++- src/objective-c/tests/InteropTests.h | 21 + src/objective-c/tests/InteropTests.m | 201 +++++ .../tests/InteropTestsCallOptions/Info.plist | 22 + .../InteropTestsCallOptions.m | 116 +++ .../tests/InteropTestsLocalCleartext.m | 12 + src/objective-c/tests/InteropTestsLocalSSL.m | 16 + .../InteropTestsMultipleChannels/Info.plist | 22 + .../InteropTestsMultipleChannels.m | 259 ++++++ src/objective-c/tests/InteropTestsRemote.m | 18 + src/objective-c/tests/Podfile | 10 +- .../tests/Tests.xcodeproj/project.pbxproj | 822 ++++++++++++++++++ .../xcschemes/ChannelTests.xcscheme | 92 ++ .../InteropTestsCallOptions.xcscheme | 56 ++ .../InteropTestsLocalCleartext.xcscheme | 8 - .../InteropTestsMultipleChannels.xcscheme | 56 ++ .../xcschemes/InteropTestsRemote.xcscheme | 2 - src/objective-c/tests/run_tests.sh | 10 + 21 files changed, 2300 insertions(+), 13 deletions(-) create mode 100644 src/objective-c/tests/ChannelTests/ChannelPoolTest.m create mode 100644 src/objective-c/tests/ChannelTests/ChannelTests.m create mode 100644 src/objective-c/tests/ChannelTests/Info.plist create mode 100644 src/objective-c/tests/InteropTestsCallOptions/Info.plist create mode 100644 src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m create mode 100644 src/objective-c/tests/InteropTestsMultipleChannels/Info.plist create mode 100644 src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m create mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme create mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsCallOptions.xcscheme create mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m new file mode 100644 index 00000000000..3b6b10b1a5f --- /dev/null +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -0,0 +1,164 @@ +/* + * + * 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. + * + */ + +#import + +#import "../../GRPCClient/private/GRPCChannel.h" +#import "../../GRPCClient/private/GRPCChannelPool.h" + +#define TEST_TIMEOUT 32 + +NSString *kDummyHost = @"dummy.host"; + +@interface ChannelPoolTest : XCTestCase + +@end + +@implementation ChannelPoolTest + ++ (void)setUp { + grpc_init(); +} + +- (void)testCreateChannel { + NSString *kDummyHost = @"dummy.host"; + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; + options1.transportType = GRPCTransportTypeInsecure; + GRPCCallOptions *options2 = [options1 copy]; + GRPCChannelConfiguration *config1 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; + GRPCChannelConfiguration *config2 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initWithChannelDestroyDelay:1]; + + __weak XCTestExpectation *expectCreateChannel = + [self expectationWithDescription:@"Create first channel"]; + GRPCChannel *channel1 = + [pool channelWithConfiguration:config1 + createChannel:^{ + [expectCreateChannel fulfill]; + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; + GRPCChannel *channel2 = [pool channelWithConfiguration:config2 + createChannel:^{ + XCTFail(@"Should not create a second channel."); + return (GRPCChannel *)nil; + }]; + XCTAssertEqual(channel1, channel2); +} + +- (void)testChannelTimeout { + NSTimeInterval kChannelDestroyDelay = 1.0; + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; + options1.transportType = GRPCTransportTypeInsecure; + GRPCChannelConfiguration *config1 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; + GRPCChannelPool *pool = + [[GRPCChannelPool alloc] initWithChannelDestroyDelay:kChannelDestroyDelay]; + GRPCChannel *channel1 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + [pool unrefChannelWithConfiguration:config1]; + __weak XCTestExpectation *expectTimerDone = [self expectationWithDescription:@"Timer elapse."]; + NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:kChannelDestroyDelay + 1 + repeats:NO + block:^(NSTimer *_Nonnull timer) { + [expectTimerDone fulfill]; + }]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; + timer = nil; + GRPCChannel *channel2 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + XCTAssertNotEqual(channel1, channel2); +} + +- (void)testChannelTimeoutCancel { + NSTimeInterval kChannelDestroyDelay = 3.0; + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; + options1.transportType = GRPCTransportTypeInsecure; + GRPCChannelConfiguration *config1 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; + GRPCChannelPool *pool = + [[GRPCChannelPool alloc] initWithChannelDestroyDelay:kChannelDestroyDelay]; + GRPCChannel *channel1 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + [channel1 unmanagedCallUnref]; + sleep(1); + GRPCChannel *channel2 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + XCTAssertEqual(channel1, channel2); + sleep((int)kChannelDestroyDelay + 2); + GRPCChannel *channel3 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + XCTAssertEqual(channel1, channel3); +} + +- (void)testClearChannels { + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; + options1.transportType = GRPCTransportTypeInsecure; + GRPCMutableCallOptions *options2 = [[GRPCMutableCallOptions alloc] init]; + options2.transportType = GRPCTransportTypeDefault; + GRPCChannelConfiguration *config1 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; + GRPCChannelConfiguration *config2 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initWithChannelDestroyDelay:1]; + + GRPCChannel *channel1 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + GRPCChannel *channel2 = + [pool channelWithConfiguration:config2 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config2]; + }]; + XCTAssertNotEqual(channel1, channel2); + + [pool clear]; + GRPCChannel *channel3 = + [pool channelWithConfiguration:config1 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config1]; + }]; + GRPCChannel *channel4 = + [pool channelWithConfiguration:config2 + createChannel:^{ + return [GRPCChannel createChannelWithConfiguration:config2]; + }]; + XCTAssertNotEqual(channel1, channel3); + XCTAssertNotEqual(channel2, channel4); +} + +@end diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m new file mode 100644 index 00000000000..0a8b7ae6ee6 --- /dev/null +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -0,0 +1,93 @@ +/* + * + * 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. + * + */ + +#import + +#import "../../GRPCClient/GRPCCallOptions.h" +#import "../../GRPCClient/private/GRPCChannel.h" + +@interface ChannelTests : XCTestCase + +@end + +@implementation ChannelTests + ++ (void)setUp { + grpc_init(); +} + +- (void)testSameConfiguration { + NSString *host = @"grpc-test.sandbox.googleapis.com"; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.userAgentPrefix = @"TestUAPrefix"; + NSMutableDictionary *args = [NSMutableDictionary new]; + args[@"abc"] = @"xyz"; + options.additionalChannelArgs = [args copy]; + GRPCChannel *channel1 = [GRPCChannel channelWithHost:host callOptions:options]; + GRPCChannel *channel2 = [GRPCChannel channelWithHost:host callOptions:options]; + XCTAssertEqual(channel1, channel2); + GRPCMutableCallOptions *options2 = [options mutableCopy]; + options2.additionalChannelArgs = [args copy]; + GRPCChannel *channel3 = [GRPCChannel channelWithHost:host callOptions:options2]; + XCTAssertEqual(channel1, channel3); +} + +- (void)testDifferentHost { + NSString *host1 = @"grpc-test.sandbox.googleapis.com"; + NSString *host2 = @"grpc-test2.sandbox.googleapis.com"; + NSString *host3 = @"http://grpc-test.sandbox.googleapis.com"; + NSString *host4 = @"dns://grpc-test.sandbox.googleapis.com"; + NSString *host5 = @"grpc-test.sandbox.googleapis.com:80"; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.userAgentPrefix = @"TestUAPrefix"; + NSMutableDictionary *args = [NSMutableDictionary new]; + args[@"abc"] = @"xyz"; + options.additionalChannelArgs = [args copy]; + GRPCChannel *channel1 = [GRPCChannel channelWithHost:host1 callOptions:options]; + GRPCChannel *channel2 = [GRPCChannel channelWithHost:host2 callOptions:options]; + GRPCChannel *channel3 = [GRPCChannel channelWithHost:host3 callOptions:options]; + GRPCChannel *channel4 = [GRPCChannel channelWithHost:host4 callOptions:options]; + GRPCChannel *channel5 = [GRPCChannel channelWithHost:host5 callOptions:options]; + XCTAssertNotEqual(channel1, channel2); + XCTAssertNotEqual(channel1, channel3); + XCTAssertNotEqual(channel1, channel4); + XCTAssertNotEqual(channel1, channel5); +} + +- (void)testDifferentChannelParameters { + NSString *host = @"grpc-test.sandbox.googleapis.com"; + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; + options1.transportType = GRPCTransportTypeDefault; + NSMutableDictionary *args = [NSMutableDictionary new]; + args[@"abc"] = @"xyz"; + options1.additionalChannelArgs = [args copy]; + GRPCMutableCallOptions *options2 = [[GRPCMutableCallOptions alloc] init]; + options2.transportType = GRPCTransportTypeInsecure; + options2.additionalChannelArgs = [args copy]; + GRPCMutableCallOptions *options3 = [[GRPCMutableCallOptions alloc] init]; + options3.transportType = GRPCTransportTypeDefault; + args[@"def"] = @"uvw"; + options3.additionalChannelArgs = [args copy]; + GRPCChannel *channel1 = [GRPCChannel channelWithHost:host callOptions:options1]; + GRPCChannel *channel2 = [GRPCChannel channelWithHost:host callOptions:options2]; + GRPCChannel *channel3 = [GRPCChannel channelWithHost:host callOptions:options3]; + XCTAssertNotEqual(channel1, channel2); + XCTAssertNotEqual(channel1, channel3); +} + +@end diff --git a/src/objective-c/tests/ChannelTests/Info.plist b/src/objective-c/tests/ChannelTests/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/ChannelTests/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/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index a0de8ba8990..bad22d30cbb 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -86,6 +86,58 @@ static GRPCProtoMethod *kFullDuplexCallMethod; @end +// Convenience class to use blocks as callbacks +@interface ClientTestsBlockCallbacks : NSObject + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; + +@end + +@implementation ClientTestsBlockCallbacks { + void (^_initialMetadataCallback)(NSDictionary *); + void (^_messageCallback)(id); + void (^_closeCallback)(NSDictionary *, NSError *); + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + if ((self = [super init])) { + _initialMetadataCallback = initialMetadataCallback; + _messageCallback = messageCallback; + _closeCallback = closeCallback; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } +} + +- (void)receivedMessage:(id)message { + if (_messageCallback) { + _messageCallback(message); + } +} + +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + #pragma mark Tests /** @@ -237,6 +289,55 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testMetadataWithV2API { + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.fillUsername = YES; + request.fillOauthScope = YES; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kRemoteSSLHost + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + __block NSDictionary *init_md; + __block NSDictionary *trailing_md; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.oauth2AccessToken = @"bogusToken"; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + handler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + init_md = initialMetadata; + } + messageCallback:^(id message) { + XCTFail(@"Received unexpected response."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + trailing_md = trailingMetadata; + if (error) { + XCTAssertEqual(error.code, 16, + @"Finished with unexpected error: %@", error); + XCTAssertEqualObjects(init_md, + error.userInfo[kGRPCHeadersKey]); + XCTAssertEqualObjects(trailing_md, + error.userInfo[kGRPCTrailersKey]); + NSString *challengeHeader = init_md[@"www-authenticate"]; + XCTAssertGreaterThan(challengeHeader.length, 0, + @"No challenge in response headers %@", + init_md); + [expectation fulfill]; + } + }] + callOptions:options]; + + [call start]; + [call writeWithData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testResponseMetadataKVO { __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."]; @@ -329,6 +430,77 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testUserAgentPrefixWithV2API { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."]; + __weak XCTestExpectation *recvInitialMd = + [self expectationWithDescription:@"Did not receive initial md."]; + + GRPCRequestOptions *request = [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kEmptyCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + NSDictionary *headers = + [NSDictionary dictionaryWithObjectsAndKeys:@"", @"x-grpc-test-echo-useragent", nil]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.userAgentPrefix = @"Foo"; + options.initialMetadata = headers; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:request + handler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( + NSDictionary *initialMetadata) { + NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; + // Test the regex is correct + NSString *expectedUserAgent = @"Foo grpc-objc/"; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:GRPC_OBJC_VERSION_STRING]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@" grpc-c/"]; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:GRPC_C_VERSION_STRING]; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:@" (ios; chttp2; "]; + expectedUserAgent = [expectedUserAgent + stringByAppendingString:[NSString + stringWithUTF8String:grpc_g_stands_for()]]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@")"]; + XCTAssertEqualObjects(userAgent, expectedUserAgent); + + NSError *error = nil; + // Change in format of user-agent field in a direction that does not match + // the regex will likely cause problem for certain gRPC users. For details, + // refer to internal doc https://goo.gl/c2diBc + NSRegularExpression *regex = [NSRegularExpression + regularExpressionWithPattern: + @" grpc-[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?/[^ ,]+( \\([^)]*\\))?" + options:0 + error:&error]; + + NSString *customUserAgent = [regex + stringByReplacingMatchesInString:userAgent + options:0 + range:NSMakeRange(0, [userAgent length]) + withTemplate:@""]; + XCTAssertEqualObjects(customUserAgent, @"Foo"); + [recvInitialMd fulfill]; + } + messageCallback:^(id message) { + XCTAssertNotNil(message); + XCTAssertEqual([message length], 0, + @"Non-empty response received: %@", message); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + if (error) { + XCTFail(@"Finished with unexpected error: %@", error); + } else { + [completion fulfill]; + } + }] + callOptions:options]; + [call writeWithData:[NSData data]]; + [call start]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testTrailers { __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."]; @@ -420,6 +592,52 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testIdempotentProtoRPCWithV2API { + __weak XCTestExpectation *response = [self expectationWithDescription:@"Expected response."]; + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseSize = 100; + request.fillUsername = YES; + request.fillOauthScope = YES; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyIdempotentRequest]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + handler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + NSData *data = (NSData *)message; + XCTAssertNotNil(data, @"nil value received as response."); + XCTAssertGreaterThan(data.length, 0, + @"Empty response received."); + RMTSimpleResponse *responseProto = + [RMTSimpleResponse parseFromData:data error:NULL]; + // We expect empty strings, not nil: + XCTAssertNotNil(responseProto.username, + @"Response's username is nil."); + XCTAssertNotNil(responseProto.oauthScope, + @"Response's OAuth scope is nil."); + [response fulfill]; + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", + error); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + [call writeWithData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testAlternateDispatchQueue { const int32_t kPayloadSize = 100; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -509,6 +727,38 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testTimeoutWithV2API { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.timeout = 0.001; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + handler: + [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id data) { + XCTFail( + @"Failure: response received; Expect: no response received."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Failure: no error received; Expect: receive " + @"deadline exceeded."); + XCTAssertEqual(error.code, GRPCErrorCodeDeadlineExceeded); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (int)findFreePort { struct sockaddr_in addr; unsigned int addr_len = sizeof(addr); @@ -580,15 +830,52 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testTimeoutBackoffWithOptionsWithTimeout:(double)timeout Backoff:(double)backoff { + const double maxConnectTime = timeout > backoff ? timeout : backoff; + const double kMargin = 0.1; + + __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; + NSString *const kDummyAddress = [NSString stringWithFormat:@"8.8.8.8:1"]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kDummyAddress path:@"" safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.connectMinTimeout = timeout; + options.connectInitialBackoff = backoff; + options.connectMaxBackoff = 0; + + NSDate *startTime = [NSDate date]; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + handler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id data) { + XCTFail(@"Received message. Should not reach here."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Finished with no error; expecting error"); + XCTAssertLessThan( + [[NSDate date] timeIntervalSinceDate:startTime], + maxConnectTime + kMargin); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + // The numbers of the following three tests are selected to be smaller than the default values of // initial backoff (1s) and min_connect_timeout (20s), so that if they fail we know the default // values fail to be overridden by the channel args. -- (void)testTimeoutBackoff2 { +- (void)testTimeoutBackoff1 { [self testTimeoutBackoffWithTimeout:0.7 Backoff:0.3]; + [self testTimeoutBackoffWithOptionsWithTimeout:0.7 Backoff:0.4]; } -- (void)testTimeoutBackoff3 { +- (void)testTimeoutBackoff2 { [self testTimeoutBackoffWithTimeout:0.3 Backoff:0.7]; + [self testTimeoutBackoffWithOptionsWithTimeout:0.3 Backoff:0.8]; } - (void)testErrorDebugInformation { diff --git a/src/objective-c/tests/InteropTests.h b/src/objective-c/tests/InteropTests.h index 039d92a8d35..e223839d3ac 100644 --- a/src/objective-c/tests/InteropTests.h +++ b/src/objective-c/tests/InteropTests.h @@ -18,6 +18,8 @@ #import +#import + /** * Implements tests as described here: * https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md @@ -38,4 +40,23 @@ * remote servers enconde responses with different overhead (?), so this is defined per-subclass. */ - (int32_t)encodingOverhead; + +/** + * The type of transport to be used. The base implementation returns default. Subclasses should + * override to appropriate settings. + */ ++ (GRPCTransportType)transportType; + +/** + * The root certificates to be used. The base implementation returns nil. Subclasses should override + * to appropriate settings. + */ ++ (NSString *)pemRootCert; + +/** + * The root certificates to be used. The base implementation returns nil. Subclasses should override + * to appropriate settings. + */ ++ (NSString *)hostNameOverride; + @end diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 9d796068818..54af7036c35 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -74,6 +74,58 @@ BOOL isRemoteInteropTest(NSString *host) { return [host isEqualToString:@"grpc-test.sandbox.googleapis.com"]; } +// Convenience class to use blocks as callbacks +@interface InteropTestsBlockCallbacks : NSObject + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; + +@end + +@implementation InteropTestsBlockCallbacks { + void (^_initialMetadataCallback)(NSDictionary *); + void (^_messageCallback)(id); + void (^_closeCallback)(NSDictionary *, NSError *); + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + if ((self = [super init])) { + _initialMetadataCallback = initialMetadataCallback; + _messageCallback = messageCallback; + _closeCallback = closeCallback; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } +} + +- (void)receivedMessage:(id)message { + if (_messageCallback) { + _messageCallback(message); + } +} + +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + #pragma mark Tests @implementation InteropTests { @@ -91,6 +143,18 @@ BOOL isRemoteInteropTest(NSString *host) { return 0; } ++ (GRPCTransportType)transportType { + return GRPCTransportTypeDefault; +} + ++ (NSString *)pemRootCert { + return nil; +} + ++ (NSString *)hostNameOverride { + return nil; +} + + (void)setUp { NSLog(@"InteropTest Started, class: %@", [[self class] description]); #ifdef GRPC_COMPILE_WITH_CRONET @@ -131,6 +195,33 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testEmptyUnaryRPCWithV2API { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnary"]; + + GPBEmpty *request = [GPBEmpty message]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = self.class.transportType; + options.pemRootCert = self.class.pemRootCert; + options.hostNameOverride = self.class.hostNameOverride; + + [_service + emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + if (message) { + id expectedResponse = [GPBEmpty message]; + XCTAssertEqualObjects(message, expectedResponse); + [expectation fulfill]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + }] + callOptions:options]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testLargeUnaryRPC { XCTAssertNotNil(self.class.host); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; @@ -380,6 +471,57 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testPingPongRPCWithV2API { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"]; + + NSArray *requests = @[ @27182, @8, @1828, @45904 ]; + NSArray *responses = @[ @31415, @9, @2653, @58979 ]; + + __block int index = 0; + + id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = self.class.transportType; + options.pemRootCert = self.class.pemRootCert; + options.hostNameOverride = self.class.hostNameOverride; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertLessThan(index, 4, + @"More than 4 responses received."); + id expected = [RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]]; + XCTAssertEqualObjects(message, expected); + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + [call writeWithMessage:request]; + } else { + [call finish]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, + @"Finished with unexpected error: %@", + error); + XCTAssertEqual(index, 4, + @"Received %i responses instead of 4.", + index); + [expectation fulfill]; + }] + callOptions:options]; + [call writeWithMessage:request]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testEmptyStreamRPC { XCTAssertNotNil(self.class.host); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"]; @@ -418,6 +560,28 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testCancelAfterBeginRPCWithV2API { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBegin"]; + + // A buffered pipe to which we never write any value acts as a writer that just hangs. + __block GRPCStreamingProtoCall *call = [_service + streamingInputCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTFail(@"Not expected to receive message"); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + [expectation fulfill]; + }] + callOptions:nil]; + [call cancel]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testCancelAfterFirstResponseRPC { XCTAssertNotNil(self.class.host); __weak XCTestExpectation *expectation = @@ -454,6 +618,43 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testCancelAfterFirstResponseRPCWithV2API { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *completionExpectation = + [self expectationWithDescription:@"Call completed."]; + __weak XCTestExpectation *responseExpectation = + [self expectationWithDescription:@"Received response."]; + + __block BOOL receivedResponse = NO; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = self.class.transportType; + options.pemRootCert = self.class.pemRootCert; + options.hostNameOverride = self.class.hostNameOverride; + + id request = + [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertFalse(receivedResponse); + receivedResponse = YES; + [call cancel]; + [responseExpectation fulfill]; + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + [completionExpectation fulfill]; + }] + callOptions:options]; + + [call writeWithMessage:request]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testRPCAfterClosingOpenConnections { XCTAssertNotNil(self.class.host); __weak XCTestExpectation *expectation = diff --git a/src/objective-c/tests/InteropTestsCallOptions/Info.plist b/src/objective-c/tests/InteropTestsCallOptions/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/InteropTestsCallOptions/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/tests/InteropTestsCallOptions/InteropTestsCallOptions.m b/src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m new file mode 100644 index 00000000000..db51cb1cfbb --- /dev/null +++ b/src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m @@ -0,0 +1,116 @@ +/* + * + * 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. + * + */ + +#import + +#import +#import +#import +#import +#import +#import + +#define NSStringize_helper(x) #x +#define NSStringize(x) @NSStringize_helper(x) +static NSString *kRemoteHost = NSStringize(HOST_PORT_REMOTE); +const int32_t kRemoteInteropServerOverhead = 12; + +static const NSTimeInterval TEST_TIMEOUT = 16000; + +@interface InteropTestsCallOptions : XCTestCase + +@end + +@implementation InteropTestsCallOptions { + RMTTestService *_service; +} + +- (void)setUp { + self.continueAfterFailure = NO; + _service = [RMTTestService serviceWithHost:kRemoteHost]; + _service.options = [[GRPCCallOptions alloc] init]; +} + +- (void)test4MBResponsesAreAccepted { + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"MaxResponseSize"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const int32_t kPayloadSize = + 4 * 1024 * 1024 - kRemoteInteropServerOverhead; // 4MB - encoding overhead + request.responseSize = kPayloadSize; + + [_service unaryCallWithRequest:request + handler:^(RMTSimpleResponse *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + XCTAssertEqual(response.payload.body.length, kPayloadSize); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testResponsesOverMaxSizeFailWithActionableMessage { + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const int32_t kPayloadSize = + 4 * 1024 * 1024 - kRemoteInteropServerOverhead + 1; // 1B over max size + request.responseSize = kPayloadSize; + + [_service unaryCallWithRequest:request + handler:^(RMTSimpleResponse *response, NSError *error) { + XCTAssertEqualObjects( + error.localizedDescription, + @"Received message larger than max (4194305 vs. 4194304)"); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testResponsesOver4MBAreAcceptedIfOptedIn { + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"HigherResponseSizeLimit"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const size_t kPayloadSize = 5 * 1024 * 1024; // 5MB + request.responseSize = kPayloadSize; + + GRPCProtoCall *rpc = [_service + RPCToUnaryCallWithRequest:request + handler:^(RMTSimpleResponse *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + XCTAssertEqual(response.payload.body.length, kPayloadSize); + [expectation fulfill]; + }]; + GRPCCallOptions *options = rpc.options; + options.responseSizeLimit = 6 * 1024 * 1024; + + [rpc start]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/src/objective-c/tests/InteropTestsLocalCleartext.m b/src/objective-c/tests/InteropTestsLocalCleartext.m index d49e875bd02..42e327a3303 100644 --- a/src/objective-c/tests/InteropTestsLocalCleartext.m +++ b/src/objective-c/tests/InteropTestsLocalCleartext.m @@ -41,6 +41,14 @@ static int32_t kLocalInteropServerOverhead = 10; return kLocalCleartextHost; } ++ (NSString *)pemRootCert { + return nil; +} + ++ (NSString *)hostNameOverride { + return nil; +} + - (int32_t)encodingOverhead { return kLocalInteropServerOverhead; // bytes } @@ -52,4 +60,8 @@ static int32_t kLocalInteropServerOverhead = 10; [GRPCCall useInsecureConnectionsForHost:kLocalCleartextHost]; } ++ (GRPCTransportType)transportType { + return GRPCTransportTypeInsecure; +} + @end diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m index a8c4dc7dfd1..eb72dd1d311 100644 --- a/src/objective-c/tests/InteropTestsLocalSSL.m +++ b/src/objective-c/tests/InteropTestsLocalSSL.m @@ -40,10 +40,26 @@ static int32_t kLocalInteropServerOverhead = 10; return kLocalSSLHost; } ++ (NSString *)pemRootCert { + NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSString *certsPath = + [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; + NSError *error; + return [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error]; +} + ++ (NSString *)hostNameOverride { + return @"foo.test.google.fr"; +} + - (int32_t)encodingOverhead { return kLocalInteropServerOverhead; // bytes } ++ (GRPCTransportType)transportType { + return GRPCTransportTypeDefault; +} + - (void)setUp { [super setUp]; diff --git a/src/objective-c/tests/InteropTestsMultipleChannels/Info.plist b/src/objective-c/tests/InteropTestsMultipleChannels/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/InteropTestsMultipleChannels/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/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m new file mode 100644 index 00000000000..eb0ba7f34b3 --- /dev/null +++ b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m @@ -0,0 +1,259 @@ +/* + * + * 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. + * + */ + +#import + +#import +#import +#import +#import +#import + +#define NSStringize_helper(x) #x +#define NSStringize(x) @NSStringize_helper(x) +static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE); +static NSString *const kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL); +static NSString *const kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL); + +static const NSTimeInterval TEST_TIMEOUT = 8000; + +@interface RMTStreamingOutputCallRequest (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize + requestedResponseSize:(NSNumber *)responseSize; +@end + +@implementation RMTStreamingOutputCallRequest (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize + requestedResponseSize:(NSNumber *)responseSize { + RMTStreamingOutputCallRequest *request = [self message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = responseSize.intValue; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; + return request; +} +@end + +@interface RMTStreamingOutputCallResponse (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize; +@end + +@implementation RMTStreamingOutputCallResponse (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize { + RMTStreamingOutputCallResponse *response = [self message]; + response.payload.type = RMTPayloadType_Compressable; + response.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; + return response; +} +@end + +@interface InteropTestsMultipleChannels : XCTestCase + +@end + +dispatch_once_t initCronet; + +@implementation InteropTestsMultipleChannels { + RMTTestService *_remoteService; + RMTTestService *_remoteCronetService; + RMTTestService *_localCleartextService; + RMTTestService *_localSSLService; +} + +- (void)setUp { + [super setUp]; + + self.continueAfterFailure = NO; + + // Default stack with remote host + _remoteService = [RMTTestService serviceWithHost:kRemoteSSLHost]; + + // Cronet stack with remote host + _remoteCronetService = [RMTTestService serviceWithHost:kRemoteSSLHost]; + + dispatch_once(&initCronet, ^{ + [Cronet setHttp2Enabled:YES]; + [Cronet start]; + }); + + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + options.transportType = GRPCTransportTypeCronet; + options.cronetEngine = [Cronet getGlobalEngine]; + _remoteCronetService.options = options; + + // Local stack with no SSL + _localCleartextService = [RMTTestService serviceWithHost:kLocalCleartextHost]; + options = [[GRPCCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + _localCleartextService.options = options; + + // Local stack with SSL + _localSSLService = [RMTTestService serviceWithHost:kLocalSSLHost]; + + NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSString *certsPath = + [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; + NSError *error = nil; + NSString *certs = + [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error]; + XCTAssertNil(error); + + options = [[GRPCCallOptions alloc] init]; + options.transportType = GRPCTransportTypeDefault; + options.pemRootCert = certs; + options.hostNameOverride = @"foo.test.google.fr"; + _localSSLService.options = options; +} + +- (void)testEmptyUnaryRPC { + __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCronetRemote = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCleartext = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; + + GPBEmpty *request = [GPBEmpty message]; + + void (^handler)(GPBEmpty *response, NSError *error) = ^(GPBEmpty *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + + id expectedResponse = [GPBEmpty message]; + XCTAssertEqualObjects(response, expectedResponse); + }; + + [_remoteService emptyCallWithRequest:request + handler:^(GPBEmpty *response, NSError *error) { + handler(response, error); + [expectRemote fulfill]; + }]; + [_remoteCronetService emptyCallWithRequest:request + handler:^(GPBEmpty *response, NSError *error) { + handler(response, error); + [expectCronetRemote fulfill]; + }]; + [_localCleartextService emptyCallWithRequest:request + handler:^(GPBEmpty *response, NSError *error) { + handler(response, error); + [expectCleartext fulfill]; + }]; + [_localSSLService emptyCallWithRequest:request + handler:^(GPBEmpty *response, NSError *error) { + handler(response, error); + [expectSSL fulfill]; + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testFullDuplexRPC { + __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCronetRemote = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCleartext = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; + + NSArray *requestSizes = @[ @100, @101, @102, @103 ]; + NSArray *responseSizes = @[ @104, @105, @106, @107 ]; + XCTAssertEqual([requestSizes count], [responseSizes count]); + NSUInteger kRounds = [requestSizes count]; + + NSMutableArray *requests = [NSMutableArray arrayWithCapacity:kRounds]; + NSMutableArray *responses = [NSMutableArray arrayWithCapacity:kRounds]; + for (int i = 0; i < kRounds; i++) { + requests[i] = [RMTStreamingOutputCallRequest messageWithPayloadSize:requestSizes[i] + requestedResponseSize:responseSizes[i]]; + responses[i] = [RMTStreamingOutputCallResponse messageWithPayloadSize:responseSizes[i]]; + } + + __block NSMutableArray *steps = [NSMutableArray arrayWithCapacity:4]; + __block NSMutableArray *requestsBuffers = [NSMutableArray arrayWithCapacity:4]; + for (int i = 0; i < 4; i++) { + steps[i] = [NSNumber numberWithUnsignedInteger:0]; + requestsBuffers[i] = [[GRXBufferedPipe alloc] init]; + [requestsBuffers[i] writeValue:requests[0]]; + } + + BOOL (^handler)(int, BOOL, RMTStreamingOutputCallResponse *, NSError *) = + ^(int index, BOOL done, RMTStreamingOutputCallResponse *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + XCTAssertTrue(done || response, @"Event handler called without an event."); + if (response) { + NSUInteger step = [steps[index] unsignedIntegerValue]; + XCTAssertLessThan(step, kRounds, @"More than %lu responses received.", + (unsigned long)kRounds); + XCTAssertEqualObjects(response, responses[step]); + step++; + steps[index] = [NSNumber numberWithUnsignedInteger:step]; + GRXBufferedPipe *pipe = requestsBuffers[index]; + if (step < kRounds) { + [pipe writeValue:requests[step]]; + } else { + [pipe writesFinishedWithError:nil]; + } + } + if (done) { + NSUInteger step = [steps[index] unsignedIntegerValue]; + XCTAssertEqual(step, kRounds, @"Received %lu responses instead of %lu.", step, kRounds); + return YES; + } + return NO; + }; + + [_remoteService + fullDuplexCallWithRequestsWriter:requestsBuffers[0] + eventHandler:^(BOOL done, + RMTStreamingOutputCallResponse *_Nullable response, + NSError *_Nullable error) { + if (handler(0, done, response, error)) { + [expectRemote fulfill]; + } + }]; + [_remoteCronetService + fullDuplexCallWithRequestsWriter:requestsBuffers[1] + eventHandler:^(BOOL done, + RMTStreamingOutputCallResponse *_Nullable response, + NSError *_Nullable error) { + if (handler(1, done, response, error)) { + [expectCronetRemote fulfill]; + } + }]; + [_localCleartextService + fullDuplexCallWithRequestsWriter:requestsBuffers[2] + eventHandler:^(BOOL done, + RMTStreamingOutputCallResponse *_Nullable response, + NSError *_Nullable error) { + if (handler(2, done, response, error)) { + [expectCleartext fulfill]; + } + }]; + [_localSSLService + fullDuplexCallWithRequestsWriter:requestsBuffers[3] + eventHandler:^(BOOL done, + RMTStreamingOutputCallResponse *_Nullable response, + NSError *_Nullable error) { + if (handler(3, done, response, error)) { + [expectSSL fulfill]; + } + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +@end diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTestsRemote.m index e5738aac73b..516a1f432a5 100644 --- a/src/objective-c/tests/InteropTestsRemote.m +++ b/src/objective-c/tests/InteropTestsRemote.m @@ -41,8 +41,26 @@ static int32_t kRemoteInteropServerOverhead = 12; return kRemoteSSLHost; } ++ (NSString *)pemRootCert { + return nil; +} + ++ (NSString *)hostNameOverride { + return nil; +} + - (int32_t)encodingOverhead { return kRemoteInteropServerOverhead; // bytes } +#ifdef GRPC_COMPILE_WITH_CRONET ++ (GRPCTransportType)transportType { + return GRPCTransportTypeCronet; +} +#else ++ (GRPCTransportType)transportType { + return GRPCTransportTypeDefault; +} +#endif + @end diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 5d2f1340daa..e87aba235ad 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -14,6 +14,8 @@ GRPC_LOCAL_SRC = '../../..' InteropTestsLocalSSL InteropTestsLocalCleartext InteropTestsRemoteWithCronet + InteropTestsMultipleChannels + InteropTestsCallOptions UnitTests ).each do |target_name| target target_name do @@ -30,7 +32,7 @@ GRPC_LOCAL_SRC = '../../..' pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true - if target_name == 'InteropTestsRemoteWithCronet' + if target_name == 'InteropTestsRemoteWithCronet' or target_name == 'InteropTestsMultipleChannels' pod 'gRPC-Core/Cronet-Implementation', :path => GRPC_LOCAL_SRC pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" end @@ -72,6 +74,12 @@ end end end +target 'ChannelTests' do + pod 'gRPC', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core', :path => GRPC_LOCAL_SRC + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true +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. diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index f0d81232635..104fd0a4ea0 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -11,14 +11,23 @@ 09B76D9585ACE7403804D9DC /* libPods-InteropTestsRemoteWithCronet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */; }; 0F9232F984C08643FD40C34F /* libPods-InteropTestsRemote.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */; }; 16A9E77B6E336B3C0B9BA6E0 /* libPods-InteropTestsLocalSSL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */; }; + 1A0FB7F8C95A2F82538BC950 /* libPods-ChannelTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 48F1841C9A920626995DC28C /* libPods-ChannelTests.a */; }; 20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */; }; 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; 5E0282E9215AA697007AC99D /* UnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* UnitTests.m */; }; 5E0282EB215AA697007AC99D /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5E7D71AD210954A8001EA6BA /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; + 5E7D71B5210B9EC9001EA6BA /* InteropTestsCallOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */; }; + 5E7D71B7210B9EC9001EA6BA /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm */; }; 5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; 5EAD6D271E27047400002378 /* CronetUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EAD6D261E27047400002378 /* CronetUnitTests.m */; }; 5EAD6D291E27047400002378 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5EB2A2E72107DED300EB4B69 /* ChannelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB2A2E62107DED300EB4B69 /* ChannelTests.m */; }; + 5EB2A2E92107DED300EB4B69 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5EB2A2F82109284500EB4B69 /* InteropTestsMultipleChannels.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB2A2F72109284500EB4B69 /* InteropTestsMultipleChannels.m */; }; + 5EB2A2FA2109284500EB4B69 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5EB5C3AA21656CEA00ADC300 /* ChannelPoolTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB5C3A921656CEA00ADC300 /* ChannelPoolTest.m */; }; 5EC5E42B2081782C000EF4AD /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; }; 5EC5E42C20817832000EF4AD /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; 5EC5E43B208185A7000EF4AD /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; }; @@ -53,6 +62,8 @@ 63DC84501BE153AA000708E8 /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; }; 63E240CE1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; }; 63E240D01B6C63DC005F3B0E /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; + 6C1A3F81CCF7C998B4813EFD /* libPods-InteropTestsCallOptions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */; }; + 886717A79EFF774F356798E6 /* libPods-InteropTestsMultipleChannels.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */; }; 91D4B3C85B6D8562F409CB48 /* libPods-InteropTestsLocalSSLCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */; }; BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */; }; C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */; }; @@ -68,6 +79,13 @@ remoteGlobalIDString = 635697C61B14FC11007A7283; remoteInfo = Tests; }; + 5E7D71B8210B9EC9001EA6BA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 635697BF1B14FC11007A7283 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 635697C61B14FC11007A7283; + remoteInfo = Tests; + }; 5E8A5DAA1D3840B4000F8BC4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 635697BF1B14FC11007A7283 /* Project object */; @@ -82,6 +100,20 @@ remoteGlobalIDString = 635697C61B14FC11007A7283; remoteInfo = Tests; }; + 5EB2A2EA2107DED300EB4B69 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 635697BF1B14FC11007A7283 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 635697C61B14FC11007A7283; + remoteInfo = Tests; + }; + 5EB2A2FB2109284500EB4B69 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 635697BF1B14FC11007A7283 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 635697C61B14FC11007A7283; + remoteInfo = Tests; + }; 5EE84BF71D4717E40050C6CC /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 635697BF1B14FC11007A7283 /* Project object */; @@ -144,20 +176,26 @@ 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartextCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.debug.xcconfig"; sourceTree = ""; }; + 1295CCBD1082B4A7CFCED95F /* Pods-InteropTestsMultipleChannels.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.cronet.xcconfig"; sourceTree = ""; }; 14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.cronet.xcconfig"; sourceTree = ""; }; 1588C85DEAF7FC0ACDEA4C02 /* Pods-InteropTestsLocalCleartext.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.test.xcconfig"; sourceTree = ""; }; 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; sourceTree = ""; }; 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-UnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2650FEF00956E7924772F9D9 /* Pods-InteropTestsMultipleChannels.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.release.xcconfig"; sourceTree = ""; }; 2B89F3037963E6EDDD48D8C3 /* Pods-InteropTestsRemoteWithCronet.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.test.xcconfig"; sourceTree = ""; }; 303F4A17EB1650FC44603D17 /* Pods-InteropTestsRemoteCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.release.xcconfig"; sourceTree = ""; }; 32748C4078AEB05F8F954361 /* Pods-InteropTestsRemoteCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.debug.xcconfig"; sourceTree = ""; }; + 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsMultipleChannels.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 386712AEACF7C2190C4B8B3F /* Pods-CronetUnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.cronet.xcconfig"; sourceTree = ""; }; + 3A98DF08852F60AF1D96481D /* Pods-InteropTestsCallOptions.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.debug.xcconfig"; sourceTree = ""; }; 3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.release.xcconfig"; sourceTree = ""; }; + 3CADF86203B9D03EA96C359D /* Pods-InteropTestsMultipleChannels.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.debug.xcconfig"; sourceTree = ""; }; 3EB55EF291706E3DDE23C3B7 /* Pods-InteropTestsLocalSSLCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.debug.xcconfig"; sourceTree = ""; }; 3F27B2E744482771EB93C394 /* Pods-InteropTestsRemoteWithCronet.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.cronet.xcconfig"; sourceTree = ""; }; 41AA59529240A6BBBD3DB904 /* Pods-InteropTestsLocalSSLCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.test.xcconfig"; sourceTree = ""; }; + 48F1841C9A920626995DC28C /* libPods-ChannelTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ChannelTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 4A1A42B2E941CCD453489E5B /* Pods-InteropTestsRemoteCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.cronet.xcconfig"; sourceTree = ""; }; 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.release.xcconfig"; sourceTree = ""; }; 4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.cronet.xcconfig"; sourceTree = ""; }; @@ -169,6 +207,9 @@ 5E0282E6215AA697007AC99D /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E0282E8215AA697007AC99D /* UnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UnitTests.m; sourceTree = ""; }; 5E0282EA215AA697007AC99D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsCallOptions.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsCallOptions.m; sourceTree = ""; }; + 5E7D71B6210B9EC9001EA6BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CoreCronetEnd2EndTests.mm; sourceTree = ""; }; 5EA908CF4CDA4CE218352A06 /* Pods-InteropTestsLocalSSLCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.release.xcconfig"; sourceTree = ""; }; @@ -176,6 +217,13 @@ 5EAD6D261E27047400002378 /* CronetUnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CronetUnitTests.m; sourceTree = ""; }; 5EAD6D281E27047400002378 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5EAFE8271F8EFB87007F2189 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = ""; }; + 5EB2A2E42107DED300EB4B69 /* ChannelTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ChannelTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EB2A2E62107DED300EB4B69 /* ChannelTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChannelTests.m; sourceTree = ""; }; + 5EB2A2E82107DED300EB4B69 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsMultipleChannels.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EB2A2F72109284500EB4B69 /* InteropTestsMultipleChannels.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsMultipleChannels.m; sourceTree = ""; }; + 5EB2A2F92109284500EB4B69 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5EB5C3A921656CEA00ADC300 /* ChannelPoolTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChannelPoolTest.m; sourceTree = ""; }; 5EC5E421208177CC000EF4AD /* InteropTestsRemoteCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsRemoteCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5EC5E4312081856B000EF4AD /* InteropTestsLocalCleartextCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalCleartextCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5EC5E442208185CE000EF4AD /* InteropTestsLocalSSLCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalSSLCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -200,25 +248,32 @@ 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = TestCertificates.bundle; sourceTree = ""; }; 64F68A9A6A63CC930DD30A6E /* Pods-CronetUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.debug.xcconfig"; sourceTree = ""; }; 6793C9D019CB268C5BB491A2 /* Pods-CoreCronetEnd2EndTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.test.xcconfig"; sourceTree = ""; }; + 73D2DF07027835BA0FB0B1C0 /* Pods-InteropTestsCallOptions.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.cronet.xcconfig"; sourceTree = ""; }; 781089FAE980F51F88A3BE0B /* Pods-RxLibraryUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.test.xcconfig"; sourceTree = ""; }; 79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.cronet.xcconfig"; sourceTree = ""; }; 7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.release.xcconfig"; sourceTree = ""; }; 7BA53C6D224288D5870FE6F3 /* Pods-InteropTestsLocalCleartextCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; sourceTree = ""; }; 8B498B05C6DA0818B2FA91D4 /* Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; sourceTree = ""; }; + 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.cronet.xcconfig"; sourceTree = ""; }; 943138072A9605B5B8DC1FC0 /* Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; sourceTree = ""; }; 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.test.xcconfig"; sourceTree = ""; }; 9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteWithCronet.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + A25967A0D40ED14B3287AD81 /* Pods-InteropTestsCallOptions.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.test.xcconfig"; sourceTree = ""; }; A2DCF2570BE515B62CB924CA /* Pods-UnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.debug.xcconfig"; sourceTree = ""; }; A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RxLibraryUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A6F832FCEFA6F6881E620F12 /* Pods-InteropTestsRemote.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.test.xcconfig"; sourceTree = ""; }; AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.cronet.xcconfig"; sourceTree = ""; }; AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.release.xcconfig"; sourceTree = ""; }; + AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsCallOptions.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B226619DC4E709E0FFFF94B8 /* Pods-CronetUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.test.xcconfig"; sourceTree = ""; }; B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.debug.xcconfig"; sourceTree = ""; }; + BED74BC8ABF9917C66175879 /* Pods-ChannelTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.test.xcconfig"; sourceTree = ""; }; C17F57E5BCB989AB1C2F1F25 /* Pods-InteropTestsRemoteCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.test.xcconfig"; sourceTree = ""; }; C6134277D2EB8B380862A03F /* libPods-CronetUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CronetUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + C9172F9020E8C97A470D7250 /* Pods-InteropTestsCallOptions.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.release.xcconfig"; sourceTree = ""; }; CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AllTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; D13BEC8181B8E678A1B52F54 /* Pods-InteropTestsLocalSSL.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.test.xcconfig"; sourceTree = ""; }; + D52B92A7108602F170DA8091 /* Pods-ChannelTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.release.xcconfig"; sourceTree = ""; }; DB1F4391AF69D20D38D74B67 /* Pods-AllTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.test.xcconfig"; sourceTree = ""; }; DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemote.a"; sourceTree = BUILT_PRODUCTS_DIR; }; DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalSSL.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -228,9 +283,11 @@ E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.release.xcconfig"; sourceTree = ""; }; E4FD4606D4AB8D5A314D72F0 /* Pods-InteropTestsLocalCleartextCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.test.xcconfig"; sourceTree = ""; }; E7E4D3FD76E3B745D992AF5F /* Pods-AllTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.cronet.xcconfig"; sourceTree = ""; }; + EA8B122ACDE73E3AAA0E4A19 /* Pods-InteropTestsMultipleChannels.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.test.xcconfig"; sourceTree = ""; }; EBFFEC04B514CB0D4922DC40 /* Pods-UnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.release.xcconfig"; sourceTree = ""; }; F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalSSLCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + F9E48EF5ACB1F38825171C5F /* Pods-ChannelTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.debug.xcconfig"; sourceTree = ""; }; FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CoreCronetEnd2EndTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartext.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; @@ -246,6 +303,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E7D71AF210B9EC8001EA6BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E7D71B7210B9EC9001EA6BA /* libTests.a in Frameworks */, + 6C1A3F81CCF7C998B4813EFD /* libPods-InteropTestsCallOptions.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E8A5DA11D3840B4000F8BC4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -264,6 +330,24 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5EB2A2E12107DED300EB4B69 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EB2A2E92107DED300EB4B69 /* libTests.a in Frameworks */, + 1A0FB7F8C95A2F82538BC950 /* libPods-ChannelTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EB2A2F22109284500EB4B69 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EB2A2FA2109284500EB4B69 /* libTests.a in Frameworks */, + 886717A79EFF774F356798E6 /* libPods-InteropTestsMultipleChannels.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5EC5E41E208177CC000EF4AD /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -368,6 +452,9 @@ F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */, 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */, F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */, + 48F1841C9A920626995DC28C /* libPods-ChannelTests.a */, + 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */, + AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */, 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */, ); name = Frameworks; @@ -422,6 +509,18 @@ 41AA59529240A6BBBD3DB904 /* Pods-InteropTestsLocalSSLCFStream.test.xcconfig */, 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */, 5EA908CF4CDA4CE218352A06 /* Pods-InteropTestsLocalSSLCFStream.release.xcconfig */, + F9E48EF5ACB1F38825171C5F /* Pods-ChannelTests.debug.xcconfig */, + BED74BC8ABF9917C66175879 /* Pods-ChannelTests.test.xcconfig */, + 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */, + D52B92A7108602F170DA8091 /* Pods-ChannelTests.release.xcconfig */, + 3CADF86203B9D03EA96C359D /* Pods-InteropTestsMultipleChannels.debug.xcconfig */, + EA8B122ACDE73E3AAA0E4A19 /* Pods-InteropTestsMultipleChannels.test.xcconfig */, + 1295CCBD1082B4A7CFCED95F /* Pods-InteropTestsMultipleChannels.cronet.xcconfig */, + 2650FEF00956E7924772F9D9 /* Pods-InteropTestsMultipleChannels.release.xcconfig */, + 3A98DF08852F60AF1D96481D /* Pods-InteropTestsCallOptions.debug.xcconfig */, + A25967A0D40ED14B3287AD81 /* Pods-InteropTestsCallOptions.test.xcconfig */, + 73D2DF07027835BA0FB0B1C0 /* Pods-InteropTestsCallOptions.cronet.xcconfig */, + C9172F9020E8C97A470D7250 /* Pods-InteropTestsCallOptions.release.xcconfig */, A2DCF2570BE515B62CB924CA /* Pods-UnitTests.debug.xcconfig */, 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */, E1E7660656D902104F728892 /* Pods-UnitTests.cronet.xcconfig */, @@ -439,6 +538,15 @@ path = UnitTests; sourceTree = ""; }; + 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */ = { + isa = PBXGroup; + children = ( + 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */, + 5E7D71B6210B9EC9001EA6BA /* Info.plist */, + ); + path = InteropTestsCallOptions; + sourceTree = ""; + }; 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { isa = PBXGroup; children = ( @@ -456,6 +564,25 @@ path = CronetUnitTests; sourceTree = ""; }; + 5EB2A2E52107DED300EB4B69 /* ChannelTests */ = { + isa = PBXGroup; + children = ( + 5EB5C3A921656CEA00ADC300 /* ChannelPoolTest.m */, + 5EB2A2E62107DED300EB4B69 /* ChannelTests.m */, + 5EB2A2E82107DED300EB4B69 /* Info.plist */, + ); + path = ChannelTests; + sourceTree = ""; + }; + 5EB2A2F62109284500EB4B69 /* InteropTestsMultipleChannels */ = { + isa = PBXGroup; + children = ( + 5EB2A2F72109284500EB4B69 /* InteropTestsMultipleChannels.m */, + 5EB2A2F92109284500EB4B69 /* Info.plist */, + ); + path = InteropTestsMultipleChannels; + sourceTree = ""; + }; 5EE84BF21D4717E40050C6CC /* InteropTestsRemoteWithCronet */ = { isa = PBXGroup; children = ( @@ -473,6 +600,9 @@ 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */, 5EE84BF21D4717E40050C6CC /* InteropTestsRemoteWithCronet */, 5EAD6D251E27047400002378 /* CronetUnitTests */, + 5EB2A2E52107DED300EB4B69 /* ChannelTests */, + 5EB2A2F62109284500EB4B69 /* InteropTestsMultipleChannels */, + 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */, 5E0282E7215AA697007AC99D /* UnitTests */, 635697C81B14FC11007A7283 /* Products */, 51E4650F34F854F41FF053B3 /* Pods */, @@ -495,6 +625,9 @@ 5EC5E421208177CC000EF4AD /* InteropTestsRemoteCFStream.xctest */, 5EC5E4312081856B000EF4AD /* InteropTestsLocalCleartextCFStream.xctest */, 5EC5E442208185CE000EF4AD /* InteropTestsLocalSSLCFStream.xctest */, + 5EB2A2E42107DED300EB4B69 /* ChannelTests.xctest */, + 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */, + 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */, 5E0282E6215AA697007AC99D /* UnitTests.xctest */, ); name = Products; @@ -548,6 +681,26 @@ productReference = 5E0282E6215AA697007AC99D /* UnitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */; + buildPhases = ( + 2865C6386D677998F861E183 /* [CP] Check Pods Manifest.lock */, + 5E7D71AE210B9EC8001EA6BA /* Sources */, + 5E7D71AF210B9EC8001EA6BA /* Frameworks */, + 5E7D71B0210B9EC8001EA6BA /* Resources */, + 6BA6D00B1816306453BF82D4 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5E7D71B9210B9EC9001EA6BA /* PBXTargetDependency */, + ); + name = InteropTestsCallOptions; + productName = InteropTestsCallOptions; + productReference = 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5E8A5DA31D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { isa = PBXNativeTarget; buildConfigurationList = 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */; @@ -588,6 +741,47 @@ productReference = 5EAD6D241E27047400002378 /* CronetUnitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 5EB2A2E32107DED300EB4B69 /* ChannelTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5EB2A2F02107DED300EB4B69 /* Build configuration list for PBXNativeTarget "ChannelTests" */; + buildPhases = ( + 021B3B1F545989843EBC9A4B /* [CP] Check Pods Manifest.lock */, + 5EB2A2E02107DED300EB4B69 /* Sources */, + 5EB2A2E12107DED300EB4B69 /* Frameworks */, + 5EB2A2E22107DED300EB4B69 /* Resources */, + 1EAF0CBDBFAB18D4DA64535D /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5EB2A2EB2107DED300EB4B69 /* PBXTargetDependency */, + ); + name = ChannelTests; + productName = ChannelTests; + productReference = 5EB2A2E42107DED300EB4B69 /* ChannelTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 5EB2A2F42109284500EB4B69 /* InteropTestsMultipleChannels */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5EB2A3012109284500EB4B69 /* Build configuration list for PBXNativeTarget "InteropTestsMultipleChannels" */; + buildPhases = ( + 8C1ED025E07C4D457C355336 /* [CP] Check Pods Manifest.lock */, + 5EB2A2F12109284500EB4B69 /* Sources */, + 5EB2A2F22109284500EB4B69 /* Frameworks */, + 5EB2A2F32109284500EB4B69 /* Resources */, + 8D685CB612835DB3F7A6F14A /* [CP] Embed Pods Frameworks */, + 0617B5294978A95BEBBFF733 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5EB2A2FC2109284500EB4B69 /* PBXTargetDependency */, + ); + name = InteropTestsMultipleChannels; + productName = InteropTestsMultipleChannels; + productReference = 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5EC5E420208177CC000EF4AD /* InteropTestsRemoteCFStream */ = { isa = PBXNativeTarget; buildConfigurationList = 5EC5E42A208177CD000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsRemoteCFStream" */; @@ -796,12 +990,24 @@ CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; }; + 5E7D71B1210B9EC8001EA6BA = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; + }; 5E8A5DA31D3840B4000F8BC4 = { CreatedOnToolsVersion = 7.3.1; }; 5EAD6D231E27047400002378 = { CreatedOnToolsVersion = 7.3.1; }; + 5EB2A2E32107DED300EB4B69 = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; + }; + 5EB2A2F42109284500EB4B69 = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; + }; 5EC5E420208177CC000EF4AD = { CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; @@ -861,6 +1067,9 @@ 5EC5E420208177CC000EF4AD /* InteropTestsRemoteCFStream */, 5EC5E4302081856B000EF4AD /* InteropTestsLocalCleartextCFStream */, 5EC5E441208185CE000EF4AD /* InteropTestsLocalSSLCFStream */, + 5EB2A2E32107DED300EB4B69 /* ChannelTests */, + 5EB2A2F42109284500EB4B69 /* InteropTestsMultipleChannels */, + 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */, 5E0282E5215AA697007AC99D /* UnitTests */, ); }; @@ -874,6 +1083,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E7D71B0210B9EC8001EA6BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E8A5DA21D3840B4000F8BC4 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -888,6 +1104,21 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5EB2A2E22107DED300EB4B69 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EB2A2F32109284500EB4B69 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E7D71AD210954A8001EA6BA /* TestCertificates.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5EC5E41F208177CC000EF4AD /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -957,6 +1188,60 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 021B3B1F545989843EBC9A4B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ChannelTests-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; + }; + 0617B5294978A95BEBBFF733 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 1EAF0CBDBFAB18D4DA64535D /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 252A376345E38FD452A89C3D /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -975,6 +1260,24 @@ 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; }; + 2865C6386D677998F861E183 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-InteropTestsCallOptions-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; + }; 31F8D1C407195CBF0C02929B /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1083,6 +1386,24 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 6BA6D00B1816306453BF82D4 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1137,6 +1458,42 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 8C1ED025E07C4D457C355336 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-InteropTestsMultipleChannels-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; + }; + 8D685CB612835DB3F7A6F14A /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-frameworks.sh", + "${PODS_ROOT}/CronetFramework/Cronet.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 914ADDD7106BA9BB8A7E569F /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1418,6 +1775,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E7D71AE210B9EC8001EA6BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E7D71B5210B9EC9001EA6BA /* InteropTestsCallOptions.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E8A5DA01D3840B4000F8BC4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1434,6 +1799,23 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5EB2A2E02107DED300EB4B69 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EB2A2E72107DED300EB4B69 /* ChannelTests.m in Sources */, + 5EB5C3AA21656CEA00ADC300 /* ChannelPoolTest.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EB2A2F12109284500EB4B69 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EB2A2F82109284500EB4B69 /* InteropTestsMultipleChannels.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5EC5E41D208177CC000EF4AD /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1536,6 +1918,11 @@ target = 635697C61B14FC11007A7283 /* Tests */; targetProxy = 5E0282EC215AA697007AC99D /* PBXContainerItemProxy */; }; + 5E7D71B9210B9EC9001EA6BA /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 635697C61B14FC11007A7283 /* Tests */; + targetProxy = 5E7D71B8210B9EC9001EA6BA /* PBXContainerItemProxy */; + }; 5E8A5DAB1D3840B4000F8BC4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 635697C61B14FC11007A7283 /* Tests */; @@ -1546,6 +1933,16 @@ target = 635697C61B14FC11007A7283 /* Tests */; targetProxy = 5EAD6D2A1E27047400002378 /* PBXContainerItemProxy */; }; + 5EB2A2EB2107DED300EB4B69 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 635697C61B14FC11007A7283 /* Tests */; + targetProxy = 5EB2A2EA2107DED300EB4B69 /* PBXContainerItemProxy */; + }; + 5EB2A2FC2109284500EB4B69 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 635697C61B14FC11007A7283 /* Tests */; + targetProxy = 5EB2A2FB2109284500EB4B69 /* PBXContainerItemProxy */; + }; 5EE84BF81D4717E40050C6CC /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 635697C61B14FC11007A7283 /* Tests */; @@ -1909,6 +2306,136 @@ }; name = Test; }; + 5E7D71BB210B9EC9001EA6BA /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3A98DF08852F60AF1D96481D /* Pods-InteropTestsCallOptions.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5E7D71BC210B9EC9001EA6BA /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A25967A0D40ED14B3287AD81 /* Pods-InteropTestsCallOptions.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5E7D71BD210B9EC9001EA6BA /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 73D2DF07027835BA0FB0B1C0 /* Pods-InteropTestsCallOptions.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5E7D71BE210B9EC9001EA6BA /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C9172F9020E8C97A470D7250 /* Pods-InteropTestsCallOptions.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 5E8A5DAC1D3840B4000F8BC4 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */; @@ -2011,6 +2538,266 @@ }; name = Release; }; + 5EB2A2EC2107DED300EB4B69 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F9E48EF5ACB1F38825171C5F /* Pods-ChannelTests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ChannelTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5EB2A2ED2107DED300EB4B69 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BED74BC8ABF9917C66175879 /* Pods-ChannelTests.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ChannelTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5EB2A2EE2107DED300EB4B69 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ChannelTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5EB2A2EF2107DED300EB4B69 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D52B92A7108602F170DA8091 /* Pods-ChannelTests.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ChannelTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 5EB2A2FD2109284500EB4B69 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3CADF86203B9D03EA96C359D /* Pods-InteropTestsMultipleChannels.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5EB2A2FE2109284500EB4B69 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EA8B122ACDE73E3AAA0E4A19 /* Pods-InteropTestsMultipleChannels.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5EB2A2FF2109284500EB4B69 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1295CCBD1082B4A7CFCED95F /* Pods-InteropTestsMultipleChannels.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5EB2A3002109284500EB4B69 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2650FEF00956E7924772F9D9 /* Pods-InteropTestsMultipleChannels.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 5EC3C7A01D4FC18C000330E2 /* Cronet */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2039,6 +2826,8 @@ "DEBUG=1", "$(inherited)", "HOST_PORT_REMOTE=$(HOST_PORT_REMOTE)", + "HOST_PORT_LOCALSSL=$(HOST_PORT_LOCALSSL)", + "HOST_PORT_LOCAL=$(HOST_PORT_LOCAL)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_TREAT_WARNINGS_AS_ERRORS = YES; @@ -2859,6 +3648,17 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E7D71BB210B9EC9001EA6BA /* Debug */, + 5E7D71BC210B9EC9001EA6BA /* Test */, + 5E7D71BD210B9EC9001EA6BA /* Cronet */, + 5E7D71BE210B9EC9001EA6BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -2881,6 +3681,28 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 5EB2A2F02107DED300EB4B69 /* Build configuration list for PBXNativeTarget "ChannelTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EB2A2EC2107DED300EB4B69 /* Debug */, + 5EB2A2ED2107DED300EB4B69 /* Test */, + 5EB2A2EE2107DED300EB4B69 /* Cronet */, + 5EB2A2EF2107DED300EB4B69 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5EB2A3012109284500EB4B69 /* Build configuration list for PBXNativeTarget "InteropTestsMultipleChannels" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EB2A2FD2109284500EB4B69 /* Debug */, + 5EB2A2FE2109284500EB4B69 /* Test */, + 5EB2A2FF2109284500EB4B69 /* Cronet */, + 5EB2A3002109284500EB4B69 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5EC5E42A208177CD000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsRemoteCFStream" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme new file mode 100644 index 00000000000..16ae481123b --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsCallOptions.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsCallOptions.xcscheme new file mode 100644 index 00000000000..dd83282190f --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsCallOptions.xcscheme @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme index 510115fc757..11b41c92140 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme @@ -26,7 +26,6 @@ buildConfiguration = "Test" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> - - - - @@ -58,7 +51,6 @@ buildConfiguration = "Test" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme new file mode 100644 index 00000000000..1b4c1f5e51c --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme index 48837e57f9a..412bf6a0143 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme @@ -26,7 +26,6 @@ buildConfiguration = "Test" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> Date: Mon, 8 Oct 2018 15:49:17 -0700 Subject: [PATCH 0013/2143] Proto-related changes --- src/compiler/objective_c_generator.cc | 103 +++++++++++++++- src/compiler/objective_c_generator.h | 7 +- src/compiler/objective_c_plugin.cc | 21 +++- src/objective-c/ProtoRPC/ProtoRPC.h | 49 ++++++++ src/objective-c/ProtoRPC/ProtoRPC.m | 157 ++++++++++++++++++++++++ src/objective-c/ProtoRPC/ProtoService.h | 28 ++++- src/objective-c/ProtoRPC/ProtoService.m | 47 ++++++- 7 files changed, 399 insertions(+), 13 deletions(-) diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc index 39f68cb9565..eb67e9bb88f 100644 --- a/src/compiler/objective_c_generator.cc +++ b/src/compiler/objective_c_generator.cc @@ -113,6 +113,29 @@ void PrintAdvancedSignature(Printer* printer, const MethodDescriptor* method, PrintMethodSignature(printer, method, vars); } +void PrintV2Signature(Printer* printer, const MethodDescriptor* method, + map< ::grpc::string, ::grpc::string> vars) { + if (method->client_streaming()) { + vars["return_type"] = "GRPCStreamingProtoCall *"; + } else { + vars["return_type"] = "GRPCUnaryProtoCall *"; + } + vars["method_name"] = + grpc_generator::LowercaseFirstLetter(vars["method_name"]); + + PrintAllComments(method, printer); + + printer->Print(vars, "- ($return_type$)$method_name$With"); + if (method->client_streaming()) { + printer->Print("ResponseHandler:(id)handler"); + } else { + printer->Print(vars, + "Message:($request_class$ *)message " + "responseHandler:(id)handler"); + } + printer->Print(" callOptions:(GRPCCallOptions *_Nullable)callOptions"); +} + inline map< ::grpc::string, ::grpc::string> GetMethodVars( const MethodDescriptor* method) { map< ::grpc::string, ::grpc::string> res; @@ -135,6 +158,16 @@ void PrintMethodDeclarations(Printer* printer, const MethodDescriptor* method) { printer->Print(";\n\n\n"); } +void PrintV2MethodDeclarations(Printer* printer, + const MethodDescriptor* method) { + map< ::grpc::string, ::grpc::string> vars = GetMethodVars(method); + + PrintProtoRpcDeclarationAsPragma(printer, method, vars); + + PrintV2Signature(printer, method, vars); + printer->Print(";\n\n"); +} + void PrintSimpleImplementation(Printer* printer, const MethodDescriptor* method, map< ::grpc::string, ::grpc::string> vars) { printer->Print("{\n"); @@ -177,6 +210,25 @@ void PrintAdvancedImplementation(Printer* printer, printer->Print("}\n"); } +void PrintV2Implementation(Printer* printer, const MethodDescriptor* method, + map< ::grpc::string, ::grpc::string> vars) { + printer->Print(" {\n"); + if (method->client_streaming()) { + printer->Print(vars, " return [self RPCToMethod:@\"$method_name$\"\n"); + printer->Print(" responseHandler:handler\n"); + printer->Print(" callOptions:callOptions\n"); + printer->Print( + vars, " responseClass:[$response_class$ class]];\n}\n\n"); + } else { + printer->Print(vars, " return [self RPCToMethod:@\"$method_name$\"\n"); + printer->Print(" message:message\n"); + printer->Print(" responseHandler:handler\n"); + printer->Print(" callOptions:callOptions\n"); + printer->Print( + vars, " responseClass:[$response_class$ class]];\n}\n\n"); + } +} + void PrintMethodImplementations(Printer* printer, const MethodDescriptor* method) { map< ::grpc::string, ::grpc::string> vars = GetMethodVars(method); @@ -184,12 +236,16 @@ void PrintMethodImplementations(Printer* printer, PrintProtoRpcDeclarationAsPragma(printer, method, vars); // TODO(jcanizales): Print documentation from the method. + printer->Print("// Deprecated methods.\n"); PrintSimpleSignature(printer, method, vars); PrintSimpleImplementation(printer, method, vars); printer->Print("// Returns a not-yet-started RPC object.\n"); PrintAdvancedSignature(printer, method, vars); PrintAdvancedImplementation(printer, method, vars); + + PrintV2Signature(printer, method, vars); + PrintV2Implementation(printer, method, vars); } } // namespace @@ -231,6 +287,25 @@ void PrintMethodImplementations(Printer* printer, return output; } +::grpc::string GetV2Protocol(const ServiceDescriptor* service) { + ::grpc::string output; + + // Scope the output stream so it closes and finalizes output to the string. + grpc::protobuf::io::StringOutputStream output_stream(&output); + Printer printer(&output_stream, '$'); + + map< ::grpc::string, ::grpc::string> vars = { + {"service_class", ServiceClassName(service) + "2"}}; + + printer.Print(vars, "@protocol $service_class$ \n\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintV2MethodDeclarations(&printer, service->method(i)); + } + printer.Print("@end\n\n"); + + return output; +} + ::grpc::string GetInterface(const ServiceDescriptor* service) { ::grpc::string output; @@ -248,10 +323,16 @@ void PrintMethodImplementations(Printer* printer, " */\n"); printer.Print(vars, "@interface $service_class$ :" - " GRPCProtoService<$service_class$>\n"); + " GRPCProtoService<$service_class$, $service_class$2>\n"); printer.Print( - "- (instancetype)initWithHost:(NSString *)host" + "- (instancetype)initWithHost:(NSString *)host " + "callOptions:(GRPCCallOptions " + "*_Nullable)callOptions" " NS_DESIGNATED_INITIALIZER;\n"); + printer.Print("- (instancetype)initWithHost:(NSString *)host;\n"); + printer.Print( + "+ (instancetype)serviceWithHost:(NSString *)host " + "callOptions:(GRPCCallOptions *_Nullable)callOptions;\n"); printer.Print("+ (instancetype)serviceWithHost:(NSString *)host;\n"); printer.Print("@end\n"); @@ -273,11 +354,19 @@ void PrintMethodImplementations(Printer* printer, printer.Print(vars, "@implementation $service_class$\n\n" "// Designated initializer\n" - "- (instancetype)initWithHost:(NSString *)host {\n" + "- (instancetype)initWithHost:(NSString *)host " + "callOptions:(GRPCCallOptions *_Nullable)callOptions{\n" " self = [super initWithHost:host\n" " packageName:@\"$package$\"\n" - " serviceName:@\"$service_name$\"];\n" + " serviceName:@\"$service_name$\"\n" + " callOptions:callOptions];\n" " return self;\n" + "}\n\n" + "- (instancetype)initWithHost:(NSString *)host {\n" + " return [self initWithHost:host\n" + " packageName:@\"$package$\"\n" + " serviceName:@\"$service_name$\"\n" + " callOptions:nil];\n" "}\n\n"); printer.Print( @@ -292,7 +381,11 @@ void PrintMethodImplementations(Printer* printer, printer.Print( "#pragma mark - Class Methods\n\n" "+ (instancetype)serviceWithHost:(NSString *)host {\n" - " return [[self alloc] initWithHost:host];\n" + " return [self serviceWithHost:host callOptions:nil];\n" + "}\n\n" + "+ (instancetype)serviceWithHost:(NSString *)host " + "callOptions:(GRPCCallOptions *_Nullable)callOptions {\n" + " return [[self alloc] initWithHost:host callOptions:callOptions];\n" "}\n\n"); printer.Print("#pragma mark - Method Implementations\n\n"); diff --git a/src/compiler/objective_c_generator.h b/src/compiler/objective_c_generator.h index eb1c7ff005a..c171e5bf772 100644 --- a/src/compiler/objective_c_generator.h +++ b/src/compiler/objective_c_generator.h @@ -32,9 +32,14 @@ using ::grpc::string; string GetAllMessageClasses(const FileDescriptor* file); // Returns the content to be included defining the @protocol segment at the -// insertion point of the generated implementation file. +// insertion point of the generated implementation file. This interface is +// legacy and for backwards compatibility. string GetProtocol(const ServiceDescriptor* service); +// Returns the content to be included defining the @protocol segment at the +// insertion point of the generated implementation file. +string GetV2Protocol(const ServiceDescriptor* service); + // Returns the content to be included defining the @interface segment at the // insertion point of the generated implementation file. string GetInterface(const ServiceDescriptor* service); diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc index f0fe3688cca..d0ef9ed0d62 100644 --- a/src/compiler/objective_c_plugin.cc +++ b/src/compiler/objective_c_plugin.cc @@ -93,7 +93,13 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { SystemImport("RxLibrary/GRXWriteable.h") + SystemImport("RxLibrary/GRXWriter.h"); - ::grpc::string forward_declarations = "@class GRPCProtoCall;\n\n"; + ::grpc::string forward_declarations = + "@class GRPCProtoCall;\n" + "@class GRPCUnaryProtoCall;\n" + "@class GRPCStreamingProtoCall;\n" + "@class GRPCCallOptions;\n" + "@protocol GRPCResponseHandler;\n" + "\n"; ::grpc::string class_declarations = grpc_objective_c_generator::GetAllMessageClasses(file); @@ -103,6 +109,12 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { class_imports += ImportProtoHeaders(file->dependency(i), " "); } + ::grpc::string ng_protocols; + for (int i = 0; i < file->service_count(); i++) { + const grpc::protobuf::ServiceDescriptor* service = file->service(i); + ng_protocols += grpc_objective_c_generator::GetV2Protocol(service); + } + ::grpc::string protocols; for (int i = 0; i < file->service_count(); i++) { const grpc::protobuf::ServiceDescriptor* service = file->service(i); @@ -120,9 +132,10 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { PreprocIfNot(kProtocolOnly, system_imports) + "\n" + class_declarations + "\n" + PreprocIfNot(kForwardDeclare, class_imports) + "\n" + - forward_declarations + "\n" + kNonNullBegin + "\n" + protocols + - "\n" + PreprocIfNot(kProtocolOnly, interfaces) + "\n" + - kNonNullEnd + "\n"); + forward_declarations + "\n" + kNonNullBegin + "\n" + + ng_protocols + protocols + "\n" + + PreprocIfNot(kProtocolOnly, interfaces) + "\n" + kNonNullEnd + + "\n"); } { diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 45d35260921..1a27cac2a32 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -21,6 +21,55 @@ #import "ProtoMethod.h" +@class GPBMessage; + +/** A unary-request RPC call with Protobuf. */ +@interface GRPCUnaryProtoCall : NSObject + +/** + * Users should not use this initializer directly. Call objects will be created, initialized, and + * returned to users by methods of the generated service. + */ +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + message:(GPBMessage *)message + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass; + +/** Cancel the call at best effort. */ +- (void)cancel; + +@end + +/** A client-streaming RPC call with Protobuf. */ +@interface GRPCStreamingProtoCall : NSObject + +/** + * Users should not use this initializer directly. Call objects will be created, initialized, and + * returned to users by methods of the generated service. + */ +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass; + +/** Cancel the call at best effort. */ +- (void)cancel; + +/** + * Send a message to the server. The message should be a Protobuf message which will be serialized + * internally. + */ +- (void)writeWithMessage:(GPBMessage *)message; + +/** + * Finish the RPC request and half-close the call. The server may still send messages and/or + * trailers to the client. + */ +- (void)finish; + +@end + __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC : GRPCCall diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 5dca971b08a..f89c1606507 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -23,9 +23,166 @@ #else #import #endif +#import #import #import +@implementation GRPCUnaryProtoCall { + GRPCStreamingProtoCall *_call; +} + +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + message:(GPBMessage *)message + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass { + if ((self = [super init])) { + _call = [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions + responseHandler:handler + callOptions:callOptions + responseClass:responseClass]; + [_call writeWithMessage:message]; + [_call finish]; + } + return self; +} + +- (void)cancel { + [_call cancel]; + _call = nil; +} + +@end + +@interface GRPCStreamingProtoCall () + +@end + +@implementation GRPCStreamingProtoCall { + GRPCRequestOptions *_requestOptions; + id _handler; + GRPCCallOptions *_callOptions; + Class _responseClass; + + GRPCCall2 *_call; + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass { + if ((self = [super init])) { + _requestOptions = [requestOptions copy]; + _handler = handler; + _callOptions = [callOptions copy]; + _responseClass = responseClass; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + + [self start]; + } + return self; +} + +- (void)start { + _call = [[GRPCCall2 alloc] initWithRequestOptions:_requestOptions + handler:self + callOptions:_callOptions]; + [_call start]; +} + +- (void)cancel { + dispatch_async(_dispatchQueue, ^{ + if (_call) { + [_call cancel]; + _call = nil; + } + if (_handler) { + id handler = _handler; + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + }); + _handler = nil; + } + }); +} + +- (void)writeWithMessage:(GPBMessage *)message { + if (![message isKindOfClass:[GPBMessage class]]) { + [NSException raise:NSInvalidArgumentException format:@"Data must be a valid protobuf type."]; + } + + dispatch_async(_dispatchQueue, ^{ + if (_call) { + [_call writeWithData:[message data]]; + } + }); +} + +- (void)finish { + dispatch_async(_dispatchQueue, ^{ + if (_call) { + [_call finish]; + _call = nil; + } + }); +} + +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { + if (_handler) { + id handler = _handler; + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedInitialMetadata:initialMetadata]; + }); + } +} + +- (void)receivedMessage:(NSData *)message { + if (_handler) { + id handler = _handler; + NSError *error = nil; + id parsed = [_responseClass parseFromData:message error:&error]; + if (parsed) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedMessage:parsed]; + }); + } else { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:nil error:error]; + }); + handler = nil; + [_call cancel]; + _call = nil; + } + } +} + +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (_handler) { + id handler = _handler; + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:trailingMetadata error:error]; + }); + _handler = nil; + } + if (_call) { + [_call cancel]; + _call = nil; + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsingError) { NSDictionary *info = @{ NSLocalizedDescriptionKey : @"Unable to parse response from the server", diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index 29c4e9be360..2105de78a38 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -21,16 +21,40 @@ @class GRPCProtoCall; @protocol GRXWriteable; @class GRXWriter; +@class GRPCCallOptions; +@class GRPCProtoCall; +@class GRPCUnaryProtoCall; +@class GRPCStreamingProtoCall; +@protocol GRPCProtoResponseCallbacks; __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoService - : NSObject - + : NSObject + + - (instancetype)initWithHost : (NSString *)host packageName - : (NSString *)packageName serviceName : (NSString *)serviceName NS_DESIGNATED_INITIALIZER; + : (NSString *)packageName serviceName : (NSString *)serviceName callOptions + : (GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithHost:(NSString *)host + packageName:(NSString *)packageName + serviceName:(NSString *)serviceName; - (GRPCProtoCall *)RPCToMethod:(NSString *)method requestsWriter:(GRXWriter *)requestsWriter responseClass:(Class)responseClass responsesWriteable:(id)responsesWriteable; + +- (GRPCUnaryProtoCall *)RPCToMethod:(NSString *)method + message:(id)message + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass; + +- (GRPCStreamingProtoCall *)RPCToMethod:(NSString *)method + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass; + @end /** diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m index 3e9cc5c0b2d..6df502fb0c0 100644 --- a/src/objective-c/ProtoRPC/ProtoService.m +++ b/src/objective-c/ProtoRPC/ProtoService.m @@ -18,6 +18,7 @@ #import "ProtoService.h" +#import #import #import @@ -31,6 +32,7 @@ NSString *_host; NSString *_packageName; NSString *_serviceName; + GRPCCallOptions *_callOptions; } - (instancetype)init { @@ -40,7 +42,8 @@ // Designated initializer - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName - serviceName:(NSString *)serviceName { + serviceName:(NSString *)serviceName + callOptions:(GRPCCallOptions *)callOptions { if (!host || !serviceName) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor serviceName can be nil."]; @@ -49,10 +52,17 @@ _host = [host copy]; _packageName = [packageName copy]; _serviceName = [serviceName copy]; + _callOptions = [callOptions copy]; } return self; } +- (instancetype)initWithHost:(NSString *)host + packageName:(NSString *)packageName + serviceName:(NSString *)serviceName { + return [self initWithHost:host packageName:packageName serviceName:serviceName callOptions:nil]; +} + - (GRPCProtoCall *)RPCToMethod:(NSString *)method requestsWriter:(GRXWriter *)requestsWriter responseClass:(Class)responseClass @@ -65,6 +75,41 @@ responseClass:responseClass responsesWriteable:responsesWriteable]; } + +- (GRPCUnaryProtoCall *)RPCToMethod:(NSString *)method + message:(id)message + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass { + GRPCProtoMethod *methodName = + [[GRPCProtoMethod alloc] initWithPackage:_packageName service:_serviceName method:method]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:_host + path:methodName.HTTPPath + safety:GRPCCallSafetyDefault]; + return [[GRPCUnaryProtoCall alloc] initWithRequestOptions:requestOptions + message:message + responseHandler:handler + callOptions:callOptions ?: _callOptions + responseClass:responseClass]; +} + +- (GRPCStreamingProtoCall *)RPCToMethod:(NSString *)method + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass { + GRPCProtoMethod *methodName = + [[GRPCProtoMethod alloc] initWithPackage:_packageName service:_serviceName method:method]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:_host + path:methodName.HTTPPath + safety:GRPCCallSafetyDefault]; + return [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions + responseHandler:handler + callOptions:callOptions ?: _callOptions + responseClass:responseClass]; +} + @end @implementation GRPCProtoService From e2e5c8189310841f7edd5ae8a51a616c9d93b309 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 8 Oct 2018 15:50:55 -0700 Subject: [PATCH 0014/2143] New API for GRPCCall --- include/grpc/impl/codegen/grpc_types.h | 4 + src/objective-c/GRPCClient/GRPCCall.h | 155 +++++-- src/objective-c/GRPCClient/GRPCCall.m | 253 ++++++++++- src/objective-c/GRPCClient/GRPCCallOptions.h | 317 ++++++++++++++ src/objective-c/GRPCClient/GRPCCallOptions.m | 431 +++++++++++++++++++ 5 files changed, 1110 insertions(+), 50 deletions(-) create mode 100644 src/objective-c/GRPCClient/GRPCCallOptions.h create mode 100644 src/objective-c/GRPCClient/GRPCCallOptions.m diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 3ce88a82645..4cf13edca93 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -347,6 +347,10 @@ typedef struct { /** If set to non zero, surfaces the user agent string to the server. User agent is surfaced by default. */ #define GRPC_ARG_SURFACE_USER_AGENT "grpc.surface_user_agent" +/** gRPC Objective-C channel pooling domain string. */ +#define GRPC_ARG_CHANNEL_POOL_DOMAIN "grpc.channel_pooling_domain" +/** gRPC Objective-C channel pooling id. */ +#define GRPC_ARG_CHANNEL_ID "grpc.channel_id" /** \} */ /** Result of a grpc call. If the caller satisfies the prerequisites of a diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index e0ef8b1391f..3f6ec75c04e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -37,6 +37,10 @@ #include +#include "GRPCCallOptions.h" + +@class GRPCCallOptions; + #pragma mark gRPC errors /** Domain of NSError objects produced by gRPC. */ @@ -139,19 +143,6 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { GRPCErrorCodeDataLoss = 15, }; -/** - * Safety remark of a gRPC method as defined in RFC 2616 Section 9.1 - */ -typedef NS_ENUM(NSUInteger, GRPCCallSafety) { - /** Signal that there is no guarantees on how the call affects the server state. */ - GRPCCallSafetyDefault = 0, - /** Signal that the call is idempotent. gRPC is free to use PUT verb. */ - GRPCCallSafetyIdempotentRequest = 1, - /** Signal that the call is cacheable and will not affect server state. gRPC is free to use GET - verb. */ - GRPCCallSafetyCacheableRequest = 2, -}; - /** * Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by * the server. @@ -159,24 +150,118 @@ typedef NS_ENUM(NSUInteger, GRPCCallSafety) { extern id const kGRPCHeadersKey; extern id const kGRPCTrailersKey; +/** An object can implement this protocol to receive responses from server from a call. */ +@protocol GRPCResponseHandler +@optional +/** Issued when initial metadata is received from the server. */ +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata; +/** + * Issued when a message is received from the server. The message may be raw data from the server + * (when using \a GRPCCall2 directly) or deserialized proto object (when using \a ProtoRPC). + */ +- (void)receivedMessage:(id)message; +/** + * Issued when a call finished. If the call finished successfully, \a error is nil and \a + * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error + * is non-nil and contains the corresponding error information, including gRPC error codes and + * error descriptions. + */ +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error; + +/** + * All the responses must be issued to a user-provided dispatch queue. This property specifies the + * dispatch queue to be used for issuing the notifications. + */ +@property(atomic, readonly) dispatch_queue_t dispatchQueue; + +@end + +/** + * Call related parameters. These parameters are automatically specified by Protobuf. If directly + * using the \a GRPCCall2 class, users should specify these parameters manually. + */ +@interface GRPCRequestOptions : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +/** Initialize with all properties. */ +- (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety; + +/** The host serving the RPC service. */ +@property(copy, readonly) NSString *host; +/** The path to the RPC call. */ +@property(copy, readonly) NSString *path; +/** + * Specify whether the call is idempotent or cachable. gRPC may select different HTTP verbs for the + * call based on this information. + */ +@property(readonly) GRPCCallSafety safety; + +@end + #pragma mark GRPCCall -/** Represents a single gRPC remote call. */ +/** + * A \a GRPCCall2 object represents an RPC call. + */ +@interface GRPCCall2 : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Designated initializer for a call. + * \param requestOptions Protobuf generated parameters for the call. + * \param handler The object to which responses should be issed. + * \param callOptions Options for the call. + */ +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + handler:(id)handler + callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; +/** + * Convevience initializer for a call that uses default call options. + */ +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + handler:(id)handler; + +/** + * Starts the call. Can only be called once. + */ +- (void)start; + +/** + * Cancel the request of this call at best effort; notifies the server that the RPC should be + * cancelled, and issue callback to the user with an error code CANCELED if the call is not + * finished. + */ +- (void)cancel; + +/** + * Send a message to the server. Data are sent as raw bytes in gRPC message frames. + */ +- (void)writeWithData:(NSData *)data; + +/** + * Finish the RPC request and half-close the call. The server may still send messages and/or + * trailers to the client. + */ -(void)finish; + +/** + * Get a copy of the original call options. + */ +@property(readonly, copy) GRPCCallOptions *callOptions; + +/** Get a copy of the original request options. */ +@property(readonly, copy) GRPCRequestOptions *requestOptions; + +@end + +/** + * This interface is deprecated. Please use \a GRPCcall2. + * + * Represents a single gRPC remote call. + */ @interface GRPCCall : GRXWriter -/** - * The authority for the RPC. If nil, the default authority will be used. This property must be nil - * when Cronet transport is enabled. - */ -@property(atomic, copy, readwrite) NSString *serverName; - -/** - * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to - * positive, the gRPC call returns with status GRPCErrorCodeDeadlineExceeded if it is not completed - * within \a timeout seconds. A negative value is not allowed. - */ -@property NSTimeInterval timeout; - /** * The container of the request headers of an RPC conforms to this protocol, which is a subset of * NSMutableDictionary's interface. It will become a NSMutableDictionary later on. @@ -236,7 +321,7 @@ extern id const kGRPCTrailersKey; */ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path - requestsWriter:(GRXWriter *)requestsWriter NS_DESIGNATED_INITIALIZER; + requestsWriter:(GRXWriter *)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -245,21 +330,13 @@ extern id const kGRPCTrailersKey; - (void)cancel; /** - * Set the call flag for a specific host path. - * - * Host parameter should not contain the scheme (http:// or https://), only the name or IP addr - * and the port number, for example @"localhost:5050". + * The following methods are deprecated. */ + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path; - -/** - * Set the dispatch queue to be used for callbacks. - * - * This configuration is only effective before the call starts. - */ +@property(atomic, copy, readwrite) NSString *serverName; +@property NSTimeInterval timeout; - (void)setResponseDispatchQueue:(dispatch_queue_t)queue; -// TODO(jcanizales): Let specify a deadline. As a category of GRXWriter? @end #pragma mark Backwards compatibiity diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 084fbdeb491..519f91e5229 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -20,13 +20,16 @@ #import "GRPCCall+OAuth2.h" +#import #import #import +#import #include #include -#import "private/GRPCConnectivityMonitor.h" +#import "GRPCCallOptions.h" #import "private/GRPCHost.h" +#import "private/GRPCConnectivityMonitor.h" #import "private/GRPCRequestHeaders.h" #import "private/GRPCWrappedCall.h" #import "private/NSData+GRPC.h" @@ -52,6 +55,165 @@ const char *kCFStreamVarName = "grpc_cfstream"; @property(atomic, strong) NSDictionary *responseHeaders; @property(atomic, strong) NSDictionary *responseTrailers; @property(atomic) BOOL isWaitingForToken; + +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + callSafety:(GRPCCallSafety)safety + requestsWriter:(GRXWriter *)requestsWriter + callOptions:(GRPCCallOptions *)callOptions; + +@end + +@implementation GRPCRequestOptions + +- (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { + if ((self = [super init])) { + _host = host; + _path = path; + _safety = safety; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone { + GRPCRequestOptions *request = + [[GRPCRequestOptions alloc] initWithHost:[_host copy] path:[_path copy] safety:_safety]; + + return request; +} + +@end + +@implementation GRPCCall2 { + GRPCCallOptions *_callOptions; + id _handler; + + GRPCCall *_call; + BOOL _initialMetadataPublished; + GRXBufferedPipe *_pipe; + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + handler:(id)handler + callOptions:(GRPCCallOptions *)callOptions { + if (!requestOptions || !requestOptions.host || !requestOptions.path) { + [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; + } + + if ((self = [super init])) { + _requestOptions = [requestOptions copy]; + _callOptions = [callOptions copy]; + _handler = handler; + _initialMetadataPublished = NO; + _pipe = [GRXBufferedPipe pipe]; + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } + + return self; +} + +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + handler:(id)handler { + return [self initWithRequestOptions:requestOptions handler:handler callOptions:nil]; +} + +- (void)start { + dispatch_async(_dispatchQueue, ^{ + if (!self->_callOptions) { + self->_callOptions = [[GRPCCallOptions alloc] init]; + } + + self->_call = [[GRPCCall alloc] initWithHost:self->_requestOptions.host + path:self->_requestOptions.path + callSafety:self->_requestOptions.safety + requestsWriter:self->_pipe + callOptions:self->_callOptions]; + if (self->_callOptions.initialMetadata) { + [self->_call.requestHeaders addEntriesFromDictionary:self->_callOptions.initialMetadata]; + } + id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(id value) { + dispatch_async(self->_dispatchQueue, ^{ + if (self->_handler) { + id handler = self->_handler; + NSDictionary *headers = nil; + if (!self->_initialMetadataPublished) { + headers = self->_call.responseHeaders; + self->_initialMetadataPublished = YES; + } + if (headers) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedInitialMetadata:headers]; + }); + } + if (value) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedMessage:value]; + }); + } + } + }); + } + completionHandler:^(NSError *errorOrNil) { + dispatch_async(self->_dispatchQueue, ^{ + if (self->_handler) { + id handler = self->_handler; + NSDictionary *headers = nil; + if (!self->_initialMetadataPublished) { + headers = self->_call.responseHeaders; + self->_initialMetadataPublished = YES; + } + if (headers) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedInitialMetadata:headers]; + }); + } + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + }); + } + }); + }]; + [self->_call startWithWriteable:responseWriteable]; + }); +} + +- (void)cancel { + dispatch_async(_dispatchQueue, ^{ + if (self->_call) { + [self->_call cancel]; + self->_call = nil; + } + if (self->_handler) { + id handler = self->_handler; + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + }); + self->_handler = nil; + } + }); +} + +- (void)writeWithData:(NSData *)data { + dispatch_async(_dispatchQueue, ^{ + [self->_pipe writeValue:data]; + }); +} + +- (void)finish { + dispatch_async(_dispatchQueue, ^{ + if (self->_call) { + [self->_pipe writesFinishedWithError:nil]; + } + }); +} + @end // The following methods of a C gRPC call object aren't reentrant, and thus @@ -75,6 +237,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; NSString *_host; NSString *_path; + GRPCCallSafety _callSafety; + GRPCCallOptions *_callOptions; GRPCWrappedCall *_wrappedCall; GRPCConnectivityMonitor *_connectivityMonitor; @@ -113,6 +277,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Whether the call is finished. If it is, should not call finishWithError again. BOOL _finished; + + // The OAuth2 token fetched from a token provider. + NSString *_fetchedOauth2AccessToken; } @synthesize state = _state; @@ -156,6 +323,18 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithHost:(NSString *)host path:(NSString *)path requestsWriter:(GRXWriter *)requestWriter { + return [self initWithHost:host + path:path + callSafety:GRPCCallSafetyDefault + requestsWriter:requestWriter + callOptions:nil]; +} + +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + callSafety:(GRPCCallSafety)safety + requestsWriter:(GRXWriter *)requestWriter + callOptions:(GRPCCallOptions *)callOptions { if (!host || !path) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; } @@ -166,6 +345,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; if ((self = [super init])) { _host = [host copy]; _path = [path copy]; + _callSafety = safety; + _callOptions = [callOptions copy]; // Serial queue to invoke the non-reentrant methods of the grpc_call object. _callQueue = dispatch_queue_create("io.grpc.call", NULL); @@ -317,11 +498,36 @@ const char *kCFStreamVarName = "grpc_cfstream"; #pragma mark Send headers -- (void)sendHeaders:(NSDictionary *)headers { +- (void)sendHeaders { + // TODO (mxyan): Remove after deprecated methods are removed + uint32_t callSafetyFlags; + switch (_callSafety) { + case GRPCCallSafetyDefault: + callSafetyFlags = 0; + break; + case GRPCCallSafetyIdempotentRequest: + callSafetyFlags = GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; + break; + case GRPCCallSafetyCacheableRequest: + callSafetyFlags = GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; + break; + default: + [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; + } + uint32_t callFlag = callSafetyFlags; + + NSMutableDictionary *headers = _requestHeaders; + if (_fetchedOauth2AccessToken != nil) { + headers[@"authorization"] = [kBearerPrefix stringByAppendingString:_fetchedOauth2AccessToken]; + } else if (_callOptions.oauth2AccessToken != nil) { + headers[@"authorization"] = + [kBearerPrefix stringByAppendingString:_callOptions.oauth2AccessToken]; + } + // TODO(jcanizales): Add error handlers for async failures GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] initWithMetadata:headers - flags:[GRPCCall callFlagsForHost:_host path:_path] + flags:callFlag handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA if (!_unaryCall) { [_wrappedCall startBatchWithOperations:@[ op ]]; @@ -458,13 +664,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; - _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host - serverName:_serverName - path:_path - timeout:_timeout]; + _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; NSAssert(_wrappedCall, @"Error allocating RPC objects. Low memory?"); - [self sendHeaders:_requestHeaders]; + [self sendHeaders]; [self invokeCall]; // Connectivity monitor is not required for CFStream @@ -486,15 +689,43 @@ const char *kCFStreamVarName = "grpc_cfstream"; // that the life of the instance is determined by this retain cycle. _retainSelf = self; - if (self.tokenProvider != nil) { + if (_callOptions == nil) { + GRPCMutableCallOptions *callOptions; + if ([GRPCHost isHostConfigured:_host]) { + GRPCHost *hostConfig = [GRPCHost hostWithAddress:_host]; + callOptions = hostConfig.callOptions; + } else { + callOptions = [[GRPCMutableCallOptions alloc] init]; + } + if (_serverName != nil) { + callOptions.serverAuthority = _serverName; + } + if (_timeout != 0) { + callOptions.timeout = _timeout; + } + uint32_t callFlags = [GRPCCall callFlagsForHost:_host path:_path]; + if (callFlags != 0) { + if (callFlags == GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) { + _callSafety = GRPCCallSafetyIdempotentRequest; + } else if (callFlags == GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) { + _callSafety = GRPCCallSafetyCacheableRequest; + } + } + + id tokenProvider = self.tokenProvider; + if (tokenProvider != nil) { + callOptions.authTokenProvider = tokenProvider; + } + _callOptions = callOptions; + } + if (_callOptions.authTokenProvider != nil) { self.isWaitingForToken = YES; __weak typeof(self) weakSelf = self; [self.tokenProvider getTokenWithHandler:^(NSString *token) { typeof(self) strongSelf = weakSelf; if (strongSelf && strongSelf.isWaitingForToken) { if (token) { - NSString *t = [kBearerPrefix stringByAppendingString:token]; - strongSelf.requestHeaders[kAuthorizationHeader] = t; + strongSelf->_fetchedOauth2AccessToken = token; } [strongSelf startCallWithWriteable:writeable]; strongSelf.isWaitingForToken = NO; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h new file mode 100644 index 00000000000..75b320ca6d6 --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -0,0 +1,317 @@ +/* + * + * 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. + * + */ + +#import + +/** + * Safety remark of a gRPC method as defined in RFC 2616 Section 9.1 + */ +typedef NS_ENUM(NSUInteger, GRPCCallSafety) { + /** Signal that there is no guarantees on how the call affects the server state. */ + GRPCCallSafetyDefault = 0, + /** Signal that the call is idempotent. gRPC is free to use PUT verb. */ + GRPCCallSafetyIdempotentRequest = 1, + /** Signal that the call is cacheable and will not affect server state. gRPC is free to use GET + verb. */ + GRPCCallSafetyCacheableRequest = 2, +}; + +// Compression algorithm to be used by a gRPC call +typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) { + GRPCCompressNone = 0, + GRPCCompressDeflate, + GRPCCompressGzip, + GRPCStreamCompressGzip, +}; + +// The transport to be used by a gRPC call +typedef NS_ENUM(NSInteger, GRPCTransportType) { + // gRPC internal HTTP/2 stack with BoringSSL + GRPCTransportTypeDefault = 0, + // Cronet stack + GRPCTransportTypeCronet, + // Insecure channel. FOR TEST ONLY! + GRPCTransportTypeInsecure, +}; + +@protocol GRPCAuthorizationProtocol +- (void)getTokenWithHandler:(void (^)(NSString *token))hander; +@end + +@interface GRPCCallOptions : NSObject + +// Call parameters +/** + * The authority for the RPC. If nil, the default authority will be used. + * + * Note: This property must be nil when Cronet transport is enabled. + * Note: This property cannot be used to validate a self-signed server certificate. It control the + * :authority header field of the call and performs an extra check that server's certificate + * matches the :authority header. + */ +@property(readonly) NSString *serverAuthority; + +/** + * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to + * positive, the gRPC call returns with status GRPCErrorCodeDeadlineExceeded if it is not completed + * within \a timeout seconds. A negative value is not allowed. + */ +@property(readonly) NSTimeInterval timeout; + +// OAuth2 parameters. Users of gRPC may specify one of the following two parameters. + +/** + * The OAuth2 access token string. The string is prefixed with "Bearer " then used as value of the + * request's "authorization" header field. This parameter should not be used simultaneously with + * \a authTokenProvider. + */ +@property(copy, readonly) NSString *oauth2AccessToken; + +/** + * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when + * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. + */ +@property(readonly) id authTokenProvider; + +/** + * Initial metadata key-value pairs that should be included in the request. + */ +@property(copy, readwrite) NSDictionary *initialMetadata; + +// Channel parameters; take into account of channel signature. + +/** + * Custom string that is prefixed to a request's user-agent header field before gRPC's internal + * user-agent string. + */ +@property(copy, readonly) NSString *userAgentPrefix; + +/** + * The size limit for the response received from server. If it is exceeded, an error with status + * code GRPCErrorCodeResourceExhausted is returned. + */ +@property(readonly) NSUInteger responseSizeLimit; + +/** + * The compression algorithm to be used by the gRPC call. For more details refer to + * https://github.com/grpc/grpc/blob/master/doc/compression.md + */ +@property(readonly) GRPCCompressAlgorithm compressAlgorithm; + +/** + * Enable/Disable gRPC call's retry feature. The default is enabled. For details of this feature + * refer to + * https://github.com/grpc/proposal/blob/master/A6-client-retries.md + */ +@property(readonly) BOOL enableRetry; + +/** + * HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two + * PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the + * call should wait for PING ACK. If PING ACK is not received after this period, the call fails. + */ +@property(readonly) NSTimeInterval keepaliveInterval; +@property(readonly) NSTimeInterval keepaliveTimeout; + +// Parameters for connection backoff. For details of gRPC's backoff behavior, refer to +// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md +@property(readonly) NSTimeInterval connectMinTimeout; +@property(readonly) NSTimeInterval connectInitialBackoff; +@property(readonly) NSTimeInterval connectMaxBackoff; + +/** + * Specify channel args to be used for this call. For a list of channel args available, see + * grpc/grpc_types.h + */ +@property(copy, readonly) NSDictionary *additionalChannelArgs; + +// Parameters for SSL authentication. + +/** + * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default + * root certificates. + */ +@property(copy, readonly) NSString *pemRootCert; + +/** + * PEM format private key for client authentication, if required by the server. + */ +@property(copy, readonly) NSString *pemPrivateKey; + +/** + * PEM format certificate chain for client authentication, if required by the server. + */ +@property(copy, readonly) NSString *pemCertChain; + +/** + * Select the transport type to be used for this call. + */ +@property(readonly) GRPCTransportType transportType; + +/** + * Override the hostname during the TLS hostname validation process. + */ +@property(copy, readonly) NSString *hostNameOverride; + +/** + * Parameter used for internal logging. + */ +@property(readonly) id logContext; + +/** + * A string that specify the domain where channel is being cached. Channels with different domains + * will not get cached to the same connection. + */ +@property(copy, readonly) NSString *channelPoolDomain; + +/** + * Channel id allows a call to force creating a new channel (connection) rather than using a cached + * channel. Calls using distinct channelId will not get cached to the same connection. + */ +@property(readonly) NSUInteger channelId; + +@end + +@interface GRPCMutableCallOptions : GRPCCallOptions + +// Call parameters +/** + * The authority for the RPC. If nil, the default authority will be used. + * + * Note: This property must be nil when Cronet transport is enabled. + * Note: This property cannot be used to validate a self-signed server certificate. It control the + * :authority header field of the call and performs an extra check that server's certificate + * matches the :authority header. + */ +@property(readwrite) NSString *serverAuthority; + +/** + * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to + * positive, the gRPC call returns with status GRPCErrorCodeDeadlineExceeded if it is not completed + * within \a timeout seconds. A negative value is not allowed. + */ +@property(readwrite) NSTimeInterval timeout; + +// OAuth2 parameters. Users of gRPC may specify one of the following two parameters. + +/** + * The OAuth2 access token string. The string is prefixed with "Bearer " then used as value of the + * request's "authorization" header field. This parameter should not be used simultaneously with + * \a authTokenProvider. + */ +@property(copy, readwrite) NSString *oauth2AccessToken; + +/** + * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when + * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. + */ +@property(readwrite) id authTokenProvider; + +// Channel parameters; take into account of channel signature. + +/** + * Custom string that is prefixed to a request's user-agent header field before gRPC's internal + * user-agent string. + */ +@property(copy, readwrite) NSString *userAgentPrefix; + +/** + * The size limit for the response received from server. If it is exceeded, an error with status + * code GRPCErrorCodeResourceExhausted is returned. + */ +@property(readwrite) NSUInteger responseSizeLimit; + +/** + * The compression algorithm to be used by the gRPC call. For more details refer to + * https://github.com/grpc/grpc/blob/master/doc/compression.md + */ +@property(readwrite) GRPCCompressAlgorithm compressAlgorithm; + +/** + * Enable/Disable gRPC call's retry feature. The default is enabled. For details of this feature + * refer to + * https://github.com/grpc/proposal/blob/master/A6-client-retries.md + */ +@property(readwrite) BOOL enableRetry; + +/** + * HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two + * PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the + * call should wait for PING ACK. If PING ACK is not received after this period, the call fails. + */ +@property(readwrite) NSTimeInterval keepaliveInterval; +@property(readwrite) NSTimeInterval keepaliveTimeout; + +// Parameters for connection backoff. For details of gRPC's backoff behavior, refer to +// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md +@property(readwrite) NSTimeInterval connectMinTimeout; +@property(readwrite) NSTimeInterval connectInitialBackoff; +@property(readwrite) NSTimeInterval connectMaxBackoff; + +/** + * Specify channel args to be used for this call. For a list of channel args available, see + * grpc/grpc_types.h + */ +@property(copy, readwrite) NSDictionary *additionalChannelArgs; + +// Parameters for SSL authentication. + +/** + * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default + * root certificates. + */ +@property(copy, readwrite) NSString *pemRootCert; + +/** + * PEM format private key for client authentication, if required by the server. + */ +@property(copy, readwrite) NSString *pemPrivateKey; + +/** + * PEM format certificate chain for client authentication, if required by the server. + */ +@property(copy, readwrite) NSString *pemCertChain; + +/** + * Select the transport type to be used for this call. + */ +@property(readwrite) GRPCTransportType transportType; + +/** + * Override the hostname during the TLS hostname validation process. + */ +@property(copy, readwrite) NSString *hostNameOverride; + +/** + * Parameter used for internal logging. + */ +@property(copy, readwrite) id logContext; + +/** + * A string that specify the domain where channel is being cached. Channels with different domains + * will not get cached to the same connection. + */ +@property(copy, readwrite) NSString *channelPoolDomain; + +/** + * Channel id allows a call to force creating a new channel (connection) rather than using a cached + * channel. Calls using distinct channelId will not get cached to the same connection. + */ +@property(readwrite) NSUInteger channelId; + +@end diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m new file mode 100644 index 00000000000..ee76c2a6420 --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -0,0 +1,431 @@ +/* + * + * 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. + * + */ + +#import "GRPCCallOptions.h" + +static NSString *const kDefaultServerAuthority = nil; +static const NSTimeInterval kDefaultTimeout = 0; +static NSDictionary *const kDefaultInitialMetadata = nil; +static NSString *const kDefaultUserAgentPrefix = nil; +static const NSUInteger kDefaultResponseSizeLimit = 0; +static const GRPCCompressAlgorithm kDefaultCompressAlgorithm = GRPCCompressNone; +static const BOOL kDefaultEnableRetry = YES; +static const NSTimeInterval kDefaultKeepaliveInterval = 0; +static const NSTimeInterval kDefaultKeepaliveTimeout = 0; +static const NSTimeInterval kDefaultConnectMinTimeout = 0; +static const NSTimeInterval kDefaultConnectInitialBackoff = 0; +static const NSTimeInterval kDefaultConnectMaxBackoff = 0; +static NSDictionary *const kDefaultAdditionalChannelArgs = nil; +static NSString *const kDefaultPemRootCert = nil; +static NSString *const kDefaultPemPrivateKey = nil; +static NSString *const kDefaultPemCertChain = nil; +static NSString *const kDefaultOauth2AccessToken = nil; +static const id kDefaultAuthTokenProvider = nil; +static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeDefault; +static NSString *const kDefaultHostNameOverride = nil; +static const id kDefaultLogContext = nil; +static NSString *kDefaultChannelPoolDomain = nil; +static NSUInteger kDefaultChannelId = 0; + +@implementation GRPCCallOptions { + @protected + NSString *_serverAuthority; + NSTimeInterval _timeout; + NSString *_oauth2AccessToken; + id _authTokenProvider; + NSDictionary *_initialMetadata; + NSString *_userAgentPrefix; + NSUInteger _responseSizeLimit; + GRPCCompressAlgorithm _compressAlgorithm; + BOOL _enableRetry; + NSTimeInterval _keepaliveInterval; + NSTimeInterval _keepaliveTimeout; + NSTimeInterval _connectMinTimeout; + NSTimeInterval _connectInitialBackoff; + NSTimeInterval _connectMaxBackoff; + NSDictionary *_additionalChannelArgs; + NSString *_pemRootCert; + NSString *_pemPrivateKey; + NSString *_pemCertChain; + GRPCTransportType _transportType; + NSString *_hostNameOverride; + id _logContext; + NSString *_channelPoolDomain; + NSUInteger _channelId; +} + +@synthesize serverAuthority = _serverAuthority; +@synthesize timeout = _timeout; +@synthesize oauth2AccessToken = _oauth2AccessToken; +@synthesize authTokenProvider = _authTokenProvider; +@synthesize initialMetadata = _initialMetadata; +@synthesize userAgentPrefix = _userAgentPrefix; +@synthesize responseSizeLimit = _responseSizeLimit; +@synthesize compressAlgorithm = _compressAlgorithm; +@synthesize enableRetry = _enableRetry; +@synthesize keepaliveInterval = _keepaliveInterval; +@synthesize keepaliveTimeout = _keepaliveTimeout; +@synthesize connectMinTimeout = _connectMinTimeout; +@synthesize connectInitialBackoff = _connectInitialBackoff; +@synthesize connectMaxBackoff = _connectMaxBackoff; +@synthesize additionalChannelArgs = _additionalChannelArgs; +@synthesize pemRootCert = _pemRootCert; +@synthesize pemPrivateKey = _pemPrivateKey; +@synthesize pemCertChain = _pemCertChain; +@synthesize transportType = _transportType; +@synthesize hostNameOverride = _hostNameOverride; +@synthesize logContext = _logContext; +@synthesize channelPoolDomain = _channelPoolDomain; +@synthesize channelId = _channelId; + +- (instancetype)init { + return [self initWithServerAuthority:kDefaultServerAuthority + timeout:kDefaultTimeout + oauth2AccessToken:kDefaultOauth2AccessToken + authTokenProvider:kDefaultAuthTokenProvider + initialMetadata:kDefaultInitialMetadata + userAgentPrefix:kDefaultUserAgentPrefix + responseSizeLimit:kDefaultResponseSizeLimit + compressAlgorithm:kDefaultCompressAlgorithm + enableRetry:kDefaultEnableRetry + keepaliveInterval:kDefaultKeepaliveInterval + keepaliveTimeout:kDefaultKeepaliveTimeout + connectMinTimeout:kDefaultConnectMinTimeout + connectInitialBackoff:kDefaultConnectInitialBackoff + connectMaxBackoff:kDefaultConnectMaxBackoff + additionalChannelArgs:kDefaultAdditionalChannelArgs + pemRootCert:kDefaultPemRootCert + pemPrivateKey:kDefaultPemPrivateKey + pemCertChain:kDefaultPemCertChain + transportType:kDefaultTransportType + hostNameOverride:kDefaultHostNameOverride + logContext:kDefaultLogContext + channelPoolDomain:kDefaultChannelPoolDomain + channelId:kDefaultChannelId]; +} + +- (instancetype)initWithServerAuthority:(NSString *)serverAuthority + timeout:(NSTimeInterval)timeout + oauth2AccessToken:(NSString *)oauth2AccessToken + authTokenProvider:(id)authTokenProvider + initialMetadata:(NSDictionary *)initialMetadata + userAgentPrefix:(NSString *)userAgentPrefix + responseSizeLimit:(NSUInteger)responseSizeLimit + compressAlgorithm:(GRPCCompressAlgorithm)compressAlgorithm + enableRetry:(BOOL)enableRetry + keepaliveInterval:(NSTimeInterval)keepaliveInterval + keepaliveTimeout:(NSTimeInterval)keepaliveTimeout + connectMinTimeout:(NSTimeInterval)connectMinTimeout + connectInitialBackoff:(NSTimeInterval)connectInitialBackoff + connectMaxBackoff:(NSTimeInterval)connectMaxBackoff + additionalChannelArgs:(NSDictionary *)additionalChannelArgs + pemRootCert:(NSString *)pemRootCert + pemPrivateKey:(NSString *)pemPrivateKey + pemCertChain:(NSString *)pemCertChain + transportType:(GRPCTransportType)transportType + hostNameOverride:(NSString *)hostNameOverride + logContext:(id)logContext + channelPoolDomain:(NSString *)channelPoolDomain + channelId:(NSUInteger)channelId { + if ((self = [super init])) { + _serverAuthority = serverAuthority; + _timeout = timeout; + _oauth2AccessToken = oauth2AccessToken; + _authTokenProvider = authTokenProvider; + _initialMetadata = initialMetadata; + _userAgentPrefix = userAgentPrefix; + _responseSizeLimit = responseSizeLimit; + _compressAlgorithm = compressAlgorithm; + _enableRetry = enableRetry; + _keepaliveInterval = keepaliveInterval; + _keepaliveTimeout = keepaliveTimeout; + _connectMinTimeout = connectMinTimeout; + _connectInitialBackoff = connectInitialBackoff; + _connectMaxBackoff = connectMaxBackoff; + _additionalChannelArgs = additionalChannelArgs; + _pemRootCert = pemRootCert; + _pemPrivateKey = pemPrivateKey; + _pemCertChain = pemCertChain; + _transportType = transportType; + _hostNameOverride = hostNameOverride; + _logContext = logContext; + _channelPoolDomain = channelPoolDomain; + _channelId = channelId; + } + return self; +} + +- (nonnull id)copyWithZone:(NSZone *)zone { + GRPCCallOptions *newOptions = + [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority + timeout:_timeout + oauth2AccessToken:_oauth2AccessToken + authTokenProvider:_authTokenProvider + initialMetadata:_initialMetadata + userAgentPrefix:_userAgentPrefix + responseSizeLimit:_responseSizeLimit + compressAlgorithm:_compressAlgorithm + enableRetry:_enableRetry + keepaliveInterval:_keepaliveInterval + keepaliveTimeout:_keepaliveTimeout + connectMinTimeout:_connectMinTimeout + connectInitialBackoff:_connectInitialBackoff + connectMaxBackoff:_connectMaxBackoff + additionalChannelArgs:[_additionalChannelArgs copy] + pemRootCert:_pemRootCert + pemPrivateKey:_pemPrivateKey + pemCertChain:_pemCertChain + transportType:_transportType + hostNameOverride:_hostNameOverride + logContext:_logContext + channelPoolDomain:_channelPoolDomain + channelId:_channelId]; + return newOptions; +} + +- (nonnull id)mutableCopyWithZone:(NSZone *)zone { + GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] + initWithServerAuthority:_serverAuthority + timeout:_timeout + oauth2AccessToken:_oauth2AccessToken + authTokenProvider:_authTokenProvider + initialMetadata:_initialMetadata + userAgentPrefix:_userAgentPrefix + responseSizeLimit:_responseSizeLimit + compressAlgorithm:_compressAlgorithm + enableRetry:_enableRetry + keepaliveInterval:_keepaliveInterval + keepaliveTimeout:_keepaliveTimeout + connectMinTimeout:_connectMinTimeout + connectInitialBackoff:_connectInitialBackoff + connectMaxBackoff:_connectMaxBackoff + additionalChannelArgs:[_additionalChannelArgs copy] + pemRootCert:_pemRootCert + pemPrivateKey:_pemPrivateKey + pemCertChain:_pemCertChain + transportType:_transportType + hostNameOverride:_hostNameOverride + logContext:_logContext + channelPoolDomain:_channelPoolDomain + channelId:_channelId]; + return newOptions; +} + +@end + +@implementation GRPCMutableCallOptions + +@dynamic serverAuthority; +@dynamic timeout; +@dynamic oauth2AccessToken; +@dynamic authTokenProvider; +@dynamic initialMetadata; +@dynamic userAgentPrefix; +@dynamic responseSizeLimit; +@dynamic compressAlgorithm; +@dynamic enableRetry; +@dynamic keepaliveInterval; +@dynamic keepaliveTimeout; +@dynamic connectMinTimeout; +@dynamic connectInitialBackoff; +@dynamic connectMaxBackoff; +@dynamic additionalChannelArgs; +@dynamic pemRootCert; +@dynamic pemPrivateKey; +@dynamic pemCertChain; +@dynamic transportType; +@dynamic hostNameOverride; +@dynamic logContext; +@dynamic channelPoolDomain; +@dynamic channelId; + +- (instancetype)init { + return [self initWithServerAuthority:kDefaultServerAuthority + timeout:kDefaultTimeout + oauth2AccessToken:kDefaultOauth2AccessToken + authTokenProvider:kDefaultAuthTokenProvider + initialMetadata:kDefaultInitialMetadata + userAgentPrefix:kDefaultUserAgentPrefix + responseSizeLimit:kDefaultResponseSizeLimit + compressAlgorithm:kDefaultCompressAlgorithm + enableRetry:kDefaultEnableRetry + keepaliveInterval:kDefaultKeepaliveInterval + keepaliveTimeout:kDefaultKeepaliveTimeout + connectMinTimeout:kDefaultConnectMinTimeout + connectInitialBackoff:kDefaultConnectInitialBackoff + connectMaxBackoff:kDefaultConnectMaxBackoff + additionalChannelArgs:kDefaultAdditionalChannelArgs + pemRootCert:kDefaultPemRootCert + pemPrivateKey:kDefaultPemPrivateKey + pemCertChain:kDefaultPemCertChain + transportType:kDefaultTransportType + hostNameOverride:kDefaultHostNameOverride + logContext:kDefaultLogContext + channelPoolDomain:kDefaultChannelPoolDomain + channelId:kDefaultChannelId]; +} + +- (nonnull id)copyWithZone:(NSZone *)zone { + GRPCCallOptions *newOptions = + [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority + timeout:_timeout + oauth2AccessToken:_oauth2AccessToken + authTokenProvider:_authTokenProvider + initialMetadata:_initialMetadata + userAgentPrefix:_userAgentPrefix + responseSizeLimit:_responseSizeLimit + compressAlgorithm:_compressAlgorithm + enableRetry:_enableRetry + keepaliveInterval:_keepaliveInterval + keepaliveTimeout:_keepaliveTimeout + connectMinTimeout:_connectMinTimeout + connectInitialBackoff:_connectInitialBackoff + connectMaxBackoff:_connectMaxBackoff + additionalChannelArgs:[_additionalChannelArgs copy] + pemRootCert:_pemRootCert + pemPrivateKey:_pemPrivateKey + pemCertChain:_pemCertChain + transportType:_transportType + hostNameOverride:_hostNameOverride + logContext:_logContext + channelPoolDomain:_channelPoolDomain + channelId:_channelId]; + return newOptions; +} + +- (nonnull id)mutableCopyWithZone:(NSZone *)zone { + GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] + initWithServerAuthority:_serverAuthority + timeout:_timeout + oauth2AccessToken:_oauth2AccessToken + authTokenProvider:_authTokenProvider + initialMetadata:_initialMetadata + userAgentPrefix:_userAgentPrefix + responseSizeLimit:_responseSizeLimit + compressAlgorithm:_compressAlgorithm + enableRetry:_enableRetry + keepaliveInterval:_keepaliveInterval + keepaliveTimeout:_keepaliveTimeout + connectMinTimeout:_connectMinTimeout + connectInitialBackoff:_connectInitialBackoff + connectMaxBackoff:_connectMaxBackoff + additionalChannelArgs:[_additionalChannelArgs copy] + pemRootCert:_pemRootCert + pemPrivateKey:_pemPrivateKey + pemCertChain:_pemCertChain + transportType:_transportType + hostNameOverride:_hostNameOverride + logContext:_logContext + channelPoolDomain:_channelPoolDomain + channelId:_channelId]; + return newOptions; +} + +- (void)setServerAuthority:(NSString *)serverAuthority { + _serverAuthority = serverAuthority; +} + +- (void)setTimeout:(NSTimeInterval)timeout { + _timeout = timeout; +} + +- (void)setOauth2AccessToken:(NSString *)oauth2AccessToken { + _oauth2AccessToken = oauth2AccessToken; +} + +- (void)setAuthTokenProvider:(id)authTokenProvider { + _authTokenProvider = authTokenProvider; +} + +- (void)setInitialMetadata:(NSDictionary *)initialMetadata { + _initialMetadata = initialMetadata; +} + +- (void)setUserAgentPrefix:(NSString *)userAgentPrefix { + _userAgentPrefix = userAgentPrefix; +} + +- (void)setResponseSizeLimit:(NSUInteger)responseSizeLimit { + _responseSizeLimit = responseSizeLimit; +} + +- (void)setCompressAlgorithm:(GRPCCompressAlgorithm)compressAlgorithm { + _compressAlgorithm = compressAlgorithm; +} + +- (void)setEnableRetry:(BOOL)enableRetry { + _enableRetry = enableRetry; +} + +- (void)setKeepaliveInterval:(NSTimeInterval)keepaliveInterval { + _keepaliveInterval = keepaliveInterval; +} + +- (void)setKeepaliveTimeout:(NSTimeInterval)keepaliveTimeout { + _keepaliveTimeout = keepaliveTimeout; +} + +- (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout { + _connectMinTimeout = connectMinTimeout; +} + +- (void)setConnectInitialBackoff:(NSTimeInterval)connectInitialBackoff { + _connectInitialBackoff = connectInitialBackoff; +} + +- (void)setConnectMaxBackoff:(NSTimeInterval)connectMaxBackoff { + _connectMaxBackoff = connectMaxBackoff; +} + +- (void)setAdditionalChannelArgs:(NSDictionary *)additionalChannelArgs { + _additionalChannelArgs = additionalChannelArgs; +} + +- (void)setPemRootCert:(NSString *)pemRootCert { + _pemRootCert = pemRootCert; +} + +- (void)setPemPrivateKey:(NSString *)pemPrivateKey { + _pemPrivateKey = pemPrivateKey; +} + +- (void)setPemCertChain:(NSString *)pemCertChain { + _pemCertChain = pemCertChain; +} + +- (void)setTransportType:(GRPCTransportType)transportType { + _transportType = transportType; +} + +- (void)setHostNameOverride:(NSString *)hostNameOverride { + _hostNameOverride = hostNameOverride; +} + +- (void)setLogContext:(id)logContext { + _logContext = logContext; +} + +- (void)setChannelPoolDomain:(NSString *)channelPoolDomain { + _channelPoolDomain = channelPoolDomain; +} + +- (void)setChannelId:(NSUInteger)channelId { + _channelId = channelId; +} + +@end From 0fd4727defda5f8bef106a1f3b59263886b9b6c6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 8 Oct 2018 15:51:39 -0700 Subject: [PATCH 0015/2143] deprecated old API --- .../GRPCClient/GRPCCall+ChannelArg.h | 34 +------------------ .../GRPCClient/GRPCCall+ChannelArg.m | 5 +-- .../GRPCClient/GRPCCall+ChannelCredentials.h | 10 +----- src/objective-c/GRPCClient/GRPCCall+Cronet.h | 13 +------ src/objective-c/GRPCClient/GRPCCall+OAuth2.h | 29 +++------------- src/objective-c/GRPCClient/GRPCCall+Tests.h | 25 ++------------ src/objective-c/GRPCClient/GRPCCall+Tests.m | 4 ++- 7 files changed, 15 insertions(+), 105 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h index 803f19dedfe..2ddd53a5c66 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h @@ -19,52 +19,20 @@ #include -typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) { - GRPCCompressNone, - GRPCCompressDeflate, - GRPCCompressGzip, -}; - -/** - * Methods to configure GRPC channel options. - */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (ChannelArg) -/** - * Use the provided @c userAgentPrefix at the beginning of the HTTP User Agent string for all calls - * to the specified @c host. - */ + (void)setUserAgentPrefix:(nonnull NSString *)userAgentPrefix forHost:(nonnull NSString *)host; - -/** The default response size limit is 4MB. Set this to override that default. */ + (void)setResponseSizeLimit:(NSUInteger)limit forHost:(nonnull NSString *)host; - + (void)closeOpenConnections DEPRECATED_MSG_ATTRIBUTE( "The API for this feature is experimental, " "and might be removed or modified at any " "time."); - + (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host; - -/** Enable keepalive and configure keepalive parameters. A user should call this function once to - * enable keepalive for a particular host. gRPC client sends a ping after every \a interval ms to - * check if the transport is still alive. After waiting for \a timeout ms, if the client does not - * receive the ping ack, it closes the transport; all pending calls to this host will fail with - * error GRPC_STATUS_INTERNAL with error information "keepalive watchdog timeout". */ + (void)setKeepaliveWithInterval:(int)interval timeout:(int)timeout forHost:(nonnull NSString *)host; - -/** Enable/Disable automatic retry of gRPC calls on the channel. If automatic retry is enabled, the - * retry is controlled by server's service config. If automatic retry is disabled, failed calls are - * immediately returned to the application layer. */ + (void)enableRetry:(BOOL)enabled forHost:(nonnull NSString *)host; - -/** Set channel connection timeout and backoff parameters. All parameters are positive integers in - * milliseconds. Set a parameter to 0 to make gRPC use default value for that parameter. - * - * Refer to gRPC's doc at https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md for the - * details of each parameter. */ + (void)setMinConnectTimeout:(unsigned int)timeout initialBackoff:(unsigned int)initialBackoff maxBackoff:(unsigned int)maxBackoff diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m index 0e631fb3adf..d01d0c0d4fd 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m @@ -18,6 +18,7 @@ #import "GRPCCall+ChannelArg.h" +#import "private/GRPCChannel.h" #import "private/GRPCHost.h" #import @@ -31,11 +32,11 @@ + (void)setResponseSizeLimit:(NSUInteger)limit forHost:(nonnull NSString *)host { GRPCHost *hostConfig = [GRPCHost hostWithAddress:host]; - hostConfig.responseSizeLimitOverride = @(limit); + hostConfig.responseSizeLimitOverride = limit; } + (void)closeOpenConnections { - [GRPCHost flushChannelCache]; + [GRPCChannel closeOpenConnections]; } + (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host { diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h b/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h index d7d15c4ee38..7d6f79b7655 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h @@ -18,20 +18,12 @@ #import "GRPCCall.h" -/** Helpers for setting TLS Trusted Roots, Client Certificates, and Private Key */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (ChannelCredentials) -/** - * Use the provided @c pemRootCert as the set of trusted root Certificate Authorities for @c host. - */ + (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCert forHost:(nonnull NSString *)host error:(NSError *_Nullable *_Nullable)errorPtr; -/** - * Configures @c host with TLS/SSL Client Credentials and optionally trusted root Certificate - * Authorities. If @c pemRootCerts is nil, the default CA Certificates bundled with gRPC will be - * used. - */ + (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCerts withPrivateKey:(nullable NSString *)pemPrivateKey withCertChain:(nullable NSString *)pemCertChain diff --git a/src/objective-c/GRPCClient/GRPCCall+Cronet.h b/src/objective-c/GRPCClient/GRPCCall+Cronet.h index 2a5f6e9cf0e..3059c6f1860 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Cronet.h +++ b/src/objective-c/GRPCClient/GRPCCall+Cronet.h @@ -20,22 +20,11 @@ #import "GRPCCall.h" -/** - * Methods for using cronet transport. - */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (Cronet) -/** - * This method should be called before issuing the first RPC. It should be - * called only once. Create an instance of Cronet engine in your app elsewhere - * and pass the instance pointer in the stream_engine parameter. Once set, - * all subsequent RPCs will use Cronet transport. The method is not thread - * safe. - */ + (void)useCronetWithEngine:(stream_engine*)engine; - + (stream_engine*)cronetEngine; - + (BOOL)isUsingCronet; @end diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h index adb1042aa0e..3054bfc5a7a 100644 --- a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h +++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h @@ -18,34 +18,13 @@ #import "GRPCCall.h" -/** - * The protocol of an OAuth2 token object from which GRPCCall can acquire a token. - */ -@protocol GRPCAuthorizationProtocol -- (void)getTokenWithHandler:(void (^)(NSString *token))hander; -@end +#import "GRPCCallOptions.h" -/** Helpers for setting and reading headers compatible with OAuth2. */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (OAuth2) -/** - * Setting this property is equivalent to setting "Bearer " as the value of the - * request header with key "authorization" (the authorization header). Setting it to nil removes the - * authorization header from the request. - * The value obtained by getting the property is the OAuth2 bearer token if the authorization header - * of the request has the form "Bearer ", or nil otherwise. - */ -@property(atomic, copy) NSString *oauth2AccessToken; - -/** Returns the value (if any) of the "www-authenticate" response header (the challenge header). */ -@property(atomic, readonly) NSString *oauth2ChallengeHeader; - -/** - * The authorization token object to be used when starting the call. If the value is set to nil, no - * oauth authentication will be used. - * - * If tokenProvider exists, it takes precedence over the token set by oauth2AccessToken. - */ +@property(atomic, copy) NSString* oauth2AccessToken; +@property(atomic, readonly) NSString* oauth2ChallengeHeader; @property(atomic, strong) id tokenProvider; @end diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.h b/src/objective-c/GRPCClient/GRPCCall+Tests.h index 5d35182ae52..edaa5ed582c 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Tests.h +++ b/src/objective-c/GRPCClient/GRPCCall+Tests.h @@ -18,34 +18,13 @@ #import "GRPCCall.h" -/** - * Methods to let tune down the security of gRPC connections for specific hosts. These shouldn't be - * used in releases, but are sometimes needed for testing. - */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (Tests) -/** - * Establish all SSL connections to the provided host using the passed SSL target name and the root - * certificates found in the file at |certsPath|. - * - * Must be called before any gRPC call to that host is made. It's illegal to pass the same host to - * more than one invocation of the methods of this category. - */ + (void)useTestCertsPath:(NSString *)certsPath testName:(NSString *)testName forHost:(NSString *)host; - -/** - * Establish all connections to the provided host using cleartext instead of SSL. - * - * Must be called before any gRPC call to that host is made. It's illegal to pass the same host to - * more than one invocation of the methods of this category. - */ + (void)useInsecureConnectionsForHost:(NSString *)host; - -/** - * Resets all host configurations to their default values, and flushes all connections from the - * cache. - */ + (void)resetHostSettings; + @end diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.m b/src/objective-c/GRPCClient/GRPCCall+Tests.m index 0db3ad6b399..ac3b6a658f9 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Tests.m +++ b/src/objective-c/GRPCClient/GRPCCall+Tests.m @@ -20,6 +20,8 @@ #import "private/GRPCHost.h" +#import "GRPCCallOptions.h" + @implementation GRPCCall (Tests) + (void)useTestCertsPath:(NSString *)certsPath @@ -42,7 +44,7 @@ + (void)useInsecureConnectionsForHost:(NSString *)host { GRPCHost *hostConfig = [GRPCHost hostWithAddress:host]; - hostConfig.secure = NO; + hostConfig.transportType = GRPCTransportTypeInsecure; } + (void)resetHostSettings { From 309ba191525a96c5314e5762ecaa2fffbc9eccbb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 8 Oct 2018 15:52:27 -0700 Subject: [PATCH 0016/2143] Channel pool --- .../GRPCClient/private/ChannelArgsUtil.h | 25 ++ .../GRPCClient/private/ChannelArgsUtil.m | 95 +++++ .../GRPCClient/private/GRPCChannel.h | 49 +-- .../GRPCClient/private/GRPCChannel.m | 258 ++++-------- .../GRPCClient/private/GRPCChannelFactory.h | 32 ++ .../GRPCClient/private/GRPCChannelPool.h | 69 ++++ .../GRPCClient/private/GRPCChannelPool.m | 387 ++++++++++++++++++ .../private/GRPCCronetChannelFactory.h | 36 ++ .../private/GRPCCronetChannelFactory.m | 94 +++++ src/objective-c/GRPCClient/private/GRPCHost.h | 29 +- src/objective-c/GRPCClient/private/GRPCHost.m | 259 ++---------- .../private/GRPCInsecureChannelFactory.h | 35 ++ .../private/GRPCInsecureChannelFactory.m | 48 +++ .../private/GRPCSecureChannelFactory.h | 38 ++ .../private/GRPCSecureChannelFactory.m | 129 ++++++ .../GRPCClient/private/GRPCWrappedCall.h | 3 +- .../GRPCClient/private/GRPCWrappedCall.m | 18 +- 17 files changed, 1147 insertions(+), 457 deletions(-) create mode 100644 src/objective-c/GRPCClient/private/ChannelArgsUtil.h create mode 100644 src/objective-c/GRPCClient/private/ChannelArgsUtil.m create mode 100644 src/objective-c/GRPCClient/private/GRPCChannelFactory.h create mode 100644 src/objective-c/GRPCClient/private/GRPCChannelPool.h create mode 100644 src/objective-c/GRPCClient/private/GRPCChannelPool.m create mode 100644 src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h create mode 100644 src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m create mode 100644 src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h create mode 100644 src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m create mode 100644 src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h create mode 100644 src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h new file mode 100644 index 00000000000..d9d6933c6bb --- /dev/null +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h @@ -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. + * + */ + +#import + +#include + +void FreeChannelArgs(grpc_channel_args* channel_args); + +grpc_channel_args* BuildChannelArgs(NSDictionary* dictionary); diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m new file mode 100644 index 00000000000..8ebf3a26593 --- /dev/null +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -0,0 +1,95 @@ +/* + * + * 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. + * + */ + +#import "ChannelArgsUtil.h" + +#include +#include + +static void *copy_pointer_arg(void *p) { + // Add ref count to the object when making copy + id obj = (__bridge id)p; + return (__bridge_retained void *)obj; +} + +static void destroy_pointer_arg(void *p) { + // Decrease ref count to the object when destroying + CFRelease((CFTreeRef)p); +} + +static int cmp_pointer_arg(void *p, void *q) { return p == q; } + +static const grpc_arg_pointer_vtable objc_arg_vtable = {copy_pointer_arg, destroy_pointer_arg, + cmp_pointer_arg}; + +void FreeChannelArgs(grpc_channel_args *channel_args) { + for (size_t i = 0; i < channel_args->num_args; ++i) { + grpc_arg *arg = &channel_args->args[i]; + gpr_free(arg->key); + if (arg->type == GRPC_ARG_STRING) { + gpr_free(arg->value.string); + } + } + gpr_free(channel_args->args); + gpr_free(channel_args); +} + +/** + * Allocates a @c grpc_channel_args and populates it with the options specified in the + * @c dictionary. Keys must be @c NSString. If the value responds to @c @selector(UTF8String) then + * it will be mapped to @c GRPC_ARG_STRING. If not, it will be mapped to @c GRPC_ARG_INTEGER if the + * value responds to @c @selector(intValue). Otherwise, an exception will be raised. The caller of + * this function is responsible for calling @c freeChannelArgs on a non-NULL returned value. + */ +grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { + if (!dictionary) { + return NULL; + } + + NSArray *keys = [dictionary allKeys]; + NSUInteger argCount = [keys count]; + + grpc_channel_args *channelArgs = gpr_malloc(sizeof(grpc_channel_args)); + channelArgs->num_args = argCount; + channelArgs->args = gpr_malloc(argCount * sizeof(grpc_arg)); + + // TODO(kriswuollett) Check that keys adhere to GRPC core library requirements + + for (NSUInteger i = 0; i < argCount; ++i) { + grpc_arg *arg = &channelArgs->args[i]; + arg->key = gpr_strdup([keys[i] UTF8String]); + + id value = dictionary[keys[i]]; + if ([value respondsToSelector:@selector(UTF8String)]) { + arg->type = GRPC_ARG_STRING; + arg->value.string = gpr_strdup([value UTF8String]); + } else if ([value respondsToSelector:@selector(intValue)]) { + arg->type = GRPC_ARG_INTEGER; + arg->value.integer = [value intValue]; + } else if (value != nil) { + arg->type = GRPC_ARG_POINTER; + arg->value.pointer.p = (__bridge_retained void *)value; + arg->value.pointer.vtable = &objc_arg_vtable; + } else { + [NSException raise:NSInvalidArgumentException + format:@"Invalid value type: %@", [value class]]; + } + } + + return channelArgs; +} diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 6499d4398c8..7d5039a8a20 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -21,6 +21,8 @@ #include @class GRPCCompletionQueue; +@class GRPCCallOptions; +@class GRPCChannelConfiguration; struct grpc_channel_credentials; /** @@ -28,41 +30,30 @@ struct grpc_channel_credentials; */ @interface GRPCChannel : NSObject -@property(nonatomic, readonly, nonnull) struct grpc_channel *unmanagedChannel; - - (nullable instancetype)init NS_UNAVAILABLE; /** - * Creates a secure channel to the specified @c host using default credentials and channel - * arguments. If certificates could not be found to create a secure channel, then @c nil is - * returned. + * Returns a channel connecting to \a host with options as \a callOptions. The channel may be new + * or a cached channel that is already connected. */ -+ (nullable GRPCChannel *)secureChannelWithHost:(nonnull NSString *)host; ++ (nullable instancetype)channelWithHost:(nonnull NSString *)host + callOptions:(nullable GRPCCallOptions *)callOptions; /** - * Creates a secure channel to the specified @c host using Cronet as a transport mechanism. + * Get a grpc core call object from this channel. */ -#ifdef GRPC_COMPILE_WITH_CRONET -+ (nullable GRPCChannel *)secureCronetChannelWithHost:(nonnull NSString *)host - channelArgs:(nonnull NSDictionary *)channelArgs; -#endif -/** - * Creates a secure channel to the specified @c host using the specified @c credentials and - * @c channelArgs. Only in tests should @c GRPC_SSL_TARGET_NAME_OVERRIDE_ARG channel arg be set. - */ -+ (nonnull GRPCChannel *)secureChannelWithHost:(nonnull NSString *)host - credentials: - (nonnull struct grpc_channel_credentials *)credentials - channelArgs:(nullable NSDictionary *)channelArgs; - -/** - * Creates an insecure channel to the specified @c host using the specified @c channelArgs. - */ -+ (nonnull GRPCChannel *)insecureChannelWithHost:(nonnull NSString *)host - channelArgs:(nullable NSDictionary *)channelArgs; - - (nullable grpc_call *)unmanagedCallWithPath:(nonnull NSString *)path - serverName:(nonnull NSString *)serverName - timeout:(NSTimeInterval)timeout - completionQueue:(nonnull GRPCCompletionQueue *)queue; + completionQueue:(nonnull GRPCCompletionQueue *)queue + callOptions:(nonnull GRPCCallOptions *)callOptions; + +- (void)unmanagedCallUnref; + +/** + * Create a channel object with the signature \a config. This function is used for testing only. Use + * channelWithHost:callOptions: in production. + */ ++ (nullable instancetype)createChannelWithConfiguration:(nonnull GRPCChannelConfiguration *)config; + +// TODO (mxyan): deprecate with GRPCCall:closeOpenConnections ++ (void)closeOpenConnections; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index b1f6ea270ef..cf44b96e220 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -18,206 +18,106 @@ #import "GRPCChannel.h" -#include -#ifdef GRPC_COMPILE_WITH_CRONET -#include -#endif -#include #include -#include -#ifdef GRPC_COMPILE_WITH_CRONET -#import -#import -#endif +#import "ChannelArgsUtil.h" +#import "GRPCChannelFactory.h" +#import "GRPCChannelPool.h" #import "GRPCCompletionQueue.h" +#import "GRPCConnectivityMonitor.h" +#import "GRPCCronetChannelFactory.h" +#import "GRPCInsecureChannelFactory.h" +#import "GRPCSecureChannelFactory.h" +#import "version.h" -static void *copy_pointer_arg(void *p) { - // Add ref count to the object when making copy - id obj = (__bridge id)p; - return (__bridge_retained void *)obj; -} - -static void destroy_pointer_arg(void *p) { - // Decrease ref count to the object when destroying - CFRelease((CFTreeRef)p); -} - -static int cmp_pointer_arg(void *p, void *q) { return p == q; } - -static const grpc_arg_pointer_vtable objc_arg_vtable = {copy_pointer_arg, destroy_pointer_arg, - cmp_pointer_arg}; - -static void FreeChannelArgs(grpc_channel_args *channel_args) { - for (size_t i = 0; i < channel_args->num_args; ++i) { - grpc_arg *arg = &channel_args->args[i]; - gpr_free(arg->key); - if (arg->type == GRPC_ARG_STRING) { - gpr_free(arg->value.string); - } - } - gpr_free(channel_args->args); - gpr_free(channel_args); -} - -/** - * Allocates a @c grpc_channel_args and populates it with the options specified in the - * @c dictionary. Keys must be @c NSString. If the value responds to @c @selector(UTF8String) then - * it will be mapped to @c GRPC_ARG_STRING. If not, it will be mapped to @c GRPC_ARG_INTEGER if the - * value responds to @c @selector(intValue). Otherwise, an exception will be raised. The caller of - * this function is responsible for calling @c freeChannelArgs on a non-NULL returned value. - */ -static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { - if (!dictionary) { - return NULL; - } - - NSArray *keys = [dictionary allKeys]; - NSUInteger argCount = [keys count]; - - grpc_channel_args *channelArgs = gpr_malloc(sizeof(grpc_channel_args)); - channelArgs->num_args = argCount; - channelArgs->args = gpr_malloc(argCount * sizeof(grpc_arg)); - - // TODO(kriswuollett) Check that keys adhere to GRPC core library requirements - - for (NSUInteger i = 0; i < argCount; ++i) { - grpc_arg *arg = &channelArgs->args[i]; - arg->key = gpr_strdup([keys[i] UTF8String]); - - id value = dictionary[keys[i]]; - if ([value respondsToSelector:@selector(UTF8String)]) { - arg->type = GRPC_ARG_STRING; - arg->value.string = gpr_strdup([value UTF8String]); - } else if ([value respondsToSelector:@selector(intValue)]) { - arg->type = GRPC_ARG_INTEGER; - arg->value.integer = [value intValue]; - } else if (value != nil) { - arg->type = GRPC_ARG_POINTER; - arg->value.pointer.p = (__bridge_retained void *)value; - arg->value.pointer.vtable = &objc_arg_vtable; - } else { - [NSException raise:NSInvalidArgumentException - format:@"Invalid value type: %@", [value class]]; - } - } - - return channelArgs; -} +#import +#import @implementation GRPCChannel { - // Retain arguments to channel_create because they may not be used on the thread that invoked - // the channel_create function. - NSString *_host; - grpc_channel_args *_channelArgs; -} - -#ifdef GRPC_COMPILE_WITH_CRONET -- (instancetype)initWithHost:(NSString *)host - cronetEngine:(stream_engine *)cronetEngine - channelArgs:(NSDictionary *)channelArgs { - if (!host) { - [NSException raise:NSInvalidArgumentException format:@"host argument missing"]; - } - - if (self = [super init]) { - _channelArgs = BuildChannelArgs(channelArgs); - _host = [host copy]; - _unmanagedChannel = - grpc_cronet_secure_channel_create(cronetEngine, _host.UTF8String, _channelArgs, NULL); - } - - return self; -} -#endif - -- (instancetype)initWithHost:(NSString *)host - secure:(BOOL)secure - credentials:(struct grpc_channel_credentials *)credentials - channelArgs:(NSDictionary *)channelArgs { - if (!host) { - [NSException raise:NSInvalidArgumentException format:@"host argument missing"]; - } - - if (secure && !credentials) { - return nil; - } - - if (self = [super init]) { - _channelArgs = BuildChannelArgs(channelArgs); - _host = [host copy]; - if (secure) { - _unmanagedChannel = - grpc_secure_channel_create(credentials, _host.UTF8String, _channelArgs, NULL); - } else { - _unmanagedChannel = grpc_insecure_channel_create(_host.UTF8String, _channelArgs, NULL); - } - } - - return self; -} - -- (void)dealloc { - // TODO(jcanizales): Be sure to add a test with a server that closes the connection prematurely, - // as in the past that made this call to crash. - grpc_channel_destroy(_unmanagedChannel); - FreeChannelArgs(_channelArgs); -} - -#ifdef GRPC_COMPILE_WITH_CRONET -+ (GRPCChannel *)secureCronetChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)channelArgs { - stream_engine *engine = [GRPCCall cronetEngine]; - if (!engine) { - [NSException raise:NSInvalidArgumentException format:@"cronet_engine is NULL. Set it first."]; - return nil; - } - return [[GRPCChannel alloc] initWithHost:host cronetEngine:engine channelArgs:channelArgs]; -} -#endif - -+ (GRPCChannel *)secureChannelWithHost:(NSString *)host { - return [[GRPCChannel alloc] initWithHost:host secure:YES credentials:NULL channelArgs:NULL]; -} - -+ (GRPCChannel *)secureChannelWithHost:(NSString *)host - credentials:(struct grpc_channel_credentials *)credentials - channelArgs:(NSDictionary *)channelArgs { - return [[GRPCChannel alloc] initWithHost:host - secure:YES - credentials:credentials - channelArgs:channelArgs]; -} - -+ (GRPCChannel *)insecureChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)channelArgs { - return [[GRPCChannel alloc] initWithHost:host secure:NO credentials:NULL channelArgs:channelArgs]; + GRPCChannelConfiguration *_configuration; + grpc_channel *_unmanagedChannel; } - (grpc_call *)unmanagedCallWithPath:(NSString *)path - serverName:(NSString *)serverName - timeout:(NSTimeInterval)timeout - completionQueue:(GRPCCompletionQueue *)queue { + completionQueue:(nonnull GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions { + NSString *serverAuthority = callOptions.serverAuthority; + NSTimeInterval timeout = callOptions.timeout; GPR_ASSERT(timeout >= 0); - if (timeout < 0) { - timeout = 0; - } grpc_slice host_slice = grpc_empty_slice(); - if (serverName) { - host_slice = grpc_slice_from_copied_string(serverName.UTF8String); + if (serverAuthority) { + host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); } grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); gpr_timespec deadline_ms = timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME) : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); - grpc_call *call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, - queue.unmanagedQueue, path_slice, - serverName ? &host_slice : NULL, deadline_ms, NULL); - if (serverName) { + grpc_call *call = grpc_channel_create_call( + _unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, + serverAuthority ? &host_slice : NULL, deadline_ms, NULL); + if (serverAuthority) { grpc_slice_unref(host_slice); } grpc_slice_unref(path_slice); return call; } +- (void)unmanagedCallUnref { + [kChannelPool unrefChannelWithConfiguration:_configuration]; +} + +- (nullable instancetype)initWithUnmanagedChannel:(nullable grpc_channel *)unmanagedChannel + configuration:(GRPCChannelConfiguration *)configuration { + if ((self = [super init])) { + _unmanagedChannel = unmanagedChannel; + _configuration = configuration; + } + return self; +} + +- (void)dealloc { + grpc_channel_destroy(_unmanagedChannel); +} + ++ (nullable instancetype)createChannelWithConfiguration:(GRPCChannelConfiguration *)config { + NSString *host = config.host; + if (host == nil || [host length] == 0) { + return nil; + } + + NSMutableDictionary *channelArgs = config.channelArgs; + [channelArgs addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; + id factory = config.channelFactory; + grpc_channel *unmanaged_channel = [factory createChannelWithHost:host channelArgs:channelArgs]; + return [[GRPCChannel alloc] initWithUnmanagedChannel:unmanaged_channel configuration:config]; +} + +static dispatch_once_t initChannelPool; +static GRPCChannelPool *kChannelPool; + ++ (nullable instancetype)channelWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions { + dispatch_once(&initChannelPool, ^{ + kChannelPool = [[GRPCChannelPool alloc] init]; + }); + + NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:host]]; + if (hostURL.host && !hostURL.port) { + host = [hostURL.host stringByAppendingString:@":443"]; + } + + GRPCChannelConfiguration *channelConfig = + [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; + return [kChannelPool channelWithConfiguration:channelConfig + createChannel:^{ + return + [GRPCChannel createChannelWithConfiguration:channelConfig]; + }]; +} + ++ (void)closeOpenConnections { + [kChannelPool clear]; +} + @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h new file mode 100644 index 00000000000..e44f8260dfd --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -0,0 +1,32 @@ +/* + * + * 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. + * + */ + +#import + +#include + +NS_ASSUME_NONNULL_BEGIN + +@protocol GRPCChannelFactory + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableDictionary *)args; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h new file mode 100644 index 00000000000..1145039549c --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -0,0 +1,69 @@ +/* + * + * 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. + * + */ + +/** + * Signature for the channel. If two channel's signatures are the same, they share the same + * underlying \a GRPCChannel object. + */ + +#import + +#import "GRPCChannelFactory.h" + +NS_ASSUME_NONNULL_BEGIN + +@class GRPCChannel; + +@interface GRPCChannelConfiguration : NSObject + +@property(atomic, strong, readwrite) NSString *host; +@property(atomic, strong, readwrite) GRPCCallOptions *callOptions; + +@property(readonly) id channelFactory; +@property(readonly) NSMutableDictionary *channelArgs; + +- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; + +@end + +/** + * Manage the pool of connected channels. When a channel is no longer referenced by any call, + * destroy the channel after a certain period of time elapsed. + */ +@interface GRPCChannelPool : NSObject + +- (instancetype)init; + +- (instancetype)initWithChannelDestroyDelay:(NSTimeInterval)channelDestroyDelay; + +/** + * Return a channel with a particular configuration. If the channel does not exist, execute \a + * createChannel then add it in the pool. If the channel exists, increase its reference count. + */ +- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration + createChannel:(GRPCChannel * (^)(void))createChannel; + +/** Decrease a channel's refcount. */ +- (void)unrefChannelWithConfiguration:configuration; + +/** Clear all channels in the pool. */ +- (void)clear; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m new file mode 100644 index 00000000000..b5f0949ef73 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -0,0 +1,387 @@ +/* + * + * 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. + * + */ + +#import + +#import "GRPCChannelFactory.h" +#import "GRPCChannelPool.h" +#import "GRPCConnectivityMonitor.h" +#import "GRPCCronetChannelFactory.h" +#import "GRPCInsecureChannelFactory.h" +#import "GRPCSecureChannelFactory.h" +#import "version.h" + +#import +#include + +extern const char *kCFStreamVarName; + +// When all calls of a channel are destroyed, destroy the channel after this much seconds. +const NSTimeInterval kChannelDestroyDelay = 30; + +@implementation GRPCChannelConfiguration + +- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { + if ((self = [super init])) { + _host = host; + _callOptions = callOptions; + } + return self; +} + +- (id)channelFactory { + NSError *error; + id factory; + GRPCTransportType type = _callOptions.transportType; + switch (type) { + case GRPCTransportTypeDefault: + // TODO (mxyan): Remove when the API is deprecated +#ifdef GRPC_COMPILE_WITH_CRONET + if (![GRPCCall isUsingCronet]) { +#endif + factory = [GRPCSecureChannelFactory factoryWithPEMRootCerts:_callOptions.pemRootCert + privateKey:_callOptions.pemPrivateKey + certChain:_callOptions.pemCertChain + error:&error]; + if (error) { + NSLog(@"Error creating secure channel factory: %@", error); + return nil; + } + return factory; +#ifdef GRPC_COMPILE_WITH_CRONET + } +#endif + // fallthrough + case GRPCTransportTypeCronet: + return [GRPCCronetChannelFactory sharedInstance]; + case GRPCTransportTypeInsecure: + return [GRPCInsecureChannelFactory sharedInstance]; + default: + GPR_UNREACHABLE_CODE(return nil); + } +} + +- (NSMutableDictionary *)channelArgs { + NSMutableDictionary *args = [NSMutableDictionary new]; + + NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; + NSString *userAgentPrefix = _callOptions.userAgentPrefix; + if (userAgentPrefix) { + args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = + [_callOptions.userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; + } else { + args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = userAgent; + } + + NSString *hostNameOverride = _callOptions.hostNameOverride; + if (hostNameOverride) { + args[@GRPC_SSL_TARGET_NAME_OVERRIDE_ARG] = hostNameOverride; + } + + if (_callOptions.responseSizeLimit) { + args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = + [NSNumber numberWithUnsignedInteger:_callOptions.responseSizeLimit]; + } + + if (_callOptions.compressAlgorithm != GRPC_COMPRESS_NONE) { + args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = + [NSNumber numberWithInt:_callOptions.compressAlgorithm]; + } + + if (_callOptions.keepaliveInterval != 0) { + args[@GRPC_ARG_KEEPALIVE_TIME_MS] = + [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.keepaliveInterval * 1000)]; + args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = + [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.keepaliveTimeout * 1000)]; + } + + if (_callOptions.enableRetry == NO) { + args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.enableRetry]; + } + + if (_callOptions.connectMinTimeout > 0) { + args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = + [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.connectMinTimeout * 1000)]; + } + if (_callOptions.connectInitialBackoff > 0) { + args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber + numberWithUnsignedInteger:(unsigned int)(_callOptions.connectInitialBackoff * 1000)]; + } + if (_callOptions.connectMaxBackoff > 0) { + args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = + [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.connectMaxBackoff * 1000)]; + } + + if (_callOptions.logContext != nil) { + args[@GRPC_ARG_MOBILE_LOG_CONTEXT] = _callOptions.logContext; + } + + if (_callOptions.channelPoolDomain != nil) { + args[@GRPC_ARG_CHANNEL_POOL_DOMAIN] = _callOptions.channelPoolDomain; + } + + [args addEntriesFromDictionary:_callOptions.additionalChannelArgs]; + + return args; +} + +- (nonnull id)copyWithZone:(nullable NSZone *)zone { + GRPCChannelConfiguration *newConfig = [[GRPCChannelConfiguration alloc] init]; + newConfig.host = _host; + newConfig.callOptions = _callOptions; + + return newConfig; +} + +- (BOOL)isEqual:(id)object { + NSAssert([object isKindOfClass:[GRPCChannelConfiguration class]], @"Illegal :isEqual"); + GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; + if (!(obj.host == _host || [obj.host isEqualToString:_host])) return NO; + if (!(obj.callOptions.userAgentPrefix == _callOptions.userAgentPrefix || + [obj.callOptions.userAgentPrefix isEqualToString:_callOptions.userAgentPrefix])) + return NO; + if (!(obj.callOptions.responseSizeLimit == _callOptions.responseSizeLimit)) return NO; + if (!(obj.callOptions.compressAlgorithm == _callOptions.compressAlgorithm)) return NO; + if (!(obj.callOptions.enableRetry == _callOptions.enableRetry)) return NO; + if (!(obj.callOptions.keepaliveInterval == _callOptions.keepaliveInterval)) return NO; + if (!(obj.callOptions.keepaliveTimeout == _callOptions.keepaliveTimeout)) return NO; + if (!(obj.callOptions.connectMinTimeout == _callOptions.connectMinTimeout)) return NO; + if (!(obj.callOptions.connectInitialBackoff == _callOptions.connectInitialBackoff)) return NO; + if (!(obj.callOptions.connectMaxBackoff == _callOptions.connectMaxBackoff)) return NO; + if (!(obj.callOptions.additionalChannelArgs == _callOptions.additionalChannelArgs || + [obj.callOptions.additionalChannelArgs + isEqualToDictionary:_callOptions.additionalChannelArgs])) + return NO; + if (!(obj.callOptions.pemRootCert == _callOptions.pemRootCert || + [obj.callOptions.pemRootCert isEqualToString:_callOptions.pemRootCert])) + return NO; + if (!(obj.callOptions.pemPrivateKey == _callOptions.pemPrivateKey || + [obj.callOptions.pemPrivateKey isEqualToString:_callOptions.pemPrivateKey])) + return NO; + if (!(obj.callOptions.pemCertChain == _callOptions.pemCertChain || + [obj.callOptions.pemCertChain isEqualToString:_callOptions.pemCertChain])) + return NO; + if (!(obj.callOptions.hostNameOverride == _callOptions.hostNameOverride || + [obj.callOptions.hostNameOverride isEqualToString:_callOptions.hostNameOverride])) + return NO; + if (!(obj.callOptions.transportType == _callOptions.transportType)) return NO; + if (!(obj.callOptions.logContext == _callOptions.logContext || + [obj.callOptions.logContext isEqual:_callOptions.logContext])) + return NO; + if (!(obj.callOptions.channelPoolDomain == _callOptions.channelPoolDomain || + [obj.callOptions.channelPoolDomain isEqualToString:_callOptions.channelPoolDomain])) + return NO; + if (!(obj.callOptions.channelId == _callOptions.channelId)) return NO; + + return YES; +} + +- (NSUInteger)hash { + NSUInteger result = 0; + result ^= _host.hash; + result ^= _callOptions.userAgentPrefix.hash; + result ^= _callOptions.responseSizeLimit; + result ^= _callOptions.compressAlgorithm; + result ^= _callOptions.enableRetry; + result ^= (unsigned int)(_callOptions.keepaliveInterval * 1000); + result ^= (unsigned int)(_callOptions.keepaliveTimeout * 1000); + result ^= (unsigned int)(_callOptions.connectMinTimeout * 1000); + result ^= (unsigned int)(_callOptions.connectInitialBackoff * 1000); + result ^= (unsigned int)(_callOptions.connectMaxBackoff * 1000); + result ^= _callOptions.additionalChannelArgs.hash; + result ^= _callOptions.pemRootCert.hash; + result ^= _callOptions.pemPrivateKey.hash; + result ^= _callOptions.pemCertChain.hash; + result ^= _callOptions.hostNameOverride.hash; + result ^= _callOptions.transportType; + result ^= [_callOptions.logContext hash]; + result ^= _callOptions.channelPoolDomain.hash; + result ^= _callOptions.channelId; + + return result; +} + +@end + +/** + * Time the channel destroy when the channel's calls are unreffed. If there's new call, reset the + * timer. + */ +@interface GRPCChannelCallRef : NSObject + +- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)configuration + destroyDelay:(NSTimeInterval)destroyDelay + dispatchQueue:(dispatch_queue_t)dispatchQueue + destroyChannel:(void (^)())destroyChannel; + +/** Add call ref count to the channel and maybe reset the timer. */ +- (void)refChannel; + +/** Reduce call ref count to the channel and maybe set the timer. */ +- (void)unrefChannel; + +@end + +@implementation GRPCChannelCallRef { + GRPCChannelConfiguration *_configuration; + NSTimeInterval _destroyDelay; + // We use dispatch queue for this purpose since timer invalidation must happen on the same + // thread which issued the timer. + dispatch_queue_t _dispatchQueue; + void (^_destroyChannel)(); + + NSUInteger _refCount; + NSTimer *_timer; +} + +- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)configuration + destroyDelay:(NSTimeInterval)destroyDelay + dispatchQueue:(dispatch_queue_t)dispatchQueue + destroyChannel:(void (^)())destroyChannel { + if ((self = [super init])) { + _configuration = configuration; + _destroyDelay = destroyDelay; + _dispatchQueue = dispatchQueue; + _destroyChannel = destroyChannel; + + _refCount = 0; + _timer = nil; + } + return self; +} + +// This function is protected by channel pool dispatch queue. +- (void)refChannel { + _refCount++; + if (_timer) { + [_timer invalidate]; + } + _timer = nil; +} + +// This function is protected by channel spool dispatch queue. +- (void)unrefChannel { + self->_refCount--; + if (self->_refCount == 0) { + if (self->_timer) { + [self->_timer invalidate]; + } + self->_timer = [NSTimer scheduledTimerWithTimeInterval:self->_destroyDelay + target:self + selector:@selector(timerFire:) + userInfo:nil + repeats:NO]; + } +} + +- (void)timerFire:(NSTimer *)timer { + dispatch_sync(_dispatchQueue, ^{ + if (self->_timer == nil || self->_timer != timer) { + return; + } + self->_timer = nil; + self->_destroyChannel(self->_configuration); + }); +} + +@end + +#pragma mark GRPCChannelPool + +@implementation GRPCChannelPool { + NSTimeInterval _channelDestroyDelay; + NSMutableDictionary *_channelPool; + NSMutableDictionary *_callRefs; + // Dedicated queue for timer + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)init { + return [self initWithChannelDestroyDelay:kChannelDestroyDelay]; +} + +- (instancetype)initWithChannelDestroyDelay:(NSTimeInterval)channelDestroyDelay { + if ((self = [super init])) { + _channelDestroyDelay = channelDestroyDelay; + _channelPool = [NSMutableDictionary dictionary]; + _callRefs = [NSMutableDictionary dictionary]; + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)]; + } + } + return self; +} + +- (void)dealloc { + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor unregisterObserver:self]; + } +} + +- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration + createChannel:(GRPCChannel * (^)(void))createChannel { + __block GRPCChannel *channel; + dispatch_sync(_dispatchQueue, ^{ + if ([self->_channelPool objectForKey:configuration]) { + [self->_callRefs[configuration] refChannel]; + channel = self->_channelPool[configuration]; + } else { + channel = createChannel(); + self->_channelPool[configuration] = channel; + + GRPCChannelCallRef *callRef = [[GRPCChannelCallRef alloc] + initWithChannelConfiguration:configuration + destroyDelay:self->_channelDestroyDelay + dispatchQueue:self->_dispatchQueue + destroyChannel:^(GRPCChannelConfiguration *configuration) { + [self->_channelPool removeObjectForKey:configuration]; + [self->_callRefs removeObjectForKey:configuration]; + }]; + [callRef refChannel]; + self->_callRefs[configuration] = callRef; + } + }); + return channel; +} + +- (void)unrefChannelWithConfiguration:configuration { + dispatch_sync(_dispatchQueue, ^{ + if ([self->_channelPool objectForKey:configuration]) { + [self->_callRefs[configuration] unrefChannel]; + } + }); +} + +- (void)clear { + dispatch_sync(_dispatchQueue, ^{ + self->_channelPool = [NSMutableDictionary dictionary]; + self->_callRefs = [NSMutableDictionary dictionary]; + }); +} + +- (void)connectivityChange:(NSNotification *)note { + [self clear]; +} + +@end diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h new file mode 100644 index 00000000000..97e1ae920a0 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h @@ -0,0 +1,36 @@ +/* + * + * 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. + * + */ +#import "GRPCChannelFactory.h" + +@class GRPCChannel; +typedef struct stream_engine stream_engine; + +NS_ASSUME_NONNULL_BEGIN + +@interface GRPCCronetChannelFactory : NSObject + ++ (nullable instancetype)sharedInstance; + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableDictionary *)args; + +- (nullable instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m new file mode 100644 index 00000000000..5c0fe16d39b --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -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. + * + */ + +#import "GRPCCronetChannelFactory.h" + +#import "ChannelArgsUtil.h" +#import "GRPCChannel.h" + +#ifdef GRPC_COMPILE_WITH_CRONET + +#import +#include + +NS_ASSUME_NONNULL_BEGIN + +@implementation GRPCCronetChannelFactory { + stream_engine *_cronetEngine; +} + ++ (nullable instancetype)sharedInstance { + static GRPCCronetChannelFactory *instance; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance = [[self alloc] initWithEngine:[Cronet getGlobalEngine]]; + }); + return instance; +} + +- (nullable instancetype)initWithEngine:(stream_engine *)engine { + if (!engine) { + [NSException raise:NSInvalidArgumentException format:@"Cronet engine is NULL. Set it first."]; + return nil; + } + if ((self = [super init])) { + _cronetEngine = engine; + } + return self; +} + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableDictionary *)args { + // Remove client authority filter since that is not supported + args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1]; + + grpc_channel_args *channelArgs = BuildChannelArgs(args); + grpc_channel *unmanagedChannel = + grpc_cronet_secure_channel_create(_cronetEngine, host.UTF8String, channelArgs, NULL); + FreeChannelArgs(channelArgs); + return unmanagedChannel; +} + +@end + +NS_ASSUME_NONNULL_END + +#else + +NS_ASSUME_NONNULL_BEGIN + +@implementation GRPCCronetChannelFactory + ++ (nullable instancetype)sharedInstance { + [NSException raise:NSInvalidArgumentException + format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; + return nil; +} + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableArray *)args { + [NSException raise:NSInvalidArgumentException + format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; + return nil; +} + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h index 291b07df377..32d3585351e 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.h +++ b/src/objective-c/GRPCClient/private/GRPCHost.h @@ -20,6 +20,10 @@ #import +#import "GRPCChannelFactory.h" + +#import + NS_ASSUME_NONNULL_BEGIN @class GRPCCompletionQueue; @@ -28,12 +32,10 @@ struct grpc_channel_credentials; @interface GRPCHost : NSObject -+ (void)flushChannelCache; + (void)resetAllHostSettings; @property(nonatomic, readonly) NSString *address; @property(nonatomic, copy, nullable) NSString *userAgentPrefix; -@property(nonatomic, nullable) struct grpc_channel_credentials *channelCreds; @property(nonatomic) grpc_compression_algorithm compressAlgorithm; @property(nonatomic) int keepaliveInterval; @property(nonatomic) int keepaliveTimeout; @@ -44,14 +46,14 @@ struct grpc_channel_credentials; @property(nonatomic) unsigned int initialConnectBackoff; @property(nonatomic) unsigned int maxConnectBackoff; -/** The following properties should only be modified for testing: */ +@property(nonatomic) id channelFactory; -@property(nonatomic, getter=isSecure) BOOL secure; +/** The following properties should only be modified for testing: */ @property(nonatomic, copy, nullable) NSString *hostNameOverride; /** The default response size limit is 4MB. Set this to override that default. */ -@property(nonatomic, strong, nullable) NSNumber *responseSizeLimitOverride; +@property(nonatomic) NSUInteger responseSizeLimitOverride; - (nullable instancetype)init NS_UNAVAILABLE; /** Host objects initialized with the same address are the same. */ @@ -62,19 +64,12 @@ struct grpc_channel_credentials; withCertChain:(nullable NSString *)pemCertChain error:(NSError **)errorPtr; -/** Create a grpc_call object to the provided path on this host. */ -- (nullable struct grpc_call *)unmanagedCallWithPath:(NSString *)path - serverName:(NSString *)serverName - timeout:(NSTimeInterval)timeout - completionQueue:(GRPCCompletionQueue *)queue; +@property(atomic, readwrite) GRPCTransportType transportType; + +@property(readonly) GRPCMutableCallOptions *callOptions; + ++ (BOOL)isHostConfigured:(NSString *)address; -// TODO: There's a race when a new RPC is coming through just as an existing one is getting -// notified that there's no connectivity. If connectivity comes back at that moment, the new RPC -// will have its channel destroyed by the other RPC, and will never get notified of a problem, so -// it'll hang (the C layer logs a timeout, with exponential back off). One solution could be to pass -// the GRPCChannel to the GRPCCall, renaming this as "disconnectChannel:channel", which would only -// act on that specific channel. -- (void)disconnect; @end NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 862909f2384..0e3fa610f9e 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -18,46 +18,35 @@ #import "GRPCHost.h" +#import #import + #include #include -#ifdef GRPC_COMPILE_WITH_CRONET -#import -#import -#endif -#import "GRPCChannel.h" +#import +#import "GRPCChannelFactory.h" #import "GRPCCompletionQueue.h" #import "GRPCConnectivityMonitor.h" +#import "GRPCCronetChannelFactory.h" +#import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" #import "version.h" NS_ASSUME_NONNULL_BEGIN -extern const char *kCFStreamVarName; - static NSMutableDictionary *kHostCache; @implementation GRPCHost { - // TODO(mlumish): Investigate whether caching channels with strong links is a good idea. - GRPCChannel *_channel; + NSString *_pemRootCerts; + NSString *_pemPrivateKey; + NSString *_pemCertChain; } + (nullable instancetype)hostWithAddress:(NSString *)address { return [[self alloc] initWithAddress:address]; } -- (void)dealloc { - if (_channelCreds != nil) { - grpc_channel_credentials_release(_channelCreds); - } - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor unregisterObserver:self]; - } -} - // Default initializer. - (nullable instancetype)initWithAddress:(NSString *)address { if (!address) { @@ -86,230 +75,58 @@ static NSMutableDictionary *kHostCache; if ((self = [super init])) { _address = address; - _secure = YES; - kHostCache[address] = self; - _compressAlgorithm = GRPC_COMPRESS_NONE; _retryEnabled = YES; - } - - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)]; + kHostCache[address] = self; } } return self; } -+ (void)flushChannelCache { - @synchronized(kHostCache) { - [kHostCache enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, GRPCHost *_Nonnull host, - BOOL *_Nonnull stop) { - [host disconnect]; - }]; - } -} - + (void)resetAllHostSettings { @synchronized(kHostCache) { kHostCache = [NSMutableDictionary dictionary]; } } -- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path - serverName:(NSString *)serverName - timeout:(NSTimeInterval)timeout - completionQueue:(GRPCCompletionQueue *)queue { - // The __block attribute is to allow channel take refcount inside @synchronized block. Without - // this attribute, retain of channel object happens after objc_sync_exit in release builds, which - // may result in channel released before used. See grpc/#15033. - __block GRPCChannel *channel; - // This is racing -[GRPCHost disconnect]. - @synchronized(self) { - if (!_channel) { - _channel = [self newChannel]; - } - channel = _channel; - } - return [channel unmanagedCallWithPath:path - serverName:serverName - timeout:timeout - completionQueue:queue]; -} - -- (NSData *)nullTerminatedDataWithString:(NSString *)string { - // dataUsingEncoding: does not return a null-terminated string. - NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; - NSMutableData *nullTerminated = [NSMutableData dataWithData:data]; - [nullTerminated appendBytes:"\0" length:1]; - return nullTerminated; -} - - (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCerts withPrivateKey:(nullable NSString *)pemPrivateKey withCertChain:(nullable NSString *)pemCertChain error:(NSError **)errorPtr { - static NSData *kDefaultRootsASCII; - static NSError *kDefaultRootsError; - 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) { - kDefaultRootsError = error; - return; - } - kDefaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8]; - }); - - NSData *rootsASCII; - if (pemRootCerts != nil) { - rootsASCII = [self nullTerminatedDataWithString:pemRootCerts]; - } else { - if (kDefaultRootsASCII == nil) { - if (errorPtr) { - *errorPtr = kDefaultRootsError; - } - NSAssert( - kDefaultRootsASCII, - @"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: %@", - kDefaultRootsError); - return NO; - } - rootsASCII = kDefaultRootsASCII; - } - - grpc_channel_credentials *creds; - if (pemPrivateKey == nil && pemCertChain == nil) { - creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL, NULL); - } else { - grpc_ssl_pem_key_cert_pair key_cert_pair; - NSData *privateKeyASCII = [self nullTerminatedDataWithString:pemPrivateKey]; - NSData *certChainASCII = [self nullTerminatedDataWithString:pemCertChain]; - key_cert_pair.private_key = privateKeyASCII.bytes; - key_cert_pair.cert_chain = certChainASCII.bytes; - creds = grpc_ssl_credentials_create(rootsASCII.bytes, &key_cert_pair, NULL, NULL); - } - - @synchronized(self) { - if (_channelCreds != nil) { - grpc_channel_credentials_release(_channelCreds); - } - _channelCreds = creds; - } - + _pemRootCerts = pemRootCerts; + _pemPrivateKey = pemPrivateKey; + _pemCertChain = pemCertChain; return YES; } -- (NSDictionary *)channelArgsUsingCronet:(BOOL)useCronet { - NSMutableDictionary *args = [NSMutableDictionary dictionary]; +- (GRPCCallOptions *)callOptions { + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.userAgentPrefix = _userAgentPrefix; + options.responseSizeLimit = _responseSizeLimitOverride; + options.compressAlgorithm = (GRPCCompressAlgorithm)_compressAlgorithm; + options.enableRetry = _retryEnabled; + options.keepaliveInterval = (NSTimeInterval)_keepaliveInterval / 1000; + options.keepaliveTimeout = (NSTimeInterval)_keepaliveTimeout / 1000; + options.connectMinTimeout = (NSTimeInterval)_minConnectTimeout / 1000; + options.connectInitialBackoff = (NSTimeInterval)_initialConnectBackoff / 1000; + options.connectMaxBackoff = (NSTimeInterval)_maxConnectBackoff / 1000; + options.pemRootCert = _pemRootCerts; + options.pemPrivateKey = _pemPrivateKey; + options.pemCertChain = _pemCertChain; + options.hostNameOverride = _hostNameOverride; + options.transportType = _transportType; + options.logContext = _logContext; - // TODO(jcanizales): Add OS and device information (see - // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#user-agents ). - NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; - if (_userAgentPrefix) { - userAgent = [_userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; - } - args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = userAgent; - - if (_secure && _hostNameOverride) { - args[@GRPC_SSL_TARGET_NAME_OVERRIDE_ARG] = _hostNameOverride; - } - - if (_responseSizeLimitOverride) { - args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = _responseSizeLimitOverride; - } - - if (_compressAlgorithm != GRPC_COMPRESS_NONE) { - args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = [NSNumber numberWithInt:_compressAlgorithm]; - } - - if (_keepaliveInterval != 0) { - args[@GRPC_ARG_KEEPALIVE_TIME_MS] = [NSNumber numberWithInt:_keepaliveInterval]; - args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = [NSNumber numberWithInt:_keepaliveTimeout]; - } - - id logContext = self.logContext; - if (logContext != nil) { - args[@GRPC_ARG_MOBILE_LOG_CONTEXT] = logContext; - } - - if (useCronet) { - args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1]; - } - - if (_retryEnabled == NO) { - args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:0]; - } - - if (_minConnectTimeout > 0) { - args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_minConnectTimeout]; - } - if (_initialConnectBackoff > 0) { - args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_initialConnectBackoff]; - } - if (_maxConnectBackoff > 0) { - args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_maxConnectBackoff]; - } - - return args; + return options; } -- (GRPCChannel *)newChannel { - BOOL useCronet = NO; -#ifdef GRPC_COMPILE_WITH_CRONET - useCronet = [GRPCCall isUsingCronet]; -#endif - NSDictionary *args = [self channelArgsUsingCronet:useCronet]; - if (_secure) { - GRPCChannel *channel; - @synchronized(self) { - if (_channelCreds == nil) { - [self setTLSPEMRootCerts:nil withPrivateKey:nil withCertChain:nil error:nil]; - } -#ifdef GRPC_COMPILE_WITH_CRONET - if (useCronet) { - channel = [GRPCChannel secureCronetChannelWithHost:_address channelArgs:args]; - } else -#endif - { - channel = - [GRPCChannel secureChannelWithHost:_address credentials:_channelCreds channelArgs:args]; - } - } - return channel; - } else { - return [GRPCChannel insecureChannelWithHost:_address channelArgs:args]; ++ (BOOL)isHostConfigured:(NSString *)address { + // TODO (mxyan): Remove when old API is deprecated + NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:address]]; + if (hostURL.host && !hostURL.port) { + address = [hostURL.host stringByAppendingString:@":443"]; } -} - -- (NSString *)hostName { - // TODO(jcanizales): Default to nil instead of _address when Issue #2635 is clarified. - return _hostNameOverride ?: _address; -} - -- (void)disconnect { - // This is racing -[GRPCHost unmanagedCallWithPath:completionQueue:]. - @synchronized(self) { - _channel = nil; - } -} - -// Flushes the host cache when connectivity status changes or when connection switch between Wifi -// and Cellular data, so that a new call will use a new channel. Otherwise, a new call will still -// use the cached channel which is no longer available and will cause gRPC to hang. -- (void)connectivityChange:(NSNotification *)note { - [self disconnect]; + GRPCHost *cachedHost = kHostCache[address]; + return (cachedHost != nil); } @end diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h new file mode 100644 index 00000000000..905a181ca78 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h @@ -0,0 +1,35 @@ +/* + * + * 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. + * + */ +#import "GRPCChannelFactory.h" + +@class GRPCChannel; + +NS_ASSUME_NONNULL_BEGIN + +@interface GRPCInsecureChannelFactory : NSObject + ++ (nullable instancetype)sharedInstance; + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableDictionary *)args; + +- (nullable instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m new file mode 100644 index 00000000000..41860bf6ff5 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -0,0 +1,48 @@ +/* + * + * 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. + * + */ + +#import "GRPCInsecureChannelFactory.h" + +#import "ChannelArgsUtil.h" +#import "GRPCChannel.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation GRPCInsecureChannelFactory + ++ (nullable instancetype)sharedInstance { + static GRPCInsecureChannelFactory *instance; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance = [[self alloc] init]; + }); + return instance; +} + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableDictionary *)args { + grpc_channel_args *coreChannelArgs = BuildChannelArgs([args copy]); + grpc_channel *unmanagedChannel = + grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); + FreeChannelArgs(coreChannelArgs); + return unmanagedChannel; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h new file mode 100644 index 00000000000..ab5eee478e1 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -0,0 +1,38 @@ +/* + * + * 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. + * + */ +#import "GRPCChannelFactory.h" + +@class GRPCChannel; + +NS_ASSUME_NONNULL_BEGIN + +@interface GRPCSecureChannelFactory : NSObject + ++ (nullable instancetype)factoryWithPEMRootCerts:(nullable NSString *)rootCerts + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain + error:(NSError **)errorPtr; + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableDictionary *)args; + +- (nullable instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m new file mode 100644 index 00000000000..a0d56e4bdc7 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -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. + * + */ + +#import "GRPCSecureChannelFactory.h" + +#include + +#import "ChannelArgsUtil.h" +#import "GRPCChannel.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation GRPCSecureChannelFactory { + grpc_channel_credentials *_channelCreds; +} + ++ (nullable instancetype)factoryWithPEMRootCerts:(nullable NSString *)rootCerts + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain + error:(NSError **)errorPtr { + return [[self alloc] initWithPEMRootCerts:rootCerts + privateKey:privateKey + certChain:certChain + error:errorPtr]; +} + +- (NSData *)nullTerminatedDataWithString:(NSString *)string { + // dataUsingEncoding: does not return a null-terminated string. + NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; + NSMutableData *nullTerminated = [NSMutableData dataWithData:data]; + [nullTerminated appendBytes:"\0" length:1]; + return nullTerminated; +} + +- (nullable instancetype)initWithPEMRootCerts:(nullable NSString *)rootCerts + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain + error:(NSError **)errorPtr { + static NSData *kDefaultRootsASCII; + static NSError *kDefaultRootsError; + 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) { + kDefaultRootsError = error; + return; + } + kDefaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8]; + }); + + NSData *rootsASCII; + if (rootCerts != nil) { + rootsASCII = [self nullTerminatedDataWithString:rootCerts]; + } else { + if (kDefaultRootsASCII == nil) { + if (errorPtr) { + *errorPtr = kDefaultRootsError; + } + NSAssert( + kDefaultRootsASCII, + @"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: %@", + kDefaultRootsError); + return nil; + } + rootsASCII = kDefaultRootsASCII; + } + + grpc_channel_credentials *creds; + if (privateKey == nil && certChain == nil) { + creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL, NULL); + } else { + grpc_ssl_pem_key_cert_pair key_cert_pair; + NSData *privateKeyASCII = [self nullTerminatedDataWithString:privateKey]; + NSData *certChainASCII = [self nullTerminatedDataWithString:certChain]; + key_cert_pair.private_key = privateKeyASCII.bytes; + key_cert_pair.cert_chain = certChainASCII.bytes; + creds = grpc_ssl_credentials_create(rootsASCII.bytes, &key_cert_pair, NULL, NULL); + } + + if ((self = [super init])) { + _channelCreds = creds; + } + return self; +} + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSMutableArray *)args { + grpc_channel_args *coreChannelArgs = BuildChannelArgs([args copy]); + grpc_channel *unmanagedChannel = + grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); + FreeChannelArgs(coreChannelArgs); + return unmanagedChannel; +} + +- (void)dealloc { + if (_channelCreds != nil) { + grpc_channel_credentials_release(_channelCreds); + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h index f711850c2f0..19aa5367c77 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h @@ -74,9 +74,8 @@ @interface GRPCWrappedCall : NSObject - (instancetype)initWithHost:(NSString *)host - serverName:(NSString *)serverName path:(NSString *)path - timeout:(NSTimeInterval)timeout NS_DESIGNATED_INITIALIZER; + callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; - (void)startBatchWithOperations:(NSArray *)ops errorHandler:(void (^)(void))errorHandler; diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 7781d27ca4f..1c03bc9efdd 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -23,6 +23,7 @@ #include #include +#import "GRPCChannel.h" #import "GRPCCompletionQueue.h" #import "GRPCHost.h" #import "NSData+GRPC.h" @@ -235,31 +236,28 @@ @implementation GRPCWrappedCall { GRPCCompletionQueue *_queue; + GRPCChannel *_channel; grpc_call *_call; } - (instancetype)init { - return [self initWithHost:nil serverName:nil path:nil timeout:0]; + return [self initWithHost:nil path:nil callOptions:[[GRPCCallOptions alloc] init]]; } - (instancetype)initWithHost:(NSString *)host - serverName:(NSString *)serverName path:(NSString *)path - timeout:(NSTimeInterval)timeout { + callOptions:(GRPCCallOptions *)callOptions { if (!path || !host) { [NSException raise:NSInvalidArgumentException format:@"path and host cannot be nil."]; } - if (self = [super init]) { + if ((self = [super init])) { // Each completion queue consumes one thread. There's a trade to be made between creating and // consuming too many threads and having contention of multiple calls in a single completion // queue. Currently we use a singleton queue. _queue = [GRPCCompletionQueue completionQueue]; - - _call = [[GRPCHost hostWithAddress:host] unmanagedCallWithPath:path - serverName:serverName - timeout:timeout - completionQueue:_queue]; + _channel = [GRPCChannel channelWithHost:host callOptions:callOptions]; + _call = [_channel unmanagedCallWithPath:path completionQueue:_queue callOptions:callOptions]; if (_call == NULL) { return nil; } @@ -313,6 +311,8 @@ - (void)dealloc { grpc_call_unref(_call); + [_channel unmanagedCallUnref]; + _channel = nil; } @end From 21c32e8f013986d6b120c852b34e058c82a4cf6d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:33:41 -0700 Subject: [PATCH 0017/2143] Remove redundant forward declaration --- src/objective-c/GRPCClient/GRPCCall.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 3f6ec75c04e..f396ffe599c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -39,8 +39,6 @@ #include "GRPCCallOptions.h" -@class GRPCCallOptions; - #pragma mark gRPC errors /** Domain of NSError objects produced by gRPC. */ From 553664f59bc947d48c73e6c1976e054fe35147f5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:34:21 -0700 Subject: [PATCH 0018/2143] Make dispatcheQueue of responseHandler required --- src/objective-c/GRPCClient/GRPCCall.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index f396ffe599c..64a6df3134c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -150,14 +150,18 @@ extern id const kGRPCTrailersKey; /** An object can implement this protocol to receive responses from server from a call. */ @protocol GRPCResponseHandler + @optional + /** Issued when initial metadata is received from the server. */ - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata; + /** * Issued when a message is received from the server. The message may be raw data from the server * (when using \a GRPCCall2 directly) or deserialized proto object (when using \a ProtoRPC). */ - (void)receivedMessage:(id)message; + /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error @@ -166,9 +170,13 @@ extern id const kGRPCTrailersKey; */ - (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error; +@required + /** * All the responses must be issued to a user-provided dispatch queue. This property specifies the - * dispatch queue to be used for issuing the notifications. + * dispatch queue to be used for issuing the notifications. A serial queue should be provided if + * the order of responses (initial metadata, message, message, ..., message, trailing metadata) + * needs to be maintained. */ @property(atomic, readonly) dispatch_queue_t dispatchQueue; From 5715719afb061feb3c7de931cc8e7126bc9560e5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:36:09 -0700 Subject: [PATCH 0019/2143] Make multiple -init and +new UNAVAILABLE; identify designated initializer --- src/objective-c/GRPCClient/GRPCCall.h | 6 +++++- src/objective-c/ProtoRPC/ProtoRPC.h | 12 ++++++++++-- src/objective-c/ProtoRPC/ProtoService.h | 4 ++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 64a6df3134c..2ee181b93ba 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -190,8 +190,10 @@ extern id const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + /** Initialize with all properties. */ -- (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety; +- (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety NS_DESIGNATED_INITIALIZER; /** The host serving the RPC service. */ @property(copy, readonly) NSString *host; @@ -214,6 +216,8 @@ extern id const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + /** * Designated initializer for a call. * \param requestOptions Protobuf generated parameters for the call. diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 1a27cac2a32..a045ef10a6c 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -26,6 +26,10 @@ /** A unary-request RPC call with Protobuf. */ @interface GRPCUnaryProtoCall : NSObject +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + /** * Users should not use this initializer directly. Call objects will be created, initialized, and * returned to users by methods of the generated service. @@ -34,7 +38,7 @@ message:(GPBMessage *)message responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions - responseClass:(Class)responseClass; + responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** Cancel the call at best effort. */ - (void)cancel; @@ -44,6 +48,10 @@ /** A client-streaming RPC call with Protobuf. */ @interface GRPCStreamingProtoCall : NSObject +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + /** * Users should not use this initializer directly. Call objects will be created, initialized, and * returned to users by methods of the generated service. @@ -51,7 +59,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions - responseClass:(Class)responseClass; + responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** Cancel the call at best effort. */ - (void)cancel; diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index 2105de78a38..2985c5cb2dc 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -30,6 +30,10 @@ __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoService : NSObject +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + - (instancetype)initWithHost : (NSString *)host packageName : (NSString *)packageName serviceName : (NSString *)serviceName callOptions From 0865a6098880b91235348cb9ffe49ddbb13ebdc6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:37:08 -0700 Subject: [PATCH 0020/2143] Typo and doc fix --- src/objective-c/GRPCClient/GRPCCall.h | 3 ++- src/objective-c/GRPCClient/GRPCCallOptions.m | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 2ee181b93ba..01d04807cc6 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -228,7 +228,8 @@ extern id const kGRPCTrailersKey; handler:(id)handler callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; /** - * Convevience initializer for a call that uses default call options. + * Convenience initializer for a call that uses default call options (see GRPCCallOptions.m for + * the default options). */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions handler:(id)handler; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index ee76c2a6420..072b980af42 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -18,6 +18,7 @@ #import "GRPCCallOptions.h" +// The default values for the call options. static NSString *const kDefaultServerAuthority = nil; static const NSTimeInterval kDefaultTimeout = 0; static NSDictionary *const kDefaultInitialMetadata = nil; From efa359b02b0122c90decfbcd5e1659198b565b4e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:50:12 -0700 Subject: [PATCH 0021/2143] Rename handler->responseHandler in function signature --- src/objective-c/GRPCClient/GRPCCall.h | 6 +++--- src/objective-c/GRPCClient/GRPCCall.m | 8 ++++---- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 01d04807cc6..8554860aded 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -221,18 +221,18 @@ extern id const kGRPCTrailersKey; /** * Designated initializer for a call. * \param requestOptions Protobuf generated parameters for the call. - * \param handler The object to which responses should be issed. + * \param responseHandler The object to which responses should be issed. * \param callOptions Options for the call. */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - handler:(id)handler + responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; /** * Convenience initializer for a call that uses default call options (see GRPCCallOptions.m for * the default options). */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - handler:(id)handler; + responseHandler:(id)responseHandler; /** * Starts the call. Can only be called once. diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 519f91e5229..6eb9e2e4066 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -95,7 +95,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - handler:(id)handler + responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *)callOptions { if (!requestOptions || !requestOptions.host || !requestOptions.path) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; @@ -104,7 +104,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; if ((self = [super init])) { _requestOptions = [requestOptions copy]; _callOptions = [callOptions copy]; - _handler = handler; + _handler = responseHandler; _initialMetadataPublished = NO; _pipe = [GRXBufferedPipe pipe]; _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); @@ -114,8 +114,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - handler:(id)handler { - return [self initWithRequestOptions:requestOptions handler:handler callOptions:nil]; + responseHandler:(id)responseHandler { + return [self initWithRequestOptions:requestOptions responseHandler:responseHandler callOptions:nil]; } - (void)start { diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index f89c1606507..34fd54a2162 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -86,7 +86,7 @@ - (void)start { _call = [[GRPCCall2 alloc] initWithRequestOptions:_requestOptions - handler:self + responseHandler:self callOptions:_callOptions]; [_call start]; } From eab498bef453e221abd4602e6ceff16da659b3c1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:44:00 -0700 Subject: [PATCH 0022/2143] Handle GRPCCall2:start: twice --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 8554860aded..5f6afab08cb 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -235,7 +235,7 @@ extern id const kGRPCTrailersKey; responseHandler:(id)responseHandler; /** - * Starts the call. Can only be called once. + * Starts the call. This function should only be called once; additional calls will be discarded. */ - (void)start; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 6eb9e2e4066..9cb4aa34c24 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -92,6 +92,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; BOOL _initialMetadataPublished; GRXBufferedPipe *_pipe; dispatch_queue_t _dispatchQueue; + bool _started; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -108,6 +109,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _initialMetadataPublished = NO; _pipe = [GRXBufferedPipe pipe]; _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + _started = NO; } return self; @@ -120,6 +122,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)start { dispatch_async(_dispatchQueue, ^{ + if (self->_started) { + return; + } + self->_started = YES; if (!self->_callOptions) { self->_callOptions = [[GRPCCallOptions alloc] init]; } From fe8a899b631b3fd804b59ca32639ef2a14bb597f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 16:56:00 -0700 Subject: [PATCH 0023/2143] Rename writeWithData to writeData --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- src/objective-c/tests/GRPCClientTests.m | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 5f6afab08cb..c8f3919a633 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -249,7 +249,7 @@ extern id const kGRPCTrailersKey; /** * Send a message to the server. Data are sent as raw bytes in gRPC message frames. */ -- (void)writeWithData:(NSData *)data; +- (void)writeData:(NSData *)data; /** * Finish the RPC request and half-close the call. The server may still send messages and/or diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9cb4aa34c24..7fdc8fcac26 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -206,7 +206,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; }); } -- (void)writeWithData:(NSData *)data { +- (void)writeData:(NSData *)data { dispatch_async(_dispatchQueue, ^{ [self->_pipe writeValue:data]; }); diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 34fd54a2162..957d6365341 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -120,7 +120,7 @@ dispatch_async(_dispatchQueue, ^{ if (_call) { - [_call writeWithData:[message data]]; + [_call writeData:[message data]]; } }); } diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index bad22d30cbb..db7265c7120 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -332,7 +332,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; callOptions:options]; [call start]; - [call writeWithData:[request data]]; + [call writeData:[request data]]; [call finish]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; @@ -495,7 +495,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; } }] callOptions:options]; - [call writeWithData:[NSData data]]; + [call writeData:[NSData data]]; [call start]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; @@ -632,7 +632,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; callOptions:options]; [call start]; - [call writeWithData:[request data]]; + [call writeData:[request data]]; [call finish]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; From 50dac6721425b225e3e031251c7eb888ec61f07e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 18:09:01 -0700 Subject: [PATCH 0024/2143] Update GRPCCall2:cancel: docs --- src/objective-c/GRPCClient/GRPCCall.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index c8f3919a633..354bdb7cfa2 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -240,9 +240,9 @@ extern id const kGRPCTrailersKey; - (void)start; /** - * Cancel the request of this call at best effort; notifies the server that the RPC should be - * cancelled, and issue callback to the user with an error code CANCELED if the call is not - * finished. + * Cancel the request of this call at best effort. It attempts to notify the server that the RPC + * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code + * CANCELED if no other error code has already been issued. */ - (void)cancel; From 161dc27b2d3882ab3f8a8bcc26733a729e034583 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 18:09:42 -0700 Subject: [PATCH 0025/2143] Copy string fix --- src/objective-c/GRPCClient/GRPCCall.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 7fdc8fcac26..c0413ec6c2d 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -68,8 +68,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { if ((self = [super init])) { - _host = host; - _path = path; + _host = [host copy]; + _path = [path copy]; _safety = safety; } return self; @@ -77,7 +77,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (id)copyWithZone:(NSZone *)zone { GRPCRequestOptions *request = - [[GRPCRequestOptions alloc] initWithHost:[_host copy] path:[_path copy] safety:_safety]; + [[GRPCRequestOptions alloc] initWithHost:_host path:_path safety:_safety]; return request; } From 413077101eab400635732b813da4f1e4a5b69c5a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 18:10:21 -0700 Subject: [PATCH 0026/2143] requestOptions precondition check polishing --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index c0413ec6c2d..c9ee5084868 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -98,7 +98,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *)callOptions { - if (!requestOptions || !requestOptions.host || !requestOptions.path) { + if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; } From f18b08a1a4454f8232c2815f0110427c1a86878f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 10 Oct 2018 18:55:28 -0700 Subject: [PATCH 0027/2143] Check if optional method of GRPCCallOptions are implemented --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 32 ++++++++++++++++++--------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 354bdb7cfa2..304fb17cca5 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -149,7 +149,7 @@ extern id const kGRPCHeadersKey; extern id const kGRPCTrailersKey; /** An object can implement this protocol to receive responses from server from a call. */ -@protocol GRPCResponseHandler +@protocol GRPCResponseHandler @optional diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index c9ee5084868..e1039a1b2a7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -149,12 +149,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; } if (headers) { dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:headers]; + if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + [handler receivedInitialMetadata:headers]; + } }); } if (value) { dispatch_async(handler.dispatchQueue, ^{ - [handler receivedMessage:value]; + if ([handler respondsToSelector:@selector(receivedMessage:)]) { + [handler receivedMessage:value]; + } }); } } @@ -171,11 +175,15 @@ const char *kCFStreamVarName = "grpc_cfstream"; } if (headers) { dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:headers]; + if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + [handler receivedInitialMetadata:headers]; + } }); } dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + [handler closedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + } }); } }); @@ -193,13 +201,15 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (self->_handler) { id handler = self->_handler; dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + [handler closedWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + } }); self->_handler = nil; } From 7b08066d8ff5cca57ee6eaa4cae014d07e4aa8e1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 10:56:51 -0700 Subject: [PATCH 0028/2143] Fix CI failures --- src/objective-c/tests/GRPCClientTests.m | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index db7265c7120..8a4eddb1b70 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -306,7 +306,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; options.oauth2AccessToken = @"bogusToken"; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:callRequest - handler:[[ClientTestsBlockCallbacks alloc] + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { init_md = initialMetadata; } @@ -446,7 +446,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; options.initialMetadata = headers; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:request - handler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( NSDictionary *initialMetadata) { NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; // Test the regex is correct @@ -609,7 +609,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; options.transportType = GRPCTransportTypeInsecure; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:requestOptions - handler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(id message) { NSData *data = (NSData *)message; XCTAssertNotNil(data, @"nil value received as response."); @@ -739,7 +739,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:requestOptions - handler: + responseHandler: [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(id data) { XCTFail( @@ -835,9 +835,9 @@ static GRPCProtoMethod *kFullDuplexCallMethod; const double kMargin = 0.1; __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; - NSString *const kDummyAddress = [NSString stringWithFormat:@"8.8.8.8:1"]; + NSString *const kDummyAddress = [NSString stringWithFormat:@"127.0.0.1:10000"]; GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kDummyAddress path:@"" safety:GRPCCallSafetyDefault]; + [[GRPCRequestOptions alloc] initWithHost:kDummyAddress path:@"/dummy/path" safety:GRPCCallSafetyDefault]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.connectMinTimeout = timeout; options.connectInitialBackoff = backoff; @@ -846,7 +846,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; NSDate *startTime = [NSDate date]; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:requestOptions - handler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(id data) { XCTFail(@"Received message. Should not reach here."); } From 5d16c2ff92eb49319d9028cbe99bb80bf41e0578 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 11:20:26 -0700 Subject: [PATCH 0029/2143] Move issuance of response in helper functions --- src/objective-c/GRPCClient/GRPCCall.m | 54 ++++++++++++++++----------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index e1039a1b2a7..1e9bc41b41b 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -141,25 +141,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(id value) { dispatch_async(self->_dispatchQueue, ^{ if (self->_handler) { - id handler = self->_handler; NSDictionary *headers = nil; if (!self->_initialMetadataPublished) { headers = self->_call.responseHeaders; self->_initialMetadataPublished = YES; } if (headers) { - dispatch_async(handler.dispatchQueue, ^{ - if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { - [handler receivedInitialMetadata:headers]; - } - }); + [self issueInitialMetadata:headers]; } if (value) { - dispatch_async(handler.dispatchQueue, ^{ - if ([handler respondsToSelector:@selector(receivedMessage:)]) { - [handler receivedMessage:value]; - } - }); + [self issueMessage:value]; } } }); @@ -167,24 +158,15 @@ const char *kCFStreamVarName = "grpc_cfstream"; completionHandler:^(NSError *errorOrNil) { dispatch_async(self->_dispatchQueue, ^{ if (self->_handler) { - id handler = self->_handler; NSDictionary *headers = nil; if (!self->_initialMetadataPublished) { headers = self->_call.responseHeaders; self->_initialMetadataPublished = YES; } if (headers) { - dispatch_async(handler.dispatchQueue, ^{ - if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { - [handler receivedInitialMetadata:headers]; - } - }); + [self issueInitialMetadata:headers]; } - dispatch_async(handler.dispatchQueue, ^{ - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [handler closedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; - } - }); + [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; } }); }]; @@ -230,6 +212,34 @@ const char *kCFStreamVarName = "grpc_cfstream"; }); } +- (void)issueInitialMetadata:(NSDictionary *)initialMetadata { + id handler = self->_handler; + if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedInitialMetadata:initialMetadata]; + }); + } +} + +- (void)issueMessage:(id)message { + id handler = self->_handler; + if ([handler respondsToSelector:@selector(receivedMessage:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedMessage:message]; + }); + } +} + +- (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata + error:(NSError *)error { + id handler = self->_handler; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:self->_call.responseTrailers error:error]; + }); + } +} + @end // The following methods of a C gRPC call object aren't reentrant, and thus From 92e81c80efb8d5dcbc6362206be09b2ef9107a2b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 11:33:27 -0700 Subject: [PATCH 0030/2143] Add comment on clearing GRPCCall2._handler --- src/objective-c/GRPCClient/GRPCCall.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 1e9bc41b41b..ace149fad5a 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -167,6 +167,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self issueInitialMetadata:headers]; } [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + + // Clean up _handler so that no more responses are reported to the handler. + self->_handler = nil; } }); }]; @@ -193,6 +196,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; }]]; } }); + + // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; } }); From b634447d2cb762b47365218e1affd317a4ccd8b3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:15:45 -0700 Subject: [PATCH 0031/2143] Resetting _call and _handler on finish --- src/objective-c/GRPCClient/GRPCCall.m | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index ace149fad5a..d0495f6cbf1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -170,6 +170,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; + + // If server terminated the call we should close the send path too. + if (self->_call) { + [self->_pipe writesFinishedWithError:nil]; + self->_call = nil; + self->_pipe = nil; + } } }); }]; @@ -182,6 +189,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (self->_call) { [self->_call cancel]; self->_call = nil; + self->_pipe = nil; } if (self->_handler) { id handler = self->_handler; @@ -214,6 +222,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (self->_call) { [self->_pipe writesFinishedWithError:nil]; } + self->_call = nil; + self->_pipe = nil; }); } From aabce5e19ca93c54fc0560116e0e8cb53dabdc19 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:16:09 -0700 Subject: [PATCH 0032/2143] Initialize flag --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index d0495f6cbf1..40db83155b4 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -541,7 +541,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)sendHeaders { // TODO (mxyan): Remove after deprecated methods are removed - uint32_t callSafetyFlags; + uint32_t callSafetyFlags = 0; switch (_callSafety) { case GRPCCallSafetyDefault: callSafetyFlags = 0; From fb9d054ac7da0cad67cb7431fc91823c7349df33 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:16:35 -0700 Subject: [PATCH 0033/2143] Check string length --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 40db83155b4..0f2c367331f 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -738,7 +738,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } else { callOptions = [[GRPCMutableCallOptions alloc] init]; } - if (_serverName != nil) { + if (_serverName.length != 0) { callOptions.serverAuthority = _serverName; } if (_timeout != 0) { From bca7e68ccbf15eab3d3a8a09d0e3d50d7db49cf9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:17:40 -0700 Subject: [PATCH 0034/2143] use strong self for authTokenProvider --- src/objective-c/GRPCClient/GRPCCall.m | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 0f2c367331f..28d3b52d5e1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -761,15 +761,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; } if (_callOptions.authTokenProvider != nil) { self.isWaitingForToken = YES; - __weak typeof(self) weakSelf = self; [self.tokenProvider getTokenWithHandler:^(NSString *token) { - typeof(self) strongSelf = weakSelf; - if (strongSelf && strongSelf.isWaitingForToken) { + if (self.isWaitingForToken) { if (token) { - strongSelf->_fetchedOauth2AccessToken = token; + self->_fetchedOauth2AccessToken = [token copy]; } - [strongSelf startCallWithWriteable:writeable]; - strongSelf.isWaitingForToken = NO; + [self startCallWithWriteable:writeable]; + self.isWaitingForToken = NO; } }]; } else { From 8592dc27223e9ec41f4f52634f662c4485bd119b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:31:07 -0700 Subject: [PATCH 0035/2143] Rename GRPCTransportTypeDefault to GRPCTransportTypeChttp2CFStream --- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- src/objective-c/tests/ChannelTests/ChannelPoolTest.m | 2 +- src/objective-c/tests/ChannelTests/ChannelTests.m | 4 ++-- src/objective-c/tests/InteropTests.m | 2 +- src/objective-c/tests/InteropTestsLocalSSL.m | 2 +- .../InteropTestsMultipleChannels.m | 2 +- src/objective-c/tests/InteropTestsRemote.m | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 75b320ca6d6..1093044c0c8 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -42,7 +42,7 @@ typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) { // The transport to be used by a gRPC call typedef NS_ENUM(NSInteger, GRPCTransportType) { // gRPC internal HTTP/2 stack with BoringSSL - GRPCTransportTypeDefault = 0, + GRPCTransportTypeChttp2BoringSSL = 0, // Cronet stack GRPCTransportTypeCronet, // Insecure channel. FOR TEST ONLY! diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 072b980af42..0216342817b 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -37,7 +37,7 @@ static NSString *const kDefaultPemPrivateKey = nil; static NSString *const kDefaultPemCertChain = nil; static NSString *const kDefaultOauth2AccessToken = nil; static const id kDefaultAuthTokenProvider = nil; -static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeDefault; +static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2BoringSSL; static NSString *const kDefaultHostNameOverride = nil; static const id kDefaultLogContext = nil; static NSString *kDefaultChannelPoolDomain = nil; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index b5f0949ef73..340f4f3c83e 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -49,7 +49,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; id factory; GRPCTransportType type = _callOptions.transportType; switch (type) { - case GRPCTransportTypeDefault: + case GRPCTransportTypeChttp2BoringSSL: // TODO (mxyan): Remove when the API is deprecated #ifdef GRPC_COMPILE_WITH_CRONET if (![GRPCCall isUsingCronet]) { diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index 3b6b10b1a5f..9e1c9eca746 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -127,7 +127,7 @@ NSString *kDummyHost = @"dummy.host"; GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; options1.transportType = GRPCTransportTypeInsecure; GRPCMutableCallOptions *options2 = [[GRPCMutableCallOptions alloc] init]; - options2.transportType = GRPCTransportTypeDefault; + options2.transportType = GRPCTransportTypeChttp2BoringSSL; GRPCChannelConfiguration *config1 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelConfiguration *config2 = diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 0a8b7ae6ee6..64c3356b13f 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -72,7 +72,7 @@ - (void)testDifferentChannelParameters { NSString *host = @"grpc-test.sandbox.googleapis.com"; GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeDefault; + options1.transportType = GRPCTransportTypeChttp2BoringSSL; NSMutableDictionary *args = [NSMutableDictionary new]; args[@"abc"] = @"xyz"; options1.additionalChannelArgs = [args copy]; @@ -80,7 +80,7 @@ options2.transportType = GRPCTransportTypeInsecure; options2.additionalChannelArgs = [args copy]; GRPCMutableCallOptions *options3 = [[GRPCMutableCallOptions alloc] init]; - options3.transportType = GRPCTransportTypeDefault; + options3.transportType = GRPCTransportTypeChttp2BoringSSL; args[@"def"] = @"uvw"; options3.additionalChannelArgs = [args copy]; GRPCChannel *channel1 = [GRPCChannel channelWithHost:host callOptions:options1]; diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 54af7036c35..16d5040a733 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -144,7 +144,7 @@ BOOL isRemoteInteropTest(NSString *host) { } + (GRPCTransportType)transportType { - return GRPCTransportTypeDefault; + return GRPCTransportTypeChttp2BoringSSL; } + (NSString *)pemRootCert { diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m index eb72dd1d311..997dd87eeea 100644 --- a/src/objective-c/tests/InteropTestsLocalSSL.m +++ b/src/objective-c/tests/InteropTestsLocalSSL.m @@ -57,7 +57,7 @@ static int32_t kLocalInteropServerOverhead = 10; } + (GRPCTransportType)transportType { - return GRPCTransportTypeDefault; + return GRPCTransportTypeChttp2BoringSSL; } - (void)setUp { diff --git a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m index eb0ba7f34b3..b1d663584c8 100644 --- a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m +++ b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m @@ -114,7 +114,7 @@ dispatch_once_t initCronet; XCTAssertNil(error); options = [[GRPCCallOptions alloc] init]; - options.transportType = GRPCTransportTypeDefault; + options.transportType = GRPCTransportTypeChttp2BoringSSL; options.pemRootCert = certs; options.hostNameOverride = @"foo.test.google.fr"; _localSSLService.options = options; diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTestsRemote.m index 516a1f432a5..30670facad0 100644 --- a/src/objective-c/tests/InteropTestsRemote.m +++ b/src/objective-c/tests/InteropTestsRemote.m @@ -59,7 +59,7 @@ static int32_t kRemoteInteropServerOverhead = 12; } #else + (GRPCTransportType)transportType { - return GRPCTransportTypeDefault; + return GRPCTransportTypeChttp2BoringSSL; } #endif From 96709ecb8cde75f2750d96dc288167292790eb5a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:34:24 -0700 Subject: [PATCH 0036/2143] Fix another NSString* != nil to NSString.length != 0 --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 340f4f3c83e..2b08eb8d5e3 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -131,7 +131,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; args[@GRPC_ARG_MOBILE_LOG_CONTEXT] = _callOptions.logContext; } - if (_callOptions.channelPoolDomain != nil) { + if (_callOptions.channelPoolDomain.length != 0) { args[@GRPC_ARG_CHANNEL_POOL_DOMAIN] = _callOptions.channelPoolDomain; } From 0d4ac971df9d2a795eac674e0a105d0c51f7387b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:45:43 -0700 Subject: [PATCH 0037/2143] Restrict NSTimeInterval parameters to non-negative --- src/objective-c/GRPCClient/GRPCCallOptions.h | 29 +++++++++------- src/objective-c/GRPCClient/GRPCCallOptions.m | 36 ++++++++++++++++---- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 1093044c0c8..70dd7741fd1 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -120,15 +120,15 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ @property(readonly) BOOL enableRetry; -/** - * HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two - * PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the - * call should wait for PING ACK. If PING ACK is not received after this period, the call fails. - */ +// HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two +// PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the +// call should wait for PING ACK. If PING ACK is not received after this period, the call fails. +// Negative values are not allowed. @property(readonly) NSTimeInterval keepaliveInterval; @property(readonly) NSTimeInterval keepaliveTimeout; -// Parameters for connection backoff. For details of gRPC's backoff behavior, refer to +// Parameters for connection backoff. Negative values are not allowed. +// For details of gRPC's backoff behavior, refer to // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md @property(readonly) NSTimeInterval connectMinTimeout; @property(readonly) NSTimeInterval connectInitialBackoff; @@ -203,7 +203,8 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to * positive, the gRPC call returns with status GRPCErrorCodeDeadlineExceeded if it is not completed - * within \a timeout seconds. A negative value is not allowed. + * within \a timeout seconds. Negative value is invalid; setting the parameter to negative value + * will reset the parameter to 0. */ @property(readwrite) NSTimeInterval timeout; @@ -249,15 +250,17 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ @property(readwrite) BOOL enableRetry; -/** - * HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two - * PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the - * call should wait for PING ACK. If PING ACK is not received after this period, the call fails. - */ +// HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two +// PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the +// call should wait for PING ACK. If PING ACK is not received after this period, the call fails. +// Negative values are invalid; setting these parameters to negative value will reset the +// corresponding parameter to 0. @property(readwrite) NSTimeInterval keepaliveInterval; @property(readwrite) NSTimeInterval keepaliveTimeout; -// Parameters for connection backoff. For details of gRPC's backoff behavior, refer to +// Parameters for connection backoff. Negative value is invalid; setting the parameters to negative +// value will reset corresponding parameter to 0. +// For details of gRPC's backoff behavior, refer to // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md @property(readwrite) NSTimeInterval connectMinTimeout; @property(readwrite) NSTimeInterval connectInitialBackoff; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 0216342817b..1f25df7d53b 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -342,7 +342,11 @@ static NSUInteger kDefaultChannelId = 0; } - (void)setTimeout:(NSTimeInterval)timeout { - _timeout = timeout; + if (timeout < 0) { + _timeout = 0; + } else { + _timeout = timeout; + } } - (void)setOauth2AccessToken:(NSString *)oauth2AccessToken { @@ -374,23 +378,43 @@ static NSUInteger kDefaultChannelId = 0; } - (void)setKeepaliveInterval:(NSTimeInterval)keepaliveInterval { - _keepaliveInterval = keepaliveInterval; + if (keepaliveInterval < 0) { + _keepaliveInterval = 0; + } else { + _keepaliveInterval = keepaliveInterval; + } } - (void)setKeepaliveTimeout:(NSTimeInterval)keepaliveTimeout { - _keepaliveTimeout = keepaliveTimeout; + if (keepaliveTimeout < 0) { + _keepaliveTimeout = 0; + } else { + _keepaliveTimeout = keepaliveTimeout; + } } - (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout { - _connectMinTimeout = connectMinTimeout; + if (connectMinTimeout < 0) { + connectMinTimeout = 0; + } else { + _connectMinTimeout = connectMinTimeout; + } } - (void)setConnectInitialBackoff:(NSTimeInterval)connectInitialBackoff { - _connectInitialBackoff = connectInitialBackoff; + if (connectInitialBackoff < 0) { + _connectInitialBackoff = 0; + } else { + _connectInitialBackoff = connectInitialBackoff; + } } - (void)setConnectMaxBackoff:(NSTimeInterval)connectMaxBackoff { - _connectMaxBackoff = connectMaxBackoff; + if (connectMaxBackoff < 0) { + _connectMaxBackoff = 0; + } else { + _connectMaxBackoff = connectMaxBackoff; + } } - (void)setAdditionalChannelArgs:(NSDictionary *)additionalChannelArgs { From a397862fd56bca95da49062b7ca622a0823bc15a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 13:52:24 -0700 Subject: [PATCH 0038/2143] property attribute fixes --- src/objective-c/GRPCClient/GRPCCallOptions.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 70dd7741fd1..abfe3965115 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -64,7 +64,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * :authority header field of the call and performs an extra check that server's certificate * matches the :authority header. */ -@property(readonly) NSString *serverAuthority; +@property(copy, readonly) NSString *serverAuthority; /** * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to @@ -91,7 +91,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * Initial metadata key-value pairs that should be included in the request. */ -@property(copy, readwrite) NSDictionary *initialMetadata; +@property(copy, readonly) NSDictionary *initialMetadata; // Channel parameters; take into account of channel signature. @@ -198,7 +198,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * :authority header field of the call and performs an extra check that server's certificate * matches the :authority header. */ -@property(readwrite) NSString *serverAuthority; +@property(copy, readwrite) NSString *serverAuthority; /** * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to From 2c1c22c3f1b9c0fe36589da691fbabc60ad1aa25 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 14:31:05 -0700 Subject: [PATCH 0039/2143] Do not nullify GRPCCall2._call on half-close --- src/objective-c/GRPCClient/GRPCCall.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 28d3b52d5e1..36cb71399ca 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -171,7 +171,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; - // If server terminated the call we should close the send path too. if (self->_call) { [self->_pipe writesFinishedWithError:nil]; self->_call = nil; @@ -222,7 +221,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (self->_call) { [self->_pipe writesFinishedWithError:nil]; } - self->_call = nil; self->_pipe = nil; }); } @@ -247,10 +245,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - id handler = self->_handler; + id handler = _handler; + NSDictionary *trailers = _call.responseTrailers; if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:self->_call.responseTrailers error:error]; + [handler closedWithTrailingMetadata:trailers error:error]; }); } } From 0fc040d19acc960ed3ab331ed92b38b43d32a284 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 14:33:00 -0700 Subject: [PATCH 0040/2143] Rename pemXxx parameters to PEMXxx --- src/objective-c/GRPCClient/GRPCCallOptions.h | 12 +-- src/objective-c/GRPCClient/GRPCCallOptions.m | 84 +++++++++---------- .../GRPCClient/private/GRPCChannelPool.m | 24 +++--- src/objective-c/GRPCClient/private/GRPCHost.m | 14 ++-- src/objective-c/tests/InteropTests.h | 2 +- src/objective-c/tests/InteropTests.m | 8 +- .../tests/InteropTestsLocalCleartext.m | 2 +- src/objective-c/tests/InteropTestsLocalSSL.m | 2 +- .../InteropTestsMultipleChannels.m | 2 +- src/objective-c/tests/InteropTestsRemote.m | 2 +- 10 files changed, 76 insertions(+), 76 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index abfe3965115..ea7c1bf22db 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -146,17 +146,17 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default * root certificates. */ -@property(copy, readonly) NSString *pemRootCert; +@property(copy, readonly) NSString *PEMRootCertificates; /** * PEM format private key for client authentication, if required by the server. */ -@property(copy, readonly) NSString *pemPrivateKey; +@property(copy, readonly) NSString *PEMPrivateKey; /** * PEM format certificate chain for client authentication, if required by the server. */ -@property(copy, readonly) NSString *pemCertChain; +@property(copy, readonly) NSString *PEMCertChain; /** * Select the transport type to be used for this call. @@ -278,17 +278,17 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default * root certificates. */ -@property(copy, readwrite) NSString *pemRootCert; +@property(copy, readwrite) NSString *PEMRootCertificates; /** * PEM format private key for client authentication, if required by the server. */ -@property(copy, readwrite) NSString *pemPrivateKey; +@property(copy, readwrite) NSString *PEMPrivateKey; /** * PEM format certificate chain for client authentication, if required by the server. */ -@property(copy, readwrite) NSString *pemCertChain; +@property(copy, readwrite) NSString *PEMCertChain; /** * Select the transport type to be used for this call. diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 1f25df7d53b..539cb9929db 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -32,9 +32,9 @@ static const NSTimeInterval kDefaultConnectMinTimeout = 0; static const NSTimeInterval kDefaultConnectInitialBackoff = 0; static const NSTimeInterval kDefaultConnectMaxBackoff = 0; static NSDictionary *const kDefaultAdditionalChannelArgs = nil; -static NSString *const kDefaultPemRootCert = nil; -static NSString *const kDefaultPemPrivateKey = nil; -static NSString *const kDefaultPemCertChain = nil; +static NSString *const kDefaultPEMRootCertificates = nil; +static NSString *const kDefaultPEMPrivateKey = nil; +static NSString *const kDefaultPEMCertChain = nil; static NSString *const kDefaultOauth2AccessToken = nil; static const id kDefaultAuthTokenProvider = nil; static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2BoringSSL; @@ -60,9 +60,9 @@ static NSUInteger kDefaultChannelId = 0; NSTimeInterval _connectInitialBackoff; NSTimeInterval _connectMaxBackoff; NSDictionary *_additionalChannelArgs; - NSString *_pemRootCert; - NSString *_pemPrivateKey; - NSString *_pemCertChain; + NSString *_PEMRootCertificates; + NSString *_PEMPrivateKey; + NSString *_PEMCertChain; GRPCTransportType _transportType; NSString *_hostNameOverride; id _logContext; @@ -85,9 +85,9 @@ static NSUInteger kDefaultChannelId = 0; @synthesize connectInitialBackoff = _connectInitialBackoff; @synthesize connectMaxBackoff = _connectMaxBackoff; @synthesize additionalChannelArgs = _additionalChannelArgs; -@synthesize pemRootCert = _pemRootCert; -@synthesize pemPrivateKey = _pemPrivateKey; -@synthesize pemCertChain = _pemCertChain; +@synthesize PEMRootCertificates = _PEMRootCertificates; +@synthesize PEMPrivateKey = _PEMPrivateKey; +@synthesize PEMCertChain = _PEMCertChain; @synthesize transportType = _transportType; @synthesize hostNameOverride = _hostNameOverride; @synthesize logContext = _logContext; @@ -110,9 +110,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:kDefaultConnectInitialBackoff connectMaxBackoff:kDefaultConnectMaxBackoff additionalChannelArgs:kDefaultAdditionalChannelArgs - pemRootCert:kDefaultPemRootCert - pemPrivateKey:kDefaultPemPrivateKey - pemCertChain:kDefaultPemCertChain + PEMRootCertificates:kDefaultPEMRootCertificates + PEMPrivateKey:kDefaultPEMPrivateKey + PEMCertChain:kDefaultPEMCertChain transportType:kDefaultTransportType hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext @@ -135,9 +135,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:(NSTimeInterval)connectInitialBackoff connectMaxBackoff:(NSTimeInterval)connectMaxBackoff additionalChannelArgs:(NSDictionary *)additionalChannelArgs - pemRootCert:(NSString *)pemRootCert - pemPrivateKey:(NSString *)pemPrivateKey - pemCertChain:(NSString *)pemCertChain + PEMRootCertificates:(NSString *)PEMRootCertificates + PEMPrivateKey:(NSString *)PEMPrivateKey + PEMCertChain:(NSString *)PEMCertChain transportType:(GRPCTransportType)transportType hostNameOverride:(NSString *)hostNameOverride logContext:(id)logContext @@ -159,9 +159,9 @@ static NSUInteger kDefaultChannelId = 0; _connectInitialBackoff = connectInitialBackoff; _connectMaxBackoff = connectMaxBackoff; _additionalChannelArgs = additionalChannelArgs; - _pemRootCert = pemRootCert; - _pemPrivateKey = pemPrivateKey; - _pemCertChain = pemCertChain; + _PEMRootCertificates = PEMRootCertificates; + _PEMPrivateKey = PEMPrivateKey; + _PEMCertChain = PEMCertChain; _transportType = transportType; _hostNameOverride = hostNameOverride; _logContext = logContext; @@ -188,9 +188,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - pemRootCert:_pemRootCert - pemPrivateKey:_pemPrivateKey - pemCertChain:_pemCertChain + PEMRootCertificates:_PEMRootCertificates + PEMPrivateKey:_PEMPrivateKey + PEMCertChain:_PEMCertChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -216,9 +216,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - pemRootCert:_pemRootCert - pemPrivateKey:_pemPrivateKey - pemCertChain:_pemCertChain + PEMRootCertificates:_PEMRootCertificates + PEMPrivateKey:_PEMPrivateKey + PEMCertChain:_PEMCertChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -246,9 +246,9 @@ static NSUInteger kDefaultChannelId = 0; @dynamic connectInitialBackoff; @dynamic connectMaxBackoff; @dynamic additionalChannelArgs; -@dynamic pemRootCert; -@dynamic pemPrivateKey; -@dynamic pemCertChain; +@dynamic PEMRootCertificates; +@dynamic PEMPrivateKey; +@dynamic PEMCertChain; @dynamic transportType; @dynamic hostNameOverride; @dynamic logContext; @@ -271,9 +271,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:kDefaultConnectInitialBackoff connectMaxBackoff:kDefaultConnectMaxBackoff additionalChannelArgs:kDefaultAdditionalChannelArgs - pemRootCert:kDefaultPemRootCert - pemPrivateKey:kDefaultPemPrivateKey - pemCertChain:kDefaultPemCertChain + PEMRootCertificates:kDefaultPEMRootCertificates + PEMPrivateKey:kDefaultPEMPrivateKey + PEMCertChain:kDefaultPEMCertChain transportType:kDefaultTransportType hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext @@ -298,9 +298,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - pemRootCert:_pemRootCert - pemPrivateKey:_pemPrivateKey - pemCertChain:_pemCertChain + PEMRootCertificates:_PEMRootCertificates + PEMPrivateKey:_PEMPrivateKey + PEMCertChain:_PEMCertChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -326,9 +326,9 @@ static NSUInteger kDefaultChannelId = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - pemRootCert:_pemRootCert - pemPrivateKey:_pemPrivateKey - pemCertChain:_pemCertChain + PEMRootCertificates:_PEMRootCertificates + PEMPrivateKey:_PEMPrivateKey + PEMCertChain:_PEMCertChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -421,16 +421,16 @@ static NSUInteger kDefaultChannelId = 0; _additionalChannelArgs = additionalChannelArgs; } -- (void)setPemRootCert:(NSString *)pemRootCert { - _pemRootCert = pemRootCert; +- (void)setPEMRootCertificates:(NSString *)PEMRootCertificates { + _PEMRootCertificates = PEMRootCertificates; } -- (void)setPemPrivateKey:(NSString *)pemPrivateKey { - _pemPrivateKey = pemPrivateKey; +- (void)setPEMPrivateKey:(NSString *)PEMPrivateKey { + _PEMPrivateKey = PEMPrivateKey; } -- (void)setPemCertChain:(NSString *)pemCertChain { - _pemCertChain = pemCertChain; +- (void)setPEMCertChain:(NSString *)PEMCertChain { + _PEMCertChain = PEMCertChain; } - (void)setTransportType:(GRPCTransportType)transportType { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 2b08eb8d5e3..9007f5fed51 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -54,9 +54,9 @@ const NSTimeInterval kChannelDestroyDelay = 30; #ifdef GRPC_COMPILE_WITH_CRONET if (![GRPCCall isUsingCronet]) { #endif - factory = [GRPCSecureChannelFactory factoryWithPEMRootCerts:_callOptions.pemRootCert - privateKey:_callOptions.pemPrivateKey - certChain:_callOptions.pemCertChain + factory = [GRPCSecureChannelFactory factoryWithPEMRootCerts:_callOptions.PEMRootCertificates + privateKey:_callOptions.PEMPrivateKey + certChain:_callOptions.PEMCertChain error:&error]; if (error) { NSLog(@"Error creating secure channel factory: %@", error); @@ -167,14 +167,14 @@ const NSTimeInterval kChannelDestroyDelay = 30; [obj.callOptions.additionalChannelArgs isEqualToDictionary:_callOptions.additionalChannelArgs])) return NO; - if (!(obj.callOptions.pemRootCert == _callOptions.pemRootCert || - [obj.callOptions.pemRootCert isEqualToString:_callOptions.pemRootCert])) + if (!(obj.callOptions.PEMRootCertificates == _callOptions.PEMRootCertificates || + [obj.callOptions.PEMRootCertificates isEqualToString:_callOptions.PEMRootCertificates])) return NO; - if (!(obj.callOptions.pemPrivateKey == _callOptions.pemPrivateKey || - [obj.callOptions.pemPrivateKey isEqualToString:_callOptions.pemPrivateKey])) + if (!(obj.callOptions.PEMPrivateKey == _callOptions.PEMPrivateKey || + [obj.callOptions.PEMPrivateKey isEqualToString:_callOptions.PEMPrivateKey])) return NO; - if (!(obj.callOptions.pemCertChain == _callOptions.pemCertChain || - [obj.callOptions.pemCertChain isEqualToString:_callOptions.pemCertChain])) + if (!(obj.callOptions.PEMCertChain == _callOptions.PEMCertChain || + [obj.callOptions.PEMCertChain isEqualToString:_callOptions.PEMCertChain])) return NO; if (!(obj.callOptions.hostNameOverride == _callOptions.hostNameOverride || [obj.callOptions.hostNameOverride isEqualToString:_callOptions.hostNameOverride])) @@ -204,9 +204,9 @@ const NSTimeInterval kChannelDestroyDelay = 30; result ^= (unsigned int)(_callOptions.connectInitialBackoff * 1000); result ^= (unsigned int)(_callOptions.connectMaxBackoff * 1000); result ^= _callOptions.additionalChannelArgs.hash; - result ^= _callOptions.pemRootCert.hash; - result ^= _callOptions.pemPrivateKey.hash; - result ^= _callOptions.pemCertChain.hash; + result ^= _callOptions.PEMRootCertificates.hash; + result ^= _callOptions.PEMPrivateKey.hash; + result ^= _callOptions.PEMCertChain.hash; result ^= _callOptions.hostNameOverride.hash; result ^= _callOptions.transportType; result ^= [_callOptions.logContext hash]; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 0e3fa610f9e..429958b4083 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -38,8 +38,8 @@ NS_ASSUME_NONNULL_BEGIN static NSMutableDictionary *kHostCache; @implementation GRPCHost { - NSString *_pemRootCerts; - NSString *_pemPrivateKey; + NSString *_PEMRootCertificates; + NSString *_PEMPrivateKey; NSString *_pemCertChain; } @@ -92,8 +92,8 @@ static NSMutableDictionary *kHostCache; withPrivateKey:(nullable NSString *)pemPrivateKey withCertChain:(nullable NSString *)pemCertChain error:(NSError **)errorPtr { - _pemRootCerts = pemRootCerts; - _pemPrivateKey = pemPrivateKey; + _PEMRootCertificates = pemRootCerts; + _PEMPrivateKey = pemPrivateKey; _pemCertChain = pemCertChain; return YES; } @@ -109,9 +109,9 @@ static NSMutableDictionary *kHostCache; options.connectMinTimeout = (NSTimeInterval)_minConnectTimeout / 1000; options.connectInitialBackoff = (NSTimeInterval)_initialConnectBackoff / 1000; options.connectMaxBackoff = (NSTimeInterval)_maxConnectBackoff / 1000; - options.pemRootCert = _pemRootCerts; - options.pemPrivateKey = _pemPrivateKey; - options.pemCertChain = _pemCertChain; + options.PEMRootCertificates = _PEMRootCertificates; + options.PEMPrivateKey = _PEMPrivateKey; + options.PEMCertChain = _pemCertChain; options.hostNameOverride = _hostNameOverride; options.transportType = _transportType; options.logContext = _logContext; diff --git a/src/objective-c/tests/InteropTests.h b/src/objective-c/tests/InteropTests.h index e223839d3ac..038f24b62e5 100644 --- a/src/objective-c/tests/InteropTests.h +++ b/src/objective-c/tests/InteropTests.h @@ -51,7 +51,7 @@ * The root certificates to be used. The base implementation returns nil. Subclasses should override * to appropriate settings. */ -+ (NSString *)pemRootCert; ++ (NSString *)PEMRootCertificates; /** * The root certificates to be used. The base implementation returns nil. Subclasses should override diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 16d5040a733..0835ff909f5 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -147,7 +147,7 @@ BOOL isRemoteInteropTest(NSString *host) { return GRPCTransportTypeChttp2BoringSSL; } -+ (NSString *)pemRootCert { ++ (NSString *)PEMRootCertificates { return nil; } @@ -202,7 +202,7 @@ BOOL isRemoteInteropTest(NSString *host) { GPBEmpty *request = [GPBEmpty message]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = self.class.transportType; - options.pemRootCert = self.class.pemRootCert; + options.PEMRootCertificates = self.class.PEMRootCertificates; options.hostNameOverride = self.class.hostNameOverride; [_service @@ -484,7 +484,7 @@ BOOL isRemoteInteropTest(NSString *host) { requestedResponseSize:responses[index]]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = self.class.transportType; - options.pemRootCert = self.class.pemRootCert; + options.PEMRootCertificates = self.class.PEMRootCertificates; options.hostNameOverride = self.class.hostNameOverride; __block GRPCStreamingProtoCall *call = [_service @@ -629,7 +629,7 @@ BOOL isRemoteInteropTest(NSString *host) { GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = self.class.transportType; - options.pemRootCert = self.class.pemRootCert; + options.PEMRootCertificates = self.class.PEMRootCertificates; options.hostNameOverride = self.class.hostNameOverride; id request = diff --git a/src/objective-c/tests/InteropTestsLocalCleartext.m b/src/objective-c/tests/InteropTestsLocalCleartext.m index 42e327a3303..a9c69183332 100644 --- a/src/objective-c/tests/InteropTestsLocalCleartext.m +++ b/src/objective-c/tests/InteropTestsLocalCleartext.m @@ -41,7 +41,7 @@ static int32_t kLocalInteropServerOverhead = 10; return kLocalCleartextHost; } -+ (NSString *)pemRootCert { ++ (NSString *)PEMRootCertificates { return nil; } diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m index 997dd87eeea..759a080380d 100644 --- a/src/objective-c/tests/InteropTestsLocalSSL.m +++ b/src/objective-c/tests/InteropTestsLocalSSL.m @@ -40,7 +40,7 @@ static int32_t kLocalInteropServerOverhead = 10; return kLocalSSLHost; } -+ (NSString *)pemRootCert { ++ (NSString *)PEMRootCertificates { NSBundle *bundle = [NSBundle bundleForClass:self.class]; NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; diff --git a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m index b1d663584c8..237804d23de 100644 --- a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m +++ b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m @@ -115,7 +115,7 @@ dispatch_once_t initCronet; options = [[GRPCCallOptions alloc] init]; options.transportType = GRPCTransportTypeChttp2BoringSSL; - options.pemRootCert = certs; + options.PEMRootCertificates = certs; options.hostNameOverride = @"foo.test.google.fr"; _localSSLService.options = options; } diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTestsRemote.m index 30670facad0..c1cd9b81efc 100644 --- a/src/objective-c/tests/InteropTestsRemote.m +++ b/src/objective-c/tests/InteropTestsRemote.m @@ -41,7 +41,7 @@ static int32_t kRemoteInteropServerOverhead = 12; return kRemoteSSLHost; } -+ (NSString *)pemRootCert { ++ (NSString *)PEMRootCertificates { return nil; } From 521ffacd7c6b90b884aae72bc342d134e41053fb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 14:44:55 -0700 Subject: [PATCH 0041/2143] Add example to channelPoolDomain --- src/objective-c/GRPCClient/GRPCCallOptions.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index ea7c1bf22db..dcd4de62233 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -307,7 +307,9 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * A string that specify the domain where channel is being cached. Channels with different domains - * will not get cached to the same connection. + * will not get cached to the same connection. For example, a gRPC example app may use the channel + * pool domain 'io.grpc.example' so that its calls do not reuse the channel created by other modules + * in the same process. */ @property(copy, readwrite) NSString *channelPoolDomain; From 2c47c953380d0a02df4bc7e4d7772b235cd7da9c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 16:17:03 -0700 Subject: [PATCH 0042/2143] Rename channelId->channelID --- src/objective-c/GRPCClient/GRPCCallOptions.h | 14 +++++----- src/objective-c/GRPCClient/GRPCCallOptions.m | 28 +++++++++---------- .../GRPCClient/private/GRPCChannelPool.m | 4 +-- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index dcd4de62233..9c6e00fd187 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -181,9 +181,9 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * Channel id allows a call to force creating a new channel (connection) rather than using a cached - * channel. Calls using distinct channelId will not get cached to the same connection. + * channel. Calls using distinct channelID will not get cached to the same connection. */ -@property(readonly) NSUInteger channelId; +@property(readonly) NSUInteger channelID; @end @@ -307,16 +307,16 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * A string that specify the domain where channel is being cached. Channels with different domains - * will not get cached to the same connection. For example, a gRPC example app may use the channel - * pool domain 'io.grpc.example' so that its calls do not reuse the channel created by other modules - * in the same process. + * will not get cached to the same channel. For example, a gRPC example app may use the channel pool + * domain 'io.grpc.example' so that its calls do not reuse the channel created by other modules in + * the same process. */ @property(copy, readwrite) NSString *channelPoolDomain; /** * Channel id allows a call to force creating a new channel (connection) rather than using a cached - * channel. Calls using distinct channelId will not get cached to the same connection. + * channel. Calls using distinct channelID's will not get cached to the same channel. */ -@property(readwrite) NSUInteger channelId; +@property(readwrite) NSUInteger channelID; @end diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 539cb9929db..ad90fb829e8 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -41,7 +41,7 @@ static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2Bo static NSString *const kDefaultHostNameOverride = nil; static const id kDefaultLogContext = nil; static NSString *kDefaultChannelPoolDomain = nil; -static NSUInteger kDefaultChannelId = 0; +static NSUInteger kDefaultChannelID = 0; @implementation GRPCCallOptions { @protected @@ -67,7 +67,7 @@ static NSUInteger kDefaultChannelId = 0; NSString *_hostNameOverride; id _logContext; NSString *_channelPoolDomain; - NSUInteger _channelId; + NSUInteger _channelID; } @synthesize serverAuthority = _serverAuthority; @@ -92,7 +92,7 @@ static NSUInteger kDefaultChannelId = 0; @synthesize hostNameOverride = _hostNameOverride; @synthesize logContext = _logContext; @synthesize channelPoolDomain = _channelPoolDomain; -@synthesize channelId = _channelId; +@synthesize channelID = _channelID; - (instancetype)init { return [self initWithServerAuthority:kDefaultServerAuthority @@ -117,7 +117,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext channelPoolDomain:kDefaultChannelPoolDomain - channelId:kDefaultChannelId]; + channelID:kDefaultChannelID]; } - (instancetype)initWithServerAuthority:(NSString *)serverAuthority @@ -142,7 +142,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:(NSString *)hostNameOverride logContext:(id)logContext channelPoolDomain:(NSString *)channelPoolDomain - channelId:(NSUInteger)channelId { + channelID:(NSUInteger)channelID { if ((self = [super init])) { _serverAuthority = serverAuthority; _timeout = timeout; @@ -166,7 +166,7 @@ static NSUInteger kDefaultChannelId = 0; _hostNameOverride = hostNameOverride; _logContext = logContext; _channelPoolDomain = channelPoolDomain; - _channelId = channelId; + _channelID = channelID; } return self; } @@ -195,7 +195,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:_hostNameOverride logContext:_logContext channelPoolDomain:_channelPoolDomain - channelId:_channelId]; + channelID:_channelID]; return newOptions; } @@ -223,7 +223,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:_hostNameOverride logContext:_logContext channelPoolDomain:_channelPoolDomain - channelId:_channelId]; + channelID:_channelID]; return newOptions; } @@ -253,7 +253,7 @@ static NSUInteger kDefaultChannelId = 0; @dynamic hostNameOverride; @dynamic logContext; @dynamic channelPoolDomain; -@dynamic channelId; +@dynamic channelID; - (instancetype)init { return [self initWithServerAuthority:kDefaultServerAuthority @@ -278,7 +278,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext channelPoolDomain:kDefaultChannelPoolDomain - channelId:kDefaultChannelId]; + channelID:kDefaultChannelID]; } - (nonnull id)copyWithZone:(NSZone *)zone { @@ -305,7 +305,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:_hostNameOverride logContext:_logContext channelPoolDomain:_channelPoolDomain - channelId:_channelId]; + channelID:_channelID]; return newOptions; } @@ -333,7 +333,7 @@ static NSUInteger kDefaultChannelId = 0; hostNameOverride:_hostNameOverride logContext:_logContext channelPoolDomain:_channelPoolDomain - channelId:_channelId]; + channelID:_channelID]; return newOptions; } @@ -449,8 +449,8 @@ static NSUInteger kDefaultChannelId = 0; _channelPoolDomain = channelPoolDomain; } -- (void)setChannelId:(NSUInteger)channelId { - _channelId = channelId; +- (void)setChannelID:(NSUInteger)channelID { + _channelID = channelID; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 9007f5fed51..37e42f8c75b 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -186,7 +186,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; if (!(obj.callOptions.channelPoolDomain == _callOptions.channelPoolDomain || [obj.callOptions.channelPoolDomain isEqualToString:_callOptions.channelPoolDomain])) return NO; - if (!(obj.callOptions.channelId == _callOptions.channelId)) return NO; + if (!(obj.callOptions.channelID == _callOptions.channelID)) return NO; return YES; } @@ -211,7 +211,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; result ^= _callOptions.transportType; result ^= [_callOptions.logContext hash]; result ^= _callOptions.channelPoolDomain.hash; - result ^= _callOptions.channelId; + result ^= _callOptions.channelID; return result; } From 229651a371ac590f47793cdacc8d28c0ac74bf48 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 16:17:38 -0700 Subject: [PATCH 0043/2143] Check range of value-typed channel arg --- src/objective-c/GRPCClient/private/ChannelArgsUtil.m | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index 8ebf3a26593..04a5cc8345a 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -21,6 +21,8 @@ #include #include +#include + static void *copy_pointer_arg(void *p) { // Add ref count to the object when making copy id obj = (__bridge id)p; @@ -79,6 +81,11 @@ grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { arg->type = GRPC_ARG_STRING; arg->value.string = gpr_strdup([value UTF8String]); } else if ([value respondsToSelector:@selector(intValue)]) { + if ([value compare:[NSNumber numberWithInteger:INT_MAX]] == NSOrderedDescending || + [value compare:[NSNumber numberWithInteger:INT_MIN]] == NSOrderedAscending) { + [NSException raise:NSInvalidArgumentException + format:@"Range exceeded for a value typed channel argument: %@", value]; + } arg->type = GRPC_ARG_INTEGER; arg->value.integer = [value intValue]; } else if (value != nil) { From ecf85f045975265d19a94b116e94f7fea42a9d38 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 16:23:25 -0700 Subject: [PATCH 0044/2143] Copy fields in GRPCCallOptions initializer --- src/objective-c/GRPCClient/GRPCCallOptions.m | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index ad90fb829e8..f9706b18467 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -144,12 +144,12 @@ static NSUInteger kDefaultChannelID = 0; channelPoolDomain:(NSString *)channelPoolDomain channelID:(NSUInteger)channelID { if ((self = [super init])) { - _serverAuthority = serverAuthority; + _serverAuthority = [serverAuthority copy]; _timeout = timeout; - _oauth2AccessToken = oauth2AccessToken; + _oauth2AccessToken = [oauth2AccessToken copy]; _authTokenProvider = authTokenProvider; - _initialMetadata = initialMetadata; - _userAgentPrefix = userAgentPrefix; + _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; + _userAgentPrefix = [userAgentPrefix copy]; _responseSizeLimit = responseSizeLimit; _compressAlgorithm = compressAlgorithm; _enableRetry = enableRetry; @@ -158,14 +158,14 @@ static NSUInteger kDefaultChannelID = 0; _connectMinTimeout = connectMinTimeout; _connectInitialBackoff = connectInitialBackoff; _connectMaxBackoff = connectMaxBackoff; - _additionalChannelArgs = additionalChannelArgs; - _PEMRootCertificates = PEMRootCertificates; - _PEMPrivateKey = PEMPrivateKey; - _PEMCertChain = PEMCertChain; + _additionalChannelArgs = [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; + _PEMRootCertificates = [PEMRootCertificates copy]; + _PEMPrivateKey = [PEMPrivateKey copy]; + _PEMCertChain = [PEMCertChain copy]; _transportType = transportType; - _hostNameOverride = hostNameOverride; + _hostNameOverride = [hostNameOverride copy]; _logContext = logContext; - _channelPoolDomain = channelPoolDomain; + _channelPoolDomain = [channelPoolDomain copy]; _channelID = channelID; } return self; From 1c8751f366fc4b51a49cc83aa8477dd2b12664a8 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 16:33:02 -0700 Subject: [PATCH 0045/2143] Avoid copy in GRPCCallOptions:copyWithZone: --- src/objective-c/GRPCClient/GRPCCallOptions.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index f9706b18467..c700bba794a 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -187,7 +187,7 @@ static NSUInteger kDefaultChannelID = 0; connectMinTimeout:_connectMinTimeout connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff - additionalChannelArgs:[_additionalChannelArgs copy] + additionalChannelArgs:_additionalChannelArgs PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey PEMCertChain:_PEMCertChain From 454966e36cab39ee1b18828575a23c75d812d895 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 16:38:14 -0700 Subject: [PATCH 0046/2143] Copy in GRPCCallOptions setters --- src/objective-c/GRPCClient/GRPCCallOptions.m | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index c700bba794a..b19917d7784 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -338,7 +338,7 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setServerAuthority:(NSString *)serverAuthority { - _serverAuthority = serverAuthority; + _serverAuthority = [serverAuthority copy]; } - (void)setTimeout:(NSTimeInterval)timeout { @@ -350,7 +350,7 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setOauth2AccessToken:(NSString *)oauth2AccessToken { - _oauth2AccessToken = oauth2AccessToken; + _oauth2AccessToken = [oauth2AccessToken copy]; } - (void)setAuthTokenProvider:(id)authTokenProvider { @@ -358,11 +358,11 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setInitialMetadata:(NSDictionary *)initialMetadata { - _initialMetadata = initialMetadata; + _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; } - (void)setUserAgentPrefix:(NSString *)userAgentPrefix { - _userAgentPrefix = userAgentPrefix; + _userAgentPrefix = [userAgentPrefix copy]; } - (void)setResponseSizeLimit:(NSUInteger)responseSizeLimit { @@ -418,19 +418,19 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setAdditionalChannelArgs:(NSDictionary *)additionalChannelArgs { - _additionalChannelArgs = additionalChannelArgs; + _additionalChannelArgs = [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; } - (void)setPEMRootCertificates:(NSString *)PEMRootCertificates { - _PEMRootCertificates = PEMRootCertificates; + _PEMRootCertificates = [PEMRootCertificates copy]; } - (void)setPEMPrivateKey:(NSString *)PEMPrivateKey { - _PEMPrivateKey = PEMPrivateKey; + _PEMPrivateKey = [PEMPrivateKey copy]; } - (void)setPEMCertChain:(NSString *)PEMCertChain { - _PEMCertChain = PEMCertChain; + _PEMCertChain = [PEMCertChain copy]; } - (void)setTransportType:(GRPCTransportType)transportType { @@ -438,7 +438,7 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setHostNameOverride:(NSString *)hostNameOverride { - _hostNameOverride = hostNameOverride; + _hostNameOverride = [hostNameOverride copy]; } - (void)setLogContext:(id)logContext { @@ -446,7 +446,7 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setChannelPoolDomain:(NSString *)channelPoolDomain { - _channelPoolDomain = channelPoolDomain; + _channelPoolDomain = [channelPoolDomain copy]; } - (void)setChannelID:(NSUInteger)channelID { From 92d6e285d174bf6c8b2e60054f82d7288231da14 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 11 Oct 2018 16:42:53 -0700 Subject: [PATCH 0047/2143] Polish exception message --- src/objective-c/GRPCClient/private/ChannelArgsUtil.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index 04a5cc8345a..b26fb12d597 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -84,7 +84,7 @@ grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { if ([value compare:[NSNumber numberWithInteger:INT_MAX]] == NSOrderedDescending || [value compare:[NSNumber numberWithInteger:INT_MIN]] == NSOrderedAscending) { [NSException raise:NSInvalidArgumentException - format:@"Range exceeded for a value typed channel argument: %@", value]; + format:@"Out of range for a value-typed channel argument: %@", value]; } arg->type = GRPC_ARG_INTEGER; arg->value.integer = [value intValue]; @@ -94,7 +94,7 @@ grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { arg->value.pointer.vtable = &objc_arg_vtable; } else { [NSException raise:NSInvalidArgumentException - format:@"Invalid value type: %@", [value class]]; + format:@"Invalid channel argument type: %@", [value class]]; } } From e457b0dacc70a28fffd42064236fbf240952e3b4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 12 Oct 2018 09:02:52 -0700 Subject: [PATCH 0048/2143] Fix missing initialMetadata in GRPCMutableCallOptions --- src/objective-c/GRPCClient/GRPCCallOptions.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 9c6e00fd187..68d3eb4fbb3 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -223,6 +223,11 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ @property(readwrite) id authTokenProvider; +/** + * Initial metadata key-value pairs that should be included in the request. + */ +@property(copy, readonly) NSDictionary *initialMetadata; + // Channel parameters; take into account of channel signature. /** From e69a7cc7f7497e67232843a3843f543740480c4e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 12 Oct 2018 11:21:52 -0700 Subject: [PATCH 0049/2143] patch the previous fix --- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 68d3eb4fbb3..ff575d09cf8 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -226,7 +226,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * Initial metadata key-value pairs that should be included in the request. */ -@property(copy, readonly) NSDictionary *initialMetadata; +@property(copy, readwrite) NSDictionary *initialMetadata; // Channel parameters; take into account of channel signature. From 6fcb5b29e18268c8948d5bd99c14fca13f9d7b67 Mon Sep 17 00:00:00 2001 From: kkm Date: Thu, 11 Oct 2018 20:22:40 -0700 Subject: [PATCH 0050/2143] Redo C# examples to use new Grpc.Tools * No pre-compilation of proto files required; * Tested under Windows and Linux dotnet and mono; * But not tested on Mac/mono; * README updated. --- examples/csharp/.gitignore | 2 + examples/csharp/Helloworld/Greeter.sln | 2 +- .../csharp/Helloworld/Greeter/Greeter.csproj | 15 +- .../csharp/Helloworld/Greeter/Helloworld.cs | 312 ------ .../Helloworld/Greeter/HelloworldGrpc.cs | 149 --- .../GreeterClient/GreeterClient.csproj | 8 +- .../GreeterServer/GreeterServer.csproj | 8 +- examples/csharp/Helloworld/README.md | 32 +- .../csharp/Helloworld/generate_protos.bat | 28 - .../csharp/HelloworldLegacyCsproj/Greeter.sln | 2 +- .../Greeter/Greeter.csproj | 23 +- .../Greeter/Helloworld.cs | 312 ------ .../Greeter/HelloworldGrpc.cs | 149 --- .../Greeter/packages.config | 10 +- .../GreeterClient/GreeterClient.csproj | 8 +- .../GreeterClient/packages.config | 6 +- .../GreeterServer/GreeterServer.csproj | 8 +- .../GreeterServer/packages.config | 6 +- .../csharp/HelloworldLegacyCsproj/README.md | 25 +- .../generate_protos.bat | 26 - examples/csharp/RouteGuide/RouteGuide.sln | 2 +- .../RouteGuide/RouteGuide/RouteGuide.cs | 981 ------------------ .../RouteGuide/RouteGuide/RouteGuide.csproj | 18 +- .../RouteGuide/RouteGuide/RouteGuideGrpc.cs | 331 ------ .../RouteGuide/RouteGuide/RouteGuideUtil.cs | 2 + .../RouteGuideClient/RouteGuideClient.csproj | 8 +- .../RouteGuideServer/RouteGuideServer.csproj | 8 +- .../csharp/RouteGuide/generate_protos.bat | 28 - 28 files changed, 82 insertions(+), 2427 deletions(-) delete mode 100644 examples/csharp/Helloworld/Greeter/Helloworld.cs delete mode 100644 examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs delete mode 100644 examples/csharp/Helloworld/generate_protos.bat delete mode 100644 examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs delete mode 100644 examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs delete mode 100644 examples/csharp/HelloworldLegacyCsproj/generate_protos.bat delete mode 100644 examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs delete mode 100644 examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs delete mode 100644 examples/csharp/RouteGuide/generate_protos.bat diff --git a/examples/csharp/.gitignore b/examples/csharp/.gitignore index 585000ea2d5..11f758f5c81 100644 --- a/examples/csharp/.gitignore +++ b/examples/csharp/.gitignore @@ -1,5 +1,7 @@ +.vs/ bin/ obj/ packages/ *.suo +*.user *.userprefs diff --git a/examples/csharp/Helloworld/Greeter.sln b/examples/csharp/Helloworld/Greeter.sln index ca50470e664..a5ba98d0bed 100644 --- a/examples/csharp/Helloworld/Greeter.sln +++ b/examples/csharp/Helloworld/Greeter.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26228.4 diff --git a/examples/csharp/Helloworld/Greeter/Greeter.csproj b/examples/csharp/Helloworld/Greeter/Greeter.csproj index eba262565d7..3421926dca5 100644 --- a/examples/csharp/Helloworld/Greeter/Greeter.csproj +++ b/examples/csharp/Helloworld/Greeter/Greeter.csproj @@ -1,18 +1,15 @@ - + - Greeter - netcoreapp2.1 - portable - Greeter - Greeter + netstandard1.5 - - - + + + + diff --git a/examples/csharp/Helloworld/Greeter/Helloworld.cs b/examples/csharp/Helloworld/Greeter/Helloworld.cs deleted file mode 100644 index e008ec27e54..00000000000 --- a/examples/csharp/Helloworld/Greeter/Helloworld.cs +++ /dev/null @@ -1,312 +0,0 @@ -// -// 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()); - private pb::UnknownFieldSet _unknownFields; - [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_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [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 Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (Name.Length != 0) hash ^= Name.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.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); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (Name.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(HelloRequest other) { - if (other == null) { - return; - } - if (other.Name.Length != 0) { - Name = other.Name; - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - 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()); - private pb::UnknownFieldSet _unknownFields; - [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_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [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 Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (Message.Length != 0) hash ^= Message.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.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); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (Message.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(HelloReply other) { - if (other == null) { - return; - } - if (other.Message.Length != 0) { - Message = other.Message; - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 10: { - Message = input.ReadString(); - break; - } - } - } - } - - } - - #endregion - -} - -#endregion Designer generated code diff --git a/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs b/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs deleted file mode 100644 index d6b959adc64..00000000000 --- a/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs +++ /dev/null @@ -1,149 +0,0 @@ -// -// 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 0414, 1591 -#region Designer generated code - -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_helloworld_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_helloworld_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_helloworld_HelloRequest, - __Marshaller_helloworld_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, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.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, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.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/Helloworld/GreeterClient/GreeterClient.csproj b/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj index 24a89d58c55..ac10d854972 100644 --- a/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj +++ b/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj @@ -1,12 +1,8 @@ - + - GreeterClient - netcoreapp2.1 - portable - GreeterClient + netcoreapp2.1 Exe - GreeterClient diff --git a/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj b/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj index 9ea1fa3817c..ac10d854972 100644 --- a/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj +++ b/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj @@ -1,12 +1,8 @@ - + - GreeterServer - netcoreapp2.1 - portable - GreeterServer + netcoreapp2.1 Exe - GreeterServer diff --git a/examples/csharp/Helloworld/README.md b/examples/csharp/Helloworld/README.md index 48711324262..e4771ee91a1 100644 --- a/examples/csharp/Helloworld/README.md +++ b/examples/csharp/Helloworld/README.md @@ -3,41 +3,31 @@ gRPC in 3 minutes (C#) BACKGROUND ------------- -For this sample, we've already generated the server and client stubs from [helloworld.proto][]. - -Example projects in this directory depend on the [Grpc](https://www.nuget.org/packages/Grpc/) -and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages -which have been already added to the project for you. +This is a version of the helloworld example using the dotnet SDK +tools to compile [helloworld.proto][] in a common library, build the server +and the client, and run them. PREREQUISITES ------------- - The [.NET Core SDK 2.1+](https://www.microsoft.com/net/core) -You can also build the example directly using Visual Studio 2017, but it's not a requirement. +You can also build the solution `Greeter.sln` using Visual Studio 2017, +but it's not a requirement. -BUILD -------- +BUILD AND RUN +------------- -From the `examples/csharp/Helloworld` directory: - -- `dotnet build Greeter.sln` - -Try it! -------- - -- Run the server +- Build and run the server ``` - > cd GreeterServer - > dotnet run -f netcoreapp2.1 + > dotnet run -p GreeterServer ``` -- Run the client +- Build and run the client ``` - > cd GreeterClient - > dotnet run -f netcoreapp2.1 + > dotnet run -p GreeterClient ``` Tutorial diff --git a/examples/csharp/Helloworld/generate_protos.bat b/examples/csharp/Helloworld/generate_protos.bat deleted file mode 100644 index ab0c0eb46a4..00000000000 --- a/examples/csharp/Helloworld/generate_protos.bat +++ /dev/null @@ -1,28 +0,0 @@ -@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 Generate the C# code for .proto files - -setlocal - -@rem enter this directory -cd /d %~dp0 - -@rem packages will be available in nuget cache directory once the project is built or after "dotnet restore" -set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.6.1\tools\windows_x64\protoc.exe -set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.14.1\tools\windows_x64\grpc_csharp_plugin.exe - -%PROTOC% -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%PLUGIN% - -endlocal diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter.sln b/examples/csharp/HelloworldLegacyCsproj/Greeter.sln index 49e364d91c0..26cae7a727e 100644 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter.sln +++ b/examples/csharp/HelloworldLegacyCsproj/Greeter.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0.31101.0 diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj b/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj index 197a9fb6257..da15ba3954b 100644 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj +++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj @@ -1,5 +1,6 @@ - + + Debug AnyCPU @@ -36,7 +37,7 @@ ..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll - ..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.1.17.0\lib\net45\Grpc.Core.dll @@ -47,25 +48,23 @@ - - - + protos\helloworld.proto - - - generate_protos.bat - + - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + + + - \ No newline at end of file + + diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs b/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs deleted file mode 100644 index e008ec27e54..00000000000 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs +++ /dev/null @@ -1,312 +0,0 @@ -// -// 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()); - private pb::UnknownFieldSet _unknownFields; - [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_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [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 Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (Name.Length != 0) hash ^= Name.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.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); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (Name.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(HelloRequest other) { - if (other == null) { - return; - } - if (other.Name.Length != 0) { - Name = other.Name; - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - 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()); - private pb::UnknownFieldSet _unknownFields; - [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_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [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 Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (Message.Length != 0) hash ^= Message.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.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); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (Message.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(HelloReply other) { - if (other == null) { - return; - } - if (other.Message.Length != 0) { - Message = other.Message; - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 10: { - Message = input.ReadString(); - break; - } - } - } - } - - } - - #endregion - -} - -#endregion Designer generated code diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs b/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs deleted file mode 100644 index d6b959adc64..00000000000 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs +++ /dev/null @@ -1,149 +0,0 @@ -// -// 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 0414, 1591 -#region Designer generated code - -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_helloworld_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_helloworld_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_helloworld_HelloRequest, - __Marshaller_helloworld_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, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.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, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.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/HelloworldLegacyCsproj/Greeter/packages.config b/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config index 23857be22fa..154b5993213 100644 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config +++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config @@ -1,8 +1,8 @@ - + - - - + + + - \ No newline at end of file + diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj index 3bb7ff1ee13..31a3a90345b 100644 --- a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj +++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj @@ -1,4 +1,4 @@ - + Debug @@ -36,7 +36,7 @@ ..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll - ..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.1.17.0\lib\net45\Grpc.Core.dll @@ -59,11 +59,11 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config index df4df8282c4..2fd8228689d 100644 --- a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config +++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config @@ -1,7 +1,7 @@ - + - - + + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj index 4396b04efeb..27ca9630401 100644 --- a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj +++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj @@ -1,4 +1,4 @@ - + Debug @@ -36,7 +36,7 @@ ..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll - ..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.1.17.0\lib\net45\Grpc.Core.dll @@ -59,11 +59,11 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config index df4df8282c4..2fd8228689d 100644 --- a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config +++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config @@ -1,7 +1,7 @@ - + - - + + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/README.md b/examples/csharp/HelloworldLegacyCsproj/README.md index 6d42c5ef258..60b09e09257 100644 --- a/examples/csharp/HelloworldLegacyCsproj/README.md +++ b/examples/csharp/HelloworldLegacyCsproj/README.md @@ -3,21 +3,21 @@ gRPC in 3 minutes (C#) BACKGROUND ------------- -This is a different version of the helloworld example, using the old-style .csproj -files supported by VS2013 and VS2015 (and older versions of mono). -You can still use gRPC with the old-style .csproj files, but [using the new-style -.csproj projects](../helloworld/README.md) (supported by VS2017 and dotnet SDK) is recommended. +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, +and dotnet SDK) is recommended. -For this sample, we've already generated the server and client stubs from [helloworld.proto][]. - -Example projects depend on the [Grpc](https://www.nuget.org/packages/Grpc/), [Grpc.Tools](https://www.nuget.org/packages/Grpc.Tools/) +Example projects depend on the [Grpc](https://www.nuget.org/packages/Grpc/), +[Grpc.Tools](https://www.nuget.org/packages/Grpc.Tools/) and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages which have been already added to the project for you. PREREQUISITES ------------- -- Windows: .NET Framework 4.5+, Visual Studio 2013 or 2015 +- Windows: .NET Framework 4.5+, Visual Studio 2013 or higher - Linux: Mono 4+, MonoDevelop 5.9+ - Mac OS X: Xamarin Studio 5.9+ @@ -28,12 +28,15 @@ BUILD # Using Visual Studio -* Build the solution (this will automatically download NuGet dependencies) +* Select "Restore NuGet Packages" from the solution context menu. It is recommended + to close and re-open the solution after the packages have been restored from + Visual Studio. +* Build the solution. # Using Monodevelop or Xamarin Studio -The nuget add-in available for Xamarin Studio and Monodevelop IDEs is too old to -download all of the nuget dependencies of gRPC. +The NuGet add-in available for Xamarin Studio and Monodevelop IDEs is too old to +download all of the NuGet dependencies of gRPC. Using these IDEs, a workaround is as follows: * Obtain a nuget executable for your platform and update it with diff --git a/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat b/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat deleted file mode 100644 index d1e7160f91e..00000000000 --- a/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat +++ /dev/null @@ -1,26 +0,0 @@ -@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 Generate the C# code for .proto files - -setlocal - -@rem enter this directory -cd /d %~dp0 - -set TOOLS_PATH=packages\Grpc.Tools.1.14.1\tools\windows_x86 - -%TOOLS_PATH%\protoc.exe -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe - -endlocal diff --git a/examples/csharp/RouteGuide/RouteGuide.sln b/examples/csharp/RouteGuide/RouteGuide.sln index 73e6e306b16..5e103294a56 100644 --- a/examples/csharp/RouteGuide/RouteGuide.sln +++ b/examples/csharp/RouteGuide/RouteGuide.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26228.4 diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs deleted file mode 100644 index 10c9aec5f80..00000000000 --- a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs +++ /dev/null @@ -1,981 +0,0 @@ -// -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: route_guide.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 Routeguide { - - /// Holder for reflection information generated from route_guide.proto - public static partial class RouteGuideReflection { - - #region Descriptor - /// File descriptor for route_guide.proto - public static pbr::FileDescriptor Descriptor { - get { return descriptor; } - } - private static pbr::FileDescriptor descriptor; - - static RouteGuideReflection() { - byte[] descriptorData = global::System.Convert.FromBase64String( - string.Concat( - "ChFyb3V0ZV9ndWlkZS5wcm90bxIKcm91dGVndWlkZSIsCgVQb2ludBIQCghs", - "YXRpdHVkZRgBIAEoBRIRCglsb25naXR1ZGUYAiABKAUiSQoJUmVjdGFuZ2xl", - "Eh0KAmxvGAEgASgLMhEucm91dGVndWlkZS5Qb2ludBIdCgJoaRgCIAEoCzIR", - "LnJvdXRlZ3VpZGUuUG9pbnQiPAoHRmVhdHVyZRIMCgRuYW1lGAEgASgJEiMK", - "CGxvY2F0aW9uGAIgASgLMhEucm91dGVndWlkZS5Qb2ludCJBCglSb3V0ZU5v", - "dGUSIwoIbG9jYXRpb24YASABKAsyES5yb3V0ZWd1aWRlLlBvaW50Eg8KB21l", - "c3NhZ2UYAiABKAkiYgoMUm91dGVTdW1tYXJ5EhMKC3BvaW50X2NvdW50GAEg", - "ASgFEhUKDWZlYXR1cmVfY291bnQYAiABKAUSEAoIZGlzdGFuY2UYAyABKAUS", - "FAoMZWxhcHNlZF90aW1lGAQgASgFMoUCCgpSb3V0ZUd1aWRlEjYKCkdldEZl", - "YXR1cmUSES5yb3V0ZWd1aWRlLlBvaW50GhMucm91dGVndWlkZS5GZWF0dXJl", - "IgASPgoMTGlzdEZlYXR1cmVzEhUucm91dGVndWlkZS5SZWN0YW5nbGUaEy5y", - "b3V0ZWd1aWRlLkZlYXR1cmUiADABEj4KC1JlY29yZFJvdXRlEhEucm91dGVn", - "dWlkZS5Qb2ludBoYLnJvdXRlZ3VpZGUuUm91dGVTdW1tYXJ5IgAoARI/CglS", - "b3V0ZUNoYXQSFS5yb3V0ZWd1aWRlLlJvdXRlTm90ZRoVLnJvdXRlZ3VpZGUu", - "Um91dGVOb3RlIgAoATABQjYKG2lvLmdycGMuZXhhbXBsZXMucm91dGVndWlk", - "ZUIPUm91dGVHdWlkZVByb3RvUAGiAgNSVEdiBnByb3RvMw==")); - descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, - new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Point), global::Routeguide.Point.Parser, new[]{ "Latitude", "Longitude" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Rectangle), global::Routeguide.Rectangle.Parser, new[]{ "Lo", "Hi" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Feature), global::Routeguide.Feature.Parser, new[]{ "Name", "Location" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.RouteNote), global::Routeguide.RouteNote.Parser, new[]{ "Location", "Message" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.RouteSummary), global::Routeguide.RouteSummary.Parser, new[]{ "PointCount", "FeatureCount", "Distance", "ElapsedTime" }, null, null, null) - })); - } - #endregion - - } - #region Messages - /// - /// Points are represented as latitude-longitude pairs in the E7 representation - /// (degrees multiplied by 10**7 and rounded to the nearest integer). - /// Latitudes should be in the range +/- 90 degrees and longitude should be in - /// the range +/- 180 degrees (inclusive). - /// - public sealed partial class Point : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Point()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[0]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Point() { - OnConstruction(); - } - - partial void OnConstruction(); - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Point(Point other) : this() { - latitude_ = other.latitude_; - longitude_ = other.longitude_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Point Clone() { - return new Point(this); - } - - /// Field number for the "latitude" field. - public const int LatitudeFieldNumber = 1; - private int latitude_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int Latitude { - get { return latitude_; } - set { - latitude_ = value; - } - } - - /// Field number for the "longitude" field. - public const int LongitudeFieldNumber = 2; - private int longitude_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int Longitude { - get { return longitude_; } - set { - longitude_ = value; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override bool Equals(object other) { - return Equals(other as Point); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(Point other) { - if (ReferenceEquals(other, null)) { - return false; - } - if (ReferenceEquals(other, this)) { - return true; - } - if (Latitude != other.Latitude) return false; - if (Longitude != other.Longitude) return false; - return Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (Latitude != 0) hash ^= Latitude.GetHashCode(); - if (Longitude != 0) hash ^= Longitude.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.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 (Latitude != 0) { - output.WriteRawTag(8); - output.WriteInt32(Latitude); - } - if (Longitude != 0) { - output.WriteRawTag(16); - output.WriteInt32(Longitude); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (Latitude != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(Latitude); - } - if (Longitude != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(Longitude); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(Point other) { - if (other == null) { - return; - } - if (other.Latitude != 0) { - Latitude = other.Latitude; - } - if (other.Longitude != 0) { - Longitude = other.Longitude; - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 8: { - Latitude = input.ReadInt32(); - break; - } - case 16: { - Longitude = input.ReadInt32(); - break; - } - } - } - } - - } - - /// - /// A latitude-longitude rectangle, represented as two diagonally opposite - /// points "lo" and "hi". - /// - public sealed partial class Rectangle : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Rectangle()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[1]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Rectangle() { - OnConstruction(); - } - - partial void OnConstruction(); - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Rectangle(Rectangle other) : this() { - lo_ = other.lo_ != null ? other.lo_.Clone() : null; - hi_ = other.hi_ != null ? other.hi_.Clone() : null; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Rectangle Clone() { - return new Rectangle(this); - } - - /// Field number for the "lo" field. - public const int LoFieldNumber = 1; - private global::Routeguide.Point lo_; - /// - /// One corner of the rectangle. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public global::Routeguide.Point Lo { - get { return lo_; } - set { - lo_ = value; - } - } - - /// Field number for the "hi" field. - public const int HiFieldNumber = 2; - private global::Routeguide.Point hi_; - /// - /// The other corner of the rectangle. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public global::Routeguide.Point Hi { - get { return hi_; } - set { - hi_ = value; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override bool Equals(object other) { - return Equals(other as Rectangle); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(Rectangle other) { - if (ReferenceEquals(other, null)) { - return false; - } - if (ReferenceEquals(other, this)) { - return true; - } - if (!object.Equals(Lo, other.Lo)) return false; - if (!object.Equals(Hi, other.Hi)) return false; - return Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (lo_ != null) hash ^= Lo.GetHashCode(); - if (hi_ != null) hash ^= Hi.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.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 (lo_ != null) { - output.WriteRawTag(10); - output.WriteMessage(Lo); - } - if (hi_ != null) { - output.WriteRawTag(18); - output.WriteMessage(Hi); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (lo_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(Lo); - } - if (hi_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(Hi); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(Rectangle other) { - if (other == null) { - return; - } - if (other.lo_ != null) { - if (lo_ == null) { - lo_ = new global::Routeguide.Point(); - } - Lo.MergeFrom(other.Lo); - } - if (other.hi_ != null) { - if (hi_ == null) { - hi_ = new global::Routeguide.Point(); - } - Hi.MergeFrom(other.Hi); - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 10: { - if (lo_ == null) { - lo_ = new global::Routeguide.Point(); - } - input.ReadMessage(lo_); - break; - } - case 18: { - if (hi_ == null) { - hi_ = new global::Routeguide.Point(); - } - input.ReadMessage(hi_); - break; - } - } - } - } - - } - - /// - /// A feature names something at a given point. - /// - /// If a feature could not be named, the name is empty. - /// - public sealed partial class Feature : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Feature()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[2]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Feature() { - OnConstruction(); - } - - partial void OnConstruction(); - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Feature(Feature other) : this() { - name_ = other.name_; - location_ = other.location_ != null ? other.location_.Clone() : null; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Feature Clone() { - return new Feature(this); - } - - /// Field number for the "name" field. - public const int NameFieldNumber = 1; - private string name_ = ""; - /// - /// The name of the feature. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public string Name { - get { return name_; } - set { - name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); - } - } - - /// Field number for the "location" field. - public const int LocationFieldNumber = 2; - private global::Routeguide.Point location_; - /// - /// The point where the feature is detected. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public global::Routeguide.Point Location { - get { return location_; } - set { - location_ = value; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override bool Equals(object other) { - return Equals(other as Feature); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(Feature other) { - if (ReferenceEquals(other, null)) { - return false; - } - if (ReferenceEquals(other, this)) { - return true; - } - if (Name != other.Name) return false; - if (!object.Equals(Location, other.Location)) return false; - return Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (Name.Length != 0) hash ^= Name.GetHashCode(); - if (location_ != null) hash ^= Location.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.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); - } - if (location_ != null) { - output.WriteRawTag(18); - output.WriteMessage(Location); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (Name.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); - } - if (location_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(Location); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(Feature other) { - if (other == null) { - return; - } - if (other.Name.Length != 0) { - Name = other.Name; - } - if (other.location_ != null) { - if (location_ == null) { - location_ = new global::Routeguide.Point(); - } - Location.MergeFrom(other.Location); - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 10: { - Name = input.ReadString(); - break; - } - case 18: { - if (location_ == null) { - location_ = new global::Routeguide.Point(); - } - input.ReadMessage(location_); - break; - } - } - } - } - - } - - /// - /// A RouteNote is a message sent while at a given point. - /// - public sealed partial class RouteNote : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new RouteNote()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[3]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public RouteNote() { - OnConstruction(); - } - - partial void OnConstruction(); - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public RouteNote(RouteNote other) : this() { - location_ = other.location_ != null ? other.location_.Clone() : null; - message_ = other.message_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public RouteNote Clone() { - return new RouteNote(this); - } - - /// Field number for the "location" field. - public const int LocationFieldNumber = 1; - private global::Routeguide.Point location_; - /// - /// The location from which the message is sent. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public global::Routeguide.Point Location { - get { return location_; } - set { - location_ = value; - } - } - - /// Field number for the "message" field. - public const int MessageFieldNumber = 2; - private string message_ = ""; - /// - /// The message to be sent. - /// - [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 RouteNote); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(RouteNote other) { - if (ReferenceEquals(other, null)) { - return false; - } - if (ReferenceEquals(other, this)) { - return true; - } - if (!object.Equals(Location, other.Location)) return false; - if (Message != other.Message) return false; - return Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (location_ != null) hash ^= Location.GetHashCode(); - if (Message.Length != 0) hash ^= Message.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.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 (location_ != null) { - output.WriteRawTag(10); - output.WriteMessage(Location); - } - if (Message.Length != 0) { - output.WriteRawTag(18); - output.WriteString(Message); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (location_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(Location); - } - if (Message.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(RouteNote other) { - if (other == null) { - return; - } - if (other.location_ != null) { - if (location_ == null) { - location_ = new global::Routeguide.Point(); - } - Location.MergeFrom(other.Location); - } - if (other.Message.Length != 0) { - Message = other.Message; - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 10: { - if (location_ == null) { - location_ = new global::Routeguide.Point(); - } - input.ReadMessage(location_); - break; - } - case 18: { - Message = input.ReadString(); - break; - } - } - } - } - - } - - /// - /// A RouteSummary is received in response to a RecordRoute rpc. - /// - /// It contains the number of individual points received, the number of - /// detected features, and the total distance covered as the cumulative sum of - /// the distance between each point. - /// - public sealed partial class RouteSummary : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new RouteSummary()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[4]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public RouteSummary() { - OnConstruction(); - } - - partial void OnConstruction(); - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public RouteSummary(RouteSummary other) : this() { - pointCount_ = other.pointCount_; - featureCount_ = other.featureCount_; - distance_ = other.distance_; - elapsedTime_ = other.elapsedTime_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public RouteSummary Clone() { - return new RouteSummary(this); - } - - /// Field number for the "point_count" field. - public const int PointCountFieldNumber = 1; - private int pointCount_; - /// - /// The number of points received. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int PointCount { - get { return pointCount_; } - set { - pointCount_ = value; - } - } - - /// Field number for the "feature_count" field. - public const int FeatureCountFieldNumber = 2; - private int featureCount_; - /// - /// The number of known features passed while traversing the route. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int FeatureCount { - get { return featureCount_; } - set { - featureCount_ = value; - } - } - - /// Field number for the "distance" field. - public const int DistanceFieldNumber = 3; - private int distance_; - /// - /// The distance covered in metres. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int Distance { - get { return distance_; } - set { - distance_ = value; - } - } - - /// Field number for the "elapsed_time" field. - public const int ElapsedTimeFieldNumber = 4; - private int elapsedTime_; - /// - /// The duration of the traversal in seconds. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int ElapsedTime { - get { return elapsedTime_; } - set { - elapsedTime_ = value; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override bool Equals(object other) { - return Equals(other as RouteSummary); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(RouteSummary other) { - if (ReferenceEquals(other, null)) { - return false; - } - if (ReferenceEquals(other, this)) { - return true; - } - if (PointCount != other.PointCount) return false; - if (FeatureCount != other.FeatureCount) return false; - if (Distance != other.Distance) return false; - if (ElapsedTime != other.ElapsedTime) return false; - return Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (PointCount != 0) hash ^= PointCount.GetHashCode(); - if (FeatureCount != 0) hash ^= FeatureCount.GetHashCode(); - if (Distance != 0) hash ^= Distance.GetHashCode(); - if (ElapsedTime != 0) hash ^= ElapsedTime.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.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 (PointCount != 0) { - output.WriteRawTag(8); - output.WriteInt32(PointCount); - } - if (FeatureCount != 0) { - output.WriteRawTag(16); - output.WriteInt32(FeatureCount); - } - if (Distance != 0) { - output.WriteRawTag(24); - output.WriteInt32(Distance); - } - if (ElapsedTime != 0) { - output.WriteRawTag(32); - output.WriteInt32(ElapsedTime); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (PointCount != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(PointCount); - } - if (FeatureCount != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(FeatureCount); - } - if (Distance != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(Distance); - } - if (ElapsedTime != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(ElapsedTime); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(RouteSummary other) { - if (other == null) { - return; - } - if (other.PointCount != 0) { - PointCount = other.PointCount; - } - if (other.FeatureCount != 0) { - FeatureCount = other.FeatureCount; - } - if (other.Distance != 0) { - Distance = other.Distance; - } - if (other.ElapsedTime != 0) { - ElapsedTime = other.ElapsedTime; - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 8: { - PointCount = input.ReadInt32(); - break; - } - case 16: { - FeatureCount = input.ReadInt32(); - break; - } - case 24: { - Distance = input.ReadInt32(); - break; - } - case 32: { - ElapsedTime = input.ReadInt32(); - break; - } - } - } - } - - } - - #endregion - -} - -#endregion Designer generated code diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj index 86346d1e149..2d4f48ec2e9 100644 --- a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj +++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj @@ -1,25 +1,19 @@ - + - RouteGuide - netcoreapp2.1 - portable - RouteGuide - RouteGuide + netstandard1.5 - - - + + - - PreserveNewest - + + diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs deleted file mode 100644 index 445708e4469..00000000000 --- a/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs +++ /dev/null @@ -1,331 +0,0 @@ -// -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: route_guide.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 0414, 1591 -#region Designer generated code - -using grpc = global::Grpc.Core; - -namespace Routeguide { - /// - /// Interface exported by the server. - /// - public static partial class RouteGuide - { - static readonly string __ServiceName = "routeguide.RouteGuide"; - - static readonly grpc::Marshaller __Marshaller_routeguide_Point = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Point.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_routeguide_Feature = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Feature.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_routeguide_Rectangle = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Rectangle.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_routeguide_RouteSummary = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteSummary.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_routeguide_RouteNote = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteNote.Parser.ParseFrom); - - static readonly grpc::Method __Method_GetFeature = new grpc::Method( - grpc::MethodType.Unary, - __ServiceName, - "GetFeature", - __Marshaller_routeguide_Point, - __Marshaller_routeguide_Feature); - - static readonly grpc::Method __Method_ListFeatures = new grpc::Method( - grpc::MethodType.ServerStreaming, - __ServiceName, - "ListFeatures", - __Marshaller_routeguide_Rectangle, - __Marshaller_routeguide_Feature); - - static readonly grpc::Method __Method_RecordRoute = new grpc::Method( - grpc::MethodType.ClientStreaming, - __ServiceName, - "RecordRoute", - __Marshaller_routeguide_Point, - __Marshaller_routeguide_RouteSummary); - - static readonly grpc::Method __Method_RouteChat = new grpc::Method( - grpc::MethodType.DuplexStreaming, - __ServiceName, - "RouteChat", - __Marshaller_routeguide_RouteNote, - __Marshaller_routeguide_RouteNote); - - /// Service descriptor - public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor - { - get { return global::Routeguide.RouteGuideReflection.Descriptor.Services[0]; } - } - - /// Base class for server-side implementations of RouteGuide - public abstract partial class RouteGuideBase - { - /// - /// A simple RPC. - /// - /// Obtains the feature at a given position. - /// - /// A feature with an empty name is returned if there's no feature at the given - /// position. - /// - /// 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 GetFeature(global::Routeguide.Point request, grpc::ServerCallContext context) - { - throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); - } - - /// - /// A server-to-client streaming RPC. - /// - /// Obtains the Features available within the given Rectangle. Results are - /// streamed rather than returned at once (e.g. in a response message with a - /// repeated field), as the rectangle may cover a large area and contain a - /// huge number of features. - /// - /// The request received from the client. - /// Used for sending responses back to the client. - /// The context of the server-side call handler being invoked. - /// A task indicating completion of the handler. - public virtual global::System.Threading.Tasks.Task ListFeatures(global::Routeguide.Rectangle request, grpc::IServerStreamWriter responseStream, grpc::ServerCallContext context) - { - throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); - } - - /// - /// A client-to-server streaming RPC. - /// - /// Accepts a stream of Points on a route being traversed, returning a - /// RouteSummary when traversal is completed. - /// - /// Used for reading requests 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 RecordRoute(grpc::IAsyncStreamReader requestStream, grpc::ServerCallContext context) - { - throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); - } - - /// - /// A Bidirectional streaming RPC. - /// - /// Accepts a stream of RouteNotes sent while a route is being traversed, - /// while receiving other RouteNotes (e.g. from other users). - /// - /// Used for reading requests from the client. - /// Used for sending responses back to the client. - /// The context of the server-side call handler being invoked. - /// A task indicating completion of the handler. - public virtual global::System.Threading.Tasks.Task RouteChat(grpc::IAsyncStreamReader requestStream, grpc::IServerStreamWriter responseStream, grpc::ServerCallContext context) - { - throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); - } - - } - - /// Client for RouteGuide - public partial class RouteGuideClient : grpc::ClientBase - { - /// Creates a new client for RouteGuide - /// The channel to use to make remote calls. - public RouteGuideClient(grpc::Channel channel) : base(channel) - { - } - /// Creates a new client for RouteGuide that uses a custom CallInvoker. - /// The callInvoker to use to make remote calls. - public RouteGuideClient(grpc::CallInvoker callInvoker) : base(callInvoker) - { - } - /// Protected parameterless constructor to allow creation of test doubles. - protected RouteGuideClient() : base() - { - } - /// Protected constructor to allow creation of configured clients. - /// The client configuration. - protected RouteGuideClient(ClientBaseConfiguration configuration) : base(configuration) - { - } - - /// - /// A simple RPC. - /// - /// Obtains the feature at a given position. - /// - /// A feature with an empty name is returned if there's no feature at the given - /// position. - /// - /// 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::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - return GetFeature(request, new grpc::CallOptions(headers, deadline, cancellationToken)); - } - /// - /// A simple RPC. - /// - /// Obtains the feature at a given position. - /// - /// A feature with an empty name is returned if there's no feature at the given - /// position. - /// - /// The request to send to the server. - /// The options for the call. - /// The response received from the server. - public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::CallOptions options) - { - return CallInvoker.BlockingUnaryCall(__Method_GetFeature, null, options, request); - } - /// - /// A simple RPC. - /// - /// Obtains the feature at a given position. - /// - /// A feature with an empty name is returned if there's no feature at the given - /// position. - /// - /// 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 GetFeatureAsync(global::Routeguide.Point request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - return GetFeatureAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken)); - } - /// - /// A simple RPC. - /// - /// Obtains the feature at a given position. - /// - /// A feature with an empty name is returned if there's no feature at the given - /// position. - /// - /// The request to send to the server. - /// The options for the call. - /// The call object. - public virtual grpc::AsyncUnaryCall GetFeatureAsync(global::Routeguide.Point request, grpc::CallOptions options) - { - return CallInvoker.AsyncUnaryCall(__Method_GetFeature, null, options, request); - } - /// - /// A server-to-client streaming RPC. - /// - /// Obtains the Features available within the given Rectangle. Results are - /// streamed rather than returned at once (e.g. in a response message with a - /// repeated field), as the rectangle may cover a large area and contain a - /// huge number of features. - /// - /// 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::AsyncServerStreamingCall ListFeatures(global::Routeguide.Rectangle request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - return ListFeatures(request, new grpc::CallOptions(headers, deadline, cancellationToken)); - } - /// - /// A server-to-client streaming RPC. - /// - /// Obtains the Features available within the given Rectangle. Results are - /// streamed rather than returned at once (e.g. in a response message with a - /// repeated field), as the rectangle may cover a large area and contain a - /// huge number of features. - /// - /// The request to send to the server. - /// The options for the call. - /// The call object. - public virtual grpc::AsyncServerStreamingCall ListFeatures(global::Routeguide.Rectangle request, grpc::CallOptions options) - { - return CallInvoker.AsyncServerStreamingCall(__Method_ListFeatures, null, options, request); - } - /// - /// A client-to-server streaming RPC. - /// - /// Accepts a stream of Points on a route being traversed, returning a - /// RouteSummary when traversal is completed. - /// - /// 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::AsyncClientStreamingCall RecordRoute(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - return RecordRoute(new grpc::CallOptions(headers, deadline, cancellationToken)); - } - /// - /// A client-to-server streaming RPC. - /// - /// Accepts a stream of Points on a route being traversed, returning a - /// RouteSummary when traversal is completed. - /// - /// The options for the call. - /// The call object. - public virtual grpc::AsyncClientStreamingCall RecordRoute(grpc::CallOptions options) - { - return CallInvoker.AsyncClientStreamingCall(__Method_RecordRoute, null, options); - } - /// - /// A Bidirectional streaming RPC. - /// - /// Accepts a stream of RouteNotes sent while a route is being traversed, - /// while receiving other RouteNotes (e.g. from other users). - /// - /// 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::AsyncDuplexStreamingCall RouteChat(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - return RouteChat(new grpc::CallOptions(headers, deadline, cancellationToken)); - } - /// - /// A Bidirectional streaming RPC. - /// - /// Accepts a stream of RouteNotes sent while a route is being traversed, - /// while receiving other RouteNotes (e.g. from other users). - /// - /// The options for the call. - /// The call object. - public virtual grpc::AsyncDuplexStreamingCall RouteChat(grpc::CallOptions options) - { - return CallInvoker.AsyncDuplexStreamingCall(__Method_RouteChat, null, options); - } - /// Creates a new instance of client from given ClientBaseConfiguration. - protected override RouteGuideClient NewInstance(ClientBaseConfiguration configuration) - { - return new RouteGuideClient(configuration); - } - } - - /// Creates service definition that can be registered with a server - /// An object implementing the server-side handling logic. - public static grpc::ServerServiceDefinition BindService(RouteGuideBase serviceImpl) - { - return grpc::ServerServiceDefinition.CreateBuilder() - .AddMethod(__Method_GetFeature, serviceImpl.GetFeature) - .AddMethod(__Method_ListFeatures, serviceImpl.ListFeatures) - .AddMethod(__Method_RecordRoute, serviceImpl.RecordRoute) - .AddMethod(__Method_RouteChat, serviceImpl.RouteChat).Build(); - } - - } -} -#endregion diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs index f9af1908880..96bd8ca09b9 100644 --- a/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs +++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs @@ -108,6 +108,7 @@ namespace Routeguide return features; } +#pragma warning disable 0649 // Suppresses "Field 'x' is never assigned to". private class JsonFeature { public string name; @@ -119,5 +120,6 @@ namespace Routeguide public int longitude; public int latitude; } +#pragma warning restore 0649 } } diff --git a/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj b/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj index c6dadf082b8..b773dd0923c 100644 --- a/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj +++ b/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj @@ -1,12 +1,8 @@ - + - RouteGuideClient - netcoreapp2.1 - portable - RouteGuideClient + netcoreapp2.1 Exe - RouteGuideClient diff --git a/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj index 005c87ca0c2..b773dd0923c 100644 --- a/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj +++ b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj @@ -1,12 +1,8 @@ - + - RouteGuideServer - netcoreapp2.1 - portable - RouteGuideServer + netcoreapp2.1 Exe - RouteGuideServer diff --git a/examples/csharp/RouteGuide/generate_protos.bat b/examples/csharp/RouteGuide/generate_protos.bat deleted file mode 100644 index f3a4382cf19..00000000000 --- a/examples/csharp/RouteGuide/generate_protos.bat +++ /dev/null @@ -1,28 +0,0 @@ -@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 Generate the C# code for .proto files - -setlocal - -@rem enter this directory -cd /d %~dp0 - -@rem packages will be available in nuget cache directory once the project is built or after "dotnet restore" -set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.6.1\tools\windows_x64\protoc.exe -set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.14.1\tools\windows_x64\grpc_csharp_plugin.exe - -%PROTOC% -I../../protos --csharp_out RouteGuide ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=%PLUGIN% - -endlocal From 519654b4b2438493d33c07ef4ed6be5a5e72dadf Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Tue, 16 Oct 2018 11:08:41 -0700 Subject: [PATCH 0051/2143] 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 bf092064962664a1a949750c9f9b273f7d27c529 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 15:34:39 -0700 Subject: [PATCH 0052/2143] Separate GRPCProtoResponseHandler from GRPCResponseHandler --- src/objective-c/GRPCClient/GRPCCall.h | 6 +- src/objective-c/GRPCClient/GRPCCall.m | 4 +- src/objective-c/ProtoRPC/ProtoRPC.h | 37 +++++++++++- src/objective-c/ProtoRPC/ProtoRPC.m | 76 ++++++++++++++----------- src/objective-c/tests/GRPCClientTests.m | 2 +- src/objective-c/tests/InteropTests.m | 4 +- 6 files changed, 85 insertions(+), 44 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 304fb17cca5..48f4514a06f 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -157,10 +157,10 @@ extern id const kGRPCTrailersKey; - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata; /** - * Issued when a message is received from the server. The message may be raw data from the server - * (when using \a GRPCCall2 directly) or deserialized proto object (when using \a ProtoRPC). + * Issued when a message is received from the server. The message is the raw data received from the + * server, with decompression and without proto deserialization. */ -- (void)receivedMessage:(id)message; +- (void)receivedRawMessage:(id)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 36cb71399ca..eb9b21eccb0 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -236,9 +236,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)issueMessage:(id)message { id handler = self->_handler; - if ([handler respondsToSelector:@selector(receivedMessage:)]) { + if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { dispatch_async(handler.dispatchQueue, ^{ - [handler receivedMessage:message]; + [handler receivedRawMessage:message]; }); } } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index a045ef10a6c..d20098ce8c9 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -23,6 +23,39 @@ @class GPBMessage; +/** An object can implement this protocol to receive responses from server from a call. */ +@protocol GRPCProtoResponseHandler + +@optional + +/** Issued when initial metadata is received from the server. */ +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata; + +/** + * Issued when a message is received from the server. The message is the deserialized proto object. + */ +- (void)receivedProtoMessage:(id)message; + +/** + * Issued when a call finished. If the call finished successfully, \a error is nil and \a + * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error + * is non-nil and contains the corresponding error information, including gRPC error codes and + * error descriptions. + */ +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error; + +@required + +/** + * All the responses must be issued to a user-provided dispatch queue. This property specifies the + * dispatch queue to be used for issuing the notifications. A serial queue should be provided if + * the order of responses (initial metadata, message, message, ..., message, trailing metadata) + * needs to be maintained. + */ +@property(atomic, readonly) dispatch_queue_t dispatchQueue; + +@end + /** A unary-request RPC call with Protobuf. */ @interface GRPCUnaryProtoCall : NSObject @@ -36,7 +69,7 @@ */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message - responseHandler:(id)handler + responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; @@ -57,7 +90,7 @@ * returned to users by methods of the generated service. */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - responseHandler:(id)handler + responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 957d6365341..7a57affbf15 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -33,7 +33,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message - responseHandler:(id)handler + responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { if ((self = [super init])) { @@ -60,7 +60,7 @@ @implementation GRPCStreamingProtoCall { GRPCRequestOptions *_requestOptions; - id _handler; + id _handler; GRPCCallOptions *_callOptions; Class _responseClass; @@ -69,7 +69,7 @@ } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - responseHandler:(id)handler + responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { if ((self = [super init])) { @@ -98,16 +98,18 @@ _call = nil; } if (_handler) { - id handler = _handler; - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; - }); + id handler = _handler; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + }); + } _handler = nil; } }); @@ -136,27 +138,33 @@ - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { if (_handler) { - id handler = _handler; - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:initialMetadata]; - }); + id handler = _handler; + if ([handler respondsToSelector:@selector(initialMetadata:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedInitialMetadata:initialMetadata]; + }); + } } } -- (void)receivedMessage:(NSData *)message { +- (void)receivedRawMessage:(NSData *)message { if (_handler) { - id handler = _handler; + id handler = _handler; NSError *error = nil; id parsed = [_responseClass parseFromData:message error:&error]; if (parsed) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedMessage:parsed]; - }); + if ([handler respondsToSelector:@selector(receivedProtoMessage:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedProtoMessage:parsed]; + }); + } } else { - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:nil error:error]; - }); - handler = nil; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:nil error:error]; + }); + } + _handler = nil; [_call cancel]; _call = nil; } @@ -165,16 +173,16 @@ - (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { if (_handler) { - id handler = _handler; - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:trailingMetadata error:error]; - }); + id handler = _handler; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:trailingMetadata error:error]; + }); + } _handler = nil; } - if (_call) { - [_call cancel]; - _call = nil; - } + [_call cancel]; + _call = nil; } - (dispatch_queue_t)dispatchQueue { diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 8a4eddb1b70..f961b6a86fd 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -120,7 +120,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; } } -- (void)receivedMessage:(id)message { +- (void)receivedProtoMessage:(id)message { if (_messageCallback) { _messageCallback(message); } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 0835ff909f5..11d4b95663a 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -75,7 +75,7 @@ BOOL isRemoteInteropTest(NSString *host) { } // Convenience class to use blocks as callbacks -@interface InteropTestsBlockCallbacks : NSObject +@interface InteropTestsBlockCallbacks : NSObject - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback messageCallback:(void (^)(id))messageCallback @@ -108,7 +108,7 @@ BOOL isRemoteInteropTest(NSString *host) { } } -- (void)receivedMessage:(id)message { +- (void)receivedProtoMessage:(id)message { if (_messageCallback) { _messageCallback(message); } From 9f47e76fc8b72c432e9b3d4711c7b2898236f37b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 16:06:54 -0700 Subject: [PATCH 0053/2143] QoS for internal dispatch queues --- src/objective-c/GRPCClient/GRPCCall.m | 11 ++++++++--- src/objective-c/ProtoRPC/ProtoRPC.m | 6 +++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index eb9b21eccb0..df50d43e076 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -108,7 +108,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; _handler = responseHandler; _initialMetadataPublished = NO; _pipe = [GRXBufferedPipe pipe]; - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + if (@available(iOS 8.0, *)) { + _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + } else { + // Fallback on earlier versions + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } _started = NO; } @@ -226,7 +231,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { - id handler = self->_handler; + id handler = _handler; if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { dispatch_async(handler.dispatchQueue, ^{ [handler receivedInitialMetadata:initialMetadata]; @@ -235,7 +240,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueMessage:(id)message { - id handler = self->_handler; + id handler = _handler; if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { dispatch_async(handler.dispatchQueue, ^{ [handler receivedRawMessage:message]; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 7a57affbf15..b860515d4e4 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -77,7 +77,11 @@ _handler = handler; _callOptions = [callOptions copy]; _responseClass = responseClass; - _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + if (@available(iOS 8.0, *)) { + _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + } else { + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } [self start]; } From b3d236d1bf4acebce821fb7f36c262e34104a9b1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 16:07:35 -0700 Subject: [PATCH 0054/2143] Prevent empty string --- src/objective-c/GRPCClient/GRPCCall.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index df50d43e076..7b100cb02a1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -380,8 +380,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; callSafety:(GRPCCallSafety)safety requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { - if (!host || !path) { - [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; + if (host.length == 0 || path.length == 0) { + [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil or empty."]; } if (requestWriter.state != GRXWriterStateNotStarted) { [NSException raise:NSInvalidArgumentException From da43545ff7b4b1a6e310ff7fdeec6eb21f0e26b8 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 16:38:04 -0700 Subject: [PATCH 0055/2143] Check callSafety in -init in GRPCCall --- src/objective-c/GRPCClient/GRPCCall.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 7b100cb02a1..50c38ed99ed 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -383,6 +383,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (host.length == 0 || path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil or empty."]; } + if (safety > GRPCCallSafetyCacheableRequest) { + [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; + } if (requestWriter.state != GRXWriterStateNotStarted) { [NSException raise:NSInvalidArgumentException format:@"The requests writer can't be already started."]; @@ -556,8 +559,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; case GRPCCallSafetyCacheableRequest: callSafetyFlags = GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; break; - default: - [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; } uint32_t callFlag = callSafetyFlags; From 7d32a2cb25275e03a44184ad9f8a3e494e62dd0d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 17:10:32 -0700 Subject: [PATCH 0056/2143] Set user's dispatch queue's handler to internal serial queue --- src/objective-c/GRPCClient/GRPCCall.h | 4 +--- src/objective-c/GRPCClient/GRPCCall.m | 7 +++++++ src/objective-c/ProtoRPC/ProtoRPC.h | 4 +--- src/objective-c/ProtoRPC/ProtoRPC.m | 11 +++++++++++ 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 48f4514a06f..6adecec144a 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -174,9 +174,7 @@ extern id const kGRPCTrailersKey; /** * All the responses must be issued to a user-provided dispatch queue. This property specifies the - * dispatch queue to be used for issuing the notifications. A serial queue should be provided if - * the order of responses (initial metadata, message, message, ..., message, trailing metadata) - * needs to be maintained. + * dispatch queue to be used for issuing the notifications. */ @property(atomic, readonly) dispatch_queue_t dispatchQueue; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 50c38ed99ed..917788e9f2e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -101,6 +101,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; } + if (requestOptions.safety > GRPCCallSafetyCacheableRequest) { + [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; + } + if (responseHandler == nil) { + [NSException raise:NSInvalidArgumentException format:@"Response handler required."]; + } if ((self = [super init])) { _requestOptions = [requestOptions copy]; @@ -114,6 +120,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Fallback on earlier versions _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } + dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); _started = NO; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index d20098ce8c9..db1e8c6deb3 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -48,9 +48,7 @@ /** * All the responses must be issued to a user-provided dispatch queue. This property specifies the - * dispatch queue to be used for issuing the notifications. A serial queue should be provided if - * the order of responses (initial metadata, message, message, ..., message, trailing metadata) - * needs to be maintained. + * dispatch queue to be used for issuing the notifications. */ @property(atomic, readonly) dispatch_queue_t dispatchQueue; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index b860515d4e4..9fb398408bf 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -72,6 +72,16 @@ responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { + if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { + [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; + } + if (requestOptions.safety > GRPCCallSafetyCacheableRequest) { + [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; + } + if (handler == nil) { + [NSException raise:NSInvalidArgumentException format:@"Response handler required."]; + } + if ((self = [super init])) { _requestOptions = [requestOptions copy]; _handler = handler; @@ -82,6 +92,7 @@ } else { _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } + dispatch_set_target_queue(handler.dispatchQueue, _dispatchQueue); [self start]; } From a8b07a37df7680bbe853f4efa0c358447db946fe Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 17:39:51 -0700 Subject: [PATCH 0057/2143] Synchronized access to kHostCache --- src/objective-c/GRPCClient/private/GRPCHost.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 429958b4083..de6f09a44b2 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -125,7 +125,10 @@ static NSMutableDictionary *kHostCache; if (hostURL.host && !hostURL.port) { address = [hostURL.host stringByAppendingString:@":443"]; } - GRPCHost *cachedHost = kHostCache[address]; + __block GRPCHost *cachedHost; + @synchronized (kHostCache) { + cachedHost = kHostCache[address]; + } return (cachedHost != nil); } From 543fbf38c0ad1690558f7be3d1c58ff445a8714f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 17:40:35 -0700 Subject: [PATCH 0058/2143] timeout > 0 --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 917788e9f2e..16acca249d6 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -753,7 +753,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (_serverName.length != 0) { callOptions.serverAuthority = _serverName; } - if (_timeout != 0) { + if (_timeout > 0) { callOptions.timeout = _timeout; } uint32_t callFlags = [GRPCCall callFlagsForHost:_host path:_path]; From 6032e960d43af5912d06553adc22012d3f7c758a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 18:06:13 -0700 Subject: [PATCH 0059/2143] Polish channelID comments --- src/objective-c/GRPCClient/GRPCCallOptions.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index ff575d09cf8..e1a63f83b2e 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -41,6 +41,7 @@ typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) { // The transport to be used by a gRPC call typedef NS_ENUM(NSInteger, GRPCTransportType) { + GRPCTransportTypeDefault = 0, // gRPC internal HTTP/2 stack with BoringSSL GRPCTransportTypeChttp2BoringSSL = 0, // Cronet stack @@ -180,8 +181,10 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { @property(copy, readonly) NSString *channelPoolDomain; /** - * Channel id allows a call to force creating a new channel (connection) rather than using a cached - * channel. Calls using distinct channelID will not get cached to the same connection. + * Channel id allows control of channel caching within a channelPoolDomain. A call with a unique + * channelID will create a new channel (connection) instead of reusing an existing one. Multiple + * calls in the same channelPoolDomain using identical channelID are allowed to share connection + * if other channel options are also the same. */ @property(readonly) NSUInteger channelID; From 62fb609df7b9534f188804c43401f6219345577c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 18:10:02 -0700 Subject: [PATCH 0060/2143] rename kChannelPool->gChannelPool --- src/objective-c/GRPCClient/private/GRPCChannel.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index cf44b96e220..ae90821de03 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -64,7 +64,7 @@ } - (void)unmanagedCallUnref { - [kChannelPool unrefChannelWithConfiguration:_configuration]; + [gChannelPool unrefChannelWithConfiguration:_configuration]; } - (nullable instancetype)initWithUnmanagedChannel:(nullable grpc_channel *)unmanagedChannel @@ -94,12 +94,12 @@ } static dispatch_once_t initChannelPool; -static GRPCChannelPool *kChannelPool; +static GRPCChannelPool *gChannelPool; + (nullable instancetype)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { dispatch_once(&initChannelPool, ^{ - kChannelPool = [[GRPCChannelPool alloc] init]; + gChannelPool = [[GRPCChannelPool alloc] init]; }); NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:host]]; @@ -109,7 +109,7 @@ static GRPCChannelPool *kChannelPool; GRPCChannelConfiguration *channelConfig = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; - return [kChannelPool channelWithConfiguration:channelConfig + return [gChannelPool channelWithConfiguration:channelConfig createChannel:^{ return [GRPCChannel createChannelWithConfiguration:channelConfig]; @@ -117,7 +117,7 @@ static GRPCChannelPool *kChannelPool; } + (void)closeOpenConnections { - [kChannelPool clear]; + [gChannelPool clear]; } @end From 549db7b80b3e6e91aaf08f9f9bf2f932050cc310 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 18:10:48 -0700 Subject: [PATCH 0061/2143] host == nil -> host.length == 0 --- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index ae90821de03..495af5ebe87 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -82,7 +82,7 @@ + (nullable instancetype)createChannelWithConfiguration:(GRPCChannelConfiguration *)config { NSString *host = config.host; - if (host == nil || [host length] == 0) { + if (host.length == 0) { return nil; } From bc292b87c26ea8f6465443a152e86b3ed71e585b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 18:14:34 -0700 Subject: [PATCH 0062/2143] polish attributes of GRPCChannelConfiguration --- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 4 ++-- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 1145039549c..2a99089d2f2 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -31,8 +31,8 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCChannelConfiguration : NSObject -@property(atomic, strong, readwrite) NSString *host; -@property(atomic, strong, readwrite) GRPCCallOptions *callOptions; +@property(copy, readonly) NSString *host; +@property(strong, readonly) GRPCCallOptions *callOptions; @property(readonly) id channelFactory; @property(readonly) NSMutableDictionary *channelArgs; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 37e42f8c75b..10a15f5255b 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -141,9 +141,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; } - (nonnull id)copyWithZone:(nullable NSZone *)zone { - GRPCChannelConfiguration *newConfig = [[GRPCChannelConfiguration alloc] init]; - newConfig.host = _host; - newConfig.callOptions = _callOptions; + GRPCChannelConfiguration *newConfig = [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; return newConfig; } From ad5485ae4ef4ec31cb6b3ed54876fd9868343388 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Oct 2018 18:28:16 -0700 Subject: [PATCH 0063/2143] Make channel args immutable --- src/objective-c/GRPCClient/private/GRPCChannel.m | 10 ++++++++-- .../GRPCClient/private/GRPCChannelFactory.h | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- .../GRPCClient/private/GRPCCronetChannelFactory.h | 2 +- .../GRPCClient/private/GRPCCronetChannelFactory.m | 4 ++-- .../GRPCClient/private/GRPCInsecureChannelFactory.h | 2 +- .../GRPCClient/private/GRPCInsecureChannelFactory.m | 2 +- .../GRPCClient/private/GRPCSecureChannelFactory.h | 2 +- .../GRPCClient/private/GRPCSecureChannelFactory.m | 2 +- 10 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 495af5ebe87..2274fa5d6ab 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -86,8 +86,14 @@ return nil; } - NSMutableDictionary *channelArgs = config.channelArgs; - [channelArgs addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; + NSDictionary *channelArgs; + if (config.callOptions.additionalChannelArgs.count != 0) { + NSMutableDictionary *args = [config.channelArgs copy]; + [args addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; + channelArgs = args; + } else { + channelArgs = config.channelArgs; + } id factory = config.channelFactory; grpc_channel *unmanaged_channel = [factory createChannelWithHost:host channelArgs:channelArgs]; return [[GRPCChannel alloc] initWithUnmanagedChannel:unmanaged_channel configuration:config]; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h index e44f8260dfd..492145da80b 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN @protocol GRPCChannelFactory - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableDictionary *)args; + channelArgs:(nullable NSDictionary *)args; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 2a99089d2f2..1984919fa75 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -35,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN @property(strong, readonly) GRPCCallOptions *callOptions; @property(readonly) id channelFactory; -@property(readonly) NSMutableDictionary *channelArgs; +@property(readonly) NSDictionary *channelArgs; - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 10a15f5255b..11c9d4be8dd 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -76,7 +76,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; } } -- (NSMutableDictionary *)channelArgs { +- (NSDictionary *)channelArgs { NSMutableDictionary *args = [NSMutableDictionary new]; NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h index 97e1ae920a0..738dfdb7370 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h @@ -27,7 +27,7 @@ NS_ASSUME_NONNULL_BEGIN + (nullable instancetype)sharedInstance; - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableDictionary *)args; + channelArgs:(nullable NSDictionary *)args; - (nullable instancetype)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 5c0fe16d39b..00b388ebbe0 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -53,7 +53,7 @@ NS_ASSUME_NONNULL_BEGIN } - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableDictionary *)args { + channelArgs:(nullable NSDictionary *)args { // Remove client authority filter since that is not supported args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1]; @@ -81,7 +81,7 @@ NS_ASSUME_NONNULL_BEGIN } - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableArray *)args { + channelArgs:(nullable NSDictionary *)args { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return nil; diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h index 905a181ca78..2d471aebed6 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h @@ -26,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN + (nullable instancetype)sharedInstance; - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableDictionary *)args; + channelArgs:(nullable NSDictionary *)args; - (nullable instancetype)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index 41860bf6ff5..d969b887b40 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -35,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN } - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableDictionary *)args { + channelArgs:(nullable NSDictionary *)args { grpc_channel_args *coreChannelArgs = BuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h index ab5eee478e1..82af0dc3e68 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN error:(NSError **)errorPtr; - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableDictionary *)args; + channelArgs:(nullable NSDictionary *)args; - (nullable instancetype)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index a0d56e4bdc7..277823c4e33 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -110,7 +110,7 @@ NS_ASSUME_NONNULL_BEGIN } - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSMutableArray *)args { + channelArgs:(nullable NSDictionary *)args { grpc_channel_args *coreChannelArgs = BuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); From da42aa1c1ba38a12450e6b75b20281d6603b3d7e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 10:06:07 -0700 Subject: [PATCH 0064/2143] Add designated initializer annotation --- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 1984919fa75..5ceb0b6d821 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -49,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init; -- (instancetype)initWithChannelDestroyDelay:(NSTimeInterval)channelDestroyDelay; +- (instancetype)initWithChannelDestroyDelay:(NSTimeInterval)channelDestroyDelay NS_DESIGNATED_INITIALIZER; /** * Return a channel with a particular configuration. If the channel does not exist, execute \a From 677ab86b4a8567197550d6969a4d5bd76b8206e1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 10:33:38 -0700 Subject: [PATCH 0065/2143] rename createChannel -> createChannelCallback --- src/objective-c/GRPCClient/private/GRPCChannel.m | 8 ++++---- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 2274fa5d6ab..bea75d25a98 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -116,10 +116,10 @@ static GRPCChannelPool *gChannelPool; GRPCChannelConfiguration *channelConfig = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; return [gChannelPool channelWithConfiguration:channelConfig - createChannel:^{ - return - [GRPCChannel createChannelWithConfiguration:channelConfig]; - }]; + createChannelCallback:^{ + return + [GRPCChannel createChannelWithConfiguration:channelConfig]; + }]; } + (void)closeOpenConnections { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 5ceb0b6d821..48c35eacb01 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -56,7 +56,7 @@ NS_ASSUME_NONNULL_BEGIN * createChannel then add it in the pool. If the channel exists, increase its reference count. */ - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration - createChannel:(GRPCChannel * (^)(void))createChannel; + createChannelCallback:(GRPCChannel * (^)(void))createChannelCallback; /** Decrease a channel's refcount. */ - (void)unrefChannelWithConfiguration:configuration; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 11c9d4be8dd..680b268dcfa 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -338,14 +338,14 @@ const NSTimeInterval kChannelDestroyDelay = 30; } - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration - createChannel:(GRPCChannel * (^)(void))createChannel { + createChannelCallback:(GRPCChannel * (^)(void))createChannelCallback { __block GRPCChannel *channel; dispatch_sync(_dispatchQueue, ^{ if ([self->_channelPool objectForKey:configuration]) { [self->_callRefs[configuration] refChannel]; channel = self->_channelPool[configuration]; } else { - channel = createChannel(); + channel = createChannelCallback(); self->_channelPool[configuration] = channel; GRPCChannelCallRef *callRef = [[GRPCChannelCallRef alloc] From 86ff72bb4736cb9333505baeb324386cfa24bcb9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 10:49:30 -0700 Subject: [PATCH 0066/2143] Add missing type information --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 680b268dcfa..c46b9ddfc80 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -363,7 +363,7 @@ const NSTimeInterval kChannelDestroyDelay = 30; return channel; } -- (void)unrefChannelWithConfiguration:configuration { +- (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { dispatch_sync(_dispatchQueue, ^{ if ([self->_channelPool objectForKey:configuration]) { [self->_callRefs[configuration] unrefChannel]; From 8fef0c87893ceda1c5bb7aaa09ddb8dfaefacbdb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 16:59:00 -0700 Subject: [PATCH 0067/2143] Rewrite the channel pool --- src/objective-c/GRPCClient/GRPCCall.m | 9 +- .../GRPCClient/private/GRPCChannel.h | 13 +- .../GRPCClient/private/GRPCChannel.m | 204 +++++++++++++++--- .../GRPCClient/private/GRPCChannelPool.h | 14 +- .../GRPCClient/private/GRPCChannelPool.m | 141 ++---------- .../tests/ChannelTests/ChannelPoolTest.m | 109 ++++------ 6 files changed, 263 insertions(+), 227 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 16acca249d6..5ffdfbaa89f 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -718,7 +718,14 @@ const char *kCFStreamVarName = "grpc_cfstream"; [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; - NSAssert(_wrappedCall, @"Error allocating RPC objects. Low memory?"); + if (_wrappedCall == nil) { + [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : @"Failed to create call from channel." + }]]; + return; + } [self sendHeaders]; [self invokeCall]; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 7d5039a8a20..7a40638dc33 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -39,6 +39,11 @@ struct grpc_channel_credentials; + (nullable instancetype)channelWithHost:(nonnull NSString *)host callOptions:(nullable GRPCCallOptions *)callOptions; +/** + * Create a channel object with the signature \a config. + */ ++ (nullable instancetype)createChannelWithConfiguration:(nonnull GRPCChannelConfiguration *)config; + /** * Get a grpc core call object from this channel. */ @@ -46,13 +51,11 @@ struct grpc_channel_credentials; completionQueue:(nonnull GRPCCompletionQueue *)queue callOptions:(nonnull GRPCCallOptions *)callOptions; +- (void)unmanagedCallRef; + - (void)unmanagedCallUnref; -/** - * Create a channel object with the signature \a config. This function is used for testing only. Use - * channelWithHost:callOptions: in production. - */ -+ (nullable instancetype)createChannelWithConfiguration:(nonnull GRPCChannelConfiguration *)config; +- (void)disconnect; // TODO (mxyan): deprecate with GRPCCall:closeOpenConnections + (void)closeOpenConnections; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index bea75d25a98..9e7e1ea1fc6 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -24,7 +24,6 @@ #import "GRPCChannelFactory.h" #import "GRPCChannelPool.h" #import "GRPCCompletionQueue.h" -#import "GRPCConnectivityMonitor.h" #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" @@ -33,38 +32,180 @@ #import #import +// When all calls of a channel are destroyed, destroy the channel after this much seconds. +NSTimeInterval kChannelDestroyDelay = 30; + +/** + * Time the channel destroy when the channel's calls are unreffed. If there's new call, reset the + * timer. + */ +@interface GRPCChannelRef : NSObject + +- (instancetype)initWithDestroyDelay:(NSTimeInterval)destroyDelay + destroyChannelCallback:(void (^)())destroyChannelCallback; + +/** Add call ref count to the channel and maybe reset the timer. */ +- (void)refChannel; + +/** Reduce call ref count to the channel and maybe set the timer. */ +- (void)unrefChannel; + +/** Disconnect the channel immediately. */ +- (void)disconnect; + +@end + +@implementation GRPCChannelRef { + NSTimeInterval _destroyDelay; + // We use dispatch queue for this purpose since timer invalidation must happen on the same + // thread which issued the timer. + dispatch_queue_t _dispatchQueue; + void (^_destroyChannelCallback)(); + + NSUInteger _refCount; + NSTimer *_timer; + BOOL _disconnected; +} + +- (instancetype)initWithDestroyDelay:(NSTimeInterval)destroyDelay + destroyChannelCallback:(void (^)())destroyChannelCallback { + if ((self = [super init])) { + _destroyDelay = destroyDelay; + _destroyChannelCallback = destroyChannelCallback; + + _refCount = 1; + _timer = nil; + _disconnected = NO; + } + return self; +} + +// This function is protected by channel dispatch queue. +- (void)refChannel { + if (!_disconnected) { + _refCount++; + if (_timer) { + [_timer invalidate]; + _timer = nil; + } + } +} + +// This function is protected by channel dispatch queue. +- (void)unrefChannel { + if (!_disconnected) { + _refCount--; + if (_refCount == 0) { + if (_timer) { + [_timer invalidate]; + } + _timer = [NSTimer scheduledTimerWithTimeInterval:self->_destroyDelay + target:self + selector:@selector(timerFire:) + userInfo:nil + repeats:NO]; + } + } +} + +// This function is protected by channel dispatch queue. +- (void)disconnect { + if (!_disconnected) { + if (self->_timer != nil) { + [self->_timer invalidate]; + self->_timer = nil; + } + _disconnected = YES; + // Break retain loop + _destroyChannelCallback = nil; + } +} + +// This function is protected by channel dispatch queue. +- (void)timerFire:(NSTimer *)timer { + if (_disconnected || _timer == nil || _timer != timer) { + return; + } + _timer = nil; + _destroyChannelCallback(); + // Break retain loop + _destroyChannelCallback = nil; + _disconnected = YES; +} + +@end + @implementation GRPCChannel { GRPCChannelConfiguration *_configuration; grpc_channel *_unmanagedChannel; + GRPCChannelRef *_channelRef; + dispatch_queue_t _dispatchQueue; } - (grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(nonnull GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions { - NSString *serverAuthority = callOptions.serverAuthority; - NSTimeInterval timeout = callOptions.timeout; - GPR_ASSERT(timeout >= 0); - grpc_slice host_slice = grpc_empty_slice(); - if (serverAuthority) { - host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); - } - grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); - gpr_timespec deadline_ms = + __block grpc_call *call = nil; + dispatch_sync(_dispatchQueue, ^{ + if (self->_unmanagedChannel) { + NSString *serverAuthority = callOptions.serverAuthority; + NSTimeInterval timeout = callOptions.timeout; + GPR_ASSERT(timeout >= 0); + grpc_slice host_slice = grpc_empty_slice(); + if (serverAuthority) { + host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); + } + grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); + gpr_timespec deadline_ms = timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME) - : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); - grpc_call *call = grpc_channel_create_call( - _unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, - serverAuthority ? &host_slice : NULL, deadline_ms, NULL); - if (serverAuthority) { - grpc_slice_unref(host_slice); - } - grpc_slice_unref(path_slice); + : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + call = grpc_channel_create_call( + self->_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, + serverAuthority ? &host_slice : NULL, deadline_ms, NULL); + if (serverAuthority) { + grpc_slice_unref(host_slice); + } + grpc_slice_unref(path_slice); + } + }); return call; } +- (void)unmanagedCallRef { + dispatch_async(_dispatchQueue, ^{ + if (self->_unmanagedChannel) { + [self->_channelRef refChannel]; + } + }); +} + - (void)unmanagedCallUnref { - [gChannelPool unrefChannelWithConfiguration:_configuration]; + dispatch_async(_dispatchQueue, ^{ + if (self->_unmanagedChannel) { + [self->_channelRef unrefChannel]; + } + }); +} + +- (void)disconnect { + dispatch_async(_dispatchQueue, ^{ + if (self->_unmanagedChannel) { + grpc_channel_destroy(self->_unmanagedChannel); + self->_unmanagedChannel = nil; + [self->_channelRef disconnect]; + } + }); +} + +- (void)destroyChannel { + dispatch_async(_dispatchQueue, ^{ + if (self->_unmanagedChannel) { + grpc_channel_destroy(self->_unmanagedChannel); + self->_unmanagedChannel = nil; + [gChannelPool removeChannelWithConfiguration:self->_configuration]; + } + }); } - (nullable instancetype)initWithUnmanagedChannel:(nullable grpc_channel *)unmanagedChannel @@ -72,12 +213,22 @@ if ((self = [super init])) { _unmanagedChannel = unmanagedChannel; _configuration = configuration; + _channelRef = [[GRPCChannelRef alloc] initWithDestroyDelay:kChannelDestroyDelay destroyChannelCallback:^{ + [self destroyChannel]; + }]; + if (@available(iOS 8.0, *)) { + _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + } else { + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } } return self; } - (void)dealloc { - grpc_channel_destroy(_unmanagedChannel); + if (_unmanagedChannel) { + grpc_channel_destroy(_unmanagedChannel); + } } + (nullable instancetype)createChannelWithConfiguration:(GRPCChannelConfiguration *)config { @@ -88,7 +239,7 @@ NSDictionary *channelArgs; if (config.callOptions.additionalChannelArgs.count != 0) { - NSMutableDictionary *args = [config.channelArgs copy]; + NSMutableDictionary *args = [config.channelArgs mutableCopy]; [args addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; channelArgs = args; } else { @@ -115,15 +266,12 @@ static GRPCChannelPool *gChannelPool; GRPCChannelConfiguration *channelConfig = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; - return [gChannelPool channelWithConfiguration:channelConfig - createChannelCallback:^{ - return - [GRPCChannel createChannelWithConfiguration:channelConfig]; - }]; + + return [gChannelPool channelWithConfiguration:channelConfig]; } + (void)closeOpenConnections { - [gChannelPool clear]; + [gChannelPool removeAndCloseAllChannels]; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 48c35eacb01..bd1350c15d2 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -49,20 +49,20 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init; -- (instancetype)initWithChannelDestroyDelay:(NSTimeInterval)channelDestroyDelay NS_DESIGNATED_INITIALIZER; - /** * Return a channel with a particular configuration. If the channel does not exist, execute \a * createChannel then add it in the pool. If the channel exists, increase its reference count. */ -- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration - createChannelCallback:(GRPCChannel * (^)(void))createChannelCallback; +- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration; -/** Decrease a channel's refcount. */ -- (void)unrefChannelWithConfiguration:configuration; +/** Remove a channel with particular configuration. */ +- (void)removeChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; /** Clear all channels in the pool. */ -- (void)clear; +- (void)removeAllChannels; + +/** Clear all channels in the pool and destroy the channels. */ +- (void)removeAndCloseAllChannels; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index c46b9ddfc80..7c0a8a8621d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -18,6 +18,7 @@ #import +#import "GRPCChannel.h" #import "GRPCChannelFactory.h" #import "GRPCChannelPool.h" #import "GRPCConnectivityMonitor.h" @@ -31,9 +32,6 @@ extern const char *kCFStreamVarName; -// When all calls of a channel are destroyed, destroy the channel after this much seconds. -const NSTimeInterval kChannelDestroyDelay = 30; - @implementation GRPCChannelConfiguration - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { @@ -216,109 +214,22 @@ const NSTimeInterval kChannelDestroyDelay = 30; @end -/** - * Time the channel destroy when the channel's calls are unreffed. If there's new call, reset the - * timer. - */ -@interface GRPCChannelCallRef : NSObject - -- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)configuration - destroyDelay:(NSTimeInterval)destroyDelay - dispatchQueue:(dispatch_queue_t)dispatchQueue - destroyChannel:(void (^)())destroyChannel; - -/** Add call ref count to the channel and maybe reset the timer. */ -- (void)refChannel; - -/** Reduce call ref count to the channel and maybe set the timer. */ -- (void)unrefChannel; - -@end - -@implementation GRPCChannelCallRef { - GRPCChannelConfiguration *_configuration; - NSTimeInterval _destroyDelay; - // We use dispatch queue for this purpose since timer invalidation must happen on the same - // thread which issued the timer. - dispatch_queue_t _dispatchQueue; - void (^_destroyChannel)(); - - NSUInteger _refCount; - NSTimer *_timer; -} - -- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)configuration - destroyDelay:(NSTimeInterval)destroyDelay - dispatchQueue:(dispatch_queue_t)dispatchQueue - destroyChannel:(void (^)())destroyChannel { - if ((self = [super init])) { - _configuration = configuration; - _destroyDelay = destroyDelay; - _dispatchQueue = dispatchQueue; - _destroyChannel = destroyChannel; - - _refCount = 0; - _timer = nil; - } - return self; -} - -// This function is protected by channel pool dispatch queue. -- (void)refChannel { - _refCount++; - if (_timer) { - [_timer invalidate]; - } - _timer = nil; -} - -// This function is protected by channel spool dispatch queue. -- (void)unrefChannel { - self->_refCount--; - if (self->_refCount == 0) { - if (self->_timer) { - [self->_timer invalidate]; - } - self->_timer = [NSTimer scheduledTimerWithTimeInterval:self->_destroyDelay - target:self - selector:@selector(timerFire:) - userInfo:nil - repeats:NO]; - } -} - -- (void)timerFire:(NSTimer *)timer { - dispatch_sync(_dispatchQueue, ^{ - if (self->_timer == nil || self->_timer != timer) { - return; - } - self->_timer = nil; - self->_destroyChannel(self->_configuration); - }); -} - -@end - #pragma mark GRPCChannelPool @implementation GRPCChannelPool { - NSTimeInterval _channelDestroyDelay; NSMutableDictionary *_channelPool; - NSMutableDictionary *_callRefs; // Dedicated queue for timer dispatch_queue_t _dispatchQueue; } - (instancetype)init { - return [self initWithChannelDestroyDelay:kChannelDestroyDelay]; -} - -- (instancetype)initWithChannelDestroyDelay:(NSTimeInterval)channelDestroyDelay { if ((self = [super init])) { - _channelDestroyDelay = channelDestroyDelay; _channelPool = [NSMutableDictionary dictionary]; - _callRefs = [NSMutableDictionary dictionary]; - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + if (@available(iOS 8.0, *)) { + _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + } else { + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } // Connectivity monitor is not required for CFStream char *enableCFStream = getenv(kCFStreamVarName); @@ -337,49 +248,43 @@ const NSTimeInterval kChannelDestroyDelay = 30; } } -- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration - createChannelCallback:(GRPCChannel * (^)(void))createChannelCallback { +- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration { __block GRPCChannel *channel; dispatch_sync(_dispatchQueue, ^{ if ([self->_channelPool objectForKey:configuration]) { - [self->_callRefs[configuration] refChannel]; channel = self->_channelPool[configuration]; + [channel unmanagedCallRef]; } else { - channel = createChannelCallback(); + channel = [GRPCChannel createChannelWithConfiguration:configuration]; self->_channelPool[configuration] = channel; - - GRPCChannelCallRef *callRef = [[GRPCChannelCallRef alloc] - initWithChannelConfiguration:configuration - destroyDelay:self->_channelDestroyDelay - dispatchQueue:self->_dispatchQueue - destroyChannel:^(GRPCChannelConfiguration *configuration) { - [self->_channelPool removeObjectForKey:configuration]; - [self->_callRefs removeObjectForKey:configuration]; - }]; - [callRef refChannel]; - self->_callRefs[configuration] = callRef; } }); return channel; } -- (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { - dispatch_sync(_dispatchQueue, ^{ - if ([self->_channelPool objectForKey:configuration]) { - [self->_callRefs[configuration] unrefChannel]; - } +- (void)removeChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { + dispatch_async(_dispatchQueue, ^{ + [self->_channelPool removeObjectForKey:configuration]; }); } -- (void)clear { +- (void)removeAllChannels { dispatch_sync(_dispatchQueue, ^{ self->_channelPool = [NSMutableDictionary dictionary]; - self->_callRefs = [NSMutableDictionary dictionary]; + }); +} + +- (void)removeAndCloseAllChannels { + dispatch_sync(_dispatchQueue, ^{ + [self->_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannel * _Nonnull obj, BOOL * _Nonnull stop) { + [obj disconnect]; + }]; + self->_channelPool = [NSMutableDictionary dictionary]; }); } - (void)connectivityChange:(NSNotification *)note { - [self clear]; + [self removeAndCloseAllChannels]; } @end diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index 9e1c9eca746..b195b747a12 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -44,83 +44,68 @@ NSString *kDummyHost = @"dummy.host"; [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelConfiguration *config2 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initWithChannelDestroyDelay:1]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - __weak XCTestExpectation *expectCreateChannel = - [self expectationWithDescription:@"Create first channel"]; - GRPCChannel *channel1 = - [pool channelWithConfiguration:config1 - createChannel:^{ - [expectCreateChannel fulfill]; - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; - GRPCChannel *channel2 = [pool channelWithConfiguration:config2 - createChannel:^{ - XCTFail(@"Should not create a second channel."); - return (GRPCChannel *)nil; - }]; + GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; + GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; XCTAssertEqual(channel1, channel2); } -- (void)testChannelTimeout { - NSTimeInterval kChannelDestroyDelay = 1.0; +- (void)testChannelRemove { GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; options1.transportType = GRPCTransportTypeInsecure; GRPCChannelConfiguration *config1 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelPool *pool = - [[GRPCChannelPool alloc] initWithChannelDestroyDelay:kChannelDestroyDelay]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCChannel *channel1 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; - [pool unrefChannelWithConfiguration:config1]; - __weak XCTestExpectation *expectTimerDone = [self expectationWithDescription:@"Timer elapse."]; - NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:kChannelDestroyDelay + 1 - repeats:NO - block:^(NSTimer *_Nonnull timer) { - [expectTimerDone fulfill]; - }]; - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; - timer = nil; + [pool channelWithConfiguration:config1]; + [pool removeChannelWithConfiguration:config1]; GRPCChannel *channel2 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; + [pool channelWithConfiguration:config1]; XCTAssertNotEqual(channel1, channel2); } +extern NSTimeInterval kChannelDestroyDelay; + - (void)testChannelTimeoutCancel { - NSTimeInterval kChannelDestroyDelay = 3.0; + NSTimeInterval kOriginalInterval = kChannelDestroyDelay; + kChannelDestroyDelay = 3.0; GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; options1.transportType = GRPCTransportTypeInsecure; GRPCChannelConfiguration *config1 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelPool *pool = - [[GRPCChannelPool alloc] initWithChannelDestroyDelay:kChannelDestroyDelay]; + [[GRPCChannelPool alloc] init]; GRPCChannel *channel1 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; + [pool channelWithConfiguration:config1]; [channel1 unmanagedCallUnref]; sleep(1); GRPCChannel *channel2 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; + [pool channelWithConfiguration:config1]; XCTAssertEqual(channel1, channel2); sleep((int)kChannelDestroyDelay + 2); GRPCChannel *channel3 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; + [pool channelWithConfiguration:config1]; XCTAssertEqual(channel1, channel3); + kChannelDestroyDelay = kOriginalInterval; +} + +- (void)testChannelDisconnect { + NSString *kDummyHost = @"dummy.host"; + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; + options1.transportType = GRPCTransportTypeInsecure; + GRPCCallOptions *options2 = [options1 copy]; + GRPCChannelConfiguration *config1 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; + GRPCChannelConfiguration *config2 = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + + + GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; + [pool removeAndCloseAllChannels]; + GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; + XCTAssertNotEqual(channel1, channel2); } - (void)testClearChannels { @@ -132,31 +117,19 @@ NSString *kDummyHost = @"dummy.host"; [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelConfiguration *config2 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initWithChannelDestroyDelay:1]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCChannel *channel1 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; + [pool channelWithConfiguration:config1]; GRPCChannel *channel2 = - [pool channelWithConfiguration:config2 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config2]; - }]; + [pool channelWithConfiguration:config2]; XCTAssertNotEqual(channel1, channel2); - [pool clear]; + [pool removeAndCloseAllChannels]; GRPCChannel *channel3 = - [pool channelWithConfiguration:config1 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config1]; - }]; + [pool channelWithConfiguration:config1]; GRPCChannel *channel4 = - [pool channelWithConfiguration:config2 - createChannel:^{ - return [GRPCChannel createChannelWithConfiguration:config2]; - }]; + [pool channelWithConfiguration:config2]; XCTAssertNotEqual(channel1, channel3); XCTAssertNotEqual(channel2, channel4); } From d47f4b4c23a9dab2813e9b521d2545ea26d0105c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 17:06:16 -0700 Subject: [PATCH 0068/2143] Check return value rather than error --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 7c0a8a8621d..740eeaf6cf8 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -36,8 +36,8 @@ extern const char *kCFStreamVarName; - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { if ((self = [super init])) { - _host = host; - _callOptions = callOptions; + _host = [host copy]; + _callOptions = [callOptions copy]; } return self; } @@ -56,9 +56,8 @@ extern const char *kCFStreamVarName; privateKey:_callOptions.PEMPrivateKey certChain:_callOptions.PEMCertChain error:&error]; - if (error) { + if (factory == nil) { NSLog(@"Error creating secure channel factory: %@", error); - return nil; } return factory; #ifdef GRPC_COMPILE_WITH_CRONET From f48c90606f246afab3a2aa1e1547578c4c34292a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 17:46:09 -0700 Subject: [PATCH 0069/2143] Add isChannelOptionsEqualTo: to GRPCCallOptions --- src/objective-c/GRPCClient/GRPCCallOptions.h | 5 +++ src/objective-c/GRPCClient/GRPCCallOptions.m | 40 +++++++++++++++++++ .../GRPCClient/private/GRPCChannelPool.m | 38 +----------------- 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index e1a63f83b2e..bf03938b272 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -188,6 +188,11 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ @property(readonly) NSUInteger channelID; +/** + * Return if the channel options are equal to another object. + */ +- (BOOL)isChannelOptionsEqualTo:(GRPCCallOptions *)callOptions; + @end @interface GRPCMutableCallOptions : GRPCCallOptions diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index b19917d7784..1fc8c9fb1af 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -227,6 +227,46 @@ static NSUInteger kDefaultChannelID = 0; return newOptions; } +- (BOOL)isChannelOptionsEqualTo:(GRPCCallOptions *)callOptions { + if (!(callOptions.userAgentPrefix == _userAgentPrefix || + [callOptions.userAgentPrefix isEqualToString:_userAgentPrefix])) + return NO; + if (!(callOptions.responseSizeLimit == _responseSizeLimit)) return NO; + if (!(callOptions.compressAlgorithm == _compressAlgorithm)) return NO; + if (!(callOptions.enableRetry == _enableRetry)) return NO; + if (!(callOptions.keepaliveInterval == _keepaliveInterval)) return NO; + if (!(callOptions.keepaliveTimeout == _keepaliveTimeout)) return NO; + if (!(callOptions.connectMinTimeout == _connectMinTimeout)) return NO; + if (!(callOptions.connectInitialBackoff == _connectInitialBackoff)) return NO; + if (!(callOptions.connectMaxBackoff == _connectMaxBackoff)) return NO; + if (!(callOptions.additionalChannelArgs == _additionalChannelArgs || + [callOptions.additionalChannelArgs + isEqualToDictionary:_additionalChannelArgs])) + return NO; + if (!(callOptions.PEMRootCertificates == _PEMRootCertificates || + [callOptions.PEMRootCertificates isEqualToString:_PEMRootCertificates])) + return NO; + if (!(callOptions.PEMPrivateKey == _PEMPrivateKey || + [callOptions.PEMPrivateKey isEqualToString:_PEMPrivateKey])) + return NO; + if (!(callOptions.PEMCertChain == _PEMCertChain || + [callOptions.PEMCertChain isEqualToString:_PEMCertChain])) + return NO; + if (!(callOptions.hostNameOverride == _hostNameOverride || + [callOptions.hostNameOverride isEqualToString:_hostNameOverride])) + return NO; + if (!(callOptions.transportType == _transportType)) return NO; + if (!(callOptions.logContext == _logContext || + [callOptions.logContext isEqual:_logContext])) + return NO; + if (!(callOptions.channelPoolDomain == _channelPoolDomain || + [callOptions.channelPoolDomain isEqualToString:_channelPoolDomain])) + return NO; + if (!(callOptions.channelID == _channelID)) return NO; + + return YES; +} + @end @implementation GRPCMutableCallOptions diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 740eeaf6cf8..995212fdb6d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -68,8 +68,6 @@ extern const char *kCFStreamVarName; return [GRPCCronetChannelFactory sharedInstance]; case GRPCTransportTypeInsecure: return [GRPCInsecureChannelFactory sharedInstance]; - default: - GPR_UNREACHABLE_CODE(return nil); } } @@ -147,41 +145,7 @@ extern const char *kCFStreamVarName; NSAssert([object isKindOfClass:[GRPCChannelConfiguration class]], @"Illegal :isEqual"); GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; if (!(obj.host == _host || [obj.host isEqualToString:_host])) return NO; - if (!(obj.callOptions.userAgentPrefix == _callOptions.userAgentPrefix || - [obj.callOptions.userAgentPrefix isEqualToString:_callOptions.userAgentPrefix])) - return NO; - if (!(obj.callOptions.responseSizeLimit == _callOptions.responseSizeLimit)) return NO; - if (!(obj.callOptions.compressAlgorithm == _callOptions.compressAlgorithm)) return NO; - if (!(obj.callOptions.enableRetry == _callOptions.enableRetry)) return NO; - if (!(obj.callOptions.keepaliveInterval == _callOptions.keepaliveInterval)) return NO; - if (!(obj.callOptions.keepaliveTimeout == _callOptions.keepaliveTimeout)) return NO; - if (!(obj.callOptions.connectMinTimeout == _callOptions.connectMinTimeout)) return NO; - if (!(obj.callOptions.connectInitialBackoff == _callOptions.connectInitialBackoff)) return NO; - if (!(obj.callOptions.connectMaxBackoff == _callOptions.connectMaxBackoff)) return NO; - if (!(obj.callOptions.additionalChannelArgs == _callOptions.additionalChannelArgs || - [obj.callOptions.additionalChannelArgs - isEqualToDictionary:_callOptions.additionalChannelArgs])) - return NO; - if (!(obj.callOptions.PEMRootCertificates == _callOptions.PEMRootCertificates || - [obj.callOptions.PEMRootCertificates isEqualToString:_callOptions.PEMRootCertificates])) - return NO; - if (!(obj.callOptions.PEMPrivateKey == _callOptions.PEMPrivateKey || - [obj.callOptions.PEMPrivateKey isEqualToString:_callOptions.PEMPrivateKey])) - return NO; - if (!(obj.callOptions.PEMCertChain == _callOptions.PEMCertChain || - [obj.callOptions.PEMCertChain isEqualToString:_callOptions.PEMCertChain])) - return NO; - if (!(obj.callOptions.hostNameOverride == _callOptions.hostNameOverride || - [obj.callOptions.hostNameOverride isEqualToString:_callOptions.hostNameOverride])) - return NO; - if (!(obj.callOptions.transportType == _callOptions.transportType)) return NO; - if (!(obj.callOptions.logContext == _callOptions.logContext || - [obj.callOptions.logContext isEqual:_callOptions.logContext])) - return NO; - if (!(obj.callOptions.channelPoolDomain == _callOptions.channelPoolDomain || - [obj.callOptions.channelPoolDomain isEqualToString:_callOptions.channelPoolDomain])) - return NO; - if (!(obj.callOptions.channelID == _callOptions.channelID)) return NO; + if (!(obj.callOptions == _callOptions || [obj.callOptions isChannelOptionsEqualTo:_callOptions])) return NO; return YES; } From d578b4321812715de7fe615a1ae8624fd05f1c69 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 18:01:14 -0700 Subject: [PATCH 0070/2143] Add channelOptionsHash: to GRPCCChannelOptions --- src/objective-c/GRPCClient/GRPCCallOptions.h | 5 ++++ src/objective-c/GRPCClient/GRPCCallOptions.m | 24 +++++++++++++++++++ .../GRPCClient/private/GRPCChannelPool.m | 19 +-------------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index bf03938b272..8864bcb8a2f 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -193,6 +193,11 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ - (BOOL)isChannelOptionsEqualTo:(GRPCCallOptions *)callOptions; +/** + * Hash for channel options. + */ +@property(readonly) NSUInteger channelOptionsHash; + @end @interface GRPCMutableCallOptions : GRPCCallOptions diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 1fc8c9fb1af..8d2b84b7484 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -267,6 +267,30 @@ static NSUInteger kDefaultChannelID = 0; return YES; } +- (NSUInteger)channelOptionsHash { + NSUInteger result = 0; + result ^= _userAgentPrefix.hash; + result ^= _responseSizeLimit; + result ^= _compressAlgorithm; + result ^= _enableRetry; + result ^= (unsigned int)(_keepaliveInterval * 1000); + result ^= (unsigned int)(_keepaliveTimeout * 1000); + result ^= (unsigned int)(_connectMinTimeout * 1000); + result ^= (unsigned int)(_connectInitialBackoff * 1000); + result ^= (unsigned int)(_connectMaxBackoff * 1000); + result ^= _additionalChannelArgs.hash; + result ^= _PEMRootCertificates.hash; + result ^= _PEMPrivateKey.hash; + result ^= _PEMCertChain.hash; + result ^= _hostNameOverride.hash; + result ^= _transportType; + result ^= [_logContext hash]; + result ^= _channelPoolDomain.hash; + result ^= _channelID; + + return result; +} + @end @implementation GRPCMutableCallOptions diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 995212fdb6d..4fae7d57ca2 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -153,24 +153,7 @@ extern const char *kCFStreamVarName; - (NSUInteger)hash { NSUInteger result = 0; result ^= _host.hash; - result ^= _callOptions.userAgentPrefix.hash; - result ^= _callOptions.responseSizeLimit; - result ^= _callOptions.compressAlgorithm; - result ^= _callOptions.enableRetry; - result ^= (unsigned int)(_callOptions.keepaliveInterval * 1000); - result ^= (unsigned int)(_callOptions.keepaliveTimeout * 1000); - result ^= (unsigned int)(_callOptions.connectMinTimeout * 1000); - result ^= (unsigned int)(_callOptions.connectInitialBackoff * 1000); - result ^= (unsigned int)(_callOptions.connectMaxBackoff * 1000); - result ^= _callOptions.additionalChannelArgs.hash; - result ^= _callOptions.PEMRootCertificates.hash; - result ^= _callOptions.PEMPrivateKey.hash; - result ^= _callOptions.PEMCertChain.hash; - result ^= _callOptions.hostNameOverride.hash; - result ^= _callOptions.transportType; - result ^= [_callOptions.logContext hash]; - result ^= _callOptions.channelPoolDomain.hash; - result ^= _callOptions.channelID; + result ^= _callOptions.channelOptionsHash; return result; } From 34e4db810fcf08f51ee5104561426fc736308216 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 18:04:42 -0700 Subject: [PATCH 0071/2143] Take advantage of nil messaging --- src/objective-c/GRPCClient/private/GRPCChannel.m | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 9e7e1ea1fc6..5e0b37c1b82 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -84,10 +84,8 @@ NSTimeInterval kChannelDestroyDelay = 30; - (void)refChannel { if (!_disconnected) { _refCount++; - if (_timer) { - [_timer invalidate]; - _timer = nil; - } + [_timer invalidate]; + _timer = nil; } } @@ -96,9 +94,7 @@ NSTimeInterval kChannelDestroyDelay = 30; if (!_disconnected) { _refCount--; if (_refCount == 0) { - if (_timer) { - [_timer invalidate]; - } + [_timer invalidate]; _timer = [NSTimer scheduledTimerWithTimeInterval:self->_destroyDelay target:self selector:@selector(timerFire:) @@ -111,10 +107,8 @@ NSTimeInterval kChannelDestroyDelay = 30; // This function is protected by channel dispatch queue. - (void)disconnect { if (!_disconnected) { - if (self->_timer != nil) { - [self->_timer invalidate]; - self->_timer = nil; - } + [_timer invalidate]; + _timer = nil; _disconnected = YES; // Break retain loop _destroyChannelCallback = nil; From be4ab30899f6ae91e07f02c33297ca462f778296 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 17 Oct 2018 18:05:22 -0700 Subject: [PATCH 0072/2143] Remove dereferencing --- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 5e0b37c1b82..a17cc253feb 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -95,7 +95,7 @@ NSTimeInterval kChannelDestroyDelay = 30; _refCount--; if (_refCount == 0) { [_timer invalidate]; - _timer = [NSTimer scheduledTimerWithTimeInterval:self->_destroyDelay + _timer = [NSTimer scheduledTimerWithTimeInterval:_destroyDelay target:self selector:@selector(timerFire:) userInfo:nil From 67a4eb6623d0870992051d0280b78dd7a2b2c0ff Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 09:53:41 -0700 Subject: [PATCH 0073/2143] Lock GRPCCall in GRPCAuthorizatioProtocol --- src/objective-c/GRPCClient/GRPCCall.m | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 5ffdfbaa89f..68f0f8892d7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -461,10 +461,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)cancel { - if (!self.isWaitingForToken) { - [self cancelCall]; - } else { - self.isWaitingForToken = NO; + @synchronized (self) { + if (!self.isWaitingForToken) { + [self cancelCall]; + } else { + self.isWaitingForToken = NO; + } } [self maybeFinishWithError:[NSError @@ -779,14 +781,18 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = callOptions; } if (_callOptions.authTokenProvider != nil) { - self.isWaitingForToken = YES; + @synchronized (self) { + self.isWaitingForToken = YES; + } [self.tokenProvider getTokenWithHandler:^(NSString *token) { - if (self.isWaitingForToken) { - if (token) { - self->_fetchedOauth2AccessToken = [token copy]; + @synchronized (self) { + if (self.isWaitingForToken) { + if (token) { + self->_fetchedOauth2AccessToken = [token copy]; + } + [self startCallWithWriteable:writeable]; + self.isWaitingForToken = NO; } - [self startCallWithWriteable:writeable]; - self.isWaitingForToken = NO; } }]; } else { From ac211b4214b9a5bbc00631b61af396557837b9fb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 10:39:48 -0700 Subject: [PATCH 0074/2143] Use dispatch_after for delayed destroy of channel --- .../GRPCClient/private/GRPCChannel.m | 93 ++++++++++--------- 1 file changed, 50 insertions(+), 43 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index a17cc253feb..a91949684c4 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -57,14 +57,13 @@ NSTimeInterval kChannelDestroyDelay = 30; @implementation GRPCChannelRef { NSTimeInterval _destroyDelay; - // We use dispatch queue for this purpose since timer invalidation must happen on the same - // thread which issued the timer. - dispatch_queue_t _dispatchQueue; void (^_destroyChannelCallback)(); NSUInteger _refCount; - NSTimer *_timer; BOOL _disconnected; + dispatch_queue_t _dispatchQueue; + dispatch_queue_t _timerQueue; + NSDate *_lastDispatch; } - (instancetype)initWithDestroyDelay:(NSTimeInterval)destroyDelay @@ -74,57 +73,65 @@ NSTimeInterval kChannelDestroyDelay = 30; _destroyChannelCallback = destroyChannelCallback; _refCount = 1; - _timer = nil; _disconnected = NO; + if (@available(iOS 8.0, *)) { + _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + _timerQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_DEFAULT, -1)); + } else { + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + _timerQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT); + } + _lastDispatch = nil; } return self; } -// This function is protected by channel dispatch queue. - (void)refChannel { - if (!_disconnected) { - _refCount++; - [_timer invalidate]; - _timer = nil; - } -} - -// This function is protected by channel dispatch queue. -- (void)unrefChannel { - if (!_disconnected) { - _refCount--; - if (_refCount == 0) { - [_timer invalidate]; - _timer = [NSTimer scheduledTimerWithTimeInterval:_destroyDelay - target:self - selector:@selector(timerFire:) - userInfo:nil - repeats:NO]; + dispatch_async(_dispatchQueue, ^{ + if (!self->_disconnected) { + self->_refCount++; + self->_lastDispatch = nil; } - } + }); +} + +- (void)unrefChannel { + dispatch_async(_dispatchQueue, ^{ + if (!self->_disconnected) { + self->_refCount--; + if (self->_refCount == 0) { + self->_lastDispatch = [NSDate date]; + dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)kChannelDestroyDelay * 1e9); + dispatch_after(delay, self->_timerQueue, ^{ + [self timerFire]; + }); + } + } + }); } -// This function is protected by channel dispatch queue. - (void)disconnect { - if (!_disconnected) { - [_timer invalidate]; - _timer = nil; - _disconnected = YES; - // Break retain loop - _destroyChannelCallback = nil; - } + dispatch_async(_dispatchQueue, ^{ + if (!self->_disconnected) { + self->_lastDispatch = nil; + self->_disconnected = YES; + // Break retain loop + self->_destroyChannelCallback = nil; + } + }); } -// This function is protected by channel dispatch queue. -- (void)timerFire:(NSTimer *)timer { - if (_disconnected || _timer == nil || _timer != timer) { - return; - } - _timer = nil; - _destroyChannelCallback(); - // Break retain loop - _destroyChannelCallback = nil; - _disconnected = YES; +- (void)timerFire { + dispatch_async(_dispatchQueue, ^{ + if (self->_disconnected || self->_lastDispatch == nil || -[self->_lastDispatch timeIntervalSinceNow] < -kChannelDestroyDelay) { + return; + } + self->_lastDispatch = nil; + self->_disconnected = YES; + self->_destroyChannelCallback(); + // Break retain loop + self->_destroyChannelCallback = nil; + }); } @end From 7871fedfd6e594ac5935d2018b9680e18979991c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 11:13:22 -0700 Subject: [PATCH 0075/2143] always unregister observer --- src/objective-c/GRPCClient/GRPCCall.m | 6 +----- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 68f0f8892d7..a142c669db0 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -445,11 +445,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; [_responseWriteable enqueueSuccessfulCompletion]; } - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor unregisterObserver:self]; - } + [GRPCConnectivityMonitor unregisterObserver:self]; // If the call isn't retained anywhere else, it can be deallocated now. _retainSelf = nil; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 4fae7d57ca2..5707e7f9507 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -187,11 +187,7 @@ extern const char *kCFStreamVarName; } - (void)dealloc { - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor unregisterObserver:self]; - } + [GRPCConnectivityMonitor unregisterObserver:self]; } - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration { From 4af17518c023cd32bc98c796d6f99e4f4978f49a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 11:42:41 -0700 Subject: [PATCH 0076/2143] Use simple locking in GRPCChannelPool --- .../GRPCClient/private/GRPCChannelPool.m | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 5707e7f9507..bfc624eb4ea 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -164,18 +164,11 @@ extern const char *kCFStreamVarName; @implementation GRPCChannelPool { NSMutableDictionary *_channelPool; - // Dedicated queue for timer - dispatch_queue_t _dispatchQueue; } - (instancetype)init { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; - if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); - } else { - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - } // Connectivity monitor is not required for CFStream char *enableCFStream = getenv(kCFStreamVarName); @@ -192,37 +185,39 @@ extern const char *kCFStreamVarName; - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration { __block GRPCChannel *channel; - dispatch_sync(_dispatchQueue, ^{ - if ([self->_channelPool objectForKey:configuration]) { - channel = self->_channelPool[configuration]; + @synchronized(self) { + if ([_channelPool objectForKey:configuration]) { + channel = _channelPool[configuration]; [channel unmanagedCallRef]; } else { channel = [GRPCChannel createChannelWithConfiguration:configuration]; - self->_channelPool[configuration] = channel; + if (channel != nil) { + _channelPool[configuration] = channel; + } } - }); + } return channel; } - (void)removeChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { - dispatch_async(_dispatchQueue, ^{ + @synchronized(self) { [self->_channelPool removeObjectForKey:configuration]; - }); + } } - (void)removeAllChannels { - dispatch_sync(_dispatchQueue, ^{ - self->_channelPool = [NSMutableDictionary dictionary]; - }); + @synchronized(self) { + _channelPool = [NSMutableDictionary dictionary]; + } } - (void)removeAndCloseAllChannels { - dispatch_sync(_dispatchQueue, ^{ - [self->_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannel * _Nonnull obj, BOOL * _Nonnull stop) { + @synchronized(self) { + [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannel * _Nonnull obj, BOOL * _Nonnull stop) { [obj disconnect]; }]; - self->_channelPool = [NSMutableDictionary dictionary]; - }); + _channelPool = [NSMutableDictionary dictionary]; + } } - (void)connectivityChange:(NSNotification *)note { From 3bdf794bd031162913f533a2a9535f4066a41abd Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 11:50:00 -0700 Subject: [PATCH 0077/2143] Handle channel nil case --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index a142c669db0..0facf97e09e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -720,7 +720,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{ - NSLocalizedDescriptionKey : @"Failed to create call from channel." + NSLocalizedDescriptionKey : @"Failed to create call or channel." }]]; return; } From a0f83554bbe47d9d99d6e3146a8ec7ba3a129b63 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 12:11:29 -0700 Subject: [PATCH 0078/2143] remove channel from pool with pointer rather than config --- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 4 ++-- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 8 ++++++-- src/objective-c/tests/ChannelTests/ChannelPoolTest.m | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index a91949684c4..2420988f427 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -204,7 +204,7 @@ NSTimeInterval kChannelDestroyDelay = 30; if (self->_unmanagedChannel) { grpc_channel_destroy(self->_unmanagedChannel); self->_unmanagedChannel = nil; - [gChannelPool removeChannelWithConfiguration:self->_configuration]; + [gChannelPool removeChannel:self]; } }); } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index bd1350c15d2..e9c2ef2bd14 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -55,8 +55,8 @@ NS_ASSUME_NONNULL_BEGIN */ - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration; -/** Remove a channel with particular configuration. */ -- (void)removeChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; +/** Remove a channel from the pool. */ +- (void)removeChannel:(GRPCChannel *)channel; /** Clear all channels in the pool. */ - (void)removeAllChannels; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index bfc624eb4ea..b5b3ff60efa 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -199,9 +199,13 @@ extern const char *kCFStreamVarName; return channel; } -- (void)removeChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { +- (void)removeChannel:(GRPCChannel *)channel { @synchronized(self) { - [self->_channelPool removeObjectForKey:configuration]; + [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannel * _Nonnull obj, BOOL * _Nonnull stop) { + if (obj == channel) { + [self->_channelPool removeObjectForKey:key]; + } + }]; } } diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index b195b747a12..db64ac6339e 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -59,7 +59,7 @@ NSString *kDummyHost = @"dummy.host"; GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - [pool removeChannelWithConfiguration:config1]; + [pool removeChannel:channel1]; GRPCChannel *channel2 = [pool channelWithConfiguration:config1]; XCTAssertNotEqual(channel1, channel2); From 1a88be4edfba35732236956e6e835ecd5c9de13d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 13:56:03 -0700 Subject: [PATCH 0079/2143] Prefix functions in ChannelArgsUtil --- src/objective-c/GRPCClient/private/ChannelArgsUtil.h | 4 ++-- src/objective-c/GRPCClient/private/ChannelArgsUtil.m | 4 ++-- .../GRPCClient/private/GRPCInsecureChannelFactory.m | 4 ++-- src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h index d9d6933c6bb..d0be4849105 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h @@ -20,6 +20,6 @@ #include -void FreeChannelArgs(grpc_channel_args* channel_args); +void GRPCFreeChannelArgs(grpc_channel_args* channel_args); -grpc_channel_args* BuildChannelArgs(NSDictionary* dictionary); +grpc_channel_args* GRPCBuildChannelArgs(NSDictionary* dictionary); diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index b26fb12d597..8669f79992c 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -39,7 +39,7 @@ static int cmp_pointer_arg(void *p, void *q) { return p == q; } static const grpc_arg_pointer_vtable objc_arg_vtable = {copy_pointer_arg, destroy_pointer_arg, cmp_pointer_arg}; -void FreeChannelArgs(grpc_channel_args *channel_args) { +void GRPCFreeChannelArgs(grpc_channel_args *channel_args) { for (size_t i = 0; i < channel_args->num_args; ++i) { grpc_arg *arg = &channel_args->args[i]; gpr_free(arg->key); @@ -58,7 +58,7 @@ void FreeChannelArgs(grpc_channel_args *channel_args) { * value responds to @c @selector(intValue). Otherwise, an exception will be raised. The caller of * this function is responsible for calling @c freeChannelArgs on a non-NULL returned value. */ -grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { +grpc_channel_args *GRPCBuildChannelArgs(NSDictionary *dictionary) { if (!dictionary) { return NULL; } diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index d969b887b40..5773f2d9af1 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -36,10 +36,10 @@ NS_ASSUME_NONNULL_BEGIN - (nullable grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(nullable NSDictionary *)args { - grpc_channel_args *coreChannelArgs = BuildChannelArgs([args copy]); + grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); - FreeChannelArgs(coreChannelArgs); + GRPCFreeChannelArgs(coreChannelArgs); return unmanagedChannel; } diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 277823c4e33..8a00d080a11 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -111,10 +111,10 @@ NS_ASSUME_NONNULL_BEGIN - (nullable grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(nullable NSDictionary *)args { - grpc_channel_args *coreChannelArgs = BuildChannelArgs([args copy]); + grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); - FreeChannelArgs(coreChannelArgs); + GRPCFreeChannelArgs(coreChannelArgs); return unmanagedChannel; } From e114983643479d20e44536cb704f5738cb848329 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 13:57:53 -0700 Subject: [PATCH 0080/2143] NULL return for non-id type --- src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 00b388ebbe0..70675784678 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -84,7 +84,7 @@ NS_ASSUME_NONNULL_BEGIN channelArgs:(nullable NSDictionary *)args { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; - return nil; + return NULL; } @end From 31de6d67e7557208b9d1e8c37300fb3f6b45a47d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 14:00:07 -0700 Subject: [PATCH 0081/2143] Make GRPCHost.callOptions immutable --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/private/GRPCHost.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 0facf97e09e..3f77aaafb3a 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -751,7 +751,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; GRPCMutableCallOptions *callOptions; if ([GRPCHost isHostConfigured:_host]) { GRPCHost *hostConfig = [GRPCHost hostWithAddress:_host]; - callOptions = hostConfig.callOptions; + callOptions = [hostConfig.callOptions mutableCopy]; } else { callOptions = [[GRPCMutableCallOptions alloc] init]; } diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h index 32d3585351e..e321363bcbf 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.h +++ b/src/objective-c/GRPCClient/private/GRPCHost.h @@ -66,7 +66,7 @@ struct grpc_channel_credentials; @property(atomic, readwrite) GRPCTransportType transportType; -@property(readonly) GRPCMutableCallOptions *callOptions; +@property(readonly) GRPCCallOptions *callOptions; + (BOOL)isHostConfigured:(NSString *)address; From d92c62fcde8559393aee346e5518faecb6f1301b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 15:22:16 -0700 Subject: [PATCH 0082/2143] Enable Cronet with old API --- src/objective-c/GRPCClient/private/GRPCHost.m | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 7c31b106360..6bb5996a1ba 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -113,7 +113,21 @@ static NSMutableDictionary *kHostCache; options.PEMPrivateKey = _PEMPrivateKey; options.PEMCertChain = _pemCertChain; options.hostNameOverride = _hostNameOverride; - options.transportType = _transportType; +#ifdef GRPC_COMPILE_WITH_CRONET + // By old API logic, insecure channel precedes Cronet channel; Cronet channel preceeds default + // channel. + if ([GRPCCall isUsingCronet]) { + if (_transportType == GRPCTransportTypeInsecure) { + options.transportType = GRPCTransportTypeInsecure; + } else { + NSAssert(_transportType == GRPCTransportTypeDefault, @"Invalid transport type"); + options.transportType = GRPCTransportTypeCronet; + } + } else +#endif + { + options.transportType = _transportType; + } options.logContext = _logContext; return options; From 1084f49c310b62ff5a06fa5f6c262f813dce75a5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 15:22:38 -0700 Subject: [PATCH 0083/2143] rename kHostCache->gHostCache --- src/objective-c/GRPCClient/private/GRPCHost.m | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 6bb5996a1ba..c1992b84e99 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -35,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN -static NSMutableDictionary *kHostCache; +static NSMutableDictionary *gHostCache; @implementation GRPCHost { NSString *_PEMRootCertificates; @@ -65,10 +65,10 @@ static NSMutableDictionary *kHostCache; // Look up the GRPCHost in the cache. static dispatch_once_t cacheInitialization; dispatch_once(&cacheInitialization, ^{ - kHostCache = [NSMutableDictionary dictionary]; + gHostCache = [NSMutableDictionary dictionary]; }); - @synchronized(kHostCache) { - GRPCHost *cachedHost = kHostCache[address]; + @synchronized(gHostCache) { + GRPCHost *cachedHost = gHostCache[address]; if (cachedHost) { return cachedHost; } @@ -76,15 +76,15 @@ static NSMutableDictionary *kHostCache; if ((self = [super init])) { _address = address; _retryEnabled = YES; - kHostCache[address] = self; + gHostCache[address] = self; } } return self; } + (void)resetAllHostSettings { - @synchronized(kHostCache) { - kHostCache = [NSMutableDictionary dictionary]; + @synchronized(gHostCache) { + gHostCache = [NSMutableDictionary dictionary]; } } @@ -140,8 +140,8 @@ static NSMutableDictionary *kHostCache; address = [hostURL.host stringByAppendingString:@":443"]; } __block GRPCHost *cachedHost; - @synchronized (kHostCache) { - cachedHost = kHostCache[address]; + @synchronized (gHostCache) { + cachedHost = gHostCache[address]; } return (cachedHost != nil); } From b9e522420741024e05f8ef3ccde7fbeeaaea2234 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 15:28:15 -0700 Subject: [PATCH 0084/2143] more copy settings --- src/objective-c/GRPCClient/private/GRPCHost.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index c1992b84e99..032b274ffcc 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -92,9 +92,9 @@ static NSMutableDictionary *gHostCache; withPrivateKey:(nullable NSString *)pemPrivateKey withCertChain:(nullable NSString *)pemCertChain error:(NSError **)errorPtr { - _PEMRootCertificates = pemRootCerts; - _PEMPrivateKey = pemPrivateKey; - _pemCertChain = pemCertChain; + _PEMRootCertificates = [pemRootCerts copy]; + _PEMPrivateKey = [pemPrivateKey copy]; + _pemCertChain = [pemCertChain copy]; return YES; } From 4201ad1681064d591f6a47fa5b3c6f824cb7cecb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 16:05:18 -0700 Subject: [PATCH 0085/2143] add callOptionsForHost: to GRPCHost --- src/objective-c/GRPCClient/GRPCCall.m | 8 ++----- src/objective-c/GRPCClient/private/GRPCHost.h | 4 +--- src/objective-c/GRPCClient/private/GRPCHost.m | 22 ++++++++++++------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 3f77aaafb3a..399206a346c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -749,12 +749,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (_callOptions == nil) { GRPCMutableCallOptions *callOptions; - if ([GRPCHost isHostConfigured:_host]) { - GRPCHost *hostConfig = [GRPCHost hostWithAddress:_host]; - callOptions = [hostConfig.callOptions mutableCopy]; - } else { - callOptions = [[GRPCMutableCallOptions alloc] init]; - } + + callOptions = [[GRPCHost callOptionsForHost:_host] mutableCopy]; if (_serverName.length != 0) { callOptions.serverAuthority = _serverName; } diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h index e321363bcbf..f1d57196424 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.h +++ b/src/objective-c/GRPCClient/private/GRPCHost.h @@ -66,9 +66,7 @@ struct grpc_channel_credentials; @property(atomic, readwrite) GRPCTransportType transportType; -@property(readonly) GRPCCallOptions *callOptions; - -+ (BOOL)isHostConfigured:(NSString *)address; ++ (GRPCCallOptions *)callOptionsForHost:(NSString *)host; @end diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 032b274ffcc..5fe022a1bae 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -133,17 +133,23 @@ static NSMutableDictionary *gHostCache; return options; } -+ (BOOL)isHostConfigured:(NSString *)address { ++ (GRPCCallOptions *)callOptionsForHost:(NSString *)host { // TODO (mxyan): Remove when old API is deprecated - NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:address]]; - if (hostURL.host && !hostURL.port) { - address = [hostURL.host stringByAppendingString:@":443"]; + NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:host]]; + if (hostURL.host && hostURL.port == nil) { + host = [hostURL.host stringByAppendingString:@":443"]; } - __block GRPCHost *cachedHost; - @synchronized (gHostCache) { - cachedHost = gHostCache[address]; + + __block GRPCCallOptions *callOptions = nil; + @synchronized(gHostCache) { + if ([gHostCache objectForKey:host]) { + callOptions = [gHostCache[host] callOptions]; + } } - return (cachedHost != nil); + if (callOptions == nil) { + callOptions = [[GRPCCallOptions alloc] init]; + } + return callOptions; } @end From f00be37dd19842e2e2f906b71d0525c2dc913378 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 16:07:09 -0700 Subject: [PATCH 0086/2143] Spell out 'certificates' rather than 'certs' --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 8 ++++---- .../GRPCClient/private/GRPCSecureChannelFactory.h | 8 ++++---- .../GRPCClient/private/GRPCSecureChannelFactory.m | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index b5b3ff60efa..5d53cb2e99f 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -52,10 +52,10 @@ extern const char *kCFStreamVarName; #ifdef GRPC_COMPILE_WITH_CRONET if (![GRPCCall isUsingCronet]) { #endif - factory = [GRPCSecureChannelFactory factoryWithPEMRootCerts:_callOptions.PEMRootCertificates - privateKey:_callOptions.PEMPrivateKey - certChain:_callOptions.PEMCertChain - error:&error]; + factory = [GRPCSecureChannelFactory factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates + privateKey:_callOptions.PEMPrivateKey + certChain:_callOptions.PEMCertChain + error:&error]; if (factory == nil) { NSLog(@"Error creating secure channel factory: %@", error); } diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h index 82af0dc3e68..588239b7064 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -23,10 +23,10 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCSecureChannelFactory : NSObject -+ (nullable instancetype)factoryWithPEMRootCerts:(nullable NSString *)rootCerts - privateKey:(nullable NSString *)privateKey - certChain:(nullable NSString *)certChain - error:(NSError **)errorPtr; ++ (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain + error:(NSError **)errorPtr; - (nullable grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(nullable NSDictionary *)args; diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 8a00d080a11..b116c16ec0f 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -29,10 +29,10 @@ NS_ASSUME_NONNULL_BEGIN grpc_channel_credentials *_channelCreds; } -+ (nullable instancetype)factoryWithPEMRootCerts:(nullable NSString *)rootCerts - privateKey:(nullable NSString *)privateKey - certChain:(nullable NSString *)certChain - error:(NSError **)errorPtr { ++ (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain + error:(NSError **)errorPtr { return [[self alloc] initWithPEMRootCerts:rootCerts privateKey:privateKey certChain:certChain From 6ae2ea643d89f7b2e7839f9016a61361ce92b5d5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 16:32:42 -0700 Subject: [PATCH 0087/2143] obj.class->[obj class] --- .../GRPCClient/private/GRPCRequestHeaders.m | 4 +- .../private/GRPCSecureChannelFactory.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- src/objective-c/tests/InteropTests.m | 62 +++++++++---------- src/objective-c/tests/InteropTestsLocalSSL.m | 4 +- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m index fa4f022ff02..5f117f0607b 100644 --- a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m +++ b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m @@ -36,7 +36,7 @@ static void CheckIsNonNilASCII(NSString *name, NSString *value) { // Precondition: key isn't nil. static void CheckKeyValuePairIsValid(NSString *key, id value) { if ([key hasSuffix:@"-bin"]) { - if (![value isKindOfClass:NSData.class]) { + if (![value isKindOfClass:[NSData class]]) { [NSException raise:NSInvalidArgumentException format: @"Expected NSData value for header %@ ending in \"-bin\", " @@ -44,7 +44,7 @@ static void CheckKeyValuePairIsValid(NSString *key, id value) { key, value]; } } else { - if (![value isKindOfClass:NSString.class]) { + if (![value isKindOfClass:[NSString class]]) { [NSException raise:NSInvalidArgumentException format: @"Expected NSString value for header %@ not ending in \"-bin\", " diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index b116c16ec0f..13bca6c40d6 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -57,7 +57,7 @@ NS_ASSUME_NONNULL_BEGIN 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]; + 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 diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 9fb398408bf..d3005e30a51 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -252,7 +252,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } // A writer that serializes the proto messages to send. GRXWriter *bytesWriter = [requestsWriter map:^id(GPBMessage *proto) { - if (![proto isKindOfClass:GPBMessage.class]) { + if (![proto isKindOfClass:[GPBMessage class]]) { [NSException raise:NSInvalidArgumentException format:@"Request must be a proto message: %@", proto]; } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 11d4b95663a..ca49b5fc390 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -173,11 +173,11 @@ BOOL isRemoteInteropTest(NSString *host) { [GRPCCall resetHostSettings]; - _service = self.class.host ? [RMTTestService serviceWithHost:self.class.host] : nil; + _service = [[self class] host] ? [RMTTestService serviceWithHost:[[self class] host]] : nil; } - (void)testEmptyUnaryRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnary"]; GPBEmpty *request = [GPBEmpty message]; @@ -196,14 +196,14 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testEmptyUnaryRPCWithV2API { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnary"]; GPBEmpty *request = [GPBEmpty message]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = self.class.transportType; - options.PEMRootCertificates = self.class.PEMRootCertificates; - options.hostNameOverride = self.class.hostNameOverride; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; [_service emptyCallWithMessage:request @@ -223,7 +223,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testLargeUnaryRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -247,7 +247,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testPacketCoalescing { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -286,7 +286,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)test4MBResponsesAreAccepted { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"MaxResponseSize"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -304,7 +304,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testResponsesOverMaxSizeFailWithActionableMessage { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -330,7 +330,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testResponsesOver4MBAreAcceptedIfOptedIn { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"HigherResponseSizeLimit"]; @@ -338,7 +338,7 @@ BOOL isRemoteInteropTest(NSString *host) { const size_t kPayloadSize = 5 * 1024 * 1024; // 5MB request.responseSize = kPayloadSize; - [GRPCCall setResponseSizeLimit:6 * 1024 * 1024 forHost:self.class.host]; + [GRPCCall setResponseSizeLimit:6 * 1024 * 1024 forHost:[[self class] host]]; [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { @@ -351,7 +351,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testClientStreamingRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ClientStreaming"]; RMTStreamingInputCallRequest *request1 = [RMTStreamingInputCallRequest message]; @@ -386,7 +386,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testServerStreamingRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ServerStreaming"]; NSArray *expectedSizes = @[ @31415, @9, @2653, @58979 ]; @@ -425,7 +425,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testPingPongRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"]; NSArray *requests = @[ @27182, @8, @1828, @45904 ]; @@ -472,7 +472,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testPingPongRPCWithV2API { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"]; NSArray *requests = @[ @27182, @8, @1828, @45904 ]; @@ -483,9 +483,9 @@ BOOL isRemoteInteropTest(NSString *host) { id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] requestedResponseSize:responses[index]]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = self.class.transportType; - options.PEMRootCertificates = self.class.PEMRootCertificates; - options.hostNameOverride = self.class.hostNameOverride; + options.transportType = [[self class] transportType ]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; __block GRPCStreamingProtoCall *call = [_service fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] @@ -523,7 +523,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testEmptyStreamRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"]; [_service fullDuplexCallWithRequestsWriter:[GRXWriter emptyWriter] eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response, @@ -536,7 +536,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testCancelAfterBeginRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBegin"]; // A buffered pipe to which we never write any value acts as a writer that just hangs. @@ -561,7 +561,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testCancelAfterBeginRPCWithV2API { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBegin"]; // A buffered pipe to which we never write any value acts as a writer that just hangs. @@ -583,7 +583,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testCancelAfterFirstResponseRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterFirstResponse"]; @@ -619,7 +619,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testCancelAfterFirstResponseRPCWithV2API { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *completionExpectation = [self expectationWithDescription:@"Call completed."]; __weak XCTestExpectation *responseExpectation = @@ -630,7 +630,7 @@ BOOL isRemoteInteropTest(NSString *host) { GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = self.class.transportType; options.PEMRootCertificates = self.class.PEMRootCertificates; - options.hostNameOverride = self.class.hostNameOverride; + options.hostNameOverride = [[self class] hostNameOverride]; id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; @@ -656,7 +656,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testRPCAfterClosingOpenConnections { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC after closing connection"]; @@ -688,10 +688,10 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testCompressedUnaryRPC { // This test needs to be disabled for remote test because interop server grpc-test // does not support compression. - if (isRemoteInteropTest(self.class.host)) { + if (isRemoteInteropTest([[self class] host])) { return; } - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -699,7 +699,7 @@ BOOL isRemoteInteropTest(NSString *host) { request.responseSize = 314159; request.payload.body = [NSMutableData dataWithLength:271828]; request.expectCompressed.value = YES; - [GRPCCall setDefaultCompressMethod:GRPCCompressGzip forhost:self.class.host]; + [GRPCCall setDefaultCompressMethod:GRPCCompressGzip forhost:[[self class] host]]; [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { @@ -718,10 +718,10 @@ BOOL isRemoteInteropTest(NSString *host) { #ifndef GRPC_COMPILE_WITH_CRONET - (void)testKeepalive { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Keepalive"]; - [GRPCCall setKeepaliveWithInterval:1500 timeout:0 forHost:self.class.host]; + [GRPCCall setKeepaliveWithInterval:1500 timeout:0 forHost:[[self class] host]]; NSArray *requests = @[ @27182, @8 ]; NSArray *responses = @[ @31415, @9 ]; diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m index 759a080380d..e8222f602f4 100644 --- a/src/objective-c/tests/InteropTestsLocalSSL.m +++ b/src/objective-c/tests/InteropTestsLocalSSL.m @@ -41,7 +41,7 @@ static int32_t kLocalInteropServerOverhead = 10; } + (NSString *)PEMRootCertificates { - NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; NSError *error; @@ -64,7 +64,7 @@ static int32_t kLocalInteropServerOverhead = 10; [super setUp]; // Register test server certificates and name. - NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; [GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:kLocalSSLHost]; From 4264ea2b55f46c1904fc179fb0db7b733b8c3e4b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 18 Oct 2018 17:04:03 -0700 Subject: [PATCH 0088/2143] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 10 +- src/objective-c/GRPCClient/GRPCCall.m | 34 ++++--- src/objective-c/GRPCClient/GRPCCallOptions.m | 26 ++--- .../GRPCClient/private/GRPCChannel.m | 36 ++++--- .../GRPCClient/private/GRPCChannelPool.m | 35 ++++--- src/objective-c/ProtoRPC/ProtoRPC.h | 6 +- src/objective-c/ProtoRPC/ProtoRPC.m | 10 +- src/objective-c/ProtoRPC/ProtoService.h | 15 +-- .../tests/ChannelTests/ChannelPoolTest.m | 35 +++---- src/objective-c/tests/GRPCClientTests.m | 97 +++++++++---------- src/objective-c/tests/InteropTests.m | 2 +- 11 files changed, 160 insertions(+), 146 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 6adecec144a..bd43a0a384b 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -149,7 +149,7 @@ extern id const kGRPCHeadersKey; extern id const kGRPCTrailersKey; /** An object can implement this protocol to receive responses from server from a call. */ -@protocol GRPCResponseHandler +@protocol GRPCResponseHandler @optional @@ -188,10 +188,12 @@ extern id const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** Initialize with all properties. */ -- (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + safety:(GRPCCallSafety)safety NS_DESIGNATED_INITIALIZER; /** The host serving the RPC service. */ @property(copy, readonly) NSString *host; @@ -214,7 +216,7 @@ extern id const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Designated initializer for a call. diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 399206a346c..bd4b4e10f0f 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -28,8 +28,8 @@ #include #import "GRPCCallOptions.h" -#import "private/GRPCHost.h" #import "private/GRPCConnectivityMonitor.h" +#import "private/GRPCHost.h" #import "private/GRPCRequestHeaders.h" #import "private/GRPCWrappedCall.h" #import "private/NSData+GRPC.h" @@ -115,7 +115,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; _initialMetadataPublished = NO; _pipe = [GRXBufferedPipe pipe]; if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); } else { // Fallback on earlier versions _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); @@ -129,7 +131,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler { - return [self initWithRequestOptions:requestOptions responseHandler:responseHandler callOptions:nil]; + return + [self initWithRequestOptions:requestOptions responseHandler:responseHandler callOptions:nil]; } - (void)start { @@ -210,9 +213,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; } }); @@ -255,13 +258,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; } } -- (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata - error:(NSError *)error { +- (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { id handler = _handler; NSDictionary *trailers = _call.responseTrailers; if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:trailers error:error]; + [handler closedWithTrailingMetadata:trailers error:error]; }); } } @@ -388,7 +390,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { if (host.length == 0 || path.length == 0) { - [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil or empty."]; + [NSException raise:NSInvalidArgumentException + format:@"Neither host nor path can be nil or empty."]; } if (safety > GRPCCallSafetyCacheableRequest) { [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; @@ -457,7 +460,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)cancel { - @synchronized (self) { + @synchronized(self) { if (!self.isWaitingForToken) { [self cancelCall]; } else { @@ -720,8 +723,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{ - NSLocalizedDescriptionKey : @"Failed to create call or channel." - }]]; + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; return; } @@ -773,11 +777,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = callOptions; } if (_callOptions.authTokenProvider != nil) { - @synchronized (self) { + @synchronized(self) { self.isWaitingForToken = YES; } [self.tokenProvider getTokenWithHandler:^(NSString *token) { - @synchronized (self) { + @synchronized(self) { if (self.isWaitingForToken) { if (token) { self->_fetchedOauth2AccessToken = [token copy]; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 8d2b84b7484..37ed3ebd1d1 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -110,7 +110,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:kDefaultConnectInitialBackoff connectMaxBackoff:kDefaultConnectMaxBackoff additionalChannelArgs:kDefaultAdditionalChannelArgs - PEMRootCertificates:kDefaultPEMRootCertificates + PEMRootCertificates:kDefaultPEMRootCertificates PEMPrivateKey:kDefaultPEMPrivateKey PEMCertChain:kDefaultPEMCertChain transportType:kDefaultTransportType @@ -135,7 +135,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:(NSTimeInterval)connectInitialBackoff connectMaxBackoff:(NSTimeInterval)connectMaxBackoff additionalChannelArgs:(NSDictionary *)additionalChannelArgs - PEMRootCertificates:(NSString *)PEMRootCertificates + PEMRootCertificates:(NSString *)PEMRootCertificates PEMPrivateKey:(NSString *)PEMPrivateKey PEMCertChain:(NSString *)PEMCertChain transportType:(GRPCTransportType)transportType @@ -158,7 +158,8 @@ static NSUInteger kDefaultChannelID = 0; _connectMinTimeout = connectMinTimeout; _connectInitialBackoff = connectInitialBackoff; _connectMaxBackoff = connectMaxBackoff; - _additionalChannelArgs = [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; + _additionalChannelArgs = + [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; _PEMRootCertificates = [PEMRootCertificates copy]; _PEMPrivateKey = [PEMPrivateKey copy]; _PEMCertChain = [PEMCertChain copy]; @@ -188,7 +189,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:_additionalChannelArgs - PEMRootCertificates:_PEMRootCertificates + PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey PEMCertChain:_PEMCertChain transportType:_transportType @@ -216,7 +217,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - PEMRootCertificates:_PEMRootCertificates + PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey PEMCertChain:_PEMCertChain transportType:_transportType @@ -240,8 +241,7 @@ static NSUInteger kDefaultChannelID = 0; if (!(callOptions.connectInitialBackoff == _connectInitialBackoff)) return NO; if (!(callOptions.connectMaxBackoff == _connectMaxBackoff)) return NO; if (!(callOptions.additionalChannelArgs == _additionalChannelArgs || - [callOptions.additionalChannelArgs - isEqualToDictionary:_additionalChannelArgs])) + [callOptions.additionalChannelArgs isEqualToDictionary:_additionalChannelArgs])) return NO; if (!(callOptions.PEMRootCertificates == _PEMRootCertificates || [callOptions.PEMRootCertificates isEqualToString:_PEMRootCertificates])) @@ -256,8 +256,7 @@ static NSUInteger kDefaultChannelID = 0; [callOptions.hostNameOverride isEqualToString:_hostNameOverride])) return NO; if (!(callOptions.transportType == _transportType)) return NO; - if (!(callOptions.logContext == _logContext || - [callOptions.logContext isEqual:_logContext])) + if (!(callOptions.logContext == _logContext || [callOptions.logContext isEqual:_logContext])) return NO; if (!(callOptions.channelPoolDomain == _channelPoolDomain || [callOptions.channelPoolDomain isEqualToString:_channelPoolDomain])) @@ -335,7 +334,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:kDefaultConnectInitialBackoff connectMaxBackoff:kDefaultConnectMaxBackoff additionalChannelArgs:kDefaultAdditionalChannelArgs - PEMRootCertificates:kDefaultPEMRootCertificates + PEMRootCertificates:kDefaultPEMRootCertificates PEMPrivateKey:kDefaultPEMPrivateKey PEMCertChain:kDefaultPEMCertChain transportType:kDefaultTransportType @@ -362,7 +361,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - PEMRootCertificates:_PEMRootCertificates + PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey PEMCertChain:_PEMCertChain transportType:_transportType @@ -390,7 +389,7 @@ static NSUInteger kDefaultChannelID = 0; connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff additionalChannelArgs:[_additionalChannelArgs copy] - PEMRootCertificates:_PEMRootCertificates + PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey PEMCertChain:_PEMCertChain transportType:_transportType @@ -482,7 +481,8 @@ static NSUInteger kDefaultChannelID = 0; } - (void)setAdditionalChannelArgs:(NSDictionary *)additionalChannelArgs { - _additionalChannelArgs = [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; + _additionalChannelArgs = + [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; } - (void)setPEMRootCertificates:(NSString *)PEMRootCertificates { diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 2420988f427..63bc267a762 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -75,8 +75,12 @@ NSTimeInterval kChannelDestroyDelay = 30; _refCount = 1; _disconnected = NO; if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); - _timerQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_DEFAULT, -1)); + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + _timerQueue = + dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class( + DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_DEFAULT, -1)); } else { _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); _timerQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT); @@ -101,7 +105,8 @@ NSTimeInterval kChannelDestroyDelay = 30; self->_refCount--; if (self->_refCount == 0) { self->_lastDispatch = [NSDate date]; - dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)kChannelDestroyDelay * 1e9); + dispatch_time_t delay = + dispatch_time(DISPATCH_TIME_NOW, (int64_t)kChannelDestroyDelay * 1e9); dispatch_after(delay, self->_timerQueue, ^{ [self timerFire]; }); @@ -123,7 +128,8 @@ NSTimeInterval kChannelDestroyDelay = 30; - (void)timerFire { dispatch_async(_dispatchQueue, ^{ - if (self->_disconnected || self->_lastDispatch == nil || -[self->_lastDispatch timeIntervalSinceNow] < -kChannelDestroyDelay) { + if (self->_disconnected || self->_lastDispatch == nil || + -[self->_lastDispatch timeIntervalSinceNow] < -kChannelDestroyDelay) { return; } self->_lastDispatch = nil; @@ -158,11 +164,12 @@ NSTimeInterval kChannelDestroyDelay = 30; } grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); gpr_timespec deadline_ms = - timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME) - : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); - call = grpc_channel_create_call( - self->_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, + timeout == 0 + ? gpr_inf_future(GPR_CLOCK_REALTIME) + : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + call = grpc_channel_create_call(self->_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, + queue.unmanagedQueue, path_slice, serverAuthority ? &host_slice : NULL, deadline_ms, NULL); if (serverAuthority) { grpc_slice_unref(host_slice); @@ -214,11 +221,14 @@ NSTimeInterval kChannelDestroyDelay = 30; if ((self = [super init])) { _unmanagedChannel = unmanagedChannel; _configuration = configuration; - _channelRef = [[GRPCChannelRef alloc] initWithDestroyDelay:kChannelDestroyDelay destroyChannelCallback:^{ - [self destroyChannel]; - }]; + _channelRef = [[GRPCChannelRef alloc] initWithDestroyDelay:kChannelDestroyDelay + destroyChannelCallback:^{ + [self destroyChannel]; + }]; if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); } else { _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 5d53cb2e99f..6659d193c68 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -52,10 +52,11 @@ extern const char *kCFStreamVarName; #ifdef GRPC_COMPILE_WITH_CRONET if (![GRPCCall isUsingCronet]) { #endif - factory = [GRPCSecureChannelFactory factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates - privateKey:_callOptions.PEMPrivateKey - certChain:_callOptions.PEMCertChain - error:&error]; + factory = [GRPCSecureChannelFactory + factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates + privateKey:_callOptions.PEMPrivateKey + certChain:_callOptions.PEMCertChain + error:&error]; if (factory == nil) { NSLog(@"Error creating secure channel factory: %@", error); } @@ -136,7 +137,8 @@ extern const char *kCFStreamVarName; } - (nonnull id)copyWithZone:(nullable NSZone *)zone { - GRPCChannelConfiguration *newConfig = [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; + GRPCChannelConfiguration *newConfig = + [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; return newConfig; } @@ -145,7 +147,8 @@ extern const char *kCFStreamVarName; NSAssert([object isKindOfClass:[GRPCChannelConfiguration class]], @"Illegal :isEqual"); GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; if (!(obj.host == _host || [obj.host isEqualToString:_host])) return NO; - if (!(obj.callOptions == _callOptions || [obj.callOptions isChannelOptionsEqualTo:_callOptions])) return NO; + if (!(obj.callOptions == _callOptions || [obj.callOptions isChannelOptionsEqualTo:_callOptions])) + return NO; return YES; } @@ -201,11 +204,13 @@ extern const char *kCFStreamVarName; - (void)removeChannel:(GRPCChannel *)channel { @synchronized(self) { - [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannel * _Nonnull obj, BOOL * _Nonnull stop) { - if (obj == channel) { - [self->_channelPool removeObjectForKey:key]; - } - }]; + [_channelPool + enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, + GRPCChannel *_Nonnull obj, BOOL *_Nonnull stop) { + if (obj == channel) { + [self->_channelPool removeObjectForKey:key]; + } + }]; } } @@ -217,9 +222,11 @@ extern const char *kCFStreamVarName; - (void)removeAndCloseAllChannels { @synchronized(self) { - [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannel * _Nonnull obj, BOOL * _Nonnull stop) { - [obj disconnect]; - }]; + [_channelPool + enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, + GRPCChannel *_Nonnull obj, BOOL *_Nonnull stop) { + [obj disconnect]; + }]; _channelPool = [NSMutableDictionary dictionary]; } } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index db1e8c6deb3..f2ba5134952 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -24,7 +24,7 @@ @class GPBMessage; /** An object can implement this protocol to receive responses from server from a call. */ -@protocol GRPCProtoResponseHandler +@protocol GRPCProtoResponseHandler @optional @@ -59,7 +59,7 @@ - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Users should not use this initializer directly. Call objects will be created, initialized, and @@ -81,7 +81,7 @@ - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Users should not use this initializer directly. Call objects will be created, initialized, and diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index d3005e30a51..238faa33437 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -88,7 +88,9 @@ _callOptions = [callOptions copy]; _responseClass = responseClass; if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); } else { _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } @@ -120,9 +122,9 @@ error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; }); } _handler = nil; diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index 2985c5cb2dc..3a16ab24026 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -30,14 +30,15 @@ __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoService : NSObject -- (instancetype)init NS_UNAVAILABLE; - -+ (instancetype)new NS_UNAVAILABLE; - - - (instancetype)initWithHost : (NSString *)host packageName - : (NSString *)packageName serviceName : (NSString *)serviceName callOptions - : (GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; + (instancetype)init NS_UNAVAILABLE; + ++ (instancetype) new NS_UNAVAILABLE; + +- (instancetype)initWithHost:(NSString *)host + packageName:(NSString *)packageName + serviceName:(NSString *)serviceName + callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index db64ac6339e..f4a9fb4a2c4 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -57,11 +57,9 @@ NSString *kDummyHost = @"dummy.host"; GRPCChannelConfiguration *config1 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - GRPCChannel *channel1 = - [pool channelWithConfiguration:config1]; + GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; [pool removeChannel:channel1]; - GRPCChannel *channel2 = - [pool channelWithConfiguration:config1]; + GRPCChannel *channel2 = [pool channelWithConfiguration:config1]; XCTAssertNotEqual(channel1, channel2); } @@ -74,18 +72,14 @@ extern NSTimeInterval kChannelDestroyDelay; options1.transportType = GRPCTransportTypeInsecure; GRPCChannelConfiguration *config1 = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelPool *pool = - [[GRPCChannelPool alloc] init]; - GRPCChannel *channel1 = - [pool channelWithConfiguration:config1]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; [channel1 unmanagedCallUnref]; sleep(1); - GRPCChannel *channel2 = - [pool channelWithConfiguration:config1]; + GRPCChannel *channel2 = [pool channelWithConfiguration:config1]; XCTAssertEqual(channel1, channel2); sleep((int)kChannelDestroyDelay + 2); - GRPCChannel *channel3 = - [pool channelWithConfiguration:config1]; + GRPCChannel *channel3 = [pool channelWithConfiguration:config1]; XCTAssertEqual(channel1, channel3); kChannelDestroyDelay = kOriginalInterval; } @@ -96,12 +90,11 @@ extern NSTimeInterval kChannelDestroyDelay; options1.transportType = GRPCTransportTypeInsecure; GRPCCallOptions *options2 = [options1 copy]; GRPCChannelConfiguration *config1 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelConfiguration *config2 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; [pool removeAndCloseAllChannels]; GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; @@ -119,17 +112,13 @@ extern NSTimeInterval kChannelDestroyDelay; [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - GRPCChannel *channel1 = - [pool channelWithConfiguration:config1]; - GRPCChannel *channel2 = - [pool channelWithConfiguration:config2]; + GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; + GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; XCTAssertNotEqual(channel1, channel2); [pool removeAndCloseAllChannels]; - GRPCChannel *channel3 = - [pool channelWithConfiguration:config1]; - GRPCChannel *channel4 = - [pool channelWithConfiguration:config2]; + GRPCChannel *channel3 = [pool channelWithConfiguration:config1]; + GRPCChannel *channel4 = [pool channelWithConfiguration:config2]; XCTAssertNotEqual(channel1, channel3); XCTAssertNotEqual(channel2, channel4); } diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index f961b6a86fd..387fcab7e9f 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -446,42 +446,40 @@ static GRPCProtoMethod *kFullDuplexCallMethod; options.initialMetadata = headers; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:request - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( NSDictionary *initialMetadata) { - NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; - // Test the regex is correct - NSString *expectedUserAgent = @"Foo grpc-objc/"; - expectedUserAgent = - [expectedUserAgent stringByAppendingString:GRPC_OBJC_VERSION_STRING]; - expectedUserAgent = [expectedUserAgent stringByAppendingString:@" grpc-c/"]; - expectedUserAgent = - [expectedUserAgent stringByAppendingString:GRPC_C_VERSION_STRING]; - expectedUserAgent = - [expectedUserAgent stringByAppendingString:@" (ios; chttp2; "]; - expectedUserAgent = [expectedUserAgent - stringByAppendingString:[NSString - stringWithUTF8String:grpc_g_stands_for()]]; - expectedUserAgent = [expectedUserAgent stringByAppendingString:@")"]; - XCTAssertEqualObjects(userAgent, expectedUserAgent); + NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; + // Test the regex is correct + NSString *expectedUserAgent = @"Foo grpc-objc/"; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:GRPC_OBJC_VERSION_STRING]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@" grpc-c/"]; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:GRPC_C_VERSION_STRING]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@" (ios; chttp2; "]; + expectedUserAgent = [expectedUserAgent + stringByAppendingString:[NSString stringWithUTF8String:grpc_g_stands_for()]]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@")"]; + XCTAssertEqualObjects(userAgent, expectedUserAgent); - NSError *error = nil; - // Change in format of user-agent field in a direction that does not match - // the regex will likely cause problem for certain gRPC users. For details, - // refer to internal doc https://goo.gl/c2diBc - NSRegularExpression *regex = [NSRegularExpression - regularExpressionWithPattern: - @" grpc-[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?/[^ ,]+( \\([^)]*\\))?" - options:0 - error:&error]; + NSError *error = nil; + // Change in format of user-agent field in a direction that does not match + // the regex will likely cause problem for certain gRPC users. For details, + // refer to internal doc https://goo.gl/c2diBc + NSRegularExpression *regex = [NSRegularExpression + regularExpressionWithPattern: + @" grpc-[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?/[^ ,]+( \\([^)]*\\))?" + options:0 + error:&error]; - NSString *customUserAgent = [regex - stringByReplacingMatchesInString:userAgent - options:0 - range:NSMakeRange(0, [userAgent length]) - withTemplate:@""]; - XCTAssertEqualObjects(customUserAgent, @"Foo"); - [recvInitialMd fulfill]; - } + NSString *customUserAgent = + [regex stringByReplacingMatchesInString:userAgent + options:0 + range:NSMakeRange(0, [userAgent length]) + withTemplate:@""]; + XCTAssertEqualObjects(customUserAgent, @"Foo"); + [recvInitialMd fulfill]; + } messageCallback:^(id message) { XCTAssertNotNil(message); XCTAssertEqual([message length], 0, @@ -609,7 +607,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; options.transportType = GRPCTransportTypeInsecure; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(id message) { NSData *data = (NSData *)message; XCTAssertNotNil(data, @"nil value received as response."); @@ -739,19 +737,18 @@ static GRPCProtoMethod *kFullDuplexCallMethod; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:requestOptions - responseHandler: - [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id data) { - XCTFail( - @"Failure: response received; Expect: no response received."); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNotNil(error, - @"Failure: no error received; Expect: receive " - @"deadline exceeded."); - XCTAssertEqual(error.code, GRPCErrorCodeDeadlineExceeded); - [completion fulfill]; - }] + responseHandler: + [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id data) { + XCTFail(@"Failure: response received; Expect: no response received."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Failure: no error received; Expect: receive " + @"deadline exceeded."); + XCTAssertEqual(error.code, GRPCErrorCodeDeadlineExceeded); + [completion fulfill]; + }] callOptions:options]; [call start]; @@ -837,7 +834,9 @@ static GRPCProtoMethod *kFullDuplexCallMethod; __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; NSString *const kDummyAddress = [NSString stringWithFormat:@"127.0.0.1:10000"]; GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kDummyAddress path:@"/dummy/path" safety:GRPCCallSafetyDefault]; + [[GRPCRequestOptions alloc] initWithHost:kDummyAddress + path:@"/dummy/path" + safety:GRPCCallSafetyDefault]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.connectMinTimeout = timeout; options.connectInitialBackoff = backoff; @@ -846,7 +845,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; NSDate *startTime = [NSDate date]; GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(id data) { XCTFail(@"Received message. Should not reach here."); } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index ca49b5fc390..1188a75df77 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -483,7 +483,7 @@ BOOL isRemoteInteropTest(NSString *host) { id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] requestedResponseSize:responses[index]]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = [[self class] transportType ]; + options.transportType = [[self class] transportType]; options.PEMRootCertificates = [[self class] PEMRootCertificates]; options.hostNameOverride = [[self class] hostNameOverride]; From 799f8ac60cf6eb1006dbb378ab73ab638cea73fa Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Thu, 18 Oct 2018 17:13:46 -0700 Subject: [PATCH 0089/2143] 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 0090/2143] 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 6d8340847caf0634853818ff4b8745e83c5279d3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:12:18 -0700 Subject: [PATCH 0091/2143] Name changes in compiler --- src/compiler/objective_c_generator.cc | 4 ++-- src/compiler/objective_c_plugin.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc index eb67e9bb88f..0a6b64f5952 100644 --- a/src/compiler/objective_c_generator.cc +++ b/src/compiler/objective_c_generator.cc @@ -127,11 +127,11 @@ void PrintV2Signature(Printer* printer, const MethodDescriptor* method, printer->Print(vars, "- ($return_type$)$method_name$With"); if (method->client_streaming()) { - printer->Print("ResponseHandler:(id)handler"); + printer->Print("ResponseHandler:(id)handler"); } else { printer->Print(vars, "Message:($request_class$ *)message " - "responseHandler:(id)handler"); + "responseHandler:(id)handler"); } printer->Print(" callOptions:(GRPCCallOptions *_Nullable)callOptions"); } diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc index d0ef9ed0d62..87977095d05 100644 --- a/src/compiler/objective_c_plugin.cc +++ b/src/compiler/objective_c_plugin.cc @@ -98,7 +98,7 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { "@class GRPCUnaryProtoCall;\n" "@class GRPCStreamingProtoCall;\n" "@class GRPCCallOptions;\n" - "@protocol GRPCResponseHandler;\n" + "@protocol GRPCProtoResponseHandler;\n" "\n"; ::grpc::string class_declarations = From 82d91964493ceb5893b3874109bc4bbc7d87b821 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:12:59 -0700 Subject: [PATCH 0092/2143] One more obj.class->[obj class] --- .../InteropTestsMultipleChannels/InteropTestsMultipleChannels.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m index 237804d23de..b0d4e4883a3 100644 --- a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m +++ b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m @@ -105,7 +105,7 @@ dispatch_once_t initCronet; // Local stack with SSL _localSSLService = [RMTTestService serviceWithHost:kLocalSSLHost]; - NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; NSError *error = nil; From b9667c6c17590c1f63435ad8dab0554775299003 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:13:27 -0700 Subject: [PATCH 0093/2143] handle NULL case when parsing certificate --- .../private/GRPCSecureChannelFactory.m | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 13bca6c40d6..90482cad219 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -42,6 +42,9 @@ NS_ASSUME_NONNULL_BEGIN - (NSData *)nullTerminatedDataWithString:(NSString *)string { // dataUsingEncoding: does not return a null-terminated string. NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; + if (data == nil) { + return nil; + } NSMutableData *nullTerminated = [NSMutableData dataWithData:data]; [nullTerminated appendBytes:"\0" length:1]; return nullTerminated; @@ -51,7 +54,7 @@ NS_ASSUME_NONNULL_BEGIN privateKey:(nullable NSString *)privateKey certChain:(nullable NSString *)certChain error:(NSError **)errorPtr { - static NSData *kDefaultRootsASCII; + static NSData *defaultRootsASCII; static NSError *kDefaultRootsError; static dispatch_once_t loading; dispatch_once(&loading, ^{ @@ -68,14 +71,14 @@ NS_ASSUME_NONNULL_BEGIN kDefaultRootsError = error; return; } - kDefaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8]; + defaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8]; }); NSData *rootsASCII; if (rootCerts != nil) { rootsASCII = [self nullTerminatedDataWithString:rootCerts]; } else { - if (kDefaultRootsASCII == nil) { + if (defaultRootsASCII == nil) { if (errorPtr) { *errorPtr = kDefaultRootsError; } @@ -88,11 +91,11 @@ NS_ASSUME_NONNULL_BEGIN kDefaultRootsError); return nil; } - rootsASCII = kDefaultRootsASCII; + rootsASCII = defaultRootsASCII; } - grpc_channel_credentials *creds; - if (privateKey == nil && certChain == nil) { + grpc_channel_credentials *creds = NULL; + if (privateKey.length == 0 && certChain.length == 0) { creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL, NULL); } else { grpc_ssl_pem_key_cert_pair key_cert_pair; @@ -100,7 +103,11 @@ NS_ASSUME_NONNULL_BEGIN NSData *certChainASCII = [self nullTerminatedDataWithString:certChain]; key_cert_pair.private_key = privateKeyASCII.bytes; key_cert_pair.cert_chain = certChainASCII.bytes; - creds = grpc_ssl_credentials_create(rootsASCII.bytes, &key_cert_pair, NULL, NULL); + if (key_cert_pair.private_key == NULL || key_cert_pair.cert_chain == NULL) { + creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL, NULL); + } else { + creds = grpc_ssl_credentials_create(rootsASCII.bytes, &key_cert_pair, NULL, NULL); + } } if ((self = [super init])) { From 56d605230f2d8c2ddb5670e8d0f2ede6c2aca4d1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:17:11 -0700 Subject: [PATCH 0094/2143] nil->NULL --- src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 90482cad219..3f2769bf447 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -126,7 +126,7 @@ NS_ASSUME_NONNULL_BEGIN } - (void)dealloc { - if (_channelCreds != nil) { + if (_channelCreds != NULL) { grpc_channel_credentials_release(_channelCreds); } } From 75f8727a3e35ac3db8a3957d9318f2dfdd798e7f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:26:38 -0700 Subject: [PATCH 0095/2143] NSString == nil -> NSString.length == 0 --- src/objective-c/GRPCClient/private/GRPCWrappedCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 1c03bc9efdd..a7c50a17519 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -247,7 +247,7 @@ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path callOptions:(GRPCCallOptions *)callOptions { - if (!path || !host) { + if (host.length == 0 || path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"path and host cannot be nil."]; } From 066949ee56a84189006abeab2e947594787738f6 Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Fri, 19 Oct 2018 09:32:06 -0700 Subject: [PATCH 0096/2143] 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 2a9efc3d1f0ddb42d0797dee5f82ca7abedc0936 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:50:33 -0700 Subject: [PATCH 0097/2143] polish cancel message of proto calls --- src/objective-c/ProtoRPC/ProtoRPC.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index f2ba5134952..663c1610bcf 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -71,7 +71,11 @@ callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; -/** Cancel the call at best effort. */ +/** + * Cancel the request of this call at best effort. It attempts to notify the server that the RPC + * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code + * CANCELED if no other error code has already been issued. + */ - (void)cancel; @end @@ -92,7 +96,11 @@ callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; -/** Cancel the call at best effort. */ +/** + * Cancel the request of this call at best effort. It attempts to notify the server that the RPC + * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code + * CANCELED if no other error code has already been issued. + */ - (void)cancel; /** From 9925c13b2710a313d489fd040f0d7f312af0f1fc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 09:51:42 -0700 Subject: [PATCH 0098/2143] writeWithMessage->writeMessage --- src/objective-c/ProtoRPC/ProtoRPC.h | 2 +- src/objective-c/ProtoRPC/ProtoRPC.m | 4 ++-- src/objective-c/tests/InteropTests.m | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 663c1610bcf..4121d4f6af2 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -107,7 +107,7 @@ * Send a message to the server. The message should be a Protobuf message which will be serialized * internally. */ -- (void)writeWithMessage:(GPBMessage *)message; +- (void)writeMessage:(GPBMessage *)message; /** * Finish the RPC request and half-close the call. The server may still send messages and/or diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 238faa33437..b04b6aca67b 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -41,7 +41,7 @@ responseHandler:handler callOptions:callOptions responseClass:responseClass]; - [_call writeWithMessage:message]; + [_call writeMessage:message]; [_call finish]; } return self; @@ -132,7 +132,7 @@ }); } -- (void)writeWithMessage:(GPBMessage *)message { +- (void)writeMessage:(GPBMessage *)message { if (![message isKindOfClass:[GPBMessage class]]) { [NSException raise:NSInvalidArgumentException format:@"Data must be a valid protobuf type."]; } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 1188a75df77..d38e1e0d972 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -501,7 +501,7 @@ BOOL isRemoteInteropTest(NSString *host) { id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] requestedResponseSize:responses[index]]; - [call writeWithMessage:request]; + [call writeMessage:request]; } else { [call finish]; } @@ -517,7 +517,7 @@ BOOL isRemoteInteropTest(NSString *host) { [expectation fulfill]; }] callOptions:options]; - [call writeWithMessage:request]; + [call writeMessage:request]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } @@ -651,7 +651,7 @@ BOOL isRemoteInteropTest(NSString *host) { }] callOptions:options]; - [call writeWithMessage:request]; + [call writeMessage:request]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } From 2d903f4732ee21c5c319c88aa738671b56b2e729 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 10:15:02 -0700 Subject: [PATCH 0099/2143] More specific typing in response handlers --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/ProtoRPC/ProtoRPC.h | 2 +- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- src/objective-c/tests/GRPCClientTests.m | 2 +- src/objective-c/tests/InteropTests.m | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index bd43a0a384b..d8d3e3cf629 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -160,7 +160,7 @@ extern id const kGRPCTrailersKey; * Issued when a message is received from the server. The message is the raw data received from the * server, with decompression and without proto deserialization. */ -- (void)receivedRawMessage:(id)message; +- (void)receivedRawMessage:(NSData *)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 4121d4f6af2..34a519bee5d 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -34,7 +34,7 @@ /** * Issued when a message is received from the server. The message is the deserialized proto object. */ -- (void)receivedProtoMessage:(id)message; +- (void)receivedProtoMessage:(GPBMessage *)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index b04b6aca67b..44e9bfde0ab 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -168,7 +168,7 @@ if (_handler) { id handler = _handler; NSError *error = nil; - id parsed = [_responseClass parseFromData:message error:&error]; + GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; if (parsed) { if ([handler respondsToSelector:@selector(receivedProtoMessage:)]) { dispatch_async(handler.dispatchQueue, ^{ diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 387fcab7e9f..985e105b816 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -120,7 +120,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; } } -- (void)receivedProtoMessage:(id)message { +- (void)receivedProtoMessage:(GPBMessage *)message { if (_messageCallback) { _messageCallback(message); } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index d38e1e0d972..a9f33aab6f1 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -108,7 +108,7 @@ BOOL isRemoteInteropTest(NSString *host) { } } -- (void)receivedProtoMessage:(id)message { +- (void)receivedProtoMessage:(GPBMessage *)message { if (_messageCallback) { _messageCallback(message); } From a6e35201b5a00949379fd04fb784f6b90d06a88a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 11:07:00 -0700 Subject: [PATCH 0100/2143] polish comments --- src/objective-c/GRPCClient/GRPCCallOptions.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 8864bcb8a2f..6e16cd56a93 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -26,8 +26,10 @@ typedef NS_ENUM(NSUInteger, GRPCCallSafety) { GRPCCallSafetyDefault = 0, /** Signal that the call is idempotent. gRPC is free to use PUT verb. */ GRPCCallSafetyIdempotentRequest = 1, - /** Signal that the call is cacheable and will not affect server state. gRPC is free to use GET - verb. */ + /** + * Signal that the call is cacheable and will not affect server state. gRPC is free to use GET + * verb. + */ GRPCCallSafetyCacheableRequest = 2, }; @@ -39,14 +41,14 @@ typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) { GRPCStreamCompressGzip, }; -// The transport to be used by a gRPC call +/** The transport to be used by a gRPC call */ typedef NS_ENUM(NSInteger, GRPCTransportType) { GRPCTransportTypeDefault = 0, - // gRPC internal HTTP/2 stack with BoringSSL + /** gRPC internal HTTP/2 stack with BoringSSL */ GRPCTransportTypeChttp2BoringSSL = 0, - // Cronet stack + /** Cronet stack */ GRPCTransportTypeCronet, - // Insecure channel. FOR TEST ONLY! + /** Insecure channel. FOR TEST ONLY! */ GRPCTransportTypeInsecure, }; From 590ab392520c0216690bc2626e2c9b55e95fc0fa Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 11:24:04 -0700 Subject: [PATCH 0101/2143] GRPCCompressAlgorithm->GRPCCompressionAlgorithm --- src/objective-c/GRPCClient/GRPCCallOptions.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 6e16cd56a93..b8bbb8a22d3 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -33,14 +33,19 @@ typedef NS_ENUM(NSUInteger, GRPCCallSafety) { GRPCCallSafetyCacheableRequest = 2, }; + + // Compression algorithm to be used by a gRPC call -typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) { +typedef NS_ENUM(NSInteger, GRPCCompressionAlgorithm) { GRPCCompressNone = 0, GRPCCompressDeflate, GRPCCompressGzip, GRPCStreamCompressGzip, }; +// GRPCCompressAlgorithm is deprecated; use GRPCCompressionAlgorithm +typedef GRPCCompressionAlgorithm GRPCCompressAlgorithm; + /** The transport to be used by a gRPC call */ typedef NS_ENUM(NSInteger, GRPCTransportType) { GRPCTransportTypeDefault = 0, From cc9157a248e20a2f24972241ae1f2d41ea171a8b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 11:45:59 -0700 Subject: [PATCH 0102/2143] Polish comments --- src/objective-c/GRPCClient/GRPCCallOptions.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index b8bbb8a22d3..9a8362cbcca 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -67,7 +67,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The authority for the RPC. If nil, the default authority will be used. * - * Note: This property must be nil when Cronet transport is enabled. + * Note: This property does not have effect on Cronet transport and will be ignored. * Note: This property cannot be used to validate a self-signed server certificate. It control the * :authority header field of the call and performs an extra check that server's certificate * matches the :authority header. @@ -85,8 +85,8 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The OAuth2 access token string. The string is prefixed with "Bearer " then used as value of the - * request's "authorization" header field. This parameter should not be used simultaneously with - * \a authTokenProvider. + * request's "authorization" header field. This parameter takes precedence over \a + * oauth2AccessToken. */ @property(copy, readonly) NSString *oauth2AccessToken; @@ -213,7 +213,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The authority for the RPC. If nil, the default authority will be used. * - * Note: This property must be nil when Cronet transport is enabled. + * Note: This property does not have effect on Cronet transport and will be ignored. * Note: This property cannot be used to validate a self-signed server certificate. It control the * :authority header field of the call and performs an extra check that server's certificate * matches the :authority header. @@ -239,7 +239,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when - * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. + * initiating the call. This parameter takes precedence over \a oauth2AccessToken. */ @property(readwrite) id authTokenProvider; From 9f9141082bcd4167488780f93eeec8d40c17e007 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 11:57:18 -0700 Subject: [PATCH 0103/2143] compressAlgorithm->compressionAlgorithm --- src/objective-c/GRPCClient/GRPCCallOptions.h | 4 +-- src/objective-c/GRPCClient/GRPCCallOptions.m | 32 +++++++++---------- .../GRPCClient/private/GRPCChannelPool.m | 4 +-- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 9a8362cbcca..484f15fde6e 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -119,7 +119,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * The compression algorithm to be used by the gRPC call. For more details refer to * https://github.com/grpc/grpc/blob/master/doc/compression.md */ -@property(readonly) GRPCCompressAlgorithm compressAlgorithm; +@property(readonly) GRPCCompressionAlgorithm compressionAlgorithm; /** * Enable/Disable gRPC call's retry feature. The default is enabled. For details of this feature @@ -266,7 +266,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * The compression algorithm to be used by the gRPC call. For more details refer to * https://github.com/grpc/grpc/blob/master/doc/compression.md */ -@property(readwrite) GRPCCompressAlgorithm compressAlgorithm; +@property(readwrite) GRPCCompressionAlgorithm compressionAlgorithm; /** * Enable/Disable gRPC call's retry feature. The default is enabled. For details of this feature diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 37ed3ebd1d1..3dc21b72873 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -24,7 +24,7 @@ static const NSTimeInterval kDefaultTimeout = 0; static NSDictionary *const kDefaultInitialMetadata = nil; static NSString *const kDefaultUserAgentPrefix = nil; static const NSUInteger kDefaultResponseSizeLimit = 0; -static const GRPCCompressAlgorithm kDefaultCompressAlgorithm = GRPCCompressNone; +static const GRPCCompressionAlgorithm kDefaultCompressionAlgorithm = GRPCCompressNone; static const BOOL kDefaultEnableRetry = YES; static const NSTimeInterval kDefaultKeepaliveInterval = 0; static const NSTimeInterval kDefaultKeepaliveTimeout = 0; @@ -52,7 +52,7 @@ static NSUInteger kDefaultChannelID = 0; NSDictionary *_initialMetadata; NSString *_userAgentPrefix; NSUInteger _responseSizeLimit; - GRPCCompressAlgorithm _compressAlgorithm; + GRPCCompressionAlgorithm _compressionAlgorithm; BOOL _enableRetry; NSTimeInterval _keepaliveInterval; NSTimeInterval _keepaliveTimeout; @@ -77,7 +77,7 @@ static NSUInteger kDefaultChannelID = 0; @synthesize initialMetadata = _initialMetadata; @synthesize userAgentPrefix = _userAgentPrefix; @synthesize responseSizeLimit = _responseSizeLimit; -@synthesize compressAlgorithm = _compressAlgorithm; +@synthesize compressionAlgorithm = _compressionAlgorithm; @synthesize enableRetry = _enableRetry; @synthesize keepaliveInterval = _keepaliveInterval; @synthesize keepaliveTimeout = _keepaliveTimeout; @@ -102,7 +102,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:kDefaultInitialMetadata userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit - compressAlgorithm:kDefaultCompressAlgorithm + compressionAlgorithm:kDefaultCompressionAlgorithm enableRetry:kDefaultEnableRetry keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout @@ -127,7 +127,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:(NSDictionary *)initialMetadata userAgentPrefix:(NSString *)userAgentPrefix responseSizeLimit:(NSUInteger)responseSizeLimit - compressAlgorithm:(GRPCCompressAlgorithm)compressAlgorithm + compressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm enableRetry:(BOOL)enableRetry keepaliveInterval:(NSTimeInterval)keepaliveInterval keepaliveTimeout:(NSTimeInterval)keepaliveTimeout @@ -151,7 +151,7 @@ static NSUInteger kDefaultChannelID = 0; _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; _userAgentPrefix = [userAgentPrefix copy]; _responseSizeLimit = responseSizeLimit; - _compressAlgorithm = compressAlgorithm; + _compressionAlgorithm = compressionAlgorithm; _enableRetry = enableRetry; _keepaliveInterval = keepaliveInterval; _keepaliveTimeout = keepaliveTimeout; @@ -181,7 +181,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressAlgorithm:_compressAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -209,7 +209,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressAlgorithm:_compressAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -233,7 +233,7 @@ static NSUInteger kDefaultChannelID = 0; [callOptions.userAgentPrefix isEqualToString:_userAgentPrefix])) return NO; if (!(callOptions.responseSizeLimit == _responseSizeLimit)) return NO; - if (!(callOptions.compressAlgorithm == _compressAlgorithm)) return NO; + if (!(callOptions.compressionAlgorithm == _compressionAlgorithm)) return NO; if (!(callOptions.enableRetry == _enableRetry)) return NO; if (!(callOptions.keepaliveInterval == _keepaliveInterval)) return NO; if (!(callOptions.keepaliveTimeout == _keepaliveTimeout)) return NO; @@ -270,7 +270,7 @@ static NSUInteger kDefaultChannelID = 0; NSUInteger result = 0; result ^= _userAgentPrefix.hash; result ^= _responseSizeLimit; - result ^= _compressAlgorithm; + result ^= _compressionAlgorithm; result ^= _enableRetry; result ^= (unsigned int)(_keepaliveInterval * 1000); result ^= (unsigned int)(_keepaliveTimeout * 1000); @@ -301,7 +301,7 @@ static NSUInteger kDefaultChannelID = 0; @dynamic initialMetadata; @dynamic userAgentPrefix; @dynamic responseSizeLimit; -@dynamic compressAlgorithm; +@dynamic compressionAlgorithm; @dynamic enableRetry; @dynamic keepaliveInterval; @dynamic keepaliveTimeout; @@ -326,7 +326,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:kDefaultInitialMetadata userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit - compressAlgorithm:kDefaultCompressAlgorithm + compressionAlgorithm:kDefaultCompressionAlgorithm enableRetry:kDefaultEnableRetry keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout @@ -353,7 +353,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressAlgorithm:_compressAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -381,7 +381,7 @@ static NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressAlgorithm:_compressAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -432,8 +432,8 @@ static NSUInteger kDefaultChannelID = 0; _responseSizeLimit = responseSizeLimit; } -- (void)setCompressAlgorithm:(GRPCCompressAlgorithm)compressAlgorithm { - _compressAlgorithm = compressAlgorithm; +- (void)setCompressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm { + _compressionAlgorithm = compressionAlgorithm; } - (void)setEnableRetry:(BOOL)enableRetry { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 6659d193c68..4908b82feac 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -94,9 +94,9 @@ extern const char *kCFStreamVarName; [NSNumber numberWithUnsignedInteger:_callOptions.responseSizeLimit]; } - if (_callOptions.compressAlgorithm != GRPC_COMPRESS_NONE) { + if (_callOptions.compressionAlgorithm != GRPC_COMPRESS_NONE) { args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = - [NSNumber numberWithInt:_callOptions.compressAlgorithm]; + [NSNumber numberWithInt:_callOptions.compressionAlgorithm]; } if (_callOptions.keepaliveInterval != 0) { diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 5fe022a1bae..41d3bec4efa 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -102,7 +102,7 @@ static NSMutableDictionary *gHostCache; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.userAgentPrefix = _userAgentPrefix; options.responseSizeLimit = _responseSizeLimitOverride; - options.compressAlgorithm = (GRPCCompressAlgorithm)_compressAlgorithm; + options.compressionAlgorithm = (GRPCCompressionAlgorithm)_compressAlgorithm; options.enableRetry = _retryEnabled; options.keepaliveInterval = (NSTimeInterval)_keepaliveInterval / 1000; options.keepaliveTimeout = (NSTimeInterval)_keepaliveTimeout / 1000; From 5eb9911a0eb13590fe558875df3512d6def20d3c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 13:55:31 -0700 Subject: [PATCH 0104/2143] Change extern type --- src/objective-c/GRPCClient/GRPCCall.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index d8d3e3cf629..7ce5a2faf2c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -145,8 +145,8 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { * Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by * the server. */ -extern id const kGRPCHeadersKey; -extern id const kGRPCTrailersKey; +extern NSString * const kGRPCHeadersKey; +extern NSString * const kGRPCTrailersKey; /** An object can implement this protocol to receive responses from server from a call. */ @protocol GRPCResponseHandler From 0242b022ccc804e498b2e631fd0e6c8478ac97c4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 14:28:25 -0700 Subject: [PATCH 0105/2143] Typo fix --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 7ce5a2faf2c..b8fccc37dc8 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -221,7 +221,7 @@ extern NSString * const kGRPCTrailersKey; /** * Designated initializer for a call. * \param requestOptions Protobuf generated parameters for the call. - * \param responseHandler The object to which responses should be issed. + * \param responseHandler The object to which responses should be issued. * \param callOptions Options for the call. */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions From e542e006eb4ffcd0c19488428a3cfe5605bf41e5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 14:29:08 -0700 Subject: [PATCH 0106/2143] Format fix --- src/objective-c/GRPCClient/GRPCCall.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index b8fccc37dc8..9fdcd93a30c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -254,7 +254,8 @@ extern NSString * const kGRPCTrailersKey; /** * Finish the RPC request and half-close the call. The server may still send messages and/or * trailers to the client. - */ -(void)finish; + */ +- (void)finish; /** * Get a copy of the original call options. From 422d3296b2d4fb3f8aa0991c2ffa895251ad8e91 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 15:42:39 -0700 Subject: [PATCH 0107/2143] Annotate Nullability --- src/objective-c/GRPCClient/GRPCCall.h | 12 ++++++++---- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.h | 14 +++++++++----- src/objective-c/ProtoRPC/ProtoRPC.m | 14 +++++++------- src/objective-c/tests/GRPCClientTests.m | 6 +++--- src/objective-c/tests/InteropTests.m | 6 +++--- 6 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 9fdcd93a30c..c862609b21c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -39,6 +39,8 @@ #include "GRPCCallOptions.h" +NS_ASSUME_NONNULL_BEGIN + #pragma mark gRPC errors /** Domain of NSError objects produced by gRPC. */ @@ -154,13 +156,13 @@ extern NSString * const kGRPCTrailersKey; @optional /** Issued when initial metadata is received from the server. */ -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata; +- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata; /** * Issued when a message is received from the server. The message is the raw data received from the * server, with decompression and without proto deserialization. */ -- (void)receivedRawMessage:(NSData *)message; +- (void)receivedRawMessage:(NSData * _Nullable)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -168,7 +170,7 @@ extern NSString * const kGRPCTrailersKey; * is non-nil and contains the corresponding error information, including gRPC error codes and * error descriptions. */ -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error; +- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error; @required @@ -226,7 +228,7 @@ extern NSString * const kGRPCTrailersKey; */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler - callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; + callOptions:(GRPCCallOptions * _Nullable)callOptions NS_DESIGNATED_INITIALIZER; /** * Convenience initializer for a call that uses default call options (see GRPCCallOptions.m for * the default options). @@ -267,6 +269,8 @@ extern NSString * const kGRPCTrailersKey; @end +NS_ASSUME_NONNULL_END + /** * This interface is deprecated. Please use \a GRPCcall2. * diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index bd4b4e10f0f..1782078961d 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -97,7 +97,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler - callOptions:(GRPCCallOptions *)callOptions { + callOptions:(GRPCCallOptions * _Nullable)callOptions { if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 34a519bee5d..3a7fd58fb16 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -21,6 +21,8 @@ #import "ProtoMethod.h" +NS_ASSUME_NONNULL_BEGIN + @class GPBMessage; /** An object can implement this protocol to receive responses from server from a call. */ @@ -29,12 +31,12 @@ @optional /** Issued when initial metadata is received from the server. */ -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata; +- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata; /** * Issued when a message is received from the server. The message is the deserialized proto object. */ -- (void)receivedProtoMessage:(GPBMessage *)message; +- (void)receivedProtoMessage:(GPBMessage * _Nullable)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -42,7 +44,7 @@ * is non-nil and contains the corresponding error information, including gRPC error codes and * error descriptions. */ -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error; +- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error; @required @@ -68,7 +70,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message responseHandler:(id)handler - callOptions:(GRPCCallOptions *)callOptions + callOptions:(GRPCCallOptions * _Nullable)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** @@ -93,7 +95,7 @@ */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler - callOptions:(GRPCCallOptions *)callOptions + callOptions:(GRPCCallOptions * _Nullable)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** @@ -117,6 +119,8 @@ @end +NS_ASSUME_NONNULL_END + __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC : GRPCCall diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 44e9bfde0ab..f6e3298f623 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -34,7 +34,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message responseHandler:(id)handler - callOptions:(GRPCCallOptions *)callOptions + callOptions:(GRPCCallOptions * _Nullable)callOptions responseClass:(Class)responseClass { if ((self = [super init])) { _call = [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions @@ -70,7 +70,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler - callOptions:(GRPCCallOptions *)callOptions + callOptions:(GRPCCallOptions * _Nullable)callOptions responseClass:(Class)responseClass { if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; @@ -153,8 +153,8 @@ }); } -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { - if (_handler) { +- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata { + if (_handler && initialMetadata != nil) { id handler = _handler; if ([handler respondsToSelector:@selector(initialMetadata:)]) { dispatch_async(handler.dispatchQueue, ^{ @@ -164,8 +164,8 @@ } } -- (void)receivedRawMessage:(NSData *)message { - if (_handler) { +- (void)receivedRawMessage:(NSData * _Nullable)message { + if (_handler && message != nil) { id handler = _handler; NSError *error = nil; GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; @@ -188,7 +188,7 @@ } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { +- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error { if (_handler) { id handler = _handler; if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 985e105b816..0a9ec97c488 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -114,19 +114,19 @@ static GRPCProtoMethod *kFullDuplexCallMethod; return self; } -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata { if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); } } -- (void)receivedProtoMessage:(GPBMessage *)message { +- (void)receivedProtoMessage:(GPBMessage * _Nullable)message { if (_messageCallback) { _messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { +- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error { if (_closeCallback) { _closeCallback(trailingMetadata, error); } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index a9f33aab6f1..fb49bb99e0a 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -102,19 +102,19 @@ BOOL isRemoteInteropTest(NSString *host) { return self; } -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata { if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); } } -- (void)receivedProtoMessage:(GPBMessage *)message { +- (void)receivedProtoMessage:(GPBMessage * _Nullable)message { if (_messageCallback) { _messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { +- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error { if (_closeCallback) { _closeCallback(trailingMetadata, error); } From 24d952b2b916030aa02f33afb7746b2582ca88e4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 15:43:46 -0700 Subject: [PATCH 0108/2143] Add comments to ivars of GRPCCall2 --- src/objective-c/GRPCClient/GRPCCall.m | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 1782078961d..74b284d924c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -85,13 +85,24 @@ const char *kCFStreamVarName = "grpc_cfstream"; @end @implementation GRPCCall2 { + /** Options for the call. */ GRPCCallOptions *_callOptions; + /** The handler of responses. */ id _handler; + // Thread safety of ivars below are protected by _dispatcheQueue. + + /** + * Make use of legacy GRPCCall to make calls. Nullified when call is finished. + */ GRPCCall *_call; + /** Flags whether initial metadata has been published to response handler. */ BOOL _initialMetadataPublished; + /** Streaming call writeable to the underlying call. */ GRXBufferedPipe *_pipe; + /** Serial dispatch queue for tasks inside the call. */ dispatch_queue_t _dispatchQueue; + /** Flags whether call has started. */ bool _started; } From c6de16fc801b654ff1cbb697c36fafa5c2ff0528 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 15:44:07 -0700 Subject: [PATCH 0109/2143] Remove redundant variable --- src/objective-c/GRPCClient/GRPCCall.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 74b284d924c..daa7e8dd4a1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -579,7 +579,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; callSafetyFlags = GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; break; } - uint32_t callFlag = callSafetyFlags; NSMutableDictionary *headers = _requestHeaders; if (_fetchedOauth2AccessToken != nil) { @@ -592,7 +591,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // TODO(jcanizales): Add error handlers for async failures GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] initWithMetadata:headers - flags:callFlag + flags:callSafetyFlags handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA if (!_unaryCall) { [_wrappedCall startBatchWithOperations:@[ op ]]; From cb745ceaf9f9ffd90447498a6e8a57d5ac600389 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 15:46:57 -0700 Subject: [PATCH 0110/2143] Synchronized access to fetchedOauth2AccessToken --- 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 daa7e8dd4a1..34a0e436eaa 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -581,8 +581,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; } NSMutableDictionary *headers = _requestHeaders; - if (_fetchedOauth2AccessToken != nil) { - headers[@"authorization"] = [kBearerPrefix stringByAppendingString:_fetchedOauth2AccessToken]; + __block NSString *fetchedOauth2AccessToken; + @synchronized(self) { + fetchedOauth2AccessToken = _fetchedOauth2AccessToken; + } + if (fetchedOauth2AccessToken != nil) { + headers[@"authorization"] = [kBearerPrefix stringByAppendingString:fetchedOauth2AccessToken]; } else if (_callOptions.oauth2AccessToken != nil) { headers[@"authorization"] = [kBearerPrefix stringByAppendingString:_callOptions.oauth2AccessToken]; From 789108d16d72c61b6df4135796116d3cffce0a58 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 17:24:23 -0700 Subject: [PATCH 0111/2143] add const attribute to defaults --- src/objective-c/GRPCClient/GRPCCallOptions.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 3dc21b72873..e148664925c 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -40,8 +40,8 @@ static const id kDefaultAuthTokenProvider = nil; static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2BoringSSL; static NSString *const kDefaultHostNameOverride = nil; static const id kDefaultLogContext = nil; -static NSString *kDefaultChannelPoolDomain = nil; -static NSUInteger kDefaultChannelID = 0; +static NSString *const kDefaultChannelPoolDomain = nil; +static const NSUInteger kDefaultChannelID = 0; @implementation GRPCCallOptions { @protected From 8cecb2a86dd5904c68f46d4b685b11c8cb0a8704 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 17:33:50 -0700 Subject: [PATCH 0112/2143] Write comments for functions in ChannelArgsUtil --- src/objective-c/GRPCClient/private/ChannelArgsUtil.h | 9 +++++++++ src/objective-c/GRPCClient/private/ChannelArgsUtil.m | 7 ------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h index d0be4849105..3fb876ecc4a 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h @@ -20,6 +20,15 @@ #include +/** Free resources in the grpc core struct grpc_channel_args */ void GRPCFreeChannelArgs(grpc_channel_args* channel_args); +/** + * Allocates a @c grpc_channel_args and populates it with the options specified in the + * @c dictionary. Keys must be @c NSString, @c NSNumber, or a pointer. If the value responds to + * @c @selector(UTF8String) then it will be mapped to @c GRPC_ARG_STRING. If the value responds to + * @c @selector(intValue), it will be mapped to @c GRPC_ARG_INTEGER. Otherwise, if the value is not + * nil, it is mapped as a pointer. The caller of this function is responsible for calling + * @c GRPCFreeChannelArgs to free the @c grpc_channel_args struct. + */ grpc_channel_args* GRPCBuildChannelArgs(NSDictionary* dictionary); diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index 8669f79992c..b8342a79e79 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -51,13 +51,6 @@ void GRPCFreeChannelArgs(grpc_channel_args *channel_args) { gpr_free(channel_args); } -/** - * Allocates a @c grpc_channel_args and populates it with the options specified in the - * @c dictionary. Keys must be @c NSString. If the value responds to @c @selector(UTF8String) then - * it will be mapped to @c GRPC_ARG_STRING. If not, it will be mapped to @c GRPC_ARG_INTEGER if the - * value responds to @c @selector(intValue). Otherwise, an exception will be raised. The caller of - * this function is responsible for calling @c freeChannelArgs on a non-NULL returned value. - */ grpc_channel_args *GRPCBuildChannelArgs(NSDictionary *dictionary) { if (!dictionary) { return NULL; From b3cb4e17f76624e563e51165954ebaa6224d806c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 17:56:42 -0700 Subject: [PATCH 0113/2143] Comment and rename GRPCChannel:ref and :unref --- src/objective-c/GRPCClient/private/GRPCChannel.h | 14 ++++++++++++-- src/objective-c/GRPCClient/private/GRPCChannel.m | 4 ++-- .../GRPCClient/private/GRPCChannelPool.m | 2 +- .../GRPCClient/private/GRPCWrappedCall.m | 2 +- .../tests/ChannelTests/ChannelPoolTest.m | 2 +- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 7a40638dc33..5f5fae04135 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -51,10 +51,20 @@ struct grpc_channel_credentials; completionQueue:(nonnull GRPCCompletionQueue *)queue callOptions:(nonnull GRPCCallOptions *)callOptions; -- (void)unmanagedCallRef; +/** + * Increase the refcount of the channel. If the channel was timed to be destroyed, cancel the timer. + */ +- (void)ref; -- (void)unmanagedCallUnref; +/** + * Decrease the refcount of the channel. If the refcount of the channel decrease to 0, start a timer + * to destroy the channel + */ +- (void)unref; +/** + * Force the channel to be disconnected and destroyed immediately. + */ - (void)disconnect; // TODO (mxyan): deprecate with GRPCCall:closeOpenConnections diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 63bc267a762..3e4db837658 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -180,7 +180,7 @@ NSTimeInterval kChannelDestroyDelay = 30; return call; } -- (void)unmanagedCallRef { +- (void)ref { dispatch_async(_dispatchQueue, ^{ if (self->_unmanagedChannel) { [self->_channelRef refChannel]; @@ -188,7 +188,7 @@ NSTimeInterval kChannelDestroyDelay = 30; }); } -- (void)unmanagedCallUnref { +- (void)unref { dispatch_async(_dispatchQueue, ^{ if (self->_unmanagedChannel) { [self->_channelRef unrefChannel]; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 4908b82feac..8e0f6976cf9 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -191,7 +191,7 @@ extern const char *kCFStreamVarName; @synchronized(self) { if ([_channelPool objectForKey:configuration]) { channel = _channelPool[configuration]; - [channel unmanagedCallRef]; + [channel ref]; } else { channel = [GRPCChannel createChannelWithConfiguration:configuration]; if (channel != nil) { diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index a7c50a17519..4d5257aca79 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -311,7 +311,7 @@ - (void)dealloc { grpc_call_unref(_call); - [_channel unmanagedCallUnref]; + [_channel unref]; _channel = nil; } diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index f4a9fb4a2c4..5c3f0edba0b 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -74,7 +74,7 @@ extern NSTimeInterval kChannelDestroyDelay; [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - [channel1 unmanagedCallUnref]; + [channel1 unref]; sleep(1); GRPCChannel *channel2 = [pool channelWithConfiguration:config1]; XCTAssertEqual(channel1, channel2); From 17d178363dafe3aa03d348bdbbbd0c3daed9e06e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 17:57:26 -0700 Subject: [PATCH 0114/2143] rename non-const variables --- .../GRPCClient/private/GRPCSecureChannelFactory.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 3f2769bf447..aa8b52e6b8f 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -55,7 +55,7 @@ NS_ASSUME_NONNULL_BEGIN certChain:(nullable NSString *)certChain error:(NSError **)errorPtr { static NSData *defaultRootsASCII; - static NSError *kDefaultRootsError; + static NSError *defaultRootsError; static dispatch_once_t loading; dispatch_once(&loading, ^{ NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem @@ -68,7 +68,7 @@ NS_ASSUME_NONNULL_BEGIN NSString *contentInUTF8 = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; if (contentInUTF8 == nil) { - kDefaultRootsError = error; + defaultRootsError = error; return; } defaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8]; @@ -80,15 +80,15 @@ NS_ASSUME_NONNULL_BEGIN } else { if (defaultRootsASCII == nil) { if (errorPtr) { - *errorPtr = kDefaultRootsError; + *errorPtr = defaultRootsError; } NSAssert( - kDefaultRootsASCII, + defaultRootsASCII, @"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: %@", - kDefaultRootsError); + defaultRootsError); return nil; } rootsASCII = defaultRootsASCII; From 5e3e744d448c8cd1271cae7e8d40d3bdeaff762f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Oct 2018 18:32:05 -0700 Subject: [PATCH 0115/2143] copy configuration --- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 3e4db837658..6bd852fd0d0 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -220,7 +220,7 @@ NSTimeInterval kChannelDestroyDelay = 30; configuration:(GRPCChannelConfiguration *)configuration { if ((self = [super init])) { _unmanagedChannel = unmanagedChannel; - _configuration = configuration; + _configuration = [configuration copy]; _channelRef = [[GRPCChannelRef alloc] initWithDestroyDelay:kChannelDestroyDelay destroyChannelCallback:^{ [self destroyChannel]; From 4186405287a6944e7b1eb59dcae5524ea2db674d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 09:40:22 -0700 Subject: [PATCH 0116/2143] GRPCChannel input parameter sanity check --- src/objective-c/GRPCClient/private/GRPCChannel.m | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 6bd852fd0d0..6b5d1fe0719 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -150,14 +150,17 @@ NSTimeInterval kChannelDestroyDelay = 30; } - (grpc_call *)unmanagedCallWithPath:(NSString *)path - completionQueue:(nonnull GRPCCompletionQueue *)queue + completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions { + NSAssert(path.length, @"path must not be empty."); + NSAssert(queue, @"completionQueue must not be empty."); + NSAssert(callOptions, @"callOptions must not be empty."); __block grpc_call *call = nil; dispatch_sync(_dispatchQueue, ^{ if (self->_unmanagedChannel) { NSString *serverAuthority = callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; - GPR_ASSERT(timeout >= 0); + NSAssert(timeout >= 0, @"Invalid timeout"); grpc_slice host_slice = grpc_empty_slice(); if (serverAuthority) { host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); @@ -216,8 +219,12 @@ NSTimeInterval kChannelDestroyDelay = 30; }); } -- (nullable instancetype)initWithUnmanagedChannel:(nullable grpc_channel *)unmanagedChannel +- (nullable instancetype)initWithUnmanagedChannel:(grpc_channel * _Nullable)unmanagedChannel configuration:(GRPCChannelConfiguration *)configuration { + NSAssert(configuration, @"Configuration must not be empty."); + if (!unmanagedChannel) { + return nil; + } if ((self = [super init])) { _unmanagedChannel = unmanagedChannel; _configuration = [configuration copy]; From 836640dc4a9e8d62fc0e1218e81076a06a3035a9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 09:41:34 -0700 Subject: [PATCH 0117/2143] Mark GRPCChannel:new: unavailable --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/private/GRPCChannel.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index c862609b21c..13dcfa07130 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -218,7 +218,7 @@ extern NSString * const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype) new NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; /** * Designated initializer for a call. diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 5f5fae04135..5fb18e0332e 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -32,6 +32,8 @@ struct grpc_channel_credentials; - (nullable instancetype)init NS_UNAVAILABLE; ++ (nullable instancetype)new NS_UNAVAILABLE; + /** * Returns a channel connecting to \a host with options as \a callOptions. The channel may be new * or a cached channel that is already connected. From c6fc07d384fe11ca4dc59111b61557053ed3dbac Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 09:44:44 -0700 Subject: [PATCH 0118/2143] Relocate global channel pool variables --- src/objective-c/GRPCClient/private/GRPCChannel.m | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 6b5d1fe0719..ac4b88f3049 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -32,9 +32,12 @@ #import #import -// When all calls of a channel are destroyed, destroy the channel after this much seconds. +/** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ NSTimeInterval kChannelDestroyDelay = 30; +/** Global instance of channel pool. */ +static GRPCChannelPool *gChannelPool; + /** * Time the channel destroy when the channel's calls are unreffed. If there's new call, reset the * timer. @@ -268,11 +271,9 @@ NSTimeInterval kChannelDestroyDelay = 30; return [[GRPCChannel alloc] initWithUnmanagedChannel:unmanaged_channel configuration:config]; } -static dispatch_once_t initChannelPool; -static GRPCChannelPool *gChannelPool; - + (nullable instancetype)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { + static dispatch_once_t initChannelPool; dispatch_once(&initChannelPool, ^{ gChannelPool = [[GRPCChannelPool alloc] init]; }); From ef830758cc90924e9fdd5be6a451774fad326db0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 09:50:36 -0700 Subject: [PATCH 0119/2143] Comments to methods of GRPCChannelConfiguration --- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index e9c2ef2bd14..43e07b98454 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -29,12 +29,22 @@ NS_ASSUME_NONNULL_BEGIN @class GRPCChannel; +/** Caching signature of a channel. */ @interface GRPCChannelConfiguration : NSObject +/** The host that this channel is connected to. */ @property(copy, readonly) NSString *host; + +/** + * Options of the corresponding call. Note that only the channel-related options are of interest to + * this class. + */ @property(strong, readonly) GRPCCallOptions *callOptions; +/** Acquire the factory to generate a new channel with current configurations. */ @property(readonly) id channelFactory; + +/** Acquire the dictionary of channel args with current configurations. */ @property(readonly) NSDictionary *channelArgs; - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; From dcf5f1ff384da2cf0dd6b38bb9062caed58e35c0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 10:03:59 -0700 Subject: [PATCH 0120/2143] Comments to GRPCChannelFactory --- src/objective-c/GRPCClient/private/GRPCChannelFactory.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h index 492145da80b..14dc7079ba3 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -22,8 +22,10 @@ NS_ASSUME_NONNULL_BEGIN +/** A factory interface which generates new channel. */ @protocol GRPCChannelFactory + /** Create a channel with specific channel args to a specific host. */ - (nullable grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(nullable NSDictionary *)args; From 4efa40d7cda4537e42adaa0dbd70097886d2c91c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 10:06:07 -0700 Subject: [PATCH 0121/2143] Validate parameters of GRPCChannelConfiguration:initWithHost: --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 8e0f6976cf9..80fa9c9151f 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -35,6 +35,8 @@ extern const char *kCFStreamVarName; @implementation GRPCChannelConfiguration - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { + NSAssert(host.length, @"Host must not be empty."); + NSAssert(callOptions, @"callOptions must not be empty."); if ((self = [super init])) { _host = [host copy]; _callOptions = [callOptions copy]; From ed1e6c48e05e510186303e430a800078128dfc89 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 12:09:19 -0700 Subject: [PATCH 0122/2143] More verbose channel destroy message --- src/objective-c/GRPCClient/private/GRPCChannel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 5fb18e0332e..7151dbb6e9c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -59,8 +59,8 @@ struct grpc_channel_credentials; - (void)ref; /** - * Decrease the refcount of the channel. If the refcount of the channel decrease to 0, start a timer - * to destroy the channel + * Decrease the refcount of the channel. If the refcount of the channel decrease to 0, the channel + * is destroyed after 30 seconds. */ - (void)unref; From e667a3fb8f3465732926d44bc882dfaabc8dae54 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 12:25:25 -0700 Subject: [PATCH 0123/2143] Another copy --- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index ac4b88f3049..f3ac140599e 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -264,7 +264,7 @@ static GRPCChannelPool *gChannelPool; [args addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; channelArgs = args; } else { - channelArgs = config.channelArgs; + channelArgs = [config.channelArgs copy]; } id factory = config.channelFactory; grpc_channel *unmanaged_channel = [factory createChannelWithHost:host channelArgs:channelArgs]; From ae99d3a5ed45e135f8b9bd9235b252fed56aa417 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 12:41:05 -0700 Subject: [PATCH 0124/2143] Document GRPCAuthorizationProtocol --- src/objective-c/GRPCClient/GRPCCallOptions.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 484f15fde6e..4a93db84bc2 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -57,7 +57,15 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { GRPCTransportTypeInsecure, }; +/** + * Implement this protocol to provide a token to gRPC when a call is initiated. + */ @protocol GRPCAuthorizationProtocol + +/** + * This method is called when gRPC is about to start the call. When OAuth token is acquired, + * \a handler is expected to be called with \a token being the new token to be used for this call. + */ - (void)getTokenWithHandler:(void (^)(NSString *token))hander; @end From 9a15b6a5cfa81ab31afb4945cc1ccd8fe5be5665 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 13:00:38 -0700 Subject: [PATCH 0125/2143] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 16 +++++++++------- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 8 +++----- src/objective-c/GRPCClient/GRPCCallOptions.m | 14 +++++++------- .../GRPCClient/private/ChannelArgsUtil.h | 14 +++++++++----- src/objective-c/GRPCClient/private/GRPCChannel.h | 2 +- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- .../GRPCClient/private/GRPCChannelFactory.h | 2 +- src/objective-c/ProtoRPC/ProtoRPC.h | 11 ++++++----- src/objective-c/ProtoRPC/ProtoRPC.m | 11 ++++++----- src/objective-c/tests/GRPCClientTests.m | 7 ++++--- src/objective-c/tests/InteropTests.m | 7 ++++--- 12 files changed, 52 insertions(+), 44 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 13dcfa07130..b3936ad8fc1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -147,8 +147,8 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { * Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by * the server. */ -extern NSString * const kGRPCHeadersKey; -extern NSString * const kGRPCTrailersKey; +extern NSString *const kGRPCHeadersKey; +extern NSString *const kGRPCTrailersKey; /** An object can implement this protocol to receive responses from server from a call. */ @protocol GRPCResponseHandler @@ -156,13 +156,13 @@ extern NSString * const kGRPCTrailersKey; @optional /** Issued when initial metadata is received from the server. */ -- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata; +- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; /** * Issued when a message is received from the server. The message is the raw data received from the * server, with decompression and without proto deserialization. */ -- (void)receivedRawMessage:(NSData * _Nullable)message; +- (void)receivedRawMessage:(NSData *_Nullable)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -170,7 +170,8 @@ extern NSString * const kGRPCTrailersKey; * is non-nil and contains the corresponding error information, including gRPC error codes and * error descriptions. */ -- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error; +- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata + error:(NSError *_Nullable)error; @required @@ -218,7 +219,7 @@ extern NSString * const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Designated initializer for a call. @@ -228,7 +229,8 @@ extern NSString * const kGRPCTrailersKey; */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler - callOptions:(GRPCCallOptions * _Nullable)callOptions NS_DESIGNATED_INITIALIZER; + callOptions:(GRPCCallOptions *_Nullable)callOptions + NS_DESIGNATED_INITIALIZER; /** * Convenience initializer for a call that uses default call options (see GRPCCallOptions.m for * the default options). diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 34a0e436eaa..60a946a472c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -108,7 +108,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler - callOptions:(GRPCCallOptions * _Nullable)callOptions { + callOptions:(GRPCCallOptions *_Nullable)callOptions { if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; } diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 4a93db84bc2..d1daaa1d822 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -27,14 +27,12 @@ typedef NS_ENUM(NSUInteger, GRPCCallSafety) { /** Signal that the call is idempotent. gRPC is free to use PUT verb. */ GRPCCallSafetyIdempotentRequest = 1, /** - * Signal that the call is cacheable and will not affect server state. gRPC is free to use GET - * verb. - */ + * Signal that the call is cacheable and will not affect server state. gRPC is free to use GET + * verb. + */ GRPCCallSafetyCacheableRequest = 2, }; - - // Compression algorithm to be used by a gRPC call typedef NS_ENUM(NSInteger, GRPCCompressionAlgorithm) { GRPCCompressNone = 0, diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index e148664925c..fe75c17b09a 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -102,7 +102,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:kDefaultInitialMetadata userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit - compressionAlgorithm:kDefaultCompressionAlgorithm + compressionAlgorithm:kDefaultCompressionAlgorithm enableRetry:kDefaultEnableRetry keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout @@ -127,7 +127,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:(NSDictionary *)initialMetadata userAgentPrefix:(NSString *)userAgentPrefix responseSizeLimit:(NSUInteger)responseSizeLimit - compressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm + compressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm enableRetry:(BOOL)enableRetry keepaliveInterval:(NSTimeInterval)keepaliveInterval keepaliveTimeout:(NSTimeInterval)keepaliveTimeout @@ -181,7 +181,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressionAlgorithm:_compressionAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -209,7 +209,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressionAlgorithm:_compressionAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -326,7 +326,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:kDefaultInitialMetadata userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit - compressionAlgorithm:kDefaultCompressionAlgorithm + compressionAlgorithm:kDefaultCompressionAlgorithm enableRetry:kDefaultEnableRetry keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout @@ -353,7 +353,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressionAlgorithm:_compressionAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout @@ -381,7 +381,7 @@ static const NSUInteger kDefaultChannelID = 0; initialMetadata:_initialMetadata userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit - compressionAlgorithm:_compressionAlgorithm + compressionAlgorithm:_compressionAlgorithm enableRetry:_enableRetry keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h index 3fb876ecc4a..f271e846f00 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h @@ -24,11 +24,15 @@ void GRPCFreeChannelArgs(grpc_channel_args* channel_args); /** - * Allocates a @c grpc_channel_args and populates it with the options specified in the - * @c dictionary. Keys must be @c NSString, @c NSNumber, or a pointer. If the value responds to - * @c @selector(UTF8String) then it will be mapped to @c GRPC_ARG_STRING. If the value responds to - * @c @selector(intValue), it will be mapped to @c GRPC_ARG_INTEGER. Otherwise, if the value is not - * nil, it is mapped as a pointer. The caller of this function is responsible for calling + * Allocates a @c grpc_channel_args and populates it with the options specified + * in the + * @c dictionary. Keys must be @c NSString, @c NSNumber, or a pointer. If the + * value responds to + * @c @selector(UTF8String) then it will be mapped to @c GRPC_ARG_STRING. If the + * value responds to + * @c @selector(intValue), it will be mapped to @c GRPC_ARG_INTEGER. Otherwise, + * if the value is not nil, it is mapped as a pointer. The caller of this + * function is responsible for calling * @c GRPCFreeChannelArgs to free the @c grpc_channel_args struct. */ grpc_channel_args* GRPCBuildChannelArgs(NSDictionary* dictionary); diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 7151dbb6e9c..e1bf8fb1af4 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -32,7 +32,7 @@ struct grpc_channel_credentials; - (nullable instancetype)init NS_UNAVAILABLE; -+ (nullable instancetype)new NS_UNAVAILABLE; ++ (nullable instancetype) new NS_UNAVAILABLE; /** * Returns a channel connecting to \a host with options as \a callOptions. The channel may be new diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index f3ac140599e..018ed28a7ab 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -222,7 +222,7 @@ static GRPCChannelPool *gChannelPool; }); } -- (nullable instancetype)initWithUnmanagedChannel:(grpc_channel * _Nullable)unmanagedChannel +- (nullable instancetype)initWithUnmanagedChannel:(grpc_channel *_Nullable)unmanagedChannel configuration:(GRPCChannelConfiguration *)configuration { NSAssert(configuration, @"Configuration must not be empty."); if (!unmanagedChannel) { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h index 14dc7079ba3..a934e966e9d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN /** A factory interface which generates new channel. */ @protocol GRPCChannelFactory - /** Create a channel with specific channel args to a specific host. */ +/** Create a channel with specific channel args to a specific host. */ - (nullable grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(nullable NSDictionary *)args; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 3a7fd58fb16..960a9a12bd2 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -31,12 +31,12 @@ NS_ASSUME_NONNULL_BEGIN @optional /** Issued when initial metadata is received from the server. */ -- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata; +- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; /** * Issued when a message is received from the server. The message is the deserialized proto object. */ -- (void)receivedProtoMessage:(GPBMessage * _Nullable)message; +- (void)receivedProtoMessage:(GPBMessage *_Nullable)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -44,7 +44,8 @@ NS_ASSUME_NONNULL_BEGIN * is non-nil and contains the corresponding error information, including gRPC error codes and * error descriptions. */ -- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error; +- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata + error:(NSError *_Nullable)error; @required @@ -70,7 +71,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message responseHandler:(id)handler - callOptions:(GRPCCallOptions * _Nullable)callOptions + callOptions:(GRPCCallOptions *_Nullable)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** @@ -95,7 +96,7 @@ NS_ASSUME_NONNULL_BEGIN */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler - callOptions:(GRPCCallOptions * _Nullable)callOptions + callOptions:(GRPCCallOptions *_Nullable)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index f6e3298f623..28c037e6092 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -34,7 +34,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message responseHandler:(id)handler - callOptions:(GRPCCallOptions * _Nullable)callOptions + callOptions:(GRPCCallOptions *_Nullable)callOptions responseClass:(Class)responseClass { if ((self = [super init])) { _call = [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions @@ -70,7 +70,7 @@ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler - callOptions:(GRPCCallOptions * _Nullable)callOptions + callOptions:(GRPCCallOptions *_Nullable)callOptions responseClass:(Class)responseClass { if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; @@ -153,7 +153,7 @@ }); } -- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { if (_handler && initialMetadata != nil) { id handler = _handler; if ([handler respondsToSelector:@selector(initialMetadata:)]) { @@ -164,7 +164,7 @@ } } -- (void)receivedRawMessage:(NSData * _Nullable)message { +- (void)receivedRawMessage:(NSData *_Nullable)message { if (_handler && message != nil) { id handler = _handler; NSError *error = nil; @@ -188,7 +188,8 @@ } } -- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error { +- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata + error:(NSError *_Nullable)error { if (_handler) { id handler = _handler; if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 0a9ec97c488..0d1b80e33c8 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -114,19 +114,20 @@ static GRPCProtoMethod *kFullDuplexCallMethod; return self; } -- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); } } -- (void)receivedProtoMessage:(GPBMessage * _Nullable)message { +- (void)receivedProtoMessage:(GPBMessage *_Nullable)message { if (_messageCallback) { _messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error { +- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata + error:(NSError *_Nullable)error { if (_closeCallback) { _closeCallback(trailingMetadata, error); } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index fb49bb99e0a..d67dc0743e8 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -102,19 +102,20 @@ BOOL isRemoteInteropTest(NSString *host) { return self; } -- (void)receivedInitialMetadata:(NSDictionary * _Nullable)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); } } -- (void)receivedProtoMessage:(GPBMessage * _Nullable)message { +- (void)receivedProtoMessage:(GPBMessage *_Nullable)message { if (_messageCallback) { _messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary * _Nullable)trailingMetadata error:(NSError * _Nullable)error { +- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata + error:(NSError *_Nullable)error { if (_closeCallback) { _closeCallback(trailingMetadata, error); } From 2b0470dcb3bd8306adb1c63a81c931482e86c5fa Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 20 Oct 2018 13:07:02 -0700 Subject: [PATCH 0126/2143] Ignore serverAuthority when using Cronet transport --- src/objective-c/GRPCClient/private/GRPCChannel.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 018ed28a7ab..60c2e29a6ec 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -161,7 +161,8 @@ static GRPCChannelPool *gChannelPool; __block grpc_call *call = nil; dispatch_sync(_dispatchQueue, ^{ if (self->_unmanagedChannel) { - NSString *serverAuthority = callOptions.serverAuthority; + NSString *serverAuthority = + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); grpc_slice host_slice = grpc_empty_slice(); From 5c7ab989bed8e8b757db0de077571eeec66d3f2f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 22 Oct 2018 11:13:39 -0700 Subject: [PATCH 0127/2143] bool->BOOL --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 60a946a472c..7e0640e8ae1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -103,7 +103,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; /** Serial dispatch queue for tasks inside the call. */ dispatch_queue_t _dispatchQueue; /** Flags whether call has started. */ - bool _started; + BOOL _started; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions From b03adfbf067cc4f7ef05eb7fa8cbf49c08b3bf6b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 22 Oct 2018 12:14:43 -0700 Subject: [PATCH 0128/2143] More nullability specifier --- src/objective-c/GRPCClient/GRPCCall.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index b3936ad8fc1..2f23b879f13 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -304,7 +304,7 @@ NS_ASSUME_NONNULL_END * * The property is initialized to an empty NSMutableDictionary. */ -@property(atomic, readonly) NSMutableDictionary *requestHeaders; +@property(null_unspecified, atomic, readonly) NSMutableDictionary * requestHeaders; /** * This dictionary is populated with the HTTP headers received from the server. This happens before @@ -315,7 +315,7 @@ NS_ASSUME_NONNULL_END * The value of this property is nil until all response headers are received, and will change before * any of -writeValue: or -writesFinishedWithError: are sent to the writeable. */ -@property(atomic, readonly) NSDictionary *responseHeaders; +@property(null_unspecified, atomic, readonly) NSDictionary *responseHeaders; /** * Same as responseHeaders, but populated with the HTTP trailers received from the server before the @@ -324,7 +324,7 @@ NS_ASSUME_NONNULL_END * The value of this property is nil until all response trailers are received, and will change * before -writesFinishedWithError: is sent to the writeable. */ -@property(atomic, readonly) NSDictionary *responseTrailers; +@property(null_unspecified, atomic, readonly) NSDictionary *responseTrailers; /** * The request writer has to write NSData objects into the provided Writeable. The server will @@ -337,9 +337,9 @@ NS_ASSUME_NONNULL_END * host parameter should not contain the scheme (http:// or https://), only the name or IP addr * and the port number, for example @"localhost:5050". */ -- (instancetype)initWithHost:(NSString *)host - path:(NSString *)path - requestsWriter:(GRXWriter *)requestWriter; +- (instancetype _Null_unspecified)initWithHost:(NSString * _Null_unspecified)host + path:(NSString * _Null_unspecified)path + requestsWriter:(GRXWriter * _Null_unspecified)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -350,10 +350,10 @@ NS_ASSUME_NONNULL_END /** * The following methods are deprecated. */ -+ (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path; -@property(atomic, copy, readwrite) NSString *serverName; ++ (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString * _Null_unspecified)host path:(NSString * _Null_unspecified)path; +@property(null_unspecified, atomic, copy, readwrite) NSString *serverName; @property NSTimeInterval timeout; -- (void)setResponseDispatchQueue:(dispatch_queue_t)queue; +- (void)setResponseDispatchQueue:(dispatch_queue_t _Null_unspecified)queue; @end @@ -364,11 +364,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (id)objectForKeyedSubscript:(id)key; -- (void)setObject:(id)obj forKeyedSubscript:(id)key; +- (id _Null_unspecified)objectForKeyedSubscript:(id _Null_unspecified)key; +- (void)setObject:(id _Null_unspecified)obj forKeyedSubscript:(id _Null_unspecified)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(id)key; +- (void)removeObjectForKey:(id _Null_unspecified)key; @end #pragma clang diagnostic push From fb1ebfef00e5153e30c1a008a350c53dde4335c3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 22 Oct 2018 13:56:10 -0700 Subject: [PATCH 0129/2143] Fix test flake --- src/objective-c/tests/GRPCClientTests.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 0d1b80e33c8..2021540f28d 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -120,7 +120,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; } } -- (void)receivedProtoMessage:(GPBMessage *_Nullable)message { +- (void)receivedRawMessage:(GPBMessage *_Nullable)message { if (_messageCallback) { _messageCallback(message); } @@ -803,7 +803,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; NSString *const kDummyAddress = [NSString stringWithFormat:@"8.8.8.8:1"]; GRPCCall *call = [[GRPCCall alloc] initWithHost:kDummyAddress - path:@"" + path:@"/dummyPath" requestsWriter:[GRXWriter writerWithValue:[NSData data]]]; [GRPCCall setMinConnectTimeout:timeout * 1000 initialBackoff:backoff * 1000 From 3566540f16451ea87aff980b5de13c41a8debeb6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 22 Oct 2018 14:45:38 -0700 Subject: [PATCH 0130/2143] nit: group includes --- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 41d3bec4efa..c0d75c0f319 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -20,11 +20,11 @@ #import #import +#import #include #include -#import #import "GRPCChannelFactory.h" #import "GRPCCompletionQueue.h" #import "GRPCConnectivityMonitor.h" From e13c8678264d85353bb2ce49ae829c03f6c9493f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 22 Oct 2018 18:25:16 -0700 Subject: [PATCH 0131/2143] Do not issue more message when the call is canceled --- src/objective-c/GRPCClient/GRPCCall.m | 61 ++++++++++++++++++++------- src/objective-c/ProtoRPC/ProtoRPC.m | 43 ++++++++++++++----- 2 files changed, 78 insertions(+), 26 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 7e0640e8ae1..23c8d0f2d71 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -104,6 +104,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_queue_t _dispatchQueue; /** Flags whether call has started. */ BOOL _started; + /** + * Flags that the call has been canceled. When this is true, pending initial metadata and message + * should not be issued to \a _handler. This ivar must be accessed with lock to self. + */ + BOOL _canceled; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -135,6 +140,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); _started = NO; + _canceled = NO; } return self; @@ -217,6 +223,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; self->_pipe = nil; } if (self->_handler) { + @synchronized(self) { + self->_canceled = YES; + } id handler = self->_handler; dispatch_async(handler.dispatchQueue, ^{ if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { @@ -252,30 +261,50 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { - id handler = _handler; - if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:initialMetadata]; - }); + if (_handler != nil && initialMetadata != nil) { + id handler = _handler; + if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + dispatch_async(handler.dispatchQueue, ^{ + // Do not issue initial metadata if the call is already canceled. + __block BOOL canceled = NO; + @synchronized(self) { + canceled = self->_canceled; + } + if (!canceled) { + [handler receivedInitialMetadata:initialMetadata]; + } + }); + } } } - (void)issueMessage:(id)message { - id handler = _handler; - if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedRawMessage:message]; - }); + if (_handler != nil && message != nil) { + id handler = _handler; + if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { + dispatch_async(handler.dispatchQueue, ^{ + // Do not issue message if the call is already canceled. + __block BOOL canceled = NO; + @synchronized(self) { + canceled = self->_canceled; + } + if (!canceled) { + [handler receivedRawMessage:message]; + } + }); + } } } - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - id handler = _handler; - NSDictionary *trailers = _call.responseTrailers; - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:trailers error:error]; - }); + if (_handler != nil) { + id handler = _handler; + NSDictionary *trailers = _call.responseTrailers; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:trailers error:error]; + }); + } } } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 28c037e6092..a6c88488fc2 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -66,6 +66,11 @@ GRPCCall2 *_call; dispatch_queue_t _dispatchQueue; + /** + * Flags that the call has been canceled. When this is true, pending initial metadata and message + * should not be issued to \a _handler. This ivar must be accessed with lock to self. + */ + BOOL _canceled; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -95,6 +100,7 @@ _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } dispatch_set_target_queue(handler.dispatchQueue, _dispatchQueue); + _canceled = NO; [self start]; } @@ -110,12 +116,15 @@ - (void)cancel { dispatch_async(_dispatchQueue, ^{ - if (_call) { - [_call cancel]; - _call = nil; + if (self->_call) { + [self->_call cancel]; + self->_call = nil; } - if (_handler) { - id handler = _handler; + if (self->_handler) { + @synchronized(self) { + self->_canceled = YES; + } + id handler = self->_handler; if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(handler.dispatchQueue, ^{ [handler closedWithTrailingMetadata:nil @@ -127,7 +136,7 @@ }]]; }); } - _handler = nil; + self->_handler = nil; } }); } @@ -155,10 +164,17 @@ - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { if (_handler && initialMetadata != nil) { - id handler = _handler; + __block id handler = _handler; if ([handler respondsToSelector:@selector(initialMetadata:)]) { dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:initialMetadata]; + // Do not issue initial metadata if the call is already canceled. + __block BOOL canceled = NO; + @synchronized(self) { + canceled = self->_canceled; + } + if (!canceled) { + [handler receivedInitialMetadata:initialMetadata]; + } }); } } @@ -166,13 +182,20 @@ - (void)receivedRawMessage:(NSData *_Nullable)message { if (_handler && message != nil) { - id handler = _handler; + __block id handler = _handler; NSError *error = nil; GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; if (parsed) { if ([handler respondsToSelector:@selector(receivedProtoMessage:)]) { dispatch_async(handler.dispatchQueue, ^{ - [handler receivedProtoMessage:parsed]; + // Do not issue message if the call is already canceled. + __block BOOL canceled = NO; + @synchronized(self) { + canceled = self->_canceled; + } + if (!canceled) { + [handler receivedProtoMessage:parsed]; + } }); } } else { From 76ddfcb6cb87611addcbc68b01264e37a4705d27 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 22 Oct 2018 18:36:59 -0700 Subject: [PATCH 0132/2143] Propagate internal error when failed parsing proto --- src/objective-c/ProtoRPC/ProtoRPC.m | 35 ++++++++++++++++------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index a6c88488fc2..6085f893560 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -27,6 +27,24 @@ #import #import +/** + * Generate an NSError object that represents a failure in parsing a proto class. + */ +static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsingError) { + NSDictionary *info = @{ + NSLocalizedDescriptionKey : @"Unable to parse response from the server", + NSLocalizedRecoverySuggestionErrorKey : + @"If this RPC is idempotent, retry " + @"with exponential backoff. Otherwise, query the server status before " + @"retrying.", + NSUnderlyingErrorKey : parsingError, + @"Expected class" : expectedClass, + @"Received value" : proto, + }; + // TODO(jcanizales): Use kGRPCErrorDomain and GRPCErrorCodeInternal when they're public. + return [NSError errorWithDomain:@"io.grpc" code:13 userInfo:info]; +} + @implementation GRPCUnaryProtoCall { GRPCStreamingProtoCall *_call; } @@ -201,7 +219,7 @@ } else { if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:nil error:error]; + [handler closedWithTrailingMetadata:nil error:ErrorForBadProto(message, _responseClass, error)]; }); } _handler = nil; @@ -232,21 +250,6 @@ @end -static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsingError) { - NSDictionary *info = @{ - NSLocalizedDescriptionKey : @"Unable to parse response from the server", - NSLocalizedRecoverySuggestionErrorKey : - @"If this RPC is idempotent, retry " - @"with exponential backoff. Otherwise, query the server status before " - @"retrying.", - NSUnderlyingErrorKey : parsingError, - @"Expected class" : expectedClass, - @"Received value" : proto, - }; - // TODO(jcanizales): Use kGRPCErrorDomain and GRPCErrorCodeInternal when they're public. - return [NSError errorWithDomain:@"io.grpc" code:13 userInfo:info]; -} - #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-implementations" @implementation ProtoRPC { From e39c146f0f7f1a56e0cd65ec5d707c8bb091366e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 10:03:48 -0700 Subject: [PATCH 0133/2143] Revert "Do not issue more message when the call is canceled" This reverts commit e13c8678264d85353bb2ce49ae829c03f6c9493f. --- src/objective-c/GRPCClient/GRPCCall.m | 61 +++++++-------------------- src/objective-c/ProtoRPC/ProtoRPC.m | 43 +++++-------------- 2 files changed, 26 insertions(+), 78 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 23c8d0f2d71..7e0640e8ae1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -104,11 +104,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_queue_t _dispatchQueue; /** Flags whether call has started. */ BOOL _started; - /** - * Flags that the call has been canceled. When this is true, pending initial metadata and message - * should not be issued to \a _handler. This ivar must be accessed with lock to self. - */ - BOOL _canceled; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -140,7 +135,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; } dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); _started = NO; - _canceled = NO; } return self; @@ -223,9 +217,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; self->_pipe = nil; } if (self->_handler) { - @synchronized(self) { - self->_canceled = YES; - } id handler = self->_handler; dispatch_async(handler.dispatchQueue, ^{ if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { @@ -261,50 +252,30 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { - if (_handler != nil && initialMetadata != nil) { - id handler = _handler; - if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { - dispatch_async(handler.dispatchQueue, ^{ - // Do not issue initial metadata if the call is already canceled. - __block BOOL canceled = NO; - @synchronized(self) { - canceled = self->_canceled; - } - if (!canceled) { - [handler receivedInitialMetadata:initialMetadata]; - } - }); - } + id handler = _handler; + if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedInitialMetadata:initialMetadata]; + }); } } - (void)issueMessage:(id)message { - if (_handler != nil && message != nil) { - id handler = _handler; - if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { - dispatch_async(handler.dispatchQueue, ^{ - // Do not issue message if the call is already canceled. - __block BOOL canceled = NO; - @synchronized(self) { - canceled = self->_canceled; - } - if (!canceled) { - [handler receivedRawMessage:message]; - } - }); - } + id handler = _handler; + if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler receivedRawMessage:message]; + }); } } - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - if (_handler != nil) { - id handler = _handler; - NSDictionary *trailers = _call.responseTrailers; - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:trailers error:error]; - }); - } + id handler = _handler; + NSDictionary *trailers = _call.responseTrailers; + if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(handler.dispatchQueue, ^{ + [handler closedWithTrailingMetadata:trailers error:error]; + }); } } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 6085f893560..294f3a4cf5c 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -84,11 +84,6 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing GRPCCall2 *_call; dispatch_queue_t _dispatchQueue; - /** - * Flags that the call has been canceled. When this is true, pending initial metadata and message - * should not be issued to \a _handler. This ivar must be accessed with lock to self. - */ - BOOL _canceled; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -118,7 +113,6 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } dispatch_set_target_queue(handler.dispatchQueue, _dispatchQueue); - _canceled = NO; [self start]; } @@ -134,15 +128,12 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)cancel { dispatch_async(_dispatchQueue, ^{ - if (self->_call) { - [self->_call cancel]; - self->_call = nil; + if (_call) { + [_call cancel]; + _call = nil; } - if (self->_handler) { - @synchronized(self) { - self->_canceled = YES; - } - id handler = self->_handler; + if (_handler) { + id handler = _handler; if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(handler.dispatchQueue, ^{ [handler closedWithTrailingMetadata:nil @@ -154,7 +145,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing }]]; }); } - self->_handler = nil; + _handler = nil; } }); } @@ -182,17 +173,10 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { if (_handler && initialMetadata != nil) { - __block id handler = _handler; + id handler = _handler; if ([handler respondsToSelector:@selector(initialMetadata:)]) { dispatch_async(handler.dispatchQueue, ^{ - // Do not issue initial metadata if the call is already canceled. - __block BOOL canceled = NO; - @synchronized(self) { - canceled = self->_canceled; - } - if (!canceled) { - [handler receivedInitialMetadata:initialMetadata]; - } + [handler receivedInitialMetadata:initialMetadata]; }); } } @@ -200,20 +184,13 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)receivedRawMessage:(NSData *_Nullable)message { if (_handler && message != nil) { - __block id handler = _handler; + id handler = _handler; NSError *error = nil; GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; if (parsed) { if ([handler respondsToSelector:@selector(receivedProtoMessage:)]) { dispatch_async(handler.dispatchQueue, ^{ - // Do not issue message if the call is already canceled. - __block BOOL canceled = NO; - @synchronized(self) { - canceled = self->_canceled; - } - if (!canceled) { - [handler receivedProtoMessage:parsed]; - } + [handler receivedProtoMessage:parsed]; }); } } else { From f3e9224f0b34a6265830600c67293d96964a4c5c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 10:22:18 -0700 Subject: [PATCH 0134/2143] Remove retain of handler in callbacks and dispatch to dispatchQueue --- src/objective-c/GRPCClient/GRPCCall.h | 11 +++-- src/objective-c/GRPCClient/GRPCCall.m | 21 +++------ src/objective-c/ProtoRPC/ProtoRPC.h | 8 +++- src/objective-c/ProtoRPC/ProtoRPC.m | 63 +++++++++++-------------- src/objective-c/tests/GRPCClientTests.m | 24 ++++++---- src/objective-c/tests/InteropTests.m | 24 ++++++---- 6 files changed, 77 insertions(+), 74 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 2f23b879f13..85d0a302d17 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -155,12 +155,16 @@ extern NSString *const kGRPCTrailersKey; @optional -/** Issued when initial metadata is received from the server. */ +/** + * Issued when initial metadata is received from the server. The task must be scheduled onto the + * dispatch queue in property \a dispatchQueue. + */ - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; /** * Issued when a message is received from the server. The message is the raw data received from the - * server, with decompression and without proto deserialization. + * server, with decompression and without proto deserialization. The task must be scheduled onto the + * dispatch queue in property \a dispatchQueue. */ - (void)receivedRawMessage:(NSData *_Nullable)message; @@ -168,7 +172,8 @@ extern NSString *const kGRPCTrailersKey; * Issued when a call finished. If the call finished successfully, \a error is nil and \a * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error * is non-nil and contains the corresponding error information, including gRPC error codes and - * error descriptions. + * error descriptions. The task must be scheduled onto the dispatch queue in property + * \a dispatchQueue. */ - (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata error:(NSError *_Nullable)error; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 7e0640e8ae1..29a0ed4e106 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -252,30 +252,21 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { - id handler = _handler; - if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:initialMetadata]; - }); + if (initialMetadata != nil && [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + [_handler receivedInitialMetadata:initialMetadata]; } } - (void)issueMessage:(id)message { - id handler = _handler; - if ([handler respondsToSelector:@selector(receivedRawMessage:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedRawMessage:message]; - }); + if (message != nil && [_handler respondsToSelector:@selector(receivedRawMessage:)]) { + [_handler receivedRawMessage:message]; } } - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - id handler = _handler; NSDictionary *trailers = _call.responseTrailers; - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:trailers error:error]; - }); + if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + [_handler closedWithTrailingMetadata:trailers error:error]; } } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 960a9a12bd2..6f4b9eed759 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -30,11 +30,14 @@ NS_ASSUME_NONNULL_BEGIN @optional -/** Issued when initial metadata is received from the server. */ +/** + * Issued when initial metadata is received from the server. The task must be scheduled onto the + * dispatch queue in property \a dispatchQueue. */ - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; /** * Issued when a message is received from the server. The message is the deserialized proto object. + * The task must be scheduled onto the dispatch queue in property \a dispatchQueue. */ - (void)receivedProtoMessage:(GPBMessage *_Nullable)message; @@ -42,7 +45,8 @@ NS_ASSUME_NONNULL_BEGIN * Issued when a call finished. If the call finished successfully, \a error is nil and \a * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error * is non-nil and contains the corresponding error information, including gRPC error codes and - * error descriptions. + * error descriptions. The task must be scheduled onto the dispatch queue in property + * \a dispatchQueue. */ - (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata error:(NSError *_Nullable)error; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 294f3a4cf5c..27070a891d5 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -172,53 +172,44 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { - if (_handler && initialMetadata != nil) { - id handler = _handler; - if ([handler respondsToSelector:@selector(initialMetadata:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedInitialMetadata:initialMetadata]; - }); + dispatch_async(_dispatchQueue, ^{ + if (initialMetadata != nil && [self->_handler respondsToSelector:@selector(initialMetadata:)]) { + [self->_handler receivedInitialMetadata:initialMetadata]; } - } + }); } - (void)receivedRawMessage:(NSData *_Nullable)message { - if (_handler && message != nil) { - id handler = _handler; - NSError *error = nil; - GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; - if (parsed) { - if ([handler respondsToSelector:@selector(receivedProtoMessage:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler receivedProtoMessage:parsed]; - }); + dispatch_async(_dispatchQueue, ^{ + if (self->_handler && message != nil) { + NSError *error = nil; + GPBMessage *parsed = [self->_responseClass parseFromData:message error:&error]; + if (parsed) { + if ([self->_handler respondsToSelector:@selector(receivedProtoMessage:)]) { + [self->_handler receivedProtoMessage:parsed]; + } + } else { + if ([self->_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + [self->_handler closedWithTrailingMetadata:nil error:ErrorForBadProto(message, _responseClass, error)]; + } + self->_handler = nil; + [self->_call cancel]; + self->_call = nil; } - } else { - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:nil error:ErrorForBadProto(message, _responseClass, error)]; - }); - } - _handler = nil; - [_call cancel]; - _call = nil; } - } + }); } - (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata error:(NSError *_Nullable)error { - if (_handler) { - id handler = _handler; - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(handler.dispatchQueue, ^{ - [handler closedWithTrailingMetadata:trailingMetadata error:error]; - }); + dispatch_async(_dispatchQueue, ^{ + if ([self->_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + [self->_handler closedWithTrailingMetadata:trailingMetadata error:error]; } - _handler = nil; - } - [_call cancel]; - _call = nil; + self->_handler = nil; + [self->_call cancel]; + self->_call = nil; + }); } - (dispatch_queue_t)dispatchQueue { diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 2021540f28d..bbe81502dcf 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -115,22 +115,28 @@ static GRPCProtoMethod *kFullDuplexCallMethod; } - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { - if (_initialMetadataCallback) { - _initialMetadataCallback(initialMetadata); - } + dispatch_async(_dispatchQueue, ^{ + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } + }); } - (void)receivedRawMessage:(GPBMessage *_Nullable)message { - if (_messageCallback) { - _messageCallback(message); - } + dispatch_async(_dispatchQueue, ^{ + if (_messageCallback) { + _messageCallback(message); + } + }); } - (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata error:(NSError *_Nullable)error { - if (_closeCallback) { - _closeCallback(trailingMetadata, error); - } + dispatch_async(_dispatchQueue, ^{ + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } + }); } - (dispatch_queue_t)dispatchQueue { diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index d67dc0743e8..c42718f15ee 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -103,22 +103,28 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { - if (_initialMetadataCallback) { - _initialMetadataCallback(initialMetadata); - } + dispatch_async(_dispatchQueue, ^{ + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } + }); } - (void)receivedProtoMessage:(GPBMessage *_Nullable)message { - if (_messageCallback) { - _messageCallback(message); - } + dispatch_async(_dispatchQueue, ^{ + if (_messageCallback) { + _messageCallback(message); + } + }); } - (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata error:(NSError *_Nullable)error { - if (_closeCallback) { - _closeCallback(trailingMetadata, error); - } + dispatch_async(_dispatchQueue, ^{ + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } + }); } - (dispatch_queue_t)dispatchQueue { From 351b5d0f13138690b8ce75a7675306caec5c9e62 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 10:28:04 -0700 Subject: [PATCH 0135/2143] enableRetry->retryEnabled --- src/objective-c/GRPCClient/GRPCCallOptions.h | 4 +-- src/objective-c/GRPCClient/GRPCCallOptions.m | 32 +++++++++---------- .../GRPCClient/private/GRPCChannelPool.m | 4 +-- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index d1daaa1d822..4c8bb605eab 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -132,7 +132,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * refer to * https://github.com/grpc/proposal/blob/master/A6-client-retries.md */ -@property(readonly) BOOL enableRetry; +@property(readonly) BOOL retryEnabled; // HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two // PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the @@ -279,7 +279,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * refer to * https://github.com/grpc/proposal/blob/master/A6-client-retries.md */ -@property(readwrite) BOOL enableRetry; +@property(readwrite) BOOL retryEnabled; // HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two // PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index fe75c17b09a..85a5a9ac89e 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -25,7 +25,7 @@ static NSDictionary *const kDefaultInitialMetadata = nil; static NSString *const kDefaultUserAgentPrefix = nil; static const NSUInteger kDefaultResponseSizeLimit = 0; static const GRPCCompressionAlgorithm kDefaultCompressionAlgorithm = GRPCCompressNone; -static const BOOL kDefaultEnableRetry = YES; +static const BOOL kDefaultRetryEnabled = YES; static const NSTimeInterval kDefaultKeepaliveInterval = 0; static const NSTimeInterval kDefaultKeepaliveTimeout = 0; static const NSTimeInterval kDefaultConnectMinTimeout = 0; @@ -53,7 +53,7 @@ static const NSUInteger kDefaultChannelID = 0; NSString *_userAgentPrefix; NSUInteger _responseSizeLimit; GRPCCompressionAlgorithm _compressionAlgorithm; - BOOL _enableRetry; + BOOL _retryEnabled; NSTimeInterval _keepaliveInterval; NSTimeInterval _keepaliveTimeout; NSTimeInterval _connectMinTimeout; @@ -78,7 +78,7 @@ static const NSUInteger kDefaultChannelID = 0; @synthesize userAgentPrefix = _userAgentPrefix; @synthesize responseSizeLimit = _responseSizeLimit; @synthesize compressionAlgorithm = _compressionAlgorithm; -@synthesize enableRetry = _enableRetry; +@synthesize retryEnabled = _retryEnabled; @synthesize keepaliveInterval = _keepaliveInterval; @synthesize keepaliveTimeout = _keepaliveTimeout; @synthesize connectMinTimeout = _connectMinTimeout; @@ -103,7 +103,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit compressionAlgorithm:kDefaultCompressionAlgorithm - enableRetry:kDefaultEnableRetry + retryEnabled:kDefaultRetryEnabled keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout connectMinTimeout:kDefaultConnectMinTimeout @@ -128,7 +128,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:(NSString *)userAgentPrefix responseSizeLimit:(NSUInteger)responseSizeLimit compressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm - enableRetry:(BOOL)enableRetry + retryEnabled:(BOOL)retryEnabled keepaliveInterval:(NSTimeInterval)keepaliveInterval keepaliveTimeout:(NSTimeInterval)keepaliveTimeout connectMinTimeout:(NSTimeInterval)connectMinTimeout @@ -152,7 +152,7 @@ static const NSUInteger kDefaultChannelID = 0; _userAgentPrefix = [userAgentPrefix copy]; _responseSizeLimit = responseSizeLimit; _compressionAlgorithm = compressionAlgorithm; - _enableRetry = enableRetry; + _retryEnabled = retryEnabled; _keepaliveInterval = keepaliveInterval; _keepaliveTimeout = keepaliveTimeout; _connectMinTimeout = connectMinTimeout; @@ -182,7 +182,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - enableRetry:_enableRetry + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -210,7 +210,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - enableRetry:_enableRetry + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -234,7 +234,7 @@ static const NSUInteger kDefaultChannelID = 0; return NO; if (!(callOptions.responseSizeLimit == _responseSizeLimit)) return NO; if (!(callOptions.compressionAlgorithm == _compressionAlgorithm)) return NO; - if (!(callOptions.enableRetry == _enableRetry)) return NO; + if (!(callOptions.retryEnabled == _retryEnabled)) return NO; if (!(callOptions.keepaliveInterval == _keepaliveInterval)) return NO; if (!(callOptions.keepaliveTimeout == _keepaliveTimeout)) return NO; if (!(callOptions.connectMinTimeout == _connectMinTimeout)) return NO; @@ -271,7 +271,7 @@ static const NSUInteger kDefaultChannelID = 0; result ^= _userAgentPrefix.hash; result ^= _responseSizeLimit; result ^= _compressionAlgorithm; - result ^= _enableRetry; + result ^= _retryEnabled; result ^= (unsigned int)(_keepaliveInterval * 1000); result ^= (unsigned int)(_keepaliveTimeout * 1000); result ^= (unsigned int)(_connectMinTimeout * 1000); @@ -302,7 +302,7 @@ static const NSUInteger kDefaultChannelID = 0; @dynamic userAgentPrefix; @dynamic responseSizeLimit; @dynamic compressionAlgorithm; -@dynamic enableRetry; +@dynamic retryEnabled; @dynamic keepaliveInterval; @dynamic keepaliveTimeout; @dynamic connectMinTimeout; @@ -327,7 +327,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit compressionAlgorithm:kDefaultCompressionAlgorithm - enableRetry:kDefaultEnableRetry + retryEnabled:kDefaultRetryEnabled keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout connectMinTimeout:kDefaultConnectMinTimeout @@ -354,7 +354,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - enableRetry:_enableRetry + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -382,7 +382,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - enableRetry:_enableRetry + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -436,8 +436,8 @@ static const NSUInteger kDefaultChannelID = 0; _compressionAlgorithm = compressionAlgorithm; } -- (void)setEnableRetry:(BOOL)enableRetry { - _enableRetry = enableRetry; +- (void)setRetryEnabled:(BOOL)retryEnabled { + _retryEnabled = retryEnabled; } - (void)setKeepaliveInterval:(NSTimeInterval)keepaliveInterval { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 80fa9c9151f..1dfae32342d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -108,8 +108,8 @@ extern const char *kCFStreamVarName; [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.keepaliveTimeout * 1000)]; } - if (_callOptions.enableRetry == NO) { - args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.enableRetry]; + if (_callOptions.retryEnabled == NO) { + args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.retryEnabled]; } if (_callOptions.connectMinTimeout > 0) { diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index c0d75c0f319..38b31c2ebcb 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -103,7 +103,7 @@ static NSMutableDictionary *gHostCache; options.userAgentPrefix = _userAgentPrefix; options.responseSizeLimit = _responseSizeLimitOverride; options.compressionAlgorithm = (GRPCCompressionAlgorithm)_compressAlgorithm; - options.enableRetry = _retryEnabled; + options.retryEnabled = _retryEnabled; options.keepaliveInterval = (NSTimeInterval)_keepaliveInterval / 1000; options.keepaliveTimeout = (NSTimeInterval)_keepaliveTimeout / 1000; options.connectMinTimeout = (NSTimeInterval)_minConnectTimeout / 1000; From 8986cfe6259fe7efc6ad438abb9e904f190c0515 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 10:39:39 -0700 Subject: [PATCH 0136/2143] Assert mutual exclusion of authTokenProvider and oauth2AccessToken --- src/objective-c/GRPCClient/GRPCCall.m | 3 +++ src/objective-c/GRPCClient/GRPCCallOptions.h | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 29a0ed4e106..85a2837336d 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -781,6 +781,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; } _callOptions = callOptions; } + + NSAssert(_callOptions.authTokenProvider != nil || _callOptions.oauth2AccessToken != nil, + @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); if (_callOptions.authTokenProvider != nil) { @synchronized(self) { self.isWaitingForToken = YES; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 4c8bb605eab..27834b20088 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -91,8 +91,8 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The OAuth2 access token string. The string is prefixed with "Bearer " then used as value of the - * request's "authorization" header field. This parameter takes precedence over \a - * oauth2AccessToken. + * request's "authorization" header field. This parameter should not be used simultaneously with + * \a authTokenProvider. */ @property(copy, readonly) NSString *oauth2AccessToken; @@ -245,7 +245,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when - * initiating the call. This parameter takes precedence over \a oauth2AccessToken. + * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. */ @property(readwrite) id authTokenProvider; From 3c8e9886aca311ee2b26e7f7ef827ac7efb42716 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 10:53:11 -0700 Subject: [PATCH 0137/2143] Mark channelArg as copy --- src/objective-c/GRPCClient/private/GRPCChannel.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 60c2e29a6ec..777cbab8092 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -265,7 +265,7 @@ static GRPCChannelPool *gChannelPool; [args addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; channelArgs = args; } else { - channelArgs = [config.channelArgs copy]; + channelArgs = config.channelArgs; } id factory = config.channelFactory; grpc_channel *unmanaged_channel = [factory createChannelWithHost:host channelArgs:channelArgs]; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 43e07b98454..2244361df2c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN @property(readonly) id channelFactory; /** Acquire the dictionary of channel args with current configurations. */ -@property(readonly) NSDictionary *channelArgs; +@property(copy, readonly) NSDictionary *channelArgs; - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; From 647e24c190465e9547583a631ac5b33de98ae812 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 11:31:36 -0700 Subject: [PATCH 0138/2143] Put logContext in class extension --- gRPC.podspec | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 10 ----- src/objective-c/GRPCClient/GRPCCallOptions.m | 1 + .../internal/GRPCCallOptions+internal.h | 37 +++++++++++++++++++ .../GRPCClient/private/GRPCChannelPool.m | 1 + src/objective-c/GRPCClient/private/GRPCHost.m | 1 + templates/gRPC.podspec.template | 2 +- 7 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h diff --git a/gRPC.podspec b/gRPC.podspec index 5e513cb1276..47a130d12d1 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -58,7 +58,7 @@ Pod::Spec.new do |s| ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}" ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}" - ss.private_header_files = "#{src_dir}/private/*.h" + ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/GRPCCallOptions+Internal.h" ss.dependency 'gRPC-Core', version end diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 27834b20088..4f02b344b15 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -182,11 +182,6 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ @property(copy, readonly) NSString *hostNameOverride; -/** - * Parameter used for internal logging. - */ -@property(readonly) id logContext; - /** * A string that specify the domain where channel is being cached. Channels with different domains * will not get cached to the same connection. @@ -331,11 +326,6 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { */ @property(copy, readwrite) NSString *hostNameOverride; -/** - * Parameter used for internal logging. - */ -@property(copy, readwrite) id logContext; - /** * A string that specify the domain where channel is being cached. Channels with different domains * will not get cached to the same channel. For example, a gRPC example app may use the channel pool diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 85a5a9ac89e..cd90bc68933 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -17,6 +17,7 @@ */ #import "GRPCCallOptions.h" +#import "internal/GRPCCallOptions+internal.h" // The default values for the call options. static NSString *const kDefaultServerAuthority = nil; diff --git a/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h b/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h new file mode 100644 index 00000000000..406f268ef21 --- /dev/null +++ b/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h @@ -0,0 +1,37 @@ +/* + * + * 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. + * + */ + +#import + +@interface GRPCCallOptions () + +/** + * Parameter used for internal logging. + */ +@property(readonly) id logContext; + +@end + +@interface GRPCMutableCallOptions () + +/** + * Parameter used for internal logging. + */ +@property(readwrite) id logContext; + +@end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 1dfae32342d..86f76678518 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -26,6 +26,7 @@ #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "version.h" +#import "../internal/GRPCCallOptions+internal.h" #import #include diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 38b31c2ebcb..592e8fe776d 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -32,6 +32,7 @@ #import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" #import "version.h" +#import "../internal/GRPCCallOptions+internal.h" NS_ASSUME_NONNULL_BEGIN diff --git a/templates/gRPC.podspec.template b/templates/gRPC.podspec.template index a3190c2d8e6..a3ed1d78584 100644 --- a/templates/gRPC.podspec.template +++ b/templates/gRPC.podspec.template @@ -60,7 +60,7 @@ ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}" ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}" - ss.private_header_files = "#{src_dir}/private/*.h" + ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/GRPCCallOptions+Internal.h" ss.dependency 'gRPC-Core', version end From 35f6ab959e7f3d05d35aa7baeeeddeba559969f6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 13:10:44 -0700 Subject: [PATCH 0139/2143] unsigned int -> NSUInteger --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 86f76678518..7b800686d01 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -104,9 +104,9 @@ extern const char *kCFStreamVarName; if (_callOptions.keepaliveInterval != 0) { args[@GRPC_ARG_KEEPALIVE_TIME_MS] = - [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.keepaliveInterval * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = - [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.keepaliveTimeout * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; } if (_callOptions.retryEnabled == NO) { @@ -115,15 +115,15 @@ extern const char *kCFStreamVarName; if (_callOptions.connectMinTimeout > 0) { args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = - [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.connectMinTimeout * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMinTimeout * 1000)]; } if (_callOptions.connectInitialBackoff > 0) { args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber - numberWithUnsignedInteger:(unsigned int)(_callOptions.connectInitialBackoff * 1000)]; + numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectInitialBackoff * 1000)]; } if (_callOptions.connectMaxBackoff > 0) { args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = - [NSNumber numberWithUnsignedInteger:(unsigned int)(_callOptions.connectMaxBackoff * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMaxBackoff * 1000)]; } if (_callOptions.logContext != nil) { From cc58524994eddfbbc7cd800efe1462a7ec28d4f0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 13:11:06 -0700 Subject: [PATCH 0140/2143] isChannelOptionsEqualTo->hasChannelOptionsEqualTo --- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 4f02b344b15..9683bd3c638 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -199,7 +199,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { /** * Return if the channel options are equal to another object. */ -- (BOOL)isChannelOptionsEqualTo:(GRPCCallOptions *)callOptions; +- (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions; /** * Hash for channel options. diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index cd90bc68933..ba3255f0e4f 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -229,7 +229,7 @@ static const NSUInteger kDefaultChannelID = 0; return newOptions; } -- (BOOL)isChannelOptionsEqualTo:(GRPCCallOptions *)callOptions { +- (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions { if (!(callOptions.userAgentPrefix == _userAgentPrefix || [callOptions.userAgentPrefix isEqualToString:_userAgentPrefix])) return NO; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 7b800686d01..61f5a55077a 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -150,7 +150,7 @@ extern const char *kCFStreamVarName; NSAssert([object isKindOfClass:[GRPCChannelConfiguration class]], @"Illegal :isEqual"); GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; if (!(obj.host == _host || [obj.host isEqualToString:_host])) return NO; - if (!(obj.callOptions == _callOptions || [obj.callOptions isChannelOptionsEqualTo:_callOptions])) + if (!(obj.callOptions == _callOptions || [obj.callOptions hasChannelOptionsEqualTo:_callOptions])) return NO; return YES; From 26108e1106cffd1767f0b7fb6ff4b0672ed6a640 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Oct 2018 13:14:24 -0700 Subject: [PATCH 0141/2143] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 18 +++++++------ src/objective-c/GRPCClient/GRPCCallOptions.m | 10 +++---- .../GRPCClient/private/GRPCChannelPool.m | 2 +- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.h | 4 +-- src/objective-c/ProtoRPC/ProtoRPC.m | 26 ++++++++++--------- 6 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 85d0a302d17..a1f139fc186 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -156,9 +156,9 @@ extern NSString *const kGRPCTrailersKey; @optional /** - * Issued when initial metadata is received from the server. The task must be scheduled onto the - * dispatch queue in property \a dispatchQueue. - */ + * Issued when initial metadata is received from the server. The task must be scheduled onto the + * dispatch queue in property \a dispatchQueue. + */ - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; /** @@ -309,7 +309,7 @@ NS_ASSUME_NONNULL_END * * The property is initialized to an empty NSMutableDictionary. */ -@property(null_unspecified, atomic, readonly) NSMutableDictionary * requestHeaders; +@property(null_unspecified, atomic, readonly) NSMutableDictionary *requestHeaders; /** * This dictionary is populated with the HTTP headers received from the server. This happens before @@ -342,9 +342,9 @@ NS_ASSUME_NONNULL_END * host parameter should not contain the scheme (http:// or https://), only the name or IP addr * and the port number, for example @"localhost:5050". */ -- (instancetype _Null_unspecified)initWithHost:(NSString * _Null_unspecified)host - path:(NSString * _Null_unspecified)path - requestsWriter:(GRXWriter * _Null_unspecified)requestWriter; +- (instancetype _Null_unspecified)initWithHost:(NSString *_Null_unspecified)host + path:(NSString *_Null_unspecified)path + requestsWriter:(GRXWriter *_Null_unspecified)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -355,7 +355,9 @@ NS_ASSUME_NONNULL_END /** * The following methods are deprecated. */ -+ (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString * _Null_unspecified)host path:(NSString * _Null_unspecified)path; ++ (void)setCallSafety:(GRPCCallSafety)callSafety + host:(NSString *_Null_unspecified)host + path:(NSString *_Null_unspecified)path; @property(null_unspecified, atomic, copy, readwrite) NSString *serverName; @property NSTimeInterval timeout; - (void)setResponseDispatchQueue:(dispatch_queue_t _Null_unspecified)queue; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index ba3255f0e4f..0977a4ccdbc 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -183,7 +183,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - retryEnabled:_retryEnabled + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -211,7 +211,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - retryEnabled:_retryEnabled + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -328,7 +328,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:kDefaultUserAgentPrefix responseSizeLimit:kDefaultResponseSizeLimit compressionAlgorithm:kDefaultCompressionAlgorithm - retryEnabled:kDefaultRetryEnabled + retryEnabled:kDefaultRetryEnabled keepaliveInterval:kDefaultKeepaliveInterval keepaliveTimeout:kDefaultKeepaliveTimeout connectMinTimeout:kDefaultConnectMinTimeout @@ -355,7 +355,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - retryEnabled:_retryEnabled + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout @@ -383,7 +383,7 @@ static const NSUInteger kDefaultChannelID = 0; userAgentPrefix:_userAgentPrefix responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm - retryEnabled:_retryEnabled + retryEnabled:_retryEnabled keepaliveInterval:_keepaliveInterval keepaliveTimeout:_keepaliveTimeout connectMinTimeout:_connectMinTimeout diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 61f5a55077a..56f76450b22 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -18,6 +18,7 @@ #import +#import "../internal/GRPCCallOptions+internal.h" #import "GRPCChannel.h" #import "GRPCChannelFactory.h" #import "GRPCChannelPool.h" @@ -26,7 +27,6 @@ #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "version.h" -#import "../internal/GRPCCallOptions+internal.h" #import #include diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 592e8fe776d..ab5b69cc4e9 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -25,6 +25,7 @@ #include #include +#import "../internal/GRPCCallOptions+internal.h" #import "GRPCChannelFactory.h" #import "GRPCCompletionQueue.h" #import "GRPCConnectivityMonitor.h" @@ -32,7 +33,6 @@ #import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" #import "version.h" -#import "../internal/GRPCCallOptions+internal.h" NS_ASSUME_NONNULL_BEGIN diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 6f4b9eed759..635ba0c90ee 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -31,8 +31,8 @@ NS_ASSUME_NONNULL_BEGIN @optional /** - * Issued when initial metadata is received from the server. The task must be scheduled onto the - * dispatch queue in property \a dispatchQueue. */ + * Issued when initial metadata is received from the server. The task must be scheduled onto the + * dispatch queue in property \a dispatchQueue. */ - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; /** diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 27070a891d5..34891e8953b 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -28,19 +28,19 @@ #import /** - * Generate an NSError object that represents a failure in parsing a proto class. - */ + * Generate an NSError object that represents a failure in parsing a proto class. + */ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsingError) { NSDictionary *info = @{ - NSLocalizedDescriptionKey : @"Unable to parse response from the server", - NSLocalizedRecoverySuggestionErrorKey : - @"If this RPC is idempotent, retry " - @"with exponential backoff. Otherwise, query the server status before " - @"retrying.", - NSUnderlyingErrorKey : parsingError, - @"Expected class" : expectedClass, - @"Received value" : proto, - }; + NSLocalizedDescriptionKey : @"Unable to parse response from the server", + NSLocalizedRecoverySuggestionErrorKey : + @"If this RPC is idempotent, retry " + @"with exponential backoff. Otherwise, query the server status before " + @"retrying.", + NSUnderlyingErrorKey : parsingError, + @"Expected class" : expectedClass, + @"Received value" : proto, + }; // TODO(jcanizales): Use kGRPCErrorDomain and GRPCErrorCodeInternal when they're public. return [NSError errorWithDomain:@"io.grpc" code:13 userInfo:info]; } @@ -190,7 +190,9 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } } else { if ([self->_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [self->_handler closedWithTrailingMetadata:nil error:ErrorForBadProto(message, _responseClass, error)]; + [self->_handler + closedWithTrailingMetadata:nil + error:ErrorForBadProto(message, _responseClass, error)]; } self->_handler = nil; [self->_call cancel]; From c62c3b920c4df9c52a51d3941814317ce8acc483 Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Tue, 23 Oct 2018 16:50:31 -0700 Subject: [PATCH 0142/2143] 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 0143/2143] 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 1cbb484729706cf89b140b8a746562a53d916e8b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 24 Oct 2018 10:45:07 -0700 Subject: [PATCH 0144/2143] Fix build failure --- .../GRPCClient/internal/GRPCCallOptions+internal.h | 2 ++ .../GRPCClient/private/GRPCCronetChannelFactory.m | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h b/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h index 406f268ef21..eb691b3acb1 100644 --- a/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h +++ b/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h @@ -18,6 +18,8 @@ #import +#import "../GRPCCallOptions.h" + @interface GRPCCallOptions () /** diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 70675784678..f976e1e06a9 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -53,14 +53,14 @@ NS_ASSUME_NONNULL_BEGIN } - (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args { + channelArgs:(NSDictionary *)args { // Remove client authority filter since that is not supported args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1]; - grpc_channel_args *channelArgs = BuildChannelArgs(args); + grpc_channel_args *channelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_cronet_secure_channel_create(_cronetEngine, host.UTF8String, channelArgs, NULL); - FreeChannelArgs(channelArgs); + GRPCFreeChannelArgs(channelArgs); return unmanagedChannel; } From 3c33020357e58202a9909d739353f4c20f78e817 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 24 Oct 2018 13:31:45 -0700 Subject: [PATCH 0145/2143] Polish nullabitily --- .../GRPCClient/private/GRPCChannelFactory.h | 4 ++-- .../private/GRPCCronetChannelFactory.h | 8 ++++---- .../private/GRPCCronetChannelFactory.m | 14 +++++++------- .../private/GRPCInsecureChannelFactory.h | 8 ++++---- .../private/GRPCInsecureChannelFactory.m | 6 +++--- .../private/GRPCSecureChannelFactory.h | 12 ++++++------ .../private/GRPCSecureChannelFactory.m | 18 +++++++++--------- 7 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h index a934e966e9d..287233f246c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -26,8 +26,8 @@ NS_ASSUME_NONNULL_BEGIN @protocol GRPCChannelFactory /** Create a channel with specific channel args to a specific host. */ -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args; +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args; @end diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h index 738dfdb7370..18e84b81fa2 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h @@ -24,12 +24,12 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCCronetChannelFactory : NSObject -+ (nullable instancetype)sharedInstance; ++ (instancetype _Nullable)sharedInstance; -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args; +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args; -- (nullable instancetype)init NS_UNAVAILABLE; +- (instancetype _Nullable)init NS_UNAVAILABLE; @end diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index f976e1e06a9..b2ab03b6488 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -32,7 +32,7 @@ NS_ASSUME_NONNULL_BEGIN stream_engine *_cronetEngine; } -+ (nullable instancetype)sharedInstance { ++ (instancetype _Nullable)sharedInstance { static GRPCCronetChannelFactory *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -41,7 +41,7 @@ NS_ASSUME_NONNULL_BEGIN return instance; } -- (nullable instancetype)initWithEngine:(stream_engine *)engine { +- (instancetype _Nullable)initWithEngine:(stream_engine *)engine { if (!engine) { [NSException raise:NSInvalidArgumentException format:@"Cronet engine is NULL. Set it first."]; return nil; @@ -52,8 +52,8 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)args { +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args { // Remove client authority filter since that is not supported args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1]; @@ -74,14 +74,14 @@ NS_ASSUME_NONNULL_BEGIN @implementation GRPCCronetChannelFactory -+ (nullable instancetype)sharedInstance { ++ (instancetype _Nullable)sharedInstance { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return nil; } -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args { +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return NULL; diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h index 2d471aebed6..1175483c680 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h @@ -23,12 +23,12 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCInsecureChannelFactory : NSObject -+ (nullable instancetype)sharedInstance; ++ (instancetype _Nullable)sharedInstance; -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args; +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args; -- (nullable instancetype)init NS_UNAVAILABLE; +- (instancetype _Nullable)init NS_UNAVAILABLE; @end diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index 5773f2d9af1..44e94831e95 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN @implementation GRPCInsecureChannelFactory -+ (nullable instancetype)sharedInstance { ++ (instancetype _Nullable)sharedInstance { static GRPCInsecureChannelFactory *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -34,8 +34,8 @@ NS_ASSUME_NONNULL_BEGIN return instance; } -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args { +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h index 588239b7064..565f58a4fab 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -23,15 +23,15 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCSecureChannelFactory : NSObject -+ (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts - privateKey:(nullable NSString *)privateKey - certChain:(nullable NSString *)certChain ++ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString * _Nullable)rootCerts + privateKey:(NSString * _Nullable)privateKey + certChain:(NSString * _Nullable)certChain error:(NSError **)errorPtr; -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args; +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args; -- (nullable instancetype)init NS_UNAVAILABLE; +- (instancetype _Nullable)init NS_UNAVAILABLE; @end diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index aa8b52e6b8f..03cfff2ed4a 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -29,9 +29,9 @@ NS_ASSUME_NONNULL_BEGIN grpc_channel_credentials *_channelCreds; } -+ (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts - privateKey:(nullable NSString *)privateKey - certChain:(nullable NSString *)certChain ++ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString * _Nullable)rootCerts + privateKey:(NSString * _Nullable)privateKey + certChain:(NSString * _Nullable)certChain error:(NSError **)errorPtr { return [[self alloc] initWithPEMRootCerts:rootCerts privateKey:privateKey @@ -39,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN error:errorPtr]; } -- (NSData *)nullTerminatedDataWithString:(NSString *)string { +- (NSData * _Nullable)nullTerminatedDataWithString:(NSString * _Nullable)string { // dataUsingEncoding: does not return a null-terminated string. NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; if (data == nil) { @@ -50,9 +50,9 @@ NS_ASSUME_NONNULL_BEGIN return nullTerminated; } -- (nullable instancetype)initWithPEMRootCerts:(nullable NSString *)rootCerts - privateKey:(nullable NSString *)privateKey - certChain:(nullable NSString *)certChain +- (instancetype _Nullable)initWithPEMRootCerts:(NSString * _Nullable)rootCerts + privateKey:(NSString * _Nullable)privateKey + certChain:(NSString * _Nullable)certChain error:(NSError **)errorPtr { static NSData *defaultRootsASCII; static NSError *defaultRootsError; @@ -116,8 +116,8 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (nullable grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(nullable NSDictionary *)args { +- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary * _Nullable)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); From c2bb7550377898e6985662d0ca9048c07bde6810 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 24 Oct 2018 16:55:23 -0700 Subject: [PATCH 0146/2143] Move GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER into core --- .../cronet/client/secure/cronet_channel_create.cc | 14 ++++++++++++-- .../GRPCClient/private/GRPCCronetChannelFactory.m | 3 --- .../GRPCClient/private/GRPCWrappedCall.m | 4 +++- .../CoreCronetEnd2EndTests.mm | 6 ------ .../tests/CronetUnitTests/CronetUnitTests.m | 13 +------------ 5 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc index 40a30e4a31d..dffb61b082d 100644 --- a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc +++ b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc @@ -46,9 +46,19 @@ GRPCAPI grpc_channel* grpc_cronet_secure_channel_create( "grpc_create_cronet_transport: stream_engine = %p, target=%s", engine, target); + // Disable client authority filter when using Cronet + grpc_arg arg; + arg.key = const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); + arg.type = GRPC_ARG_INTEGER; + arg.value.integer = 1; + grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args, &arg, 1); + grpc_transport* ct = - grpc_create_cronet_transport(engine, target, args, reserved); + grpc_create_cronet_transport(engine, target, new_args, reserved); grpc_core::ExecCtx exec_ctx; - return grpc_channel_create(target, args, GRPC_CLIENT_DIRECT_CHANNEL, ct); + grpc_channel* channel = + grpc_channel_create(target, new_args, GRPC_CLIENT_DIRECT_CHANNEL, ct); + grpc_channel_args_destroy(new_args); + return channel; } diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index b2ab03b6488..51d8df0fb71 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -54,9 +54,6 @@ NS_ASSUME_NONNULL_BEGIN - (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary * _Nullable)args { - // Remove client authority filter since that is not supported - args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1]; - grpc_channel_args *channelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_cronet_secure_channel_create(_cronetEngine, host.UTF8String, channelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 4d5257aca79..100d4cf2914 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -310,7 +310,9 @@ } - (void)dealloc { - grpc_call_unref(_call); + if (_call) { + grpc_call_unref(_call); + } [_channel unref]; _channel = nil; } diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm index 80fa0f47852..fe85e915d4d 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm @@ -81,13 +81,7 @@ static void cronet_init_client_secure_fullstack(grpc_end2end_test_fixture *f, grpc_channel_args *client_args, stream_engine *cronetEngine) { fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; - grpc_arg arg; - arg.key = const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); - arg.type = GRPC_ARG_INTEGER; - arg.value.integer = 1; - client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1); f->client = grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL); - grpc_channel_args_destroy(client_args); GPR_ASSERT(f->client != NULL); } diff --git a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m index 84893b92c1a..d732bc6ba99 100644 --- a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m +++ b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m @@ -124,14 +124,6 @@ unsigned int parse_h2_length(const char *field) { ((unsigned int)(unsigned char)(field[2])); } -grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *args) { - grpc_arg arg; - arg.key = const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); - arg.type = GRPC_ARG_INTEGER; - arg.value.integer = 1; - return grpc_channel_args_copy_and_add(args, &arg, 1); -} - - (void)testInternalError { grpc_call *c; grpc_slice request_payload_slice = grpc_slice_from_copied_string("hello world"); @@ -151,9 +143,7 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a gpr_join_host_port(&addr, "127.0.0.1", port); grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL); stream_engine *cronetEngine = [Cronet getGlobalEngine]; - grpc_channel_args *client_args = add_disable_client_authority_filter_args(NULL); - grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, client_args, NULL); - grpc_channel_args_destroy(client_args); + grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, NULL, NULL); cq_verifier *cqv = cq_verifier_create(cq); grpc_op ops[6]; @@ -265,7 +255,6 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a arg.type = GRPC_ARG_INTEGER; arg.value.integer = useCoalescing ? 1 : 0; grpc_channel_args *args = grpc_channel_args_copy_and_add(NULL, &arg, 1); - args = add_disable_client_authority_filter_args(args); grpc_call *c; grpc_slice request_payload_slice = grpc_slice_from_copied_string("hello world"); From a8a7c2bdd10eb7dc9e072327da2ddb70e5785cf7 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 24 Oct 2018 17:05:38 -0700 Subject: [PATCH 0147/2143] clang-format --- .../GRPCClient/private/GRPCChannelFactory.h | 4 ++-- .../private/GRPCCronetChannelFactory.h | 4 ++-- .../private/GRPCCronetChannelFactory.m | 8 +++---- .../private/GRPCInsecureChannelFactory.h | 4 ++-- .../private/GRPCInsecureChannelFactory.m | 4 ++-- .../private/GRPCSecureChannelFactory.h | 12 +++++----- .../private/GRPCSecureChannelFactory.m | 22 +++++++++---------- 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h index 287233f246c..3a3500fc95e 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -26,8 +26,8 @@ NS_ASSUME_NONNULL_BEGIN @protocol GRPCChannelFactory /** Create a channel with specific channel args to a specific host. */ -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args; +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args; @end diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h index 18e84b81fa2..5e35576ea10 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h @@ -26,8 +26,8 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype _Nullable)sharedInstance; -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args; +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args; - (instancetype _Nullable)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 51d8df0fb71..781881d211b 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -52,8 +52,8 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args { +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args { grpc_channel_args *channelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_cronet_secure_channel_create(_cronetEngine, host.UTF8String, channelArgs, NULL); @@ -77,8 +77,8 @@ NS_ASSUME_NONNULL_BEGIN return nil; } -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args { +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return NULL; diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h index 1175483c680..98a985fe84d 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h @@ -25,8 +25,8 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype _Nullable)sharedInstance; -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args; +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args; - (instancetype _Nullable)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index 44e94831e95..99698877124 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -34,8 +34,8 @@ NS_ASSUME_NONNULL_BEGIN return instance; } -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args { +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h index 565f58a4fab..02e7052996d 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -23,13 +23,13 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCSecureChannelFactory : NSObject -+ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString * _Nullable)rootCerts - privateKey:(NSString * _Nullable)privateKey - certChain:(NSString * _Nullable)certChain - error:(NSError **)errorPtr; ++ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString *_Nullable)rootCerts + privateKey:(NSString *_Nullable)privateKey + certChain:(NSString *_Nullable)certChain + error:(NSError **)errorPtr; -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args; +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args; - (instancetype _Nullable)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 03cfff2ed4a..1f6458c5247 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -29,17 +29,17 @@ NS_ASSUME_NONNULL_BEGIN grpc_channel_credentials *_channelCreds; } -+ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString * _Nullable)rootCerts - privateKey:(NSString * _Nullable)privateKey - certChain:(NSString * _Nullable)certChain - error:(NSError **)errorPtr { ++ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString *_Nullable)rootCerts + privateKey:(NSString *_Nullable)privateKey + certChain:(NSString *_Nullable)certChain + error:(NSError **)errorPtr { return [[self alloc] initWithPEMRootCerts:rootCerts privateKey:privateKey certChain:certChain error:errorPtr]; } -- (NSData * _Nullable)nullTerminatedDataWithString:(NSString * _Nullable)string { +- (NSData *_Nullable)nullTerminatedDataWithString:(NSString *_Nullable)string { // dataUsingEncoding: does not return a null-terminated string. NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; if (data == nil) { @@ -50,10 +50,10 @@ NS_ASSUME_NONNULL_BEGIN return nullTerminated; } -- (instancetype _Nullable)initWithPEMRootCerts:(NSString * _Nullable)rootCerts - privateKey:(NSString * _Nullable)privateKey - certChain:(NSString * _Nullable)certChain - error:(NSError **)errorPtr { +- (instancetype _Nullable)initWithPEMRootCerts:(NSString *_Nullable)rootCerts + privateKey:(NSString *_Nullable)privateKey + certChain:(NSString *_Nullable)certChain + error:(NSError **)errorPtr { static NSData *defaultRootsASCII; static NSError *defaultRootsError; static dispatch_once_t loading; @@ -116,8 +116,8 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (grpc_channel * _Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary * _Nullable)args { +- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *_Nullable)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); From 2808bd0ba05fa3ddc0b6ef814db09c435e4e9676 Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Thu, 25 Oct 2018 15:47:13 -0700 Subject: [PATCH 0148/2143] 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 0149/2143] 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 f9d2510d8f655badea3dea14493b6d4d3882705a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 26 Oct 2018 11:15:16 -0700 Subject: [PATCH 0150/2143] Specify nullability in ProtoRPC --- src/objective-c/ProtoRPC/ProtoRPC.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 635ba0c90ee..b0f4ced99e8 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -134,10 +134,11 @@ __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC * addr and the port number, for example @"localhost:5050". */ - - (instancetype)initWithHost : (NSString *)host method - : (GRPCProtoMethod *)method requestsWriter : (GRXWriter *)requestsWriter responseClass - : (Class)responseClass responsesWriteable - : (id)responsesWriteable NS_DESIGNATED_INITIALIZER; + (instancetype _Null_unspecified)initWithHost : (NSString *_Null_unspecified)host method + : (GRPCProtoMethod *_Null_unspecified)method requestsWriter + : (GRXWriter *_Null_unspecified)requestsWriter responseClass + : (Class _Null_unspecified)responseClass responsesWriteable + : (id _Null_unspecified)responsesWriteable NS_DESIGNATED_INITIALIZER; - (void)start; @end From a8c4eb7d2742eb3ba370d9801cc1b83e35d551a9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 29 Oct 2018 14:15:26 -0700 Subject: [PATCH 0151/2143] Bug fix --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 85a2837336d..44432a120ac 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -782,7 +782,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = callOptions; } - NSAssert(_callOptions.authTokenProvider != nil || _callOptions.oauth2AccessToken != nil, + NSAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); if (_callOptions.authTokenProvider != nil) { @synchronized(self) { From abe4aae40049ca73fb29ccf325cc3734408d9aae Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 29 Oct 2018 15:21:05 -0700 Subject: [PATCH 0152/2143] Remove length check in GRPCCall for backwards compatibility --- src/objective-c/GRPCClient/GRPCCall.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 44432a120ac..ca2cdd6b312 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -391,7 +391,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; callSafety:(GRPCCallSafety)safety requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { - if (host.length == 0 || path.length == 0) { + // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. + if (!host || !path) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil or empty."]; } From aec84416a4308e547736569f2bc815a8bbd9c80f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 29 Oct 2018 15:48:16 -0700 Subject: [PATCH 0153/2143] Remove NS_UNAVAILABLE for backwards compatibility --- src/objective-c/ProtoRPC/ProtoService.h | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index 3a16ab24026..2105de78a38 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -31,14 +31,9 @@ __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoServ : NSObject - - (instancetype)init NS_UNAVAILABLE; - -+ (instancetype) new NS_UNAVAILABLE; - -- (instancetype)initWithHost:(NSString *)host - packageName:(NSString *)packageName - serviceName:(NSString *)serviceName - callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; + (instancetype)initWithHost : (NSString *)host packageName + : (NSString *)packageName serviceName : (NSString *)serviceName callOptions + : (GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName From 40750ef4846847648a964d62a6cd1c87eff2f959 Mon Sep 17 00:00:00 2001 From: Daniel Joos Date: Mon, 29 Oct 2018 17:26:20 +0100 Subject: [PATCH 0154/2143] Enable compilation with OpenSSL 1.1 API This adds the possibility to compile the core library against OpenSSL 1.1 without backwards-compatible/deprecated API enabled. It also adds missing include statements in `jwt_verifier.cc` that are required to build with OpenSSL 1.1 (as the `BN_` and `RSA_` APIs are used there). --- .../lib/security/credentials/jwt/jwt_verifier.cc | 2 ++ src/core/tsi/ssl_transport_security.cc | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.cc b/src/core/lib/security/credentials/jwt/jwt_verifier.cc index c7d1b36ff0a..cdef0f322a9 100644 --- a/src/core/lib/security/credentials/jwt/jwt_verifier.cc +++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc @@ -31,7 +31,9 @@ #include extern "C" { +#include #include +#include } #include "src/core/lib/gpr/string.h" diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index d6a72ada0d8..9243d845cb3 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -156,9 +156,13 @@ static unsigned long openssl_thread_id_cb(void) { #endif static void init_openssl(void) { +#if OPENSSL_API_COMPAT >= 0x10100000L + OPENSSL_init_ssl(0, NULL); +#else SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); +#endif #if OPENSSL_VERSION_NUMBER < 0x10100000 if (!CRYPTO_get_locking_callback()) { int num_locks = CRYPTO_num_locks(); @@ -1649,7 +1653,11 @@ tsi_result tsi_create_ssl_client_handshaker_factory_with_options( return TSI_INVALID_ARGUMENT; } +#if defined(OPENSSL_NO_TLS1_2_METHOD) || OPENSSL_API_COMPAT >= 0x10100000L + ssl_context = SSL_CTX_new(TLS_method()); +#else ssl_context = SSL_CTX_new(TLSv1_2_method()); +#endif if (ssl_context == nullptr) { gpr_log(GPR_ERROR, "Could not create ssl context."); return TSI_INVALID_ARGUMENT; @@ -1806,7 +1814,11 @@ tsi_result tsi_create_ssl_server_handshaker_factory_with_options( for (i = 0; i < options->num_key_cert_pairs; i++) { do { +#if defined(OPENSSL_NO_TLS1_2_METHOD) || OPENSSL_API_COMPAT >= 0x10100000L + impl->ssl_contexts[i] = SSL_CTX_new(TLS_method()); +#else impl->ssl_contexts[i] = SSL_CTX_new(TLSv1_2_method()); +#endif if (impl->ssl_contexts[i] == nullptr) { gpr_log(GPR_ERROR, "Could not create ssl context."); result = TSI_OUT_OF_RESOURCES; From 0cabf27fa3e5afc4918a6aaf7d51825d7c0eb8e0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 31 Oct 2018 18:25:49 -0700 Subject: [PATCH 0155/2143] Clean codes --- src/objective-c/GRPCClient/GRPCCall.m | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index ca2cdd6b312..505d84a954c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -167,13 +167,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(id value) { dispatch_async(self->_dispatchQueue, ^{ if (self->_handler) { - NSDictionary *headers = nil; if (!self->_initialMetadataPublished) { - headers = self->_call.responseHeaders; self->_initialMetadataPublished = YES; - } - if (headers) { - [self issueInitialMetadata:headers]; + [self issueInitialMetadata:self->_call.responseHeaders]; } if (value) { [self issueMessage:value]; @@ -184,13 +180,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; completionHandler:^(NSError *errorOrNil) { dispatch_async(self->_dispatchQueue, ^{ if (self->_handler) { - NSDictionary *headers = nil; if (!self->_initialMetadataPublished) { - headers = self->_call.responseHeaders; self->_initialMetadataPublished = YES; - } - if (headers) { - [self issueInitialMetadata:headers]; + [self issueInitialMetadata:self->_call.responseHeaders]; } [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; From a37ec5e3e6f7184458108bd5419ce6b832061975 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 31 Oct 2018 18:26:02 -0700 Subject: [PATCH 0156/2143] Polish error message --- src/objective-c/GRPCClient/GRPCCall.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 505d84a954c..5aeedba9a7d 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -385,8 +385,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. if (!host || !path) { - [NSException raise:NSInvalidArgumentException - format:@"Neither host nor path can be nil or empty."]; + [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; } if (safety > GRPCCallSafetyCacheableRequest) { [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; From 16fd5a758c2418dcf0be3a0985e68b1e15582387 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 31 Oct 2018 18:26:39 -0700 Subject: [PATCH 0157/2143] Remove __block for synchronized blocks --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 5aeedba9a7d..8e7d5a5f94b 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -564,7 +564,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } NSMutableDictionary *headers = _requestHeaders; - __block NSString *fetchedOauth2AccessToken; + NSString *fetchedOauth2AccessToken; @synchronized(self) { fetchedOauth2AccessToken = _fetchedOauth2AccessToken; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 56f76450b22..7aac077e773 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -190,7 +190,7 @@ extern const char *kCFStreamVarName; } - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration { - __block GRPCChannel *channel; + GRPCChannel *channel; @synchronized(self) { if ([_channelPool objectForKey:configuration]) { channel = _channelPool[configuration]; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index ab5b69cc4e9..480e4621845 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -141,7 +141,7 @@ static NSMutableDictionary *gHostCache; host = [hostURL.host stringByAppendingString:@":443"]; } - __block GRPCCallOptions *callOptions = nil; + GRPCCallOptions *callOptions = nil; @synchronized(gHostCache) { if ([gHostCache objectForKey:host]) { callOptions = [gHostCache[host] callOptions]; From 73251477bc4f7cb10bf40c9f56df8a65d58689f1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 09:03:23 -0700 Subject: [PATCH 0158/2143] clamp positive NSTimeInterval in initializer --- src/objective-c/GRPCClient/GRPCCallOptions.m | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 0977a4ccdbc..8bb2ad29fc6 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -146,7 +146,7 @@ static const NSUInteger kDefaultChannelID = 0; channelID:(NSUInteger)channelID { if ((self = [super init])) { _serverAuthority = [serverAuthority copy]; - _timeout = timeout; + _timeout = timeout < 0 ? 0 : timeout; _oauth2AccessToken = [oauth2AccessToken copy]; _authTokenProvider = authTokenProvider; _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; @@ -154,11 +154,11 @@ static const NSUInteger kDefaultChannelID = 0; _responseSizeLimit = responseSizeLimit; _compressionAlgorithm = compressionAlgorithm; _retryEnabled = retryEnabled; - _keepaliveInterval = keepaliveInterval; - _keepaliveTimeout = keepaliveTimeout; - _connectMinTimeout = connectMinTimeout; - _connectInitialBackoff = connectInitialBackoff; - _connectMaxBackoff = connectMaxBackoff; + _keepaliveInterval = keepaliveInterval < 0 ? 0 : keepaliveInterval; + _keepaliveTimeout = keepaliveTimeout < 0 ? 0 : keepaliveTimeout; + _connectMinTimeout = connectMinTimeout < 0 ? 0 : connectMinTimeout; + _connectInitialBackoff = connectInitialBackoff < 0 ? 0 : connectInitialBackoff; + _connectMaxBackoff = connectMaxBackoff < 0 ? 0 : connectMaxBackoff; _additionalChannelArgs = [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; _PEMRootCertificates = [PEMRootCertificates copy]; From 790adca8e397d78affef7589e1ddf94b80b052f1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 09:18:50 -0700 Subject: [PATCH 0159/2143] copy items in GRPCCallOptions:mutableCopy: --- src/objective-c/GRPCClient/GRPCCallOptions.m | 22 +++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 8bb2ad29fc6..c7096cf1cfb 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -203,12 +203,13 @@ static const NSUInteger kDefaultChannelID = 0; - (nonnull id)mutableCopyWithZone:(NSZone *)zone { GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] - initWithServerAuthority:_serverAuthority + initWithServerAuthority:[_serverAuthority copy] timeout:_timeout - oauth2AccessToken:_oauth2AccessToken + oauth2AccessToken:[_oauth2AccessToken copy] authTokenProvider:_authTokenProvider - initialMetadata:_initialMetadata - userAgentPrefix:_userAgentPrefix + initialMetadata:[[NSDictionary alloc] initWithDictionary:_initialMetadata + copyItems:YES] + userAgentPrefix:[_userAgentPrefix copy] responseSizeLimit:_responseSizeLimit compressionAlgorithm:_compressionAlgorithm retryEnabled:_retryEnabled @@ -217,14 +218,15 @@ static const NSUInteger kDefaultChannelID = 0; connectMinTimeout:_connectMinTimeout connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff - additionalChannelArgs:[_additionalChannelArgs copy] - PEMRootCertificates:_PEMRootCertificates - PEMPrivateKey:_PEMPrivateKey - PEMCertChain:_PEMCertChain + additionalChannelArgs:[[NSDictionary alloc] initWithDictionary:_additionalChannelArgs + copyItems:YES] + PEMRootCertificates:[_PEMRootCertificates copy] + PEMPrivateKey:[_PEMPrivateKey copy] + PEMCertChain:[_PEMCertChain copy] transportType:_transportType - hostNameOverride:_hostNameOverride + hostNameOverride:[_hostNameOverride copy] logContext:_logContext - channelPoolDomain:_channelPoolDomain + channelPoolDomain:[_channelPoolDomain copy] channelID:_channelID]; return newOptions; } From ce53ba74746248ef914986bc5fe8a2f89f42ceda Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 09:27:40 -0700 Subject: [PATCH 0160/2143] kChannelDestroyDelay->_destroyDelay in GRPCChannelRef --- src/objective-c/GRPCClient/private/GRPCChannel.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 777cbab8092..67a3ac12749 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -109,7 +109,7 @@ static GRPCChannelPool *gChannelPool; if (self->_refCount == 0) { self->_lastDispatch = [NSDate date]; dispatch_time_t delay = - dispatch_time(DISPATCH_TIME_NOW, (int64_t)kChannelDestroyDelay * 1e9); + dispatch_time(DISPATCH_TIME_NOW, (int64_t)_destroyDelay * 1e9); dispatch_after(delay, self->_timerQueue, ^{ [self timerFire]; }); @@ -132,7 +132,7 @@ static GRPCChannelPool *gChannelPool; - (void)timerFire { dispatch_async(_dispatchQueue, ^{ if (self->_disconnected || self->_lastDispatch == nil || - -[self->_lastDispatch timeIntervalSinceNow] < -kChannelDestroyDelay) { + -[self->_lastDispatch timeIntervalSinceNow] < -_destroyDelay) { return; } self->_lastDispatch = nil; From dc4fc1ce38f9060c10ae639173d106c5a7d2bece Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 09:29:15 -0700 Subject: [PATCH 0161/2143] Use NSEC_PER_SEC --- src/objective-c/GRPCClient/private/GRPCChannel.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 67a3ac12749..377900fd9e1 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -109,7 +109,7 @@ static GRPCChannelPool *gChannelPool; if (self->_refCount == 0) { self->_lastDispatch = [NSDate date]; dispatch_time_t delay = - dispatch_time(DISPATCH_TIME_NOW, (int64_t)_destroyDelay * 1e9); + dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); dispatch_after(delay, self->_timerQueue, ^{ [self timerFire]; }); @@ -132,7 +132,7 @@ static GRPCChannelPool *gChannelPool; - (void)timerFire { dispatch_async(_dispatchQueue, ^{ if (self->_disconnected || self->_lastDispatch == nil || - -[self->_lastDispatch timeIntervalSinceNow] < -_destroyDelay) { + -[self->_lastDispatch timeIntervalSinceNow] < -self->_destroyDelay) { return; } self->_lastDispatch = nil; From 601475b57105f0aff3e96043e6399b621cfc5b84 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 11:43:09 -0700 Subject: [PATCH 0162/2143] Easier check if timer is canceled --- src/objective-c/GRPCClient/private/GRPCChannel.m | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 377900fd9e1..1d7fb421e5e 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -66,6 +66,12 @@ static GRPCChannelPool *gChannelPool; BOOL _disconnected; dispatch_queue_t _dispatchQueue; dispatch_queue_t _timerQueue; + + /** + * Date and time when last timer is scheduled. When a timer is fired, if + * _lastDispatch + _destroyDelay < now, it can be determined that another timer is scheduled after + * schedule of the current timer, hence the current one should be discarded. + */ NSDate *_lastDispatch; } @@ -107,11 +113,12 @@ static GRPCChannelPool *gChannelPool; if (!self->_disconnected) { self->_refCount--; if (self->_refCount == 0) { - self->_lastDispatch = [NSDate date]; + NSDate *now = [NSDate date]; + self->_lastDispatch = now; dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); dispatch_after(delay, self->_timerQueue, ^{ - [self timerFire]; + [self timerFireWithScheduleDate:now]; }); } } @@ -129,10 +136,9 @@ static GRPCChannelPool *gChannelPool; }); } -- (void)timerFire { +- (void)timerFireWithScheduleDate:(NSDate *)scheduleDate { dispatch_async(_dispatchQueue, ^{ - if (self->_disconnected || self->_lastDispatch == nil || - -[self->_lastDispatch timeIntervalSinceNow] < -self->_destroyDelay) { + if (self->_disconnected || self->_lastDispatch != scheduleDate) { return; } self->_lastDispatch = nil; From 29bf3864d1a3d00b2199adb0d56298c3a32178fb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 12:44:48 -0700 Subject: [PATCH 0163/2143] Remove object after finish iterating in loop --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 7aac077e773..56de8a0d6f5 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -147,7 +147,9 @@ extern const char *kCFStreamVarName; } - (BOOL)isEqual:(id)object { - NSAssert([object isKindOfClass:[GRPCChannelConfiguration class]], @"Illegal :isEqual"); + if (![object isKindOfClass:[GRPCChannelConfiguration class]]) { + return NO; + } GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; if (!(obj.host == _host || [obj.host isEqualToString:_host])) return NO; if (!(obj.callOptions == _callOptions || [obj.callOptions hasChannelOptionsEqualTo:_callOptions])) @@ -207,13 +209,16 @@ extern const char *kCFStreamVarName; - (void)removeChannel:(GRPCChannel *)channel { @synchronized(self) { + __block GRPCChannelConfiguration *keyToDelete = nil; [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, GRPCChannel *_Nonnull obj, BOOL *_Nonnull stop) { if (obj == channel) { - [self->_channelPool removeObjectForKey:key]; + keyToDelete = key; + *stop = YES; } }]; + [self->_channelPool removeObjectForKey:keyToDelete]; } } From 395fc1226f1225b267f912f4a860ad52ef6f4e0a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 12:54:38 -0700 Subject: [PATCH 0164/2143] Cleaner code using nil messaging --- src/objective-c/GRPCClient/private/GRPCHost.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 480e4621845..8a59bd43d74 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -143,9 +143,7 @@ static NSMutableDictionary *gHostCache; GRPCCallOptions *callOptions = nil; @synchronized(gHostCache) { - if ([gHostCache objectForKey:host]) { - callOptions = [gHostCache[host] callOptions]; - } + callOptions = [gHostCache[host] callOptions]; } if (callOptions == nil) { callOptions = [[GRPCCallOptions alloc] init]; From c827fbc1d044f31a1f925e52e07c843f88094a74 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 13:06:31 -0700 Subject: [PATCH 0165/2143] Log failures when unable to create call or channel --- src/objective-c/GRPCClient/private/GRPCWrappedCall.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 100d4cf2914..577002e7a85 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -257,8 +257,13 @@ // queue. Currently we use a singleton queue. _queue = [GRPCCompletionQueue completionQueue]; _channel = [GRPCChannel channelWithHost:host callOptions:callOptions]; + if (_channel == nil) { + NSLog(@"Failed to get a channel for the host."); + return nil; + } _call = [_channel unmanagedCallWithPath:path completionQueue:_queue callOptions:callOptions]; if (_call == NULL) { + NSLog(@"Failed to create a call."); return nil; } } From bc0ce06951b091e81e8bc1c71dc660dc3168e75f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 1 Nov 2018 15:05:58 -0700 Subject: [PATCH 0166/2143] use _dispatchQueue for timer --- src/objective-c/GRPCClient/private/GRPCChannel.m | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 1d7fb421e5e..0ca2a359926 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -65,7 +65,6 @@ static GRPCChannelPool *gChannelPool; NSUInteger _refCount; BOOL _disconnected; dispatch_queue_t _dispatchQueue; - dispatch_queue_t _timerQueue; /** * Date and time when last timer is scheduled. When a timer is fired, if @@ -87,12 +86,8 @@ static GRPCChannelPool *gChannelPool; _dispatchQueue = dispatch_queue_create( NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); - _timerQueue = - dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class( - DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_DEFAULT, -1)); } else { _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - _timerQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT); } _lastDispatch = nil; } @@ -117,7 +112,7 @@ static GRPCChannelPool *gChannelPool; self->_lastDispatch = now; dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); - dispatch_after(delay, self->_timerQueue, ^{ + dispatch_after(delay, self->_dispatchQueue, ^{ [self timerFireWithScheduleDate:now]; }); } From 17a67fdb0fb01fe34c75d2c6bf34e24214222a89 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 2 Nov 2018 14:48:56 -0700 Subject: [PATCH 0167/2143] Aggregate v2 api tests --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 482 ++++++++++++++++++ src/objective-c/tests/APIv2Tests/Info.plist | 22 + src/objective-c/tests/GRPCClientTests.m | 291 ----------- src/objective-c/tests/Podfile | 1 + .../tests/Tests.xcodeproj/project.pbxproj | 263 ++++++++++ .../xcschemes/APIv2Tests.xcscheme | 90 ++++ src/objective-c/tests/run_tests.sh | 10 + 9 files changed, 870 insertions(+), 293 deletions(-) create mode 100644 src/objective-c/tests/APIv2Tests/APIv2Tests.m create mode 100644 src/objective-c/tests/APIv2Tests/Info.plist create mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 8e7d5a5f94b..2abc0fe8f3b 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -780,7 +780,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(self) { self.isWaitingForToken = YES; } - [self.tokenProvider getTokenWithHandler:^(NSString *token) { + [_callOptions.authTokenProvider getTokenWithHandler:^(NSString *token) { @synchronized(self) { if (self.isWaitingForToken) { if (token) { diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 9683bd3c638..77fde371bc0 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -64,7 +64,7 @@ typedef NS_ENUM(NSInteger, GRPCTransportType) { * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)getTokenWithHandler:(void (^)(NSString *token))hander; +- (void)getTokenWithHandler:(void (^)(NSString *token))handler; @end @interface GRPCCallOptions : NSObject diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m new file mode 100644 index 00000000000..7fc353391f3 --- /dev/null +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -0,0 +1,482 @@ +/* + * + * 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. + * + */ + +#import +#import +#import +#import + +#include + +#import "../version.h" + +// The server address is derived from preprocessor macro, which is +// in turn derived from environment variable of the same name. +#define NSStringize_helper(x) #x +#define NSStringize(x) @NSStringize_helper(x) +static NSString *const kHostAddress = NSStringize(HOST_PORT_LOCAL); +static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE); + +// Package and service name of test server +static NSString *const kPackage = @"grpc.testing"; +static NSString *const kService = @"TestService"; + +static GRPCProtoMethod *kInexistentMethod; +static GRPCProtoMethod *kEmptyCallMethod; +static GRPCProtoMethod *kUnaryCallMethod; +static GRPCProtoMethod *kFullDuplexCallMethod; + +static const int kSimpleDataLength = 100; + +static const NSTimeInterval kTestTimeout = 16; + +// Reveal the _class ivar for testing access +@interface GRPCCall2 () { + @public + GRPCCall *_call; +} + +@end + +// Convenience class to use blocks as callbacks +@interface ClientTestsBlockCallbacks : NSObject + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; + +@end + +@implementation ClientTestsBlockCallbacks { + void (^_initialMetadataCallback)(NSDictionary *); + void (^_messageCallback)(id); + void (^_closeCallback)(NSDictionary *, NSError *); + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + if ((self = [super init])) { + _initialMetadataCallback = initialMetadataCallback; + _messageCallback = messageCallback; + _closeCallback = closeCallback; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { + dispatch_async(_dispatchQueue, ^{ + if (self->_initialMetadataCallback) { + self->_initialMetadataCallback(initialMetadata); + } + }); +} + +- (void)receivedRawMessage:(GPBMessage *_Nullable)message { + dispatch_async(_dispatchQueue, ^{ + if (self->_messageCallback) { + self->_messageCallback(message); + } + }); +} + +- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata + error:(NSError *_Nullable)error { + dispatch_async(_dispatchQueue, ^{ + if (self->_closeCallback) { + self->_closeCallback(trailingMetadata, error); + } + }); +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + +@interface CallAPIv2Tests : XCTestCase + +@end + +@implementation CallAPIv2Tests + +- (void)setUp { + // This method isn't implemented by the remote server. + kInexistentMethod = + [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"Inexistent"]; + kEmptyCallMethod = + [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"EmptyCall"]; + kUnaryCallMethod = + [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"UnaryCall"]; + kFullDuplexCallMethod = + [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"FullDuplexCall"]; +} + +- (void)testMetadata { + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.fillUsername = YES; + request.fillOauthScope = YES; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kRemoteSSLHost + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + __block NSDictionary *init_md; + __block NSDictionary *trailing_md; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.oauth2AccessToken = @"bogusToken"; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + init_md = initialMetadata; + } + messageCallback:^(id message) { + XCTFail(@"Received unexpected response."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + trailing_md = trailingMetadata; + if (error) { + XCTAssertEqual(error.code, 16, + @"Finished with unexpected error: %@", error); + XCTAssertEqualObjects(init_md, + error.userInfo[kGRPCHeadersKey]); + XCTAssertEqualObjects(trailing_md, + error.userInfo[kGRPCTrailersKey]); + NSString *challengeHeader = init_md[@"www-authenticate"]; + XCTAssertGreaterThan(challengeHeader.length, 0, + @"No challenge in response headers %@", + init_md); + [expectation fulfill]; + } + }] + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testUserAgentPrefix { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."]; + __weak XCTestExpectation *recvInitialMd = + [self expectationWithDescription:@"Did not receive initial md."]; + + GRPCRequestOptions *request = [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kEmptyCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + NSDictionary *headers = + [NSDictionary dictionaryWithObjectsAndKeys:@"", @"x-grpc-test-echo-useragent", nil]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.userAgentPrefix = @"Foo"; + options.initialMetadata = headers; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:request + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( + NSDictionary *initialMetadata) { + NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; + // Test the regex is correct + NSString *expectedUserAgent = @"Foo grpc-objc/"; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:GRPC_OBJC_VERSION_STRING]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@" grpc-c/"]; + expectedUserAgent = + [expectedUserAgent stringByAppendingString:GRPC_C_VERSION_STRING]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@" (ios; chttp2; "]; + expectedUserAgent = [expectedUserAgent + stringByAppendingString:[NSString stringWithUTF8String:grpc_g_stands_for()]]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@")"]; + XCTAssertEqualObjects(userAgent, expectedUserAgent); + + NSError *error = nil; + // Change in format of user-agent field in a direction that does not match + // the regex will likely cause problem for certain gRPC users. For details, + // refer to internal doc https://goo.gl/c2diBc + NSRegularExpression *regex = [NSRegularExpression + regularExpressionWithPattern: + @" grpc-[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?/[^ ,]+( \\([^)]*\\))?" + options:0 + error:&error]; + + NSString *customUserAgent = + [regex stringByReplacingMatchesInString:userAgent + options:0 + range:NSMakeRange(0, [userAgent length]) + withTemplate:@""]; + XCTAssertEqualObjects(customUserAgent, @"Foo"); + [recvInitialMd fulfill]; + } + messageCallback:^(id message) { + XCTAssertNotNil(message); + XCTAssertEqual([message length], 0, + @"Non-empty response received: %@", message); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + if (error) { + XCTFail(@"Finished with unexpected error: %@", error); + } else { + [completion fulfill]; + } + }] + callOptions:options]; + [call writeData:[NSData data]]; + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)getTokenWithHandler:(void (^)(NSString *token))handler { + dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + dispatch_sync(queue, ^{ + handler(@"test-access-token"); + }); +} + +- (void)testOAuthToken { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kEmptyCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.authTokenProvider = self; + __block GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + [completion fulfill]; + }] + callOptions:options]; + [call writeData:[NSData data]]; + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testResponseSizeLimitExceeded { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.responseSizeLimit = kSimpleDataLength; + options.transportType = GRPCTransportTypeInsecure; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.payload.body = [NSMutableData dataWithLength:options.responseSizeLimit]; + request.responseSize = (int32_t)(options.responseSizeLimit * 2); + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNotNil(error, + @"Expecting non-nil error"); + XCTAssertEqual(error.code, + GRPCErrorCodeResourceExhausted); + [completion fulfill]; + }] + callOptions:options]; + [call writeData:[request data]]; + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testIdempotentProtoRPC { + __weak XCTestExpectation *response = [self expectationWithDescription:@"Expected response."]; + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseSize = kSimpleDataLength; + request.fillUsername = YES; + request.fillOauthScope = YES; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyIdempotentRequest]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + NSData *data = (NSData *)message; + XCTAssertNotNil(data, @"nil value received as response."); + XCTAssertGreaterThan(data.length, 0, + @"Empty response received."); + RMTSimpleResponse *responseProto = + [RMTSimpleResponse parseFromData:data error:NULL]; + // We expect empty strings, not nil: + XCTAssertNotNil(responseProto.username, + @"Response's username is nil."); + XCTAssertNotNil(responseProto.oauthScope, + @"Response's OAuth scope is nil."); + [response fulfill]; + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", + error); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testTimeout { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.timeout = 0.001; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler: + [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + XCTFail(@"Failure: response received; Expect: no response received."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Failure: no error received; Expect: receive " + @"deadline exceeded."); + XCTAssertEqual(error.code, GRPCErrorCodeDeadlineExceeded); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testTimeoutBackoffWithTimeout:(double)timeout Backoff:(double)backoff { + const double maxConnectTime = timeout > backoff ? timeout : backoff; + const double kMargin = 0.1; + + __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; + NSString *const kDummyAddress = [NSString stringWithFormat:@"127.0.0.1:10000"]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kDummyAddress + path:@"/dummy/path" + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.connectMinTimeout = timeout; + options.connectInitialBackoff = backoff; + options.connectMaxBackoff = 0; + + NSDate *startTime = [NSDate date]; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + XCTFail(@"Received message. Should not reach here."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Finished with no error; expecting error"); + XCTAssertLessThan( + [[NSDate date] timeIntervalSinceDate:startTime], + maxConnectTime + kMargin); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testTimeoutBackoff1 { + [self testTimeoutBackoffWithTimeout:0.7 Backoff:0.4]; +} + +- (void)testTimeoutBackoff2 { + [self testTimeoutBackoffWithTimeout:0.3 Backoff:0.8]; +} + +- (void)testCompression { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.expectCompressed = [RMTBoolValue message]; + request.expectCompressed.value = YES; + request.responseCompressed = [RMTBoolValue message]; + request.expectCompressed.value = YES; + request.responseSize = kSimpleDataLength; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.compressionAlgorithm = GRPCCompressGzip; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler: [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + NSError *error; + RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:data error:&error]; + XCTAssertNil(error, @"Error when parsing response: %@", error); + XCTAssertEqual(response.payload.body.length, kSimpleDataLength); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Received failure: %@", error); + [completion fulfill]; + }] + + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +@end diff --git a/src/objective-c/tests/APIv2Tests/Info.plist b/src/objective-c/tests/APIv2Tests/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/APIv2Tests/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/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index bbe81502dcf..727dc59ca11 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -86,65 +86,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; @end -// Convenience class to use blocks as callbacks -@interface ClientTestsBlockCallbacks : NSObject - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; - -@end - -@implementation ClientTestsBlockCallbacks { - void (^_initialMetadataCallback)(NSDictionary *); - void (^_messageCallback)(id); - void (^_closeCallback)(NSDictionary *, NSError *); - dispatch_queue_t _dispatchQueue; -} - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { - if ((self = [super init])) { - _initialMetadataCallback = initialMetadataCallback; - _messageCallback = messageCallback; - _closeCallback = closeCallback; - _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); - } - return self; -} - -- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { - dispatch_async(_dispatchQueue, ^{ - if (_initialMetadataCallback) { - _initialMetadataCallback(initialMetadata); - } - }); -} - -- (void)receivedRawMessage:(GPBMessage *_Nullable)message { - dispatch_async(_dispatchQueue, ^{ - if (_messageCallback) { - _messageCallback(message); - } - }); -} - -- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata - error:(NSError *_Nullable)error { - dispatch_async(_dispatchQueue, ^{ - if (_closeCallback) { - _closeCallback(trailingMetadata, error); - } - }); -} - -- (dispatch_queue_t)dispatchQueue { - return _dispatchQueue; -} - -@end - #pragma mark Tests /** @@ -296,55 +237,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testMetadataWithV2API { - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."]; - - RMTSimpleRequest *request = [RMTSimpleRequest message]; - request.fillUsername = YES; - request.fillOauthScope = YES; - - GRPCRequestOptions *callRequest = - [[GRPCRequestOptions alloc] initWithHost:(NSString *)kRemoteSSLHost - path:kUnaryCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - __block NSDictionary *init_md; - __block NSDictionary *trailing_md; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.oauth2AccessToken = @"bogusToken"; - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:callRequest - responseHandler:[[ClientTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { - init_md = initialMetadata; - } - messageCallback:^(id message) { - XCTFail(@"Received unexpected response."); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - trailing_md = trailingMetadata; - if (error) { - XCTAssertEqual(error.code, 16, - @"Finished with unexpected error: %@", error); - XCTAssertEqualObjects(init_md, - error.userInfo[kGRPCHeadersKey]); - XCTAssertEqualObjects(trailing_md, - error.userInfo[kGRPCTrailersKey]); - NSString *challengeHeader = init_md[@"www-authenticate"]; - XCTAssertGreaterThan(challengeHeader.length, 0, - @"No challenge in response headers %@", - init_md); - [expectation fulfill]; - } - }] - callOptions:options]; - - [call start]; - [call writeData:[request data]]; - [call finish]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - - (void)testResponseMetadataKVO { __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."]; @@ -437,75 +329,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testUserAgentPrefixWithV2API { - __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."]; - __weak XCTestExpectation *recvInitialMd = - [self expectationWithDescription:@"Did not receive initial md."]; - - GRPCRequestOptions *request = [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kEmptyCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - NSDictionary *headers = - [NSDictionary dictionaryWithObjectsAndKeys:@"", @"x-grpc-test-echo-useragent", nil]; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = GRPCTransportTypeInsecure; - options.userAgentPrefix = @"Foo"; - options.initialMetadata = headers; - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:request - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( - NSDictionary *initialMetadata) { - NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; - // Test the regex is correct - NSString *expectedUserAgent = @"Foo grpc-objc/"; - expectedUserAgent = - [expectedUserAgent stringByAppendingString:GRPC_OBJC_VERSION_STRING]; - expectedUserAgent = [expectedUserAgent stringByAppendingString:@" grpc-c/"]; - expectedUserAgent = - [expectedUserAgent stringByAppendingString:GRPC_C_VERSION_STRING]; - expectedUserAgent = [expectedUserAgent stringByAppendingString:@" (ios; chttp2; "]; - expectedUserAgent = [expectedUserAgent - stringByAppendingString:[NSString stringWithUTF8String:grpc_g_stands_for()]]; - expectedUserAgent = [expectedUserAgent stringByAppendingString:@")"]; - XCTAssertEqualObjects(userAgent, expectedUserAgent); - - NSError *error = nil; - // Change in format of user-agent field in a direction that does not match - // the regex will likely cause problem for certain gRPC users. For details, - // refer to internal doc https://goo.gl/c2diBc - NSRegularExpression *regex = [NSRegularExpression - regularExpressionWithPattern: - @" grpc-[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?/[^ ,]+( \\([^)]*\\))?" - options:0 - error:&error]; - - NSString *customUserAgent = - [regex stringByReplacingMatchesInString:userAgent - options:0 - range:NSMakeRange(0, [userAgent length]) - withTemplate:@""]; - XCTAssertEqualObjects(customUserAgent, @"Foo"); - [recvInitialMd fulfill]; - } - messageCallback:^(id message) { - XCTAssertNotNil(message); - XCTAssertEqual([message length], 0, - @"Non-empty response received: %@", message); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - if (error) { - XCTFail(@"Finished with unexpected error: %@", error); - } else { - [completion fulfill]; - } - }] - callOptions:options]; - [call writeData:[NSData data]]; - [call start]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - - (void)testTrailers { __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."]; @@ -597,52 +420,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testIdempotentProtoRPCWithV2API { - __weak XCTestExpectation *response = [self expectationWithDescription:@"Expected response."]; - __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; - - RMTSimpleRequest *request = [RMTSimpleRequest message]; - request.responseSize = 100; - request.fillUsername = YES; - request.fillOauthScope = YES; - GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kUnaryCallMethod.HTTPPath - safety:GRPCCallSafetyIdempotentRequest]; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = GRPCTransportTypeInsecure; - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - NSData *data = (NSData *)message; - XCTAssertNotNil(data, @"nil value received as response."); - XCTAssertGreaterThan(data.length, 0, - @"Empty response received."); - RMTSimpleResponse *responseProto = - [RMTSimpleResponse parseFromData:data error:NULL]; - // We expect empty strings, not nil: - XCTAssertNotNil(responseProto.username, - @"Response's username is nil."); - XCTAssertNotNil(responseProto.oauthScope, - @"Response's OAuth scope is nil."); - [response fulfill]; - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error, @"Finished with unexpected error: %@", - error); - [completion fulfill]; - }] - callOptions:options]; - - [call start]; - [call writeData:[request data]]; - [call finish]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - - (void)testAlternateDispatchQueue { const int32_t kPayloadSize = 100; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -732,37 +509,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testTimeoutWithV2API { - __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.timeout = 0.001; - GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kFullDuplexCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler: - [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id data) { - XCTFail(@"Failure: response received; Expect: no response received."); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNotNil(error, - @"Failure: no error received; Expect: receive " - @"deadline exceeded."); - XCTAssertEqual(error.code, GRPCErrorCodeDeadlineExceeded); - [completion fulfill]; - }] - callOptions:options]; - - [call start]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - - (int)findFreePort { struct sockaddr_in addr; unsigned int addr_len = sizeof(addr); @@ -834,43 +580,6 @@ static GRPCProtoMethod *kFullDuplexCallMethod; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testTimeoutBackoffWithOptionsWithTimeout:(double)timeout Backoff:(double)backoff { - const double maxConnectTime = timeout > backoff ? timeout : backoff; - const double kMargin = 0.1; - - __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; - NSString *const kDummyAddress = [NSString stringWithFormat:@"127.0.0.1:10000"]; - GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kDummyAddress - path:@"/dummy/path" - safety:GRPCCallSafetyDefault]; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.connectMinTimeout = timeout; - options.connectInitialBackoff = backoff; - options.connectMaxBackoff = 0; - - NSDate *startTime = [NSDate date]; - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id data) { - XCTFail(@"Received message. Should not reach here."); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNotNil(error, - @"Finished with no error; expecting error"); - XCTAssertLessThan( - [[NSDate date] timeIntervalSinceDate:startTime], - maxConnectTime + kMargin); - [completion fulfill]; - }] - callOptions:options]; - - [call start]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - // The numbers of the following three tests are selected to be smaller than the default values of // initial backoff (1s) and min_connect_timeout (20s), so that if they fail we know the default // values fail to be overridden by the channel args. diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index e87aba235ad..5df9d4e85bd 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -17,6 +17,7 @@ GRPC_LOCAL_SRC = '../../..' InteropTestsMultipleChannels InteropTestsCallOptions UnitTests + APIv2Tests ).each do |target_name| target target_name do pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 104fd0a4ea0..6d1932b0215 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; 5E0282E9215AA697007AC99D /* UnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* UnitTests.m */; }; 5E0282EB215AA697007AC99D /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5E10F5AA218CB0D2008BAB68 /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */; }; 5E7D71AD210954A8001EA6BA /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; 5E7D71B5210B9EC9001EA6BA /* InteropTestsCallOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */; }; 5E7D71B7210B9EC9001EA6BA /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; @@ -68,6 +69,7 @@ BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */; }; C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */; }; CCF5C0719EF608276AE16374 /* libPods-UnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */; }; + E7F4C80FC8FC667B7447BFE7 /* libPods-APIv2Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */; }; F15EF7852DC70770EFDB1D2C /* libPods-AllTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */; }; /* End PBXBuildFile section */ @@ -176,7 +178,9 @@ 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartextCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.debug.xcconfig"; sourceTree = ""; }; + 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.debug.xcconfig"; sourceTree = ""; }; 1295CCBD1082B4A7CFCED95F /* Pods-InteropTestsMultipleChannels.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.cronet.xcconfig"; sourceTree = ""; }; + 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.release.xcconfig"; sourceTree = ""; }; 14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.cronet.xcconfig"; sourceTree = ""; }; 1588C85DEAF7FC0ACDEA4C02 /* Pods-InteropTestsLocalCleartext.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.test.xcconfig"; sourceTree = ""; }; 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; sourceTree = ""; }; @@ -200,6 +204,7 @@ 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.release.xcconfig"; sourceTree = ""; }; 4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.cronet.xcconfig"; sourceTree = ""; }; 51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = ""; }; + 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.test.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.test.xcconfig"; sourceTree = ""; }; 553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = ""; }; 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; sourceTree = ""; }; 573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; sourceTree = ""; }; @@ -207,6 +212,9 @@ 5E0282E6215AA697007AC99D /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E0282E8215AA697007AC99D /* UnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UnitTests.m; sourceTree = ""; }; 5E0282EA215AA697007AC99D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = APIv2Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = APIv2Tests.m; sourceTree = ""; }; + 5E10F5AB218CB0D2008BAB68 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsCallOptions.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsCallOptions.m; sourceTree = ""; }; 5E7D71B6210B9EC9001EA6BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -254,6 +262,7 @@ 7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.release.xcconfig"; sourceTree = ""; }; 7BA53C6D224288D5870FE6F3 /* Pods-InteropTestsLocalCleartextCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; sourceTree = ""; }; 8B498B05C6DA0818B2FA91D4 /* Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; sourceTree = ""; }; + 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.cronet.xcconfig"; sourceTree = ""; }; 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.cronet.xcconfig"; sourceTree = ""; }; 943138072A9605B5B8DC1FC0 /* Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; sourceTree = ""; }; 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.test.xcconfig"; sourceTree = ""; }; @@ -266,6 +275,7 @@ AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.release.xcconfig"; sourceTree = ""; }; AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsCallOptions.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B226619DC4E709E0FFFF94B8 /* Pods-CronetUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.test.xcconfig"; sourceTree = ""; }; + B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-APIv2Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.debug.xcconfig"; sourceTree = ""; }; BED74BC8ABF9917C66175879 /* Pods-ChannelTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.test.xcconfig"; sourceTree = ""; }; C17F57E5BCB989AB1C2F1F25 /* Pods-InteropTestsRemoteCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.test.xcconfig"; sourceTree = ""; }; @@ -303,6 +313,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E10F5A4218CB0D1008BAB68 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E7F4C80FC8FC667B7447BFE7 /* libPods-APIv2Tests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E7D71AF210B9EC8001EA6BA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -456,6 +474,7 @@ 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */, AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */, 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */, + B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */, ); name = Frameworks; sourceTree = ""; @@ -525,6 +544,10 @@ 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */, E1E7660656D902104F728892 /* Pods-UnitTests.cronet.xcconfig */, EBFFEC04B514CB0D4922DC40 /* Pods-UnitTests.release.xcconfig */, + 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */, + 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */, + 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */, + 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -538,6 +561,15 @@ path = UnitTests; sourceTree = ""; }; + 5E10F5A8218CB0D1008BAB68 /* APIv2Tests */ = { + isa = PBXGroup; + children = ( + 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */, + 5E10F5AB218CB0D2008BAB68 /* Info.plist */, + ); + path = APIv2Tests; + sourceTree = ""; + }; 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */ = { isa = PBXGroup; children = ( @@ -604,6 +636,7 @@ 5EB2A2F62109284500EB4B69 /* InteropTestsMultipleChannels */, 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */, 5E0282E7215AA697007AC99D /* UnitTests */, + 5E10F5A8218CB0D1008BAB68 /* APIv2Tests */, 635697C81B14FC11007A7283 /* Products */, 51E4650F34F854F41FF053B3 /* Pods */, 136D535E19727099B941D7B1 /* Frameworks */, @@ -629,6 +662,7 @@ 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */, 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */, 5E0282E6215AA697007AC99D /* UnitTests.xctest */, + 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */, ); name = Products; sourceTree = ""; @@ -681,6 +715,25 @@ productReference = 5E0282E6215AA697007AC99D /* UnitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 5E10F5A6218CB0D1008BAB68 /* APIv2Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E10F5B0218CB0D2008BAB68 /* Build configuration list for PBXNativeTarget "APIv2Tests" */; + buildPhases = ( + 031ADD72298D6C6979CB06DB /* [CP] Check Pods Manifest.lock */, + 5E10F5A3218CB0D1008BAB68 /* Sources */, + 5E10F5A4218CB0D1008BAB68 /* Frameworks */, + 5E10F5A5218CB0D1008BAB68 /* Resources */, + FBB92A8B11C52512E67791E8 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = APIv2Tests; + productName = APIv2Tests; + productReference = 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */ = { isa = PBXNativeTarget; buildConfigurationList = 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */; @@ -990,6 +1043,10 @@ CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; }; + 5E10F5A6218CB0D1008BAB68 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; 5E7D71B1210B9EC8001EA6BA = { CreatedOnToolsVersion = 9.3; ProvisioningStyle = Automatic; @@ -1071,6 +1128,7 @@ 5EB2A2F42109284500EB4B69 /* InteropTestsMultipleChannels */, 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */, 5E0282E5215AA697007AC99D /* UnitTests */, + 5E10F5A6218CB0D1008BAB68 /* APIv2Tests */, ); }; /* End PBXProject section */ @@ -1083,6 +1141,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E10F5A5218CB0D1008BAB68 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E7D71B0210B9EC8001EA6BA /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1206,6 +1271,28 @@ 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; }; + 031ADD72298D6C6979CB06DB /* [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-APIv2Tests-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; + }; 0617B5294978A95BEBBFF733 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1764,6 +1851,28 @@ 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; }; + FBB92A8B11C52512E67791E8 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-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-APIv2Tests/Pods-APIv2Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1775,6 +1884,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E10F5A3218CB0D1008BAB68 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E10F5AA218CB0D2008BAB68 /* APIv2Tests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E7D71AE210B9EC8001EA6BA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2098,6 +2215,141 @@ }; name = Release; }; + 5E10F5AC218CB0D2008BAB68 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5E10F5AD218CB0D2008BAB68 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5E10F5AE218CB0D2008BAB68 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5E10F5AF218CB0D2008BAB68 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 5E1228981E4D400F00E8504F /* Test */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3648,6 +3900,17 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 5E10F5B0218CB0D2008BAB68 /* Build configuration list for PBXNativeTarget "APIv2Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E10F5AC218CB0D2008BAB68 /* Debug */, + 5E10F5AD218CB0D2008BAB68 /* Test */, + 5E10F5AE218CB0D2008BAB68 /* Cronet */, + 5E10F5AF218CB0D2008BAB68 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme new file mode 100644 index 00000000000..b444ddc2b67 --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index 118220ce4b1..e8c3e6ec2a4 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -183,4 +183,14 @@ xcodebuild \ | egrep -v '^$' \ | egrep -v "(GPBDictionary|GPBArray)" - +echo "TIME: $(date)" +xcodebuild \ + -workspace Tests.xcworkspace \ + -scheme APIv2Tests \ + -destination name="iPhone 8" \ + test \ + | egrep -v "$XCODEBUILD_FILTER" \ + | egrep -v '^$' \ + | egrep -v "(GPBDictionary|GPBArray)" - + exit 0 From 6b8f0ceae8f581cfd63b40c4e2ccab95783081ae Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 10:15:20 -0800 Subject: [PATCH 0168/2143] A few nits --- src/objective-c/GRPCClient/GRPCCall+OAuth2.h | 2 +- src/objective-c/GRPCClient/GRPCCall.h | 4 ++-- src/objective-c/GRPCClient/GRPCCall.m | 9 +++++++-- src/objective-c/ProtoRPC/ProtoRPC.h | 4 ++-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h index 3054bfc5a7a..60cdc50bfda 100644 --- a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h +++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h @@ -24,7 +24,7 @@ @interface GRPCCall (OAuth2) @property(atomic, copy) NSString* oauth2AccessToken; -@property(atomic, readonly) NSString* oauth2ChallengeHeader; +@property(atomic, copy, readonly) NSString* oauth2ChallengeHeader; @property(atomic, strong) id tokenProvider; @end diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index a1f139fc186..4f0660d203e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -196,7 +196,7 @@ extern NSString *const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype) new NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; /** Initialize with all properties. */ - (instancetype)initWithHost:(NSString *)host @@ -224,7 +224,7 @@ extern NSString *const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype) new NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; /** * Designated initializer for a call. diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 2abc0fe8f3b..2f727e62be1 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -67,6 +67,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @implementation GRPCRequestOptions - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { + NSAssert(host.length != 0 && path.length != 0, @"Host and Path cannot be empty"); if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -90,7 +91,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; /** The handler of responses. */ id _handler; - // Thread safety of ivars below are protected by _dispatcheQueue. + // Thread safety of ivars below are protected by _dispatchQueue. /** * Make use of legacy GRPCCall to make calls. Nullified when call is finished. @@ -121,7 +122,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; if ((self = [super init])) { _requestOptions = [requestOptions copy]; - _callOptions = [callOptions copy]; + if (callOptions == nil) { + _callOptions = [[GRPCCallOptions alloc] init]; + } else { + _callOptions = [callOptions copy]; + } _handler = responseHandler; _initialMetadataPublished = NO; _pipe = [GRXBufferedPipe pipe]; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index b0f4ced99e8..3d137a53ffc 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -66,7 +66,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; -+ (instancetype) new NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; /** * Users should not use this initializer directly. Call objects will be created, initialized, and @@ -92,7 +92,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; -+ (instancetype) new NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; /** * Users should not use this initializer directly. Call objects will be created, initialized, and From b496e3a2663824c22806b7ee7b1423c806ecc61a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 11:07:03 -0800 Subject: [PATCH 0169/2143] On finish, clean _handler and _call independently --- src/objective-c/GRPCClient/GRPCCall.m | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 2f727e62be1..af141935813 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -184,6 +184,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; } completionHandler:^(NSError *errorOrNil) { dispatch_async(self->_dispatchQueue, ^{ + if (self->_call) { + [self->_pipe writesFinishedWithError:nil]; + self->_call = nil; + self->_pipe = nil; + } if (self->_handler) { if (!self->_initialMetadataPublished) { self->_initialMetadataPublished = YES; @@ -193,12 +198,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; - - if (self->_call) { - [self->_pipe writesFinishedWithError:nil]; - self->_call = nil; - self->_pipe = nil; - } } }); }]; From 739760cdc8a6625fe93f4f0312d84305052b0d09 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 11:22:51 -0800 Subject: [PATCH 0170/2143] More comment --- src/objective-c/GRPCClient/GRPCCall.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index af141935813..9be0554ff98 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -185,6 +185,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; completionHandler:^(NSError *errorOrNil) { dispatch_async(self->_dispatchQueue, ^{ if (self->_call) { + // Clean up the request writers. This should have no effect to _call since its + // response writeable is already nullified. [self->_pipe writesFinishedWithError:nil]; self->_call = nil; self->_pipe = nil; From 24265b03ac5c6ace73916f3bc3a847abf1c64c33 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 11:31:48 -0800 Subject: [PATCH 0171/2143] Clarify cancel before call is started --- src/objective-c/GRPCClient/GRPCCall.h | 1 + src/objective-c/GRPCClient/GRPCCall.m | 1 + 2 files changed, 2 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 4f0660d203e..f713262b643 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -245,6 +245,7 @@ extern NSString *const kGRPCTrailersKey; /** * Starts the call. This function should only be called once; additional calls will be discarded. + * Invokes after calling cancel: are discarded. */ - (void)start; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9be0554ff98..5ce361300d6 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -209,6 +209,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { dispatch_async(_dispatchQueue, ^{ + self->_started = YES; if (self->_call) { [self->_call cancel]; self->_call = nil; From 9558618182aa817ad5aa9885f1fe12003ee1a93e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 11:37:41 -0800 Subject: [PATCH 0172/2143] Check if call is cancelled --- src/objective-c/GRPCClient/GRPCCall.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 5ce361300d6..1338c1edd60 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -237,7 +237,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeData:(NSData *)data { dispatch_async(_dispatchQueue, ^{ - [self->_pipe writeValue:data]; + if (self->_call) { + [self->_pipe writeValue:data]; + } }); } From b3b98ba4a29f434541355e026765938998c22da4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 12:09:46 -0800 Subject: [PATCH 0173/2143] test fix --- src/objective-c/tests/GRPCClientTests.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 727dc59ca11..834bf6d661a 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -585,12 +585,10 @@ static GRPCProtoMethod *kFullDuplexCallMethod; // values fail to be overridden by the channel args. - (void)testTimeoutBackoff1 { [self testTimeoutBackoffWithTimeout:0.7 Backoff:0.3]; - [self testTimeoutBackoffWithOptionsWithTimeout:0.7 Backoff:0.4]; } - (void)testTimeoutBackoff2 { [self testTimeoutBackoffWithTimeout:0.3 Backoff:0.7]; - [self testTimeoutBackoffWithOptionsWithTimeout:0.3 Backoff:0.8]; } - (void)testErrorDebugInformation { From 1be316e5641db3192a3f7b276e3926d8da17c62a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 14:12:14 -0800 Subject: [PATCH 0174/2143] Remove check in cancel --- src/objective-c/GRPCClient/GRPCCall.h | 5 ++-- src/objective-c/GRPCClient/GRPCCall.m | 42 +++++++++++++++------------ 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index f713262b643..260305a989c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -244,8 +244,7 @@ extern NSString *const kGRPCTrailersKey; responseHandler:(id)responseHandler; /** - * Starts the call. This function should only be called once; additional calls will be discarded. - * Invokes after calling cancel: are discarded. + * Starts the call. This function must only be called once for each instance. */ - (void)start; @@ -263,7 +262,7 @@ extern NSString *const kGRPCTrailersKey; /** * Finish the RPC request and half-close the call. The server may still send messages and/or - * trailers to the client. + * trailers to the client. The method must only be called once and after start is called. */ - (void)finish; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 1338c1edd60..9f8339eb601 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -105,6 +105,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_queue_t _dispatchQueue; /** Flags whether call has started. */ BOOL _started; + /** Flags whether call has been canceled. */ + BOOL _canceled; + /** Flags whether call has been finished. */ } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -140,6 +143,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); _started = NO; + _canceled = NO; } return self; @@ -153,9 +157,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)start { dispatch_async(_dispatchQueue, ^{ - if (self->_started) { - return; - } + NSAssert(!self->_started, @"Call already started."); + NSAssert(!self->_canceled, @"Call already canceled."); self->_started = YES; if (!self->_callOptions) { self->_callOptions = [[GRPCCallOptions alloc] init]; @@ -184,13 +187,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; } completionHandler:^(NSError *errorOrNil) { dispatch_async(self->_dispatchQueue, ^{ - if (self->_call) { - // Clean up the request writers. This should have no effect to _call since its - // response writeable is already nullified. - [self->_pipe writesFinishedWithError:nil]; - self->_call = nil; - self->_pipe = nil; - } if (self->_handler) { if (!self->_initialMetadataPublished) { self->_initialMetadataPublished = YES; @@ -201,6 +197,15 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; } + // Clearing _call must happen *after* dispatching close in order to get trailing + // metadata from _call. + if (self->_call) { + // Clean up the request writers. This should have no effect to _call since its + // response writeable is already nullified. + [self->_pipe writesFinishedWithError:nil]; + self->_call = nil; + self->_pipe = nil; + } }); }]; [self->_call startWithWriteable:responseWriteable]; @@ -209,7 +214,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { dispatch_async(_dispatchQueue, ^{ - self->_started = YES; + NSAssert(!self->_canceled, @"Call already canceled."); if (self->_call) { [self->_call cancel]; self->_call = nil; @@ -237,6 +242,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeData:(NSData *)data { dispatch_async(_dispatchQueue, ^{ + NSAssert(!self->_canceled, @"Call arleady canceled."); + NSAssert(!self->_finished, @"Call is half-closed before sending data."); if (self->_call) { [self->_pipe writeValue:data]; } @@ -245,6 +252,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)finish { dispatch_async(_dispatchQueue, ^{ + NSAssert(self->started, @"Call not started."); + NSAssert(!self->_canceled, @"Call arleady canceled."); + NSAssert(!self->_finished, @"Call already half-closed."); if (self->_call) { [self->_pipe writesFinishedWithError:nil]; } @@ -265,9 +275,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - NSDictionary *trailers = _call.responseTrailers; if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [_handler closedWithTrailingMetadata:trailers error:error]; + [_handler closedWithTrailingMetadata:_call.responseTrailers error:error]; } } @@ -464,11 +473,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { @synchronized(self) { - if (!self.isWaitingForToken) { - [self cancelCall]; - } else { - self.isWaitingForToken = NO; - } + [self cancelCall]; + self.isWaitingForToken = NO; } [self maybeFinishWithError:[NSError From 515941ae1899ca125e8da77c3031d3f0471488ff Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 16:04:56 -0800 Subject: [PATCH 0175/2143] copy _requestHeaders in GRPCCall --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9f8339eb601..c10fe7c1346 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -578,7 +578,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; break; } - NSMutableDictionary *headers = _requestHeaders; + NSMutableDictionary *headers = [_requestHeaders copy]; NSString *fetchedOauth2AccessToken; @synchronized(self) { fetchedOauth2AccessToken = _fetchedOauth2AccessToken; From d635d9f9f98bc374c0b3502bbcc8f707c27d7038 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 16:43:58 -0800 Subject: [PATCH 0176/2143] fix some threading issues --- src/objective-c/GRPCClient/GRPCCall.m | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index c10fe7c1346..b3bddf08a05 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -468,7 +468,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancelCall { // Can be called from any thread, any number of times. - [_wrappedCall cancel]; + @synchronized (self) { + [_wrappedCall cancel]; + } } - (void)cancel { @@ -730,17 +732,21 @@ const char *kCFStreamVarName = "grpc_cfstream"; _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; - _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; - if (_wrappedCall == nil) { + GRPCWrappedCall *wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; + if (wrappedCall == nil) { [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{ - NSLocalizedDescriptionKey : - @"Failed to create call or channel." - }]]; + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; return; } + @synchronized (self) { + _wrappedCall = wrappedCall; + } + [self sendHeaders]; [self invokeCall]; From d40e828d53cdb983255e0406261fed71710ba361 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 17:08:26 -0800 Subject: [PATCH 0177/2143] NSInteger->NSUInteger --- src/objective-c/GRPCClient/GRPCCallOptions.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 77fde371bc0..bb8a1d251a9 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -34,7 +34,7 @@ typedef NS_ENUM(NSUInteger, GRPCCallSafety) { }; // Compression algorithm to be used by a gRPC call -typedef NS_ENUM(NSInteger, GRPCCompressionAlgorithm) { +typedef NS_ENUM(NSUInteger, GRPCCompressionAlgorithm) { GRPCCompressNone = 0, GRPCCompressDeflate, GRPCCompressGzip, @@ -45,7 +45,7 @@ typedef NS_ENUM(NSInteger, GRPCCompressionAlgorithm) { typedef GRPCCompressionAlgorithm GRPCCompressAlgorithm; /** The transport to be used by a gRPC call */ -typedef NS_ENUM(NSInteger, GRPCTransportType) { +typedef NS_ENUM(NSUInteger, GRPCTransportType) { GRPCTransportTypeDefault = 0, /** gRPC internal HTTP/2 stack with BoringSSL */ GRPCTransportTypeChttp2BoringSSL = 0, From ae623ea5b65ff6060d0b8a63fdf3f26560118720 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 17:32:22 -0800 Subject: [PATCH 0178/2143] Polish isEqual of options --- src/objective-c/GRPCClient/GRPCCallOptions.m | 43 +++++++++---------- .../GRPCClient/private/GRPCChannelPool.m | 2 +- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index c7096cf1cfb..beea9ce46ec 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -44,6 +44,17 @@ static const id kDefaultLogContext = nil; static NSString *const kDefaultChannelPoolDomain = nil; static const NSUInteger kDefaultChannelID = 0; +// Check if two objects are equal. Returns YES if both are nil; +BOOL areObjectsEqual(id obj1, id obj2) { + if (obj1 == obj2) { + return YES; + } + if (obj1 == nil || obj2 == nil) { + return NO; + } + return [obj1 isEqual:obj2]; +} + @implementation GRPCCallOptions { @protected NSString *_serverAuthority; @@ -232,9 +243,8 @@ static const NSUInteger kDefaultChannelID = 0; } - (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions { - if (!(callOptions.userAgentPrefix == _userAgentPrefix || - [callOptions.userAgentPrefix isEqualToString:_userAgentPrefix])) - return NO; + if (callOptions == nil) return NO; + if (!areObjectsEqual(callOptions.userAgentPrefix, _userAgentPrefix)) return NO; if (!(callOptions.responseSizeLimit == _responseSizeLimit)) return NO; if (!(callOptions.compressionAlgorithm == _compressionAlgorithm)) return NO; if (!(callOptions.retryEnabled == _retryEnabled)) return NO; @@ -243,27 +253,14 @@ static const NSUInteger kDefaultChannelID = 0; if (!(callOptions.connectMinTimeout == _connectMinTimeout)) return NO; if (!(callOptions.connectInitialBackoff == _connectInitialBackoff)) return NO; if (!(callOptions.connectMaxBackoff == _connectMaxBackoff)) return NO; - if (!(callOptions.additionalChannelArgs == _additionalChannelArgs || - [callOptions.additionalChannelArgs isEqualToDictionary:_additionalChannelArgs])) - return NO; - if (!(callOptions.PEMRootCertificates == _PEMRootCertificates || - [callOptions.PEMRootCertificates isEqualToString:_PEMRootCertificates])) - return NO; - if (!(callOptions.PEMPrivateKey == _PEMPrivateKey || - [callOptions.PEMPrivateKey isEqualToString:_PEMPrivateKey])) - return NO; - if (!(callOptions.PEMCertChain == _PEMCertChain || - [callOptions.PEMCertChain isEqualToString:_PEMCertChain])) - return NO; - if (!(callOptions.hostNameOverride == _hostNameOverride || - [callOptions.hostNameOverride isEqualToString:_hostNameOverride])) - return NO; + if (!areObjectsEqual(callOptions.additionalChannelArgs, _additionalChannelArgs)) return NO; + if (!areObjectsEqual(callOptions.PEMRootCertificates, _PEMRootCertificates)) return NO; + if (!areObjectsEqual(callOptions.PEMPrivateKey, _PEMPrivateKey)) return NO; + if (!areObjectsEqual(callOptions.PEMCertChain, _PEMCertChain)) return NO; + if (!areObjectsEqual(callOptions.hostNameOverride, _hostNameOverride)) return NO; if (!(callOptions.transportType == _transportType)) return NO; - if (!(callOptions.logContext == _logContext || [callOptions.logContext isEqual:_logContext])) - return NO; - if (!(callOptions.channelPoolDomain == _channelPoolDomain || - [callOptions.channelPoolDomain isEqualToString:_channelPoolDomain])) - return NO; + if (!areObjectsEqual(callOptions.logContext, _logContext)) return NO; + if (!areObjectsEqual(callOptions.channelPoolDomain, _channelPoolDomain)) return NO; if (!(callOptions.channelID == _channelID)) return NO; return YES; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 56de8a0d6f5..627bbab3c01 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -151,7 +151,7 @@ extern const char *kCFStreamVarName; return NO; } GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; - if (!(obj.host == _host || [obj.host isEqualToString:_host])) return NO; + if (!(obj.host == _host || (_host != nil && [obj.host isEqualToString:_host]))) return NO; if (!(obj.callOptions == _callOptions || [obj.callOptions hasChannelOptionsEqualTo:_callOptions])) return NO; From bb5e55e86896ff353010db58bc6381436e11c4a5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 17:37:47 -0800 Subject: [PATCH 0179/2143] remove extra copy --- src/objective-c/GRPCClient/GRPCCallOptions.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index beea9ce46ec..696e81703ff 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -360,7 +360,7 @@ BOOL areObjectsEqual(id obj1, id obj2) { connectMinTimeout:_connectMinTimeout connectInitialBackoff:_connectInitialBackoff connectMaxBackoff:_connectMaxBackoff - additionalChannelArgs:[_additionalChannelArgs copy] + additionalChannelArgs:_additionalChannelArgs PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey PEMCertChain:_PEMCertChain From d8e7a6c6f1269eedec3f7b175ac85ed89e6e490e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 17:38:21 -0800 Subject: [PATCH 0180/2143] hash: -> .hash --- src/objective-c/GRPCClient/GRPCCallOptions.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 696e81703ff..3e0dbbf7e42 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -283,7 +283,7 @@ BOOL areObjectsEqual(id obj1, id obj2) { result ^= _PEMCertChain.hash; result ^= _hostNameOverride.hash; result ^= _transportType; - result ^= [_logContext hash]; + result ^= _logContext.hash; result ^= _channelPoolDomain.hash; result ^= _channelID; From a0f5db15815d3ec5b2ad3b781cca5e2eb6468824 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 17:42:30 -0800 Subject: [PATCH 0181/2143] Rename GRPCCallOptions+internal->GRPCCallOptions+Internal --- gRPC.podspec | 2 +- .../{GRPCCallOptions+internal.h => GRPCCallOptions+Internal.h} | 0 templates/gRPC.podspec.template | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/objective-c/GRPCClient/internal/{GRPCCallOptions+internal.h => GRPCCallOptions+Internal.h} (100%) diff --git a/gRPC.podspec b/gRPC.podspec index 47a130d12d1..d8aa997e7cb 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -58,7 +58,7 @@ Pod::Spec.new do |s| ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}" ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}" - ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/GRPCCallOptions+Internal.h" + ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/*.h" ss.dependency 'gRPC-Core', version end diff --git a/src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h b/src/objective-c/GRPCClient/internal/GRPCCallOptions+Internal.h similarity index 100% rename from src/objective-c/GRPCClient/internal/GRPCCallOptions+internal.h rename to src/objective-c/GRPCClient/internal/GRPCCallOptions+Internal.h diff --git a/templates/gRPC.podspec.template b/templates/gRPC.podspec.template index a3ed1d78584..593d277e5ba 100644 --- a/templates/gRPC.podspec.template +++ b/templates/gRPC.podspec.template @@ -60,7 +60,7 @@ ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}" ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}" - ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/GRPCCallOptions+Internal.h" + ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/*.h" ss.dependency 'gRPC-Core', version end From ab9510560781dd2f27608e694518f67b7d425d9a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 6 Nov 2018 17:46:22 -0800 Subject: [PATCH 0182/2143] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 4 +-- src/objective-c/GRPCClient/GRPCCall.m | 13 ++++---- src/objective-c/ProtoRPC/ProtoRPC.h | 4 +-- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 33 ++++++++++--------- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 260305a989c..bde69f01c52 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -196,7 +196,7 @@ extern NSString *const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** Initialize with all properties. */ - (instancetype)initWithHost:(NSString *)host @@ -224,7 +224,7 @@ extern NSString *const kGRPCTrailersKey; - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Designated initializer for a call. diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index b3bddf08a05..321a0bd1bd7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -468,7 +468,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancelCall { // Can be called from any thread, any number of times. - @synchronized (self) { + @synchronized(self) { [_wrappedCall cancel]; } } @@ -732,18 +732,19 @@ const char *kCFStreamVarName = "grpc_cfstream"; _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; - GRPCWrappedCall *wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; + GRPCWrappedCall *wrappedCall = + [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; if (wrappedCall == nil) { [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{ - NSLocalizedDescriptionKey : - @"Failed to create call or channel." - }]]; + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; return; } - @synchronized (self) { + @synchronized(self) { _wrappedCall = wrappedCall; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 3d137a53ffc..b0f4ced99e8 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -66,7 +66,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Users should not use this initializer directly. Call objects will be created, initialized, and @@ -92,7 +92,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Users should not use this initializer directly. Call objects will be created, initialized, and diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index 7fc353391f3..d681163419d 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -449,28 +449,29 @@ static const NSTimeInterval kTestTimeout = 16; request.responseSize = kSimpleDataLength; request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kUnaryCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = GRPCTransportTypeInsecure; options.compressionAlgorithm = GRPCCompressGzip; GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler: [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(NSData *data) { - NSError *error; - RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:data error:&error]; - XCTAssertNil(error, @"Error when parsing response: %@", error); - XCTAssertEqual(response.payload.body.length, kSimpleDataLength); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error, @"Received failure: %@", error); - [completion fulfill]; - }] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + NSError *error; + RMTSimpleResponse *response = + [RMTSimpleResponse parseFromData:data error:&error]; + XCTAssertNil(error, @"Error when parsing response: %@", error); + XCTAssertEqual(response.payload.body.length, kSimpleDataLength); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Received failure: %@", error); + [completion fulfill]; + }] - callOptions:options]; + callOptions:options]; [call start]; [call writeData:[request data]]; From 9e5d7476ac48b82ee8ce7855c30d3aa5edab5280 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 7 Nov 2018 11:32:12 -0800 Subject: [PATCH 0183/2143] nit build fix --- src/objective-c/GRPCClient/GRPCCallOptions.m | 4 ++-- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 2 +- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 3e0dbbf7e42..ecb517762b3 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -17,7 +17,7 @@ */ #import "GRPCCallOptions.h" -#import "internal/GRPCCallOptions+internal.h" +#import "internal/GRPCCallOptions+Internal.h" // The default values for the call options. static NSString *const kDefaultServerAuthority = nil; @@ -77,7 +77,7 @@ BOOL areObjectsEqual(id obj1, id obj2) { NSString *_PEMCertChain; GRPCTransportType _transportType; NSString *_hostNameOverride; - id _logContext; + id _logContext; NSString *_channelPoolDomain; NSUInteger _channelID; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 627bbab3c01..b4a589ae838 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -18,7 +18,7 @@ #import -#import "../internal/GRPCCallOptions+internal.h" +#import "../internal/GRPCCallOptions+Internal.h" #import "GRPCChannel.h" #import "GRPCChannelFactory.h" #import "GRPCChannelPool.h" diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 8a59bd43d74..a67162c1014 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -25,7 +25,7 @@ #include #include -#import "../internal/GRPCCallOptions+internal.h" +#import "../internal/GRPCCallOptions+Internal.h" #import "GRPCChannelFactory.h" #import "GRPCCompletionQueue.h" #import "GRPCConnectivityMonitor.h" From c9c060c52da12cc55bbd383b1544260ad665dbab Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 7 Nov 2018 11:32:30 -0800 Subject: [PATCH 0184/2143] nit fixes in ChannelArgsUtil --- src/objective-c/GRPCClient/private/ChannelArgsUtil.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index b8342a79e79..d9e44b557d1 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -31,7 +31,7 @@ static void *copy_pointer_arg(void *p) { static void destroy_pointer_arg(void *p) { // Decrease ref count to the object when destroying - CFRelease((CFTreeRef)p); + CFRelease((CFTypeRef)p); } static int cmp_pointer_arg(void *p, void *q) { return p == q; } @@ -52,7 +52,7 @@ void GRPCFreeChannelArgs(grpc_channel_args *channel_args) { } grpc_channel_args *GRPCBuildChannelArgs(NSDictionary *dictionary) { - if (!dictionary) { + if (dictionary.count == 0) { return NULL; } From 9759a1b241c11203f6630634d8cb3e38aefd8aaa Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 7 Nov 2018 15:21:04 -0800 Subject: [PATCH 0185/2143] removed accidental submodule update --- bazel/grpc_build_system.bzl | 3 +- test/core/gpr/BUILD | 2 +- test/core/iomgr/BUILD | 2 +- test/cpp/qps/BUILD | 2 +- third_party/toolchains/BUILD | 37 +++++++++++++++---- .../toolchains/RBE_USE_MACHINE_TYPE_LARGE | 1 - third_party/toolchains/machine_size/BUILD | 31 ++++++++++++++++ tools/remote_build/rbe_common.bazelrc | 4 +- 8 files changed, 68 insertions(+), 14 deletions(-) delete mode 100644 third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE create mode 100644 third_party/toolchains/machine_size/BUILD diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 159ebd5d1fe..22c77e468fb 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -131,7 +131,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 = []): +def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = "moderate", tags = [], exec_compatible_with = []): copts = [] if language.upper() == "C": copts = if_not_windows(["-std=c99"]) @@ -145,6 +145,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data "linkopts": if_not_windows(["-pthread"]), "size": size, "timeout": timeout, + "exec_compatible_with": exec_compatible_with, } if uses_polling: native.cc_test(testonly = True, tags = ["manual"], **args) diff --git a/test/core/gpr/BUILD b/test/core/gpr/BUILD index d58d4f2a14d..67657ee1ce9 100644 --- a/test/core/gpr/BUILD +++ b/test/core/gpr/BUILD @@ -81,12 +81,12 @@ grpc_cc_test( grpc_cc_test( name = "mpscq_test", srcs = ["mpscq_test.cc"], + exec_compatible_with = ["//third_party/toolchains/machine_size:large"], language = "C++", deps = [ "//:gpr", "//test/core/util:gpr_test_util", ], - data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"], ) grpc_cc_test( diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 70ee83acd23..e278632e502 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -40,7 +40,7 @@ grpc_cc_library( grpc_cc_test( name = "combiner_test", srcs = ["combiner_test.cc"], - data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"], + exec_compatible_with = ["//third_party/toolchains/machine_size:large"], language = "C++", deps = [ "//:gpr", diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index 26f43284a68..626ac5f3f2e 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -170,7 +170,7 @@ grpc_cc_test( grpc_cc_test( name = "qps_openloop_test", srcs = ["qps_openloop_test.cc"], - data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"], + exec_compatible_with = ["//third_party/toolchains/machine_size:large"], deps = [ ":benchmark_config", ":driver_impl", diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 02cd87a7b9b..efb52736fe5 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -16,36 +16,59 @@ licenses(["notice"]) # Apache v2 package(default_visibility = ["//visibility:public"]) -exports_files(["RBE_USE_MACHINE_TYPE_LARGE",]) - # Latest RBE Ubuntu16_04 container # Update every time when a new container is released. alias( name = "rbe_ubuntu1604", - actual = ":rbe_ubuntu1604_r328903", + actual = ":rbe_ubuntu1604_r340178", ) -# RBE Ubuntu16_04 r328903 +alias( + name = "rbe_ubuntu1604_large", + actual = ":rbe_ubuntu1604_r340178_large", +) + +# RBE Ubuntu16_04 r340178 platform( - name = "rbe_ubuntu1604_r328903", + name = "rbe_ubuntu1604_r340178", constraint_values = [ "@bazel_tools//platforms:x86_64", "@bazel_tools//platforms:linux", "@bazel_tools//tools/cpp:clang", "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", + "//third_party/toolchains/machine_size:standard", ], remote_execution_properties = """ properties: { name: "container-image" - value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:59bf0e191a6b5cc1ab62c2224c810681d1326bad5a27b1d36c9f40113e79da7f" + value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:9bd8ba020af33edb5f11eff0af2f63b3bcb168cd6566d7b27c6685e717787928" } properties: { name: "gceMachineType" # Small machines for majority of tests. value: "n1-highmem-2" } + """, +) + +# RBE Ubuntu16_04 r340178 large +platform( + name = "rbe_ubuntu1604_r340178_large", + constraint_values = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:linux", + "@bazel_tools//tools/cpp:clang", + "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", + "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", + "//third_party/toolchains/machine_size:large", + ], + remote_execution_properties = """ properties: { - name: "gceMachineType_LARGE" # Large machines for a small set of resource-consuming tests such as combiner_tests under TSAN. + name: "container-image" + value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:9bd8ba020af33edb5f11eff0af2f63b3bcb168cd6566d7b27c6685e717787928" + } + properties: { + name: "gceMachineType" # Small machines for majority of tests. value: "n1-standard-8" } """, diff --git a/third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE b/third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE deleted file mode 100644 index b1120238d7e..00000000000 --- a/third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE +++ /dev/null @@ -1 +0,0 @@ -# This file is a sentinel and is meant to be empty. diff --git a/third_party/toolchains/machine_size/BUILD b/third_party/toolchains/machine_size/BUILD new file mode 100644 index 00000000000..cc962946c31 --- /dev/null +++ b/third_party/toolchains/machine_size/BUILD @@ -0,0 +1,31 @@ +# 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. + +licenses(["notice"]) # Apache v2 + +package(default_visibility = ["//visibility:public"]) + +constraint_setting(name = "machine_size") + +constraint_value( + name = "large", + constraint_setting = ":machine_size", +) + +constraint_value( + name = "standard", + constraint_setting = ":machine_size", +) + +# Add other constraint values as needed (tiny, huge, etc.) in the future. diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index e8c7f0b9cb6..3f8a4cb1931 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -21,9 +21,9 @@ startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain build --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default # Use custom execution platforms defined in third_party/toolchains -build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 +build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large build --host_platform=//third_party/toolchains:rbe_ubuntu1604 -build --platforms=//third_party/toolchains:rbe_ubuntu1604 +build --platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large build --spawn_strategy=remote build --strategy=Javac=remote From d72d5b2c8eaa8a434a7db4624fe6a45bc0d6bde4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 8 Nov 2018 15:33:27 -0800 Subject: [PATCH 0186/2143] Some nit fixes --- src/objective-c/GRPCClient/GRPCCall.m | 4 +++- .../GRPCClient/private/GRPCChannel.m | 21 +++++++++++-------- .../GRPCClient/private/GRPCChannelPool.h | 2 -- .../GRPCClient/private/GRPCChannelPool.m | 1 + 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 321a0bd1bd7..9b9b4f95471 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -108,6 +108,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; /** Flags whether call has been canceled. */ BOOL _canceled; /** Flags whether call has been finished. */ + BOOL _finished; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -144,6 +145,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); _started = NO; _canceled = NO; + _finished = YES; } return self; @@ -252,7 +254,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)finish { dispatch_async(_dispatchQueue, ^{ - NSAssert(self->started, @"Call not started."); + NSAssert(self->_started, @"Call not started."); NSAssert(!self->_canceled, @"Call arleady canceled."); NSAssert(!self->_finished, @"Call already half-closed."); if (self->_call) { diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 0ca2a359926..773f4261d75 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -53,7 +53,7 @@ static GRPCChannelPool *gChannelPool; /** Reduce call ref count to the channel and maybe set the timer. */ - (void)unrefChannel; -/** Disconnect the channel immediately. */ +/** Disconnect the channel. Any further ref/unref are discarded. */ - (void)disconnect; @end @@ -67,9 +67,8 @@ static GRPCChannelPool *gChannelPool; dispatch_queue_t _dispatchQueue; /** - * Date and time when last timer is scheduled. When a timer is fired, if - * _lastDispatch + _destroyDelay < now, it can be determined that another timer is scheduled after - * schedule of the current timer, hence the current one should be discarded. + * Date and time when last timer is scheduled. If a firing timer's scheduled date is different + * from this, it is discarded. */ NSDate *_lastDispatch; } @@ -113,7 +112,7 @@ static GRPCChannelPool *gChannelPool; dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); dispatch_after(delay, self->_dispatchQueue, ^{ - [self timerFireWithScheduleDate:now]; + [self timedDisconnectWithScheduleDate:now]; }); } } @@ -131,7 +130,7 @@ static GRPCChannelPool *gChannelPool; }); } -- (void)timerFireWithScheduleDate:(NSDate *)scheduleDate { +- (void)timedDisconnectWithScheduleDate:(NSDate *)scheduleDate { dispatch_async(_dispatchQueue, ^{ if (self->_disconnected || self->_lastDispatch != scheduleDate) { return; @@ -183,6 +182,8 @@ static GRPCChannelPool *gChannelPool; grpc_slice_unref(host_slice); } grpc_slice_unref(path_slice); + } else { + NSAssert(self->_unmanagedChannel != nil, @"Invalid channeg."); } }); return call; @@ -255,10 +256,9 @@ static GRPCChannelPool *gChannelPool; } + (nullable instancetype)createChannelWithConfiguration:(GRPCChannelConfiguration *)config { + NSAssert(config != nil, @"configuration cannot be empty"); NSString *host = config.host; - if (host.length == 0) { - return nil; - } + NSAssert(host.length != 0, @"host cannot be nil"); NSDictionary *channelArgs; if (config.callOptions.additionalChannelArgs.count != 0) { @@ -287,6 +287,9 @@ static GRPCChannelPool *gChannelPool; GRPCChannelConfiguration *channelConfig = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; + if (channelConfig == nil) { + return nil; + } return [gChannelPool channelWithConfiguration:channelConfig]; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 2244361df2c..f99c0ba4dc2 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -57,8 +57,6 @@ NS_ASSUME_NONNULL_BEGIN */ @interface GRPCChannelPool : NSObject -- (instancetype)init; - /** * Return a channel with a particular configuration. If the channel does not exist, execute \a * createChannel then add it in the pool. If the channel exists, increase its reference count. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index b4a589ae838..1bf2a5c5633 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -192,6 +192,7 @@ extern const char *kCFStreamVarName; } - (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration { + NSAssert(configuration != nil, @"Must has a configuration"); GRPCChannel *channel; @synchronized(self) { if ([_channelPool objectForKey:configuration]) { From c21393e553e7ab528edb5966c835bc0832ea4edf Mon Sep 17 00:00:00 2001 From: "tongxuan.ltx" Date: Thu, 8 Nov 2018 10:43:18 +0800 Subject: [PATCH 0187/2143] g_default_client_callbacks shouldn't be global variable In tensorflow, RPC client thread doesn't active release, rely on process to cleanup. If process have already cleanup the global variable(g_default_client_callbacks), after that client issue a RPC call which contains the ClientContext, then once ClientContext destructor called, pure virtual functions call error is reported. --- src/cpp/client/client_context.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc index 50da75f09c1..c9ea3e5f83b 100644 --- a/src/cpp/client/client_context.cc +++ b/src/cpp/client/client_context.cc @@ -41,9 +41,10 @@ class DefaultGlobalClientCallbacks final }; static internal::GrpcLibraryInitializer g_gli_initializer; -static DefaultGlobalClientCallbacks g_default_client_callbacks; +static DefaultGlobalClientCallbacks* g_default_client_callbacks = + new DefaultGlobalClientCallbacks(); static ClientContext::GlobalCallbacks* g_client_callbacks = - &g_default_client_callbacks; + g_default_client_callbacks; ClientContext::ClientContext() : initial_metadata_received_(false), @@ -139,9 +140,9 @@ grpc::string ClientContext::peer() const { } void ClientContext::SetGlobalCallbacks(GlobalCallbacks* client_callbacks) { - GPR_ASSERT(g_client_callbacks == &g_default_client_callbacks); + GPR_ASSERT(g_client_callbacks == g_default_client_callbacks); GPR_ASSERT(client_callbacks != nullptr); - GPR_ASSERT(client_callbacks != &g_default_client_callbacks); + GPR_ASSERT(client_callbacks != g_default_client_callbacks); g_client_callbacks = client_callbacks; } From 37dbad80d5254f9bf17076d12b22b7a081e6e9dc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 8 Nov 2018 22:01:10 -0800 Subject: [PATCH 0188/2143] Refactor channel pool --- .../GRPCClient/GRPCCall+ChannelArg.m | 4 +- .../GRPCClient/private/GRPCChannel.h | 71 ++- .../GRPCClient/private/GRPCChannel.m | 413 ++++++++++-------- .../GRPCClient/private/GRPCChannelPool.h | 55 ++- .../GRPCClient/private/GRPCChannelPool.m | 217 ++------- .../GRPCClient/private/GRPCWrappedCall.m | 24 +- .../tests/ChannelTests/ChannelPoolTest.m | 173 ++++---- .../tests/ChannelTests/ChannelTests.m | 97 ++-- 8 files changed, 498 insertions(+), 556 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m index d01d0c0d4fd..971c2803e29 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m @@ -18,7 +18,7 @@ #import "GRPCCall+ChannelArg.h" -#import "private/GRPCChannel.h" +#import "private/GRPCChannelPool.h" #import "private/GRPCHost.h" #import @@ -36,7 +36,7 @@ } + (void)closeOpenConnections { - [GRPCChannel closeOpenConnections]; + [GRPCChannelPool closeOpenConnections]; } + (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host { diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index e1bf8fb1af4..bbe0ba53904 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -20,11 +20,37 @@ #include +@protocol GRPCChannelFactory; + @class GRPCCompletionQueue; @class GRPCCallOptions; @class GRPCChannelConfiguration; struct grpc_channel_credentials; +NS_ASSUME_NONNULL_BEGIN + +/** Caching signature of a channel. */ +@interface GRPCChannelConfiguration : NSObject + +/** The host that this channel is connected to. */ +@property(copy, readonly) NSString *host; + +/** + * Options of the corresponding call. Note that only the channel-related options are of interest to + * this class. + */ +@property(strong, readonly) GRPCCallOptions *callOptions; + +/** Acquire the factory to generate a new channel with current configurations. */ +@property(readonly) id channelFactory; + +/** Acquire the dictionary of channel args with current configurations. */ +@property(copy, readonly) NSDictionary *channelArgs; + +- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; + +@end + /** * Each separate instance of this class represents at least one TCP connection to the provided host. */ @@ -35,40 +61,45 @@ struct grpc_channel_credentials; + (nullable instancetype) new NS_UNAVAILABLE; /** - * Returns a channel connecting to \a host with options as \a callOptions. The channel may be new - * or a cached channel that is already connected. + * Create a channel with remote \a host and signature \a channelConfigurations. Destroy delay is + * defaulted to 30 seconds. */ -+ (nullable instancetype)channelWithHost:(nonnull NSString *)host - callOptions:(nullable GRPCCallOptions *)callOptions; +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration; /** - * Create a channel object with the signature \a config. + * Create a channel with remote \a host, signature \a channelConfigurations, and destroy delay of + * \a destroyDelay. */ -+ (nullable instancetype)createChannelWithConfiguration:(nonnull GRPCChannelConfiguration *)config; +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay NS_DESIGNATED_INITIALIZER; /** - * Get a grpc core call object from this channel. + * Create a grpc core call object from this channel. The channel's refcount is added by 1. If no + * call is created, NULL is returned, and if the reason is because the channel is already + * disconnected, \a disconnected is set to YES. When the returned call is unreffed, the caller is + * obligated to call \a unref method once. \a disconnected may be null. */ -- (nullable grpc_call *)unmanagedCallWithPath:(nonnull NSString *)path - completionQueue:(nonnull GRPCCompletionQueue *)queue - callOptions:(nonnull GRPCCallOptions *)callOptions; +- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions + disconnected:(BOOL * _Nullable)disconnected; /** - * Increase the refcount of the channel. If the channel was timed to be destroyed, cancel the timer. - */ -- (void)ref; - -/** - * Decrease the refcount of the channel. If the refcount of the channel decrease to 0, the channel - * is destroyed after 30 seconds. + * Unref the channel when a call is done. It also decreases the channel's refcount. If the refcount + * of the channel decreases to 0, the channel is destroyed after the destroy delay. */ - (void)unref; /** - * Force the channel to be disconnected and destroyed immediately. + * Force the channel to be disconnected and destroyed. */ - (void)disconnect; -// TODO (mxyan): deprecate with GRPCCall:closeOpenConnections -+ (void)closeOpenConnections; +/** + * Return whether the channel is already disconnected. + */ +@property(readonly) BOOL disconnected; + @end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 773f4261d75..298b6605d1f 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -28,141 +28,222 @@ #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "version.h" +#import "../internal/GRPCCallOptions+Internal.h" #import #import /** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ -NSTimeInterval kChannelDestroyDelay = 30; +NSTimeInterval kDefaultChannelDestroyDelay = 30; -/** Global instance of channel pool. */ -static GRPCChannelPool *gChannelPool; +@implementation GRPCChannelConfiguration -/** - * Time the channel destroy when the channel's calls are unreffed. If there's new call, reset the - * timer. - */ -@interface GRPCChannelRef : NSObject - -- (instancetype)initWithDestroyDelay:(NSTimeInterval)destroyDelay - destroyChannelCallback:(void (^)())destroyChannelCallback; - -/** Add call ref count to the channel and maybe reset the timer. */ -- (void)refChannel; - -/** Reduce call ref count to the channel and maybe set the timer. */ -- (void)unrefChannel; - -/** Disconnect the channel. Any further ref/unref are discarded. */ -- (void)disconnect; - -@end - -@implementation GRPCChannelRef { - NSTimeInterval _destroyDelay; - void (^_destroyChannelCallback)(); - - NSUInteger _refCount; - BOOL _disconnected; - dispatch_queue_t _dispatchQueue; - - /** - * Date and time when last timer is scheduled. If a firing timer's scheduled date is different - * from this, it is discarded. - */ - NSDate *_lastDispatch; -} - -- (instancetype)initWithDestroyDelay:(NSTimeInterval)destroyDelay - destroyChannelCallback:(void (^)())destroyChannelCallback { +- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { + NSAssert(host.length, @"Host must not be empty."); + NSAssert(callOptions, @"callOptions must not be empty."); if ((self = [super init])) { - _destroyDelay = destroyDelay; - _destroyChannelCallback = destroyChannelCallback; - - _refCount = 1; - _disconnected = NO; - if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); - } else { - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - } - _lastDispatch = nil; + _host = [host copy]; + _callOptions = [callOptions copy]; } return self; } -- (void)refChannel { - dispatch_async(_dispatchQueue, ^{ - if (!self->_disconnected) { - self->_refCount++; - self->_lastDispatch = nil; - } - }); -} - -- (void)unrefChannel { - dispatch_async(_dispatchQueue, ^{ - if (!self->_disconnected) { - self->_refCount--; - if (self->_refCount == 0) { - NSDate *now = [NSDate date]; - self->_lastDispatch = now; - dispatch_time_t delay = - dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); - dispatch_after(delay, self->_dispatchQueue, ^{ - [self timedDisconnectWithScheduleDate:now]; - }); +- (id)channelFactory { + NSError *error; + id factory; + GRPCTransportType type = _callOptions.transportType; + switch (type) { + case GRPCTransportTypeChttp2BoringSSL: + // TODO (mxyan): Remove when the API is deprecated +#ifdef GRPC_COMPILE_WITH_CRONET + if (![GRPCCall isUsingCronet]) { +#endif + factory = [GRPCSecureChannelFactory + factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates + privateKey:_callOptions.PEMPrivateKey + certChain:_callOptions.PEMCertChain + error:&error]; + if (factory == nil) { + NSLog(@"Error creating secure channel factory: %@", error); + } + return factory; +#ifdef GRPC_COMPILE_WITH_CRONET } - } - }); +#endif + // fallthrough + case GRPCTransportTypeCronet: + return [GRPCCronetChannelFactory sharedInstance]; + case GRPCTransportTypeInsecure: + return [GRPCInsecureChannelFactory sharedInstance]; + } } -- (void)disconnect { - dispatch_async(_dispatchQueue, ^{ - if (!self->_disconnected) { - self->_lastDispatch = nil; - self->_disconnected = YES; - // Break retain loop - self->_destroyChannelCallback = nil; - } - }); +- (NSDictionary *)channelArgs { + NSMutableDictionary *args = [NSMutableDictionary new]; + + NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; + NSString *userAgentPrefix = _callOptions.userAgentPrefix; + if (userAgentPrefix) { + args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = + [_callOptions.userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; + } else { + args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = userAgent; + } + + NSString *hostNameOverride = _callOptions.hostNameOverride; + if (hostNameOverride) { + args[@GRPC_SSL_TARGET_NAME_OVERRIDE_ARG] = hostNameOverride; + } + + if (_callOptions.responseSizeLimit) { + args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = + [NSNumber numberWithUnsignedInteger:_callOptions.responseSizeLimit]; + } + + if (_callOptions.compressionAlgorithm != GRPC_COMPRESS_NONE) { + args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = + [NSNumber numberWithInt:_callOptions.compressionAlgorithm]; + } + + if (_callOptions.keepaliveInterval != 0) { + args[@GRPC_ARG_KEEPALIVE_TIME_MS] = + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; + args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; + } + + if (_callOptions.retryEnabled == NO) { + args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.retryEnabled]; + } + + if (_callOptions.connectMinTimeout > 0) { + args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMinTimeout * 1000)]; + } + if (_callOptions.connectInitialBackoff > 0) { + args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber + numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectInitialBackoff * 1000)]; + } + if (_callOptions.connectMaxBackoff > 0) { + args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMaxBackoff * 1000)]; + } + + if (_callOptions.logContext != nil) { + args[@GRPC_ARG_MOBILE_LOG_CONTEXT] = _callOptions.logContext; + } + + if (_callOptions.channelPoolDomain.length != 0) { + args[@GRPC_ARG_CHANNEL_POOL_DOMAIN] = _callOptions.channelPoolDomain; + } + + [args addEntriesFromDictionary:_callOptions.additionalChannelArgs]; + + return args; } -- (void)timedDisconnectWithScheduleDate:(NSDate *)scheduleDate { - dispatch_async(_dispatchQueue, ^{ - if (self->_disconnected || self->_lastDispatch != scheduleDate) { - return; - } - self->_lastDispatch = nil; - self->_disconnected = YES; - self->_destroyChannelCallback(); - // Break retain loop - self->_destroyChannelCallback = nil; - }); +- (nonnull id)copyWithZone:(nullable NSZone *)zone { + GRPCChannelConfiguration *newConfig = + [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; + + return newConfig; +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[GRPCChannelConfiguration class]]) { + return NO; + } + GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; + if (!(obj.host == _host || (_host != nil && [obj.host isEqualToString:_host]))) return NO; + if (!(obj.callOptions == _callOptions || [obj.callOptions hasChannelOptionsEqualTo:_callOptions])) + return NO; + + return YES; +} + +- (NSUInteger)hash { + NSUInteger result = 0; + result ^= _host.hash; + result ^= _callOptions.channelOptionsHash; + + return result; } @end + + @implementation GRPCChannel { GRPCChannelConfiguration *_configuration; - grpc_channel *_unmanagedChannel; - GRPCChannelRef *_channelRef; + dispatch_queue_t _dispatchQueue; + grpc_channel *_unmanagedChannel; + NSTimeInterval _destroyDelay; + + NSUInteger _refcount; + NSDate *_lastDispatch; +} +@synthesize disconnected = _disconnected; + +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { + return [self initWithChannelConfiguration:channelConfiguration + destroyDelay:kDefaultChannelDestroyDelay]; +} + +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay { + NSAssert(channelConfiguration, @"channelConfiguration must not be empty."); + NSAssert(destroyDelay > 0, @"destroyDelay must be greater than 0."); + if ((self = [super init])) { + _configuration = [channelConfiguration copy]; + if (@available(iOS 8.0, *)) { + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + } else { + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } + + // Create gRPC core channel object. + NSString *host = channelConfiguration.host; + NSAssert(host.length != 0, @"host cannot be nil"); + NSDictionary *channelArgs; + if (channelConfiguration.callOptions.additionalChannelArgs.count != 0) { + NSMutableDictionary *args = [channelConfiguration.channelArgs mutableCopy]; + [args addEntriesFromDictionary:channelConfiguration.callOptions.additionalChannelArgs]; + channelArgs = args; + } else { + channelArgs = channelConfiguration.channelArgs; + } + id factory = channelConfiguration.channelFactory; + _unmanagedChannel = [factory createChannelWithHost:host channelArgs:channelArgs]; + if (_unmanagedChannel == NULL) { + NSLog(@"Unable to create channel."); + return nil; + } + _destroyDelay = destroyDelay; + _disconnected = NO; + } + return self; } - (grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions { + callOptions:(GRPCCallOptions *)callOptions + disconnected:(BOOL *)disconnected { NSAssert(path.length, @"path must not be empty."); NSAssert(queue, @"completionQueue must not be empty."); NSAssert(callOptions, @"callOptions must not be empty."); - __block grpc_call *call = nil; + __block BOOL isDisconnected = NO; + __block grpc_call *call = NULL; dispatch_sync(_dispatchQueue, ^{ - if (self->_unmanagedChannel) { + if (self->_disconnected) { + isDisconnected = YES; + } else { + NSAssert(self->_unmanagedChannel != NULL, @"Invalid channel."); + NSString *serverAuthority = - callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); grpc_slice host_slice = grpc_empty_slice(); @@ -171,10 +252,10 @@ static GRPCChannelPool *gChannelPool; } grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); gpr_timespec deadline_ms = - timeout == 0 - ? gpr_inf_future(GPR_CLOCK_REALTIME) - : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + timeout == 0 + ? gpr_inf_future(GPR_CLOCK_REALTIME) + : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); call = grpc_channel_create_call(self->_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, serverAuthority ? &host_slice : NULL, deadline_ms, NULL); @@ -182,71 +263,64 @@ static GRPCChannelPool *gChannelPool; grpc_slice_unref(host_slice); } grpc_slice_unref(path_slice); - } else { - NSAssert(self->_unmanagedChannel != nil, @"Invalid channeg."); + if (call == NULL) { + NSLog(@"Unable to create call."); + } else { + // Ref the channel; + [self ref]; + } } }); + if (disconnected != nil) { + *disconnected = isDisconnected; + } return call; } +// This function should be called on _dispatchQueue. - (void)ref { - dispatch_async(_dispatchQueue, ^{ - if (self->_unmanagedChannel) { - [self->_channelRef refChannel]; - } - }); + _refcount++; + if (_refcount == 1 && _lastDispatch != nil) { + _lastDispatch = nil; + } } - (void)unref { dispatch_async(_dispatchQueue, ^{ - if (self->_unmanagedChannel) { - [self->_channelRef unrefChannel]; + self->_refcount--; + if (self->_refcount == 0 && !self->_disconnected) { + // Start timer. + dispatch_time_t delay = + dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); + NSDate *now = [NSDate date]; + self->_lastDispatch = now; + dispatch_after(delay, self->_dispatchQueue, ^{ + if (self->_lastDispatch == now) { + grpc_channel_destroy(self->_unmanagedChannel); + self->_unmanagedChannel = NULL; + self->_disconnected = YES; + } + }); } }); } - (void)disconnect { dispatch_async(_dispatchQueue, ^{ - if (self->_unmanagedChannel) { + if (!self->_disconnected) { grpc_channel_destroy(self->_unmanagedChannel); self->_unmanagedChannel = nil; - [self->_channelRef disconnect]; + self->_disconnected = YES; } }); } -- (void)destroyChannel { - dispatch_async(_dispatchQueue, ^{ - if (self->_unmanagedChannel) { - grpc_channel_destroy(self->_unmanagedChannel); - self->_unmanagedChannel = nil; - [gChannelPool removeChannel:self]; - } +- (BOOL)disconnected { + __block BOOL disconnected; + dispatch_sync(_dispatchQueue, ^{ + disconnected = self->_disconnected; }); -} - -- (nullable instancetype)initWithUnmanagedChannel:(grpc_channel *_Nullable)unmanagedChannel - configuration:(GRPCChannelConfiguration *)configuration { - NSAssert(configuration, @"Configuration must not be empty."); - if (!unmanagedChannel) { - return nil; - } - if ((self = [super init])) { - _unmanagedChannel = unmanagedChannel; - _configuration = [configuration copy]; - _channelRef = [[GRPCChannelRef alloc] initWithDestroyDelay:kChannelDestroyDelay - destroyChannelCallback:^{ - [self destroyChannel]; - }]; - if (@available(iOS 8.0, *)) { - _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); - } else { - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - } - } - return self; + return disconnected; } - (void)dealloc { @@ -255,47 +329,4 @@ static GRPCChannelPool *gChannelPool; } } -+ (nullable instancetype)createChannelWithConfiguration:(GRPCChannelConfiguration *)config { - NSAssert(config != nil, @"configuration cannot be empty"); - NSString *host = config.host; - NSAssert(host.length != 0, @"host cannot be nil"); - - NSDictionary *channelArgs; - if (config.callOptions.additionalChannelArgs.count != 0) { - NSMutableDictionary *args = [config.channelArgs mutableCopy]; - [args addEntriesFromDictionary:config.callOptions.additionalChannelArgs]; - channelArgs = args; - } else { - channelArgs = config.channelArgs; - } - id factory = config.channelFactory; - grpc_channel *unmanaged_channel = [factory createChannelWithHost:host channelArgs:channelArgs]; - return [[GRPCChannel alloc] initWithUnmanagedChannel:unmanaged_channel configuration:config]; -} - -+ (nullable instancetype)channelWithHost:(NSString *)host - callOptions:(GRPCCallOptions *)callOptions { - static dispatch_once_t initChannelPool; - dispatch_once(&initChannelPool, ^{ - gChannelPool = [[GRPCChannelPool alloc] init]; - }); - - NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:host]]; - if (hostURL.host && !hostURL.port) { - host = [hostURL.host stringByAppendingString:@":443"]; - } - - GRPCChannelConfiguration *channelConfig = - [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; - if (channelConfig == nil) { - return nil; - } - - return [gChannelPool channelWithConfiguration:channelConfig]; -} - -+ (void)closeOpenConnections { - [gChannelPool removeAndCloseAllChannels]; -} - @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index f99c0ba4dc2..24c0a8df115 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -29,48 +29,45 @@ NS_ASSUME_NONNULL_BEGIN @class GRPCChannel; -/** Caching signature of a channel. */ -@interface GRPCChannelConfiguration : NSObject - -/** The host that this channel is connected to. */ -@property(copy, readonly) NSString *host; - -/** - * Options of the corresponding call. Note that only the channel-related options are of interest to - * this class. - */ -@property(strong, readonly) GRPCCallOptions *callOptions; - -/** Acquire the factory to generate a new channel with current configurations. */ -@property(readonly) id channelFactory; - -/** Acquire the dictionary of channel args with current configurations. */ -@property(copy, readonly) NSDictionary *channelArgs; - -- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; - -@end - /** * Manage the pool of connected channels. When a channel is no longer referenced by any call, * destroy the channel after a certain period of time elapsed. */ @interface GRPCChannelPool : NSObject +/** + * Get the singleton instance + */ ++ (nullable instancetype)sharedInstance; + /** * Return a channel with a particular configuration. If the channel does not exist, execute \a * createChannel then add it in the pool. If the channel exists, increase its reference count. */ -- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration; +- (GRPCChannel *)channelWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions; -/** Remove a channel from the pool. */ -- (void)removeChannel:(GRPCChannel *)channel; +/** + * This method is deprecated. + * + * Destroy all open channels and close their connections. + */ ++ (void)closeOpenConnections; -/** Clear all channels in the pool. */ -- (void)removeAllChannels; +// Test-only methods below -/** Clear all channels in the pool and destroy the channels. */ -- (void)removeAndCloseAllChannels; +/** + * Return a channel with a special destroy delay. If \a destroyDelay is 0, use the default destroy + * delay. + */ +- (GRPCChannel *)channelWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions + destroyDelay:(NSTimeInterval)destroyDelay; + +/** + * Simulate a network transition event and destroy all channels. + */ +- (void)destroyAllChannels; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 1bf2a5c5633..98c1634bc8b 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -33,147 +33,23 @@ extern const char *kCFStreamVarName; -@implementation GRPCChannelConfiguration - -- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { - NSAssert(host.length, @"Host must not be empty."); - NSAssert(callOptions, @"callOptions must not be empty."); - if ((self = [super init])) { - _host = [host copy]; - _callOptions = [callOptions copy]; - } - return self; -} - -- (id)channelFactory { - NSError *error; - id factory; - GRPCTransportType type = _callOptions.transportType; - switch (type) { - case GRPCTransportTypeChttp2BoringSSL: - // TODO (mxyan): Remove when the API is deprecated -#ifdef GRPC_COMPILE_WITH_CRONET - if (![GRPCCall isUsingCronet]) { -#endif - factory = [GRPCSecureChannelFactory - factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates - privateKey:_callOptions.PEMPrivateKey - certChain:_callOptions.PEMCertChain - error:&error]; - if (factory == nil) { - NSLog(@"Error creating secure channel factory: %@", error); - } - return factory; -#ifdef GRPC_COMPILE_WITH_CRONET - } -#endif - // fallthrough - case GRPCTransportTypeCronet: - return [GRPCCronetChannelFactory sharedInstance]; - case GRPCTransportTypeInsecure: - return [GRPCInsecureChannelFactory sharedInstance]; - } -} - -- (NSDictionary *)channelArgs { - NSMutableDictionary *args = [NSMutableDictionary new]; - - NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; - NSString *userAgentPrefix = _callOptions.userAgentPrefix; - if (userAgentPrefix) { - args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = - [_callOptions.userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; - } else { - args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = userAgent; - } - - NSString *hostNameOverride = _callOptions.hostNameOverride; - if (hostNameOverride) { - args[@GRPC_SSL_TARGET_NAME_OVERRIDE_ARG] = hostNameOverride; - } - - if (_callOptions.responseSizeLimit) { - args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = - [NSNumber numberWithUnsignedInteger:_callOptions.responseSizeLimit]; - } - - if (_callOptions.compressionAlgorithm != GRPC_COMPRESS_NONE) { - args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = - [NSNumber numberWithInt:_callOptions.compressionAlgorithm]; - } - - if (_callOptions.keepaliveInterval != 0) { - args[@GRPC_ARG_KEEPALIVE_TIME_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; - args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; - } - - if (_callOptions.retryEnabled == NO) { - args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.retryEnabled]; - } - - if (_callOptions.connectMinTimeout > 0) { - args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMinTimeout * 1000)]; - } - if (_callOptions.connectInitialBackoff > 0) { - args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber - numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectInitialBackoff * 1000)]; - } - if (_callOptions.connectMaxBackoff > 0) { - args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMaxBackoff * 1000)]; - } - - if (_callOptions.logContext != nil) { - args[@GRPC_ARG_MOBILE_LOG_CONTEXT] = _callOptions.logContext; - } - - if (_callOptions.channelPoolDomain.length != 0) { - args[@GRPC_ARG_CHANNEL_POOL_DOMAIN] = _callOptions.channelPoolDomain; - } - - [args addEntriesFromDictionary:_callOptions.additionalChannelArgs]; - - return args; -} - -- (nonnull id)copyWithZone:(nullable NSZone *)zone { - GRPCChannelConfiguration *newConfig = - [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; - - return newConfig; -} - -- (BOOL)isEqual:(id)object { - if (![object isKindOfClass:[GRPCChannelConfiguration class]]) { - return NO; - } - GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; - if (!(obj.host == _host || (_host != nil && [obj.host isEqualToString:_host]))) return NO; - if (!(obj.callOptions == _callOptions || [obj.callOptions hasChannelOptionsEqualTo:_callOptions])) - return NO; - - return YES; -} - -- (NSUInteger)hash { - NSUInteger result = 0; - result ^= _host.hash; - result ^= _callOptions.channelOptionsHash; - - return result; -} - -@end - -#pragma mark GRPCChannelPool +static GRPCChannelPool *gChannelPool; +static dispatch_once_t gInitChannelPool; @implementation GRPCChannelPool { NSMutableDictionary *_channelPool; } ++ (nullable instancetype)sharedInstance { + dispatch_once(&gInitChannelPool, ^{ + gChannelPool = [[GRPCChannelPool alloc] init]; + if (gChannelPool == nil) { + [NSException raise:NSMallocException format:@"Cannot initialize global channel pool."]; + } + }); + return gChannelPool; +} + - (instancetype)init { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; @@ -187,61 +63,56 @@ extern const char *kCFStreamVarName; return self; } -- (void)dealloc { - [GRPCConnectivityMonitor unregisterObserver:self]; +- (GRPCChannel *)channelWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions { + return [self channelWithHost:host + callOptions:callOptions + destroyDelay:0]; } -- (GRPCChannel *)channelWithConfiguration:(GRPCChannelConfiguration *)configuration { - NSAssert(configuration != nil, @"Must has a configuration"); +- (GRPCChannel *)channelWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions + destroyDelay:(NSTimeInterval)destroyDelay { + NSAssert(host.length > 0, @"Host must not be empty."); + NSAssert(callOptions != nil, @"callOptions must not be empty."); GRPCChannel *channel; + GRPCChannelConfiguration *configuration = + [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; @synchronized(self) { - if ([_channelPool objectForKey:configuration]) { - channel = _channelPool[configuration]; - [channel ref]; - } else { - channel = [GRPCChannel createChannelWithConfiguration:configuration]; - if (channel != nil) { - _channelPool[configuration] = channel; + channel = _channelPool[configuration]; + if (channel == nil || channel.disconnected) { + if (destroyDelay == 0) { + channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration]; + } else { + channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:destroyDelay]; } + _channelPool[configuration] = channel; } } return channel; } -- (void)removeChannel:(GRPCChannel *)channel { - @synchronized(self) { - __block GRPCChannelConfiguration *keyToDelete = nil; - [_channelPool - enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, - GRPCChannel *_Nonnull obj, BOOL *_Nonnull stop) { - if (obj == channel) { - keyToDelete = key; - *stop = YES; - } - }]; - [self->_channelPool removeObjectForKey:keyToDelete]; - } + + ++ (void)closeOpenConnections { + [[GRPCChannelPool sharedInstance] destroyAllChannels]; } -- (void)removeAllChannels { +- (void)destroyAllChannels { @synchronized(self) { - _channelPool = [NSMutableDictionary dictionary]; - } -} - -- (void)removeAndCloseAllChannels { - @synchronized(self) { - [_channelPool - enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, - GRPCChannel *_Nonnull obj, BOOL *_Nonnull stop) { - [obj disconnect]; - }]; + for (id key in _channelPool) { + [_channelPool[key] disconnect]; + } _channelPool = [NSMutableDictionary dictionary]; } } - (void)connectivityChange:(NSNotification *)note { - [self removeAndCloseAllChannels]; + [self destroyAllChannels]; +} + +- (void)dealloc { + [GRPCConnectivityMonitor unregisterObserver:self]; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 577002e7a85..2358c7bb0a8 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -24,6 +24,7 @@ #include #import "GRPCChannel.h" +#import "GRPCChannelPool.h" #import "GRPCCompletionQueue.h" #import "GRPCHost.h" #import "NSData+GRPC.h" @@ -256,13 +257,21 @@ // consuming too many threads and having contention of multiple calls in a single completion // queue. Currently we use a singleton queue. _queue = [GRPCCompletionQueue completionQueue]; - _channel = [GRPCChannel channelWithHost:host callOptions:callOptions]; - if (_channel == nil) { - NSLog(@"Failed to get a channel for the host."); - return nil; - } - _call = [_channel unmanagedCallWithPath:path completionQueue:_queue callOptions:callOptions]; - if (_call == NULL) { + BOOL disconnected; + do { + _channel = [[GRPCChannelPool sharedInstance] channelWithHost:host callOptions:callOptions]; + if (_channel == nil) { + NSLog(@"Failed to get a channel for the host."); + return nil; + } + _call = [_channel unmanagedCallWithPath:path + completionQueue:_queue + callOptions:callOptions + disconnected:&disconnected]; + // Try create another channel if the current channel is disconnected (due to idleness or + // connectivity monitor disconnection). + } while (_call == NULL && disconnected); + if (_call == nil) { NSLog(@"Failed to create a call."); return nil; } @@ -317,6 +326,7 @@ - (void)dealloc { if (_call) { grpc_call_unref(_call); + [_channel unref]; } [_channel unref]; _channel = nil; diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index 5c3f0edba0b..d684db545e9 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -20,6 +20,7 @@ #import "../../GRPCClient/private/GRPCChannel.h" #import "../../GRPCClient/private/GRPCChannelPool.h" +#import "../../GRPCClient/private/GRPCCompletionQueue.h" #define TEST_TIMEOUT 32 @@ -35,92 +36,104 @@ NSString *kDummyHost = @"dummy.host"; grpc_init(); } -- (void)testCreateChannel { +- (void)testChannelPooling { NSString *kDummyHost = @"dummy.host"; + NSString *kDummyHost2 = @"dummy.host2"; + GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeInsecure; GRPCCallOptions *options2 = [options1 copy]; - GRPCChannelConfiguration *config1 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelConfiguration *config2 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCMutableCallOptions *options3 = [options2 mutableCopy]; + options3.transportType = GRPCTransportTypeInsecure; - GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; + GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; + + GRPCChannel *channel1 = [pool channelWithHost:kDummyHost + callOptions:options1]; + GRPCChannel *channel2 = [pool channelWithHost:kDummyHost + callOptions:options2]; + GRPCChannel *channel3 = [pool channelWithHost:kDummyHost2 + callOptions:options1]; + GRPCChannel *channel4 = [pool channelWithHost:kDummyHost + callOptions:options3]; XCTAssertEqual(channel1, channel2); -} - -- (void)testChannelRemove { - GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeInsecure; - GRPCChannelConfiguration *config1 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - [pool removeChannel:channel1]; - GRPCChannel *channel2 = [pool channelWithConfiguration:config1]; - XCTAssertNotEqual(channel1, channel2); -} - -extern NSTimeInterval kChannelDestroyDelay; - -- (void)testChannelTimeoutCancel { - NSTimeInterval kOriginalInterval = kChannelDestroyDelay; - kChannelDestroyDelay = 3.0; - GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeInsecure; - GRPCChannelConfiguration *config1 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - [channel1 unref]; - sleep(1); - GRPCChannel *channel2 = [pool channelWithConfiguration:config1]; - XCTAssertEqual(channel1, channel2); - sleep((int)kChannelDestroyDelay + 2); - GRPCChannel *channel3 = [pool channelWithConfiguration:config1]; - XCTAssertEqual(channel1, channel3); - kChannelDestroyDelay = kOriginalInterval; -} - -- (void)testChannelDisconnect { - NSString *kDummyHost = @"dummy.host"; - GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeInsecure; - GRPCCallOptions *options2 = [options1 copy]; - GRPCChannelConfiguration *config1 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelConfiguration *config2 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - - GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - [pool removeAndCloseAllChannels]; - GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; - XCTAssertNotEqual(channel1, channel2); -} - -- (void)testClearChannels { - GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeInsecure; - GRPCMutableCallOptions *options2 = [[GRPCMutableCallOptions alloc] init]; - options2.transportType = GRPCTransportTypeChttp2BoringSSL; - GRPCChannelConfiguration *config1 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options1]; - GRPCChannelConfiguration *config2 = - [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options2]; - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - - GRPCChannel *channel1 = [pool channelWithConfiguration:config1]; - GRPCChannel *channel2 = [pool channelWithConfiguration:config2]; - XCTAssertNotEqual(channel1, channel2); - - [pool removeAndCloseAllChannels]; - GRPCChannel *channel3 = [pool channelWithConfiguration:config1]; - GRPCChannel *channel4 = [pool channelWithConfiguration:config2]; XCTAssertNotEqual(channel1, channel3); - XCTAssertNotEqual(channel2, channel4); + XCTAssertNotEqual(channel1, channel4); + XCTAssertNotEqual(channel3, channel4); +} + +- (void)testDestroyAllChannels { + NSString *kDummyHost = @"dummy.host"; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; + GRPCChannel *channel = [pool channelWithHost:kDummyHost + callOptions:options]; + grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:nil]; + [pool destroyAllChannels]; + XCTAssertTrue(channel.disconnected); + GRPCChannel *channel2 = [pool channelWithHost:kDummyHost + callOptions:options]; + XCTAssertNotEqual(channel, channel2); + grpc_call_unref(call); +} + +- (void)testGetChannelBeforeChannelTimedDisconnection { + NSString *kDummyHost = @"dummy.host"; + const NSTimeInterval kDestroyDelay = 1; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; + GRPCChannel *channel = [pool channelWithHost:kDummyHost + callOptions:options + destroyDelay:kDestroyDelay]; + grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:nil]; + grpc_call_unref(call); + [channel unref]; + + // Test that we can still get the channel at this time + GRPCChannel *channel2 = [pool channelWithHost:kDummyHost + callOptions:options + destroyDelay:kDestroyDelay]; + XCTAssertEqual(channel, channel2); + call = [channel2 unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:nil]; + + // Test that after the destroy delay, the channel is still alive + sleep(kDestroyDelay + 1); + XCTAssertFalse(channel.disconnected); +} + +- (void)testGetChannelAfterChannelTimedDisconnection { + NSString *kDummyHost = @"dummy.host"; + const NSTimeInterval kDestroyDelay = 1; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; + GRPCChannel *channel = [pool channelWithHost:kDummyHost + callOptions:options + destroyDelay:kDestroyDelay]; + grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:nil]; + grpc_call_unref(call); + [channel unref]; + + sleep(kDestroyDelay + 1); + + // Test that we get new channel to the same host and with the same callOptions + GRPCChannel *channel2 = [pool channelWithHost:kDummyHost + callOptions:options + destroyDelay:kDestroyDelay]; + XCTAssertNotEqual(channel, channel2); } @end diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 64c3356b13f..27e76d41799 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -20,6 +20,7 @@ #import "../../GRPCClient/GRPCCallOptions.h" #import "../../GRPCClient/private/GRPCChannel.h" +#import "../../GRPCClient/private/GRPCCompletionQueue.h" @interface ChannelTests : XCTestCase @@ -31,63 +32,51 @@ grpc_init(); } -- (void)testSameConfiguration { - NSString *host = @"grpc-test.sandbox.googleapis.com"; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.userAgentPrefix = @"TestUAPrefix"; - NSMutableDictionary *args = [NSMutableDictionary new]; - args[@"abc"] = @"xyz"; - options.additionalChannelArgs = [args copy]; - GRPCChannel *channel1 = [GRPCChannel channelWithHost:host callOptions:options]; - GRPCChannel *channel2 = [GRPCChannel channelWithHost:host callOptions:options]; - XCTAssertEqual(channel1, channel2); - GRPCMutableCallOptions *options2 = [options mutableCopy]; - options2.additionalChannelArgs = [args copy]; - GRPCChannel *channel3 = [GRPCChannel channelWithHost:host callOptions:options2]; - XCTAssertEqual(channel1, channel3); +- (void)testTimedDisconnection { + NSString * const kHost = @"grpc-test.sandbox.googleapis.com"; + const NSTimeInterval kDestroyDelay = 1; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; + GRPCChannel *channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration + destroyDelay:kDestroyDelay]; + BOOL disconnected; + grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:&disconnected]; + XCTAssertFalse(disconnected); + grpc_call_unref(call); + [channel unref]; + XCTAssertFalse(channel.disconnected, @"Channel is pre-maturely disconnected."); + sleep(kDestroyDelay + 1); + XCTAssertTrue(channel.disconnected, @"Channel is not disconnected after delay."); + + // Check another call creation returns null and indicates disconnected. + call = [channel unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:&disconnected]; + XCTAssert(call == NULL); + XCTAssertTrue(disconnected); } -- (void)testDifferentHost { - NSString *host1 = @"grpc-test.sandbox.googleapis.com"; - NSString *host2 = @"grpc-test2.sandbox.googleapis.com"; - NSString *host3 = @"http://grpc-test.sandbox.googleapis.com"; - NSString *host4 = @"dns://grpc-test.sandbox.googleapis.com"; - NSString *host5 = @"grpc-test.sandbox.googleapis.com:80"; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.userAgentPrefix = @"TestUAPrefix"; - NSMutableDictionary *args = [NSMutableDictionary new]; - args[@"abc"] = @"xyz"; - options.additionalChannelArgs = [args copy]; - GRPCChannel *channel1 = [GRPCChannel channelWithHost:host1 callOptions:options]; - GRPCChannel *channel2 = [GRPCChannel channelWithHost:host2 callOptions:options]; - GRPCChannel *channel3 = [GRPCChannel channelWithHost:host3 callOptions:options]; - GRPCChannel *channel4 = [GRPCChannel channelWithHost:host4 callOptions:options]; - GRPCChannel *channel5 = [GRPCChannel channelWithHost:host5 callOptions:options]; - XCTAssertNotEqual(channel1, channel2); - XCTAssertNotEqual(channel1, channel3); - XCTAssertNotEqual(channel1, channel4); - XCTAssertNotEqual(channel1, channel5); -} +- (void)testForceDisconnection { + NSString * const kHost = @"grpc-test.sandbox.googleapis.com"; + const NSTimeInterval kDestroyDelay = 1; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; + GRPCChannel *channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration + destroyDelay:kDestroyDelay]; + grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:options + disconnected:nil]; + grpc_call_unref(call); + [channel disconnect]; + XCTAssertTrue(channel.disconnected, @"Channel is not disconnected."); -- (void)testDifferentChannelParameters { - NSString *host = @"grpc-test.sandbox.googleapis.com"; - GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; - options1.transportType = GRPCTransportTypeChttp2BoringSSL; - NSMutableDictionary *args = [NSMutableDictionary new]; - args[@"abc"] = @"xyz"; - options1.additionalChannelArgs = [args copy]; - GRPCMutableCallOptions *options2 = [[GRPCMutableCallOptions alloc] init]; - options2.transportType = GRPCTransportTypeInsecure; - options2.additionalChannelArgs = [args copy]; - GRPCMutableCallOptions *options3 = [[GRPCMutableCallOptions alloc] init]; - options3.transportType = GRPCTransportTypeChttp2BoringSSL; - args[@"def"] = @"uvw"; - options3.additionalChannelArgs = [args copy]; - GRPCChannel *channel1 = [GRPCChannel channelWithHost:host callOptions:options1]; - GRPCChannel *channel2 = [GRPCChannel channelWithHost:host callOptions:options2]; - GRPCChannel *channel3 = [GRPCChannel channelWithHost:host callOptions:options3]; - XCTAssertNotEqual(channel1, channel2); - XCTAssertNotEqual(channel1, channel3); + // Test calling another unref here will not crash + [channel unref]; } @end From 861e7ce452866311ee2746d7b7a9fd1d11b84087 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 9 Nov 2018 07:51:38 -0800 Subject: [PATCH 0189/2143] nit fixes --- src/objective-c/GRPCClient/private/GRPCChannel.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 298b6605d1f..4f26b349b49 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -34,7 +34,7 @@ #import /** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ -NSTimeInterval kDefaultChannelDestroyDelay = 30; +static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannelConfiguration @@ -295,6 +295,7 @@ NSTimeInterval kDefaultChannelDestroyDelay = 30; NSDate *now = [NSDate date]; self->_lastDispatch = now; dispatch_after(delay, self->_dispatchQueue, ^{ + // Timed disconnection. if (self->_lastDispatch == now) { grpc_channel_destroy(self->_unmanagedChannel); self->_unmanagedChannel = NULL; From 33022c9172bd3cf52c9aa3416ce9c69d9f3c6494 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 9 Nov 2018 10:23:05 -0800 Subject: [PATCH 0190/2143] Introduce GRPCAssert --- src/objective-c/GRPCClient/GRPCCall.m | 47 +++++++------------ .../GRPCClient/private/GRPCChannel.m | 21 +++++---- .../GRPCClient/private/GRPCChannelPool.m | 9 ++-- src/objective-c/GRPCClient/private/GRPCHost.m | 3 +- .../private/GRPCSecureChannelFactory.m | 4 +- .../GRPCClient/private/utilities.h | 35 ++++++++++++++ 6 files changed, 72 insertions(+), 47 deletions(-) create mode 100644 src/objective-c/GRPCClient/private/utilities.h diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9b9b4f95471..3d06aa929bb 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -35,6 +35,7 @@ #import "private/NSData+GRPC.h" #import "private/NSDictionary+GRPC.h" #import "private/NSError+GRPC.h" +#import "private/utilities.h" // At most 6 ops can be in an op batch for a client: SEND_INITIAL_METADATA, // SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT, RECV_INITIAL_METADATA, RECV_MESSAGE, @@ -67,7 +68,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @implementation GRPCRequestOptions - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { - NSAssert(host.length != 0 && path.length != 0, @"Host and Path cannot be empty"); + GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, @"Host and Path cannot be empty"); if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -114,15 +115,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *_Nullable)callOptions { - if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { - [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; - } - if (requestOptions.safety > GRPCCallSafetyCacheableRequest) { - [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; - } - if (responseHandler == nil) { - [NSException raise:NSInvalidArgumentException format:@"Response handler required."]; - } + GRPCAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, NSInvalidArgumentException, @"Neither host nor path can be nil."); + GRPCAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, @"Invalid call safety value."); + GRPCAssert(responseHandler != nil, NSInvalidArgumentException, @"Response handler required."); if ((self = [super init])) { _requestOptions = [requestOptions copy]; @@ -159,8 +154,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)start { dispatch_async(_dispatchQueue, ^{ - NSAssert(!self->_started, @"Call already started."); - NSAssert(!self->_canceled, @"Call already canceled."); + GRPCAssert(!self->_started, NSInternalInconsistencyException, @"Call already started."); + GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call already canceled."); self->_started = YES; if (!self->_callOptions) { self->_callOptions = [[GRPCCallOptions alloc] init]; @@ -216,7 +211,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { dispatch_async(_dispatchQueue, ^{ - NSAssert(!self->_canceled, @"Call already canceled."); + GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call already canceled."); if (self->_call) { [self->_call cancel]; self->_call = nil; @@ -244,8 +239,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeData:(NSData *)data { dispatch_async(_dispatchQueue, ^{ - NSAssert(!self->_canceled, @"Call arleady canceled."); - NSAssert(!self->_finished, @"Call is half-closed before sending data."); + GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); + GRPCAssert(!self->_finished, NSInternalInconsistencyException, @"Call is half-closed before sending data."); if (self->_call) { [self->_pipe writeValue:data]; } @@ -254,9 +249,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)finish { dispatch_async(_dispatchQueue, ^{ - NSAssert(self->_started, @"Call not started."); - NSAssert(!self->_canceled, @"Call arleady canceled."); - NSAssert(!self->_finished, @"Call already half-closed."); + GRPCAssert(self->_started, NSInternalInconsistencyException, @"Call not started."); + GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); + GRPCAssert(!self->_finished, NSInternalInconsistencyException, @"Call already half-closed."); if (self->_call) { [self->_pipe writesFinishedWithError:nil]; } @@ -404,16 +399,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. - if (!host || !path) { - [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; - } - if (safety > GRPCCallSafetyCacheableRequest) { - [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; - } - if (requestWriter.state != GRXWriterStateNotStarted) { - [NSException raise:NSInvalidArgumentException - format:@"The requests writer can't be already started."]; - } + GRPCAssert(host && path, NSInvalidArgumentException, @"Neither host nor path can be nil."); + GRPCAssert(safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, @"Invalid call safety value."); + GRPCAssert(requestWriter.state == GRXWriterStateNotStarted, NSInvalidArgumentException, @"The requests writer can't be already started."); if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -798,8 +786,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = callOptions; } - NSAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, - @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); + GRPCAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, NSInvalidArgumentException, @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); if (_callOptions.authTokenProvider != nil) { @synchronized(self) { self.isWaitingForToken = YES; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 4f26b349b49..7d0baa91ee6 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -28,6 +28,7 @@ #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "version.h" +#import "utilities.h" #import "../internal/GRPCCallOptions+Internal.h" #import @@ -39,8 +40,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannelConfiguration - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { - NSAssert(host.length, @"Host must not be empty."); - NSAssert(callOptions, @"callOptions must not be empty."); + GRPCAssert(host.length, NSInvalidArgumentException, @"Host must not be empty."); + GRPCAssert(callOptions != nil, NSInvalidArgumentException, @"callOptions must not be empty."); if ((self = [super init])) { _host = [host copy]; _callOptions = [callOptions copy]; @@ -192,8 +193,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration destroyDelay:(NSTimeInterval)destroyDelay { - NSAssert(channelConfiguration, @"channelConfiguration must not be empty."); - NSAssert(destroyDelay > 0, @"destroyDelay must be greater than 0."); + GRPCAssert(channelConfiguration != nil, NSInvalidArgumentException, @"channelConfiguration must not be empty."); + GRPCAssert(destroyDelay > 0, NSInvalidArgumentException, @"destroyDelay must be greater than 0."); if ((self = [super init])) { _configuration = [channelConfiguration copy]; if (@available(iOS 8.0, *)) { @@ -206,7 +207,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; // Create gRPC core channel object. NSString *host = channelConfiguration.host; - NSAssert(host.length != 0, @"host cannot be nil"); + GRPCAssert(host.length != 0, NSInvalidArgumentException, @"host cannot be nil"); NSDictionary *channelArgs; if (channelConfiguration.callOptions.additionalChannelArgs.count != 0) { NSMutableDictionary *args = [channelConfiguration.channelArgs mutableCopy]; @@ -231,21 +232,21 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions disconnected:(BOOL *)disconnected { - NSAssert(path.length, @"path must not be empty."); - NSAssert(queue, @"completionQueue must not be empty."); - NSAssert(callOptions, @"callOptions must not be empty."); + GRPCAssert(path.length, NSInvalidArgumentException, @"path must not be empty."); + GRPCAssert(queue, NSInvalidArgumentException, @"completionQueue must not be empty."); + GRPCAssert(callOptions, NSInvalidArgumentException, @"callOptions must not be empty."); __block BOOL isDisconnected = NO; __block grpc_call *call = NULL; dispatch_sync(_dispatchQueue, ^{ if (self->_disconnected) { isDisconnected = YES; } else { - NSAssert(self->_unmanagedChannel != NULL, @"Invalid channel."); + GRPCAssert(self->_unmanagedChannel != NULL, NSInvalidArgumentException, @"Invalid channel."); NSString *serverAuthority = callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; - NSAssert(timeout >= 0, @"Invalid timeout"); + GRPCAssert(timeout >= 0, NSInvalidArgumentException, @"Invalid timeout"); grpc_slice host_slice = grpc_empty_slice(); if (serverAuthority) { host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 98c1634bc8b..8a3b5edfa12 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -27,6 +27,7 @@ #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "version.h" +#import "utilities.h" #import #include @@ -43,9 +44,7 @@ static dispatch_once_t gInitChannelPool; + (nullable instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ gChannelPool = [[GRPCChannelPool alloc] init]; - if (gChannelPool == nil) { - [NSException raise:NSMallocException format:@"Cannot initialize global channel pool."]; - } + GRPCAssert(gChannelPool != nil, NSMallocException, @"Cannot initialize global channel pool."); }); return gChannelPool; } @@ -73,8 +72,8 @@ static dispatch_once_t gInitChannelPool; - (GRPCChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions destroyDelay:(NSTimeInterval)destroyDelay { - NSAssert(host.length > 0, @"Host must not be empty."); - NSAssert(callOptions != nil, @"callOptions must not be empty."); + GRPCAssert(host.length > 0, NSInvalidArgumentException, @"Host must not be empty."); + GRPCAssert(callOptions != nil, NSInvalidArgumentException, @"callOptions must not be empty."); GRPCChannel *channel; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index a67162c1014..14d07e949b7 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -33,6 +33,7 @@ #import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" #import "version.h" +#import "utilities.h" NS_ASSUME_NONNULL_BEGIN @@ -121,7 +122,7 @@ static NSMutableDictionary *gHostCache; if (_transportType == GRPCTransportTypeInsecure) { options.transportType = GRPCTransportTypeInsecure; } else { - NSAssert(_transportType == GRPCTransportTypeDefault, @"Invalid transport type"); + GRPCAssert(_transportType == GRPCTransportTypeDefault, NSInvalidArgumentException, @"Invalid transport type"); options.transportType = GRPCTransportTypeCronet; } } else diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 1f6458c5247..3079394ed8a 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -22,6 +22,7 @@ #import "ChannelArgsUtil.h" #import "GRPCChannel.h" +#import "utilities.h" NS_ASSUME_NONNULL_BEGIN @@ -82,8 +83,9 @@ NS_ASSUME_NONNULL_BEGIN if (errorPtr) { *errorPtr = defaultRootsError; } - NSAssert( + GRPCAssertWithArgument( 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 " diff --git a/src/objective-c/GRPCClient/private/utilities.h b/src/objective-c/GRPCClient/private/utilities.h new file mode 100644 index 00000000000..c664e8bf9df --- /dev/null +++ b/src/objective-c/GRPCClient/private/utilities.h @@ -0,0 +1,35 @@ +/* + * + * 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. + * + */ + +#import + +/** Raise exception when condition not met. Disregard NS_BLOCK_ASSERTIONS. */ +#define GRPCAssert(condition, errorType, errorString) \ +do { \ +if (!(condition)) { \ +[NSException raise:(errorType) format:(errorString)]; \ +} \ +} while (0) + +/** The same as GRPCAssert but allows arguments to be put in the raised string. */ +#define GRPCAssertWithArgument(condition, errorType, errorFormat, ...) \ + do { \ + if (!(condition)) { \ + [NSException raise:(errorType) format:(errorFormat), __VA_ARGS__]; \ + } \ + } while (0) From 2895ee9b6a63c19ebbd6c188ab475f0a6e7f0ba5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 9 Nov 2018 11:06:46 -0800 Subject: [PATCH 0191/2143] clang-format --- src/objective-c/GRPCClient/GRPCCall.m | 22 +++++--- .../GRPCClient/private/GRPCChannel.h | 11 ++-- .../GRPCClient/private/GRPCChannel.m | 55 ++++++++++--------- .../GRPCClient/private/GRPCChannelPool.h | 3 +- .../GRPCClient/private/GRPCChannelPool.m | 16 ++---- src/objective-c/GRPCClient/private/GRPCHost.m | 5 +- .../private/GRPCSecureChannelFactory.m | 3 +- .../GRPCClient/private/utilities.h | 27 ++++----- 8 files changed, 75 insertions(+), 67 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 3d06aa929bb..5e3491dafaa 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -68,7 +68,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; @implementation GRPCRequestOptions - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { - GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, @"Host and Path cannot be empty"); + GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, + @"Host and Path cannot be empty"); if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -115,8 +116,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *_Nullable)callOptions { - GRPCAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, NSInvalidArgumentException, @"Neither host nor path can be nil."); - GRPCAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, @"Invalid call safety value."); + GRPCAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, + NSInvalidArgumentException, @"Neither host nor path can be nil."); + GRPCAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, + @"Invalid call safety value."); GRPCAssert(responseHandler != nil, NSInvalidArgumentException, @"Response handler required."); if ((self = [super init])) { @@ -240,7 +243,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeData:(NSData *)data { dispatch_async(_dispatchQueue, ^{ GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); - GRPCAssert(!self->_finished, NSInternalInconsistencyException, @"Call is half-closed before sending data."); + GRPCAssert(!self->_finished, NSInternalInconsistencyException, + @"Call is half-closed before sending data."); if (self->_call) { [self->_pipe writeValue:data]; } @@ -400,8 +404,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. GRPCAssert(host && path, NSInvalidArgumentException, @"Neither host nor path can be nil."); - GRPCAssert(safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, @"Invalid call safety value."); - GRPCAssert(requestWriter.state == GRXWriterStateNotStarted, NSInvalidArgumentException, @"The requests writer can't be already started."); + GRPCAssert(safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, + @"Invalid call safety value."); + GRPCAssert(requestWriter.state == GRXWriterStateNotStarted, NSInvalidArgumentException, + @"The requests writer can't be already started."); if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -786,7 +792,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = callOptions; } - GRPCAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, NSInvalidArgumentException, @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); + GRPCAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, + NSInvalidArgumentException, + @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); if (_callOptions.authTokenProvider != nil) { @synchronized(self) { self.isWaitingForToken = YES; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index bbe0ba53904..6c58f4f387f 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -64,14 +64,17 @@ NS_ASSUME_NONNULL_BEGIN * Create a channel with remote \a host and signature \a channelConfigurations. Destroy delay is * defaulted to 30 seconds. */ -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration; +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration; /** * Create a channel with remote \a host, signature \a channelConfigurations, and destroy delay of * \a destroyDelay. */ -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration - destroyDelay:(NSTimeInterval)destroyDelay NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay + NS_DESIGNATED_INITIALIZER; /** * Create a grpc core call object from this channel. The channel's refcount is added by 1. If no @@ -82,7 +85,7 @@ NS_ASSUME_NONNULL_BEGIN - (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions - disconnected:(BOOL * _Nullable)disconnected; + disconnected:(BOOL *_Nullable)disconnected; /** * Unref the channel when a call is done. It also decreases the channel's refcount. If the refcount diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 7d0baa91ee6..fc0448bb962 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -20,6 +20,7 @@ #include +#import "../internal/GRPCCallOptions+Internal.h" #import "ChannelArgsUtil.h" #import "GRPCChannelFactory.h" #import "GRPCChannelPool.h" @@ -27,9 +28,8 @@ #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" -#import "version.h" #import "utilities.h" -#import "../internal/GRPCCallOptions+Internal.h" +#import "version.h" #import #import @@ -60,10 +60,10 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (![GRPCCall isUsingCronet]) { #endif factory = [GRPCSecureChannelFactory - factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates - privateKey:_callOptions.PEMPrivateKey - certChain:_callOptions.PEMCertChain - error:&error]; + factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates + privateKey:_callOptions.PEMPrivateKey + certChain:_callOptions.PEMCertChain + error:&error]; if (factory == nil) { NSLog(@"Error creating secure channel factory: %@", error); } @@ -86,7 +86,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSString *userAgentPrefix = _callOptions.userAgentPrefix; if (userAgentPrefix) { args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = - [_callOptions.userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; + [_callOptions.userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; } else { args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = userAgent; } @@ -98,19 +98,19 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (_callOptions.responseSizeLimit) { args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = - [NSNumber numberWithUnsignedInteger:_callOptions.responseSizeLimit]; + [NSNumber numberWithUnsignedInteger:_callOptions.responseSizeLimit]; } if (_callOptions.compressionAlgorithm != GRPC_COMPRESS_NONE) { args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = - [NSNumber numberWithInt:_callOptions.compressionAlgorithm]; + [NSNumber numberWithInt:_callOptions.compressionAlgorithm]; } if (_callOptions.keepaliveInterval != 0) { args[@GRPC_ARG_KEEPALIVE_TIME_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; } if (_callOptions.retryEnabled == NO) { @@ -119,15 +119,15 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (_callOptions.connectMinTimeout > 0) { args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMinTimeout * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMinTimeout * 1000)]; } if (_callOptions.connectInitialBackoff > 0) { args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber - numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectInitialBackoff * 1000)]; + numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectInitialBackoff * 1000)]; } if (_callOptions.connectMaxBackoff > 0) { args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = - [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMaxBackoff * 1000)]; + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMaxBackoff * 1000)]; } if (_callOptions.logContext != nil) { @@ -145,7 +145,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (nonnull id)copyWithZone:(nullable NSZone *)zone { GRPCChannelConfiguration *newConfig = - [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; + [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; return newConfig; } @@ -172,8 +172,6 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @end - - @implementation GRPCChannel { GRPCChannelConfiguration *_configuration; @@ -186,21 +184,24 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } @synthesize disconnected = _disconnected; -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration { return [self initWithChannelConfiguration:channelConfiguration destroyDelay:kDefaultChannelDestroyDelay]; } -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration destroyDelay:(NSTimeInterval)destroyDelay { - GRPCAssert(channelConfiguration != nil, NSInvalidArgumentException, @"channelConfiguration must not be empty."); + GRPCAssert(channelConfiguration != nil, NSInvalidArgumentException, + @"channelConfiguration must not be empty."); GRPCAssert(destroyDelay > 0, NSInvalidArgumentException, @"destroyDelay must be greater than 0."); if ((self = [super init])) { _configuration = [channelConfiguration copy]; if (@available(iOS 8.0, *)) { _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); } else { _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } @@ -244,7 +245,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; GRPCAssert(self->_unmanagedChannel != NULL, NSInvalidArgumentException, @"Invalid channel."); NSString *serverAuthority = - callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; GRPCAssert(timeout >= 0, NSInvalidArgumentException, @"Invalid timeout"); grpc_slice host_slice = grpc_empty_slice(); @@ -253,10 +254,10 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); gpr_timespec deadline_ms = - timeout == 0 - ? gpr_inf_future(GPR_CLOCK_REALTIME) - : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + timeout == 0 + ? gpr_inf_future(GPR_CLOCK_REALTIME) + : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); call = grpc_channel_create_call(self->_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, serverAuthority ? &host_slice : NULL, deadline_ms, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 24c0a8df115..48779c44497 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -44,8 +44,7 @@ NS_ASSUME_NONNULL_BEGIN * Return a channel with a particular configuration. If the channel does not exist, execute \a * createChannel then add it in the pool. If the channel exists, increase its reference count. */ -- (GRPCChannel *)channelWithHost:(NSString *)host - callOptions:(GRPCCallOptions *)callOptions; +- (GRPCChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; /** * This method is deprecated. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 8a3b5edfa12..85ca527277c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -26,8 +26,8 @@ #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" -#import "version.h" #import "utilities.h" +#import "version.h" #import #include @@ -62,11 +62,8 @@ static dispatch_once_t gInitChannelPool; return self; } -- (GRPCChannel *)channelWithHost:(NSString *)host - callOptions:(GRPCCallOptions *)callOptions { - return [self channelWithHost:host - callOptions:callOptions - destroyDelay:0]; +- (GRPCChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { + return [self channelWithHost:host callOptions:callOptions destroyDelay:0]; } - (GRPCChannel *)channelWithHost:(NSString *)host @@ -76,14 +73,15 @@ static dispatch_once_t gInitChannelPool; GRPCAssert(callOptions != nil, NSInvalidArgumentException, @"callOptions must not be empty."); GRPCChannel *channel; GRPCChannelConfiguration *configuration = - [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; + [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; @synchronized(self) { channel = _channelPool[configuration]; if (channel == nil || channel.disconnected) { if (destroyDelay == 0) { channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration]; } else { - channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:destroyDelay]; + channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration + destroyDelay:destroyDelay]; } _channelPool[configuration] = channel; } @@ -91,8 +89,6 @@ static dispatch_once_t gInitChannelPool; return channel; } - - + (void)closeOpenConnections { [[GRPCChannelPool sharedInstance] destroyAllChannels]; } diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 14d07e949b7..5fc7427b689 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -32,8 +32,8 @@ #import "GRPCCronetChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" -#import "version.h" #import "utilities.h" +#import "version.h" NS_ASSUME_NONNULL_BEGIN @@ -122,7 +122,8 @@ static NSMutableDictionary *gHostCache; if (_transportType == GRPCTransportTypeInsecure) { options.transportType = GRPCTransportTypeInsecure; } else { - GRPCAssert(_transportType == GRPCTransportTypeDefault, NSInvalidArgumentException, @"Invalid transport type"); + GRPCAssert(_transportType == GRPCTransportTypeDefault, NSInvalidArgumentException, + @"Invalid transport type"); options.transportType = GRPCTransportTypeCronet; } } else diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 3079394ed8a..57bd40d6787 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -84,8 +84,7 @@ NS_ASSUME_NONNULL_BEGIN *errorPtr = defaultRootsError; } GRPCAssertWithArgument( - defaultRootsASCII, - NSObjectNotAvailableException, + 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 " diff --git a/src/objective-c/GRPCClient/private/utilities.h b/src/objective-c/GRPCClient/private/utilities.h index c664e8bf9df..3e51730d637 100644 --- a/src/objective-c/GRPCClient/private/utilities.h +++ b/src/objective-c/GRPCClient/private/utilities.h @@ -19,17 +19,18 @@ #import /** Raise exception when condition not met. Disregard NS_BLOCK_ASSERTIONS. */ -#define GRPCAssert(condition, errorType, errorString) \ -do { \ -if (!(condition)) { \ -[NSException raise:(errorType) format:(errorString)]; \ -} \ -} while (0) +#define GRPCAssert(condition, errorType, errorString) \ + do { \ + if (!(condition)) { \ + [NSException raise:(errorType)format:(errorString)]; \ + } \ + } while (0) -/** The same as GRPCAssert but allows arguments to be put in the raised string. */ -#define GRPCAssertWithArgument(condition, errorType, errorFormat, ...) \ - do { \ - if (!(condition)) { \ - [NSException raise:(errorType) format:(errorFormat), __VA_ARGS__]; \ - } \ - } while (0) +/** The same as GRPCAssert but allows arguments to be put in the raised string. + */ +#define GRPCAssertWithArgument(condition, errorType, errorFormat, ...) \ + do { \ + if (!(condition)) { \ + [NSException raise:(errorType)format:(errorFormat), __VA_ARGS__]; \ + } \ + } while (0) From 699c10386d6f0cbed7364e5a94144f0794f469d5 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 9 Nov 2018 19:43:00 -0800 Subject: [PATCH 0192/2143] Add method to fail recv msg for hijacked rpcs --- include/grpcpp/impl/codegen/call_op_set.h | 4 +- include/grpcpp/impl/codegen/interceptor.h | 3 + .../grpcpp/impl/codegen/interceptor_common.h | 14 ++- .../grpcpp/impl/codegen/server_interface.h | 2 +- src/cpp/server/server_cc.cc | 4 +- .../client_interceptors_end2end_test.cc | 101 ++++++++++++++++++ 6 files changed, 122 insertions(+), 6 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index b4c34a01c9a..aae8b9d3e37 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -406,7 +406,7 @@ class CallOpRecvMessage { void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - interceptor_methods->SetRecvMessage(message_); + interceptor_methods->SetRecvMessage(message_, &got_message); } void SetFinishInterceptionHookPoint( @@ -501,7 +501,7 @@ class CallOpGenericRecvMessage { void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - interceptor_methods->SetRecvMessage(message_); + interceptor_methods->SetRecvMessage(message_, &got_message); } void SetFinishInterceptionHookPoint( diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index e449e44a23b..943376a5451 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -118,6 +118,9 @@ class InterceptorBatchMethods { // only interceptors after the current interceptor are created from the // factory objects registered with the channel. virtual std::unique_ptr GetInterceptedChannel() = 0; + + // On a hijacked RPC, an interceptor can decide to fail a RECV MESSAGE op. + virtual void FailHijackedRecvMessage() = 0; }; class Interceptor { diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index d0aa23cb0a0..4c881c783d3 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -134,7 +134,10 @@ class InterceptorBatchMethodsImpl send_trailing_metadata_ = metadata; } - void SetRecvMessage(void* message) { recv_message_ = message; } + void SetRecvMessage(void* message, bool* got_message) { + recv_message_ = message; + got_message_ = got_message; + } void SetRecvInitialMetadata(MetadataMap* map) { recv_initial_metadata_ = map; @@ -157,6 +160,8 @@ class InterceptorBatchMethodsImpl info->channel(), current_interceptor_index_ + 1)); } + void FailHijackedRecvMessage() override { *got_message_ = false; } + // Clears all state void ClearState() { reverse_ = false; @@ -345,6 +350,7 @@ class InterceptorBatchMethodsImpl std::multimap* send_trailing_metadata_ = nullptr; void* recv_message_ = nullptr; + bool* got_message_ = nullptr; MetadataMap* recv_initial_metadata_ = nullptr; @@ -451,6 +457,12 @@ class CancelInterceptorBatchMethods "method which has a Cancel notification"); return std::unique_ptr(nullptr); } + + void FailHijackedRecvMessage() override { + GPR_CODEGEN_ASSERT(false && + "It is illegal to call FailHijackedRecvMessage on a " + "method which has a Cancel notification"); + } }; } // namespace internal } // namespace grpc diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index 55c94f4d2fa..23d1f445b16 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -270,7 +270,7 @@ class ServerInterface : public internal::CallHook { /* Set interception point for recv message */ interceptor_methods_.AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); - interceptor_methods_.SetRecvMessage(request_); + interceptor_methods_.SetRecvMessage(request_, nullptr); return RegisteredAsyncRequest::FinalizeResult(tag, status); } diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 7a98bce507a..8b1658dd278 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -280,7 +280,7 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { request_payload_ = nullptr; interceptor_methods_.AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); - interceptor_methods_.SetRecvMessage(request_); + interceptor_methods_.SetRecvMessage(request_, nullptr); } if (interceptor_methods_.RunInterceptors( @@ -447,7 +447,7 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { req_->request_payload_ = nullptr; req_->interceptor_methods_.AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); - req_->interceptor_methods_.SetRecvMessage(req_->request_); + req_->interceptor_methods_.SetRecvMessage(req_->request_, nullptr); } if (req_->interceptor_methods_.RunInterceptors( diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 0b34ec93ae7..b94a3d752e8 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -269,6 +269,92 @@ class HijackingInterceptorMakesAnotherCallFactory } }; +class ServerStreamingRpcHijackingInterceptor + : public experimental::Interceptor { + public: + ServerStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) { + info_ = info; + } + + virtual void Intercept(experimental::InterceptorBatchMethods* methods) { + bool hijack = false; + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { + auto* map = methods->GetSendInitialMetadata(); + // Check that we can see the test metadata + ASSERT_EQ(map->size(), static_cast(1)); + auto iterator = map->begin(); + EXPECT_EQ("testkey", iterator->first); + EXPECT_EQ("testvalue", iterator->second); + hijack = true; + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + EchoRequest req; + auto* buffer = methods->GetSendMessage(); + auto copied_buffer = *buffer; + EXPECT_TRUE( + SerializationTraits::Deserialize(&copied_buffer, &req) + .ok()); + EXPECT_EQ(req.message(), "Hello"); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { + // Got nothing to do here for now + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_RECV_STATUS)) { + auto* map = methods->GetRecvTrailingMetadata(); + bool found = false; + // Check that we received the metadata as an echo + for (const auto& pair : *map) { + found = pair.first.starts_with("testkey") && + pair.second.starts_with("testvalue"); + if (found) break; + } + EXPECT_EQ(found, true); + auto* status = methods->GetRecvStatus(); + EXPECT_EQ(status->ok(), true); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { + if (++count > 10) { + methods->FailHijackedRecvMessage(); + } + EchoResponse* resp = + static_cast(methods->GetRecvMessage()); + resp->set_message("Hello"); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { + auto* map = methods->GetRecvTrailingMetadata(); + // insert the metadata that we want + EXPECT_EQ(map->size(), static_cast(0)); + map->insert(std::make_pair("testkey", "testvalue")); + auto* status = methods->GetRecvStatus(); + *status = Status(StatusCode::OK, ""); + } + if (hijack) { + methods->Hijack(); + } else { + methods->Proceed(); + } + } + + private: + experimental::ClientRpcInfo* info_; + int count = 0; +}; + +class ServerStreamingRpcHijackingInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return new ServerStreamingRpcHijackingInterceptor(info); + } +}; + class LoggingInterceptor : public experimental::Interceptor { public: LoggingInterceptor(experimental::ClientRpcInfo* info) { info_ = info; } @@ -535,6 +621,21 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) { EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } +TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingHijackingTest) { + ChannelArguments args; + DummyInterceptor::Reset(); + auto creators = std::unique_ptr>>( + new std::vector< + std::unique_ptr>()); + creators->push_back( + std::unique_ptr( + new ServerStreamingRpcHijackingInterceptorFactory())); + auto channel = experimental::CreateCustomChannelWithInterceptors( + server_address_, InsecureChannelCredentials(), args, std::move(creators)); + MakeServerStreamingCall(channel); +} + TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); From 565edf529766e66b4394f59ff33a89211c92206a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 9 Nov 2018 19:51:11 -0800 Subject: [PATCH 0193/2143] Add safety checks --- include/grpcpp/impl/codegen/interceptor_common.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 4c881c783d3..d23b71f8a77 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -160,7 +160,11 @@ class InterceptorBatchMethodsImpl info->channel(), current_interceptor_index_ + 1)); } - void FailHijackedRecvMessage() override { *got_message_ = false; } + void FailHijackedRecvMessage() override { + GPR_CODEGEN_ASSERT(hooks_[static_cast( + experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)]); + *got_message_ = false; + } // Clears all state void ClearState() { From f932b8e2d092c1407d4d4bad4f9f7a4456503b33 Mon Sep 17 00:00:00 2001 From: Alex Lo Date: Mon, 12 Nov 2018 16:16:40 -0500 Subject: [PATCH 0194/2143] ipv6 addresses must be bracketed if using a port The host/port splitting code will not pull out a port if there are >=2 colons[1]. Unit test code demos this [2]. Note other documentation gets this right[3]. Example IP came from this issue[4] and the unit tests[2]. See also: relevant RFCs [5] [6] [1]https://github.com/grpc/grpc/blob/618a3f561d4a93f263cca23abad086ed8f4d5e86/src/core/lib/gpr/host_port.cc#L81 [2]https://github.com/grpc/grpc/blob/618a3f561d4a93f263cca23abad086ed8f4d5e86/test/core/client_channel/resolvers/sockaddr_resolver_test.cc#L107 [3]https://chromium.googlesource.com/external/github.com/grpc/grpc/+/chromium-deps/2016-07-19/src/core/ext/client_config/README.md [4]https://github.com/grpc/grpc/issues/6623 [5]http://www.iana.org/go/rfc5952#section-6 [6]http://www.iana.org/go/rfc3986#section-3.2.3 --- doc/naming.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/naming.md b/doc/naming.md index 581c550567f..5e54ca67b31 100644 --- a/doc/naming.md +++ b/doc/naming.md @@ -51,7 +51,9 @@ 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. + - `address` is the IPv6 address to use. To use with a `port` the `address` + must enclosed in literal square brakets (`[` and `]`). Example: + `ipv6:[2607:f8b0:400e:c00::ef]:443` or `ipv6:[::]:1234` - `port` is the port to use. If not specified, 443 is used. In the future, additional schemes such as `etcd` could be added. From 94d220d32c0db708a3afa36a17aae25d93c2636b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 14:03:27 -0800 Subject: [PATCH 0195/2143] Rename variable --- .../cronet/client/secure/cronet_channel_create.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc index dffb61b082d..1cb38f25b6d 100644 --- a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc +++ b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc @@ -47,11 +47,11 @@ GRPCAPI grpc_channel* grpc_cronet_secure_channel_create( target); // Disable client authority filter when using Cronet - grpc_arg arg; - arg.key = const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); - arg.type = GRPC_ARG_INTEGER; - arg.value.integer = 1; - grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args, &arg, 1); + grpc_arg disable_client_authority_filter_arg; + disable_client_authority_filter_arg.key = const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); + disable_client_authority_filter_arg.type = GRPC_ARG_INTEGER; + disable_client_authority_filter_arg.value.integer = 1; + grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args, &disable_client_authority_filter_arg, 1); grpc_transport* ct = grpc_create_cronet_transport(engine, target, new_args, reserved); From 8d0cf9ec0aaa9e9efd23254d189d78fbaead2702 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 14:03:50 -0800 Subject: [PATCH 0196/2143] clang-format --- .../tests/ChannelTests/ChannelPoolTest.m | 38 +++++++------------ .../tests/ChannelTests/ChannelTests.m | 18 +++++---- 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index d684db545e9..b85e62feb5f 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -47,14 +47,10 @@ NSString *kDummyHost = @"dummy.host"; GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel1 = [pool channelWithHost:kDummyHost - callOptions:options1]; - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost - callOptions:options2]; - GRPCChannel *channel3 = [pool channelWithHost:kDummyHost2 - callOptions:options1]; - GRPCChannel *channel4 = [pool channelWithHost:kDummyHost - callOptions:options3]; + GRPCChannel *channel1 = [pool channelWithHost:kDummyHost callOptions:options1]; + GRPCChannel *channel2 = [pool channelWithHost:kDummyHost callOptions:options2]; + GRPCChannel *channel3 = [pool channelWithHost:kDummyHost2 callOptions:options1]; + GRPCChannel *channel4 = [pool channelWithHost:kDummyHost callOptions:options3]; XCTAssertEqual(channel1, channel2); XCTAssertNotEqual(channel1, channel3); XCTAssertNotEqual(channel1, channel4); @@ -66,16 +62,14 @@ NSString *kDummyHost = @"dummy.host"; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = [pool channelWithHost:kDummyHost - callOptions:options]; + GRPCChannel *channel = [pool channelWithHost:kDummyHost callOptions:options]; grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" completionQueue:[GRPCCompletionQueue completionQueue] callOptions:options disconnected:nil]; [pool destroyAllChannels]; XCTAssertTrue(channel.disconnected); - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost - callOptions:options]; + GRPCChannel *channel2 = [pool channelWithHost:kDummyHost callOptions:options]; XCTAssertNotEqual(channel, channel2); grpc_call_unref(call); } @@ -86,9 +80,8 @@ NSString *kDummyHost = @"dummy.host"; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = [pool channelWithHost:kDummyHost - callOptions:options - destroyDelay:kDestroyDelay]; + GRPCChannel *channel = + [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" completionQueue:[GRPCCompletionQueue completionQueue] callOptions:options @@ -97,9 +90,8 @@ NSString *kDummyHost = @"dummy.host"; [channel unref]; // Test that we can still get the channel at this time - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost - callOptions:options - destroyDelay:kDestroyDelay]; + GRPCChannel *channel2 = + [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; XCTAssertEqual(channel, channel2); call = [channel2 unmanagedCallWithPath:@"dummy.path" completionQueue:[GRPCCompletionQueue completionQueue] @@ -117,9 +109,8 @@ NSString *kDummyHost = @"dummy.host"; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = [pool channelWithHost:kDummyHost - callOptions:options - destroyDelay:kDestroyDelay]; + GRPCChannel *channel = + [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" completionQueue:[GRPCCompletionQueue completionQueue] callOptions:options @@ -130,9 +121,8 @@ NSString *kDummyHost = @"dummy.host"; sleep(kDestroyDelay + 1); // Test that we get new channel to the same host and with the same callOptions - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost - callOptions:options - destroyDelay:kDestroyDelay]; + GRPCChannel *channel2 = + [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; XCTAssertNotEqual(channel, channel2); } diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 27e76d41799..5daafcdf3f3 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -33,12 +33,13 @@ } - (void)testTimedDisconnection { - NSString * const kHost = @"grpc-test.sandbox.googleapis.com"; + NSString *const kHost = @"grpc-test.sandbox.googleapis.com"; const NSTimeInterval kDestroyDelay = 1; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; - GRPCChannel *channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration - destroyDelay:kDestroyDelay]; + GRPCChannelConfiguration *configuration = + [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; + GRPCChannel *channel = + [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:kDestroyDelay]; BOOL disconnected; grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" completionQueue:[GRPCCompletionQueue completionQueue] @@ -61,12 +62,13 @@ } - (void)testForceDisconnection { - NSString * const kHost = @"grpc-test.sandbox.googleapis.com"; + NSString *const kHost = @"grpc-test.sandbox.googleapis.com"; const NSTimeInterval kDestroyDelay = 1; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; - GRPCChannel *channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration - destroyDelay:kDestroyDelay]; + GRPCChannelConfiguration *configuration = + [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; + GRPCChannel *channel = + [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:kDestroyDelay]; grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" completionQueue:[GRPCCompletionQueue completionQueue] callOptions:options From b77203fdf59faa38e7be01f8796d3bc3e67db602 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 14:09:41 -0800 Subject: [PATCH 0197/2143] Move blocks into varibles for readability --- src/objective-c/GRPCClient/GRPCCall.m | 51 ++++++++++++++------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 5e3491dafaa..39681d2adfb 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -172,7 +172,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (self->_callOptions.initialMetadata) { [self->_call.requestHeaders addEntriesFromDictionary:self->_callOptions.initialMetadata]; } - id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(id value) { + + void (^valueHandler)(id value) = ^(id value) { dispatch_async(self->_dispatchQueue, ^{ if (self->_handler) { if (!self->_initialMetadataPublished) { @@ -184,30 +185,32 @@ const char *kCFStreamVarName = "grpc_cfstream"; } } }); - } - completionHandler:^(NSError *errorOrNil) { - dispatch_async(self->_dispatchQueue, ^{ - if (self->_handler) { - if (!self->_initialMetadataPublished) { - self->_initialMetadataPublished = YES; - [self issueInitialMetadata:self->_call.responseHeaders]; - } - [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + }; + void (^completionHandler)(NSError *errorOrNil) = ^(NSError *errorOrNil) { + dispatch_async(self->_dispatchQueue, ^{ + if (self->_handler) { + if (!self->_initialMetadataPublished) { + self->_initialMetadataPublished = YES; + [self issueInitialMetadata:self->_call.responseHeaders]; + } + [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; - // Clean up _handler so that no more responses are reported to the handler. - self->_handler = nil; - } - // Clearing _call must happen *after* dispatching close in order to get trailing - // metadata from _call. - if (self->_call) { - // Clean up the request writers. This should have no effect to _call since its - // response writeable is already nullified. - [self->_pipe writesFinishedWithError:nil]; - self->_call = nil; - self->_pipe = nil; - } - }); - }]; + // Clean up _handler so that no more responses are reported to the handler. + self->_handler = nil; + } + // Clearing _call must happen *after* dispatching close in order to get trailing + // metadata from _call. + if (self->_call) { + // Clean up the request writers. This should have no effect to _call since its + // response writeable is already nullified. + [self->_pipe writesFinishedWithError:nil]; + self->_call = nil; + self->_pipe = nil; + } + }); + }; + id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:valueHandler + completionHandler:completionHandler]; [self->_call startWithWriteable:responseWriteable]; }); } From 78c2176afcdf2267467c68f6f070fc6543673bd7 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 14:40:44 -0800 Subject: [PATCH 0198/2143] Assign finished and canceled --- src/objective-c/GRPCClient/GRPCCall.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 39681d2adfb..9d81dcf6e6e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -143,7 +143,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); _started = NO; _canceled = NO; - _finished = YES; + _finished = NO; } return self; @@ -218,6 +218,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { dispatch_async(_dispatchQueue, ^{ GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call already canceled."); + self->_canceled = YES; if (self->_call) { [self->_call cancel]; self->_call = nil; @@ -263,6 +264,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self->_pipe writesFinishedWithError:nil]; } self->_pipe = nil; + self->_finished = YES; }); } From f4a77ce4926064e193787521081e835bd94f1e7d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 14:51:07 -0800 Subject: [PATCH 0199/2143] _call->_pipe --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9d81dcf6e6e..46cd5a4f227 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -260,7 +260,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; GRPCAssert(self->_started, NSInternalInconsistencyException, @"Call not started."); GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); GRPCAssert(!self->_finished, NSInternalInconsistencyException, @"Call already half-closed."); - if (self->_call) { + if (self->_pipe) { [self->_pipe writesFinishedWithError:nil]; } self->_pipe = nil; From c83ab56fe1d4bc6e5c3cebbc4943505eaf6ea74a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 14:51:25 -0800 Subject: [PATCH 0200/2143] copy->mutableCopy --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 46cd5a4f227..6de7bd8967b 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -581,7 +581,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; break; } - NSMutableDictionary *headers = [_requestHeaders copy]; + NSMutableDictionary *headers = [_requestHeaders mutableCopy]; NSString *fetchedOauth2AccessToken; @synchronized(self) { fetchedOauth2AccessToken = _fetchedOauth2AccessToken; From 8006dddea2f8e6d6f4bb77c9aa64c21ee09674ec Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 14 Nov 2018 15:49:00 -0800 Subject: [PATCH 0201/2143] updated toolchain subversion --- tools/remote_build/rbe_common.bazelrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index 3f8a4cb1931..6718c3aade1 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -76,7 +76,7 @@ build:ubsan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:ubsan --test_timeout=3600 # override the config-agnostic crosstool_top ---crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.16.1/ubsan:toolchain +--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.1/bazel_0.16.1/ubsan:toolchain # TODO(jtattermusch): remove this once Foundry adds the env to the docker image. # ubsan needs symbolizer to work properly, otherwise the suppression file doesn't work # and we get test failures. From 2532b8488c1745bb9afee54268997337edd89dac Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 14 Nov 2018 15:49:45 -0800 Subject: [PATCH 0202/2143] updated toolchain subversion --- tools/remote_build/rbe_common.bazelrc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index 6718c3aade1..583781effc5 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -18,8 +18,8 @@ startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 -build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain -build --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default +build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain +build --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default # Use custom execution platforms defined in third_party/toolchains build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large build --host_platform=//third_party/toolchains:rbe_ubuntu1604 @@ -59,9 +59,9 @@ build:msan --cxxopt=--stdlib=libc++ # setting LD_LIBRARY_PATH is necessary # to avoid "libc++.so.1: cannot open shared object file" build:msan --action_env=LD_LIBRARY_PATH=/usr/local/lib -build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain +build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain # override the config-agnostic crosstool_top -build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/msan:toolchain +build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/msan:toolchain # thread sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific From b22120f69601450d4cbdc6957f661ba7ec29ca3a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 16:10:10 -0800 Subject: [PATCH 0203/2143] Test fix --- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index d681163419d..28f94cd8c77 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -277,6 +277,7 @@ static const NSTimeInterval kTestTimeout = 16; callOptions:options]; [call writeData:[NSData data]]; [call start]; + [call finish]; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } @@ -312,6 +313,7 @@ static const NSTimeInterval kTestTimeout = 16; callOptions:options]; [call writeData:[request data]]; [call start]; + [call finish]; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } From d069bb2444a38021caf3ab4eee489fa2310fe7a8 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 14 Nov 2018 16:25:31 -0800 Subject: [PATCH 0204/2143] more destination fixes --- third_party/toolchains/BUILD | 8 ++++---- tools/remote_build/rbe_common.bazelrc | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index efb52736fe5..f5767f212d6 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -35,8 +35,8 @@ platform( "@bazel_tools//platforms:x86_64", "@bazel_tools//platforms:linux", "@bazel_tools//tools/cpp:clang", - "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", - "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", + "@bazel_toolchains//constraints:xenial", + "@bazel_toolchains//constraints/sanitizers:support_msan", "//third_party/toolchains/machine_size:standard", ], remote_execution_properties = """ @@ -58,8 +58,8 @@ platform( "@bazel_tools//platforms:x86_64", "@bazel_tools//platforms:linux", "@bazel_tools//tools/cpp:clang", - "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", - "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", + "@bazel_toolchains//constraints:xenial", + "@@bazel_toolchains//constraints/sanitizers:support_msan", "//third_party/toolchains/machine_size:large", ], remote_execution_properties = """ diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index 583781effc5..f17ed10f57e 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -18,8 +18,8 @@ startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 -build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain -build --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default +build --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain +build --extra_toolchains=@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default # Use custom execution platforms defined in third_party/toolchains build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large build --host_platform=//third_party/toolchains:rbe_ubuntu1604 @@ -59,9 +59,9 @@ build:msan --cxxopt=--stdlib=libc++ # setting LD_LIBRARY_PATH is necessary # to avoid "libc++.so.1: cannot open shared object file" build:msan --action_env=LD_LIBRARY_PATH=/usr/local/lib -build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain +build:msan --host_crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain # override the config-agnostic crosstool_top -build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/msan:toolchain +build:msan --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/msan:toolchain # thread sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific @@ -76,7 +76,7 @@ build:ubsan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:ubsan --test_timeout=3600 # override the config-agnostic crosstool_top ---crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.1/bazel_0.16.1/ubsan:toolchain +--crosstool_top=@bazel_toolchains//configs/experimental/ubuntu16_04_clang/1.1/bazel_0.16.1/ubsan:toolchain # TODO(jtattermusch): remove this once Foundry adds the env to the docker image. # ubsan needs symbolizer to work properly, otherwise the suppression file doesn't work # and we get test failures. From e023468e9a82a4338e30e57ab822c86406480b94 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 16:34:58 -0800 Subject: [PATCH 0205/2143] some nit fixes --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannel.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 6de7bd8967b..2a56514bdc9 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -282,7 +282,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [_handler closedWithTrailingMetadata:_call.responseTrailers error:error]; + [_handler closedWithTrailingMetadata:trailingMetadata error:error]; } } diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index ecb517762b3..9a36ee547cd 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -45,7 +45,7 @@ static NSString *const kDefaultChannelPoolDomain = nil; static const NSUInteger kDefaultChannelID = 0; // Check if two objects are equal. Returns YES if both are nil; -BOOL areObjectsEqual(id obj1, id obj2) { +static BOOL areObjectsEqual(id obj1, id obj2) { if (obj1 == obj2) { return YES; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 6c58f4f387f..32e68bb2625 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -39,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN * Options of the corresponding call. Note that only the channel-related options are of interest to * this class. */ -@property(strong, readonly) GRPCCallOptions *callOptions; +@property(readonly) GRPCCallOptions *callOptions; /** Acquire the factory to generate a new channel with current configurations. */ @property(readonly) id channelFactory; From 5d7d6c0fbdcac75ea482e1fde3e128cd0c1646c1 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 14 Nov 2018 17:35:26 -0800 Subject: [PATCH 0206/2143] Add method to fail hijacked send messages --- include/grpcpp/impl/codegen/call_op_set.h | 10 ++- include/grpcpp/impl/codegen/interceptor.h | 4 + .../grpcpp/impl/codegen/interceptor_common.h | 18 ++++- .../client_interceptors_end2end_test.cc | 73 +++++++++++++++++++ 4 files changed, 102 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index b4c34a01c9a..1f2b88e9e14 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -314,14 +314,19 @@ class CallOpSendMessage { // Flags are per-message: clear them after use. write_options_.Clear(); } - void FinishOp(bool* status) { send_buf_.Clear(); } + void FinishOp(bool* status) { + send_buf_.Clear(); + if (hijacked_ && failed_send_) { + *status = false; + } + } void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { if (!send_buf_.Valid()) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE); - interceptor_methods->SetSendMessage(&send_buf_); + interceptor_methods->SetSendMessage(&send_buf_, &failed_send_); } void SetFinishInterceptionHookPoint( @@ -333,6 +338,7 @@ class CallOpSendMessage { private: bool hijacked_ = false; + bool failed_send_ = false; ByteBuffer send_buf_; WriteOptions write_options_; }; diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index e449e44a23b..47239332c86 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -118,6 +118,10 @@ class InterceptorBatchMethods { // only interceptors after the current interceptor are created from the // factory objects registered with the channel. virtual std::unique_ptr GetInterceptedChannel() = 0; + + // On a hijacked RPC/ to-be hijacked RPC, this can be called to fail a SEND + // MESSAGE op + virtual void FailHijackedSendMessage() = 0; }; class Interceptor { diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index d0aa23cb0a0..601a929afe6 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -110,12 +110,21 @@ class InterceptorBatchMethodsImpl Status* GetRecvStatus() override { return recv_status_; } + void FailHijackedSendMessage() override { + GPR_CODEGEN_ASSERT(hooks_[static_cast( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)]); + *fail_send_message_ = true; + } + std::multimap* GetRecvTrailingMetadata() override { return recv_trailing_metadata_->map(); } - void SetSendMessage(ByteBuffer* buf) { send_message_ = buf; } + void SetSendMessage(ByteBuffer* buf, bool* fail_send_message) { + send_message_ = buf; + fail_send_message_ = fail_send_message; + } void SetSendInitialMetadata( std::multimap* metadata) { @@ -334,6 +343,7 @@ class InterceptorBatchMethodsImpl std::function callback_; ByteBuffer* send_message_ = nullptr; + bool* fail_send_message_ = nullptr; std::multimap* send_initial_metadata_; @@ -451,6 +461,12 @@ class CancelInterceptorBatchMethods "method which has a Cancel notification"); return std::unique_ptr(nullptr); } + + void FailHijackedSendMessage() override { + GPR_CODEGEN_ASSERT(false && + "It is illegal to call FailHijackedSendMessage on a " + "method which has a Cancel notification"); + } }; } // namespace internal } // namespace grpc diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 0b34ec93ae7..81efd154525 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -269,6 +269,49 @@ class HijackingInterceptorMakesAnotherCallFactory } }; +class ClientStreamingRpcHijackingInterceptor + : public experimental::Interceptor { + public: + ClientStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) { + info_ = info; + } + virtual void Intercept(experimental::InterceptorBatchMethods* methods) { + bool hijack = false; + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { + hijack = true; + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + if (++count_ > 10) { + methods->FailHijackedSendMessage(); + } + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { + auto* status = methods->GetRecvStatus(); + *status = Status(StatusCode::UNAVAILABLE, "Done sending 10 messages"); + } + if (hijack) { + methods->Hijack(); + } else { + methods->Proceed(); + } + } + + private: + experimental::ClientRpcInfo* info_; + int count_ = 0; +}; +class ClientStreamingRpcHijackingInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return new ClientStreamingRpcHijackingInterceptor(info); + } +}; + class LoggingInterceptor : public experimental::Interceptor { public: LoggingInterceptor(experimental::ClientRpcInfo* info) { info_ = info; } @@ -535,6 +578,36 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) { EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } +TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingHijackingTest) { + ChannelArguments args; + auto creators = std::unique_ptr>>( + new std::vector< + std::unique_ptr>()); + creators->push_back( + std::unique_ptr( + new ClientStreamingRpcHijackingInterceptorFactory())); + auto channel = experimental::CreateCustomChannelWithInterceptors( + server_address_, InsecureChannelCredentials(), args, std::move(creators)); + + auto stub = grpc::testing::EchoTestService::NewStub(channel); + ClientContext ctx; + EchoRequest req; + EchoResponse resp; + req.mutable_param()->set_echo_metadata(true); + req.set_message("Hello"); + string expected_resp = ""; + auto writer = stub->RequestStream(&ctx, &resp); + for (int i = 0; i < 10; i++) { + EXPECT_TRUE(writer->Write(req)); + expected_resp += "Hello"; + } + // Expect that the interceptor will reject the 11th message + EXPECT_FALSE(writer->Write(req)); + Status s = writer->Finish(); + EXPECT_EQ(s.ok(), false); +} + TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); From a9bee9b7edb4045efd52b0e238d07485a791162f Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 14 Nov 2018 17:48:35 -0800 Subject: [PATCH 0207/2143] Make Pluck use the changes made in FinalizeResult --- include/grpcpp/impl/codegen/completion_queue.h | 3 +-- src/cpp/server/server_cc.cc | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index d603c7c7009..fb38788f7d6 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -307,8 +307,7 @@ class CompletionQueue : private GrpcLibraryCodegen { void* ignored = tag; if (tag->FinalizeResult(&ignored, &ok)) { GPR_CODEGEN_ASSERT(ignored == tag); - // Ignore mutations by FinalizeResult: Pluck returns the C API status - return ev.success != 0; + return ok; } } } diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 7a98bce507a..a703411c2a1 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -84,10 +84,7 @@ class ShutdownTag : public internal::CompletionQueueTag { class DummyTag : public internal::CompletionQueueTag { public: - bool FinalizeResult(void** tag, bool* status) { - *status = true; - return true; - } + bool FinalizeResult(void** tag, bool* status) { return true; } }; class UnimplementedAsyncRequestContext { From 2bd38f29df16b874bea254e001e3c40d6945c28c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 17:59:30 -0800 Subject: [PATCH 0208/2143] Batch fixes --- .../GRPCClient/private/GRPCChannel.m | 17 ++++++++++------- .../GRPCClient/private/GRPCWrappedCall.m | 7 +++---- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index fc0448bb962..52dacad9f50 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -84,7 +84,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; NSString *userAgentPrefix = _callOptions.userAgentPrefix; - if (userAgentPrefix) { + if (userAgentPrefix.length != 0) { args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = [_callOptions.userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; } else { @@ -242,7 +242,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (self->_disconnected) { isDisconnected = YES; } else { - GRPCAssert(self->_unmanagedChannel != NULL, NSInvalidArgumentException, @"Invalid channel."); + GRPCAssert(self->_unmanagedChannel != NULL, NSInternalInconsistencyException, @"Channel should have valid unmanaged channel."); NSString *serverAuthority = callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; @@ -281,14 +281,17 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; // This function should be called on _dispatchQueue. - (void)ref { - _refcount++; - if (_refcount == 1 && _lastDispatch != nil) { - _lastDispatch = nil; - } + dispatch_sync(_dispatchQueue, ^{ + self->_refcount++; + if (self->_refcount == 1 && self->_lastDispatch != nil) { + self->_lastDispatch = nil; + } + }); } - (void)unref { dispatch_async(_dispatchQueue, ^{ + GRPCAssert(self->_refcount > 0, NSInternalInconsistencyException, @"Illegal reference count."); self->_refcount--; if (self->_refcount == 0 && !self->_disconnected) { // Start timer. @@ -298,7 +301,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; self->_lastDispatch = now; dispatch_after(delay, self->_dispatchQueue, ^{ // Timed disconnection. - if (self->_lastDispatch == now) { + if (!self->_disconnected && self->_lastDispatch == now) { grpc_channel_destroy(self->_unmanagedChannel); self->_unmanagedChannel = NULL; self->_disconnected = YES; diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 2358c7bb0a8..f3fe8bac455 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -30,6 +30,7 @@ #import "NSData+GRPC.h" #import "NSDictionary+GRPC.h" #import "NSError+GRPC.h" +#import "utilities.h" #import "GRPCOpBatchLog.h" @@ -248,16 +249,14 @@ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path callOptions:(GRPCCallOptions *)callOptions { - if (host.length == 0 || path.length == 0) { - [NSException raise:NSInvalidArgumentException format:@"path and host cannot be nil."]; - } + GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, @"path and host cannot be nil."); if ((self = [super init])) { // Each completion queue consumes one thread. There's a trade to be made between creating and // consuming too many threads and having contention of multiple calls in a single completion // queue. Currently we use a singleton queue. _queue = [GRPCCompletionQueue completionQueue]; - BOOL disconnected; + BOOL disconnected = NO; do { _channel = [[GRPCChannelPool sharedInstance] channelWithHost:host callOptions:callOptions]; if (_channel == nil) { From ceeb28a360d48389edb8c1c91a1efac46e24a9b7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 14 Nov 2018 18:02:54 -0800 Subject: [PATCH 0209/2143] s/count/count_/ --- test/cpp/end2end/client_interceptors_end2end_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index b94a3d752e8..459788ba519 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -318,7 +318,7 @@ class ServerStreamingRpcHijackingInterceptor } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { - if (++count > 10) { + if (++count_ > 10) { methods->FailHijackedRecvMessage(); } EchoResponse* resp = @@ -343,7 +343,7 @@ class ServerStreamingRpcHijackingInterceptor private: experimental::ClientRpcInfo* info_; - int count = 0; + int count_ = 0; }; class ServerStreamingRpcHijackingInterceptorFactory From b5434c05aaaacfba9d6ef6882b6c1f3285a304e2 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 18:48:09 -0800 Subject: [PATCH 0210/2143] Make tests pass --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/private/GRPCChannel.m | 11 +++++------ src/objective-c/GRPCClient/private/GRPCWrappedCall.m | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 2a56514bdc9..1ba55a7744d 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -249,7 +249,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); GRPCAssert(!self->_finished, NSInternalInconsistencyException, @"Call is half-closed before sending data."); - if (self->_call) { + if (self->_pipe) { [self->_pipe writeValue:data]; } }); diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 52dacad9f50..f63157c9743 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -281,15 +281,14 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; // This function should be called on _dispatchQueue. - (void)ref { - dispatch_sync(_dispatchQueue, ^{ - self->_refcount++; - if (self->_refcount == 1 && self->_lastDispatch != nil) { - self->_lastDispatch = nil; - } - }); + _refcount++; + if (_refcount == 1 && _lastDispatch != nil) { + _lastDispatch = nil; + } } - (void)unref { + NSLog(@"unref"); dispatch_async(_dispatchQueue, ^{ GRPCAssert(self->_refcount > 0, NSInternalInconsistencyException, @"Illegal reference count."); self->_refcount--; diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index f3fe8bac455..905719f4642 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -325,7 +325,6 @@ - (void)dealloc { if (_call) { grpc_call_unref(_call); - [_channel unref]; } [_channel unref]; _channel = nil; From e14ec44b0ac1512bc3def0f2094be883d1b53c5f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 14 Nov 2018 18:52:35 -0800 Subject: [PATCH 0211/2143] clang-format --- src/objective-c/GRPCClient/GRPCCall.m | 5 +++-- src/objective-c/GRPCClient/private/GRPCChannel.m | 3 ++- src/objective-c/GRPCClient/private/GRPCWrappedCall.m | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 1ba55a7744d..4068c3b4608 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -209,8 +209,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; } }); }; - id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:valueHandler - completionHandler:completionHandler]; + id responseWriteable = + [[GRXWriteable alloc] initWithValueHandler:valueHandler + completionHandler:completionHandler]; [self->_call startWithWriteable:responseWriteable]; }); } diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index f63157c9743..2933ca7044a 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -242,7 +242,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (self->_disconnected) { isDisconnected = YES; } else { - GRPCAssert(self->_unmanagedChannel != NULL, NSInternalInconsistencyException, @"Channel should have valid unmanaged channel."); + GRPCAssert(self->_unmanagedChannel != NULL, NSInternalInconsistencyException, + @"Channel should have valid unmanaged channel."); NSString *serverAuthority = callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 905719f4642..aa7d60786ea 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -249,7 +249,8 @@ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path callOptions:(GRPCCallOptions *)callOptions { - GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, @"path and host cannot be nil."); + GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, + @"path and host cannot be nil."); if ((self = [super init])) { // Each completion queue consumes one thread. There's a trade to be made between creating and From 7500528b15b3a47343a6483c1b71857cbe00244a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 09:45:12 -0800 Subject: [PATCH 0212/2143] clang-format --- .../transport/cronet/client/secure/cronet_channel_create.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc index 1cb38f25b6d..6e08d27b21d 100644 --- a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc +++ b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc @@ -48,10 +48,12 @@ GRPCAPI grpc_channel* grpc_cronet_secure_channel_create( // Disable client authority filter when using Cronet grpc_arg disable_client_authority_filter_arg; - disable_client_authority_filter_arg.key = const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); + disable_client_authority_filter_arg.key = + const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); disable_client_authority_filter_arg.type = GRPC_ARG_INTEGER; disable_client_authority_filter_arg.value.integer = 1; - grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args, &disable_client_authority_filter_arg, 1); + grpc_channel_args* new_args = grpc_channel_args_copy_and_add( + args, &disable_client_authority_filter_arg, 1); grpc_transport* ct = grpc_create_cronet_transport(engine, target, new_args, reserved); From caf56447d5b67092b99ea74dbe5a7ec9cc7c6b1d Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 15 Nov 2018 10:52:41 -0800 Subject: [PATCH 0213/2143] added custom platform --- third_party/toolchains/BUILD | 20 ++++++++++++++++++++ tools/remote_build/rbe_common.bazelrc | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index f5767f212d6..b9a8cfd46aa 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -73,3 +73,23 @@ platform( } """, ) + +# This target is auto-generated from release/cpp.tpl and should not be +# modified directly. +toolchain( + name = "cc-toolchain-clang-x86_64-default", + exec_compatible_with = [ + "@bazel_tools//platforms:linux", + "@bazel_tools//platforms:x86_64", + "@bazel_tools//tools/cpp:clang", + "//constraints:xenial", + ], + target_compatible_with = [ + "//third_party/toolchains:rbe_ubuntu1604", + "//third_party/toolchains:rbe_ubuntu1604_large", + "@bazel_tools//platforms:linux", + "@bazel_tools//platforms:x86_64", + ], + toolchain = "//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:cc-compiler-k8", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index f17ed10f57e..82b59355cb6 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -19,7 +19,7 @@ startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 build --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain -build --extra_toolchains=@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default +build --extra_toolchains=//third_party/toolchains:cc-toolchain-clang-x86_64-default # Use custom execution platforms defined in third_party/toolchains build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large build --host_platform=//third_party/toolchains:rbe_ubuntu1604 From 6b6ab2bdc9d03ffe85398451342a140320aac1dd Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 12:22:38 -0800 Subject: [PATCH 0214/2143] Back to NSAssert --- src/objective-c/GRPCClient/GRPCCall.m | 37 +++++++++---------- .../GRPCClient/private/GRPCChannel.m | 22 +++++------ .../GRPCClient/private/GRPCChannelPool.m | 6 +-- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- .../private/GRPCSecureChannelFactory.m | 2 +- .../GRPCClient/private/GRPCWrappedCall.m | 4 +- .../GRPCClient/private/utilities.h | 19 ++-------- 7 files changed, 39 insertions(+), 53 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 4068c3b4608..788afeb6c3c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -68,8 +68,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @implementation GRPCRequestOptions - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { - GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, - @"Host and Path cannot be empty"); + NSAssert(host.length != 0 && path.length != 0, @"Host and Path cannot be empty"); if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -116,11 +115,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *_Nullable)callOptions { - GRPCAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, - NSInvalidArgumentException, @"Neither host nor path can be nil."); - GRPCAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, + NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, + @"Neither host nor path can be nil."); + NSAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); - GRPCAssert(responseHandler != nil, NSInvalidArgumentException, @"Response handler required."); + NSAssert(responseHandler != nil, @"Response handler required."); if ((self = [super init])) { _requestOptions = [requestOptions copy]; @@ -157,8 +156,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)start { dispatch_async(_dispatchQueue, ^{ - GRPCAssert(!self->_started, NSInternalInconsistencyException, @"Call already started."); - GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call already canceled."); + NSAssert(!self->_started, @"Call already started."); + NSAssert(!self->_canceled, @"Call already canceled."); self->_started = YES; if (!self->_callOptions) { self->_callOptions = [[GRPCCallOptions alloc] init]; @@ -218,7 +217,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { dispatch_async(_dispatchQueue, ^{ - GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call already canceled."); + NSAssert(!self->_canceled, @"Call already canceled."); self->_canceled = YES; if (self->_call) { [self->_call cancel]; @@ -247,9 +246,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeData:(NSData *)data { dispatch_async(_dispatchQueue, ^{ - GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); - GRPCAssert(!self->_finished, NSInternalInconsistencyException, - @"Call is half-closed before sending data."); + NSAssert(!self->_canceled, @"Call arleady canceled."); + NSAssert(!self->_finished, @"Call is half-closed before sending data."); if (self->_pipe) { [self->_pipe writeValue:data]; } @@ -258,9 +256,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)finish { dispatch_async(_dispatchQueue, ^{ - GRPCAssert(self->_started, NSInternalInconsistencyException, @"Call not started."); - GRPCAssert(!self->_canceled, NSInternalInconsistencyException, @"Call arleady canceled."); - GRPCAssert(!self->_finished, NSInternalInconsistencyException, @"Call already half-closed."); + NSAssert(self->_started, @"Call not started."); + NSAssert(!self->_canceled, @"Call arleady canceled."); + NSAssert(!self->_finished, @"Call already half-closed."); if (self->_pipe) { [self->_pipe writesFinishedWithError:nil]; } @@ -409,10 +407,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. - GRPCAssert(host && path, NSInvalidArgumentException, @"Neither host nor path can be nil."); - GRPCAssert(safety <= GRPCCallSafetyCacheableRequest, NSInvalidArgumentException, + NSAssert(host && path, @"Neither host nor path can be nil."); + NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); - GRPCAssert(requestWriter.state == GRXWriterStateNotStarted, NSInvalidArgumentException, + NSAssert(requestWriter.state == GRXWriterStateNotStarted, @"The requests writer can't be already started."); if ((self = [super init])) { _host = [host copy]; @@ -798,8 +796,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = callOptions; } - GRPCAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, - NSInvalidArgumentException, + NSAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); if (_callOptions.authTokenProvider != nil) { @synchronized(self) { diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 2933ca7044a..ab084fba480 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -40,8 +40,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannelConfiguration - (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { - GRPCAssert(host.length, NSInvalidArgumentException, @"Host must not be empty."); - GRPCAssert(callOptions != nil, NSInvalidArgumentException, @"callOptions must not be empty."); + NSAssert(host.length, @"Host must not be empty."); + NSAssert(callOptions != nil, @"callOptions must not be empty."); if ((self = [super init])) { _host = [host copy]; _callOptions = [callOptions copy]; @@ -193,9 +193,9 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (nullable instancetype)initWithChannelConfiguration: (GRPCChannelConfiguration *)channelConfiguration destroyDelay:(NSTimeInterval)destroyDelay { - GRPCAssert(channelConfiguration != nil, NSInvalidArgumentException, + NSAssert(channelConfiguration != nil, @"channelConfiguration must not be empty."); - GRPCAssert(destroyDelay > 0, NSInvalidArgumentException, @"destroyDelay must be greater than 0."); + NSAssert(destroyDelay > 0, @"destroyDelay must be greater than 0."); if ((self = [super init])) { _configuration = [channelConfiguration copy]; if (@available(iOS 8.0, *)) { @@ -208,7 +208,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; // Create gRPC core channel object. NSString *host = channelConfiguration.host; - GRPCAssert(host.length != 0, NSInvalidArgumentException, @"host cannot be nil"); + NSAssert(host.length != 0, @"host cannot be nil"); NSDictionary *channelArgs; if (channelConfiguration.callOptions.additionalChannelArgs.count != 0) { NSMutableDictionary *args = [channelConfiguration.channelArgs mutableCopy]; @@ -233,22 +233,22 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions disconnected:(BOOL *)disconnected { - GRPCAssert(path.length, NSInvalidArgumentException, @"path must not be empty."); - GRPCAssert(queue, NSInvalidArgumentException, @"completionQueue must not be empty."); - GRPCAssert(callOptions, NSInvalidArgumentException, @"callOptions must not be empty."); + NSAssert(path.length, @"path must not be empty."); + NSAssert(queue, @"completionQueue must not be empty."); + NSAssert(callOptions, @"callOptions must not be empty."); __block BOOL isDisconnected = NO; __block grpc_call *call = NULL; dispatch_sync(_dispatchQueue, ^{ if (self->_disconnected) { isDisconnected = YES; } else { - GRPCAssert(self->_unmanagedChannel != NULL, NSInternalInconsistencyException, + NSAssert(self->_unmanagedChannel != NULL, @"Channel should have valid unmanaged channel."); NSString *serverAuthority = callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; - GRPCAssert(timeout >= 0, NSInvalidArgumentException, @"Invalid timeout"); + NSAssert(timeout >= 0, @"Invalid timeout"); grpc_slice host_slice = grpc_empty_slice(); if (serverAuthority) { host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); @@ -291,7 +291,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (void)unref { NSLog(@"unref"); dispatch_async(_dispatchQueue, ^{ - GRPCAssert(self->_refcount > 0, NSInternalInconsistencyException, @"Illegal reference count."); + NSAssert(self->_refcount > 0, @"Illegal reference count."); self->_refcount--; if (self->_refcount == 0 && !self->_disconnected) { // Start timer. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 85ca527277c..6745010bd49 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -44,7 +44,7 @@ static dispatch_once_t gInitChannelPool; + (nullable instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ gChannelPool = [[GRPCChannelPool alloc] init]; - GRPCAssert(gChannelPool != nil, NSMallocException, @"Cannot initialize global channel pool."); + NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); }); return gChannelPool; } @@ -69,8 +69,8 @@ static dispatch_once_t gInitChannelPool; - (GRPCChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions destroyDelay:(NSTimeInterval)destroyDelay { - GRPCAssert(host.length > 0, NSInvalidArgumentException, @"Host must not be empty."); - GRPCAssert(callOptions != nil, NSInvalidArgumentException, @"callOptions must not be empty."); + NSAssert(host.length > 0, @"Host must not be empty."); + NSAssert(callOptions != nil, @"callOptions must not be empty."); GRPCChannel *channel; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 5fc7427b689..b693b926bad 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -122,7 +122,7 @@ static NSMutableDictionary *gHostCache; if (_transportType == GRPCTransportTypeInsecure) { options.transportType = GRPCTransportTypeInsecure; } else { - GRPCAssert(_transportType == GRPCTransportTypeDefault, NSInvalidArgumentException, + NSAssert(_transportType == GRPCTransportTypeDefault, @"Invalid transport type"); options.transportType = GRPCTransportTypeCronet; } diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 57bd40d6787..f5e7a2b9e20 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -83,7 +83,7 @@ NS_ASSUME_NONNULL_BEGIN if (errorPtr) { *errorPtr = defaultRootsError; } - GRPCAssertWithArgument( + NSAssert( defaultRootsASCII, NSObjectNotAvailableException, @"Could not read gRPCCertificates.bundle/roots.pem. This file, " "with the root certificates, is needed to establish secure (TLS) connections. " diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index aa7d60786ea..ae7f07f1192 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -249,7 +249,7 @@ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path callOptions:(GRPCCallOptions *)callOptions { - GRPCAssert(host.length != 0 && path.length != 0, NSInvalidArgumentException, + NSAssert(host.length != 0 && path.length != 0, @"path and host cannot be nil."); if ((self = [super init])) { @@ -261,6 +261,7 @@ do { _channel = [[GRPCChannelPool sharedInstance] channelWithHost:host callOptions:callOptions]; if (_channel == nil) { + NSAssert(_channel != nil, @"Failed to get a channel for the host."); NSLog(@"Failed to get a channel for the host."); return nil; } @@ -272,6 +273,7 @@ // connectivity monitor disconnection). } while (_call == NULL && disconnected); if (_call == nil) { + NSAssert(_channel != nil, @"Failed to get a channel for the host."); NSLog(@"Failed to create a call."); return nil; } diff --git a/src/objective-c/GRPCClient/private/utilities.h b/src/objective-c/GRPCClient/private/utilities.h index 3e51730d637..8f6baadcf7b 100644 --- a/src/objective-c/GRPCClient/private/utilities.h +++ b/src/objective-c/GRPCClient/private/utilities.h @@ -18,19 +18,6 @@ #import -/** Raise exception when condition not met. Disregard NS_BLOCK_ASSERTIONS. */ -#define GRPCAssert(condition, errorType, errorString) \ - do { \ - if (!(condition)) { \ - [NSException raise:(errorType)format:(errorString)]; \ - } \ - } while (0) - -/** The same as GRPCAssert but allows arguments to be put in the raised string. - */ -#define GRPCAssertWithArgument(condition, errorType, errorFormat, ...) \ - do { \ - if (!(condition)) { \ - [NSException raise:(errorType)format:(errorFormat), __VA_ARGS__]; \ - } \ - } while (0) +/** Raise exception when condition not met. */ +#define GRPCAssert(condition, errorString) \ + NSAssert(condition, errorString) From 8a762d447813db1b1c3fe52b24e638581235460e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 12:56:08 -0800 Subject: [PATCH 0215/2143] Polish nullability + something else --- src/objective-c/GRPCClient/GRPCCall.h | 28 +++++------ src/objective-c/GRPCClient/GRPCCall.m | 4 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 46 +++++++++---------- .../GRPCClient/private/GRPCChannel.h | 2 +- .../GRPCClient/private/GRPCChannel.m | 10 ++-- .../GRPCClient/private/GRPCChannelFactory.h | 4 +- .../GRPCClient/private/GRPCChannelPool.m | 2 +- .../private/GRPCConnectivityMonitor.m | 4 +- .../private/GRPCCronetChannelFactory.m | 22 +++------ .../private/GRPCInsecureChannelFactory.m | 10 ++-- .../private/GRPCSecureChannelFactory.m | 22 ++++----- src/objective-c/ProtoRPC/ProtoRPC.h | 12 ++--- src/objective-c/ProtoRPC/ProtoRPC.m | 14 +++--- src/objective-c/tests/InteropTests.m | 8 ++-- 14 files changed, 86 insertions(+), 102 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index bde69f01c52..fcda4dc8acd 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -159,14 +159,14 @@ extern NSString *const kGRPCTrailersKey; * Issued when initial metadata is received from the server. The task must be scheduled onto the * dispatch queue in property \a dispatchQueue. */ -- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; +- (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; /** * Issued when a message is received from the server. The message is the raw data received from the * server, with decompression and without proto deserialization. The task must be scheduled onto the * dispatch queue in property \a dispatchQueue. */ -- (void)receivedRawMessage:(NSData *_Nullable)message; +- (void)receivedRawMessage:(nullable NSData *)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -175,8 +175,8 @@ extern NSString *const kGRPCTrailersKey; * error descriptions. The task must be scheduled onto the dispatch queue in property * \a dispatchQueue. */ -- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata - error:(NSError *_Nullable)error; +- (void)closedWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata + error:(nullable NSError *)error; @required @@ -234,7 +234,7 @@ extern NSString *const kGRPCTrailersKey; */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler - callOptions:(GRPCCallOptions *_Nullable)callOptions + callOptions:(nullable GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; /** * Convenience initializer for a call that uses default call options (see GRPCCallOptions.m for @@ -342,9 +342,9 @@ NS_ASSUME_NONNULL_END * host parameter should not contain the scheme (http:// or https://), only the name or IP addr * and the port number, for example @"localhost:5050". */ -- (instancetype _Null_unspecified)initWithHost:(NSString *_Null_unspecified)host - path:(NSString *_Null_unspecified)path - requestsWriter:(GRXWriter *_Null_unspecified)requestWriter; +- (null_unspecified instancetype)initWithHost:(null_unspecified NSString *)host + path:(null_unspecified NSString *)path + requestsWriter:(null_unspecified GRXWriter *)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -356,11 +356,11 @@ NS_ASSUME_NONNULL_END * The following methods are deprecated. */ + (void)setCallSafety:(GRPCCallSafety)callSafety - host:(NSString *_Null_unspecified)host - path:(NSString *_Null_unspecified)path; + host:(null_unspecified NSString *)host + path:(null_unspecified NSString *)path; @property(null_unspecified, atomic, copy, readwrite) NSString *serverName; @property NSTimeInterval timeout; -- (void)setResponseDispatchQueue:(dispatch_queue_t _Null_unspecified)queue; +- (void)setResponseDispatchQueue:(null_unspecified dispatch_queue_t)queue; @end @@ -371,11 +371,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (id _Null_unspecified)objectForKeyedSubscript:(id _Null_unspecified)key; -- (void)setObject:(id _Null_unspecified)obj forKeyedSubscript:(id _Null_unspecified)key; +- (null_unspecified id)objectForKeyedSubscript:(null_unspecified id)key; +- (void)setObject:(null_unspecified id)obj forKeyedSubscript:(null_unspecified id)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(id _Null_unspecified)key; +- (void)removeObjectForKey:(null_unspecified id)key; @end #pragma clang diagnostic push diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 788afeb6c3c..68b51d8c846 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -114,7 +114,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)responseHandler - callOptions:(GRPCCallOptions *_Nullable)callOptions { + callOptions:(GRPCCallOptions *)callOptions { NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, @"Neither host nor path can be nil."); NSAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, @@ -134,7 +134,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (@available(iOS 8.0, *)) { _dispatchQueue = dispatch_queue_create( NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { // Fallback on earlier versions _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index bb8a1d251a9..61d85642863 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -78,7 +78,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * :authority header field of the call and performs an extra check that server's certificate * matches the :authority header. */ -@property(copy, readonly) NSString *serverAuthority; +@property(copy, readonly, nullable) NSString *serverAuthority; /** * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to @@ -94,18 +94,18 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * request's "authorization" header field. This parameter should not be used simultaneously with * \a authTokenProvider. */ -@property(copy, readonly) NSString *oauth2AccessToken; +@property(copy, readonly, nullable) NSString *oauth2AccessToken; /** * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. */ -@property(readonly) id authTokenProvider; +@property(readonly, nullable) id authTokenProvider; /** * Initial metadata key-value pairs that should be included in the request. */ -@property(copy, readonly) NSDictionary *initialMetadata; +@property(copy, readonly, nullable) NSDictionary *initialMetadata; // Channel parameters; take into account of channel signature. @@ -113,7 +113,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * Custom string that is prefixed to a request's user-agent header field before gRPC's internal * user-agent string. */ -@property(copy, readonly) NSString *userAgentPrefix; +@property(copy, readonly, nullable) NSString *userAgentPrefix; /** * The size limit for the response received from server. If it is exceeded, an error with status @@ -152,7 +152,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * Specify channel args to be used for this call. For a list of channel args available, see * grpc/grpc_types.h */ -@property(copy, readonly) NSDictionary *additionalChannelArgs; +@property(copy, readonly, nullable) NSDictionary *additionalChannelArgs; // Parameters for SSL authentication. @@ -160,17 +160,17 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default * root certificates. */ -@property(copy, readonly) NSString *PEMRootCertificates; +@property(copy, readonly, nullable) NSString *PEMRootCertificates; /** * PEM format private key for client authentication, if required by the server. */ -@property(copy, readonly) NSString *PEMPrivateKey; +@property(copy, readonly, nullable) NSString *PEMPrivateKey; /** * PEM format certificate chain for client authentication, if required by the server. */ -@property(copy, readonly) NSString *PEMCertChain; +@property(copy, readonly, nullable) NSString *PEMCertChain; /** * Select the transport type to be used for this call. @@ -180,13 +180,13 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * Override the hostname during the TLS hostname validation process. */ -@property(copy, readonly) NSString *hostNameOverride; +@property(copy, readonly, nullable) NSString *hostNameOverride; /** * A string that specify the domain where channel is being cached. Channels with different domains * will not get cached to the same connection. */ -@property(copy, readonly) NSString *channelPoolDomain; +@property(copy, readonly, nullable) NSString *channelPoolDomain; /** * Channel id allows control of channel caching within a channelPoolDomain. A call with a unique @@ -199,7 +199,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * Return if the channel options are equal to another object. */ -- (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions; +- (BOOL)hasChannelOptionsEqualTo:(nonnull GRPCCallOptions *)callOptions; /** * Hash for channel options. @@ -219,7 +219,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * :authority header field of the call and performs an extra check that server's certificate * matches the :authority header. */ -@property(copy, readwrite) NSString *serverAuthority; +@property(copy, readwrite, nullable) NSString *serverAuthority; /** * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to @@ -236,18 +236,18 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * request's "authorization" header field. This parameter should not be used simultaneously with * \a authTokenProvider. */ -@property(copy, readwrite) NSString *oauth2AccessToken; +@property(copy, readwrite, nullable) NSString *oauth2AccessToken; /** * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. */ -@property(readwrite) id authTokenProvider; +@property(readwrite, nullable) id authTokenProvider; /** * Initial metadata key-value pairs that should be included in the request. */ -@property(copy, readwrite) NSDictionary *initialMetadata; +@property(copy, readwrite, nullable) NSDictionary *initialMetadata; // Channel parameters; take into account of channel signature. @@ -255,7 +255,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * Custom string that is prefixed to a request's user-agent header field before gRPC's internal * user-agent string. */ -@property(copy, readwrite) NSString *userAgentPrefix; +@property(copy, readwrite, nullable) NSString *userAgentPrefix; /** * The size limit for the response received from server. If it is exceeded, an error with status @@ -296,7 +296,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * Specify channel args to be used for this call. For a list of channel args available, see * grpc/grpc_types.h */ -@property(copy, readwrite) NSDictionary *additionalChannelArgs; +@property(copy, readwrite, nullable) NSDictionary *additionalChannelArgs; // Parameters for SSL authentication. @@ -304,17 +304,17 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default * root certificates. */ -@property(copy, readwrite) NSString *PEMRootCertificates; +@property(copy, readwrite, nullable) NSString *PEMRootCertificates; /** * PEM format private key for client authentication, if required by the server. */ -@property(copy, readwrite) NSString *PEMPrivateKey; +@property(copy, readwrite, nullable) NSString *PEMPrivateKey; /** * PEM format certificate chain for client authentication, if required by the server. */ -@property(copy, readwrite) NSString *PEMCertChain; +@property(copy, readwrite, nullable) NSString *PEMCertChain; /** * Select the transport type to be used for this call. @@ -324,7 +324,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * Override the hostname during the TLS hostname validation process. */ -@property(copy, readwrite) NSString *hostNameOverride; +@property(copy, readwrite, nullable) NSString *hostNameOverride; /** * A string that specify the domain where channel is being cached. Channels with different domains @@ -332,7 +332,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * domain 'io.grpc.example' so that its calls do not reuse the channel created by other modules in * the same process. */ -@property(copy, readwrite) NSString *channelPoolDomain; +@property(copy, readwrite, nullable) NSString *channelPoolDomain; /** * Channel id allows a call to force creating a new channel (connection) rather than using a cached diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 32e68bb2625..4dbe0c276ce 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -85,7 +85,7 @@ NS_ASSUME_NONNULL_BEGIN - (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions - disconnected:(BOOL *_Nullable)disconnected; + disconnected:(nullable BOOL *)disconnected; /** * Unref the channel when a call is done. It also decreases the channel's refcount. If the refcount diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index ab084fba480..de3302598ef 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -39,7 +39,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannelConfiguration -- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { +- (instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { NSAssert(host.length, @"Host must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); if ((self = [super init])) { @@ -143,7 +143,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; return args; } -- (nonnull id)copyWithZone:(nullable NSZone *)zone { +- (id)copyWithZone:(NSZone *)zone { GRPCChannelConfiguration *newConfig = [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; @@ -184,13 +184,13 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } @synthesize disconnected = _disconnected; -- (nullable instancetype)initWithChannelConfiguration: +- (instancetype)initWithChannelConfiguration: (GRPCChannelConfiguration *)channelConfiguration { return [self initWithChannelConfiguration:channelConfiguration destroyDelay:kDefaultChannelDestroyDelay]; } -- (nullable instancetype)initWithChannelConfiguration: +- (instancetype)initWithChannelConfiguration: (GRPCChannelConfiguration *)channelConfiguration destroyDelay:(NSTimeInterval)destroyDelay { NSAssert(channelConfiguration != nil, @@ -201,7 +201,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (@available(iOS 8.0, *)) { _dispatchQueue = dispatch_queue_create( NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h index 3a3500fc95e..a934e966e9d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h @@ -26,8 +26,8 @@ NS_ASSUME_NONNULL_BEGIN @protocol GRPCChannelFactory /** Create a channel with specific channel args to a specific host. */ -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args; +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSDictionary *)args; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 6745010bd49..72554ca6dc8 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -41,7 +41,7 @@ static dispatch_once_t gInitChannelPool; NSMutableDictionary *_channelPool; } -+ (nullable instancetype)sharedInstance { ++ (instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ gChannelPool = [[GRPCChannelPool alloc] init]; NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); diff --git a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m index a36788b35aa..bb8618ff335 100644 --- a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m +++ b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m @@ -76,14 +76,14 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach } } -+ (void)registerObserver:(_Nonnull id)observer selector:(SEL)selector { ++ (void)registerObserver:(id)observer selector:(SEL)selector { [[NSNotificationCenter defaultCenter] addObserver:observer selector:selector name:kGRPCConnectivityNotification object:nil]; } -+ (void)unregisterObserver:(_Nonnull id)observer { ++ (void)unregisterObserver:(id)observer { [[NSNotificationCenter defaultCenter] removeObserver:observer]; } diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 781881d211b..74ea9723b3d 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -26,13 +26,11 @@ #import #include -NS_ASSUME_NONNULL_BEGIN - @implementation GRPCCronetChannelFactory { stream_engine *_cronetEngine; } -+ (instancetype _Nullable)sharedInstance { ++ (instancetype)sharedInstance { static GRPCCronetChannelFactory *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -41,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN return instance; } -- (instancetype _Nullable)initWithEngine:(stream_engine *)engine { +- (instancetype)initWithEngine:(stream_engine *)engine { if (!engine) { [NSException raise:NSInvalidArgumentException format:@"Cronet engine is NULL. Set it first."]; return nil; @@ -52,8 +50,8 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *)args { grpc_channel_args *channelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_cronet_secure_channel_create(_cronetEngine, host.UTF8String, channelArgs, NULL); @@ -63,22 +61,18 @@ NS_ASSUME_NONNULL_BEGIN @end -NS_ASSUME_NONNULL_END - #else -NS_ASSUME_NONNULL_BEGIN - @implementation GRPCCronetChannelFactory -+ (instancetype _Nullable)sharedInstance { ++ (instancetype)sharedInstance { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return nil; } -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *)args { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return NULL; @@ -86,6 +80,4 @@ NS_ASSUME_NONNULL_BEGIN @end -NS_ASSUME_NONNULL_END - #endif diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index 99698877124..3e9ebe7ae02 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -21,11 +21,9 @@ #import "ChannelArgsUtil.h" #import "GRPCChannel.h" -NS_ASSUME_NONNULL_BEGIN - @implementation GRPCInsecureChannelFactory -+ (instancetype _Nullable)sharedInstance { ++ (instancetype)sharedInstance { static GRPCInsecureChannelFactory *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -34,8 +32,8 @@ NS_ASSUME_NONNULL_BEGIN return instance; } -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); @@ -44,5 +42,3 @@ NS_ASSUME_NONNULL_BEGIN } @end - -NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index f5e7a2b9e20..2e7f1a0dbe2 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -24,15 +24,13 @@ #import "GRPCChannel.h" #import "utilities.h" -NS_ASSUME_NONNULL_BEGIN - @implementation GRPCSecureChannelFactory { grpc_channel_credentials *_channelCreds; } -+ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString *_Nullable)rootCerts - privateKey:(NSString *_Nullable)privateKey - certChain:(NSString *_Nullable)certChain ++ (instancetype)factoryWithPEMRootCertificates:(NSString *)rootCerts + privateKey:(NSString *)privateKey + certChain:(NSString *)certChain error:(NSError **)errorPtr { return [[self alloc] initWithPEMRootCerts:rootCerts privateKey:privateKey @@ -40,7 +38,7 @@ NS_ASSUME_NONNULL_BEGIN error:errorPtr]; } -- (NSData *_Nullable)nullTerminatedDataWithString:(NSString *_Nullable)string { +- (NSData *)nullTerminatedDataWithString:(NSString *)string { // dataUsingEncoding: does not return a null-terminated string. NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; if (data == nil) { @@ -51,9 +49,9 @@ NS_ASSUME_NONNULL_BEGIN return nullTerminated; } -- (instancetype _Nullable)initWithPEMRootCerts:(NSString *_Nullable)rootCerts - privateKey:(NSString *_Nullable)privateKey - certChain:(NSString *_Nullable)certChain +- (instancetype)initWithPEMRootCerts:(NSString *)rootCerts + privateKey:(NSString *)privateKey + certChain:(NSString *)certChain error:(NSError **)errorPtr { static NSData *defaultRootsASCII; static NSError *defaultRootsError; @@ -117,8 +115,8 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); @@ -133,5 +131,3 @@ NS_ASSUME_NONNULL_BEGIN } @end - -NS_ASSUME_NONNULL_END diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index b0f4ced99e8..dc776368a8f 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -33,13 +33,13 @@ NS_ASSUME_NONNULL_BEGIN /** * Issued when initial metadata is received from the server. The task must be scheduled onto the * dispatch queue in property \a dispatchQueue. */ -- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata; +- (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; /** * Issued when a message is received from the server. The message is the deserialized proto object. * The task must be scheduled onto the dispatch queue in property \a dispatchQueue. */ -- (void)receivedProtoMessage:(GPBMessage *_Nullable)message; +- (void)receivedProtoMessage:(nullable GPBMessage *)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -48,8 +48,8 @@ NS_ASSUME_NONNULL_BEGIN * error descriptions. The task must be scheduled onto the dispatch queue in property * \a dispatchQueue. */ -- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata - error:(NSError *_Nullable)error; +- (void)closedWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata + error:(nullable NSError *)error; @required @@ -75,7 +75,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message responseHandler:(id)handler - callOptions:(GRPCCallOptions *_Nullable)callOptions + callOptions:(nullable GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** @@ -100,7 +100,7 @@ NS_ASSUME_NONNULL_BEGIN */ - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler - callOptions:(GRPCCallOptions *_Nullable)callOptions + callOptions:(nullable GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 34891e8953b..f99da45fef9 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -52,7 +52,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions message:(GPBMessage *)message responseHandler:(id)handler - callOptions:(GRPCCallOptions *_Nullable)callOptions + callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { if ((self = [super init])) { _call = [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions @@ -88,7 +88,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions responseHandler:(id)handler - callOptions:(GRPCCallOptions *_Nullable)callOptions + callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; @@ -108,7 +108,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing if (@available(iOS 8.0, *)) { _dispatchQueue = dispatch_queue_create( NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, -1)); + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } @@ -171,7 +171,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing }); } -- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { dispatch_async(_dispatchQueue, ^{ if (initialMetadata != nil && [self->_handler respondsToSelector:@selector(initialMetadata:)]) { [self->_handler receivedInitialMetadata:initialMetadata]; @@ -179,7 +179,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing }); } -- (void)receivedRawMessage:(NSData *_Nullable)message { +- (void)receivedRawMessage:(NSData *)message { dispatch_async(_dispatchQueue, ^{ if (self->_handler && message != nil) { NSError *error = nil; @@ -202,8 +202,8 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing }); } -- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata - error:(NSError *_Nullable)error { +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata + error:(NSError *)error { dispatch_async(_dispatchQueue, ^{ if ([self->_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { [self->_handler closedWithTrailingMetadata:trailingMetadata error:error]; diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index c42718f15ee..dcc8f1b589a 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -102,7 +102,7 @@ BOOL isRemoteInteropTest(NSString *host) { return self; } -- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { dispatch_async(_dispatchQueue, ^{ if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); @@ -110,7 +110,7 @@ BOOL isRemoteInteropTest(NSString *host) { }); } -- (void)receivedProtoMessage:(GPBMessage *_Nullable)message { +- (void)receivedProtoMessage:(GPBMessage *)message { dispatch_async(_dispatchQueue, ^{ if (_messageCallback) { _messageCallback(message); @@ -118,8 +118,8 @@ BOOL isRemoteInteropTest(NSString *host) { }); } -- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata - error:(NSError *_Nullable)error { +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata + error:(NSError *)error { dispatch_async(_dispatchQueue, ^{ if (_closeCallback) { _closeCallback(trailingMetadata, error); From 0911e489e3fe22e2ca5d7c927dac83358f2f05b7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 15 Nov 2018 13:55:56 -0800 Subject: [PATCH 0216/2143] Add a method to check whether the message was received successfully --- include/grpcpp/impl/codegen/call_op_set.h | 6 ++++-- include/grpcpp/impl/codegen/interceptor.h | 3 +++ include/grpcpp/impl/codegen/interceptor_common.h | 10 ++++++++++ test/cpp/end2end/client_interceptors_end2end_test.cc | 12 ++++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index aae8b9d3e37..3699ec94f2f 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -406,12 +406,13 @@ class CallOpRecvMessage { void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { + if (message_ == nullptr) return; interceptor_methods->SetRecvMessage(message_, &got_message); } void SetFinishInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - if (!got_message) return; + if (message_ == nullptr) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); } @@ -501,12 +502,13 @@ class CallOpGenericRecvMessage { void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { + if (!deserialize_) return; interceptor_methods->SetRecvMessage(message_, &got_message); } void SetFinishInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - if (!got_message) return; + if (!deserialize_) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); } diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 943376a5451..b977c350166 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -103,6 +103,9 @@ class InterceptorBatchMethods { // is already deserialized virtual void* GetRecvMessage() = 0; + // Checks whether the RECV MESSAGE op completed successfully + virtual bool GetRecvMessageStatus() = 0; + // Returns a modifiable multimap of the received initial metadata virtual std::multimap* GetRecvInitialMetadata() = 0; diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index d23b71f8a77..b2e92dd6f3d 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -103,6 +103,8 @@ class InterceptorBatchMethodsImpl void* GetRecvMessage() override { return recv_message_; } + bool GetRecvMessageStatus() override { return *got_message_; } + std::multimap* GetRecvInitialMetadata() override { return recv_initial_metadata_->map(); @@ -432,6 +434,14 @@ class CancelInterceptorBatchMethods return nullptr; } + bool GetRecvMessageStatus() override { + GPR_CODEGEN_ASSERT( + false && + "It is illegal to call GetRecvMessageStatus on a method which " + "has a Cancel notification"); + return false; + } + std::multimap* GetRecvInitialMetadata() override { GPR_CODEGEN_ASSERT(false && diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 459788ba519..4d4760a6524 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -325,6 +325,12 @@ class ServerStreamingRpcHijackingInterceptor static_cast(methods->GetRecvMessage()); resp->set_message("Hello"); } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { + // Only the last message will be a failure + EXPECT_FALSE(got_failed_message_); + got_failed_message_ = !methods->GetRecvMessageStatus(); + } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { auto* map = methods->GetRecvTrailingMetadata(); @@ -341,11 +347,16 @@ class ServerStreamingRpcHijackingInterceptor } } + static bool GotFailedMessage() { return got_failed_message_; } + private: experimental::ClientRpcInfo* info_; + static bool got_failed_message_; int count_ = 0; }; +bool ServerStreamingRpcHijackingInterceptor::got_failed_message_ = false; + class ServerStreamingRpcHijackingInterceptorFactory : public experimental::ClientInterceptorFactoryInterface { public: @@ -634,6 +645,7 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingHijackingTest) { auto channel = experimental::CreateCustomChannelWithInterceptors( server_address_, InsecureChannelCredentials(), args, std::move(creators)); MakeServerStreamingCall(channel); + EXPECT_TRUE(ServerStreamingRpcHijackingInterceptor::GotFailedMessage()); } TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { From 4d84165bb00b18bad657a6f8b09a97a655a08a29 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 15 Nov 2018 13:56:30 -0800 Subject: [PATCH 0217/2143] added machine size to toolchain constraints --- third_party/toolchains/BUILD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index b9a8cfd46aa..2699cf391d9 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -83,6 +83,8 @@ toolchain( "@bazel_tools//platforms:x86_64", "@bazel_tools//tools/cpp:clang", "//constraints:xenial", + "//third_party/toolchains/machine_size:standard", + "//third_party/toolchains/machine_size:large", ], target_compatible_with = [ "//third_party/toolchains:rbe_ubuntu1604", From 57464321214a5ce34e5de1868ce4eb3624ebdebb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 14:00:51 -0800 Subject: [PATCH 0218/2143] Fix handler release - Part 1 --- src/objective-c/GRPCClient/GRPCCall.h | 9 +++---- src/objective-c/ProtoRPC/ProtoRPC.h | 7 ++---- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 24 +++++++------------ src/objective-c/tests/InteropTests.m | 24 +++++++------------ 4 files changed, 23 insertions(+), 41 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index fcda4dc8acd..7f80c17f1f3 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -156,15 +156,13 @@ extern NSString *const kGRPCTrailersKey; @optional /** - * Issued when initial metadata is received from the server. The task must be scheduled onto the - * dispatch queue in property \a dispatchQueue. + * Issued when initial metadata is received from the server. */ - (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; /** * Issued when a message is received from the server. The message is the raw data received from the - * server, with decompression and without proto deserialization. The task must be scheduled onto the - * dispatch queue in property \a dispatchQueue. + * server, with decompression and without proto deserialization. */ - (void)receivedRawMessage:(nullable NSData *)message; @@ -172,8 +170,7 @@ extern NSString *const kGRPCTrailersKey; * Issued when a call finished. If the call finished successfully, \a error is nil and \a * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error * is non-nil and contains the corresponding error information, including gRPC error codes and - * error descriptions. The task must be scheduled onto the dispatch queue in property - * \a dispatchQueue. + * error descriptions. */ - (void)closedWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index dc776368a8f..569aaa79e4d 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -31,13 +31,11 @@ NS_ASSUME_NONNULL_BEGIN @optional /** - * Issued when initial metadata is received from the server. The task must be scheduled onto the - * dispatch queue in property \a dispatchQueue. */ + * Issued when initial metadata is received from the server. - (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; /** * Issued when a message is received from the server. The message is the deserialized proto object. - * The task must be scheduled onto the dispatch queue in property \a dispatchQueue. */ - (void)receivedProtoMessage:(nullable GPBMessage *)message; @@ -45,8 +43,7 @@ NS_ASSUME_NONNULL_BEGIN * Issued when a call finished. If the call finished successfully, \a error is nil and \a * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error * is non-nil and contains the corresponding error information, including gRPC error codes and - * error descriptions. The task must be scheduled onto the dispatch queue in property - * \a dispatchQueue. + * error descriptions. */ - (void)closedWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index 28f94cd8c77..e49f58ae9d3 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -82,28 +82,22 @@ static const NSTimeInterval kTestTimeout = 16; } - (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { - dispatch_async(_dispatchQueue, ^{ - if (self->_initialMetadataCallback) { - self->_initialMetadataCallback(initialMetadata); - } - }); + if (self->_initialMetadataCallback) { + self->_initialMetadataCallback(initialMetadata); + } } - (void)receivedRawMessage:(GPBMessage *_Nullable)message { - dispatch_async(_dispatchQueue, ^{ - if (self->_messageCallback) { - self->_messageCallback(message); - } - }); + if (self->_messageCallback) { + self->_messageCallback(message); + } } - (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata error:(NSError *_Nullable)error { - dispatch_async(_dispatchQueue, ^{ - if (self->_closeCallback) { - self->_closeCallback(trailingMetadata, error); - } - }); + if (self->_closeCallback) { + self->_closeCallback(trailingMetadata, error); + } } - (dispatch_queue_t)dispatchQueue { diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index dcc8f1b589a..8754bd5ccaf 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -103,28 +103,22 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { - dispatch_async(_dispatchQueue, ^{ - if (_initialMetadataCallback) { - _initialMetadataCallback(initialMetadata); - } - }); + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } } - (void)receivedProtoMessage:(GPBMessage *)message { - dispatch_async(_dispatchQueue, ^{ - if (_messageCallback) { - _messageCallback(message); - } - }); + if (_messageCallback) { + _messageCallback(message); + } } - (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - dispatch_async(_dispatchQueue, ^{ - if (_closeCallback) { - _closeCallback(trailingMetadata, error); - } - }); + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } } - (dispatch_queue_t)dispatchQueue { From 17ce7e0d94d147040c86cd3d92b03d46f591f681 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 15 Nov 2018 14:26:30 -0800 Subject: [PATCH 0219/2143] addressed Nick's comments --- third_party/toolchains/BUILD | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 2699cf391d9..27a62b74950 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -59,7 +59,7 @@ platform( "@bazel_tools//platforms:linux", "@bazel_tools//tools/cpp:clang", "@bazel_toolchains//constraints:xenial", - "@@bazel_toolchains//constraints/sanitizers:support_msan", + "@bazel_toolchains//constraints/sanitizers:support_msan", "//third_party/toolchains/machine_size:large", ], remote_execution_properties = """ @@ -82,7 +82,8 @@ toolchain( "@bazel_tools//platforms:linux", "@bazel_tools//platforms:x86_64", "@bazel_tools//tools/cpp:clang", - "//constraints:xenial", + "@bazel_toolchains//constraints:xenial", + "@bazel_toolchains//constraints/sanitizers:support_msan", "//third_party/toolchains/machine_size:standard", "//third_party/toolchains/machine_size:large", ], From 8575588fde9cfb7c8ab1bcd550e13b2f635a9292 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 15 Nov 2018 14:32:35 -0800 Subject: [PATCH 0220/2143] added path prefix to bazel_toolchains repo --- third_party/toolchains/BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 27a62b74950..e7ef03f5db8 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -93,6 +93,6 @@ toolchain( "@bazel_tools//platforms:linux", "@bazel_tools//platforms:x86_64", ], - toolchain = "//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:cc-compiler-k8", + toolchain = "@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:cc-compiler-k8", toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", ) From 3f70672827018b97e7ce13be826d91e8455ce19f Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 15 Nov 2018 14:39:29 -0800 Subject: [PATCH 0221/2143] reverted bazel-toolchains alias to its original form --- third_party/toolchains/BUILD | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index e7ef03f5db8..4b075eb7dc9 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -35,8 +35,8 @@ platform( "@bazel_tools//platforms:x86_64", "@bazel_tools//platforms:linux", "@bazel_tools//tools/cpp:clang", - "@bazel_toolchains//constraints:xenial", - "@bazel_toolchains//constraints/sanitizers:support_msan", + "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", + "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", "//third_party/toolchains/machine_size:standard", ], remote_execution_properties = """ @@ -58,8 +58,8 @@ platform( "@bazel_tools//platforms:x86_64", "@bazel_tools//platforms:linux", "@bazel_tools//tools/cpp:clang", - "@bazel_toolchains//constraints:xenial", - "@bazel_toolchains//constraints/sanitizers:support_msan", + "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", + "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", "//third_party/toolchains/machine_size:large", ], remote_execution_properties = """ @@ -82,8 +82,8 @@ toolchain( "@bazel_tools//platforms:linux", "@bazel_tools//platforms:x86_64", "@bazel_tools//tools/cpp:clang", - "@bazel_toolchains//constraints:xenial", - "@bazel_toolchains//constraints/sanitizers:support_msan", + "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", + "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", "//third_party/toolchains/machine_size:standard", "//third_party/toolchains/machine_size:large", ], @@ -93,6 +93,6 @@ toolchain( "@bazel_tools//platforms:linux", "@bazel_tools//platforms:x86_64", ], - toolchain = "@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:cc-compiler-k8", + toolchain = "@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:cc-compiler-k8", toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", ) From 09b0b0b71207e716b990ed0fb8d1cfae435fbc43 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 15 Nov 2018 14:50:05 -0800 Subject: [PATCH 0222/2143] Attempting Eric Burnett's fix --- third_party/toolchains/BUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 4b075eb7dc9..8b16b669dfc 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -88,8 +88,8 @@ toolchain( "//third_party/toolchains/machine_size:large", ], target_compatible_with = [ - "//third_party/toolchains:rbe_ubuntu1604", - "//third_party/toolchains:rbe_ubuntu1604_large", + # "//third_party/toolchains:rbe_ubuntu1604", + # "//third_party/toolchains:rbe_ubuntu1604_large", "@bazel_tools//platforms:linux", "@bazel_tools//platforms:x86_64", ], From ffeb0e682393e5b76d732e0b034c71f3837b9e57 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 14:56:50 -0800 Subject: [PATCH 0223/2143] Add *if* after assert --- src/objective-c/GRPCClient/GRPCCall.m | 54 +++++++++++++++++++ .../GRPCClient/private/GRPCChannel.m | 25 +++++++-- .../GRPCClient/private/GRPCChannelPool.m | 3 ++ 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 68b51d8c846..f340e2bd8c2 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -69,6 +69,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { NSAssert(host.length != 0 && path.length != 0, @"Host and Path cannot be empty"); + if (host.length == 0) { + host = [NSString string]; + } + if (path.length == 0) { + path = [NSString string]; + } if ((self = [super init])) { _host = [host copy]; _path = [path copy]; @@ -120,6 +126,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; NSAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); NSAssert(responseHandler != nil, @"Response handler required."); + if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { + return nil; + } + if (requestOptions.safety > GRPCCallSafetyCacheableRequest) { + return nil; + } + if (responseHandler == nil) { + return nil; + } + if ((self = [super init])) { _requestOptions = [requestOptions copy]; @@ -158,6 +174,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_async(_dispatchQueue, ^{ NSAssert(!self->_started, @"Call already started."); NSAssert(!self->_canceled, @"Call already canceled."); + if (self->_started) { + return; + } + if (self->_canceled) { + return; + } + self->_started = YES; if (!self->_callOptions) { self->_callOptions = [[GRPCCallOptions alloc] init]; @@ -218,6 +241,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)cancel { dispatch_async(_dispatchQueue, ^{ NSAssert(!self->_canceled, @"Call already canceled."); + if (self->_canceled) { + return; + } + self->_canceled = YES; if (self->_call) { [self->_call cancel]; @@ -248,6 +275,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_async(_dispatchQueue, ^{ NSAssert(!self->_canceled, @"Call arleady canceled."); NSAssert(!self->_finished, @"Call is half-closed before sending data."); + if (self->_canceled) { + return; + } + if (self->_finished) { + return; + } + if (self->_pipe) { [self->_pipe writeValue:data]; } @@ -259,6 +293,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; NSAssert(self->_started, @"Call not started."); NSAssert(!self->_canceled, @"Call arleady canceled."); NSAssert(!self->_finished, @"Call already half-closed."); + if (!self->_started) { + return; + } + if (self->_canceled) { + return; + } + if (self->_finished) { + return; + } + if (self->_pipe) { [self->_pipe writesFinishedWithError:nil]; } @@ -412,6 +456,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; @"Invalid call safety value."); NSAssert(requestWriter.state == GRXWriterStateNotStarted, @"The requests writer can't be already started."); + if (!host || !path) { + return nil; + } + if (safety > GRPCCallSafetyCacheableRequest) { + return nil; + } + if (requestWriter.state != GRXWriterStateNotStarted) { + return nil; + } + if ((self = [super init])) { _host = [host copy]; _path = [path copy]; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index de3302598ef..a19802b0106 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -40,8 +40,11 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannelConfiguration - (instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { - NSAssert(host.length, @"Host must not be empty."); + NSAssert(host.length > 0, @"Host must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); + if (host.length == 0) return nil; + if (callOptions == nil) return nil; + if ((self = [super init])) { _host = [host copy]; _callOptions = [callOptions copy]; @@ -196,6 +199,9 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSAssert(channelConfiguration != nil, @"channelConfiguration must not be empty."); NSAssert(destroyDelay > 0, @"destroyDelay must be greater than 0."); + if (channelConfiguration == nil) return nil; + if (destroyDelay <= 0) return nil; + if ((self = [super init])) { _configuration = [channelConfiguration copy]; if (@available(iOS 8.0, *)) { @@ -219,6 +225,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } id factory = channelConfiguration.channelFactory; _unmanagedChannel = [factory createChannelWithHost:host channelArgs:channelArgs]; + NSAssert(_unmanagedChannel != NULL, @"Failed to create channel"); if (_unmanagedChannel == NULL) { NSLog(@"Unable to create channel."); return nil; @@ -233,9 +240,13 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions disconnected:(BOOL *)disconnected { - NSAssert(path.length, @"path must not be empty."); - NSAssert(queue, @"completionQueue must not be empty."); - NSAssert(callOptions, @"callOptions must not be empty."); + NSAssert(path.length > 0, @"path must not be empty."); + NSAssert(queue != nil, @"completionQueue must not be empty."); + NSAssert(callOptions != nil, @"callOptions must not be empty."); + if (path.length == 0) return nil; + if (queue == nil) return nil; + if (callOptions == nil) return nil; + __block BOOL isDisconnected = NO; __block grpc_call *call = NULL; dispatch_sync(_dispatchQueue, ^{ @@ -244,11 +255,13 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } else { NSAssert(self->_unmanagedChannel != NULL, @"Channel should have valid unmanaged channel."); + if (self->_unmanagedChannel == NULL) return; NSString *serverAuthority = callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); + if (timeout < 0) return; grpc_slice host_slice = grpc_empty_slice(); if (serverAuthority) { host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); @@ -292,6 +305,10 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSLog(@"unref"); dispatch_async(_dispatchQueue, ^{ NSAssert(self->_refcount > 0, @"Illegal reference count."); + if (self->_refcount == 0) { + NSLog(@"Illegal reference count."); + return; + } self->_refcount--; if (self->_refcount == 0 && !self->_disconnected) { // Start timer. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 72554ca6dc8..5e2e9bcfebb 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -71,6 +71,9 @@ static dispatch_once_t gInitChannelPool; destroyDelay:(NSTimeInterval)destroyDelay { NSAssert(host.length > 0, @"Host must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); + if (host.length == 0) return nil; + if (callOptions == nil) return nil; + GRPCChannel *channel; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; From d4ebd30eb2eb94f77ac9b52c44880e3d70c6aef0 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 15 Nov 2018 15:57:43 -0800 Subject: [PATCH 0224/2143] Add method to get status of send message op on POST_SEND_MESSAGE --- include/grpcpp/impl/codegen/call_op_set.h | 18 ++++++++++++++++-- include/grpcpp/impl/codegen/interceptor.h | 6 +++++- .../grpcpp/impl/codegen/interceptor_common.h | 10 ++++++++++ .../client_interceptors_end2end_test.cc | 18 ++++++++++++++++-- 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 1f2b88e9e14..f330679ffc9 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -315,9 +315,16 @@ class CallOpSendMessage { write_options_.Clear(); } void FinishOp(bool* status) { - send_buf_.Clear(); + if (!send_buf_.Valid()) { + return; + } if (hijacked_ && failed_send_) { + // Hijacking interceptor failed this Op *status = false; + } else if (!*status) { + // This Op was passed down to core and the Op failed + gpr_log(GPR_ERROR, "failure status"); + failed_send_ = true; } } @@ -330,7 +337,14 @@ class CallOpSendMessage { } void SetFinishInterceptionHookPoint( - InterceptorBatchMethodsImpl* interceptor_methods) {} + InterceptorBatchMethodsImpl* interceptor_methods) { + if (send_buf_.Valid()) { + interceptor_methods->AddInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_SEND_MESSAGE); + // We had already registered failed_send_ earlier. No need to do it again. + } + send_buf_.Clear(); + } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { hijacked_ = true; diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 47239332c86..154172dd814 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -41,9 +41,10 @@ class InterceptedMessage { }; enum class InterceptionHookPoints { - /* The first two in this list are for clients and servers */ + /* The first three in this list are for clients and servers */ PRE_SEND_INITIAL_METADATA, PRE_SEND_MESSAGE, + POST_SEND_MESSAGE, PRE_SEND_STATUS /* server only */, PRE_SEND_CLOSE /* client only */, /* The following three are for hijacked clients only and can only be @@ -85,6 +86,9 @@ class InterceptorBatchMethods { // sent virtual ByteBuffer* GetSendMessage() = 0; + // Checks whether the SEND MESSAGE op succeeded + virtual bool GetSendMessageStatus() = 0; + // Returns a modifiable multimap of the initial metadata to be sent virtual std::multimap* GetSendInitialMetadata() = 0; diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 601a929afe6..21326df73be 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -81,6 +81,8 @@ class InterceptorBatchMethodsImpl ByteBuffer* GetSendMessage() override { return send_message_; } + bool GetSendMessageStatus() override { return !*fail_send_message_; } + std::multimap* GetSendInitialMetadata() override { return send_initial_metadata_; } @@ -113,6 +115,7 @@ class InterceptorBatchMethodsImpl void FailHijackedSendMessage() override { GPR_CODEGEN_ASSERT(hooks_[static_cast( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)]); + gpr_log(GPR_ERROR, "failing"); *fail_send_message_ = true; } @@ -396,6 +399,13 @@ class CancelInterceptorBatchMethods return nullptr; } + bool GetSendMessageStatus() override { + GPR_CODEGEN_ASSERT( + false && + "It is illegal to call GetSendMessageStatus on a method which " + "has a Cancel notification"); + } + std::multimap* GetSendInitialMetadata() override { GPR_CODEGEN_ASSERT(false && "It is illegal to call GetSendInitialMetadata on a " diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 81efd154525..97947e73931 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -287,6 +287,13 @@ class ClientStreamingRpcHijackingInterceptor methods->FailHijackedSendMessage(); } } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_SEND_MESSAGE)) { + EXPECT_FALSE(got_failed_send_); + gpr_log(GPR_ERROR, "%d", got_failed_send_); + got_failed_send_ = !methods->GetSendMessageStatus(); + gpr_log(GPR_ERROR, "%d", got_failed_send_); + } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { auto* status = methods->GetRecvStatus(); @@ -299,10 +306,16 @@ class ClientStreamingRpcHijackingInterceptor } } + static bool GotFailedSend() { return got_failed_send_; } + private: experimental::ClientRpcInfo* info_; int count_ = 0; + static bool got_failed_send_; }; + +bool ClientStreamingRpcHijackingInterceptor::got_failed_send_ = false; + class ClientStreamingRpcHijackingInterceptorFactory : public experimental::ClientInterceptorFactoryInterface { public: @@ -602,10 +615,11 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingHijackingTest) { EXPECT_TRUE(writer->Write(req)); expected_resp += "Hello"; } - // Expect that the interceptor will reject the 11th message - EXPECT_FALSE(writer->Write(req)); + // The interceptor will reject the 11th message + writer->Write(req); Status s = writer->Finish(); EXPECT_EQ(s.ok(), false); + EXPECT_TRUE(ClientStreamingRpcHijackingInterceptor::GotFailedSend()); } TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { From 00c9c40004d011f01c72d253a530edb3364992bf Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 15 Nov 2018 16:00:33 -0800 Subject: [PATCH 0225/2143] Remove extraneous logging statements --- include/grpcpp/impl/codegen/call_op_set.h | 1 - include/grpcpp/impl/codegen/interceptor_common.h | 1 - test/cpp/end2end/client_interceptors_end2end_test.cc | 2 -- 3 files changed, 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index f330679ffc9..ac3ba17bd9d 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -323,7 +323,6 @@ class CallOpSendMessage { *status = false; } else if (!*status) { // This Op was passed down to core and the Op failed - gpr_log(GPR_ERROR, "failure status"); failed_send_ = true; } } diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 21326df73be..321691236be 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -115,7 +115,6 @@ class InterceptorBatchMethodsImpl void FailHijackedSendMessage() override { GPR_CODEGEN_ASSERT(hooks_[static_cast( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)]); - gpr_log(GPR_ERROR, "failing"); *fail_send_message_ = true; } diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 97947e73931..3708c11235a 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -290,9 +290,7 @@ class ClientStreamingRpcHijackingInterceptor if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::POST_SEND_MESSAGE)) { EXPECT_FALSE(got_failed_send_); - gpr_log(GPR_ERROR, "%d", got_failed_send_); got_failed_send_ = !methods->GetSendMessageStatus(); - gpr_log(GPR_ERROR, "%d", got_failed_send_); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { From 365ce568e1d4b6a017f70af9639e25a32ac3745b Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 15 Nov 2018 16:12:04 -0800 Subject: [PATCH 0226/2143] fixed incorrect repo name --- tools/remote_build/rbe_common.bazelrc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index 82b59355cb6..adcd6427cfe 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -18,7 +18,7 @@ startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 -build --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain +build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain build --extra_toolchains=//third_party/toolchains:cc-toolchain-clang-x86_64-default # Use custom execution platforms defined in third_party/toolchains build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large @@ -59,9 +59,9 @@ build:msan --cxxopt=--stdlib=libc++ # setting LD_LIBRARY_PATH is necessary # to avoid "libc++.so.1: cannot open shared object file" build:msan --action_env=LD_LIBRARY_PATH=/usr/local/lib -build:msan --host_crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain +build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain # override the config-agnostic crosstool_top -build:msan --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/msan:toolchain +build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/msan:toolchain # thread sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific @@ -76,7 +76,7 @@ build:ubsan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:ubsan --test_timeout=3600 # override the config-agnostic crosstool_top ---crosstool_top=@bazel_toolchains//configs/experimental/ubuntu16_04_clang/1.1/bazel_0.16.1/ubsan:toolchain +--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.1/bazel_0.16.1/ubsan:toolchain # TODO(jtattermusch): remove this once Foundry adds the env to the docker image. # ubsan needs symbolizer to work properly, otherwise the suppression file doesn't work # and we get test failures. From c3720d124a5a911e60107f1ed8cb0c6b86ff1112 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 15 Nov 2018 16:34:46 -0800 Subject: [PATCH 0227/2143] attempting single platform --- tools/remote_build/rbe_common.bazelrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index adcd6427cfe..77ce96b8d4a 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -23,7 +23,7 @@ build --extra_toolchains=//third_party/toolchains:cc-toolchain-clang-x86_64-defa # Use custom execution platforms defined in third_party/toolchains build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large build --host_platform=//third_party/toolchains:rbe_ubuntu1604 -build --platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large +build --platforms=//third_party/toolchains:rbe_ubuntu1604 build --spawn_strategy=remote build --strategy=Javac=remote From 6cbbefc6c6f03bf6d48816f36f2d496768c39a12 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 15 Nov 2018 16:47:51 -0800 Subject: [PATCH 0228/2143] temporarily removed some constraints --- third_party/toolchains/BUILD | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 8b16b669dfc..bf32ae4786d 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -35,9 +35,9 @@ platform( "@bazel_tools//platforms:x86_64", "@bazel_tools//platforms:linux", "@bazel_tools//tools/cpp:clang", - "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", - "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", - "//third_party/toolchains/machine_size:standard", + # "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", + # "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", + # "//third_party/toolchains/machine_size:standard", ], remote_execution_properties = """ properties: { @@ -82,10 +82,10 @@ toolchain( "@bazel_tools//platforms:linux", "@bazel_tools//platforms:x86_64", "@bazel_tools//tools/cpp:clang", - "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", - "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", - "//third_party/toolchains/machine_size:standard", - "//third_party/toolchains/machine_size:large", + # "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", + # "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", + # "//third_party/toolchains/machine_size:standard", + # "//third_party/toolchains/machine_size:large", ], target_compatible_with = [ # "//third_party/toolchains:rbe_ubuntu1604", From 512c01bc574ab09129608bc501d80f06503c79a3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 16:59:31 -0800 Subject: [PATCH 0229/2143] Polish threading + something else --- src/objective-c/GRPCClient/GRPCCall.m | 245 ++++++++++-------- .../GRPCClient/private/GRPCChannel.m | 1 - src/objective-c/ProtoRPC/ProtoRPC.h | 1 + src/objective-c/ProtoRPC/ProtoRPC.m | 123 +++++---- 4 files changed, 211 insertions(+), 159 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index f340e2bd8c2..ede16b42e8c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -155,7 +155,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Fallback on earlier versions _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } - dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue); + dispatch_set_target_queue(_dispatchQueue ,responseHandler.dispatchQueue); _started = NO; _canceled = NO; _finished = NO; @@ -171,161 +171,194 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)start { - dispatch_async(_dispatchQueue, ^{ - NSAssert(!self->_started, @"Call already started."); - NSAssert(!self->_canceled, @"Call already canceled."); - if (self->_started) { + GRPCCall *call = nil; + @synchronized (self) { + NSAssert(!_started, @"Call already started."); + NSAssert(!_canceled, @"Call already canceled."); + if (_started) { return; } - if (self->_canceled) { + if (_canceled) { return; } - self->_started = YES; - if (!self->_callOptions) { - self->_callOptions = [[GRPCCallOptions alloc] init]; + _started = YES; + if (!_callOptions) { + _callOptions = [[GRPCCallOptions alloc] init]; } - self->_call = [[GRPCCall alloc] initWithHost:self->_requestOptions.host - path:self->_requestOptions.path - callSafety:self->_requestOptions.safety - requestsWriter:self->_pipe - callOptions:self->_callOptions]; - if (self->_callOptions.initialMetadata) { - [self->_call.requestHeaders addEntriesFromDictionary:self->_callOptions.initialMetadata]; + _call = [[GRPCCall alloc] initWithHost:_requestOptions.host + path:_requestOptions.path + callSafety:_requestOptions.safety + requestsWriter:_pipe + callOptions:_callOptions]; + if (_callOptions.initialMetadata) { + [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata]; } + call = _call; + } - void (^valueHandler)(id value) = ^(id value) { - dispatch_async(self->_dispatchQueue, ^{ - if (self->_handler) { - if (!self->_initialMetadataPublished) { - self->_initialMetadataPublished = YES; - [self issueInitialMetadata:self->_call.responseHeaders]; - } - if (value) { - [self issueMessage:value]; - } + void (^valueHandler)(id value) = ^(id value) { + @synchronized (self) { + if (self->_handler) { + if (!self->_initialMetadataPublished) { + self->_initialMetadataPublished = YES; + [self issueInitialMetadata:self->_call.responseHeaders]; } - }); - }; - void (^completionHandler)(NSError *errorOrNil) = ^(NSError *errorOrNil) { - dispatch_async(self->_dispatchQueue, ^{ - if (self->_handler) { - if (!self->_initialMetadataPublished) { - self->_initialMetadataPublished = YES; - [self issueInitialMetadata:self->_call.responseHeaders]; - } - [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + if (value) { + [self issueMessage:value]; + } + } + } + }; + void (^completionHandler)(NSError *errorOrNil) = ^(NSError *errorOrNil) { + @synchronized(self) { + if (self->_handler) { + if (!self->_initialMetadataPublished) { + self->_initialMetadataPublished = YES; + [self issueInitialMetadata:self->_call.responseHeaders]; + } + [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; - // Clean up _handler so that no more responses are reported to the handler. - self->_handler = nil; - } - // Clearing _call must happen *after* dispatching close in order to get trailing - // metadata from _call. - if (self->_call) { - // Clean up the request writers. This should have no effect to _call since its - // response writeable is already nullified. - [self->_pipe writesFinishedWithError:nil]; - self->_call = nil; - self->_pipe = nil; - } - }); - }; - id responseWriteable = - [[GRXWriteable alloc] initWithValueHandler:valueHandler - completionHandler:completionHandler]; - [self->_call startWithWriteable:responseWriteable]; - }); + } + // Clearing _call must happen *after* dispatching close in order to get trailing + // metadata from _call. + if (self->_call) { + // Clean up the request writers. This should have no effect to _call since its + // response writeable is already nullified. + [self->_pipe writesFinishedWithError:nil]; + self->_call = nil; + self->_pipe = nil; + } + } + }; + id responseWriteable = + [[GRXWriteable alloc] initWithValueHandler:valueHandler + completionHandler:completionHandler]; + [call startWithWriteable:responseWriteable]; } - (void)cancel { - dispatch_async(_dispatchQueue, ^{ - NSAssert(!self->_canceled, @"Call already canceled."); - if (self->_canceled) { + GRPCCall *call = nil; + @synchronized (self) { + if (_canceled) { return; } - self->_canceled = YES; - if (self->_call) { - [self->_call cancel]; - self->_call = nil; - self->_pipe = nil; - } - if (self->_handler) { - id handler = self->_handler; - dispatch_async(handler.dispatchQueue, ^{ - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [handler closedWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; - } - }); + _canceled = YES; - // Clean up _handler so that no more responses are reported to the handler. - self->_handler = nil; + call = _call; + _call = nil; + _pipe = nil; + + if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(_dispatchQueue, ^{ + // Copy to local so that block is freed after cancellation completes. + id copiedHandler = nil; + @synchronized (self) { + copiedHandler = self->_handler; + self->_handler = nil; + } + + [copiedHandler closedWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + }); } - }); + } + [call cancel]; } - (void)writeData:(NSData *)data { - dispatch_async(_dispatchQueue, ^{ - NSAssert(!self->_canceled, @"Call arleady canceled."); - NSAssert(!self->_finished, @"Call is half-closed before sending data."); - if (self->_canceled) { + GRXBufferedPipe *pipe = nil; + @synchronized(self) { + NSAssert(!_canceled, @"Call arleady canceled."); + NSAssert(!_finished, @"Call is half-closed before sending data."); + if (_canceled) { return; } - if (self->_finished) { + if (_finished) { return; } - if (self->_pipe) { - [self->_pipe writeValue:data]; + if (_pipe) { + pipe = _pipe; } - }); + } + [pipe writeValue:data]; } - (void)finish { - dispatch_async(_dispatchQueue, ^{ - NSAssert(self->_started, @"Call not started."); - NSAssert(!self->_canceled, @"Call arleady canceled."); - NSAssert(!self->_finished, @"Call already half-closed."); - if (!self->_started) { + GRXBufferedPipe *pipe = nil; + @synchronized(self) { + NSAssert(_started, @"Call not started."); + NSAssert(!_canceled, @"Call arleady canceled."); + NSAssert(!_finished, @"Call already half-closed."); + if (!_started) { return; } - if (self->_canceled) { + if (_canceled) { return; } - if (self->_finished) { + if (_finished) { return; } - if (self->_pipe) { - [self->_pipe writesFinishedWithError:nil]; + if (_pipe) { + pipe = _pipe; + _pipe = nil; } - self->_pipe = nil; - self->_finished = YES; - }); + _finished = YES; + } + [pipe writesFinishedWithError:nil]; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { - if (initialMetadata != nil && [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { - [_handler receivedInitialMetadata:initialMetadata]; + @synchronized (self) { + if (initialMetadata != nil && [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; + } + [handler receivedInitialMetadata:initialMetadata]; + }); + } } } - (void)issueMessage:(id)message { - if (message != nil && [_handler respondsToSelector:@selector(receivedRawMessage:)]) { - [_handler receivedRawMessage:message]; + @synchronized (self) { + if (message != nil && [_handler respondsToSelector:@selector(receivedRawMessage:)]) { + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; + } + [handler receivedRawMessage:message]; + }); + } } } - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [_handler closedWithTrailingMetadata:trailingMetadata error:error]; + @synchronized (self) { + if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; + // Clean up _handler so that no more responses are reported to the handler. + self->_handler = nil; + } + [handler closedWithTrailingMetadata:trailingMetadata + error:error]; + }); + } } } diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index a19802b0106..997d1ff663c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -302,7 +302,6 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (void)unref { - NSLog(@"unref"); dispatch_async(_dispatchQueue, ^{ NSAssert(self->_refcount > 0, @"Illegal reference count."); if (self->_refcount == 0) { diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 569aaa79e4d..98b60c3f727 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -32,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN /** * Issued when initial metadata is received from the server. + */ - (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; /** diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index f99da45fef9..9f45bdfcd46 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -112,7 +112,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } else { _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } - dispatch_set_target_queue(handler.dispatchQueue, _dispatchQueue); + dispatch_set_target_queue(_dispatchQueue, handler.dispatchQueue); [self start]; } @@ -127,15 +127,17 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)cancel { - dispatch_async(_dispatchQueue, ^{ - if (_call) { - [_call cancel]; - _call = nil; - } - if (_handler) { - id handler = _handler; - if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(handler.dispatchQueue, ^{ + GRPCCall2 *call; + @synchronized(self) { + call = _call; + _call = nil; + if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(_handler.dispatchQueue, ^{ + id handler = nil; + @synchronized(self) { + handler = self->_handler; + self->_handler = nil; + } [handler closedWithTrailingMetadata:nil error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled @@ -145,9 +147,8 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing }]]; }); } - _handler = nil; - } - }); + } + [call cancel]; } - (void)writeMessage:(GPBMessage *)message { @@ -155,63 +156,81 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing [NSException raise:NSInvalidArgumentException format:@"Data must be a valid protobuf type."]; } - dispatch_async(_dispatchQueue, ^{ - if (_call) { - [_call writeData:[message data]]; - } - }); + GRPCCall2 *call; + @synchronized(self) { + call = _call; + } + [call writeData:[message data]]; } - (void)finish { - dispatch_async(_dispatchQueue, ^{ - if (_call) { - [_call finish]; - _call = nil; - } - }); + GRPCCall2 *call; + @synchronized(self) { + call = _call; + _call = nil; + } + [call finish]; } - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { - dispatch_async(_dispatchQueue, ^{ - if (initialMetadata != nil && [self->_handler respondsToSelector:@selector(initialMetadata:)]) { - [self->_handler receivedInitialMetadata:initialMetadata]; + @synchronized (self) { + if (initialMetadata != nil && [_handler respondsToSelector:@selector(initialMetadata:)]) { + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; + } + [handler receivedInitialMetadata:initialMetadata]; + }); } - }); + } } - (void)receivedRawMessage:(NSData *)message { - dispatch_async(_dispatchQueue, ^{ - if (self->_handler && message != nil) { - NSError *error = nil; - GPBMessage *parsed = [self->_responseClass parseFromData:message error:&error]; - if (parsed) { - if ([self->_handler respondsToSelector:@selector(receivedProtoMessage:)]) { - [self->_handler receivedProtoMessage:parsed]; + if (message == nil) return; + + NSError *error = nil; + GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; + @synchronized (self) { + if (parsed && [_handler respondsToSelector:@selector(receivedProtoMessage:)]) { + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; } - } else { - if ([self->_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [self->_handler - closedWithTrailingMetadata:nil - error:ErrorForBadProto(message, _responseClass, error)]; + [handler receivedProtoMessage:parsed]; + }); + } else if (!parsed && [_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]){ + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; + self->_handler = nil; } - self->_handler = nil; - [self->_call cancel]; - self->_call = nil; - } + [handler closedWithTrailingMetadata:nil + error:ErrorForBadProto(message, _responseClass, error)]; + }); + [_call cancel]; + _call = nil; } - }); + } } - (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - dispatch_async(_dispatchQueue, ^{ - if ([self->_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - [self->_handler closedWithTrailingMetadata:trailingMetadata error:error]; + @synchronized (self) { + if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + dispatch_async(_dispatchQueue, ^{ + id handler = nil; + @synchronized (self) { + handler = self->_handler; + self->_handler = nil; + } + [handler closedWithTrailingMetadata:trailingMetadata error:error]; + }); } - self->_handler = nil; - [self->_call cancel]; - self->_call = nil; - }); + _call = nil; + } } - (dispatch_queue_t)dispatchQueue { From 87abab45c99ab4b40718557cbc1c25dcd7f5a418 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 15 Nov 2018 17:44:26 -0800 Subject: [PATCH 0230/2143] Fix version availability --- src/objective-c/GRPCClient/GRPCCall.m | 8 ++++++-- src/objective-c/GRPCClient/private/GRPCChannel.m | 7 +++++-- src/objective-c/ProtoRPC/ProtoRPC.m | 8 +++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index ede16b42e8c..19de004cbcd 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -147,12 +147,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; _handler = responseHandler; _initialMetadataPublished = NO; _pipe = [GRXBufferedPipe pipe]; - if (@available(iOS 8.0, *)) { + // Set queue QoS only when iOS version is 8.0 or above and Xcode version is 9.0 or above +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { _dispatchQueue = dispatch_queue_create( NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { - // Fallback on earlier versions +#else + { +#endif _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } dispatch_set_target_queue(_dispatchQueue ,responseHandler.dispatchQueue); diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 997d1ff663c..0220141db04 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -204,14 +204,17 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if ((self = [super init])) { _configuration = [channelConfiguration copy]; - if (@available(iOS 8.0, *)) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED < 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED < 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { _dispatchQueue = dispatch_queue_create( NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { +#else + { +#endif _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } - // Create gRPC core channel object. NSString *host = channelConfiguration.host; NSAssert(host.length != 0, @"host cannot be nil"); diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 9f45bdfcd46..9164f2320bf 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -105,11 +105,17 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing _handler = handler; _callOptions = [callOptions copy]; _responseClass = responseClass; - if (@available(iOS 8.0, *)) { + + // Set queue QoS only when iOS version is 8.0 or above and Xcode version is 9.0 or above +#if __IPHONE_OS_VERSION_MAX_ALLOWED < 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED < 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { _dispatchQueue = dispatch_queue_create( NULL, dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { +#else + { +#endif _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } dispatch_set_target_queue(_dispatchQueue, handler.dispatchQueue); From fafde8ff213916ab20b9faac7013518a8320f2e1 Mon Sep 17 00:00:00 2001 From: Vishal Powar Date: Fri, 16 Nov 2018 15:11:24 -0800 Subject: [PATCH 0231/2143] Adding ads (data-plane-api) method name to wellknown names list. This is the api for getting assignments from xDS server --- tools/codegen/core/gen_static_metadata.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index adfd4a24f95..ab288a00909 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -64,6 +64,7 @@ CONFIG = [ # well known method names '/grpc.lb.v1.LoadBalancer/BalanceLoad', '/grpc.health.v1.Health/Watch', + '/envoy.service.discovery.v2.AggregatedDiscoveryService/StreamAggregatedResources', # compression algorithm names 'deflate', 'gzip', From 68c353351c92df71ca12e4323810856ffd34e6f8 Mon Sep 17 00:00:00 2001 From: Vishal Powar Date: Fri, 16 Nov 2018 16:16:36 -0800 Subject: [PATCH 0232/2143] Run the tools/codegen/core/gen_static_metadata.py and generate the required files --- src/core/lib/transport/static_metadata.cc | 449 +++++++++++---------- src/core/lib/transport/static_metadata.h | 146 +++---- test/core/end2end/fuzzers/hpack.dictionary | 1 + 3 files changed, 304 insertions(+), 292 deletions(-) diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 4ebe73f82a0..3dfaaaad5c8 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -65,51 +65,56 @@ static uint8_t g_bytes[] = { 97, 110, 99, 101, 114, 47, 66, 97, 108, 97, 110, 99, 101, 76, 111, 97, 100, 47, 103, 114, 112, 99, 46, 104, 101, 97, 108, 116, 104, 46, 118, 49, 46, 72, 101, 97, 108, 116, 104, 47, 87, 97, 116, 99, 104, - 100, 101, 102, 108, 97, 116, 101, 103, 122, 105, 112, 115, 116, 114, 101, - 97, 109, 47, 103, 122, 105, 112, 71, 69, 84, 80, 79, 83, 84, 47, - 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 104, 116, 116, 112, - 104, 116, 116, 112, 115, 50, 48, 48, 50, 48, 52, 50, 48, 54, 51, - 48, 52, 52, 48, 48, 52, 48, 52, 53, 48, 48, 97, 99, 99, 101, - 112, 116, 45, 99, 104, 97, 114, 115, 101, 116, 103, 122, 105, 112, 44, - 32, 100, 101, 102, 108, 97, 116, 101, 97, 99, 99, 101, 112, 116, 45, - 108, 97, 110, 103, 117, 97, 103, 101, 97, 99, 99, 101, 112, 116, 45, - 114, 97, 110, 103, 101, 115, 97, 99, 99, 101, 112, 116, 97, 99, 99, - 101, 115, 115, 45, 99, 111, 110, 116, 114, 111, 108, 45, 97, 108, 108, - 111, 119, 45, 111, 114, 105, 103, 105, 110, 97, 103, 101, 97, 108, 108, - 111, 119, 97, 117, 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, - 99, 97, 99, 104, 101, 45, 99, 111, 110, 116, 114, 111, 108, 99, 111, - 110, 116, 101, 110, 116, 45, 100, 105, 115, 112, 111, 115, 105, 116, 105, - 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 108, 97, 110, 103, 117, - 97, 103, 101, 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, - 116, 104, 99, 111, 110, 116, 101, 110, 116, 45, 108, 111, 99, 97, 116, - 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 114, 97, 110, 103, - 101, 99, 111, 111, 107, 105, 101, 100, 97, 116, 101, 101, 116, 97, 103, - 101, 120, 112, 101, 99, 116, 101, 120, 112, 105, 114, 101, 115, 102, 114, - 111, 109, 105, 102, 45, 109, 97, 116, 99, 104, 105, 102, 45, 109, 111, - 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 105, 102, 45, - 110, 111, 110, 101, 45, 109, 97, 116, 99, 104, 105, 102, 45, 114, 97, - 110, 103, 101, 105, 102, 45, 117, 110, 109, 111, 100, 105, 102, 105, 101, - 100, 45, 115, 105, 110, 99, 101, 108, 97, 115, 116, 45, 109, 111, 100, - 105, 102, 105, 101, 100, 108, 105, 110, 107, 108, 111, 99, 97, 116, 105, - 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114, 100, 115, 112, - 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, - 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 111, 114, 105, - 122, 97, 116, 105, 111, 110, 114, 97, 110, 103, 101, 114, 101, 102, 101, - 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101, 116, 114, 121, - 45, 97, 102, 116, 101, 114, 115, 101, 114, 118, 101, 114, 115, 101, 116, - 45, 99, 111, 111, 107, 105, 101, 115, 116, 114, 105, 99, 116, 45, 116, - 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, 101, 99, 117, 114, 105, - 116, 121, 116, 114, 97, 110, 115, 102, 101, 114, 45, 101, 110, 99, 111, - 100, 105, 110, 103, 118, 97, 114, 121, 118, 105, 97, 119, 119, 119, 45, - 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, 48, 105, 100, - 101, 110, 116, 105, 116, 121, 116, 114, 97, 105, 108, 101, 114, 115, 97, - 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 103, 114, 112, 99, - 103, 114, 112, 99, 80, 85, 84, 108, 98, 45, 99, 111, 115, 116, 45, - 98, 105, 110, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, - 108, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 103, 122, - 105, 112, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, 112, 105, - 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, - 44, 103, 122, 105, 112}; + 47, 101, 110, 118, 111, 121, 46, 115, 101, 114, 118, 105, 99, 101, 46, + 100, 105, 115, 99, 111, 118, 101, 114, 121, 46, 118, 50, 46, 65, 103, + 103, 114, 101, 103, 97, 116, 101, 100, 68, 105, 115, 99, 111, 118, 101, + 114, 121, 83, 101, 114, 118, 105, 99, 101, 47, 83, 116, 114, 101, 97, + 109, 65, 103, 103, 114, 101, 103, 97, 116, 101, 100, 82, 101, 115, 111, + 117, 114, 99, 101, 115, 100, 101, 102, 108, 97, 116, 101, 103, 122, 105, + 112, 115, 116, 114, 101, 97, 109, 47, 103, 122, 105, 112, 71, 69, 84, + 80, 79, 83, 84, 47, 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, + 108, 104, 116, 116, 112, 104, 116, 116, 112, 115, 50, 48, 48, 50, 48, + 52, 50, 48, 54, 51, 48, 52, 52, 48, 48, 52, 48, 52, 53, 48, + 48, 97, 99, 99, 101, 112, 116, 45, 99, 104, 97, 114, 115, 101, 116, + 103, 122, 105, 112, 44, 32, 100, 101, 102, 108, 97, 116, 101, 97, 99, + 99, 101, 112, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 97, 99, + 99, 101, 112, 116, 45, 114, 97, 110, 103, 101, 115, 97, 99, 99, 101, + 112, 116, 97, 99, 99, 101, 115, 115, 45, 99, 111, 110, 116, 114, 111, + 108, 45, 97, 108, 108, 111, 119, 45, 111, 114, 105, 103, 105, 110, 97, + 103, 101, 97, 108, 108, 111, 119, 97, 117, 116, 104, 111, 114, 105, 122, + 97, 116, 105, 111, 110, 99, 97, 99, 104, 101, 45, 99, 111, 110, 116, + 114, 111, 108, 99, 111, 110, 116, 101, 110, 116, 45, 100, 105, 115, 112, + 111, 115, 105, 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, + 108, 97, 110, 103, 117, 97, 103, 101, 99, 111, 110, 116, 101, 110, 116, + 45, 108, 101, 110, 103, 116, 104, 99, 111, 110, 116, 101, 110, 116, 45, + 108, 111, 99, 97, 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, + 45, 114, 97, 110, 103, 101, 99, 111, 111, 107, 105, 101, 100, 97, 116, + 101, 101, 116, 97, 103, 101, 120, 112, 101, 99, 116, 101, 120, 112, 105, + 114, 101, 115, 102, 114, 111, 109, 105, 102, 45, 109, 97, 116, 99, 104, + 105, 102, 45, 109, 111, 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, + 99, 101, 105, 102, 45, 110, 111, 110, 101, 45, 109, 97, 116, 99, 104, + 105, 102, 45, 114, 97, 110, 103, 101, 105, 102, 45, 117, 110, 109, 111, + 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 108, 97, 115, + 116, 45, 109, 111, 100, 105, 102, 105, 101, 100, 108, 105, 110, 107, 108, + 111, 99, 97, 116, 105, 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, + 97, 114, 100, 115, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, + 110, 116, 105, 99, 97, 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, + 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 114, 97, 110, 103, + 101, 114, 101, 102, 101, 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, + 114, 101, 116, 114, 121, 45, 97, 102, 116, 101, 114, 115, 101, 114, 118, + 101, 114, 115, 101, 116, 45, 99, 111, 111, 107, 105, 101, 115, 116, 114, + 105, 99, 116, 45, 116, 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, + 101, 99, 117, 114, 105, 116, 121, 116, 114, 97, 110, 115, 102, 101, 114, + 45, 101, 110, 99, 111, 100, 105, 110, 103, 118, 97, 114, 121, 118, 105, + 97, 119, 119, 119, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, + 116, 101, 48, 105, 100, 101, 110, 116, 105, 116, 121, 116, 114, 97, 105, + 108, 101, 114, 115, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, + 47, 103, 114, 112, 99, 103, 114, 112, 99, 80, 85, 84, 108, 98, 45, + 99, 111, 115, 116, 45, 98, 105, 110, 105, 100, 101, 110, 116, 105, 116, + 121, 44, 100, 101, 102, 108, 97, 116, 101, 105, 100, 101, 110, 116, 105, + 116, 121, 44, 103, 122, 105, 112, 100, 101, 102, 108, 97, 116, 101, 44, + 103, 122, 105, 112, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, + 102, 108, 97, 116, 101, 44, 103, 122, 105, 112}; static void static_ref(void* unused) {} static void static_unref(void* unused) {} @@ -227,6 +232,7 @@ grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = { {&grpc_static_metadata_vtable, &static_sub_refcnt}, {&grpc_static_metadata_vtable, &static_sub_refcnt}, {&grpc_static_metadata_vtable, &static_sub_refcnt}, + {&grpc_static_metadata_vtable, &static_sub_refcnt}, }; const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { @@ -266,76 +272,77 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { {&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, 7}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 521, 11}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 532, 3}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 535, 4}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 539, 1}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 540, 11}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 551, 4}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 555, 5}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 560, 3}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 563, 3}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 566, 3}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 569, 3}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 572, 3}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 575, 3}}}, - {&grpc_static_metadata_refcounts[51], {{g_bytes + 578, 3}}}, - {&grpc_static_metadata_refcounts[52], {{g_bytes + 581, 14}}}, - {&grpc_static_metadata_refcounts[53], {{g_bytes + 595, 13}}}, - {&grpc_static_metadata_refcounts[54], {{g_bytes + 608, 15}}}, - {&grpc_static_metadata_refcounts[55], {{g_bytes + 623, 13}}}, - {&grpc_static_metadata_refcounts[56], {{g_bytes + 636, 6}}}, - {&grpc_static_metadata_refcounts[57], {{g_bytes + 642, 27}}}, - {&grpc_static_metadata_refcounts[58], {{g_bytes + 669, 3}}}, - {&grpc_static_metadata_refcounts[59], {{g_bytes + 672, 5}}}, - {&grpc_static_metadata_refcounts[60], {{g_bytes + 677, 13}}}, - {&grpc_static_metadata_refcounts[61], {{g_bytes + 690, 13}}}, - {&grpc_static_metadata_refcounts[62], {{g_bytes + 703, 19}}}, - {&grpc_static_metadata_refcounts[63], {{g_bytes + 722, 16}}}, - {&grpc_static_metadata_refcounts[64], {{g_bytes + 738, 14}}}, - {&grpc_static_metadata_refcounts[65], {{g_bytes + 752, 16}}}, - {&grpc_static_metadata_refcounts[66], {{g_bytes + 768, 13}}}, - {&grpc_static_metadata_refcounts[67], {{g_bytes + 781, 6}}}, - {&grpc_static_metadata_refcounts[68], {{g_bytes + 787, 4}}}, - {&grpc_static_metadata_refcounts[69], {{g_bytes + 791, 4}}}, - {&grpc_static_metadata_refcounts[70], {{g_bytes + 795, 6}}}, - {&grpc_static_metadata_refcounts[71], {{g_bytes + 801, 7}}}, - {&grpc_static_metadata_refcounts[72], {{g_bytes + 808, 4}}}, - {&grpc_static_metadata_refcounts[73], {{g_bytes + 812, 8}}}, - {&grpc_static_metadata_refcounts[74], {{g_bytes + 820, 17}}}, - {&grpc_static_metadata_refcounts[75], {{g_bytes + 837, 13}}}, - {&grpc_static_metadata_refcounts[76], {{g_bytes + 850, 8}}}, - {&grpc_static_metadata_refcounts[77], {{g_bytes + 858, 19}}}, - {&grpc_static_metadata_refcounts[78], {{g_bytes + 877, 13}}}, - {&grpc_static_metadata_refcounts[79], {{g_bytes + 890, 4}}}, - {&grpc_static_metadata_refcounts[80], {{g_bytes + 894, 8}}}, - {&grpc_static_metadata_refcounts[81], {{g_bytes + 902, 12}}}, - {&grpc_static_metadata_refcounts[82], {{g_bytes + 914, 18}}}, - {&grpc_static_metadata_refcounts[83], {{g_bytes + 932, 19}}}, - {&grpc_static_metadata_refcounts[84], {{g_bytes + 951, 5}}}, - {&grpc_static_metadata_refcounts[85], {{g_bytes + 956, 7}}}, - {&grpc_static_metadata_refcounts[86], {{g_bytes + 963, 7}}}, - {&grpc_static_metadata_refcounts[87], {{g_bytes + 970, 11}}}, - {&grpc_static_metadata_refcounts[88], {{g_bytes + 981, 6}}}, - {&grpc_static_metadata_refcounts[89], {{g_bytes + 987, 10}}}, - {&grpc_static_metadata_refcounts[90], {{g_bytes + 997, 25}}}, - {&grpc_static_metadata_refcounts[91], {{g_bytes + 1022, 17}}}, - {&grpc_static_metadata_refcounts[92], {{g_bytes + 1039, 4}}}, - {&grpc_static_metadata_refcounts[93], {{g_bytes + 1043, 3}}}, - {&grpc_static_metadata_refcounts[94], {{g_bytes + 1046, 16}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1062, 1}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1071, 8}}}, - {&grpc_static_metadata_refcounts[98], {{g_bytes + 1079, 16}}}, - {&grpc_static_metadata_refcounts[99], {{g_bytes + 1095, 4}}}, - {&grpc_static_metadata_refcounts[100], {{g_bytes + 1099, 3}}}, - {&grpc_static_metadata_refcounts[101], {{g_bytes + 1102, 11}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1113, 16}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}, - {&grpc_static_metadata_refcounts[104], {{g_bytes + 1142, 12}}}, - {&grpc_static_metadata_refcounts[105], {{g_bytes + 1154, 21}}}, + {&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}}}, }; uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { @@ -345,17 +352,17 @@ uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4}; static const int8_t elems_r[] = { - 16, 11, -8, 0, 3, -42, -81, -43, 0, 6, -8, 0, 0, 0, -7, - -3, -10, 0, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -63, 0, -47, -68, -69, -70, 0, 33, - 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 20, - 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, - 4, 4, 4, 3, 10, 9, 0, 0, 0, 0, 0, 0, -3, 0}; + 15, 10, -8, 0, 2, -42, -81, -43, 0, 6, -8, 0, 0, 0, 2, + -3, -10, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -64, 0, -67, -68, -69, -70, 0, + 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, + 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, + 5, 4, 5, 4, 4, 8, 8, 0, 0, 0, 0, 0, 0, -5, 0}; static uint32_t elems_phash(uint32_t i) { - i -= 41; - uint32_t x = i % 104; - uint32_t y = i / 104; + i -= 42; + uint32_t x = i % 105; + uint32_t y = i / 105; uint32_t h = x; if (y < GPR_ARRAY_SIZE(elems_r)) { uint32_t delta = (uint32_t)elems_r[y]; @@ -365,29 +372,29 @@ static uint32_t elems_phash(uint32_t i) { } static const uint16_t elem_keys[] = { - 257, 258, 259, 260, 261, 262, 263, 1096, 1097, 1513, 1725, 145, - 146, 467, 468, 1619, 41, 42, 1733, 990, 991, 767, 768, 1627, - 627, 837, 2043, 2149, 2255, 5541, 5859, 5965, 6071, 6177, 1749, 6283, - 6389, 6495, 6601, 6707, 6813, 6919, 7025, 7131, 7237, 7343, 7449, 7555, - 7661, 5753, 7767, 7873, 7979, 8085, 8191, 8297, 8403, 8509, 8615, 8721, - 8827, 8933, 9039, 9145, 9251, 9357, 9463, 1156, 9569, 523, 9675, 9781, - 206, 1162, 1163, 1164, 1165, 1792, 1582, 1050, 9887, 9993, 1686, 10735, - 1799, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0}; + 260, 261, 262, 263, 264, 265, 266, 1107, 1108, 1741, 147, 148, + 472, 473, 1634, 42, 43, 1527, 1750, 1000, 1001, 774, 775, 1643, + 633, 845, 2062, 2169, 2276, 5700, 5914, 6021, 6128, 6235, 1766, 6342, + 6449, 6556, 6663, 6770, 6877, 6984, 7091, 7198, 7305, 7412, 7519, 7626, + 7733, 7840, 7947, 8054, 8161, 8268, 8375, 8482, 8589, 8696, 8803, 8910, + 9017, 9124, 9231, 9338, 9445, 9552, 9659, 1167, 528, 9766, 9873, 208, + 9980, 1173, 1174, 1175, 1176, 1809, 10087, 1060, 10194, 10943, 1702, 0, + 1816, 0, 0, 1597, 0, 0, 350, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0}; static const uint8_t elem_idxs[] = { - 7, 8, 9, 10, 11, 12, 13, 77, 79, 30, 71, 1, 2, 5, 6, 25, - 3, 4, 84, 66, 65, 62, 63, 73, 67, 61, 57, 37, 74, 14, 17, 18, - 19, 20, 15, 21, 22, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 35, - 36, 16, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 76, 55, 69, 56, 58, 70, 78, 80, 81, 82, 83, 68, 64, - 59, 60, 72, 75, 85, 255, 255, 255, 255, 255, 0}; + 7, 8, 9, 10, 11, 12, 13, 77, 79, 71, 1, 2, 5, 6, 25, 3, + 4, 30, 84, 66, 65, 62, 63, 73, 67, 61, 57, 37, 74, 14, 16, 17, + 18, 19, 15, 20, 21, 22, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, + 35, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 76, 69, 55, 56, 70, 58, 78, 80, 81, 82, 83, 59, 64, + 60, 75, 72, 255, 85, 255, 255, 68, 255, 255, 0}; grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) { if (a == -1 || b == -1) return GRPC_MDNULL; - uint32_t k = (uint32_t)(a * 106 + b); + uint32_t k = (uint32_t)(a * 107 + b); uint32_t h = elems_phash(k); return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 @@ -400,175 +407,175 @@ 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[39], {{g_bytes + 532, 3}}}}, + {&grpc_static_metadata_refcounts[40], {{g_bytes + 612, 3}}}}, {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 535, 4}}}}, + {&grpc_static_metadata_refcounts[41], {{g_bytes + 615, 4}}}}, {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 539, 1}}}}, + {&grpc_static_metadata_refcounts[42], {{g_bytes + 619, 1}}}}, {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 540, 11}}}}, + {&grpc_static_metadata_refcounts[43], {{g_bytes + 620, 11}}}}, {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 551, 4}}}}, + {&grpc_static_metadata_refcounts[44], {{g_bytes + 631, 4}}}}, {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 555, 5}}}}, + {&grpc_static_metadata_refcounts[45], {{g_bytes + 635, 5}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 560, 3}}}}, + {&grpc_static_metadata_refcounts[46], {{g_bytes + 640, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 563, 3}}}}, + {&grpc_static_metadata_refcounts[47], {{g_bytes + 643, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 566, 3}}}}, + {&grpc_static_metadata_refcounts[48], {{g_bytes + 646, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 569, 3}}}}, + {&grpc_static_metadata_refcounts[49], {{g_bytes + 649, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 572, 3}}}}, + {&grpc_static_metadata_refcounts[50], {{g_bytes + 652, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 575, 3}}}}, + {&grpc_static_metadata_refcounts[51], {{g_bytes + 655, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[51], {{g_bytes + 578, 3}}}}, - {{&grpc_static_metadata_refcounts[52], {{g_bytes + 581, 14}}}, + {&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[53], {{g_bytes + 595, 13}}}}, - {{&grpc_static_metadata_refcounts[54], {{g_bytes + 608, 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[55], {{g_bytes + 623, 13}}}, + {{&grpc_static_metadata_refcounts[56], {{g_bytes + 703, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[56], {{g_bytes + 636, 6}}}, + {{&grpc_static_metadata_refcounts[57], {{g_bytes + 716, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[57], {{g_bytes + 642, 27}}}, + {{&grpc_static_metadata_refcounts[58], {{g_bytes + 722, 27}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[58], {{g_bytes + 669, 3}}}, + {{&grpc_static_metadata_refcounts[59], {{g_bytes + 749, 3}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[59], {{g_bytes + 672, 5}}}, + {{&grpc_static_metadata_refcounts[60], {{g_bytes + 752, 5}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[60], {{g_bytes + 677, 13}}}, + {{&grpc_static_metadata_refcounts[61], {{g_bytes + 757, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[61], {{g_bytes + 690, 13}}}, + {{&grpc_static_metadata_refcounts[62], {{g_bytes + 770, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[62], {{g_bytes + 703, 19}}}, + {{&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[63], {{g_bytes + 722, 16}}}, + {{&grpc_static_metadata_refcounts[64], {{g_bytes + 802, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[64], {{g_bytes + 738, 14}}}, + {{&grpc_static_metadata_refcounts[65], {{g_bytes + 818, 14}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[65], {{g_bytes + 752, 16}}}, + {{&grpc_static_metadata_refcounts[66], {{g_bytes + 832, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[66], {{g_bytes + 768, 13}}}, + {{&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[67], {{g_bytes + 781, 6}}}, + {{&grpc_static_metadata_refcounts[68], {{g_bytes + 861, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[68], {{g_bytes + 787, 4}}}, + {{&grpc_static_metadata_refcounts[69], {{g_bytes + 867, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[69], {{g_bytes + 791, 4}}}, + {{&grpc_static_metadata_refcounts[70], {{g_bytes + 871, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[70], {{g_bytes + 795, 6}}}, + {{&grpc_static_metadata_refcounts[71], {{g_bytes + 875, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[71], {{g_bytes + 801, 7}}}, + {{&grpc_static_metadata_refcounts[72], {{g_bytes + 881, 7}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[72], {{g_bytes + 808, 4}}}, + {{&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[73], {{g_bytes + 812, 8}}}, + {{&grpc_static_metadata_refcounts[74], {{g_bytes + 892, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[74], {{g_bytes + 820, 17}}}, + {{&grpc_static_metadata_refcounts[75], {{g_bytes + 900, 17}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[75], {{g_bytes + 837, 13}}}, + {{&grpc_static_metadata_refcounts[76], {{g_bytes + 917, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[76], {{g_bytes + 850, 8}}}, + {{&grpc_static_metadata_refcounts[77], {{g_bytes + 930, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[77], {{g_bytes + 858, 19}}}, + {{&grpc_static_metadata_refcounts[78], {{g_bytes + 938, 19}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[78], {{g_bytes + 877, 13}}}, + {{&grpc_static_metadata_refcounts[79], {{g_bytes + 957, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[79], {{g_bytes + 890, 4}}}, + {{&grpc_static_metadata_refcounts[80], {{g_bytes + 970, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[80], {{g_bytes + 894, 8}}}, + {{&grpc_static_metadata_refcounts[81], {{g_bytes + 974, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[81], {{g_bytes + 902, 12}}}, + {{&grpc_static_metadata_refcounts[82], {{g_bytes + 982, 12}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[82], {{g_bytes + 914, 18}}}, + {{&grpc_static_metadata_refcounts[83], {{g_bytes + 994, 18}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[83], {{g_bytes + 932, 19}}}, + {{&grpc_static_metadata_refcounts[84], {{g_bytes + 1012, 19}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[84], {{g_bytes + 951, 5}}}, + {{&grpc_static_metadata_refcounts[85], {{g_bytes + 1031, 5}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[85], {{g_bytes + 956, 7}}}, + {{&grpc_static_metadata_refcounts[86], {{g_bytes + 1036, 7}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[86], {{g_bytes + 963, 7}}}, + {{&grpc_static_metadata_refcounts[87], {{g_bytes + 1043, 7}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[87], {{g_bytes + 970, 11}}}, + {{&grpc_static_metadata_refcounts[88], {{g_bytes + 1050, 11}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[88], {{g_bytes + 981, 6}}}, + {{&grpc_static_metadata_refcounts[89], {{g_bytes + 1061, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[89], {{g_bytes + 987, 10}}}, + {{&grpc_static_metadata_refcounts[90], {{g_bytes + 1067, 10}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[90], {{g_bytes + 997, 25}}}, + {{&grpc_static_metadata_refcounts[91], {{g_bytes + 1077, 25}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[91], {{g_bytes + 1022, 17}}}, + {{&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[92], {{g_bytes + 1039, 4}}}, + {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1119, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1043, 3}}}, + {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1123, 3}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1046, 16}}}, + {{&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[95], {{g_bytes + 1062, 1}}}}, + {&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[96], {{g_bytes + 1063, 8}}}}, + {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}}, {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, + {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}}, {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}}, + {&grpc_static_metadata_refcounts[37], {{g_bytes + 590, 7}}}}, {{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1071, 8}}}}, + {&grpc_static_metadata_refcounts[98], {{g_bytes + 1151, 8}}}}, {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[98], {{g_bytes + 1079, 16}}}}, + {&grpc_static_metadata_refcounts[99], {{g_bytes + 1159, 16}}}}, {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[99], {{g_bytes + 1095, 4}}}}, + {&grpc_static_metadata_refcounts[100], {{g_bytes + 1175, 4}}}}, {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[100], {{g_bytes + 1099, 3}}}}, + {&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[96], {{g_bytes + 1063, 8}}}}, + {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}}, {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, + {&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[101], {{g_bytes + 1102, 11}}}, + {{&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[96], {{g_bytes + 1063, 8}}}}, + {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}}, + {&grpc_static_metadata_refcounts[37], {{g_bytes + 590, 7}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1113, 16}}}}, + {&grpc_static_metadata_refcounts[103], {{g_bytes + 1193, 16}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, + {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}}, + {&grpc_static_metadata_refcounts[104], {{g_bytes + 1209, 13}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[104], {{g_bytes + 1142, 12}}}}, + {&grpc_static_metadata_refcounts[105], {{g_bytes + 1222, 12}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[105], {{g_bytes + 1154, 21}}}}, + {&grpc_static_metadata_refcounts[106], {{g_bytes + 1234, 21}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}}, + {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, + {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}}, + {&grpc_static_metadata_refcounts[104], {{g_bytes + 1209, 13}}}}, }; const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78, 79, 80, 81, 82}; diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 2bb9f728380..4f9670232c3 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -31,7 +31,7 @@ #include "src/core/lib/transport/metadata.h" -#define GRPC_STATIC_MDSTR_COUNT 106 +#define GRPC_STATIC_MDSTR_COUNT 107 extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* ":path" */ #define GRPC_MDSTR_PATH (grpc_static_slice_table[0]) @@ -110,147 +110,151 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "/grpc.health.v1.Health/Watch" */ #define GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH \ (grpc_static_slice_table[35]) +/* "/envoy.service.discovery.v2.AggregatedDiscoveryService/StreamAggregatedResources" + */ +#define GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_DISCOVERY_DOT_V2_DOT_AGGREGATEDDISCOVERYSERVICE_SLASH_STREAMAGGREGATEDRESOURCES \ + (grpc_static_slice_table[36]) /* "deflate" */ -#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[36]) +#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[37]) /* "gzip" */ -#define GRPC_MDSTR_GZIP (grpc_static_slice_table[37]) +#define GRPC_MDSTR_GZIP (grpc_static_slice_table[38]) /* "stream/gzip" */ -#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[38]) +#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[39]) /* "GET" */ -#define GRPC_MDSTR_GET (grpc_static_slice_table[39]) +#define GRPC_MDSTR_GET (grpc_static_slice_table[40]) /* "POST" */ -#define GRPC_MDSTR_POST (grpc_static_slice_table[40]) +#define GRPC_MDSTR_POST (grpc_static_slice_table[41]) /* "/" */ -#define GRPC_MDSTR_SLASH (grpc_static_slice_table[41]) +#define GRPC_MDSTR_SLASH (grpc_static_slice_table[42]) /* "/index.html" */ -#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[42]) +#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[43]) /* "http" */ -#define GRPC_MDSTR_HTTP (grpc_static_slice_table[43]) +#define GRPC_MDSTR_HTTP (grpc_static_slice_table[44]) /* "https" */ -#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[44]) +#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[45]) /* "200" */ -#define GRPC_MDSTR_200 (grpc_static_slice_table[45]) +#define GRPC_MDSTR_200 (grpc_static_slice_table[46]) /* "204" */ -#define GRPC_MDSTR_204 (grpc_static_slice_table[46]) +#define GRPC_MDSTR_204 (grpc_static_slice_table[47]) /* "206" */ -#define GRPC_MDSTR_206 (grpc_static_slice_table[47]) +#define GRPC_MDSTR_206 (grpc_static_slice_table[48]) /* "304" */ -#define GRPC_MDSTR_304 (grpc_static_slice_table[48]) +#define GRPC_MDSTR_304 (grpc_static_slice_table[49]) /* "400" */ -#define GRPC_MDSTR_400 (grpc_static_slice_table[49]) +#define GRPC_MDSTR_400 (grpc_static_slice_table[50]) /* "404" */ -#define GRPC_MDSTR_404 (grpc_static_slice_table[50]) +#define GRPC_MDSTR_404 (grpc_static_slice_table[51]) /* "500" */ -#define GRPC_MDSTR_500 (grpc_static_slice_table[51]) +#define GRPC_MDSTR_500 (grpc_static_slice_table[52]) /* "accept-charset" */ -#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[52]) +#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[53]) /* "gzip, deflate" */ -#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[53]) +#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[54]) /* "accept-language" */ -#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[54]) +#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[55]) /* "accept-ranges" */ -#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[55]) +#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[56]) /* "accept" */ -#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[56]) +#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[57]) /* "access-control-allow-origin" */ -#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[57]) +#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[58]) /* "age" */ -#define GRPC_MDSTR_AGE (grpc_static_slice_table[58]) +#define GRPC_MDSTR_AGE (grpc_static_slice_table[59]) /* "allow" */ -#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[59]) +#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[60]) /* "authorization" */ -#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[60]) +#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[61]) /* "cache-control" */ -#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[61]) +#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[62]) /* "content-disposition" */ -#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[62]) +#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[63]) /* "content-language" */ -#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[63]) +#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[64]) /* "content-length" */ -#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[64]) +#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[65]) /* "content-location" */ -#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[65]) +#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[66]) /* "content-range" */ -#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[66]) +#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[67]) /* "cookie" */ -#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[67]) +#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[68]) /* "date" */ -#define GRPC_MDSTR_DATE (grpc_static_slice_table[68]) +#define GRPC_MDSTR_DATE (grpc_static_slice_table[69]) /* "etag" */ -#define GRPC_MDSTR_ETAG (grpc_static_slice_table[69]) +#define GRPC_MDSTR_ETAG (grpc_static_slice_table[70]) /* "expect" */ -#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[70]) +#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[71]) /* "expires" */ -#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[71]) +#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[72]) /* "from" */ -#define GRPC_MDSTR_FROM (grpc_static_slice_table[72]) +#define GRPC_MDSTR_FROM (grpc_static_slice_table[73]) /* "if-match" */ -#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[73]) +#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[74]) /* "if-modified-since" */ -#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[74]) +#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[75]) /* "if-none-match" */ -#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[75]) +#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[76]) /* "if-range" */ -#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[76]) +#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[77]) /* "if-unmodified-since" */ -#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[77]) +#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[78]) /* "last-modified" */ -#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[78]) +#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[79]) /* "link" */ -#define GRPC_MDSTR_LINK (grpc_static_slice_table[79]) +#define GRPC_MDSTR_LINK (grpc_static_slice_table[80]) /* "location" */ -#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[80]) +#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[81]) /* "max-forwards" */ -#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[81]) +#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[82]) /* "proxy-authenticate" */ -#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[82]) +#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[83]) /* "proxy-authorization" */ -#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[83]) +#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[84]) /* "range" */ -#define GRPC_MDSTR_RANGE (grpc_static_slice_table[84]) +#define GRPC_MDSTR_RANGE (grpc_static_slice_table[85]) /* "referer" */ -#define GRPC_MDSTR_REFERER (grpc_static_slice_table[85]) +#define GRPC_MDSTR_REFERER (grpc_static_slice_table[86]) /* "refresh" */ -#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[86]) +#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[87]) /* "retry-after" */ -#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[87]) +#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[88]) /* "server" */ -#define GRPC_MDSTR_SERVER (grpc_static_slice_table[88]) +#define GRPC_MDSTR_SERVER (grpc_static_slice_table[89]) /* "set-cookie" */ -#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[89]) +#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[90]) /* "strict-transport-security" */ -#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[90]) +#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[91]) /* "transfer-encoding" */ -#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[91]) +#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[92]) /* "vary" */ -#define GRPC_MDSTR_VARY (grpc_static_slice_table[92]) +#define GRPC_MDSTR_VARY (grpc_static_slice_table[93]) /* "via" */ -#define GRPC_MDSTR_VIA (grpc_static_slice_table[93]) +#define GRPC_MDSTR_VIA (grpc_static_slice_table[94]) /* "www-authenticate" */ -#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[94]) +#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[95]) /* "0" */ -#define GRPC_MDSTR_0 (grpc_static_slice_table[95]) +#define GRPC_MDSTR_0 (grpc_static_slice_table[96]) /* "identity" */ -#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[96]) +#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[97]) /* "trailers" */ -#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[97]) +#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[98]) /* "application/grpc" */ -#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[98]) +#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[99]) /* "grpc" */ -#define GRPC_MDSTR_GRPC (grpc_static_slice_table[99]) +#define GRPC_MDSTR_GRPC (grpc_static_slice_table[100]) /* "PUT" */ -#define GRPC_MDSTR_PUT (grpc_static_slice_table[100]) +#define GRPC_MDSTR_PUT (grpc_static_slice_table[101]) /* "lb-cost-bin" */ -#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[101]) +#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[102]) /* "identity,deflate" */ -#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[102]) +#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[103]) /* "identity,gzip" */ -#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[103]) +#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[104]) /* "deflate,gzip" */ -#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[104]) +#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[105]) /* "identity,deflate,gzip" */ #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (grpc_static_slice_table[105]) + (grpc_static_slice_table[106]) extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable; extern grpc_slice_refcount diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary index a79fe5ad957..0469421c975 100644 --- a/test/core/end2end/fuzzers/hpack.dictionary +++ b/test/core/end2end/fuzzers/hpack.dictionary @@ -35,6 +35,7 @@ "\x1Fgrpc.max_response_message_bytes" "$/grpc.lb.v1.LoadBalancer/BalanceLoad" "\x1C/grpc.health.v1.Health/Watch" +"P/envoy.service.discovery.v2.AggregatedDiscoveryService/StreamAggregatedResources" "\x07deflate" "\x04gzip" "\x0Bstream/gzip" From bab043e8650799b91a4e40853e56439c2ddb15a7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 16 Nov 2018 15:27:13 -0800 Subject: [PATCH 0233/2143] Cleanup --- CMakeLists.txt | 72 ++++++++-------- Makefile | 84 +++++++++++-------- build.yaml | 18 ++-- .../chttp2/transport/chttp2_transport.cc | 7 +- .../chttp2/transport/context_list.cc | 17 ++-- .../transport/chttp2/transport/context_list.h | 30 +++---- .../ext/transport/chttp2/transport/internal.h | 4 +- .../ext/transport/chttp2/transport/writing.cc | 3 +- src/core/lib/iomgr/buffer_list.cc | 13 +-- src/core/lib/iomgr/buffer_list.h | 7 +- src/core/lib/iomgr/iomgr.cc | 2 - src/core/lib/iomgr/tcp_posix.cc | 17 +--- .../transport/chttp2/context_list_test.cc | 39 +++++++-- test/core/util/mock_endpoint.cc | 26 +++--- test/core/util/passthru_endpoint.cc | 4 +- test/core/util/trickle_endpoint.cc | 4 +- .../microbenchmarks/bm_chttp2_transport.cc | 4 +- .../generated/sources_and_headers.json | 30 +++---- tools/run_tests/generated/tests.json | 48 +++++------ 19 files changed, 231 insertions(+), 198 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ccb31e6412..1da78e8f57a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -262,7 +262,6 @@ add_dependencies(buildtests_c combiner_test) add_dependencies(buildtests_c compression_test) add_dependencies(buildtests_c concurrent_connectivity_test) add_dependencies(buildtests_c connection_refused_test) -add_dependencies(buildtests_c context_list_test) add_dependencies(buildtests_c dns_resolver_connectivity_test) add_dependencies(buildtests_c dns_resolver_cooldown_test) add_dependencies(buildtests_c dns_resolver_test) @@ -589,6 +588,7 @@ add_dependencies(buildtests_cxx client_interceptors_end2end_test) add_dependencies(buildtests_cxx client_lb_end2end_test) add_dependencies(buildtests_cxx codegen_test_full) add_dependencies(buildtests_cxx codegen_test_minimal) +add_dependencies(buildtests_cxx context_list_test) add_dependencies(buildtests_cxx credentials_test) add_dependencies(buildtests_cxx cxx_byte_buffer_test) add_dependencies(buildtests_cxx cxx_slice_test) @@ -6459,39 +6459,6 @@ target_link_libraries(connection_refused_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) -add_executable(context_list_test - test/core/transport/chttp2/context_list_test.cc -) - - -target_include_directories(context_list_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(context_list_test - ${_gRPC_ALLTARGETS_LIBRARIES} - grpc_test_util - grpc -) - - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(context_list_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(context_list_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() - -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) - add_executable(dns_resolver_connectivity_test test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc ) @@ -12738,6 +12705,43 @@ target_link_libraries(codegen_test_minimal ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(context_list_test + test/core/transport/chttp2/context_list_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(context_list_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(context_list_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 6dc9fe6ed1c..ca867ebc46d 100644 --- a/Makefile +++ b/Makefile @@ -991,7 +991,6 @@ combiner_test: $(BINDIR)/$(CONFIG)/combiner_test compression_test: $(BINDIR)/$(CONFIG)/compression_test concurrent_connectivity_test: $(BINDIR)/$(CONFIG)/concurrent_connectivity_test connection_refused_test: $(BINDIR)/$(CONFIG)/connection_refused_test -context_list_test: $(BINDIR)/$(CONFIG)/context_list_test dns_resolver_connectivity_test: $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test dns_resolver_cooldown_test: $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test dns_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_test @@ -1169,6 +1168,7 @@ client_interceptors_end2end_test: $(BINDIR)/$(CONFIG)/client_interceptors_end2en client_lb_end2end_test: $(BINDIR)/$(CONFIG)/client_lb_end2end_test codegen_test_full: $(BINDIR)/$(CONFIG)/codegen_test_full codegen_test_minimal: $(BINDIR)/$(CONFIG)/codegen_test_minimal +context_list_test: $(BINDIR)/$(CONFIG)/context_list_test credentials_test: $(BINDIR)/$(CONFIG)/credentials_test cxx_byte_buffer_test: $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test @@ -1448,7 +1448,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/compression_test \ $(BINDIR)/$(CONFIG)/concurrent_connectivity_test \ $(BINDIR)/$(CONFIG)/connection_refused_test \ - $(BINDIR)/$(CONFIG)/context_list_test \ $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test \ $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test \ $(BINDIR)/$(CONFIG)/dns_resolver_test \ @@ -1675,6 +1674,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/client_lb_end2end_test \ $(BINDIR)/$(CONFIG)/codegen_test_full \ $(BINDIR)/$(CONFIG)/codegen_test_minimal \ + $(BINDIR)/$(CONFIG)/context_list_test \ $(BINDIR)/$(CONFIG)/credentials_test \ $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test \ $(BINDIR)/$(CONFIG)/cxx_slice_test \ @@ -1858,6 +1858,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/client_lb_end2end_test \ $(BINDIR)/$(CONFIG)/codegen_test_full \ $(BINDIR)/$(CONFIG)/codegen_test_minimal \ + $(BINDIR)/$(CONFIG)/context_list_test \ $(BINDIR)/$(CONFIG)/credentials_test \ $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test \ $(BINDIR)/$(CONFIG)/cxx_slice_test \ @@ -1980,8 +1981,6 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/concurrent_connectivity_test || ( echo test concurrent_connectivity_test failed ; exit 1 ) $(E) "[RUN] Testing connection_refused_test" $(Q) $(BINDIR)/$(CONFIG)/connection_refused_test || ( echo test connection_refused_test failed ; exit 1 ) - $(E) "[RUN] Testing context_list_test" - $(Q) $(BINDIR)/$(CONFIG)/context_list_test || ( echo test context_list_test failed ; exit 1 ) $(E) "[RUN] Testing dns_resolver_connectivity_test" $(Q) $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test || ( echo test dns_resolver_connectivity_test failed ; exit 1 ) $(E) "[RUN] Testing dns_resolver_cooldown_test" @@ -2324,6 +2323,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/codegen_test_full || ( echo test codegen_test_full failed ; exit 1 ) $(E) "[RUN] Testing codegen_test_minimal" $(Q) $(BINDIR)/$(CONFIG)/codegen_test_minimal || ( echo test codegen_test_minimal failed ; exit 1 ) + $(E) "[RUN] Testing context_list_test" + $(Q) $(BINDIR)/$(CONFIG)/context_list_test || ( echo test context_list_test failed ; exit 1 ) $(E) "[RUN] Testing credentials_test" $(Q) $(BINDIR)/$(CONFIG)/credentials_test || ( echo test credentials_test failed ; exit 1 ) $(E) "[RUN] Testing cxx_byte_buffer_test" @@ -11216,38 +11217,6 @@ endif endif -CONTEXT_LIST_TEST_SRC = \ - test/core/transport/chttp2/context_list_test.cc \ - -CONTEXT_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CONTEXT_LIST_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/context_list_test: openssl_dep_error - -else - - - -$(BINDIR)/$(CONFIG)/context_list_test: $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/context_list_test - -endif - -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a - -deps_context_list_test: $(CONTEXT_LIST_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(CONTEXT_LIST_TEST_OBJS:.o=.dep) -endif -endif - - DNS_RESOLVER_CONNECTIVITY_TEST_SRC = \ test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc \ @@ -17590,6 +17559,49 @@ $(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_minimal.o: $(GENDIR)/src/proto $(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc +CONTEXT_LIST_TEST_SRC = \ + test/core/transport/chttp2/context_list_test.cc \ + +CONTEXT_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CONTEXT_LIST_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/context_list_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)/context_list_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/context_list_test: $(PROTOBUF_DEP) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/context_list_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a + +deps_context_list_test: $(CONTEXT_LIST_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(CONTEXT_LIST_TEST_OBJS:.o=.dep) +endif +endif + + CREDENTIALS_TEST_SRC = \ test/cpp/client/credentials_test.cc \ diff --git a/build.yaml b/build.yaml index f837ea90b65..cca5ed3cbff 100644 --- a/build.yaml +++ b/build.yaml @@ -2300,15 +2300,6 @@ targets: - grpc - gpr_test_util - gpr -- name: context_list_test - build: test - language: c - src: - - test/core/transport/chttp2/context_list_test.cc - deps: - - grpc_test_util - - grpc - uses_polling: false - name: dns_resolver_connectivity_test cpu_cost: 0.1 build: test @@ -4613,6 +4604,15 @@ targets: - grpc++_codegen_base - grpc++_codegen_base_src uses_polling: false +- name: context_list_test + build: test + language: c++ + src: + - test/core/transport/chttp2/context_list_test.cc + deps: + - grpc_test_util + - grpc + uses_polling: false - name: credentials_test gtest: true build: test diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index da29ff1b37e..4ca0f49adf2 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -157,7 +157,6 @@ bool g_flow_control_enabled = true; */ grpc_chttp2_transport::~grpc_chttp2_transport() { - gpr_log(GPR_INFO, "destruct transport %p", t); size_t i; if (channelz_socket != nullptr) { @@ -172,11 +171,12 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { grpc_chttp2_hpack_compressor_destroy(&hpack_compressor); grpc_core::ContextList::Execute(cl, nullptr, GRPC_ERROR_NONE); + cl = nullptr; + grpc_slice_buffer_destroy_internal(&read_buffer); grpc_chttp2_hpack_parser_destroy(&hpack_parser); grpc_chttp2_goaway_parser_destroy(&goaway_parser); - for (i = 0; i < STREAM_LIST_COUNT; i++) { GPR_ASSERT(lists[i].head == nullptr); GPR_ASSERT(lists[i].tail == nullptr); @@ -1072,9 +1072,6 @@ static void write_action(void* gt, grpc_error* error) { grpc_chttp2_transport* t = static_cast(gt); void* cl = t->cl; t->cl = nullptr; - if (cl) { - gpr_log(GPR_INFO, "cleared for write"); - } grpc_endpoint_write( t->ep, &t->outbuf, GRPC_CLOSURE_INIT(&t->write_action_end_locked, write_action_end_locked, t, diff --git a/src/core/ext/transport/chttp2/transport/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc index 91c26a5bca0..11f5c14a39b 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.cc +++ b/src/core/ext/transport/chttp2/transport/context_list.cc @@ -21,33 +21,30 @@ #include "src/core/ext/transport/chttp2/transport/context_list.h" namespace { -void (*cb)(void*, const char*) = nullptr; +void (*cb)(void*, grpc_core::Timestamps*) = nullptr; } namespace grpc_core { void ContextList::Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error) { - gpr_log(GPR_INFO, "execute"); ContextList* head = static_cast(arg); ContextList* ptr; while (head != nullptr) { if (error == GRPC_ERROR_NONE && ts != nullptr) { if (cb) { - cb(head->s->context, ts); + cb(head->s_->context, ts); } } - gpr_log(GPR_INFO, "one iteration %p %p", head, arg); - GRPC_CHTTP2_STREAM_UNREF(static_cast(head->s), - "timestamp exec"); - //grpc_stream_unref(head->s->refcount); + GRPC_CHTTP2_STREAM_UNREF(static_cast(head->s_), + "timestamp"); ptr = head; - head = head->next; - gpr_free(ptr); + head = head->next_; + grpc_core::Delete(ptr); } } void grpc_http2_set_write_timestamps_callback( - void (*fn)(void*, const char*)) { + void (*fn)(void*, grpc_core::Timestamps*)) { cb = fn; } } /* namespace grpc_core */ diff --git a/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h index 23a49d5b320..0cf7ba4dc31 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.h +++ b/src/core/ext/transport/chttp2/transport/context_list.h @@ -35,29 +35,25 @@ class ContextList { /* Make sure context is not already present */ ContextList* ptr = *head; GRPC_CHTTP2_STREAM_REF(s, "timestamp"); - //grpc_stream_ref(s->refcount); while (ptr != nullptr) { - if (ptr->s == s) { - GPR_ASSERT(false); + if (ptr->s_ == s) { + GPR_ASSERT( + false && + "Trying to append a stream that is already present in the list"); } - ptr = ptr->next; + ptr = ptr->next_; } - ContextList* elem = - static_cast(gpr_malloc(sizeof(ContextList))); - elem->s = s; - elem->next = nullptr; + ContextList* elem = grpc_core::New(); + elem->s_ = s; if (*head == nullptr) { *head = elem; - gpr_log(GPR_INFO, "new head"); - gpr_log(GPR_INFO, "append %p %p", elem, *head); return; } - gpr_log(GPR_INFO, "append %p %p", elem, *head); ptr = *head; - while (ptr->next != nullptr) { - ptr = ptr->next; + while (ptr->next_ != nullptr) { + ptr = ptr->next_; } - ptr->next = elem; + ptr->next_ = elem; } /* Executes a function \a fn with each context in the list and \a ts. It also @@ -65,12 +61,12 @@ class ContextList { static void Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error); private: - grpc_chttp2_stream* s; - ContextList* next; + grpc_chttp2_stream* s_ = nullptr; + ContextList* next_ = nullptr; }; void grpc_http2_set_write_timestamps_callback( - void (*fn)(void*, const char*)); + void (*fn)(void*, grpc_core::Timestamps*)); } /* namespace grpc_core */ #endif /* GRPC_CORE_EXT_TRANSPORT_CONTEXT_LIST_H */ diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 8a83f4894ca..877b8aba77c 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -485,7 +485,7 @@ struct grpc_chttp2_transport { bool keepalive_permit_without_calls = false; /** keep-alive state machine state */ grpc_chttp2_keepalive_state keepalive_state; - grpc_core::ContextList* cl; + grpc_core::ContextList* cl = nullptr; grpc_core::RefCountedPtr channelz_socket; uint32_t num_messages_in_next_write = 0; }; @@ -640,6 +640,8 @@ struct grpc_chttp2_stream { bool unprocessed_incoming_frames_decompressed = false; /** gRPC header bytes that are already decompressed */ size_t decompressed_header_bytes = 0; + /** Whether the bytes needs to be traced using Fathom */ + bool traced = false; }; /** Transport writing call flow: diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index 3b3367d0f3b..77320b496f9 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -488,8 +488,7 @@ class StreamWriteContext { return; // early out: nothing to do } - if (/* traced && */ grpc_endpoint_can_track_err(t_->ep)) { - gpr_log(GPR_INFO, "for transport %p", t_); + if (s_->traced && grpc_endpoint_can_track_err(t_->ep)) { grpc_core::ContextList::Append(&t_->cl, s_); } while ((s_->flow_controlled_buffer.length > 0 || diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index d7884a59657..e20dab15b18 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -31,7 +31,6 @@ namespace grpc_core { void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, void* arg) { - gpr_log(GPR_INFO, "new entry %u", seq_no); GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* new_elem = New(seq_no, arg); /* Store the current time as the sendmsg time. */ @@ -56,16 +55,21 @@ void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) { gts->clock_type = GPR_CLOCK_REALTIME; } +void default_timestamps_callback(void* arg, grpc_core::Timestamps* ts, + grpc_error* shudown_err) { + gpr_log(GPR_DEBUG, "Timestamps callback has not been registered"); +} + /** The saved callback function that will be invoked when we get all the * timestamps that we are going to get for a TracedBuffer. */ void (*timestamps_callback)(void*, grpc_core::Timestamps*, - grpc_error* shutdown_err); + grpc_error* shutdown_err) = + default_timestamps_callback; } /* namespace */ void TracedBuffer::ProcessTimestamp(TracedBuffer** head, struct sock_extended_err* serr, struct scm_timestamping* tss) { - gpr_log(GPR_INFO, "process timestamp %u", serr->ee_data); GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* elem = *head; TracedBuffer* next = nullptr; @@ -87,7 +91,6 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head, /* 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. */ - gpr_log(GPR_INFO, "calling"); timestamps_callback(elem->arg_, &(elem->ts_), GRPC_ERROR_NONE); next = elem->next_; Delete(elem); @@ -106,10 +109,8 @@ void TracedBuffer::Shutdown(TracedBuffer** head, void* remaining, grpc_error* shutdown_err) { GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* elem = *head; - gpr_log(GPR_INFO, "shutdown"); while (elem != nullptr) { timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err); - gpr_log(GPR_INFO, "iter"); auto* next = elem->next_; Delete(elem); elem = next; diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index f7d2f6c3701..87d74f9ce27 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -82,7 +82,12 @@ class TracedBuffer { grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */ }; #else /* GRPC_LINUX_ERRQUEUE */ -class TracedBuffer {}; +class TracedBuffer { + public: + /* Dummy shutdown function */ + static void Shutdown(grpc_core::TracedBuffer** head, void* remaining, + grpc_error* shutdown_err) {} +}; #endif /* GRPC_LINUX_ERRQUEUE */ /** Sets the callback function to call when timestamps for a write are diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index 7c0f19d0dd3..30b68db4df7 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -33,7 +33,6 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/thd.h" -#include "src/core/ext/transport/chttp2/transport/context_list.h" #include "src/core/lib/iomgr/buffer_list.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/executor.h" @@ -59,7 +58,6 @@ void grpc_iomgr_init() { g_root_object.name = (char*)"root"; grpc_network_status_init(); grpc_iomgr_platform_init(); - grpc_tcp_set_write_timestamps_callback(grpc_core::ContextList::Execute); } void grpc_iomgr_start() { grpc_timer_manager_init(); } diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 78c8d1eed81..cb4c9db7a68 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -382,7 +382,6 @@ static void tcp_ref(grpc_tcp* tcp) { gpr_ref(&tcp->refcount); } static void tcp_destroy(grpc_endpoint* ep) { grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = reinterpret_cast(ep); - gpr_log(GPR_INFO, "tcp destroy %p %p", ep, tcp->outgoing_buffer_arg); grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { gpr_mu_lock(&tcp->tb_mu); @@ -594,7 +593,6 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, ssize_t* sent_length, grpc_error** error) { if (!tcp->socket_ts_enabled) { - gpr_log(GPR_INFO, "set timestamps"); uint32_t opt = grpc_core::kTimestampingSocketOptions; if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING, static_cast(&opt), sizeof(opt)) != 0) { @@ -627,7 +625,6 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, *sent_length = length; /* Only save timestamps if all the bytes were taken by sendmsg. */ if (sending_length == static_cast(length)) { - gpr_log(GPR_INFO, "tcp new entry %p %p", tcp, tcp->outgoing_buffer_arg); gpr_mu_lock(&tcp->tb_mu); grpc_core::TracedBuffer::AddNewEntry( &tcp->tb_head, static_cast(tcp->bytes_counter + length), @@ -687,7 +684,6 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, * non-linux platforms, error processing is not used/enabled currently. */ static bool process_errors(grpc_tcp* tcp) { - gpr_log(GPR_INFO, "process errors"); while (true) { struct iovec iov; iov.iov_base = nullptr; @@ -750,8 +746,6 @@ static bool process_errors(grpc_tcp* tcp) { } static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { - gpr_log(GPR_INFO, "handle error %p", arg); - GRPC_LOG_IF_ERROR("handle error", GRPC_ERROR_REF(error)); grpc_tcp* tcp = static_cast(arg); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p got_error: %s", tcp, grpc_error_string(error)); @@ -761,8 +755,6 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { static_cast(gpr_atm_acq_load(&tcp->stop_error_notification))) { /* We aren't going to register to hear on error anymore, so it is safe to * unref. */ - gpr_log(GPR_INFO, "%p %d early return", error, - static_cast(gpr_atm_acq_load(&tcp->stop_error_notification))); TCP_UNREF(tcp, "error-tracking"); return; } @@ -797,6 +789,8 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { } #endif /* GRPC_LINUX_ERRQUEUE */ +/* If outgoing_buffer_arg is filled, shuts down the list early, so that any + * release operations needed can be performed on the arg */ void tcp_shutdown_buffer_list(grpc_tcp* tcp) { if (tcp->outgoing_buffer_arg) { gpr_mu_lock(&tcp->tb_mu); @@ -856,7 +850,6 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { if (tcp->outgoing_buffer_arg != nullptr) { if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length, error)) { - gpr_log(GPR_INFO, "something went wrong"); tcp_shutdown_buffer_list(tcp); return true; /* something went wrong with timestamps */ } @@ -881,13 +874,11 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { } return false; } else if (errno == EPIPE) { - gpr_log(GPR_INFO, "something went wrong"); *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp); grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); tcp_shutdown_buffer_list(tcp); return true; } else { - gpr_log(GPR_INFO, "something went wrong"); *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp); grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); tcp_shutdown_buffer_list(tcp); @@ -951,7 +942,6 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) { static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, grpc_closure* cb, void* arg) { GPR_TIMER_SCOPE("tcp_write", 0); - gpr_log(GPR_INFO, "tcp_write %p %p", ep, arg); grpc_tcp* tcp = reinterpret_cast(ep); grpc_error* error = GRPC_ERROR_NONE; @@ -992,7 +982,6 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, } notify_on_write(tcp); } else { - gpr_log(GPR_INFO, "imm sched"); if (grpc_tcp_trace.enabled()) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "write: %s", str); @@ -1041,7 +1030,6 @@ static bool tcp_can_track_err(grpc_endpoint* ep) { struct sockaddr addr; socklen_t len = sizeof(addr); if (getsockname(tcp->fd, &addr, &len) < 0) { - gpr_log(GPR_ERROR, "getsockname"); return false; } if (addr.sa_family == AF_INET || addr.sa_family == AF_INET6) { @@ -1160,7 +1148,6 @@ 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_log(GPR_INFO, "destroy and release %p %p", ep, tcp->outgoing_buffer_arg); GPR_ASSERT(ep->vtable == &vtable); tcp->release_fd = fd; tcp->release_fd_cb = done; diff --git a/test/core/transport/chttp2/context_list_test.cc b/test/core/transport/chttp2/context_list_test.cc index 1f7a38a107c..3814184e164 100644 --- a/test/core/transport/chttp2/context_list_test.cc +++ b/test/core/transport/chttp2/context_list_test.cc @@ -18,12 +18,17 @@ #include "src/core/lib/iomgr/port.h" +#include +#include + +#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/ext/transport/chttp2/transport/context_list.h" +#include "src/core/lib/transport/transport.h" +#include "test/core/util/mock_endpoint.h" +#include "test/core/util/test_config.h" #include -#include "test/core/util/test_config.h" - static void TestExecuteFlushesListVerifier(void* arg, grpc_core::Timestamps* ts) { GPR_ASSERT(arg != nullptr); @@ -31,6 +36,8 @@ static void TestExecuteFlushesListVerifier(void* arg, gpr_atm_rel_store(done, static_cast(1)); } +static void discard_write(grpc_slice slice) {} + /** Tests that all ContextList elements in the list are flushed out on * execute. * Also tests that arg is passed correctly. @@ -39,19 +46,41 @@ static void TestExecuteFlushesList() { grpc_core::ContextList* list = nullptr; grpc_http2_set_write_timestamps_callback(TestExecuteFlushesListVerifier); #define NUM_ELEM 5 - grpc_chttp2_stream s[NUM_ELEM]; + grpc_core::ExecCtx exec_ctx; + grpc_stream_refcount ref; + grpc_resource_quota* resource_quota = + grpc_resource_quota_create("context_list_test"); + grpc_endpoint* mock_endpoint = + grpc_mock_endpoint_create(discard_write, resource_quota); + grpc_transport* t = + grpc_create_chttp2_transport(nullptr, mock_endpoint, true); + std::vector s; + s.reserve(NUM_ELEM); gpr_atm verifier_called[NUM_ELEM]; for (auto i = 0; i < NUM_ELEM; i++) { - s[i].context = &verifier_called[i]; + s.push_back(static_cast( + gpr_malloc(grpc_transport_stream_size(t)))); + grpc_transport_init_stream(reinterpret_cast(t), + reinterpret_cast(s[i]), &ref, + nullptr, nullptr); + s[i]->context = &verifier_called[i]; gpr_atm_rel_store(&verifier_called[i], static_cast(0)); - grpc_core::ContextList::Append(&list, &s[i]); + grpc_core::ContextList::Append(&list, s[i]); } grpc_core::Timestamps ts; grpc_core::ContextList::Execute(list, &ts, GRPC_ERROR_NONE); for (auto i = 0; i < NUM_ELEM; i++) { GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) == static_cast(1)); + grpc_transport_destroy_stream(reinterpret_cast(t), + reinterpret_cast(s[i]), + nullptr); + exec_ctx.Flush(); + gpr_free(s[i]); } + grpc_transport_destroy(t); + grpc_resource_quota_unref(resource_quota); + exec_ctx.Flush(); } static void TestContextList() { TestExecuteFlushesList(); } diff --git a/test/core/util/mock_endpoint.cc b/test/core/util/mock_endpoint.cc index 570edf18e55..e5867cd526b 100644 --- a/test/core/util/mock_endpoint.cc +++ b/test/core/util/mock_endpoint.cc @@ -103,19 +103,19 @@ static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) { static int me_get_fd(grpc_endpoint* ep) { return -1; } -static const grpc_endpoint_vtable vtable = { - me_read, - me_write, - me_add_to_pollset, - me_add_to_pollset_set, - me_delete_from_pollset_set, - me_shutdown, - me_destroy, - me_get_resource_user, - me_get_peer, - me_get_fd, - nullptr, -}; +static bool me_can_track_err(grpc_endpoint* ep) { return false; } + +static const grpc_endpoint_vtable vtable = {me_read, + me_write, + me_add_to_pollset, + me_add_to_pollset_set, + me_delete_from_pollset_set, + me_shutdown, + me_destroy, + me_get_resource_user, + me_get_peer, + me_get_fd, + me_can_track_err}; grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice), grpc_resource_quota* resource_quota) { diff --git a/test/core/util/passthru_endpoint.cc b/test/core/util/passthru_endpoint.cc index 835a39394c5..51b6de46951 100644 --- a/test/core/util/passthru_endpoint.cc +++ b/test/core/util/passthru_endpoint.cc @@ -155,6 +155,8 @@ static char* me_get_peer(grpc_endpoint* ep) { static int me_get_fd(grpc_endpoint* ep) { return -1; } +static bool me_can_track_err(grpc_endpoint* ep) { return false; } + static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) { half* m = reinterpret_cast(ep); return m->resource_user; @@ -171,7 +173,7 @@ static const grpc_endpoint_vtable vtable = { me_get_resource_user, me_get_peer, me_get_fd, - nullptr, + me_can_track_err, }; static void half_init(half* m, passthru_endpoint* parent, diff --git a/test/core/util/trickle_endpoint.cc b/test/core/util/trickle_endpoint.cc index 8d93db05e6c..b0da735e57f 100644 --- a/test/core/util/trickle_endpoint.cc +++ b/test/core/util/trickle_endpoint.cc @@ -131,6 +131,8 @@ static int te_get_fd(grpc_endpoint* ep) { return grpc_endpoint_get_fd(te->wrapped); } +static bool te_can_track_err(grpc_endpoint* ep) { return false; } + static void te_finish_write(void* arg, grpc_error* error) { trickle_endpoint* te = static_cast(arg); gpr_mu_lock(&te->mu); @@ -149,7 +151,7 @@ static const grpc_endpoint_vtable vtable = {te_read, te_get_resource_user, te_get_peer, te_get_fd, - nullptr}; + te_can_track_err}; grpc_endpoint* grpc_trickle_endpoint_create(grpc_endpoint* wrap, double bytes_per_second) { diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index f7ae16e61d4..650152ecc0d 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -54,7 +54,8 @@ class DummyEndpoint : public grpc_endpoint { destroy, get_resource_user, get_peer, - get_fd}; + get_fd, + can_track_err}; grpc_endpoint::vtable = &my_vtable; ru_ = grpc_resource_user_create(Library::get().rq(), "dummy_endpoint"); } @@ -125,6 +126,7 @@ class DummyEndpoint : public grpc_endpoint { } static char* get_peer(grpc_endpoint* ep) { return gpr_strdup("test"); } static int get_fd(grpc_endpoint* ep) { return 0; } + static bool can_track_err(grpc_endpoint* ep) { return false; } }; class Fixture { diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8d6ffdb9590..1581b9a94b3 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -364,21 +364,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "grpc", - "grpc_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c", - "name": "context_list_test", - "src": [ - "test/core/transport/chttp2/context_list_test.cc" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "gpr", @@ -3522,6 +3507,21 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "context_list_test", + "src": [ + "test/core/transport/chttp2/context_list_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 30c9c6a5250..0569f81e6a0 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -433,30 +433,6 @@ ], "uses_polling": true }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": false, - "language": "c", - "name": "context_list_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": false - }, { "args": [], "benchmark": false, @@ -4147,6 +4123,30 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "context_list_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, From f0cbcde73195b8e17130538c3479d4c0e3bcd2a2 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 18 Nov 2018 22:47:35 -0800 Subject: [PATCH 0234/2143] New channel pool design --- .../GRPCClient/GRPCCall+ChannelArg.m | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 2 +- .../GRPCClient/private/GRPCChannel.h | 36 +-- .../GRPCClient/private/GRPCChannel.m | 165 +++-------- .../GRPCClient/private/GRPCChannelPool.h | 74 ++++- .../GRPCClient/private/GRPCChannelPool.m | 267 ++++++++++++++++-- .../GRPCClient/private/GRPCWrappedCall.m | 31 +- .../tests/ChannelTests/ChannelPoolTest.m | 212 +++++++++----- .../tests/ChannelTests/ChannelTests.m | 126 +++++---- 9 files changed, 568 insertions(+), 347 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m index 971c2803e29..703cff63bb0 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m @@ -36,7 +36,7 @@ } + (void)closeOpenConnections { - [GRPCChannelPool closeOpenConnections]; + [[GRPCChannelPool sharedInstance] closeOpenConnections]; } + (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host { diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 19de004cbcd..6f4b1647a5a 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -488,7 +488,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. - NSAssert(host && path, @"Neither host nor path can be nil."); + NSAssert(host != nil && path != nil, @"Neither host nor path can be nil."); NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); NSAssert(requestWriter.state == GRXWriterStateNotStarted, diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 4dbe0c276ce..de6d1bf4a24 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -61,47 +61,19 @@ NS_ASSUME_NONNULL_BEGIN + (nullable instancetype) new NS_UNAVAILABLE; /** - * Create a channel with remote \a host and signature \a channelConfigurations. Destroy delay is - * defaulted to 30 seconds. - */ -- (nullable instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration; - -/** - * Create a channel with remote \a host, signature \a channelConfigurations, and destroy delay of - * \a destroyDelay. + * Create a channel with remote \a host and signature \a channelConfigurations. */ - (nullable instancetype)initWithChannelConfiguration: (GRPCChannelConfiguration *)channelConfiguration - destroyDelay:(NSTimeInterval)destroyDelay NS_DESIGNATED_INITIALIZER; /** - * Create a grpc core call object from this channel. The channel's refcount is added by 1. If no - * call is created, NULL is returned, and if the reason is because the channel is already - * disconnected, \a disconnected is set to YES. When the returned call is unreffed, the caller is - * obligated to call \a unref method once. \a disconnected may be null. + * Create a grpc core call object (grpc_call) from this channel. If no call is created, NULL is + * returned. */ - (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions - disconnected:(nullable BOOL *)disconnected; - -/** - * Unref the channel when a call is done. It also decreases the channel's refcount. If the refcount - * of the channel decreases to 0, the channel is destroyed after the destroy delay. - */ -- (void)unref; - -/** - * Force the channel to be disconnected and destroyed. - */ -- (void)disconnect; - -/** - * Return whether the channel is already disconnected. - */ -@property(readonly) BOOL disconnected; + callOptions:(GRPCCallOptions *)callOptions; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 0220141db04..81e53d48e34 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -34,9 +34,6 @@ #import #import -/** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ -static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - @implementation GRPCChannelConfiguration - (instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { @@ -178,43 +175,18 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannel { GRPCChannelConfiguration *_configuration; - dispatch_queue_t _dispatchQueue; grpc_channel *_unmanagedChannel; - NSTimeInterval _destroyDelay; - - NSUInteger _refcount; - NSDate *_lastDispatch; -} -@synthesize disconnected = _disconnected; - -- (instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration { - return [self initWithChannelConfiguration:channelConfiguration - destroyDelay:kDefaultChannelDestroyDelay]; } - (instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration - destroyDelay:(NSTimeInterval)destroyDelay { + (GRPCChannelConfiguration *)channelConfiguration { NSAssert(channelConfiguration != nil, @"channelConfiguration must not be empty."); - NSAssert(destroyDelay > 0, @"destroyDelay must be greater than 0."); if (channelConfiguration == nil) return nil; - if (destroyDelay <= 0) return nil; if ((self = [super init])) { _configuration = [channelConfiguration copy]; -#if __IPHONE_OS_VERSION_MAX_ALLOWED < 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED < 101300 - if (@available(iOS 8.0, macOS 10.10, *)) { - _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); - } else { -#else - { -#endif - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - } + // Create gRPC core channel object. NSString *host = channelConfiguration.host; NSAssert(host.length != 0, @"host cannot be nil"); @@ -233,121 +205,56 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSLog(@"Unable to create channel."); return nil; } - _destroyDelay = destroyDelay; - _disconnected = NO; } return self; } - (grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions - disconnected:(BOOL *)disconnected { + callOptions:(GRPCCallOptions *)callOptions { NSAssert(path.length > 0, @"path must not be empty."); NSAssert(queue != nil, @"completionQueue must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); - if (path.length == 0) return nil; - if (queue == nil) return nil; - if (callOptions == nil) return nil; + if (path.length == 0) return NULL; + if (queue == nil) return NULL; + if (callOptions == nil) return NULL; - __block BOOL isDisconnected = NO; - __block grpc_call *call = NULL; - dispatch_sync(_dispatchQueue, ^{ - if (self->_disconnected) { - isDisconnected = YES; - } else { - NSAssert(self->_unmanagedChannel != NULL, - @"Channel should have valid unmanaged channel."); - if (self->_unmanagedChannel == NULL) return; + grpc_call *call = NULL; + @synchronized(self) { + NSAssert(_unmanagedChannel != NULL, + @"Channel should have valid unmanaged channel."); + if (_unmanagedChannel == NULL) return NULL; - NSString *serverAuthority = - callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; - NSTimeInterval timeout = callOptions.timeout; - NSAssert(timeout >= 0, @"Invalid timeout"); - if (timeout < 0) return; - grpc_slice host_slice = grpc_empty_slice(); - if (serverAuthority) { - host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); - } - grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); - gpr_timespec deadline_ms = - timeout == 0 - ? gpr_inf_future(GPR_CLOCK_REALTIME) - : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); - call = grpc_channel_create_call(self->_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, - queue.unmanagedQueue, path_slice, - serverAuthority ? &host_slice : NULL, deadline_ms, NULL); - if (serverAuthority) { - grpc_slice_unref(host_slice); - } - grpc_slice_unref(path_slice); - if (call == NULL) { - NSLog(@"Unable to create call."); - } else { - // Ref the channel; - [self ref]; - } + NSString *serverAuthority = + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; + NSTimeInterval timeout = callOptions.timeout; + NSAssert(timeout >= 0, @"Invalid timeout"); + if (timeout < 0) return NULL; + grpc_slice host_slice = grpc_empty_slice(); + if (serverAuthority) { + host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); + } + grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); + gpr_timespec deadline_ms = + timeout == 0 + ? gpr_inf_future(GPR_CLOCK_REALTIME) + : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, + queue.unmanagedQueue, path_slice, + serverAuthority ? &host_slice : NULL, deadline_ms, NULL); + if (serverAuthority) { + grpc_slice_unref(host_slice); + } + grpc_slice_unref(path_slice); + NSAssert(call != nil, @"Unable to create call."); + if (call == NULL) { + NSLog(@"Unable to create call."); } - }); - if (disconnected != nil) { - *disconnected = isDisconnected; } return call; } -// This function should be called on _dispatchQueue. -- (void)ref { - _refcount++; - if (_refcount == 1 && _lastDispatch != nil) { - _lastDispatch = nil; - } -} - -- (void)unref { - dispatch_async(_dispatchQueue, ^{ - NSAssert(self->_refcount > 0, @"Illegal reference count."); - if (self->_refcount == 0) { - NSLog(@"Illegal reference count."); - return; - } - self->_refcount--; - if (self->_refcount == 0 && !self->_disconnected) { - // Start timer. - dispatch_time_t delay = - dispatch_time(DISPATCH_TIME_NOW, (int64_t)self->_destroyDelay * NSEC_PER_SEC); - NSDate *now = [NSDate date]; - self->_lastDispatch = now; - dispatch_after(delay, self->_dispatchQueue, ^{ - // Timed disconnection. - if (!self->_disconnected && self->_lastDispatch == now) { - grpc_channel_destroy(self->_unmanagedChannel); - self->_unmanagedChannel = NULL; - self->_disconnected = YES; - } - }); - } - }); -} - -- (void)disconnect { - dispatch_async(_dispatchQueue, ^{ - if (!self->_disconnected) { - grpc_channel_destroy(self->_unmanagedChannel); - self->_unmanagedChannel = nil; - self->_disconnected = YES; - } - }); -} - -- (BOOL)disconnected { - __block BOOL disconnected; - dispatch_sync(_dispatchQueue, ^{ - disconnected = self->_disconnected; - }); - return disconnected; -} - - (void)dealloc { if (_unmanagedChannel) { grpc_channel_destroy(_unmanagedChannel); diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 48779c44497..887bd5f89f7 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -27,7 +27,53 @@ NS_ASSUME_NONNULL_BEGIN +@protocol GRPCChannel; @class GRPCChannel; +@class GRPCChannelPool; +@class GRPCCompletionQueue; +@class GRPCChannelConfiguration; + +/** + * Channel proxy that can be retained and automatically reestablish connection when the channel is + * disconnected. + */ +@interface GRPCPooledChannel : NSObject + +/** + * Initialize with an actual channel object \a channel and a reference to the channel pool. + */ +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration + channelPool:(GRPCChannelPool *)channelPool; + + +/** + * Create a grpc core call object (grpc_call) from this channel. If channel is disconnected, get a + * new channel object from the channel pool. + */ +- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions; + +/** + * Return ownership and destroy the grpc_call object created by + * \a unmanagedCallWithPath:completionQueue:callOptions: and decrease channel refcount. If refcount + * of the channel becomes 0, return the channel object to channel pool. + */ +- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall; + +/** + * Force the channel to disconnect immediately. + */ +- (void)disconnect; + +// The following methods and properties are for test only + +/** + * Return the pointer to the real channel wrapped by the proxy. + */ +@property(atomic, readonly) GRPCChannel *wrappedChannel; + +@end /** * Manage the pool of connected channels. When a channel is no longer referenced by any call, @@ -36,37 +82,41 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCChannelPool : NSObject /** - * Get the singleton instance + * Get the global channel pool. */ + (nullable instancetype)sharedInstance; /** - * Return a channel with a particular configuration. If the channel does not exist, execute \a - * createChannel then add it in the pool. If the channel exists, increase its reference count. + * Return a channel with a particular configuration. The channel may be a cached channel. */ -- (GRPCChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; +- (GRPCPooledChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; /** * This method is deprecated. * * Destroy all open channels and close their connections. */ -+ (void)closeOpenConnections; +- (void)closeOpenConnections; // Test-only methods below /** - * Return a channel with a special destroy delay. If \a destroyDelay is 0, use the default destroy - * delay. + * Get an instance of pool isolated from the global shared pool. This method is for test only. + * Global pool should be used in production. */ -- (GRPCChannel *)channelWithHost:(NSString *)host - callOptions:(GRPCCallOptions *)callOptions - destroyDelay:(NSTimeInterval)destroyDelay; +- (nullable instancetype)init; /** - * Simulate a network transition event and destroy all channels. + * Simulate a network transition event and destroy all channels. This method is for internal and + * test only. */ -- (void)destroyAllChannels; +- (void)disconnectAllChannels; + +/** + * Set the destroy delay of channels. A channel should be destroyed if it stayed idle (no active + * call on it) for this period of time. This property is for test only. + */ +@property(atomic) NSTimeInterval destroyDelay; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 5e2e9bcfebb..92dd4c86aee 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -37,8 +37,150 @@ extern const char *kCFStreamVarName; static GRPCChannelPool *gChannelPool; static dispatch_once_t gInitChannelPool; +/** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ +static const NSTimeInterval kDefaultChannelDestroyDelay = 30; + +@interface GRPCChannelPool() + +- (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; + +- (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; + +@end + +@implementation GRPCPooledChannel { + __weak GRPCChannelPool *_channelPool; + GRPCChannelConfiguration *_channelConfiguration; + NSMutableSet *_unmanagedCalls; +} + +@synthesize wrappedChannel = _wrappedChannel; + +- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration + channelPool:(GRPCChannelPool *)channelPool { + NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); + NSAssert(channelPool != nil, @"channelPool cannot be empty."); + if (channelPool == nil || channelConfiguration == nil) { + return nil; + } + + if ((self = [super init])) { + _channelPool = channelPool; + _channelConfiguration = channelConfiguration; + _unmanagedCalls = [NSMutableSet set]; + } + + return self; +} + +- (grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions { + NSAssert(path.length > 0, @"path must not be empty."); + NSAssert(queue != nil, @"completionQueue must not be empty."); + NSAssert(callOptions, @"callOptions must not be empty."); + if (path.length == 0 || queue == nil || callOptions == nil) return NULL; + + grpc_call *call = NULL; + @synchronized(self) { + if (_wrappedChannel == nil) { + __strong GRPCChannelPool *strongPool = _channelPool; + if (strongPool) { + _wrappedChannel = [strongPool refChannelWithConfiguration:_channelConfiguration]; + } + NSAssert(_wrappedChannel != nil, @"Unable to get a raw channel for proxy."); + } + call = [_wrappedChannel unmanagedCallWithPath:path completionQueue:queue callOptions:callOptions]; + if (call != NULL) { + [_unmanagedCalls addObject:[NSValue valueWithPointer:call]]; + } + } + return call; +} + +- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall { + if (unmanagedCall == nil) return; + + grpc_call_unref(unmanagedCall); + BOOL timedDestroy = NO; + @synchronized(self) { + if ([_unmanagedCalls containsObject:[NSValue valueWithPointer:unmanagedCall]]) { + [_unmanagedCalls removeObject:[NSValue valueWithPointer:unmanagedCall]]; + if ([_unmanagedCalls count] == 0) { + timedDestroy = YES; + } + } + } + if (timedDestroy) { + [self timedDestroy]; + } +} + +- (void)disconnect { + @synchronized(self) { + _wrappedChannel = nil; + [_unmanagedCalls removeAllObjects]; + } +} + +- (GRPCChannel *)wrappedChannel { + GRPCChannel *channel = nil; + @synchronized (self) { + channel = _wrappedChannel; + } + return channel; +} + +- (void)timedDestroy { + __strong GRPCChannelPool *pool = nil; + @synchronized(self) { + // Check if we still want to destroy the channel. + if ([_unmanagedCalls count] == 0) { + pool = _channelPool; + _wrappedChannel = nil; + } + } + [pool unrefChannelWithConfiguration:_channelConfiguration]; +} + +@end + +/** + * A convenience value type for cached channel. + */ +@interface GRPCChannelRecord : NSObject + +/** Pointer to the raw channel. May be nil when the channel has been destroyed. */ +@property GRPCChannel *channel; + +/** Channel proxy corresponding to this channel configuration. */ +@property GRPCPooledChannel *proxy; + +/** Last time when a timed destroy is initiated on the channel. */ +@property NSDate *timedDestroyDate; + +/** Reference count of the proxy to the channel. */ +@property NSUInteger refcount; + +@end + +@implementation GRPCChannelRecord + +- (id)copyWithZone:(NSZone *)zone { + GRPCChannelRecord *newRecord = [[GRPCChannelRecord allocWithZone:zone] init]; + newRecord.channel = _channel; + newRecord.proxy = _proxy; + newRecord.timedDestroyDate = _timedDestroyDate; + newRecord.refcount = _refcount; + + return newRecord; +} + +@end + @implementation GRPCChannelPool { - NSMutableDictionary *_channelPool; + NSMutableDictionary *_channelPool; + dispatch_queue_t _dispatchQueue; } + (instancetype)sharedInstance { @@ -52,6 +194,18 @@ static dispatch_once_t gInitChannelPool; - (instancetype)init { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + } else { +#else + { +#endif + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } + _destroyDelay = kDefaultChannelDestroyDelay; // Connectivity monitor is not required for CFStream char *enableCFStream = getenv(kCFStreamVarName); @@ -62,51 +216,106 @@ static dispatch_once_t gInitChannelPool; return self; } -- (GRPCChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { - return [self channelWithHost:host callOptions:callOptions destroyDelay:0]; -} - -- (GRPCChannel *)channelWithHost:(NSString *)host - callOptions:(GRPCCallOptions *)callOptions - destroyDelay:(NSTimeInterval)destroyDelay { +- (GRPCPooledChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { NSAssert(host.length > 0, @"Host must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); if (host.length == 0) return nil; if (callOptions == nil) return nil; - GRPCChannel *channel; + GRPCPooledChannel *channelProxy = nil; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; @synchronized(self) { - channel = _channelPool[configuration]; - if (channel == nil || channel.disconnected) { - if (destroyDelay == 0) { - channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration]; - } else { - channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration - destroyDelay:destroyDelay]; + GRPCChannelRecord *record = _channelPool[configuration]; + if (record == nil) { + record = [[GRPCChannelRecord alloc] init]; + record.proxy = [[GRPCPooledChannel alloc] initWithChannelConfiguration:configuration + channelPool:self]; + record.timedDestroyDate = nil; + _channelPool[configuration] = record; + channelProxy = record.proxy; + } else { + channelProxy = record.proxy; + } + } + return channelProxy; +} + +- (void)closeOpenConnections { + [self disconnectAllChannels]; +} + +- (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { + GRPCChannel *ret = nil; + @synchronized (self) { + NSAssert(configuration != nil, @"configuration cannot be empty."); + if (configuration == nil) return nil; + + GRPCChannelRecord *record = _channelPool[configuration]; + NSAssert(record != nil, @"No record corresponding to a proxy."); + if (record == nil) return nil; + + if (record.channel == nil) { + // Channel is already destroyed; + record.channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration]; + record.timedDestroyDate = nil; + record.refcount = 1; + ret = record.channel; + } else { + ret = record.channel; + record.timedDestroyDate = nil; + record.refcount++; + } + } + return ret; +} + +- (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { + @synchronized (self) { + GRPCChannelRecord *record = _channelPool[configuration]; + NSAssert(record != nil, @"No record corresponding to a proxy."); + if (record == nil) return; + NSAssert(record.refcount > 0, @"Inconsistent channel refcount."); + if (record.refcount > 0) { + record.refcount--; + if (record.refcount == 0) { + NSDate *now = [NSDate date]; + record.timedDestroyDate = now; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_destroyDelay * NSEC_PER_SEC)), + _dispatchQueue, + ^{ + @synchronized (self) { + if (now == record.timedDestroyDate) { + // Destroy the raw channel and reset related records. + record.timedDestroyDate = nil; + record.refcount = 0; + record.channel = nil; + } + } + }); } - _channelPool[configuration] = channel; } } - return channel; } -+ (void)closeOpenConnections { - [[GRPCChannelPool sharedInstance] destroyAllChannels]; -} - -- (void)destroyAllChannels { - @synchronized(self) { - for (id key in _channelPool) { - [_channelPool[key] disconnect]; - } - _channelPool = [NSMutableDictionary dictionary]; +- (void)disconnectAllChannels { + NSMutableSet *proxySet = [NSMutableSet set]; + @synchronized (self) { + [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannelRecord * _Nonnull obj, BOOL * _Nonnull stop) { + obj.channel = nil; + obj.timedDestroyDate = nil; + obj.refcount = 0; + [proxySet addObject:obj.proxy]; + }]; } + // Disconnect proxies + [proxySet enumerateObjectsUsingBlock:^(GRPCPooledChannel * _Nonnull obj, BOOL * _Nonnull stop) { + [obj disconnect]; + }]; } - (void)connectivityChange:(NSNotification *)note { - [self destroyAllChannels]; + [self disconnectAllChannels]; } - (void)dealloc { diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index ae7f07f1192..5c402250ccf 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -238,7 +238,7 @@ @implementation GRPCWrappedCall { GRPCCompletionQueue *_queue; - GRPCChannel *_channel; + GRPCPooledChannel *_channel; grpc_call *_call; } @@ -257,21 +257,15 @@ // consuming too many threads and having contention of multiple calls in a single completion // queue. Currently we use a singleton queue. _queue = [GRPCCompletionQueue completionQueue]; - BOOL disconnected = NO; - do { - _channel = [[GRPCChannelPool sharedInstance] channelWithHost:host callOptions:callOptions]; - if (_channel == nil) { - NSAssert(_channel != nil, @"Failed to get a channel for the host."); - NSLog(@"Failed to get a channel for the host."); - return nil; - } - _call = [_channel unmanagedCallWithPath:path - completionQueue:_queue - callOptions:callOptions - disconnected:&disconnected]; - // Try create another channel if the current channel is disconnected (due to idleness or - // connectivity monitor disconnection). - } while (_call == NULL && disconnected); + _channel = [[GRPCChannelPool sharedInstance] channelWithHost:host callOptions:callOptions]; + if (_channel == nil) { + NSAssert(_channel != nil, @"Failed to get a channel for the host."); + NSLog(@"Failed to get a channel for the host."); + return nil; + } + _call = [_channel unmanagedCallWithPath:path + completionQueue:_queue + callOptions:callOptions]; if (_call == nil) { NSAssert(_channel != nil, @"Failed to get a channel for the host."); NSLog(@"Failed to create a call."); @@ -326,10 +320,7 @@ } - (void)dealloc { - if (_call) { - grpc_call_unref(_call); - } - [_channel unref]; + [_channel unrefUnmanagedCall:_call]; _channel = nil; } diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index b85e62feb5f..51819b12c2f 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -25,6 +25,8 @@ #define TEST_TIMEOUT 32 NSString *kDummyHost = @"dummy.host"; +NSString *kDummyHost2 = @"dummy.host.2"; +NSString *kDummyPath = @"/dummy/path"; @interface ChannelPoolTest : XCTestCase @@ -36,94 +38,156 @@ NSString *kDummyHost = @"dummy.host"; grpc_init(); } -- (void)testChannelPooling { - NSString *kDummyHost = @"dummy.host"; - NSString *kDummyHost2 = @"dummy.host2"; +- (void)testCreateChannelAndCall { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + XCTAssertNil(channel.wrappedChannel); + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + grpc_call *call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq callOptions:options]; + XCTAssert(call != NULL); + XCTAssertNotNil(channel.wrappedChannel); + [channel unrefUnmanagedCall:call]; + XCTAssertNil(channel.wrappedChannel); +} - GRPCMutableCallOptions *options1 = [[GRPCMutableCallOptions alloc] init]; +- (void)testCacheChannel { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCCallOptions *options1 = [[GRPCCallOptions alloc] init]; GRPCCallOptions *options2 = [options1 copy]; - GRPCMutableCallOptions *options3 = [options2 mutableCopy]; + GRPCMutableCallOptions *options3 = [options1 mutableCopy]; options3.transportType = GRPCTransportTypeInsecure; - - GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - - GRPCChannel *channel1 = [pool channelWithHost:kDummyHost callOptions:options1]; - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost callOptions:options2]; - GRPCChannel *channel3 = [pool channelWithHost:kDummyHost2 callOptions:options1]; - GRPCChannel *channel4 = [pool channelWithHost:kDummyHost callOptions:options3]; - XCTAssertEqual(channel1, channel2); - XCTAssertNotEqual(channel1, channel3); - XCTAssertNotEqual(channel1, channel4); - XCTAssertNotEqual(channel3, channel4); + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + GRPCPooledChannel *channel1 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options1]; + grpc_call *call1 = [channel1 unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options1]; + GRPCPooledChannel *channel2 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options2]; + grpc_call *call2 = [channel2 unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options2]; + GRPCPooledChannel *channel3 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options3]; + grpc_call *call3 = [channel3 unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options3]; + GRPCPooledChannel *channel4 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost2 + callOptions:options1]; + grpc_call *call4 = [channel4 unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options1]; + XCTAssertEqual(channel1.wrappedChannel, channel2.wrappedChannel); + XCTAssertNotEqual(channel1.wrappedChannel, channel3.wrappedChannel); + XCTAssertNotEqual(channel1.wrappedChannel, channel4.wrappedChannel); + XCTAssertNotEqual(channel3.wrappedChannel, channel4.wrappedChannel); + [channel1 unrefUnmanagedCall:call1]; + [channel2 unrefUnmanagedCall:call2]; + [channel3 unrefUnmanagedCall:call3]; + [channel4 unrefUnmanagedCall:call4]; } -- (void)testDestroyAllChannels { - NSString *kDummyHost = @"dummy.host"; +- (void)testTimedDestroyChannel { + const NSTimeInterval kDestroyDelay = 1.0; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = [pool channelWithHost:kDummyHost callOptions:options]; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - [pool destroyAllChannels]; - XCTAssertTrue(channel.disconnected); - GRPCChannel *channel2 = [pool channelWithHost:kDummyHost callOptions:options]; - XCTAssertNotEqual(channel, channel2); - grpc_call_unref(call); -} + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + pool.destroyDelay = kDestroyDelay; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + grpc_call *call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq callOptions:options]; + GRPCChannel *wrappedChannel = channel.wrappedChannel; -- (void)testGetChannelBeforeChannelTimedDisconnection { - NSString *kDummyHost = @"dummy.host"; - const NSTimeInterval kDestroyDelay = 1; + [channel unrefUnmanagedCall:call]; + // Confirm channel is not destroyed at this time + call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertEqual(wrappedChannel, channel.wrappedChannel); - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = - [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - grpc_call_unref(call); - [channel unref]; - - // Test that we can still get the channel at this time - GRPCChannel *channel2 = - [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; - XCTAssertEqual(channel, channel2); - call = [channel2 unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - - // Test that after the destroy delay, the channel is still alive + [channel unrefUnmanagedCall:call]; sleep(kDestroyDelay + 1); - XCTAssertFalse(channel.disconnected); + // Confirm channel is new at this time + call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); + + // Confirm the new channel can create call + call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssert(call != NULL); + [channel unrefUnmanagedCall:call]; } -- (void)testGetChannelAfterChannelTimedDisconnection { - NSString *kDummyHost = @"dummy.host"; - const NSTimeInterval kDestroyDelay = 1; +- (void)testPoolDisconnection { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + grpc_call *call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + GRPCChannel *wrappedChannel = channel.wrappedChannel; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - GRPCChannelPool *pool = [GRPCChannelPool sharedInstance]; - GRPCChannel *channel = - [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - grpc_call_unref(call); - [channel unref]; + // Test a new channel is created by requesting a channel from pool + [pool disconnectAllChannels]; + channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); + wrappedChannel = channel.wrappedChannel; - sleep(kDestroyDelay + 1); + // Test a new channel is created by requesting a new call from the previous proxy + [pool disconnectAllChannels]; + grpc_call *call2 = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); + [channel unrefUnmanagedCall:call]; + [channel unrefUnmanagedCall:call2]; +} - // Test that we get new channel to the same host and with the same callOptions - GRPCChannel *channel2 = - [pool channelWithHost:kDummyHost callOptions:options destroyDelay:kDestroyDelay]; - XCTAssertNotEqual(channel, channel2); +- (void)testUnrefCallFromStaleChannel { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + grpc_call *call = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + + [pool disconnectAllChannels]; + channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost + callOptions:options]; + + grpc_call *call2 = [channel unmanagedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + // Test unref the call of a stale channel will not cause the current channel going into timed + // destroy state + XCTAssertNotNil(channel.wrappedChannel); + GRPCChannel *wrappedChannel = channel.wrappedChannel; + [channel unrefUnmanagedCall:call]; + XCTAssertNotNil(channel.wrappedChannel); + XCTAssertEqual(wrappedChannel, channel.wrappedChannel); + // Test unref the call of the current channel will cause the channel going into timed destroy + // state + [channel unrefUnmanagedCall:call2]; + XCTAssertNil(channel.wrappedChannel); } @end diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 5daafcdf3f3..212db2f653a 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -20,8 +20,85 @@ #import "../../GRPCClient/GRPCCallOptions.h" #import "../../GRPCClient/private/GRPCChannel.h" +#import "../../GRPCClient/private/GRPCChannelPool.h" #import "../../GRPCClient/private/GRPCCompletionQueue.h" +/* +#define TEST_TIMEOUT 8 + +@interface GRPCChannelFake : NSObject + +- (instancetype)initWithCreateExpectation:(XCTestExpectation *)createExpectation + unrefExpectation:(XCTestExpectation *)unrefExpectation; + +- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions; + +- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall; + +@end + +@implementation GRPCChannelFake { + __weak XCTestExpectation *_createExpectation; + __weak XCTestExpectation *_unrefExpectation; + long _grpcCallCounter; +} + +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { + return nil; +} + +- (instancetype)initWithCreateExpectation:(XCTestExpectation *)createExpectation + unrefExpectation:(XCTestExpectation *)unrefExpectation { + if ((self = [super init])) { + _createExpectation = createExpectation; + _unrefExpectation = unrefExpectation; + _grpcCallCounter = 0; + } + return self; +} + +- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions { + if (_createExpectation) [_createExpectation fulfill]; + return (grpc_call *)(++_grpcCallCounter); +} + +- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall { + if (_unrefExpectation) [_unrefExpectation fulfill]; +} + +@end + +@interface GRPCChannelPoolFake : NSObject + +- (instancetype)initWithDelayedDestroyExpectation:(XCTestExpectation *)delayedDestroyExpectation; + +- (GRPCChannel *)rawChannelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; + +- (void)delayedDestroyChannel; + +@end + +@implementation GRPCChannelPoolFake { + __weak XCTestExpectation *_delayedDestroyExpectation; +} + +- (instancetype)initWithDelayedDestroyExpectation:(XCTestExpectation *)delayedDestroyExpectation { + if ((self = [super init])) { + _delayedDestroyExpectation = delayedDestroyExpectation; + } + return self; +} + +- (void)delayedDestroyChannel { + if (_delayedDestroyExpectation) [_delayedDestroyExpectation fulfill]; +} + +@end */ + @interface ChannelTests : XCTestCase @end @@ -32,53 +109,4 @@ grpc_init(); } -- (void)testTimedDisconnection { - NSString *const kHost = @"grpc-test.sandbox.googleapis.com"; - const NSTimeInterval kDestroyDelay = 1; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *configuration = - [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; - GRPCChannel *channel = - [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:kDestroyDelay]; - BOOL disconnected; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:&disconnected]; - XCTAssertFalse(disconnected); - grpc_call_unref(call); - [channel unref]; - XCTAssertFalse(channel.disconnected, @"Channel is pre-maturely disconnected."); - sleep(kDestroyDelay + 1); - XCTAssertTrue(channel.disconnected, @"Channel is not disconnected after delay."); - - // Check another call creation returns null and indicates disconnected. - call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:&disconnected]; - XCTAssert(call == NULL); - XCTAssertTrue(disconnected); -} - -- (void)testForceDisconnection { - NSString *const kHost = @"grpc-test.sandbox.googleapis.com"; - const NSTimeInterval kDestroyDelay = 1; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *configuration = - [[GRPCChannelConfiguration alloc] initWithHost:kHost callOptions:options]; - GRPCChannel *channel = - [[GRPCChannel alloc] initWithChannelConfiguration:configuration destroyDelay:kDestroyDelay]; - grpc_call *call = [channel unmanagedCallWithPath:@"dummy.path" - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:options - disconnected:nil]; - grpc_call_unref(call); - [channel disconnect]; - XCTAssertTrue(channel.disconnected, @"Channel is not disconnected."); - - // Test calling another unref here will not crash - [channel unref]; -} - @end From 680b53f7ad7c93947003dcf8d377f2b33c7623e9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 18 Nov 2018 23:00:08 -0800 Subject: [PATCH 0235/2143] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 4 +- src/objective-c/GRPCClient/GRPCCall.m | 59 +++++----- .../GRPCClient/private/GRPCChannel.h | 3 +- .../GRPCClient/private/GRPCChannel.m | 18 ++-- .../GRPCClient/private/GRPCChannelPool.h | 4 +- .../GRPCClient/private/GRPCChannelPool.m | 58 +++++----- .../private/GRPCCronetChannelFactory.m | 6 +- src/objective-c/GRPCClient/private/GRPCHost.m | 3 +- .../private/GRPCInsecureChannelFactory.m | 3 +- .../private/GRPCSecureChannelFactory.m | 15 ++- .../GRPCClient/private/GRPCWrappedCall.m | 7 +- .../GRPCClient/private/utilities.h | 3 +- src/objective-c/ProtoRPC/ProtoRPC.m | 50 ++++----- .../tests/ChannelTests/ChannelPoolTest.m | 102 ++++++++---------- .../tests/ChannelTests/ChannelTests.m | 4 +- src/objective-c/tests/InteropTests.m | 3 +- 16 files changed, 153 insertions(+), 189 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 7f80c17f1f3..4c8c11eded2 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -340,8 +340,8 @@ NS_ASSUME_NONNULL_END * and the port number, for example @"localhost:5050". */ - (null_unspecified instancetype)initWithHost:(null_unspecified NSString *)host - path:(null_unspecified NSString *)path - requestsWriter:(null_unspecified GRXWriter *)requestWriter; + path:(null_unspecified NSString *)path + requestsWriter:(null_unspecified GRXWriter *)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 6f4b1647a5a..94e470d4ed9 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -122,9 +122,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; responseHandler:(id)responseHandler callOptions:(GRPCCallOptions *)callOptions { NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, - @"Neither host nor path can be nil."); - NSAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, - @"Invalid call safety value."); + @"Neither host nor path can be nil."); + NSAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); NSAssert(responseHandler != nil, @"Response handler required."); if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { return nil; @@ -136,7 +135,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; return nil; } - if ((self = [super init])) { _requestOptions = [requestOptions copy]; if (callOptions == nil) { @@ -159,7 +157,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; #endif _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } - dispatch_set_target_queue(_dispatchQueue ,responseHandler.dispatchQueue); + dispatch_set_target_queue(_dispatchQueue, responseHandler.dispatchQueue); _started = NO; _canceled = NO; _finished = NO; @@ -176,7 +174,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)start { GRPCCall *call = nil; - @synchronized (self) { + @synchronized(self) { NSAssert(!_started, @"Call already started."); NSAssert(!_canceled, @"Call already canceled."); if (_started) { @@ -192,10 +190,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; } _call = [[GRPCCall alloc] initWithHost:_requestOptions.host - path:_requestOptions.path - callSafety:_requestOptions.safety - requestsWriter:_pipe - callOptions:_callOptions]; + path:_requestOptions.path + callSafety:_requestOptions.safety + requestsWriter:_pipe + callOptions:_callOptions]; if (_callOptions.initialMetadata) { [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata]; } @@ -203,7 +201,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } void (^valueHandler)(id value) = ^(id value) { - @synchronized (self) { + @synchronized(self) { if (self->_handler) { if (!self->_initialMetadataPublished) { self->_initialMetadataPublished = YES; @@ -223,7 +221,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self issueInitialMetadata:self->_call.responseHeaders]; } [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; - } // Clearing _call must happen *after* dispatching close in order to get trailing // metadata from _call. @@ -237,14 +234,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; } }; id responseWriteable = - [[GRXWriteable alloc] initWithValueHandler:valueHandler - completionHandler:completionHandler]; + [[GRXWriteable alloc] initWithValueHandler:valueHandler completionHandler:completionHandler]; [call startWithWriteable:responseWriteable]; } - (void)cancel { GRPCCall *call = nil; - @synchronized (self) { + @synchronized(self) { if (_canceled) { return; } @@ -259,7 +255,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_async(_dispatchQueue, ^{ // Copy to local so that block is freed after cancellation completes. id copiedHandler = nil; - @synchronized (self) { + @synchronized(self) { copiedHandler = self->_handler; self->_handler = nil; } @@ -268,9 +264,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; }); } } @@ -322,11 +318,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { - @synchronized (self) { - if (initialMetadata != nil && [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + @synchronized(self) { + if (initialMetadata != nil && + [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; } [handler receivedInitialMetadata:initialMetadata]; @@ -336,11 +333,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueMessage:(id)message { - @synchronized (self) { + @synchronized(self) { if (message != nil && [_handler respondsToSelector:@selector(receivedRawMessage:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; } [handler receivedRawMessage:message]; @@ -350,17 +347,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - @synchronized (self) { + @synchronized(self) { if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; } - [handler closedWithTrailingMetadata:trailingMetadata - error:error]; + [handler closedWithTrailingMetadata:trailingMetadata error:error]; }); } } @@ -489,10 +485,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. NSAssert(host != nil && path != nil, @"Neither host nor path can be nil."); - NSAssert(safety <= GRPCCallSafetyCacheableRequest, - @"Invalid call safety value."); + NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); NSAssert(requestWriter.state == GRXWriterStateNotStarted, - @"The requests writer can't be already started."); + @"The requests writer can't be already started."); if (!host || !path) { return nil; } @@ -888,7 +883,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } NSAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, - @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); + @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); if (_callOptions.authTokenProvider != nil) { @synchronized(self) { self.isWaitingForToken = YES; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index de6d1bf4a24..5426b28d758 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -64,8 +64,7 @@ NS_ASSUME_NONNULL_BEGIN * Create a channel with remote \a host and signature \a channelConfigurations. */ - (nullable instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration - NS_DESIGNATED_INITIALIZER; + (GRPCChannelConfiguration *)channelConfiguration NS_DESIGNATED_INITIALIZER; /** * Create a grpc core call object (grpc_call) from this channel. If no call is created, NULL is diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 81e53d48e34..e4cefc338c6 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -178,10 +178,8 @@ grpc_channel *_unmanagedChannel; } -- (instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration { - NSAssert(channelConfiguration != nil, - @"channelConfiguration must not be empty."); +- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { + NSAssert(channelConfiguration != nil, @"channelConfiguration must not be empty."); if (channelConfiguration == nil) return nil; if ((self = [super init])) { @@ -221,12 +219,11 @@ grpc_call *call = NULL; @synchronized(self) { - NSAssert(_unmanagedChannel != NULL, - @"Channel should have valid unmanaged channel."); + NSAssert(_unmanagedChannel != NULL, @"Channel should have valid unmanaged channel."); if (_unmanagedChannel == NULL) return NULL; NSString *serverAuthority = - callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); if (timeout < 0) return NULL; @@ -236,10 +233,9 @@ } grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); gpr_timespec deadline_ms = - timeout == 0 - ? gpr_inf_future(GPR_CLOCK_REALTIME) - : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME) + : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, serverAuthority ? &host_slice : NULL, deadline_ms, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 887bd5f89f7..1e3c1d7d976 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -42,10 +42,10 @@ NS_ASSUME_NONNULL_BEGIN /** * Initialize with an actual channel object \a channel and a reference to the channel pool. */ -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration channelPool:(GRPCChannelPool *)channelPool; - /** * Create a grpc core call object (grpc_call) from this channel. If channel is disconnected, get a * new channel object from the channel pool. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 92dd4c86aee..7c139b37176 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -40,7 +40,7 @@ static dispatch_once_t gInitChannelPool; /** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; -@interface GRPCChannelPool() +@interface GRPCChannelPool () - (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; @@ -74,7 +74,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (grpc_call *)unmanagedCallWithPath:(NSString *)path - completionQueue:(GRPCCompletionQueue *)queue + completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions { NSAssert(path.length > 0, @"path must not be empty."); NSAssert(queue != nil, @"completionQueue must not be empty."); @@ -90,7 +90,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } NSAssert(_wrappedChannel != nil, @"Unable to get a raw channel for proxy."); } - call = [_wrappedChannel unmanagedCallWithPath:path completionQueue:queue callOptions:callOptions]; + call = + [_wrappedChannel unmanagedCallWithPath:path completionQueue:queue callOptions:callOptions]; if (call != NULL) { [_unmanagedCalls addObject:[NSValue valueWithPointer:call]]; } @@ -100,7 +101,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall { if (unmanagedCall == nil) return; - + grpc_call_unref(unmanagedCall); BOOL timedDestroy = NO; @synchronized(self) { @@ -125,7 +126,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (GRPCChannel *)wrappedChannel { GRPCChannel *channel = nil; - @synchronized (self) { + @synchronized(self) { channel = _wrappedChannel; } return channel; @@ -148,7 +149,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; /** * A convenience value type for cached channel. */ -@interface GRPCChannelRecord : NSObject +@interface GRPCChannelRecord : NSObject /** Pointer to the raw channel. May be nil when the channel has been destroyed. */ @property GRPCChannel *channel; @@ -197,14 +198,14 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 if (@available(iOS 8.0, macOS 10.10, *)) { _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { #else - { + { #endif - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - } + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } _destroyDelay = kDefaultChannelDestroyDelay; // Connectivity monitor is not required for CFStream @@ -221,7 +222,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSAssert(callOptions != nil, @"callOptions must not be empty."); if (host.length == 0) return nil; if (callOptions == nil) return nil; - + GRPCPooledChannel *channelProxy = nil; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; @@ -229,8 +230,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; GRPCChannelRecord *record = _channelPool[configuration]; if (record == nil) { record = [[GRPCChannelRecord alloc] init]; - record.proxy = [[GRPCPooledChannel alloc] initWithChannelConfiguration:configuration - channelPool:self]; + record.proxy = + [[GRPCPooledChannel alloc] initWithChannelConfiguration:configuration channelPool:self]; record.timedDestroyDate = nil; _channelPool[configuration] = record; channelProxy = record.proxy; @@ -247,7 +248,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { GRPCChannel *ret = nil; - @synchronized (self) { + @synchronized(self) { NSAssert(configuration != nil, @"configuration cannot be empty."); if (configuration == nil) return nil; @@ -271,7 +272,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { - @synchronized (self) { + @synchronized(self) { GRPCChannelRecord *record = _channelPool[configuration]; NSAssert(record != nil, @"No record corresponding to a proxy."); if (record == nil) return; @@ -282,9 +283,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; NSDate *now = [NSDate date]; record.timedDestroyDate = now; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_destroyDelay * NSEC_PER_SEC)), - _dispatchQueue, - ^{ - @synchronized (self) { + _dispatchQueue, ^{ + @synchronized(self) { if (now == record.timedDestroyDate) { // Destroy the raw channel and reset related records. record.timedDestroyDate = nil; @@ -292,7 +292,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; record.channel = nil; } } - }); + }); } } } @@ -300,16 +300,18 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (void)disconnectAllChannels { NSMutableSet *proxySet = [NSMutableSet set]; - @synchronized (self) { - [_channelPool enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration * _Nonnull key, GRPCChannelRecord * _Nonnull obj, BOOL * _Nonnull stop) { - obj.channel = nil; - obj.timedDestroyDate = nil; - obj.refcount = 0; - [proxySet addObject:obj.proxy]; - }]; + @synchronized(self) { + [_channelPool + enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, + GRPCChannelRecord *_Nonnull obj, BOOL *_Nonnull stop) { + obj.channel = nil; + obj.timedDestroyDate = nil; + obj.refcount = 0; + [proxySet addObject:obj.proxy]; + }]; } // Disconnect proxies - [proxySet enumerateObjectsUsingBlock:^(GRPCPooledChannel * _Nonnull obj, BOOL * _Nonnull stop) { + [proxySet enumerateObjectsUsingBlock:^(GRPCPooledChannel *_Nonnull obj, BOOL *_Nonnull stop) { [obj disconnect]; }]; } diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 74ea9723b3d..0aeb67b1426 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -50,8 +50,7 @@ return self; } -- (grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { grpc_channel_args *channelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_cronet_secure_channel_create(_cronetEngine, host.UTF8String, channelArgs, NULL); @@ -71,8 +70,7 @@ return nil; } -- (grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { [NSException raise:NSInvalidArgumentException format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; return NULL; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index b693b926bad..0f2281ede85 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -122,8 +122,7 @@ static NSMutableDictionary *gHostCache; if (_transportType == GRPCTransportTypeInsecure) { options.transportType = GRPCTransportTypeInsecure; } else { - NSAssert(_transportType == GRPCTransportTypeDefault, - @"Invalid transport type"); + NSAssert(_transportType == GRPCTransportTypeDefault, @"Invalid transport type"); options.transportType = GRPCTransportTypeCronet; } } else diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index 3e9ebe7ae02..b802137c13a 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -32,8 +32,7 @@ return instance; } -- (grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 2e7f1a0dbe2..69f70de17d1 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -29,9 +29,9 @@ } + (instancetype)factoryWithPEMRootCertificates:(NSString *)rootCerts - privateKey:(NSString *)privateKey - certChain:(NSString *)certChain - error:(NSError **)errorPtr { + privateKey:(NSString *)privateKey + certChain:(NSString *)certChain + error:(NSError **)errorPtr { return [[self alloc] initWithPEMRootCerts:rootCerts privateKey:privateKey certChain:certChain @@ -50,9 +50,9 @@ } - (instancetype)initWithPEMRootCerts:(NSString *)rootCerts - privateKey:(NSString *)privateKey - certChain:(NSString *)certChain - error:(NSError **)errorPtr { + privateKey:(NSString *)privateKey + certChain:(NSString *)certChain + error:(NSError **)errorPtr { static NSData *defaultRootsASCII; static NSError *defaultRootsError; static dispatch_once_t loading; @@ -115,8 +115,7 @@ return self; } -- (grpc_channel *)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)args { +- (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 5c402250ccf..615dfc85569 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -249,8 +249,7 @@ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path callOptions:(GRPCCallOptions *)callOptions { - NSAssert(host.length != 0 && path.length != 0, - @"path and host cannot be nil."); + NSAssert(host.length != 0 && path.length != 0, @"path and host cannot be nil."); if ((self = [super init])) { // Each completion queue consumes one thread. There's a trade to be made between creating and @@ -263,9 +262,7 @@ NSLog(@"Failed to get a channel for the host."); return nil; } - _call = [_channel unmanagedCallWithPath:path - completionQueue:_queue - callOptions:callOptions]; + _call = [_channel unmanagedCallWithPath:path completionQueue:_queue callOptions:callOptions]; if (_call == nil) { NSAssert(_channel != nil, @"Failed to get a channel for the host."); NSLog(@"Failed to create a call."); diff --git a/src/objective-c/GRPCClient/private/utilities.h b/src/objective-c/GRPCClient/private/utilities.h index 8f6baadcf7b..8e3dd793586 100644 --- a/src/objective-c/GRPCClient/private/utilities.h +++ b/src/objective-c/GRPCClient/private/utilities.h @@ -19,5 +19,4 @@ #import /** Raise exception when condition not met. */ -#define GRPCAssert(condition, errorString) \ - NSAssert(condition, errorString) +#define GRPCAssert(condition, errorString) NSAssert(condition, errorString) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 9164f2320bf..2de2932072a 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -138,21 +138,21 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing call = _call; _call = nil; if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { - dispatch_async(_handler.dispatchQueue, ^{ - id handler = nil; - @synchronized(self) { - handler = self->_handler; - self->_handler = nil; - } - [handler closedWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; - }); - } + dispatch_async(_handler.dispatchQueue, ^{ + id handler = nil; + @synchronized(self) { + handler = self->_handler; + self->_handler = nil; + } + [handler closedWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + }); + } } [call cancel]; } @@ -179,11 +179,11 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { - @synchronized (self) { + @synchronized(self) { if (initialMetadata != nil && [_handler respondsToSelector:@selector(initialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; } [handler receivedInitialMetadata:initialMetadata]; @@ -197,19 +197,20 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing NSError *error = nil; GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; - @synchronized (self) { + @synchronized(self) { if (parsed && [_handler respondsToSelector:@selector(receivedProtoMessage:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; } [handler receivedProtoMessage:parsed]; }); - } else if (!parsed && [_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]){ + } else if (!parsed && + [_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; self->_handler = nil; } @@ -222,13 +223,12 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata - error:(NSError *)error { - @synchronized (self) { +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + @synchronized(self) { if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ id handler = nil; - @synchronized (self) { + @synchronized(self) { handler = self->_handler; self->_handler = nil; } diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index 51819b12c2f..4424801c110 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -41,12 +41,12 @@ NSString *kDummyPath = @"/dummy/path"; - (void)testCreateChannelAndCall { GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options]; + GRPCPooledChannel *channel = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; XCTAssertNil(channel.wrappedChannel); GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq callOptions:options]; + grpc_call *call = + [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssert(call != NULL); XCTAssertNotNil(channel.wrappedChannel); [channel unrefUnmanagedCall:call]; @@ -60,26 +60,22 @@ NSString *kDummyPath = @"/dummy/path"; GRPCMutableCallOptions *options3 = [options1 mutableCopy]; options3.transportType = GRPCTransportTypeInsecure; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - GRPCPooledChannel *channel1 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options1]; - grpc_call *call1 = [channel1 unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options1]; - GRPCPooledChannel *channel2 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options2]; - grpc_call *call2 = [channel2 unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options2]; - GRPCPooledChannel *channel3 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options3]; - grpc_call *call3 = [channel3 unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options3]; - GRPCPooledChannel *channel4 = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost2 - callOptions:options1]; - grpc_call *call4 = [channel4 unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options1]; + GRPCPooledChannel *channel1 = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options1]; + grpc_call *call1 = + [channel1 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options1]; + GRPCPooledChannel *channel2 = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options2]; + grpc_call *call2 = + [channel2 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options2]; + GRPCPooledChannel *channel3 = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options3]; + grpc_call *call3 = + [channel3 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options3]; + GRPCPooledChannel *channel4 = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost2 callOptions:options1]; + grpc_call *call4 = + [channel4 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options1]; XCTAssertEqual(channel1.wrappedChannel, channel2.wrappedChannel); XCTAssertNotEqual(channel1.wrappedChannel, channel3.wrappedChannel); XCTAssertNotEqual(channel1.wrappedChannel, channel4.wrappedChannel); @@ -96,32 +92,26 @@ NSString *kDummyPath = @"/dummy/path"; GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; pool.destroyDelay = kDestroyDelay; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options]; + GRPCPooledChannel *channel = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq callOptions:options]; + grpc_call *call = + [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; GRPCChannel *wrappedChannel = channel.wrappedChannel; [channel unrefUnmanagedCall:call]; // Confirm channel is not destroyed at this time - call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertEqual(wrappedChannel, channel.wrappedChannel); [channel unrefUnmanagedCall:call]; sleep(kDestroyDelay + 1); // Confirm channel is new at this time - call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); // Confirm the new channel can create call - call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssert(call != NULL); [channel unrefUnmanagedCall:call]; } @@ -129,31 +119,26 @@ NSString *kDummyPath = @"/dummy/path"; - (void)testPoolDisconnection { GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options]; + GRPCPooledChannel *channel = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + grpc_call *call = + [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); GRPCChannel *wrappedChannel = channel.wrappedChannel; // Test a new channel is created by requesting a channel from pool [pool disconnectAllChannels]; - channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options]; - call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; + call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); wrappedChannel = channel.wrappedChannel; // Test a new channel is created by requesting a new call from the previous proxy [pool disconnectAllChannels]; - grpc_call *call2 = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + grpc_call *call2 = + [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); [channel unrefUnmanagedCall:call]; @@ -163,20 +148,17 @@ NSString *kDummyPath = @"/dummy/path"; - (void)testUnrefCallFromStaleChannel { GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options]; + GRPCPooledChannel *channel = + (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + grpc_call *call = + [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; [pool disconnectAllChannels]; - channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost - callOptions:options]; + channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - grpc_call *call2 = [channel unmanagedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + grpc_call *call2 = + [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; // Test unref the call of a stale channel will not cause the current channel going into timed // destroy state XCTAssertNotNil(channel.wrappedChannel); diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 212db2f653a..c07c8e69834 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -45,8 +45,8 @@ long _grpcCallCounter; } -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { - return nil; +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration +*)channelConfiguration { return nil; } - (instancetype)initWithCreateExpectation:(XCTestExpectation *)createExpectation diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 8754bd5ccaf..a9f33aab6f1 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -114,8 +114,7 @@ BOOL isRemoteInteropTest(NSString *host) { } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata - error:(NSError *)error { +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { if (_closeCallback) { _closeCallback(trailingMetadata, error); } From 00ff5805a3c00e9d29cb71dfd5365c36dd5bf96c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 09:43:24 -0800 Subject: [PATCH 0236/2143] null_unspecified -> nullable --- src/objective-c/GRPCClient/GRPCCall.h | 26 +++++++++++++------------- src/objective-c/ProtoRPC/ProtoRPC.h | 10 +++++----- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 4c8c11eded2..214969af230 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -306,7 +306,7 @@ NS_ASSUME_NONNULL_END * * The property is initialized to an empty NSMutableDictionary. */ -@property(null_unspecified, atomic, readonly) NSMutableDictionary *requestHeaders; +@property(nullable, atomic, readonly) NSMutableDictionary *requestHeaders; /** * This dictionary is populated with the HTTP headers received from the server. This happens before @@ -317,7 +317,7 @@ NS_ASSUME_NONNULL_END * The value of this property is nil until all response headers are received, and will change before * any of -writeValue: or -writesFinishedWithError: are sent to the writeable. */ -@property(null_unspecified, atomic, readonly) NSDictionary *responseHeaders; +@property(nullable, atomic, readonly) NSDictionary *responseHeaders; /** * Same as responseHeaders, but populated with the HTTP trailers received from the server before the @@ -326,7 +326,7 @@ NS_ASSUME_NONNULL_END * The value of this property is nil until all response trailers are received, and will change * before -writesFinishedWithError: is sent to the writeable. */ -@property(null_unspecified, atomic, readonly) NSDictionary *responseTrailers; +@property(nullable, atomic, readonly) NSDictionary *responseTrailers; /** * The request writer has to write NSData objects into the provided Writeable. The server will @@ -339,9 +339,9 @@ NS_ASSUME_NONNULL_END * host parameter should not contain the scheme (http:// or https://), only the name or IP addr * and the port number, for example @"localhost:5050". */ -- (null_unspecified instancetype)initWithHost:(null_unspecified NSString *)host - path:(null_unspecified NSString *)path - requestsWriter:(null_unspecified GRXWriter *)requestWriter; +- (nullable instancetype)initWithHost:(nullable NSString *)host + path:(nullable NSString *)path + requestsWriter:(nullable GRXWriter *)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -353,11 +353,11 @@ NS_ASSUME_NONNULL_END * The following methods are deprecated. */ + (void)setCallSafety:(GRPCCallSafety)callSafety - host:(null_unspecified NSString *)host - path:(null_unspecified NSString *)path; -@property(null_unspecified, atomic, copy, readwrite) NSString *serverName; + host:(nullable NSString *)host + path:(nullable NSString *)path; +@property(nullable, atomic, copy, readwrite) NSString *serverName; @property NSTimeInterval timeout; -- (void)setResponseDispatchQueue:(null_unspecified dispatch_queue_t)queue; +- (void)setResponseDispatchQueue:(nullable dispatch_queue_t)queue; @end @@ -368,11 +368,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (null_unspecified id)objectForKeyedSubscript:(null_unspecified id)key; -- (void)setObject:(null_unspecified id)obj forKeyedSubscript:(null_unspecified id)key; +- (nullable id)objectForKeyedSubscript:(nullable id)key; +- (void)setObject:(nullable id)obj forKeyedSubscript:(nullable id)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(null_unspecified id)key; +- (void)removeObjectForKey:(nullable id)key; @end #pragma clang diagnostic push diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 98b60c3f727..2623aecb82f 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -132,11 +132,11 @@ __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC * addr and the port number, for example @"localhost:5050". */ - - (instancetype _Null_unspecified)initWithHost : (NSString *_Null_unspecified)host method - : (GRPCProtoMethod *_Null_unspecified)method requestsWriter - : (GRXWriter *_Null_unspecified)requestsWriter responseClass - : (Class _Null_unspecified)responseClass responsesWriteable - : (id _Null_unspecified)responsesWriteable NS_DESIGNATED_INITIALIZER; + (nullable instancetype)initWithHost : (nullable NSString *)host method + : (nullable GRPCProtoMethod *)method requestsWriter + : (nullable GRXWriter *)requestsWriter responseClass + : (nullable Class)responseClass responsesWriteable + : (nullable id)responsesWriteable NS_DESIGNATED_INITIALIZER; - (void)start; @end From 29e1591904539fcb6d92ba49e69ed27ee9d3349d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 09:52:29 -0800 Subject: [PATCH 0237/2143] _Nullable -> nullable --- .../GRPCClient/private/GRPCCronetChannelFactory.h | 8 ++++---- .../GRPCClient/private/GRPCInsecureChannelFactory.h | 8 ++++---- .../GRPCClient/private/GRPCSecureChannelFactory.h | 12 ++++++------ src/objective-c/tests/APIv2Tests/APIv2Tests.m | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h index 5e35576ea10..738dfdb7370 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h @@ -24,12 +24,12 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCCronetChannelFactory : NSObject -+ (instancetype _Nullable)sharedInstance; ++ (nullable instancetype)sharedInstance; -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args; +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSDictionary *)args; -- (instancetype _Nullable)init NS_UNAVAILABLE; +- (nullable instancetype)init NS_UNAVAILABLE; @end diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h index 98a985fe84d..2d471aebed6 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h @@ -23,12 +23,12 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCInsecureChannelFactory : NSObject -+ (instancetype _Nullable)sharedInstance; ++ (nullable instancetype)sharedInstance; -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args; +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSDictionary *)args; -- (instancetype _Nullable)init NS_UNAVAILABLE; +- (nullable instancetype)init NS_UNAVAILABLE; @end diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h index 02e7052996d..5dc5a973120 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -23,15 +23,15 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCSecureChannelFactory : NSObject -+ (instancetype _Nullable)factoryWithPEMRootCertificates:(NSString *_Nullable)rootCerts - privateKey:(NSString *_Nullable)privateKey - certChain:(NSString *_Nullable)certChain ++ (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain error:(NSError **)errorPtr; -- (grpc_channel *_Nullable)createChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *_Nullable)args; +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSDictionary *)args; -- (instancetype _Nullable)init NS_UNAVAILABLE; +- (nullable instancetype)init NS_UNAVAILABLE; @end diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index e49f58ae9d3..1b14043af92 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -81,20 +81,20 @@ static const NSTimeInterval kTestTimeout = 16; return self; } -- (void)receivedInitialMetadata:(NSDictionary *_Nullable)initialMetadata { +- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { if (self->_initialMetadataCallback) { self->_initialMetadataCallback(initialMetadata); } } -- (void)receivedRawMessage:(GPBMessage *_Nullable)message { +- (void)receivedRawMessage:(GPBMessage *)message { if (self->_messageCallback) { self->_messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary *_Nullable)trailingMetadata - error:(NSError *_Nullable)error { +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata + error:(NSError *)error { if (self->_closeCallback) { self->_closeCallback(trailingMetadata, error); } From d806ce71d762a1a2fc03e41cc186d002ee604316 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 10:08:23 -0800 Subject: [PATCH 0238/2143] more nullability --- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- .../GRPCClient/private/GRPCSecureChannelFactory.h | 6 +++--- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 61d85642863..e88e28109cf 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -64,7 +64,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)getTokenWithHandler:(void (^)(NSString *token))handler; +- (void)getTokenWithHandler:(void (^)(NSString * _Nullable token))handler; @end @interface GRPCCallOptions : NSObject diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h index 5dc5a973120..588239b7064 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -24,9 +24,9 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCSecureChannelFactory : NSObject + (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts - privateKey:(nullable NSString *)privateKey - certChain:(nullable NSString *)certChain - error:(NSError **)errorPtr; + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain + error:(NSError **)errorPtr; - (nullable grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(nullable NSDictionary *)args; diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index 1b14043af92..32f2122f79b 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -93,8 +93,7 @@ static const NSTimeInterval kTestTimeout = 16; } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata - error:(NSError *)error { +- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { if (self->_closeCallback) { self->_closeCallback(trailingMetadata, error); } From 1d8550c4c27ca357195946759f161942a6e07589 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 11:26:24 -0800 Subject: [PATCH 0239/2143] nit nullability fix --- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index e88e28109cf..48bb11aeeb0 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -64,7 +64,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)getTokenWithHandler:(void (^)(NSString * _Nullable token))handler; +- (void)getTokenWithHandler:(void (^ _Nullable)(NSString * _Nullable token))handler; @end @interface GRPCCallOptions : NSObject From be5eea1f42de9cc108d589361783b9996024ffd3 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 19 Nov 2018 12:31:21 -0800 Subject: [PATCH 0240/2143] Extend ev_posix.* to prepare for the new background poller 'epollbg', and get rid of the dependency loop on the grpc shutdown path. Make sure all background closures are complete before shutting down the other grpc modules. Avoid using the backup poller in TCP endpoints if using the background poller. --- src/core/lib/iomgr/ev_epoll1_linux.cc | 4 ++++ src/core/lib/iomgr/ev_epollex_linux.cc | 4 ++++ src/core/lib/iomgr/ev_poll_posix.cc | 4 ++++ src/core/lib/iomgr/ev_posix.cc | 8 ++++++++ src/core/lib/iomgr/ev_posix.h | 10 ++++++++++ src/core/lib/iomgr/iomgr.cc | 4 ++++ src/core/lib/iomgr/iomgr.h | 4 ++++ src/core/lib/iomgr/iomgr_custom.cc | 4 +++- src/core/lib/iomgr/iomgr_internal.cc | 4 ++++ src/core/lib/iomgr/iomgr_internal.h | 4 ++++ src/core/lib/iomgr/iomgr_posix.cc | 7 ++++++- src/core/lib/iomgr/iomgr_posix_cfstream.cc | 7 ++++++- src/core/lib/iomgr/tcp_posix.cc | 15 +++++++++++---- src/core/lib/surface/init.cc | 1 + 14 files changed, 73 insertions(+), 7 deletions(-) diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index 38571b1957b..4b8c891e9b0 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -1242,6 +1242,8 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag, * Event engine binding */ +static void shutdown_background_closure(void) {} + static void shutdown_engine(void) { fd_global_shutdown(); pollset_global_shutdown(); @@ -1255,6 +1257,7 @@ static void shutdown_engine(void) { static const grpc_event_engine_vtable vtable = { sizeof(grpc_pollset), true, + false, fd_create, fd_wrapped_fd, @@ -1284,6 +1287,7 @@ static const grpc_event_engine_vtable vtable = { pollset_set_add_fd, pollset_set_del_fd, + shutdown_background_closure, shutdown_engine, }; diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index 06a382c5560..7a4870db785 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -1604,6 +1604,8 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag, * Event engine binding */ +static void shutdown_background_closure(void) {} + static void shutdown_engine(void) { fd_global_shutdown(); pollset_global_shutdown(); @@ -1612,6 +1614,7 @@ static void shutdown_engine(void) { static const grpc_event_engine_vtable vtable = { sizeof(grpc_pollset), true, + false, fd_create, fd_wrapped_fd, @@ -1641,6 +1644,7 @@ static const grpc_event_engine_vtable vtable = { pollset_set_add_fd, pollset_set_del_fd, + shutdown_background_closure, shutdown_engine, }; diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc index 16562538a63..67cbfbbd021 100644 --- a/src/core/lib/iomgr/ev_poll_posix.cc +++ b/src/core/lib/iomgr/ev_poll_posix.cc @@ -1782,6 +1782,8 @@ static void global_cv_fd_table_shutdown() { * event engine binding */ +static void shutdown_background_closure(void) {} + static void shutdown_engine(void) { pollset_global_shutdown(); if (grpc_cv_wakeup_fds_enabled()) { @@ -1796,6 +1798,7 @@ static void shutdown_engine(void) { static const grpc_event_engine_vtable vtable = { sizeof(grpc_pollset), false, + false, fd_create, fd_wrapped_fd, @@ -1825,6 +1828,7 @@ static const grpc_event_engine_vtable vtable = { pollset_set_add_fd, pollset_set_del_fd, + shutdown_background_closure, shutdown_engine, }; diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 8a7dc7b004a..c876eb08c55 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -244,6 +244,10 @@ bool grpc_event_engine_can_track_errors(void) { #endif /* GRPC_LINUX_ERRQUEUE */ } +bool grpc_event_engine_run_in_background(void) { + return g_event_engine->run_in_background; +} + grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) { GRPC_POLLING_API_TRACE("fd_create(%d, %s, %d)", fd, name, track_err); GRPC_FD_TRACE("fd_create(%d, %s, %d)", fd, name, track_err); @@ -395,4 +399,8 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) { g_event_engine->pollset_set_del_fd(pollset_set, fd); } +void grpc_shutdown_background_closure(void) { + g_event_engine->shutdown_background_closure(); +} + #endif // GRPC_POSIX_SOCKET_EV diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h index b8fb8f534b4..812c7a0f0f8 100644 --- a/src/core/lib/iomgr/ev_posix.h +++ b/src/core/lib/iomgr/ev_posix.h @@ -42,6 +42,7 @@ typedef struct grpc_fd grpc_fd; typedef struct grpc_event_engine_vtable { size_t pollset_size; bool can_track_err; + bool run_in_background; grpc_fd* (*fd_create)(int fd, const char* name, bool track_err); int (*fd_wrapped_fd)(grpc_fd* fd); @@ -79,6 +80,7 @@ typedef struct grpc_event_engine_vtable { void (*pollset_set_add_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd); void (*pollset_set_del_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd); + void (*shutdown_background_closure)(void); void (*shutdown_engine)(void); } grpc_event_engine_vtable; @@ -101,6 +103,11 @@ const char* grpc_get_poll_strategy_name(); */ bool grpc_event_engine_can_track_errors(); +/* Returns true if polling engine runs in the background, false otherwise. + * Currently only 'epollbg' runs in the background. + */ +bool grpc_event_engine_run_in_background(); + /* Create a wrapped file descriptor. Requires fd is a non-blocking file descriptor. \a track_err if true means that error events would be tracked separately @@ -174,6 +181,9 @@ void grpc_pollset_add_fd(grpc_pollset* pollset, struct grpc_fd* fd); void grpc_pollset_set_add_fd(grpc_pollset_set* pollset_set, grpc_fd* fd); void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd); +/* Shut down all the closures registered in the background poller. */ +void grpc_shutdown_background_closure(); + /* override to allow tests to hook poll() usage */ typedef int (*grpc_poll_function_type)(struct pollfd*, nfds_t, int); extern grpc_poll_function_type grpc_poll_function; diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index 46afda17742..7d2fa09d085 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -154,6 +154,10 @@ void grpc_iomgr_shutdown() { gpr_cv_destroy(&g_rcv); } +void grpc_iomgr_shutdown_background_closure() { + grpc_iomgr_platform_shutdown_background_closure(); +} + 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 537ef8a6ffe..8ea9289e068 100644 --- a/src/core/lib/iomgr/iomgr.h +++ b/src/core/lib/iomgr/iomgr.h @@ -35,6 +35,10 @@ void grpc_iomgr_start(); * exec_ctx. */ void grpc_iomgr_shutdown(); +/** Signals the intention to shutdown all the closures registered in the + * background poller. */ +void grpc_iomgr_shutdown_background_closure(); + /* 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 d34c8e7cd14..4b112c9097f 100644 --- a/src/core/lib/iomgr/iomgr_custom.cc +++ b/src/core/lib/iomgr/iomgr_custom.cc @@ -40,9 +40,11 @@ static void iomgr_platform_init(void) { } static void iomgr_platform_flush(void) {} static void iomgr_platform_shutdown(void) { grpc_pollset_global_shutdown(); } +static void iomgr_platform_shutdown_background_closure(void) {} 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}; 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 32dbabb79dc..b6c9211865d 100644 --- a/src/core/lib/iomgr/iomgr_internal.cc +++ b/src/core/lib/iomgr/iomgr_internal.cc @@ -41,3 +41,7 @@ void grpc_iomgr_platform_init() { iomgr_platform_vtable->init(); } void grpc_iomgr_platform_flush() { iomgr_platform_vtable->flush(); } void grpc_iomgr_platform_shutdown() { iomgr_platform_vtable->shutdown(); } + +void grpc_iomgr_platform_shutdown_background_closure() { + iomgr_platform_vtable->shutdown_background_closure(); +} diff --git a/src/core/lib/iomgr/iomgr_internal.h b/src/core/lib/iomgr/iomgr_internal.h index b011d9c7b19..bca7409907f 100644 --- a/src/core/lib/iomgr/iomgr_internal.h +++ b/src/core/lib/iomgr/iomgr_internal.h @@ -35,6 +35,7 @@ typedef struct grpc_iomgr_platform_vtable { void (*init)(void); void (*flush)(void); void (*shutdown)(void); + void (*shutdown_background_closure)(void); } grpc_iomgr_platform_vtable; void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name); @@ -52,6 +53,9 @@ void grpc_iomgr_platform_flush(void); /** tear down all platform specific global iomgr structures */ void grpc_iomgr_platform_shutdown(void); +/** shut down all the closures registered in the background poller */ +void grpc_iomgr_platform_shutdown_background_closure(void); + 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 ca7334c9a4b..9386adf060d 100644 --- a/src/core/lib/iomgr/iomgr_posix.cc +++ b/src/core/lib/iomgr/iomgr_posix.cc @@ -51,8 +51,13 @@ static void iomgr_platform_shutdown(void) { grpc_wakeup_fd_global_destroy(); } +static void iomgr_platform_shutdown_background_closure(void) { + grpc_shutdown_background_closure(); +} + 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}; 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 235a9e0712f..552ef4309c8 100644 --- a/src/core/lib/iomgr/iomgr_posix_cfstream.cc +++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc @@ -54,8 +54,13 @@ static void iomgr_platform_shutdown(void) { grpc_wakeup_fd_global_destroy(); } +static void iomgr_platform_shutdown_background_closure(void) { + grpc_shutdown_background_closure(); +} + 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}; void grpc_set_default_iomgr_platform() { char* enable_cfstream = getenv(grpc_cfstream_env_var); diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index aa2704ce263..c802fcca750 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -260,10 +260,17 @@ static void notify_on_write(grpc_tcp* tcp) { if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p notify_on_write", tcp); } - cover_self(tcp); - GRPC_CLOSURE_INIT(&tcp->write_done_closure, - tcp_drop_uncovered_then_handle_write, tcp, - grpc_schedule_on_exec_ctx); + if (grpc_event_engine_run_in_background()) { + // If there is a polling engine always running in the background, there is + // no need to run the backup poller. + GRPC_CLOSURE_INIT(&tcp->write_done_closure, tcp_handle_write, tcp, + grpc_schedule_on_exec_ctx); + } else { + cover_self(tcp); + GRPC_CLOSURE_INIT(&tcp->write_done_closure, + tcp_drop_uncovered_then_handle_write, tcp, + grpc_schedule_on_exec_ctx); + } grpc_fd_notify_on_write(tcp->em_fd, &tcp->write_done_closure); } diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index c6198b8ae76..67cf5d89bff 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -161,6 +161,7 @@ void grpc_shutdown(void) { if (--g_initializations == 0) { { grpc_core::ExecCtx exec_ctx(0); + grpc_iomgr_shutdown_background_closure(); { grpc_timer_manager_set_threading( false); // shutdown timer_manager thread From 667a17c1f36847c74d95e5edb91f6704a50e033f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 19 Nov 2018 22:15:22 +0100 Subject: [PATCH 0241/2143] split up coverage runs by language --- .../multilang_jessie_x64/Dockerfile.template | 41 ----- .../test/multilang_jessie_x64/Dockerfile | 170 ------------------ tools/internal_ci/linux/grpc_coverage.sh | 20 ++- tools/run_tests/run_tests.py | 18 +- 4 files changed, 18 insertions(+), 231 deletions(-) delete mode 100644 templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template delete mode 100644 tools/dockerfile/test/multilang_jessie_x64/Dockerfile diff --git a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template deleted file mode 100644 index ac687b710ff..00000000000 --- a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template +++ /dev/null @@ -1,41 +0,0 @@ -%YAML 1.2 ---- | - # 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. - - FROM debian:jessie - - <%include file="../../apt_get_basic.include"/> - <%include file="../../gcp_api_libraries.include"/> - <%include file="../../csharp_deps.include"/> - <%include file="../../csharp_dotnetcli_deps.include"/> - <%include file="../../cxx_deps.include"/> - <%include file="../../node_deps.include"/> - <%include file="../../php_deps.include"/> - <%include file="../../ruby_deps.include"/> - <%include file="../../python_deps.include"/> - # Install pip and virtualenv for Python 3.4 - RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4 - RUN python3.4 -m pip install virtualenv - - # Install coverage for Python test coverage reporting - RUN pip install coverage - ENV PATH ~/.local/bin:$PATH - - # Install Mako to generate files in grpc/grpc-node - RUN pip install Mako - - <%include file="../../run_tests_addons.include"/> - # Define the default command. - CMD ["bash"] diff --git a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile deleted file mode 100644 index 3c95554b029..00000000000 --- a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile +++ /dev/null @@ -1,170 +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. - -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 - -#================ -# C# dependencies - -# Update to a newer version of mono -RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF -RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list - -# Install dependencies -RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ - mono-devel \ - ca-certificates-mono \ - nuget \ - && apt-get clean - -RUN nuget update -self - -#================= -# Use cmake 3.6 from jessie-backports -# needed to build grpc_csharp_ext with cmake - -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean - -# Install dotnet SDK based on https://www.microsoft.com/net/core#debian -RUN apt-get update && apt-get install -y curl libunwind8 gettext -# dotnet-dev-1.0.0-preview2-003131 -RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530 -RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet -# dotnet-dev-1.0.1 -RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 -RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet -RUN ln -s /opt/dotnet/dotnet /usr/local/bin - -# Trigger the population of the local package cache -ENV NUGET_XMLDOC_MODE skip -RUN mkdir warmup \ - && cd warmup \ - && dotnet new \ - && cd .. \ - && rm -rf warmup - -#================= -# C++ dependencies -RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang && apt-get clean - -#================== -# Node dependencies - -# Install nvm -RUN touch .profile -RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash -# Install all versions of node that we want to test -RUN /bin/bash -l -c "nvm install 4 && npm config set cache /tmp/npm-cache" -RUN /bin/bash -l -c "nvm install 5 && npm config set cache /tmp/npm-cache" -RUN /bin/bash -l -c "nvm install 6 && npm config set cache /tmp/npm-cache" -RUN /bin/bash -l -c "nvm install 8 && npm config set cache /tmp/npm-cache" -RUN /bin/bash -l -c "nvm install 9 && npm config set cache /tmp/npm-cache" -RUN /bin/bash -l -c "nvm install 10 && npm config set cache /tmp/npm-cache" -RUN /bin/bash -l -c "nvm alias default 10" -#================= -# PHP dependencies - -# Install dependencies - -RUN apt-get update && apt-get install -y \ - git php5 php5-dev phpunit unzip - -#================== -# Ruby dependencies - -# Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 -RUN \curl -sSL https://get.rvm.io | bash -s stable - -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.1" -RUN /bin/bash -l -c "rvm use --default ruby-2.1" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" -RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" - -#==================== -# 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 - -# Install pip and virtualenv for Python 3.4 -RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4 -RUN python3.4 -m pip install virtualenv - -# Install coverage for Python test coverage reporting -RUN pip install coverage -ENV PATH ~/.local/bin:$PATH - -# Install Mako to generate files in grpc/grpc-node -RUN pip install Mako - - -RUN mkdir /var/local/jenkins - -# Define the default command. -CMD ["bash"] diff --git a/tools/internal_ci/linux/grpc_coverage.sh b/tools/internal_ci/linux/grpc_coverage.sh index 97166372ab4..ae820193371 100755 --- a/tools/internal_ci/linux/grpc_coverage.sh +++ b/tools/internal_ci/linux/grpc_coverage.sh @@ -21,12 +21,20 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc python tools/run_tests/run_tests.py \ - --use_docker \ - -t \ - -l all \ - -c gcov \ - -x sponge_log.xml \ - -j 16 || FAILED="true" + -l c c++ -x coverage_cpp/sponge_log.xml \ + --use_docker -t -c gcov -j 8 || FAILED="true" + +python tools/run_tests/run_tests.py \ + -l python -x coverage_python/sponge_log.xml \ + --use_docker -t -c gcov -j 8 || FAILED="true" + +python tools/run_tests/run_tests.py \ + -l ruby -x coverage_ruby/sponge_log.xml \ + --use_docker -t -c gcov -j 8 || FAILED="true" + +python tools/run_tests/run_tests.py \ + -l php -x coverage_php/sponge_log.xml \ + --use_docker -t -c gcov -j 8 || FAILED="true" # HTML reports can't be easily displayed in GCS, so create a zip archive # and put it under reports directory to get it uploaded as an artifact. diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index a1f2aaab2f3..4bc7ed907cc 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1340,9 +1340,9 @@ argp.add_argument( argp.add_argument( '-l', '--language', - choices=['all'] + sorted(_LANGUAGES.keys()), + choices=sorted(_LANGUAGES.keys()), nargs='+', - default=['all']) + required=True) argp.add_argument( '-S', '--stop_on_failure', default=False, action='store_const', const=True) argp.add_argument( @@ -1513,17 +1513,7 @@ build_config = run_config.build_config if args.travis: _FORCE_ENVIRON_FOR_WRAPPERS = {'GRPC_TRACE': 'api'} -if 'all' in args.language: - lang_list = list(_LANGUAGES.keys()) -else: - lang_list = args.language -# We don't support code coverage on some languages -if 'gcov' in args.config: - for bad in ['csharp', 'grpc-node', 'objc', 'sanity']: - if bad in lang_list: - lang_list.remove(bad) - -languages = set(_LANGUAGES[l] for l in lang_list) +languages = set(_LANGUAGES[l] for l in args.language) for l in languages: l.configure(run_config, args) @@ -1535,7 +1525,7 @@ if any(language.make_options() for language in languages): ) sys.exit(1) else: - # Combining make options is not clean and just happens to work. It allows C/C++ and C# to build + # Combining make options is not clean and just happens to work. It allows C & C++ to build # together, and is only used under gcov. All other configs should build languages individually. language_make_options = list( set([ From f836319f1f0a5ec1786b971c4c33eb40a67371bd Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 15:14:44 -0800 Subject: [PATCH 0242/2143] Bump version to v1.18.0-dev --- BUILD | 4 ++-- build.yaml | 4 ++-- doc/g_stands_for.md | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/BUILD b/BUILD index 3627096f2d2..526307a5e6f 100644 --- a/BUILD +++ b/BUILD @@ -64,11 +64,11 @@ config_setting( ) # This should be updated along with build.yaml -g_stands_for = "gizmo" +g_stands_for = "goose" core_version = "7.0.0-dev" -version = "1.17.0-dev" +version = "1.18.0-dev" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 09acdbe6f17..6798538a3c3 100644 --- a/build.yaml +++ b/build.yaml @@ -13,8 +13,8 @@ settings: '#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: gizmo - version: 1.17.0-dev + g_stands_for: goose + version: 1.18.0-dev filegroups: - name: alts_proto headers: diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index a5a8efb21c7..1e49b4d3f17 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -16,4 +16,5 @@ - 1.14 'g' stands for ['gladiolus'](https://github.com/grpc/grpc/tree/v1.14.x) - 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/master) +- 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) From f3e4ae633ee4476b1a30c9216f736eb71ffc968c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 15:24:53 -0800 Subject: [PATCH 0243/2143] 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/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 | 4 ++-- 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 | 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_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/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 5c2ba2048c0..bea450037d1 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.17.0-dev") +set(PACKAGE_VERSION "1.18.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 12603f1fc8b..a6b56bb4f7b 100644 --- a/Makefile +++ b/Makefile @@ -438,8 +438,8 @@ Q = @ endif CORE_VERSION = 7.0.0-dev -CPP_VERSION = 1.17.0-dev -CSHARP_VERSION = 1.17.0-dev +CPP_VERSION = 1.18.0-dev +CSHARP_VERSION = 1.18.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 fae5ce4a6ea..c59d8fe1a6e 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.17.0-dev' + # version = '1.18.0-dev' version = '0.0.4' 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.17.0-dev' + grpc_version = '1.18.0-dev' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f0a715cb585..3f041770740 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.17.0-dev' + version = '1.18.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 693b873d14d..13fe3e0b9c0 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.17.0-dev' + version = '1.18.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 fd590023e1a..e132ad41b40 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.17.0-dev' + version = '1.18.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 5e513cb1276..940a1ac6217 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.17.0-dev' + version = '1.18.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 3044cbf8625..c5046cd4614 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.17.0dev - 1.17.0dev + 1.18.0dev + 1.18.0dev beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 66890ce65ac..4829cc80a53 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -25,4 +25,4 @@ const char* grpc_version_string(void) { return "7.0.0-dev"; } -const char* grpc_g_stands_for(void) { return "gizmo"; } +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 8abd45efb77..55da89e6c83 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.17.0-dev"; } +grpc::string Version() { return "1.18.0-dev"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index ed0d8843650..4fffe4f6448 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.17.0-dev + 1.18.0-dev 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 14714c8c4ae..633880189ce 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.17.0.0"; + public const string CurrentAssemblyFileVersion = "1.18.0.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.17.0-dev"; + public const string CurrentVersion = "1.18.0-dev"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 27688360e9a..76d4f143901 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.17.0-dev +set VERSION=1.18.0-dev @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 dd74de0491a..3334d24c115 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.17.0-dev +set VERSION=1.18.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 a95a120d213..55ca6048bc3 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.17.0-dev' + v = '1.18.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 d5463c0b4cc..0be0e3c9a00 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.17.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.18.0-dev" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index ca27c03b3c7..f2fd692070b 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.17.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.18.0-dev" #define GRPC_C_VERSION_STRING @"7.0.0-dev" diff --git a/src/php/composer.json b/src/php/composer.json index d54db91b5fb..9c298c0e851 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.17.0", + "version": "1.18.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 70f8bbbf40b..1ddf90a667a 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.17.0dev" +#define PHP_GRPC_VERSION "1.18.0dev" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 42b3a1ad498..7a9f173947a 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.17.0.dev0""" +__version__ = """1.18.0.dev0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 71113e68d99..2e91818d2ca 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.17.0.dev0' +VERSION = '1.18.0.dev0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index a30aac2e0b8..85fa762f7e8 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.17.0.dev0' +VERSION = '1.18.0.dev0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index aafea9fe76b..e62ab169a2f 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.17.0.dev0' +VERSION = '1.18.0.dev0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 876acd3142f..7b4c1695faa 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.17.0.dev0' +VERSION = '1.18.0.dev0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index cc9b41587ca..2fcd1ad617f 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.17.0.dev0' +VERSION = '1.18.0.dev0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 243d5666451..a4ed052d85e 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.17.0.dev' + VERSION = '1.18.0.dev' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 92e85eb882b..389fb70684b 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.17.0.dev' + VERSION = '1.18.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 4b775e667ea..29b2127960a 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.17.0.dev0' +VERSION = '1.18.0.dev0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 392113c2843..fbac37e8e75 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.17.0-dev +PROJECT_NUMBER = 1.18.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 a96683883ca..f7a9c79620b 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.17.0-dev +PROJECT_NUMBER = 1.18.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 From 56f67728a82950ddeca8ad02e7432ef6d185ba2e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 15:30:46 -0800 Subject: [PATCH 0244/2143] Bump version to v1.17.0-pre1 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index 3627096f2d2..192606d8b61 100644 --- a/BUILD +++ b/BUILD @@ -68,7 +68,7 @@ g_stands_for = "gizmo" core_version = "7.0.0-dev" -version = "1.17.0-dev" +version = "1.17.0-pre1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 09acdbe6f17..32aeea9d64b 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-dev g_stands_for: gizmo - version: 1.17.0-dev + version: 1.17.0-pre1 filegroups: - name: alts_proto headers: From da14743f1a19d8d36b5891a71dc46cb55eaa496d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 15:32:20 -0800 Subject: [PATCH 0245/2143] Generate 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 | 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 | 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_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/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 +- 28 files changed, 31 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c2ba2048c0..92dec7da80e 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.17.0-dev") +set(PACKAGE_VERSION "1.17.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 12603f1fc8b..64e770565a7 100644 --- a/Makefile +++ b/Makefile @@ -438,8 +438,8 @@ Q = @ endif CORE_VERSION = 7.0.0-dev -CPP_VERSION = 1.17.0-dev -CSHARP_VERSION = 1.17.0-dev +CPP_VERSION = 1.17.0-pre1 +CSHARP_VERSION = 1.17.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 fae5ce4a6ea..6e0267723b6 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.17.0-dev' + # version = '1.17.0-pre1' version = '0.0.4' 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.17.0-dev' + grpc_version = '1.17.0-pre1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f0a715cb585..42ee1176cca 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.17.0-dev' + version = '1.17.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 693b873d14d..bed6f8480b1 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.17.0-dev' + version = '1.17.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 fd590023e1a..67a087d9b68 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.17.0-dev' + version = '1.17.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 5e513cb1276..c99386bb866 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.17.0-dev' + version = '1.17.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 3044cbf8625..471cee33f9d 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.17.0dev - 1.17.0dev + 1.17.0RC1 + 1.17.0RC1 beta diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 8abd45efb77..77c2cdd7d53 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.17.0-dev"; } +grpc::string Version() { return "1.17.0-pre1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index ed0d8843650..80bc939280f 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.17.0-dev + 1.17.0-pre1 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 14714c8c4ae..25d114686fb 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.17.0-dev"; + public const string CurrentVersion = "1.17.0-pre1"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 27688360e9a..23caffec0ce 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.17.0-dev +set VERSION=1.17.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 dd74de0491a..1ceefef6d69 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.17.0-dev +set VERSION=1.17.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 a95a120d213..020737b62ce 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.17.0-dev' + v = '1.17.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 d5463c0b4cc..a5603b5c7d2 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.17.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.17.0-pre1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index ca27c03b3c7..fa72c1117e9 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.17.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.17.0-pre1" #define GRPC_C_VERSION_STRING @"7.0.0-dev" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 70f8bbbf40b..5bfb987aaa2 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.17.0dev" +#define PHP_GRPC_VERSION "1.17.0RC1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 42b3a1ad498..a1b8f105d54 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.17.0.dev0""" +__version__ = """1.17.0rc1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 71113e68d99..be2aac35949 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.17.0.dev0' +VERSION = '1.17.0rc1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index a30aac2e0b8..befd54a4f21 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.17.0.dev0' +VERSION = '1.17.0rc1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index aafea9fe76b..c940f290c85 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.17.0.dev0' +VERSION = '1.17.0rc1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 876acd3142f..99b6bd90171 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.17.0.dev0' +VERSION = '1.17.0rc1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index cc9b41587ca..5aa6f60dcca 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.17.0.dev0' +VERSION = '1.17.0rc1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 243d5666451..099d33debb4 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.17.0.dev' + VERSION = '1.17.0.pre1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 92e85eb882b..f6d24eaaa33 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.17.0.dev' + VERSION = '1.17.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 4b775e667ea..7f4448d0b4b 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.17.0.dev0' +VERSION = '1.17.0rc1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 392113c2843..cb4ebb465bf 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.17.0-dev +PROJECT_NUMBER = 1.17.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 a96683883ca..f52eee8e005 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.17.0-dev +PROJECT_NUMBER = 1.17.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 8fad166c854d9685233457c1848661bc48e4986f Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 19 Nov 2018 16:11:57 -0800 Subject: [PATCH 0246/2143] added autoconfigured --- third_party/toolchains/BUILD | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index bf32ae4786d..bbaecae5653 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -35,9 +35,9 @@ platform( "@bazel_tools//platforms:x86_64", "@bazel_tools//platforms:linux", "@bazel_tools//tools/cpp:clang", - # "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", - # "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", - # "//third_party/toolchains/machine_size:standard", + "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", + "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", + "//third_party/toolchains/machine_size:standard", ], remote_execution_properties = """ properties: { @@ -79,17 +79,18 @@ platform( toolchain( name = "cc-toolchain-clang-x86_64-default", exec_compatible_with = [ + "@bazel_tools//platforms:autoconfigured", "@bazel_tools//platforms:linux", "@bazel_tools//platforms:x86_64", "@bazel_tools//tools/cpp:clang", - # "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", - # "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", - # "//third_party/toolchains/machine_size:standard", - # "//third_party/toolchains/machine_size:large", + "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", + "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", + "//third_party/toolchains/machine_size:standard", + "//third_party/toolchains/machine_size:large", ], target_compatible_with = [ - # "//third_party/toolchains:rbe_ubuntu1604", - # "//third_party/toolchains:rbe_ubuntu1604_large", + "//third_party/toolchains:rbe_ubuntu1604", + "//third_party/toolchains:rbe_ubuntu1604_large", "@bazel_tools//platforms:linux", "@bazel_tools//platforms:x86_64", ], From a3348a3bc9d86bb7a0bf6f0abef7c92e6235f84b Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 19 Nov 2018 16:12:18 -0800 Subject: [PATCH 0247/2143] Also extend iomgr_windows.cc --- src/core/lib/iomgr/iomgr_windows.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/iomgr_windows.cc b/src/core/lib/iomgr/iomgr_windows.cc index cdef89cbf04..24ef0dba7b4 100644 --- a/src/core/lib/iomgr/iomgr_windows.cc +++ b/src/core/lib/iomgr/iomgr_windows.cc @@ -71,8 +71,11 @@ static void iomgr_platform_shutdown(void) { winsock_shutdown(); } +static void iomgr_platform_shutdown_background_closure(void) {} + 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}; void grpc_set_default_iomgr_platform() { grpc_set_tcp_client_impl(&grpc_windows_tcp_client_vtable); From 96ed4b75789d422eb362cb7909428217bab63c7d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 17:01:28 -0800 Subject: [PATCH 0248/2143] dev->pre1 for core version --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index 192606d8b61..71df75dc8b2 100644 --- a/BUILD +++ b/BUILD @@ -66,7 +66,7 @@ config_setting( # This should be updated along with build.yaml g_stands_for = "gizmo" -core_version = "7.0.0-dev" +core_version = "7.0.0-pre1" version = "1.17.0-pre1" diff --git a/build.yaml b/build.yaml index 32aeea9d64b..044976f0ca9 100644 --- a/build.yaml +++ b/build.yaml @@ -12,7 +12,7 @@ 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: gizmo version: 1.17.0-pre1 filegroups: From 4f41886324fcf83616f4ed493b675a308b40a22e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 17:21:04 -0800 Subject: [PATCH 0249/2143] Generate projects --- Makefile | 2 +- src/core/lib/surface/version.cc | 2 +- src/objective-c/tests/version.h | 2 +- tools/doxygen/Doxyfile.core | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 64e770565a7..10dfd976236 100644 --- a/Makefile +++ b/Makefile @@ -437,7 +437,7 @@ E = @echo Q = @ endif -CORE_VERSION = 7.0.0-dev +CORE_VERSION = 7.0.0-pre1 CPP_VERSION = 1.17.0-pre1 CSHARP_VERSION = 1.17.0-pre1 diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 66890ce65ac..3ca1d830f7c 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 "gizmo"; } diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index fa72c1117e9..41a8c10ec24 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -23,4 +23,4 @@ // `tools/buildgen/generate_projects.sh`. #define GRPC_OBJC_VERSION_STRING @"1.17.0-pre1" -#define GRPC_C_VERSION_STRING @"7.0.0-dev" +#define GRPC_C_VERSION_STRING @"7.0.0-pre1" diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index b78fb607ad3..5ef4357e92b 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 7d105b32ce0..83a25e2b594 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 195c042d3231d0ebbb1c2684ce32457b879062ef Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 19 Nov 2018 17:35:21 -0800 Subject: [PATCH 0250/2143] Replace PB_FIELD_16BIT with PB_FIELD_32BIT --- CMakeLists.txt | 2 +- gRPC-Core.podspec | 2 +- setup.py | 2 +- .../lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c | 4 ++-- src/core/tsi/alts/handshaker/altscontext.pb.c | 4 ++-- src/core/tsi/alts/handshaker/handshaker.pb.c | 4 ++-- src/core/tsi/alts/handshaker/transport_security_common.pb.c | 4 ++-- templates/CMakeLists.txt.template | 2 +- templates/gRPC-Core.podspec.template | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c2ba2048c0..f1bcb7b9f99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,7 +94,7 @@ endif() set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) -add_definitions(-DPB_FIELD_16BIT) +add_definitions(-DPB_FIELD_32BIT) if (MSVC) include(cmake/msvc_static_runtime.cmake) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f0a715cb585..bd48ea3825a 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -93,7 +93,7 @@ Pod::Spec.new do |s| } s.default_subspecs = 'Interface', 'Implementation' - s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_16BIT' + s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_32BIT' s.libraries = 'c++' # Like many other C libraries, gRPC-Core has its public headers under `include//` and its diff --git a/setup.py b/setup.py index ae86e6c9fb7..c3aae1696b9 100644 --- a/setup.py +++ b/setup.py @@ -144,7 +144,7 @@ if EXTRA_ENV_COMPILE_ARGS is None: 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 += ' -DPB_FIELD_16BIT' +EXTRA_ENV_COMPILE_ARGS += ' -DPB_FIELD_32BIT' if EXTRA_ENV_LINK_ARGS is None: EXTRA_ENV_LINK_ARGS = '' diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c index f6538e1349f..a7b072420ec 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c @@ -75,14 +75,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_16BIT +/* If you get an error here, it means that you need to define PB_FIELD_32BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 256 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server) +PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 256 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server) #endif diff --git a/src/core/tsi/alts/handshaker/altscontext.pb.c b/src/core/tsi/alts/handshaker/altscontext.pb.c index 5fb152a558e..2320edb1eff 100644 --- a/src/core/tsi/alts/handshaker/altscontext.pb.c +++ b/src/core/tsi/alts/handshaker/altscontext.pb.c @@ -33,14 +33,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 65536 #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_16BIT +/* If you get an error here, it means that you need to define PB_FIELD_32BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_AltsContext) +PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_AltsContext) #endif diff --git a/src/core/tsi/alts/handshaker/handshaker.pb.c b/src/core/tsi/alts/handshaker/handshaker.pb.c index 5450b1602d4..8eda290e123 100644 --- a/src/core/tsi/alts/handshaker/handshaker.pb.c +++ b/src/core/tsi/alts/handshaker/handshaker.pb.c @@ -108,14 +108,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identit #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_16BIT +/* If you get an error here, it means that you need to define PB_FIELD_32BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identities) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_identity) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_ServerHandshakeParameters, local_identities) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, handshake_parameters[0]) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry, value) < 256 && pb_membersize(grpc_gcp_HandshakerReq, client_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, server_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, next) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, local_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_rpc_versions) < 256 && pb_membersize(grpc_gcp_HandshakerResp, result) < 256 && pb_membersize(grpc_gcp_HandshakerResp, status) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_Endpoint_grpc_gcp_Identity_grpc_gcp_StartClientHandshakeReq_grpc_gcp_ServerHandshakeParameters_grpc_gcp_StartServerHandshakeReq_grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_grpc_gcp_NextHandshakeMessageReq_grpc_gcp_HandshakerReq_grpc_gcp_HandshakerResult_grpc_gcp_HandshakerStatus_grpc_gcp_HandshakerResp) +PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identities) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_identity) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_ServerHandshakeParameters, local_identities) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, handshake_parameters[0]) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry, value) < 256 && pb_membersize(grpc_gcp_HandshakerReq, client_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, server_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, next) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, local_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_rpc_versions) < 256 && pb_membersize(grpc_gcp_HandshakerResp, result) < 256 && pb_membersize(grpc_gcp_HandshakerResp, status) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_Endpoint_grpc_gcp_Identity_grpc_gcp_StartClientHandshakeReq_grpc_gcp_ServerHandshakeParameters_grpc_gcp_StartServerHandshakeReq_grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_grpc_gcp_NextHandshakeMessageReq_grpc_gcp_HandshakerReq_grpc_gcp_HandshakerResult_grpc_gcp_HandshakerStatus_grpc_gcp_HandshakerResp) #endif diff --git a/src/core/tsi/alts/handshaker/transport_security_common.pb.c b/src/core/tsi/alts/handshaker/transport_security_common.pb.c index 326b1b10ab7..aac699314e7 100644 --- a/src/core/tsi/alts/handshaker/transport_security_common.pb.c +++ b/src/core/tsi/alts/handshaker/transport_security_common.pb.c @@ -35,14 +35,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_16BIT +/* If you get an error here, it means that you need to define PB_FIELD_32BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < 256 && pb_membersize(grpc_gcp_RpcProtocolVersions, min_rpc_version) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_RpcProtocolVersions_grpc_gcp_RpcProtocolVersions_Version) +PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < 256 && pb_membersize(grpc_gcp_RpcProtocolVersions, min_rpc_version) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_RpcProtocolVersions_grpc_gcp_RpcProtocolVersions_Version) #endif diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 1628493d000..f33d980cd00 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -143,7 +143,7 @@ ## Some libraries are shared even with BUILD_SHARED_LIBRARIES=OFF set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) - add_definitions(-DPB_FIELD_16BIT) + add_definitions(-DPB_FIELD_32BIT) if (MSVC) include(cmake/msvc_static_runtime.cmake) diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 98b6344a4bf..17178af4195 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -152,7 +152,7 @@ } s.default_subspecs = 'Interface', 'Implementation' - s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_16BIT' + s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_32BIT' s.libraries = 'c++' # Like many other C libraries, gRPC-Core has its public headers under `include//` and its From 3a0c72ff6b3f57a4f18fea102254f272dcb0593d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 20 Nov 2018 09:43:43 +0100 Subject: [PATCH 0251/2143] remove an unneeded shell script --- tools/run_tests/helper_scripts/run_lcov.sh | 31 ---------------------- 1 file changed, 31 deletions(-) delete mode 100755 tools/run_tests/helper_scripts/run_lcov.sh diff --git a/tools/run_tests/helper_scripts/run_lcov.sh b/tools/run_tests/helper_scripts/run_lcov.sh deleted file mode 100755 index 9d8b6793fce..00000000000 --- a/tools/run_tests/helper_scripts/run_lcov.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -# 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. - -set -ex - -out=$(readlink -f "${1:-coverage}") - -root=$(readlink -f "$(dirname "$0")/../../..") -shift || true -tmp=$(mktemp) -cd "$root" -tools/run_tests/run_tests.py -c gcov -l c c++ "$@" || true -lcov --capture --directory . --output-file "$tmp" -genhtml "$tmp" --output-directory "$out" -rm "$tmp" -if which xdg-open > /dev/null -then - xdg-open "file://$out/index.html" -fi From cde2cec2795b5475b52195703810e2bf30efc3c3 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 20 Nov 2018 09:46:30 +0100 Subject: [PATCH 0252/2143] pip install coverage for python_stretch3.7 image --- .../dockerfile/test/python_stretch_3.7_x64/Dockerfile.template | 3 +++ tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile | 3 +++ 2 files changed, 6 insertions(+) diff --git a/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template index ff342db493b..c3602f6c512 100644 --- a/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template @@ -18,3 +18,6 @@ RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 + + # for Python test coverage reporting + RUN pip install coverage diff --git a/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile b/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile index add1cc509db..45291ffdcfc 100644 --- a/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile +++ b/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile @@ -70,3 +70,6 @@ CMD ["bash"] RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 + +# for Python test coverage reporting +RUN pip install coverage From 3543b1b151cb2d0a7155fa39fa51017a9e7c745b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 20 Nov 2018 09:49:41 +0100 Subject: [PATCH 0253/2143] remove broken toplevel index.html file --- tools/run_tests/dockerize/docker_run_tests.sh | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh index c41734c92d2..b7686e48ba3 100755 --- a/tools/run_tests/dockerize/docker_run_tests.sh +++ b/tools/run_tests/dockerize/docker_run_tests.sh @@ -38,16 +38,8 @@ exit_code=0 $RUN_TESTS_COMMAND || exit_code=$? -cd reports -echo '' > index.html -find . -maxdepth 1 -mindepth 1 -type d | sort | while read d ; do - d=${d#*/} - n=${d//_/ } - echo "$n
" >> index.html -done -echo '' >> index.html -cd .. - +# The easiest way to copy all the reports files from inside of +# the docker container is to zip them and then copy the zip. zip -r reports.zip reports find . -name report.xml -print0 | xargs -0 -r zip reports.zip find . -name sponge_log.xml -print0 | xargs -0 -r zip reports.zip From 51e238c2ed02f191aac6e2dbd660cfbd949c73d0 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 20 Nov 2018 12:05:20 +0100 Subject: [PATCH 0254/2143] run_tests.py cleanup: nits in PythonLanguage --- tools/run_tests/run_tests.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index a1f2aaab2f3..f00355bafc0 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -756,9 +756,10 @@ class PythonLanguage(object): def dockerfile_dir(self): return 'tools/dockerfile/test/python_%s_%s' % ( - self.python_manager_name(), _docker_arch_suffix(self.args.arch)) + self._python_manager_name(), _docker_arch_suffix(self.args.arch)) - def python_manager_name(self): + def _python_manager_name(self): + """Choose the docker image to use based on python version.""" if self.args.compiler in [ 'python2.7', 'python3.5', 'python3.6', 'python3.7' ]: @@ -771,6 +772,7 @@ class PythonLanguage(object): return 'stretch_3.7' def _get_pythons(self, args): + """Get python runtimes to test with, based on current platform, architecture, compiler etc.""" if args.arch == 'x86': bits = '32' else: From 2108c0b6a78170118a542875daa3857b932bb29f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 20 Nov 2018 12:40:16 +0100 Subject: [PATCH 0255/2143] avoid C++ flakes by decreasing coverage parallelism --- tools/internal_ci/linux/grpc_coverage.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/internal_ci/linux/grpc_coverage.sh b/tools/internal_ci/linux/grpc_coverage.sh index ae820193371..a91cffdf989 100755 --- a/tools/internal_ci/linux/grpc_coverage.sh +++ b/tools/internal_ci/linux/grpc_coverage.sh @@ -22,19 +22,19 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc python tools/run_tests/run_tests.py \ -l c c++ -x coverage_cpp/sponge_log.xml \ - --use_docker -t -c gcov -j 8 || FAILED="true" + --use_docker -t -c gcov -j 2 || FAILED="true" python tools/run_tests/run_tests.py \ -l python -x coverage_python/sponge_log.xml \ - --use_docker -t -c gcov -j 8 || FAILED="true" + --use_docker -t -c gcov -j 2 || FAILED="true" python tools/run_tests/run_tests.py \ -l ruby -x coverage_ruby/sponge_log.xml \ - --use_docker -t -c gcov -j 8 || FAILED="true" + --use_docker -t -c gcov -j 2 || FAILED="true" python tools/run_tests/run_tests.py \ -l php -x coverage_php/sponge_log.xml \ - --use_docker -t -c gcov -j 8 || FAILED="true" + --use_docker -t -c gcov -j 2 || FAILED="true" # HTML reports can't be easily displayed in GCS, so create a zip archive # and put it under reports directory to get it uploaded as an artifact. From 3ce9b4fc43be787a548f0398cd0fb348e863a059 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 30 Oct 2018 12:50:49 +0100 Subject: [PATCH 0256/2143] remove remnants of ccache with --use_docker using ccache when building under a docker image isn't useful when building on kokoro as each build runs on a fresh VM. Originally ccache builds were used to speed up jenkins builds, now removing to guarantee build isolation and simplify stuff. --- tools/dockerfile/test/python_alpine_x64/Dockerfile | 8 +------- tools/run_tests/dockerize/build_docker_and_run_tests.sh | 5 ----- tools/run_tests/dockerize/build_interop_image.sh | 4 ---- 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/tools/dockerfile/test/python_alpine_x64/Dockerfile b/tools/dockerfile/test/python_alpine_x64/Dockerfile index 6e06e2d52c3..3001bf43ff6 100644 --- a/tools/dockerfile/test/python_alpine_x64/Dockerfile +++ b/tools/dockerfile/test/python_alpine_x64/Dockerfile @@ -42,13 +42,7 @@ RUN pip install virtualenv RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 # Google Cloud platform API libraries -RUN pip install --upgrade google-api-python-client - -# Prepare ccache -RUN ln -s /usr/bin/ccache /usr/local/bin/gcc -RUN ln -s /usr/bin/ccache /usr/local/bin/g++ -RUN ln -s /usr/bin/ccache /usr/local/bin/cc -RUN ln -s /usr/bin/ccache /usr/local/bin/c++ +RUN pip install --upgrade google-api-python-client oauth2client RUN mkdir -p /var/local/jenkins diff --git a/tools/run_tests/dockerize/build_docker_and_run_tests.sh b/tools/run_tests/dockerize/build_docker_and_run_tests.sh index 614049cae53..1741b3268be 100755 --- a/tools/run_tests/dockerize/build_docker_and_run_tests.sh +++ b/tools/run_tests/dockerize/build_docker_and_run_tests.sh @@ -22,9 +22,6 @@ cd "$(dirname "$0")/../../.." git_root=$(pwd) cd - -# Ensure existence of ccache directory -mkdir -p /tmp/ccache - # Inputs # DOCKERFILE_DIR - Directory in which Dockerfile file is located. # DOCKER_RUN_SCRIPT - Script to run under docker (relative to grpc repo root) @@ -57,7 +54,6 @@ docker run \ -e "RUN_TESTS_COMMAND=$RUN_TESTS_COMMAND" \ -e "config=$config" \ -e "arch=$arch" \ - -e CCACHE_DIR=/tmp/ccache \ -e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \ -e HOST_GIT_ROOT="$git_root" \ -e LOCAL_GIT_ROOT=$docker_instance_git_root \ @@ -73,7 +69,6 @@ docker run \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ -v ~/.config/gcloud:/root/.config/gcloud \ -v "$git_root:$docker_instance_git_root" \ - -v /tmp/ccache:/tmp/ccache \ -v /tmp/npm-cache:/tmp/npm-cache \ -w /var/local/git/grpc \ --name="$CONTAINER_NAME" \ diff --git a/tools/run_tests/dockerize/build_interop_image.sh b/tools/run_tests/dockerize/build_interop_image.sh index fcfcdeb4e41..126dd4065e0 100755 --- a/tools/run_tests/dockerize/build_interop_image.sh +++ b/tools/run_tests/dockerize/build_interop_image.sh @@ -64,8 +64,6 @@ else echo "WARNING: grpc-node not found, it won't be mounted to the docker container." fi -mkdir -p /tmp/ccache - # Mount service account dir if available. # If service_directory does not contain the service account JSON file, # some of the tests will fail. @@ -105,14 +103,12 @@ CONTAINER_NAME="build_${BASE_NAME}_$(uuidgen)" # shellcheck disable=SC2086 (docker run \ --cap-add SYS_PTRACE \ - -e CCACHE_DIR=/tmp/ccache \ -e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \ -e THIS_IS_REALLY_NEEDED_ONCE_AGAIN='For issue 4835. See https://github.com/docker/docker/issues/14203 for why docker is awful' \ -i \ $TTY_FLAG \ $MOUNT_ARGS \ $BUILD_INTEROP_DOCKER_EXTRA_ARGS \ - -v /tmp/ccache:/tmp/ccache \ --name="$CONTAINER_NAME" \ "$BASE_IMAGE" \ bash -l "/var/local/jenkins/grpc/tools/dockerfile/interoptest/$BASE_NAME/build_interop.sh" \ From 070d52435208b3fe7bf74963d7f17ab309ca82e2 Mon Sep 17 00:00:00 2001 From: Vishal Powar Date: Tue, 20 Nov 2018 10:50:01 -0800 Subject: [PATCH 0257/2143] xDS plugin is going to use LRS stream to report load to balancer. Remove the current grpclb specific load reporting from the implementation. The changes here also mean that the plugin will just get the initial response and no subsequent response from the balancer. --- .../client_channel/lb_policy/xds/xds.cc | 22 +++---------------- 1 file changed, 3 insertions(+), 19 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 29cd9043755..e4b29a0d93f 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 @@ -668,16 +668,17 @@ bool XdsLb::BalancerCallState::LoadReportCountersAreZero( (drop_entries == nullptr || drop_entries->empty()); } +// TODO(vpowar): Use LRS to send the client Load Report. void XdsLb::BalancerCallState::SendClientLoadReportLocked() { // Construct message payload. GPR_ASSERT(send_message_payload_ == nullptr); xds_grpclb_request* request = xds_grpclb_load_report_request_create_locked(client_stats_.get()); + // Skip client load report if the counters were all zero in the last // report and they are still zero in this one. if (LoadReportCountersAreZero(request)) { if (last_client_load_report_counters_were_zero_) { - xds_grpclb_request_destroy(request); ScheduleNextClientLoadReportLocked(); return; } @@ -685,25 +686,8 @@ void XdsLb::BalancerCallState::SendClientLoadReportLocked() { } else { last_client_load_report_counters_were_zero_ = false; } - grpc_slice request_payload_slice = xds_grpclb_request_encode(request); - send_message_payload_ = - grpc_raw_byte_buffer_create(&request_payload_slice, 1); - grpc_slice_unref_internal(request_payload_slice); + // TODO(vpowar): Send the report on LRS stream. xds_grpclb_request_destroy(request); - // Send the report. - grpc_op op; - memset(&op, 0, sizeof(op)); - op.op = GRPC_OP_SEND_MESSAGE; - op.data.send_message.send_message = send_message_payload_; - GRPC_CLOSURE_INIT(&client_load_report_closure_, ClientLoadReportDoneLocked, - this, grpc_combiner_scheduler(xdslb_policy()->combiner())); - grpc_call_error call_error = grpc_call_start_batch_and_execute( - lb_call_, &op, 1, &client_load_report_closure_); - if (GPR_UNLIKELY(call_error != GRPC_CALL_OK)) { - gpr_log(GPR_ERROR, "[xdslb %p] call_error=%d", xdslb_policy_.get(), - call_error); - GPR_ASSERT(GRPC_CALL_OK == call_error); - } } void XdsLb::BalancerCallState::ClientLoadReportDoneLocked(void* arg, From 458d9d28dbe71b48986e9a296192bd92c0bb7936 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Tue, 20 Nov 2018 11:09:06 -0800 Subject: [PATCH 0258/2143] Add the missing definition of shutdown_background_closure to bm_cq_multiple_threads --- test/cpp/microbenchmarks/bm_cq_multiple_threads.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc index 85767c8758f..dca97c85b19 100644 --- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc +++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc @@ -94,6 +94,7 @@ static const grpc_event_engine_vtable* init_engine_vtable(bool) { g_vtable.pollset_destroy = pollset_destroy; g_vtable.pollset_work = pollset_work; g_vtable.pollset_kick = pollset_kick; + g_vtable.shutdown_background_closure = [] {}; g_vtable.shutdown_engine = [] {}; return &g_vtable; From b0417a59bf98b27eb16cec7289a3dbb7a70729d9 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 4 Jun 2018 11:25:46 +0200 Subject: [PATCH 0259/2143] Revert "pin google-api-python-client to 1.6.7 to avoid breakage" --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 24a3545dedc..62e75b84a23 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -28,8 +28,7 @@ sudo systemsetup -setusingnetworktime on date # Add GCP credentials for BQ access -# pin google-api-python-client to avoid https://github.com/grpc/grpc/issues/15600 -pip install google-api-python-client==1.6.7 --user python +pip install google-api-python-client --user python export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests From f62323aea28260d4233487dc84834dd26c48845c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 20 Nov 2018 13:21:07 -0800 Subject: [PATCH 0260/2143] Tests project fixes --- src/objective-c/tests/Tests.xcodeproj/project.pbxproj | 8 -------- .../xcshareddata/xcschemes/ChannelTests.xcscheme | 7 +++++-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 6d1932b0215..6f24d3512f8 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -1276,15 +1276,11 @@ 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-APIv2Tests-checkManifestLockResult.txt", ); @@ -1856,15 +1852,11 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-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", ); diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme index 16ae481123b..8c8623d7b21 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme @@ -26,7 +26,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -47,7 +51,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" From c7e92f26ebaecc8ea619de8b757034bb848b37d4 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 20 Nov 2018 15:03:12 -0800 Subject: [PATCH 0261/2143] Reviewer comments --- CMakeLists.txt | 2 ++ Makefile | 6 ++-- build.yaml | 3 ++ .../chttp2/transport/context_list.cc | 14 ++++---- .../transport/chttp2/transport/context_list.h | 24 +++++++------- src/core/lib/iomgr/endpoint.cc | 5 +-- test/core/transport/chttp2/BUILD | 3 ++ .../transport/chttp2/context_list_test.cc | 33 +++++++++++-------- .../generated/sources_and_headers.json | 2 ++ tools/run_tests/generated/tests.json | 2 +- 10 files changed, 52 insertions(+), 42 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1da78e8f57a..7b36b3a5a8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12738,6 +12738,8 @@ target_link_libraries(context_list_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc + gpr_test_util + gpr ${_gRPC_GFLAGS_LIBRARIES} ) diff --git a/Makefile b/Makefile index ca867ebc46d..d0f28281d73 100644 --- a/Makefile +++ b/Makefile @@ -17582,16 +17582,16 @@ $(BINDIR)/$(CONFIG)/context_list_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/context_list_test: $(PROTOBUF_DEP) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(BINDIR)/$(CONFIG)/context_list_test: $(PROTOBUF_DEP) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/context_list_test + $(Q) $(LDXX) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/context_list_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_context_list_test: $(CONTEXT_LIST_TEST_OBJS:.o=.dep) diff --git a/build.yaml b/build.yaml index cca5ed3cbff..772bdbbdede 100644 --- a/build.yaml +++ b/build.yaml @@ -4605,6 +4605,7 @@ targets: - grpc++_codegen_base_src uses_polling: false - name: context_list_test + gtest: true build: test language: c++ src: @@ -4612,6 +4613,8 @@ targets: deps: - grpc_test_util - grpc + - gpr_test_util + - gpr uses_polling: false - name: credentials_test gtest: true diff --git a/src/core/ext/transport/chttp2/transport/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc index 11f5c14a39b..4acd0c95833 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.cc +++ b/src/core/ext/transport/chttp2/transport/context_list.cc @@ -21,30 +21,30 @@ #include "src/core/ext/transport/chttp2/transport/context_list.h" namespace { -void (*cb)(void*, grpc_core::Timestamps*) = nullptr; +void (*write_timestamps_callback_g)(void*, grpc_core::Timestamps*) = nullptr; } namespace grpc_core { void ContextList::Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error) { ContextList* head = static_cast(arg); - ContextList* ptr; + ContextList* to_be_freed; while (head != nullptr) { if (error == GRPC_ERROR_NONE && ts != nullptr) { - if (cb) { - cb(head->s_->context, ts); + if (write_timestamps_callback_g) { + write_timestamps_callback_g(head->s_->context, ts); } } GRPC_CHTTP2_STREAM_UNREF(static_cast(head->s_), "timestamp"); - ptr = head; + to_be_freed = head; head = head->next_; - grpc_core::Delete(ptr); + grpc_core::Delete(to_be_freed); } } void grpc_http2_set_write_timestamps_callback( void (*fn)(void*, grpc_core::Timestamps*)) { - cb = fn; + write_timestamps_callback_g = fn; } } /* namespace grpc_core */ diff --git a/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h index 0cf7ba4dc31..68d11e94d86 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.h +++ b/src/core/ext/transport/chttp2/transport/context_list.h @@ -16,8 +16,8 @@ * */ -#ifndef GRPC_CORE_EXT_TRANSPORT_CONTEXT_LIST_H -#define GRPC_CORE_EXT_TRANSPORT_CONTEXT_LIST_H +#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H +#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H #include @@ -33,8 +33,10 @@ class ContextList { * list. */ static void Append(ContextList** head, grpc_chttp2_stream* s) { /* Make sure context is not already present */ - ContextList* ptr = *head; GRPC_CHTTP2_STREAM_REF(s, "timestamp"); + +#ifndef NDEBUG + ContextList* ptr = *head; while (ptr != nullptr) { if (ptr->s_ == s) { GPR_ASSERT( @@ -43,17 +45,13 @@ class ContextList { } ptr = ptr->next_; } +#endif + + /* Create a new element in the list and add it at the front */ ContextList* elem = grpc_core::New(); elem->s_ = s; - if (*head == nullptr) { - *head = elem; - return; - } - ptr = *head; - while (ptr->next_ != nullptr) { - ptr = ptr->next_; - } - ptr->next_ = elem; + elem->next_ = *head; + *head = elem; } /* Executes a function \a fn with each context in the list and \a ts. It also @@ -69,4 +67,4 @@ void grpc_http2_set_write_timestamps_callback( void (*fn)(void*, grpc_core::Timestamps*)); } /* namespace grpc_core */ -#endif /* GRPC_CORE_EXT_TRANSPORT_CONTEXT_LIST_H */ +#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H */ diff --git a/src/core/lib/iomgr/endpoint.cc b/src/core/lib/iomgr/endpoint.cc index 5e5effb2f13..06316c60315 100644 --- a/src/core/lib/iomgr/endpoint.cc +++ b/src/core/lib/iomgr/endpoint.cc @@ -63,8 +63,5 @@ grpc_resource_user* grpc_endpoint_get_resource_user(grpc_endpoint* ep) { } bool grpc_endpoint_can_track_err(grpc_endpoint* ep) { - if (ep->vtable->can_track_err != nullptr) { - return ep->vtable->can_track_err(ep); - } - return false; + return ep->vtable->can_track_err(ep); } diff --git a/test/core/transport/chttp2/BUILD b/test/core/transport/chttp2/BUILD index c7bfa1ec09e..33437373e4e 100644 --- a/test/core/transport/chttp2/BUILD +++ b/test/core/transport/chttp2/BUILD @@ -69,6 +69,9 @@ grpc_cc_test( grpc_cc_test( name = "context_list_test", srcs = ["context_list_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", diff --git a/test/core/transport/chttp2/context_list_test.cc b/test/core/transport/chttp2/context_list_test.cc index 3814184e164..e2100899d39 100644 --- a/test/core/transport/chttp2/context_list_test.cc +++ b/test/core/transport/chttp2/context_list_test.cc @@ -18,6 +18,7 @@ #include "src/core/lib/iomgr/port.h" +#include #include #include @@ -29,25 +30,28 @@ #include -static void TestExecuteFlushesListVerifier(void* arg, - grpc_core::Timestamps* ts) { +namespace grpc_core { +namespace testing { +namespace { +void TestExecuteFlushesListVerifier(void* arg, grpc_core::Timestamps* ts) { GPR_ASSERT(arg != nullptr); gpr_atm* done = reinterpret_cast(arg); gpr_atm_rel_store(done, static_cast(1)); } -static void discard_write(grpc_slice slice) {} +void discard_write(grpc_slice slice) {} /** Tests that all ContextList elements in the list are flushed out on * execute. * Also tests that arg is passed correctly. */ -static void TestExecuteFlushesList() { +TEST(ContextList, ExecuteFlushesList) { grpc_core::ContextList* list = nullptr; grpc_http2_set_write_timestamps_callback(TestExecuteFlushesListVerifier); -#define NUM_ELEM 5 + const int kNumElems = 5; grpc_core::ExecCtx exec_ctx; grpc_stream_refcount ref; + GRPC_STREAM_REF_INIT(&ref, 1, nullptr, nullptr, "dummy ref"); grpc_resource_quota* resource_quota = grpc_resource_quota_create("context_list_test"); grpc_endpoint* mock_endpoint = @@ -55,9 +59,9 @@ static void TestExecuteFlushesList() { grpc_transport* t = grpc_create_chttp2_transport(nullptr, mock_endpoint, true); std::vector s; - s.reserve(NUM_ELEM); - gpr_atm verifier_called[NUM_ELEM]; - for (auto i = 0; i < NUM_ELEM; i++) { + s.reserve(kNumElems); + gpr_atm verifier_called[kNumElems]; + for (auto i = 0; i < kNumElems; i++) { s.push_back(static_cast( gpr_malloc(grpc_transport_stream_size(t)))); grpc_transport_init_stream(reinterpret_cast(t), @@ -69,7 +73,7 @@ static void TestExecuteFlushesList() { } grpc_core::Timestamps ts; grpc_core::ContextList::Execute(list, &ts, GRPC_ERROR_NONE); - for (auto i = 0; i < NUM_ELEM; i++) { + for (auto i = 0; i < kNumElems; i++) { GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) == static_cast(1)); grpc_transport_destroy_stream(reinterpret_cast(t), @@ -82,12 +86,13 @@ static void TestExecuteFlushesList() { grpc_resource_quota_unref(resource_quota); exec_ctx.Flush(); } - -static void TestContextList() { TestExecuteFlushesList(); } +} // namespace +} // namespace testing +} // namespace grpc_core int main(int argc, char** argv) { + grpc_test_init(argc, argv); grpc_init(); - TestContextList(); - grpc_shutdown(); - return 0; + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 1581b9a94b3..81af7829e50 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3509,6 +3509,8 @@ }, { "deps": [ + "gpr", + "gpr_test_util", "grpc", "grpc_test_util" ], diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 0569f81e6a0..cc28e52ae21 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -4136,7 +4136,7 @@ "exclude_configs": [], "exclude_iomgrs": [], "flaky": false, - "gtest": false, + "gtest": true, "language": "c++", "name": "context_list_test", "platforms": [ From 9809e018881ef4dd1a1cd7fc025445f772724648 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 20 Nov 2018 15:21:29 -0800 Subject: [PATCH 0262/2143] Wrap pthread_atwork call --- src/php/ext/grpc/php_grpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index cbc7f63be07..492325b1e8b 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -200,7 +200,9 @@ void postfork_parent() { void register_fork_handlers() { if (getenv("GRPC_ENABLE_FORK_SUPPORT")) { +#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK pthread_atfork(&prefork, &postfork_parent, &postfork_child); +#endif // GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK } } From c04583f6475981d7f2874d51cb39b2e68617f0f3 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 20 Nov 2018 15:23:08 -0800 Subject: [PATCH 0263/2143] registered toolchain and platform --- WORKSPACE | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index a547c24cbe2..d75d093896f 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,45 +1,59 @@ -workspace(name="com_github_grpc_grpc") +workspace(name = "com_github_grpc_grpc") load("//bazel:grpc_deps.bzl", "grpc_deps", "grpc_test_only_deps") + grpc_deps() + grpc_test_only_deps() +register_execution_platforms( + "//third_party/toolchains:all", +) + +register_toolchain( + "//third_party/toolchains:all", +) + new_http_archive( - name="cython", - sha256="d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27", - urls=[ + name = "cython", + build_file = "//third_party:cython.BUILD", + sha256 = "d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27", + strip_prefix = "cython-c2b80d87658a8525ce091cbe146cb7eaa29fed5c", + urls = [ "https://github.com/cython/cython/archive/c2b80d87658a8525ce091cbe146cb7eaa29fed5c.tar.gz", ], - strip_prefix="cython-c2b80d87658a8525ce091cbe146cb7eaa29fed5c", - build_file="//third_party:cython.BUILD", ) load("//third_party/py:python_configure.bzl", "python_configure") -python_configure(name="local_config_python") + +python_configure(name = "local_config_python") git_repository( - name="io_bazel_rules_python", - remote="https://github.com/bazelbuild/rules_python.git", - commit="8b5d0683a7d878b28fffe464779c8a53659fc645", + name = "io_bazel_rules_python", + commit = "8b5d0683a7d878b28fffe464779c8a53659fc645", + remote = "https://github.com/bazelbuild/rules_python.git", ) load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories", "pip_import") pip_repositories() + pip_import( - name="grpc_python_dependencies", - requirements="//:requirements.bazel.txt", + name = "grpc_python_dependencies", + requirements = "//:requirements.bazel.txt", ) load("@grpc_python_dependencies//:requirements.bzl", "pip_install") + pip_install() # NOTE(https://github.com/pubref/rules_protobuf/pull/196): Switch to upstream repo after this gets merged. git_repository( - name="org_pubref_rules_protobuf", - remote="https://github.com/ghostwriternr/rules_protobuf", - tag="v0.8.2.1-alpha", + name = "org_pubref_rules_protobuf", + remote = "https://github.com/ghostwriternr/rules_protobuf", + tag = "v0.8.2.1-alpha", ) load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories") + py_proto_repositories() From b654c8d279667c63cbb5725a70f72576d5d305e1 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 20 Nov 2018 12:54:31 -0800 Subject: [PATCH 0264/2143] python: close channels in _server_ssl_cert_config_test --- .../unit/_server_ssl_cert_config_test.py | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py index e733a59a5b1..9e4bd618168 100644 --- a/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py +++ b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py @@ -70,18 +70,11 @@ SERVER_CERT_CHAIN_2_PEM = (resources.cert_hier_2_server_1_cert() + Call = collections.namedtuple('Call', ['did_raise', 'returned_cert_config']) -def _create_client_stub( - port, - expect_success, - root_certificates=None, - private_key=None, - certificate_chain=None, -): - channel = grpc.secure_channel('localhost:{}'.format(port), - grpc.ssl_channel_credentials( - root_certificates=root_certificates, - private_key=private_key, - certificate_chain=certificate_chain)) +def _create_channel(port, credentials): + return grpc.secure_channel('localhost:{}'.format(port), credentials) + + +def _create_client_stub(channel, expect_success): if expect_success: # per Nathaniel: there's some robustness issue if we start # using a channel without waiting for it to be actually ready @@ -176,14 +169,13 @@ class _ServerSSLCertReloadTest( root_certificates=None, private_key=None, certificate_chain=None): - client_stub = _create_client_stub( - self.port, - expect_success, + credentials = grpc.ssl_channel_credentials( root_certificates=root_certificates, private_key=private_key, certificate_chain=certificate_chain) - self._perform_rpc(client_stub, expect_success) - del client_stub + with _create_channel(self.port, credentials) as client_channel: + client_stub = _create_client_stub(client_channel, expect_success) + self._perform_rpc(client_stub, expect_success) def _test(self): # things should work... @@ -259,12 +251,13 @@ class _ServerSSLCertReloadTest( # now create the "persistent" clients self.cert_config_fetcher.reset() self.cert_config_fetcher.configure(False, None) - persistent_client_stub_A = _create_client_stub( + channel_A = _create_channel( self.port, - True, - root_certificates=CA_1_PEM, - private_key=CLIENT_KEY_2_PEM, - certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + grpc.ssl_channel_credentials( + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM)) + persistent_client_stub_A = _create_client_stub(channel_A, True) self._perform_rpc(persistent_client_stub_A, True) actual_calls = self.cert_config_fetcher.getCalls() self.assertEqual(len(actual_calls), 1) @@ -273,12 +266,13 @@ class _ServerSSLCertReloadTest( self.cert_config_fetcher.reset() self.cert_config_fetcher.configure(False, None) - persistent_client_stub_B = _create_client_stub( + channel_B = _create_channel( self.port, - True, - root_certificates=CA_1_PEM, - private_key=CLIENT_KEY_2_PEM, - certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + grpc.ssl_channel_credentials( + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM)) + persistent_client_stub_B = _create_client_stub(channel_B, True) self._perform_rpc(persistent_client_stub_B, True) actual_calls = self.cert_config_fetcher.getCalls() self.assertEqual(len(actual_calls), 1) @@ -359,6 +353,9 @@ class _ServerSSLCertReloadTest( actual_calls = self.cert_config_fetcher.getCalls() self.assertEqual(len(actual_calls), 0) + channel_A.close() + channel_B.close() + class ServerSSLCertConfigFetcherParamsChecks(unittest.TestCase): From a548f1cc64c781c0d9a0051b7a44d2b19bd5a934 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 20 Nov 2018 15:43:24 -0800 Subject: [PATCH 0265/2143] fixed typo on WORKSPACE file --- WORKSPACE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WORKSPACE b/WORKSPACE index d75d093896f..cd2718204d1 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -10,7 +10,7 @@ register_execution_platforms( "//third_party/toolchains:all", ) -register_toolchain( +register_toolchains( "//third_party/toolchains:all", ) From c575d687301a1ffd225445be70243e7b8bc0ac49 Mon Sep 17 00:00:00 2001 From: Vishal Powar Date: Tue, 20 Nov 2018 15:52:45 -0800 Subject: [PATCH 0266/2143] Incorporate review comments --- .../filters/client_channel/lb_policy/xds/xds.cc | 16 +--------------- 1 file changed, 1 insertion(+), 15 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 e4b29a0d93f..89b86b38a63 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 @@ -199,7 +199,6 @@ class XdsLb : public LoadBalancingPolicy { static bool LoadReportCountersAreZero(xds_grpclb_request* request); static void MaybeSendClientLoadReportLocked(void* arg, grpc_error* error); - static void ClientLoadReportDoneLocked(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); @@ -674,11 +673,11 @@ void XdsLb::BalancerCallState::SendClientLoadReportLocked() { GPR_ASSERT(send_message_payload_ == nullptr); xds_grpclb_request* request = xds_grpclb_load_report_request_create_locked(client_stats_.get()); - // Skip client load report if the counters were all zero in the last // report and they are still zero in this one. if (LoadReportCountersAreZero(request)) { if (last_client_load_report_counters_were_zero_) { + xds_grpclb_request_destroy(request); ScheduleNextClientLoadReportLocked(); return; } @@ -690,19 +689,6 @@ void XdsLb::BalancerCallState::SendClientLoadReportLocked() { xds_grpclb_request_destroy(request); } -void XdsLb::BalancerCallState::ClientLoadReportDoneLocked(void* arg, - grpc_error* error) { - BalancerCallState* lb_calld = static_cast(arg); - XdsLb* xdslb_policy = lb_calld->xdslb_policy(); - grpc_byte_buffer_destroy(lb_calld->send_message_payload_); - lb_calld->send_message_payload_ = nullptr; - if (error != GRPC_ERROR_NONE || lb_calld != xdslb_policy->lb_calld_.get()) { - lb_calld->Unref(DEBUG_LOCATION, "client_load_report"); - return; - } - lb_calld->ScheduleNextClientLoadReportLocked(); -} - void XdsLb::BalancerCallState::OnInitialRequestSentLocked(void* arg, grpc_error* error) { BalancerCallState* lb_calld = static_cast(arg); From 894b313c0bd6992d2f1f1ab01f72c152c542511a Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 20 Nov 2018 16:12:05 -0800 Subject: [PATCH 0267/2143] Bump to v1.17.0-pre2 --- BUILD | 10 +++++----- build.yaml | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/BUILD b/BUILD index 71df75dc8b2..270c56ff6ed 100644 --- a/BUILD +++ b/BUILD @@ -66,9 +66,9 @@ config_setting( # This should be updated along with build.yaml g_stands_for = "gizmo" -core_version = "7.0.0-pre1" +core_version = "7.0.0-pre2" -version = "1.17.0-pre1" +version = "1.17.0-pre2" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", @@ -1087,11 +1087,11 @@ grpc_cc_library( "grpc_base", "grpc_client_authority_filter", "grpc_deadline_filter", + "health_proto", "inlined_vector", "orphanable", "ref_counted", "ref_counted_ptr", - "health_proto", ], ) @@ -1589,8 +1589,8 @@ grpc_cc_library( "src/core/lib/security/security_connector/load_system_roots_linux.cc", "src/core/lib/security/security_connector/local/local_security_connector.cc", "src/core/lib/security/security_connector/security_connector.cc", - "src/core/lib/security/security_connector/ssl_utils.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/transport/client_auth_filter.cc", "src/core/lib/security/transport/secure_endpoint.cc", "src/core/lib/security/transport/security_handshaker.cc", @@ -1623,8 +1623,8 @@ grpc_cc_library( "src/core/lib/security/security_connector/load_system_roots_linux.h", "src/core/lib/security/security_connector/local/local_security_connector.h", "src/core/lib/security/security_connector/security_connector.h", - "src/core/lib/security/security_connector/ssl_utils.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/transport/auth_filters.h", "src/core/lib/security/transport/secure_endpoint.h", "src/core/lib/security/transport/security_handshaker.h", diff --git a/build.yaml b/build.yaml index 044976f0ca9..0a74fd29ffd 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-pre2 g_stands_for: gizmo - version: 1.17.0-pre1 + version: 1.17.0-pre2 filegroups: - name: alts_proto headers: From 4a9feff1fd9a0e789f10ea7b556a7af8f878e70d Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 20 Nov 2018 16:15:42 -0800 Subject: [PATCH 0268/2143] removed autoconfigured constraint --- third_party/toolchains/BUILD | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index bbaecae5653..2a68f3e7ccc 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -71,7 +71,7 @@ platform( name: "gceMachineType" # Small machines for majority of tests. value: "n1-standard-8" } - """, + """, ) # This target is auto-generated from release/cpp.tpl and should not be @@ -79,7 +79,6 @@ platform( toolchain( name = "cc-toolchain-clang-x86_64-default", exec_compatible_with = [ - "@bazel_tools//platforms:autoconfigured", "@bazel_tools//platforms:linux", "@bazel_tools//platforms:x86_64", "@bazel_tools//tools/cpp:clang", From 3391245e739f587ded080aa62b104af1d66f0b79 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 20 Nov 2018 16:18:17 -0800 Subject: [PATCH 0269/2143] removed all constraints from custom toolchain --- third_party/toolchains/BUILD | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 2a68f3e7ccc..7506c6a1fbb 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -79,19 +79,8 @@ platform( toolchain( name = "cc-toolchain-clang-x86_64-default", exec_compatible_with = [ - "@bazel_tools//platforms:linux", - "@bazel_tools//platforms:x86_64", - "@bazel_tools//tools/cpp:clang", - "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", - "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", - "//third_party/toolchains/machine_size:standard", - "//third_party/toolchains/machine_size:large", ], target_compatible_with = [ - "//third_party/toolchains:rbe_ubuntu1604", - "//third_party/toolchains:rbe_ubuntu1604_large", - "@bazel_tools//platforms:linux", - "@bazel_tools//platforms:x86_64", ], toolchain = "@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:cc-compiler-k8", toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", From c51d9c169e248d4231805f93ee32393974ac44d0 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 20 Nov 2018 15:21:29 -0800 Subject: [PATCH 0270/2143] Wrap pthread_atwork call --- src/php/ext/grpc/php_grpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index cbc7f63be07..492325b1e8b 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -200,7 +200,9 @@ void postfork_parent() { void register_fork_handlers() { if (getenv("GRPC_ENABLE_FORK_SUPPORT")) { +#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK pthread_atfork(&prefork, &postfork_parent, &postfork_child); +#endif // GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK } } From 42e3ae730913cff77b8c9eec7fb0bccd7e0b7db9 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 20 Nov 2018 23:36:04 -0800 Subject: [PATCH 0271/2143] Re-generate 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 | 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_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/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 +- 31 files changed, 36 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 92dec7da80e..17f5f4ca637 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.17.0-pre1") +set(PACKAGE_VERSION "1.17.0-pre2") 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 10dfd976236..3ac25a788dd 100644 --- a/Makefile +++ b/Makefile @@ -437,9 +437,9 @@ E = @echo Q = @ endif -CORE_VERSION = 7.0.0-pre1 -CPP_VERSION = 1.17.0-pre1 -CSHARP_VERSION = 1.17.0-pre1 +CORE_VERSION = 7.0.0-pre2 +CPP_VERSION = 1.17.0-pre2 +CSHARP_VERSION = 1.17.0-pre2 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 6e0267723b6..5aea7c6f8cd 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.17.0-pre1' + # version = '1.17.0-pre2' version = '0.0.4' 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.17.0-pre1' + grpc_version = '1.17.0-pre2' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 42ee1176cca..65e0528e572 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.17.0-pre1' + version = '1.17.0-pre2' 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 bed6f8480b1..719da004785 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.17.0-pre1' + version = '1.17.0-pre2' 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 67a087d9b68..56b95d1642a 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.17.0-pre1' + version = '1.17.0-pre2' 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 c99386bb866..9b856456151 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.17.0-pre1' + version = '1.17.0-pre2' 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 471cee33f9d..433fdad8409 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.17.0RC1 - 1.17.0RC1 + 1.17.0RC2 + 1.17.0RC2 beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 3ca1d830f7c..625c1bd59a2 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-pre2"; } const char* grpc_g_stands_for(void) { return "gizmo"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 77c2cdd7d53..33643848fa0 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.17.0-pre1"; } +grpc::string Version() { return "1.17.0-pre2"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 80bc939280f..ade0cfdeecc 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.17.0-pre1 + 1.17.0-pre2 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 25d114686fb..3a060caeb2f 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.17.0-pre1"; + public const string CurrentVersion = "1.17.0-pre2"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 23caffec0ce..af3354fa664 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.17.0-pre1 +set VERSION=1.17.0-pre2 @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 1ceefef6d69..71e3a7302a6 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.17.0-pre1 +set VERSION=1.17.0-pre2 @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 020737b62ce..ae5a976ecc6 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.17.0-pre1' + v = '1.17.0-pre2' 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 a5603b5c7d2..2e4f01f9a4e 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.17.0-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.17.0-pre2" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 41a8c10ec24..cfe1ff98e55 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.17.0-pre1" -#define GRPC_C_VERSION_STRING @"7.0.0-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.17.0-pre2" +#define GRPC_C_VERSION_STRING @"7.0.0-pre2" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 5bfb987aaa2..5b6d808c728 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.17.0RC1" +#define PHP_GRPC_VERSION "1.17.0RC2" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index a1b8f105d54..cf0f72fe63a 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.17.0rc1""" +__version__ = """1.17.0rc2""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index be2aac35949..dd0817c1444 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.17.0rc1' +VERSION = '1.17.0rc2' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index befd54a4f21..1c6f6aa7c23 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.17.0rc1' +VERSION = '1.17.0rc2' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index c940f290c85..cd97840cb4b 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.17.0rc1' +VERSION = '1.17.0rc2' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 99b6bd90171..d019ce75ad3 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.17.0rc1' +VERSION = '1.17.0rc2' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 5aa6f60dcca..cc59a197375 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.17.0rc1' +VERSION = '1.17.0rc2' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 099d33debb4..d1fa0b60fa2 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.17.0.pre1' + VERSION = '1.17.0.pre2' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index f6d24eaaa33..f30e5074840 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.17.0.pre1' + VERSION = '1.17.0.pre2' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 7f4448d0b4b..9cad73cb39e 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.17.0rc1' +VERSION = '1.17.0rc2' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index cb4ebb465bf..eb41083bc56 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.17.0-pre1 +PROJECT_NUMBER = 1.17.0-pre2 # 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 f52eee8e005..b888c408307 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.17.0-pre1 +PROJECT_NUMBER = 1.17.0-pre2 # 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 5ef4357e92b..29a4ba79b16 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-pre2 # 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 83a25e2b594..acaf04a7c6c 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-pre2 # 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 989af50e1de41e49ca5fab5c36aa77260f113915 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Wed, 21 Nov 2018 00:17:25 -0800 Subject: [PATCH 0272/2143] Remove beta modules from the Python Bazel package --- src/python/grpcio/grpc/BUILD.bazel | 1 - 1 file changed, 1 deletion(-) diff --git a/src/python/grpcio/grpc/BUILD.bazel b/src/python/grpcio/grpc/BUILD.bazel index 2e6839ef2d8..6958ccdfb66 100644 --- a/src/python/grpcio/grpc/BUILD.bazel +++ b/src/python/grpcio/grpc/BUILD.bazel @@ -13,7 +13,6 @@ py_library( ":interceptor", ":server", "//src/python/grpcio/grpc/_cython:cygrpc", - "//src/python/grpcio/grpc/beta", "//src/python/grpcio/grpc/experimental", "//src/python/grpcio/grpc/framework", requirement('enum34'), From 64c5f313ef9c38c1e7f13b3560c0d48f08eea3eb Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 21 Nov 2018 09:47:25 +0100 Subject: [PATCH 0273/2143] avoid c-ares dependency on libnsl --- cmake/cares.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/cares.cmake b/cmake/cares.cmake index 3d4a0cae765..4ea0d8725d0 100644 --- a/cmake/cares.cmake +++ b/cmake/cares.cmake @@ -18,6 +18,10 @@ if("${gRPC_CARES_PROVIDER}" STREQUAL "module") endif() set(CARES_SHARED OFF CACHE BOOL "disable shared library") set(CARES_STATIC ON CACHE BOOL "link cares statically") + if(gRPC_BACKWARDS_COMPATIBILITY_MODE) + # See https://github.com/grpc/grpc/issues/17255 + set(HAVE_LIBNSL OFF CACHE BOOL "avoid cares dependency on libnsl") + endif() add_subdirectory(third_party/cares/cares) if(TARGET c-ares) From 609cb8daa047833dc7062bd749a24b9a85359151 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 21 Nov 2018 12:47:31 +0100 Subject: [PATCH 0274/2143] Revert "Revert "pin google-api-python-client to 1.6.7 to avoid breakage"" --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 62e75b84a23..24a3545dedc 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -28,7 +28,8 @@ sudo systemsetup -setusingnetworktime on date # Add GCP credentials for BQ access -pip install google-api-python-client --user python +# pin google-api-python-client to avoid https://github.com/grpc/grpc/issues/15600 +pip install google-api-python-client==1.6.7 --user python export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests From 5a0f72259072c1ff0002126de0fb4b8fa4f33329 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 5 Jun 2018 14:56:15 +0200 Subject: [PATCH 0275/2143] run interop tests using python3.4 --- .../interoptest/grpc_interop_python/build_interop.sh | 4 ++-- tools/run_tests/run_interop_tests.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh index 7917e1cd60d..ee042d40c89 100755 --- a/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh @@ -28,5 +28,5 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc -# interop tests only run using python2.7 currently (and python build is slow) -tools/run_tests/run_tests.py -l python --compiler python2.7 -c opt --build_only +# interop tests only run using python3.4 currently (and python build is slow) +tools/run_tests/run_tests.py -l python --compiler python3.4 -c opt --build_only diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index ff6682c3cf8..1983220463c 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -545,13 +545,13 @@ class PythonLanguage: def client_cmd(self, args): return [ - 'py27_native/bin/python', 'src/python/grpcio_tests/setup.py', + 'py34_native/bin/python', 'src/python/grpcio_tests/setup.py', 'run_interop', '--client', '--args="{}"'.format(' '.join(args)) ] def client_cmd_http2interop(self, args): return [ - 'py27_native/bin/python', + 'py34_native/bin/python', 'src/python/grpcio_tests/tests/http2/negative_http2_client.py', ] + args @@ -560,7 +560,7 @@ class PythonLanguage: def server_cmd(self, args): return [ - 'py27_native/bin/python', 'src/python/grpcio_tests/setup.py', + 'py34_native/bin/python', 'src/python/grpcio_tests/setup.py', 'run_interop', '--server', '--args="{}"'.format(' '.join(args)) ] From 95bae1ead938dfade8b120350a79b3cbebb7e797 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 6 Jun 2018 10:31:45 +0200 Subject: [PATCH 0276/2143] make client_email loading python3 compatible --- src/python/grpcio_tests/tests/interop/methods.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index 721dedf0b75..d0a9c7aaf0e 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -422,7 +422,7 @@ def _compute_engine_creds(stub, args): def _oauth2_auth_token(stub, args): json_key_filename = os.environ[google_auth_environment_vars.CREDENTIALS] - wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] + wanted_email = json.load(open(json_key_filename, 'r'))['client_email'] response = _large_unary_common_behavior(stub, True, True, None) if wanted_email != response.username: raise ValueError('expected username %s, got %s' % (wanted_email, @@ -435,7 +435,7 @@ def _oauth2_auth_token(stub, args): def _jwt_token_creds(stub, args): json_key_filename = os.environ[google_auth_environment_vars.CREDENTIALS] - wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] + wanted_email = json.load(open(json_key_filename, 'r'))['client_email'] response = _large_unary_common_behavior(stub, True, False, None) if wanted_email != response.username: raise ValueError('expected username %s, got %s' % (wanted_email, @@ -444,7 +444,7 @@ def _jwt_token_creds(stub, args): def _per_rpc_creds(stub, args): json_key_filename = os.environ[google_auth_environment_vars.CREDENTIALS] - wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] + wanted_email = json.load(open(json_key_filename, 'r'))['client_email'] google_credentials, unused_project_id = google_auth.default( scopes=[args.oauth_scope]) call_credentials = grpc.metadata_call_credentials( From 29f44db128d02de35ecae5465d375fa5f9349dbf Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 21 Nov 2018 19:06:14 +0100 Subject: [PATCH 0277/2143] fix initial->trailing --- src/python/grpcio_tests/tests/interop/methods.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index d0a9c7aaf0e..1a3b964f94c 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -391,7 +391,7 @@ def _custom_metadata(stub): if trailing_metadata[_TRAILING_METADATA_KEY] != trailing_metadata_value: raise ValueError('expected trailing metadata %s, got %s' % (trailing_metadata_value, - initial_metadata[_TRAILING_METADATA_KEY])) + trailing_metadata[_TRAILING_METADATA_KEY])) # Testing with UnaryCall request = messages_pb2.SimpleRequest( From b609caebf1cf843ebf61e255dd5aeabd825b96d2 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 21 Nov 2018 19:12:15 +0100 Subject: [PATCH 0278/2143] trailing "-bin" metadata is binary --- src/python/grpcio_tests/tests/interop/methods.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index 1a3b964f94c..a96386a6db1 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -377,7 +377,7 @@ def _unimplemented_service(unimplemented_service_stub): def _custom_metadata(stub): initial_metadata_value = "test_initial_metadata_value" - trailing_metadata_value = "\x0a\x0b\x0a\x0b\x0a\x0b" + trailing_metadata_value = b"\x0a\x0b\x0a\x0b\x0a\x0b" metadata = ((_INITIAL_METADATA_KEY, initial_metadata_value), (_TRAILING_METADATA_KEY, trailing_metadata_value)) From d9dbb76969632489f0304128474e0706aaed340f Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Tue, 20 Nov 2018 13:36:37 -0800 Subject: [PATCH 0279/2143] Allow specifying specific credential types to reach specific works in QPS benchmark driver --- test/cpp/qps/driver.cc | 36 ++++-- test/cpp/qps/driver.h | 9 +- .../qps/inproc_sync_unary_ping_pong_test.cc | 2 +- test/cpp/qps/qps_json_driver.cc | 111 +++++++++++++----- test/cpp/qps/qps_openloop_test.cc | 2 +- .../qps/secure_sync_unary_ping_pong_test.cc | 2 +- 6 files changed, 121 insertions(+), 41 deletions(-) diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 11cfb4aa05a..181e11f12b2 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -95,6 +95,17 @@ static deque get_workers(const string& env_name) { return out; } +std::string GetCredType( + const std::string& worker_addr, + const std::map& per_worker_credential_types, + const std::string& credential_type) { + auto it = per_worker_credential_types.find(worker_addr); + if (it != per_worker_credential_types.end()) { + return it->second; + } + return credential_type; +} + // helpers for postprocess_scenario_result static double WallTime(const ClientStats& s) { return s.time_elapsed(); } static double SystemTime(const ClientStats& s) { return s.time_system(); } @@ -198,8 +209,9 @@ std::unique_ptr RunScenario( const ServerConfig& initial_server_config, size_t num_servers, int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count, const grpc::string& qps_server_target_override, - const grpc::string& credential_type, bool run_inproc, - int32_t median_latency_collection_interval_millis) { + const grpc::string& credential_type, + const std::map& per_worker_credential_types, + bool run_inproc, int32_t median_latency_collection_interval_millis) { if (run_inproc) { g_inproc_servers = new std::vector; } @@ -278,7 +290,9 @@ std::unique_ptr RunScenario( if (!run_inproc) { servers[i].stub = WorkerService::NewStub(CreateChannel( workers[i], GetCredentialsProvider()->GetChannelCredentials( - credential_type, &channel_args))); + GetCredType(workers[i], per_worker_credential_types, + credential_type), + &channel_args))); } else { servers[i].stub = WorkerService::NewStub( local_workers[i]->InProcessChannel(channel_args)); @@ -335,9 +349,11 @@ std::unique_ptr RunScenario( gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")", worker.c_str(), i + num_servers); if (!run_inproc) { - clients[i].stub = WorkerService::NewStub( - CreateChannel(worker, GetCredentialsProvider()->GetChannelCredentials( - credential_type, &channel_args))); + clients[i].stub = WorkerService::NewStub(CreateChannel( + worker, + GetCredentialsProvider()->GetChannelCredentials( + GetCredType(worker, per_worker_credential_types, credential_type), + &channel_args))); } else { clients[i].stub = WorkerService::NewStub( local_workers[i + num_servers]->InProcessChannel(channel_args)); @@ -529,7 +545,9 @@ std::unique_ptr RunScenario( return result; } -bool RunQuit(const grpc::string& credential_type) { +bool RunQuit( + const grpc::string& credential_type, + const std::map& per_worker_credential_types) { // Get client, server lists bool result = true; auto workers = get_workers("QPS_WORKERS"); @@ -541,7 +559,9 @@ bool RunQuit(const grpc::string& credential_type) { for (size_t i = 0; i < workers.size(); i++) { auto stub = WorkerService::NewStub(CreateChannel( workers[i], GetCredentialsProvider()->GetChannelCredentials( - credential_type, &channel_args))); + GetCredType(workers[i], per_worker_credential_types, + credential_type), + &channel_args))); Void dummy; grpc::ClientContext ctx; ctx.set_wait_for_ready(true); diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h index cda89f7ddfd..568871d2daa 100644 --- a/test/cpp/qps/driver.h +++ b/test/cpp/qps/driver.h @@ -32,10 +32,13 @@ std::unique_ptr RunScenario( const grpc::testing::ServerConfig& server_config, size_t num_servers, int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count, const grpc::string& qps_server_target_override, - const grpc::string& credential_type, bool run_inproc, - int32_t median_latency_collection_interval_millis); + const grpc::string& credential_type, + const std::map& per_worker_credential_types, + bool run_inproc, int32_t median_latency_collection_interval_millis); -bool RunQuit(const grpc::string& credential_type); +bool RunQuit( + const grpc::string& credential_type, + const std::map& per_worker_credential_types); } // namespace testing } // namespace grpc diff --git a/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc b/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc index 56d1730252f..6257e42ebf4 100644 --- a/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc +++ b/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc @@ -48,7 +48,7 @@ static void RunSynchronousUnaryPingPong() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "", - kInsecureCredentialsType, true, 0); + kInsecureCredentialsType, {}, true, 0); GetReporter()->ReportQPS(*result); GetReporter()->ReportLatency(*result); diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc index eaa0dd992c5..2b81cca2d60 100644 --- a/test/cpp/qps/qps_json_driver.cc +++ b/test/cpp/qps/qps_json_driver.cc @@ -65,6 +65,16 @@ DEFINE_string(json_file_out, "", "File to write the JSON output to."); DEFINE_string(credential_type, grpc::testing::kInsecureCredentialsType, "Credential type for communication with workers"); +DEFINE_string( + per_worker_credential_types, "", + "A map of QPS worker addresses to credential types. When creating a " + "channel to a QPS worker's driver port, the qps_json_driver first checks " + "if the 'name:port' string is in the map, and it uses the corresponding " + "credential type if so. If the QPS worker's 'name:port' string is not " + "in the map, then the driver -> worker channel will be created with " + "the credentials specified in --credential_type. The value of this flag " + "is a semicolon-separated list of map entries, where each map entry is " + "a comma-separated pair."); DEFINE_bool(run_inproc, false, "Perform an in-process transport test"); DEFINE_int32( median_latency_collection_interval_millis, 0, @@ -75,16 +85,53 @@ DEFINE_int32( namespace grpc { namespace testing { -static std::unique_ptr RunAndReport(const Scenario& scenario, - bool* success) { +static std::map +ConstructPerWorkerCredentialTypesMap() { + // Parse a list of the form: "addr1,cred_type1;addr2,cred_type2;..." into + // a map. + std::string remaining = FLAGS_per_worker_credential_types; + std::map out; + while (remaining.size() > 0) { + size_t next_semicolon = remaining.find(';'); + std::string next_entry = remaining.substr(0, next_semicolon); + if (next_semicolon == std::string::npos) { + remaining = ""; + } else { + remaining = remaining.substr(next_semicolon + 1, std::string::npos); + } + size_t comma = next_entry.find(','); + if (comma == std::string::npos) { + gpr_log(GPR_ERROR, + "Expectd --per_worker_credential_types to be a list " + "of the form: 'addr1,cred_type1;addr2,cred_type2;...' " + "into."); + abort(); + } + std::string addr = next_entry.substr(0, comma); + std::string cred_type = next_entry.substr(comma + 1, std::string::npos); + if (out.find(addr) != out.end()) { + gpr_log(GPR_ERROR, + "Found duplicate addr in per_worker_credential_types."); + abort(); + } + out[addr] = cred_type; + } + return out; +} + +static std::unique_ptr RunAndReport( + const Scenario& scenario, + const std::map& per_worker_credential_types, + bool* success) { std::cerr << "RUNNING SCENARIO: " << scenario.name() << "\n"; - auto result = RunScenario( - scenario.client_config(), scenario.num_clients(), - scenario.server_config(), scenario.num_servers(), - scenario.warmup_seconds(), scenario.benchmark_seconds(), - !FLAGS_run_inproc ? scenario.spawn_local_worker_count() : -2, - FLAGS_qps_server_target_override, FLAGS_credential_type, FLAGS_run_inproc, - FLAGS_median_latency_collection_interval_millis); + auto result = + RunScenario(scenario.client_config(), scenario.num_clients(), + scenario.server_config(), scenario.num_servers(), + scenario.warmup_seconds(), scenario.benchmark_seconds(), + !FLAGS_run_inproc ? scenario.spawn_local_worker_count() : -2, + FLAGS_qps_server_target_override, FLAGS_credential_type, + per_worker_credential_types, FLAGS_run_inproc, + FLAGS_median_latency_collection_interval_millis); // Amend the result with scenario config. Eventually we should adjust // RunScenario contract so we don't need to touch the result here. @@ -115,21 +162,26 @@ static std::unique_ptr RunAndReport(const Scenario& scenario, return result; } -static double GetCpuLoad(Scenario* scenario, double offered_load, - bool* success) { +static double GetCpuLoad( + Scenario* scenario, double offered_load, + const std::map& per_worker_credential_types, + bool* success) { scenario->mutable_client_config() ->mutable_load_params() ->mutable_poisson() ->set_offered_load(offered_load); - auto result = RunAndReport(*scenario, success); + auto result = RunAndReport(*scenario, per_worker_credential_types, success); return result->summary().server_cpu_usage(); } -static double BinarySearch(Scenario* scenario, double targeted_cpu_load, - double low, double high, bool* success) { +static double BinarySearch( + Scenario* scenario, double targeted_cpu_load, double low, double high, + const std::map& per_worker_credential_types, + bool* success) { while (low <= high * (1 - FLAGS_error_tolerance)) { double mid = low + (high - low) / 2; - double current_cpu_load = GetCpuLoad(scenario, mid, success); + double current_cpu_load = + GetCpuLoad(scenario, mid, per_worker_credential_types, success); gpr_log(GPR_DEBUG, "Binary Search: current_offered_load %.0f", mid); if (!*success) { gpr_log(GPR_ERROR, "Client/Server Failure"); @@ -145,12 +197,14 @@ static double BinarySearch(Scenario* scenario, double targeted_cpu_load, return low; } -static double SearchOfferedLoad(double initial_offered_load, - double targeted_cpu_load, Scenario* scenario, - bool* success) { +static double SearchOfferedLoad( + double initial_offered_load, double targeted_cpu_load, Scenario* scenario, + const std::map& per_worker_credential_types, + bool* success) { std::cerr << "RUNNING SCENARIO: " << scenario->name() << "\n"; double current_offered_load = initial_offered_load; - double current_cpu_load = GetCpuLoad(scenario, current_offered_load, success); + double current_cpu_load = GetCpuLoad(scenario, current_offered_load, + per_worker_credential_types, success); if (current_cpu_load > targeted_cpu_load) { gpr_log(GPR_ERROR, "Initial offered load too high"); return -1; @@ -158,14 +212,15 @@ static double SearchOfferedLoad(double initial_offered_load, while (*success && (current_cpu_load < targeted_cpu_load)) { current_offered_load *= 2; - current_cpu_load = GetCpuLoad(scenario, current_offered_load, success); + current_cpu_load = GetCpuLoad(scenario, current_offered_load, + per_worker_credential_types, success); gpr_log(GPR_DEBUG, "Binary Search: current_offered_load %.0f", current_offered_load); } double targeted_offered_load = BinarySearch(scenario, targeted_cpu_load, current_offered_load / 2, - current_offered_load, success); + current_offered_load, per_worker_credential_types, success); return targeted_offered_load; } @@ -183,6 +238,7 @@ static bool QpsDriver() { abort(); } + auto per_worker_credential_types = ConstructPerWorkerCredentialTypesMap(); if (scfile) { // Read the json data from disk FILE* json_file = fopen(FLAGS_scenarios_file.c_str(), "r"); @@ -198,7 +254,7 @@ static bool QpsDriver() { } else if (scjson) { json = FLAGS_scenarios_json.c_str(); } else if (FLAGS_quit) { - return RunQuit(FLAGS_credential_type); + return RunQuit(FLAGS_credential_type, per_worker_credential_types); } // Parse into an array of scenarios @@ -212,15 +268,16 @@ static bool QpsDriver() { for (int i = 0; i < scenarios.scenarios_size(); i++) { if (FLAGS_search_param == "") { const Scenario& scenario = scenarios.scenarios(i); - RunAndReport(scenario, &success); + RunAndReport(scenario, per_worker_credential_types, &success); } else { if (FLAGS_search_param == "offered_load") { Scenario* scenario = scenarios.mutable_scenarios(i); - double targeted_offered_load = - SearchOfferedLoad(FLAGS_initial_search_value, - FLAGS_targeted_cpu_load, scenario, &success); + double targeted_offered_load = SearchOfferedLoad( + FLAGS_initial_search_value, FLAGS_targeted_cpu_load, scenario, + per_worker_credential_types, &success); gpr_log(GPR_INFO, "targeted_offered_load %f", targeted_offered_load); - GetCpuLoad(scenario, targeted_offered_load, &success); + GetCpuLoad(scenario, targeted_offered_load, per_worker_credential_types, + &success); } else { gpr_log(GPR_ERROR, "Unimplemented search param"); } diff --git a/test/cpp/qps/qps_openloop_test.cc b/test/cpp/qps/qps_openloop_test.cc index 6044f4265a3..68062e66f25 100644 --- a/test/cpp/qps/qps_openloop_test.cc +++ b/test/cpp/qps/qps_openloop_test.cc @@ -52,7 +52,7 @@ static void RunQPS() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "", - kInsecureCredentialsType, false, 0); + kInsecureCredentialsType, {}, false, 0); GetReporter()->ReportQPSPerCore(*result); GetReporter()->ReportLatency(*result); diff --git a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc index a559c82cc81..422bd617ebc 100644 --- a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc +++ b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc @@ -55,7 +55,7 @@ static void RunSynchronousUnaryPingPong() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "", - kInsecureCredentialsType, false, 0); + kInsecureCredentialsType, {}, false, 0); GetReporter()->ReportQPS(*result); GetReporter()->ReportLatency(*result); From d704cfe3d11ae32a833e9b995f87d5e2d15bacef Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 21 Nov 2018 11:48:14 -0800 Subject: [PATCH 0280/2143] Add can_track_err methods to other platforms too --- src/core/lib/iomgr/endpoint_cfstream.cc | 5 ++++- src/core/lib/iomgr/tcp_windows.cc | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc index df2cf508c8f..7c4bc1ace2a 100644 --- a/src/core/lib/iomgr/endpoint_cfstream.cc +++ b/src/core/lib/iomgr/endpoint_cfstream.cc @@ -315,6 +315,8 @@ char* CFStreamGetPeer(grpc_endpoint* ep) { int CFStreamGetFD(grpc_endpoint* ep) { return 0; } +bool CFStreamCanTrackErr(grpc_endpoint* ep) { return false; } + void CFStreamAddToPollset(grpc_endpoint* ep, grpc_pollset* pollset) {} void CFStreamAddToPollsetSet(grpc_endpoint* ep, grpc_pollset_set* pollset) {} void CFStreamDeleteFromPollsetSet(grpc_endpoint* ep, @@ -329,7 +331,8 @@ static const grpc_endpoint_vtable vtable = {CFStreamRead, CFStreamDestroy, CFStreamGetResourceUser, CFStreamGetPeer, - CFStreamGetFD}; + CFStreamGetFD, + CFStreamCanTrackErr}; grpc_endpoint* grpc_cfstream_endpoint_create( CFReadStreamRef read_stream, CFWriteStreamRef write_stream, diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 64c4a56ae95..4b5250803d1 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -427,6 +427,8 @@ static grpc_resource_user* win_get_resource_user(grpc_endpoint* ep) { static int win_get_fd(grpc_endpoint* ep) { return -1; } +static bool win_can_track_err(grpc_endpoint* ep) { return false; } + static grpc_endpoint_vtable vtable = {win_read, win_write, win_add_to_pollset, @@ -436,7 +438,8 @@ static grpc_endpoint_vtable vtable = {win_read, win_destroy, win_get_resource_user, win_get_peer, - win_get_fd}; + win_get_fd, + win_can_track_err}; grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket, grpc_channel_args* channel_args, From 107539c0d70da3428169d75ec708ecb251d86ec4 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Wed, 21 Nov 2018 13:37:02 -0800 Subject: [PATCH 0281/2143] Removed unused import from grpc.beta in tests --- src/python/grpcio_tests/tests/interop/methods.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index 721dedf0b75..60e0f82cf7b 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -23,7 +23,6 @@ from google.auth import environment_vars as google_auth_environment_vars from google.auth.transport import grpc as google_auth_transport_grpc from google.auth.transport import requests as google_auth_transport_requests import grpc -from grpc.beta import implementations from src.proto.grpc.testing import empty_pb2 from src.proto.grpc.testing import messages_pb2 From e69c1b960f61e3699338abed7e9f5b60a031fd66 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Wed, 21 Nov 2018 13:40:10 -0800 Subject: [PATCH 0282/2143] Remove BUILD.bazel files from beta code elements Beta code elements are going to get deprecated and Bazel support is much newer, so Bazel users are not supposed to accidentally depend on beta code elements. Preventing Bazel from building and including beta code elements makes our tests pass without depending on beta in grpcio target and helps avoid including that dependency accidentally if you are using Bazel. --- src/python/grpcio/grpc/beta/BUILD.bazel | 58 -------------- .../grpcio_tests/tests/unit/beta/BUILD.bazel | 75 ------------------- 2 files changed, 133 deletions(-) delete mode 100644 src/python/grpcio/grpc/beta/BUILD.bazel delete mode 100644 src/python/grpcio_tests/tests/unit/beta/BUILD.bazel diff --git a/src/python/grpcio/grpc/beta/BUILD.bazel b/src/python/grpcio/grpc/beta/BUILD.bazel deleted file mode 100644 index 731be5cb25b..00000000000 --- a/src/python/grpcio/grpc/beta/BUILD.bazel +++ /dev/null @@ -1,58 +0,0 @@ -load("@grpc_python_dependencies//:requirements.bzl", "requirement") -package(default_visibility = ["//visibility:public"]) - -py_library( - name = "beta", - srcs = ["__init__.py",], - deps = [ - ":client_adaptations", - ":metadata", - ":server_adaptations", - ":implementations", - ":interfaces", - ":utilities", - ], -) - -py_library( - name = "client_adaptations", - srcs = ["_client_adaptations.py"], - imports=["../../",] -) - -py_library( - name = "metadata", - srcs = ["_metadata.py"], -) - -py_library( - name = "server_adaptations", - srcs = ["_server_adaptations.py"], - imports=["../../",], -) - -py_library( - name = "implementations", - srcs = ["implementations.py"], - imports=["../../",], -) - -py_library( - name = "interfaces", - srcs = ["interfaces.py"], - deps = [ - requirement("six"), - ], - imports=["../../",], -) - -py_library( - name = "utilities", - srcs = ["utilities.py"], - deps = [ - ":implementations", - ":interfaces", - "//src/python/grpcio/grpc/framework/foundation", - ], -) - diff --git a/src/python/grpcio_tests/tests/unit/beta/BUILD.bazel b/src/python/grpcio_tests/tests/unit/beta/BUILD.bazel deleted file mode 100644 index d3e0fe20eb7..00000000000 --- a/src/python/grpcio_tests/tests/unit/beta/BUILD.bazel +++ /dev/null @@ -1,75 +0,0 @@ -load("@grpc_python_dependencies//:requirements.bzl", "requirement") - -package(default_visibility = ["//visibility:public"]) - -py_library( - name = "test_utilities", - srcs = ["test_utilities.py"], - deps = [ - "//src/python/grpcio/grpc:grpcio", - ], -) - -py_test( - name = "_beta_features_test", - srcs = ["_beta_features_test.py"], - main = "_beta_features_test.py", - size = "small", - deps = [ - "//src/python/grpcio/grpc:grpcio", - "//src/python/grpcio_tests/tests/unit:resources", - "//src/python/grpcio_tests/tests/unit/framework/common", - ":test_utilities", - ], - imports=["../../../",], -) - -py_test( - name = "_connectivity_channel_test", - srcs = ["_connectivity_channel_test.py"], - main = "_connectivity_channel_test.py", - size = "small", - deps = [ - "//src/python/grpcio/grpc:grpcio", - ], -) - -# TODO(ghostwriternr): To be added later. -#py_test( -# name = "_implementations_test", -# srcs = ["_implementations_test.py"], -# main = "_implementations_test.py", -# size = "small", -# deps = [ -# "//src/python/grpcio/grpc:grpcio", -# "//src/python/grpcio_tests/tests/unit:resources", -# requirement('oauth2client'), -# ], -# imports=["../../../",], -#) - -py_test( - name = "_not_found_test", - srcs = ["_not_found_test.py"], - main = "_not_found_test.py", - size = "small", - deps = [ - "//src/python/grpcio/grpc:grpcio", - "//src/python/grpcio_tests/tests/unit/framework/common", - ], - imports=["../../../",], -) - -py_test( - name = "_utilities_test", - srcs = ["_utilities_test.py"], - main = "_utilities_test.py", - size = "small", - deps = [ - "//src/python/grpcio/grpc:grpcio", - "//src/python/grpcio_tests/tests/unit/framework/common", - ], - imports=["../../../",], -) - - From 96a0db9575988cc669e9081d7a142abeac91a022 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 21 Nov 2018 13:46:02 -0800 Subject: [PATCH 0283/2143] Use 'preX' when pre-releasing gRPC-C++.podspec --- gRPC-C++.podspec | 2 +- templates/gRPC-C++.podspec.template | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 5aea7c6f8cd..8bacc33966b 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.17.0-pre2' - version = '0.0.4' + version = '0.0.6-pre2' 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 ab330415af2..94d5a4fb09e 100644 --- a/templates/gRPC-C++.podspec.template +++ b/templates/gRPC-C++.podspec.template @@ -127,12 +127,20 @@ def ruby_multiline_list(files, indent): return (',\n' + indent*' ').join('\'%s\'' % f for f in files) + + def modify_podspec_version_string(pod_version, grpc_version): + # Append -preX when it is a pre-release + if len(str(grpc_version).split('-')) > 1: + return pod_version + '-' + str(grpc_version).split('-')[-1] + else: + return pod_version + %> Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized # version = '${settings.version}' - version = '0.0.4' + version = '${modify_podspec_version_string('0.0.6', settings.version)}' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' From 544f2a5abbee840c5b7a28b41e75b3ff5c0f3b60 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 21 Nov 2018 14:00:16 -0800 Subject: [PATCH 0284/2143] Necessary change after #17219 --- include/grpcpp/impl/codegen/client_unary_call.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index b1c80764f23..18ee5b34bfa 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -75,7 +75,12 @@ class BlockingUnaryCallImpl { "No message returned for unary request"); } } else { - GPR_CODEGEN_ASSERT(!status_.ok()); + // Some of the ops failed. For example, this can happen if deserialization + // of the message fails. gRPC Core guarantees that the op + // GRPC_OP_RECV_STATUS_ON_CLIENT always succeeds, so status would still be + // filled. + // TODO(yashykt): If deserialization fails, but the status received is OK, + // then it might be a good idea to change the status to reflect this. } } Status status() { return status_; } From 8fb11e6d5e2228523f79c3ed8ee1b4d8fb4b7174 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 21 Nov 2018 14:11:59 -0800 Subject: [PATCH 0285/2143] Apply the conversion on the status irrespective of whether Pluck returned true --- .../grpcpp/impl/codegen/client_unary_call.h | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index 18ee5b34bfa..5151839412b 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -69,18 +69,17 @@ class BlockingUnaryCallImpl { ops.ClientSendClose(); ops.ClientRecvStatus(context, &status_); call.PerformOps(&ops); - if (cq.Pluck(&ops)) { - if (!ops.got_message && status_.ok()) { - status_ = Status(StatusCode::UNIMPLEMENTED, - "No message returned for unary request"); - } - } else { - // Some of the ops failed. For example, this can happen if deserialization - // of the message fails. gRPC Core guarantees that the op - // GRPC_OP_RECV_STATUS_ON_CLIENT always succeeds, so status would still be - // filled. - // TODO(yashykt): If deserialization fails, but the status received is OK, - // then it might be a good idea to change the status to reflect this. + cq.Pluck(&ops); + // Some of the ops might fail. If the ops fail in the core layer, status + // would reflect the error. But, if the ops fail in the C++ layer, the + // status would still be the same as the one returned by gRPC Core. This can + // happen if deserialization of the message fails. + // TODO(yashykt): If deserialization fails, but the status received is OK, + // then it might be a good idea to change the status to something better + // than StatusCode::UNIMPLEMENTED to reflect this. + if (!ops.got_message && status_.ok()) { + status_ = Status(StatusCode::UNIMPLEMENTED, + "No message returned for unary request"); } } Status status() { return status_; } From 726f044932c2ae096d05f4f6cac2850ae2be3f83 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 21 Nov 2018 14:24:22 -0800 Subject: [PATCH 0286/2143] Include linux/version.h for manylinux --- include/grpc/impl/codegen/port_platform.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index b2028a63053..6795f05a6d9 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -121,6 +121,7 @@ #else /* _LP64 */ #define GPR_ARCH_32 1 #endif /* _LP64 */ +#include #elif defined(ANDROID) || defined(__ANDROID__) #define GPR_PLATFORM_STRING "android" #define GPR_ANDROID 1 From 03c73e92f1dedb1de4bba0269e7c614b47cf8035 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 21 Nov 2018 15:31:10 -0800 Subject: [PATCH 0287/2143] Fix test failure due to NSAssert --- src/objective-c/tests/Podfile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 5df9d4e85bd..12112f95e14 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -148,5 +148,14 @@ post_install do |installer| end end end + + # Enable NSAssert on gRPC + if target.name == 'gRPC' || target.name == 'ProtoRPC' || target.name == 'RxLibrary' + target.build_configurations.each do |config| + if config.name != 'Release' + config.build_settings['ENABLE_NS_ASSERTIONS'] = 'YES' + end + end + end end end From bd1fdfaabe6b330e83c7a8d4b3b7cefc477d02f4 Mon Sep 17 00:00:00 2001 From: ganmacs Date: Sun, 25 Nov 2018 17:31:53 +0900 Subject: [PATCH 0288/2143] Return unimplemented when calling a method which is server_streamer and is not implemented by user --- src/ruby/lib/grpc/generic/service.rb | 2 +- src/ruby/spec/generic/rpc_server_spec.rb | 22 ++++++++++++++++++++++ src/ruby/spec/support/services.rb | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/ruby/lib/grpc/generic/service.rb b/src/ruby/lib/grpc/generic/service.rb index 4764217406b..169a62f11d3 100644 --- a/src/ruby/lib/grpc/generic/service.rb +++ b/src/ruby/lib/grpc/generic/service.rb @@ -95,7 +95,7 @@ module GRPC rpc_descs[name] = RpcDesc.new(name, input, output, marshal_class_method, unmarshal_class_method) - define_method(GenericService.underscore(name.to_s).to_sym) do |_, _| + define_method(GenericService.underscore(name.to_s).to_sym) do |*| fail GRPC::BadStatus.new_status_exception( GRPC::Core::StatusCodes::UNIMPLEMENTED) end diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb index 44a61340869..924d747a79c 100644 --- a/src/ruby/spec/generic/rpc_server_spec.rb +++ b/src/ruby/spec/generic/rpc_server_spec.rb @@ -342,6 +342,28 @@ describe GRPC::RpcServer do t.join end + it 'should return UNIMPLEMENTED on unimplemented ' \ + 'methods for client_streamer', server: true do + @srv.handle(EchoService) + t = Thread.new { @srv.run } + @srv.wait_till_running + blk = proc do + stub = EchoStub.new(@host, :this_channel_is_insecure, **client_opts) + requests = [EchoMsg.new, EchoMsg.new] + stub.a_client_streaming_rpc_unimplemented(requests) + end + + begin + expect(&blk).to raise_error do |error| + expect(error).to be_a(GRPC::BadStatus) + expect(error.code).to eq(GRPC::Core::StatusCodes::UNIMPLEMENTED) + end + ensure + @srv.stop # should be call not to crash + t.join + end + end + it 'should handle multiple sequential requests', server: true do @srv.handle(EchoService) t = Thread.new { @srv.run } diff --git a/src/ruby/spec/support/services.rb b/src/ruby/spec/support/services.rb index 6e693f1cdec..438459dfd79 100644 --- a/src/ruby/spec/support/services.rb +++ b/src/ruby/spec/support/services.rb @@ -33,6 +33,7 @@ class EchoService rpc :a_client_streaming_rpc, stream(EchoMsg), EchoMsg rpc :a_server_streaming_rpc, EchoMsg, stream(EchoMsg) rpc :a_bidi_rpc, stream(EchoMsg), stream(EchoMsg) + rpc :a_client_streaming_rpc_unimplemented, stream(EchoMsg), EchoMsg attr_reader :received_md def initialize(**kw) From 422fdbfd6c96cb43d882f38c61c842d2110dd8b8 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 22 Nov 2018 09:40:28 +0100 Subject: [PATCH 0289/2143] run python interop tests with python3.7 --- .../interoptest/grpc_interop_python/build_interop.sh | 4 ++-- tools/run_tests/run_interop_tests.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh index ee042d40c89..468aa20e3fd 100755 --- a/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh @@ -28,5 +28,5 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc -# interop tests only run using python3.4 currently (and python build is slow) -tools/run_tests/run_tests.py -l python --compiler python3.4 -c opt --build_only +# interop tests only run using python3.7 currently (and python build is slow) +tools/run_tests/run_tests.py -l python --compiler python3.7 -c opt --build_only diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 1983220463c..021f21dcd42 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -545,13 +545,13 @@ class PythonLanguage: def client_cmd(self, args): return [ - 'py34_native/bin/python', 'src/python/grpcio_tests/setup.py', + 'py37_native/bin/python', 'src/python/grpcio_tests/setup.py', 'run_interop', '--client', '--args="{}"'.format(' '.join(args)) ] def client_cmd_http2interop(self, args): return [ - 'py34_native/bin/python', + 'py37_native/bin/python', 'src/python/grpcio_tests/tests/http2/negative_http2_client.py', ] + args @@ -560,7 +560,7 @@ class PythonLanguage: def server_cmd(self, args): return [ - 'py34_native/bin/python', 'src/python/grpcio_tests/setup.py', + 'py37_native/bin/python', 'src/python/grpcio_tests/setup.py', 'run_interop', '--server', '--args="{}"'.format(' '.join(args)) ] From b0bcfb4ea5d5a32828ba5e12eb60efc332562f65 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 22 Nov 2018 09:53:17 +0100 Subject: [PATCH 0290/2143] use python stretch3.7 image for interop tests --- .../grpc_interop_python/Dockerfile.template | 14 ++------ .../grpc_interop_python/Dockerfile | 33 +++++++++---------- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template index bf28796de38..f584a2378eb 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template @@ -14,15 +14,7 @@ # 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="../../python_deps.include"/> - # Install pip and virtualenv for Python 3.4 - RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4 - RUN python3.4 -m pip install virtualenv + <%include file="../../python_stretch.include"/> - <%include file="../../run_tests_addons.include"/> - # Define the default command. - CMD ["bash"] - + RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev + RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 diff --git a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile index dadd8567407..acad500f90c 100644 --- a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM debian:jessie - +FROM debian:stretch + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ @@ -49,27 +49,24 @@ RUN apt-get update && apt-get install -y \ # Build profiling RUN apt-get update && apt-get install -y time && apt-get clean -#==================== -# Python dependencies +# 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 -# Install dependencies +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 -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 - -# Install pip and virtualenv for Python 3.4 -RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4 -RUN python3.4 -m pip install virtualenv +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local RUN mkdir /var/local/jenkins # Define the default command. CMD ["bash"] + + +RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 From b5ee54add3c2b2d5063c9ed16cc9cc2dcdb5c860 Mon Sep 17 00:00:00 2001 From: ganmacs Date: Mon, 26 Nov 2018 19:50:50 +0900 Subject: [PATCH 0291/2143] Remove unused require --- src/ruby/pb/grpc/health/checker.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ruby/pb/grpc/health/checker.rb b/src/ruby/pb/grpc/health/checker.rb index c492455d8ff..0e357cbd0ca 100644 --- a/src/ruby/pb/grpc/health/checker.rb +++ b/src/ruby/pb/grpc/health/checker.rb @@ -14,7 +14,6 @@ require 'grpc' require 'grpc/health/v1/health_services_pb' -require 'thread' module Grpc # Health contains classes and modules that support providing a health check From 79f58ec74ebc4f0d7693109dd1abb856ae29296c Mon Sep 17 00:00:00 2001 From: ganmacs Date: Mon, 26 Nov 2018 19:51:07 +0900 Subject: [PATCH 0292/2143] Use space --- src/ruby/pb/grpc/health/checker.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ruby/pb/grpc/health/checker.rb b/src/ruby/pb/grpc/health/checker.rb index 0e357cbd0ca..7ad68409dd4 100644 --- a/src/ruby/pb/grpc/health/checker.rb +++ b/src/ruby/pb/grpc/health/checker.rb @@ -36,9 +36,9 @@ module Grpc @status_mutex.synchronize do status = @statuses["#{req.service}"] end - if status.nil? + if status.nil? fail GRPC::BadStatus.new_status_exception(StatusCodes::NOT_FOUND) - end + end HealthCheckResponse.new(status: status) end From d3631f9c799b1b5f50e1581d67e956db8a8816a3 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 26 Nov 2018 06:11:30 -0500 Subject: [PATCH 0293/2143] fix clang tidy --- test/cpp/qps/qps_json_driver.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc index 2b81cca2d60..1d67e79b868 100644 --- a/test/cpp/qps/qps_json_driver.cc +++ b/test/cpp/qps/qps_json_driver.cc @@ -91,7 +91,7 @@ ConstructPerWorkerCredentialTypesMap() { // a map. std::string remaining = FLAGS_per_worker_credential_types; std::map out; - while (remaining.size() > 0) { + while (!remaining.empty()) { size_t next_semicolon = remaining.find(';'); std::string next_entry = remaining.substr(0, next_semicolon); if (next_semicolon == std::string::npos) { From 70f9992d77e67f90234b079eabaa33210d866c87 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 26 Nov 2018 10:10:53 -0800 Subject: [PATCH 0294/2143] modified execution platform registration, added host platform --- WORKSPACE | 4 ---- third_party/toolchains/BUILD | 22 ++++++++++++++++++++++ tools/remote_build/rbe_common.bazelrc | 3 ++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index cd2718204d1..1340ba0c6be 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -6,10 +6,6 @@ grpc_deps() grpc_test_only_deps() -register_execution_platforms( - "//third_party/toolchains:all", -) - register_toolchains( "//third_party/toolchains:all", ) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 7506c6a1fbb..39699f31123 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -74,6 +74,28 @@ platform( """, ) +platform( + name = "host_platform-large", + constraint_values = [ + "//third_party/toolchains/machine_size:large", + ], + cpu_constraints = [ + "@bazel_tools//platforms:x86_32", + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:ppc", + "@bazel_tools//platforms:arm", + "@bazel_tools//platforms:aarch64", + "@bazel_tools//platforms:s390x", + ], + host_platform = True, + os_constraints = [ + "@bazel_tools//platforms:osx", + "@bazel_tools//platforms:freebsd", + "@bazel_tools//platforms:linux", + "@bazel_tools//platforms:windows", + ], +) + # This target is auto-generated from release/cpp.tpl and should not be # modified directly. toolchain( diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index 77ce96b8d4a..c1ee4280822 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -21,7 +21,7 @@ startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain build --extra_toolchains=//third_party/toolchains:cc-toolchain-clang-x86_64-default # Use custom execution platforms defined in third_party/toolchains -build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large +build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large,//third_party/toolchains:host_platform-large build --host_platform=//third_party/toolchains:rbe_ubuntu1604 build --platforms=//third_party/toolchains:rbe_ubuntu1604 @@ -69,6 +69,7 @@ build:tsan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:tsan --test_timeout=3600 build:tsan --test_tag_filters=-qps_json_driver,-json_run_localhost +build:tsan --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large # undefined behavior sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific From b7fd18daa469057d9dabc6787729fc746cca317c Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 21 Nov 2018 15:30:44 -0800 Subject: [PATCH 0295/2143] Raise the exception while credential initialization --- .../grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi | 2 ++ .../grpcio_tests/tests/unit/_credentials_test.py | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 63048e8da0d..ff523fb256c 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -129,6 +129,8 @@ cdef class SSLSessionCacheLRU: cdef class SSLChannelCredentials(ChannelCredentials): def __cinit__(self, pem_root_certificates, private_key, certificate_chain): + if pem_root_certificates is not None and not isinstance(pem_root_certificates, bytes): + raise TypeError('expected certificate to be bytes, got %s' % (type(pem_root_certificates))) self._pem_root_certificates = pem_root_certificates self._private_key = private_key self._certificate_chain = certificate_chain diff --git a/src/python/grpcio_tests/tests/unit/_credentials_test.py b/src/python/grpcio_tests/tests/unit/_credentials_test.py index be7378ecbce..187a6f03881 100644 --- a/src/python/grpcio_tests/tests/unit/_credentials_test.py +++ b/src/python/grpcio_tests/tests/unit/_credentials_test.py @@ -15,6 +15,7 @@ import unittest import logging +import six import grpc @@ -53,6 +54,16 @@ class CredentialsTest(unittest.TestCase): self.assertIsInstance(channel_first_second_and_third, grpc.ChannelCredentials) + @unittest.skipIf(six.PY2, 'only invalid in Python3') + def test_invalid_string_certificate(self): + self.assertRaises( + TypeError, + grpc.ssl_channel_credentials, + root_certificates='A Certificate', + private_key=None, + certificate_chain=None, + ) + if __name__ == '__main__': logging.basicConfig() From 1e53e3c17fdca56340a5c2ceb8261b77fa1cb1a7 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 26 Nov 2018 10:26:07 -0800 Subject: [PATCH 0296/2143] added back platform registration to WORKSPACE --- WORKSPACE | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/WORKSPACE b/WORKSPACE index 1340ba0c6be..cd2718204d1 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -6,6 +6,10 @@ grpc_deps() grpc_test_only_deps() +register_execution_platforms( + "//third_party/toolchains:all", +) + register_toolchains( "//third_party/toolchains:all", ) From 9bbda894cbd845cea48a76c536d9731436c6313f Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 26 Nov 2018 14:39:49 -0800 Subject: [PATCH 0297/2143] Use a static local flag to memorize whether the grpc event engine runs in background or not --- src/core/lib/iomgr/tcp_posix.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index c802fcca750..4d9a66e82c8 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -260,7 +260,10 @@ static void notify_on_write(grpc_tcp* tcp) { if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p notify_on_write", tcp); } - if (grpc_event_engine_run_in_background()) { + + static bool grpc_event_engine_run_in_background = + grpc_event_engine_run_in_background(); + if (grpc_event_engine_run_in_background) { // If there is a polling engine always running in the background, there is // no need to run the backup poller. GRPC_CLOSURE_INIT(&tcp->write_done_closure, tcp_handle_write, tcp, From c1af11fbd622c640b15a7c8e5977e0c40a546969 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 26 Nov 2018 15:05:44 -0800 Subject: [PATCH 0298/2143] Resolve naming conflicts --- 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 4d9a66e82c8..58e15bf15ee 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -261,9 +261,9 @@ static void notify_on_write(grpc_tcp* tcp) { gpr_log(GPR_INFO, "TCP:%p notify_on_write", tcp); } - static bool grpc_event_engine_run_in_background = + static bool event_engine_run_in_background = grpc_event_engine_run_in_background(); - if (grpc_event_engine_run_in_background) { + if (event_engine_run_in_background) { // If there is a polling engine always running in the background, there is // no need to run the backup poller. GRPC_CLOSURE_INIT(&tcp->write_done_closure, tcp_handle_write, tcp, From b77c77f7da12e8b6eaf128ea8938d11c7e2e025b Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Mon, 26 Nov 2018 18:47:24 -0500 Subject: [PATCH 0299/2143] Use grpc_core::RefCount in place of gpr_refcount --- BUILD | 1 + src/core/lib/gprpp/orphanable.h | 27 +++++++++++++-------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/BUILD b/BUILD index ace108be34e..9a2c16c6012 100644 --- a/BUILD +++ b/BUILD @@ -647,6 +647,7 @@ grpc_cc_library( "debug_location", "gpr_base", "grpc_trace", + "ref_counted", "ref_counted_ptr", ], ) diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h index 3123e3f5a39..3eb510165e2 100644 --- a/src/core/lib/gprpp/orphanable.h +++ b/src/core/lib/gprpp/orphanable.h @@ -31,6 +31,7 @@ #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" namespace grpc_core { @@ -89,8 +90,8 @@ class InternallyRefCounted : public Orphanable { template friend class RefCountedPtr; - InternallyRefCounted() { gpr_ref_init(&refs_, 1); } - virtual ~InternallyRefCounted() {} + InternallyRefCounted() = default; + virtual ~InternallyRefCounted() = default; RefCountedPtr Ref() GRPC_MUST_USE_RESULT { IncrementRefCount(); @@ -98,15 +99,15 @@ class InternallyRefCounted : public Orphanable { } void Unref() { - if (gpr_unref(&refs_)) { + if (refs_.Unref()) { Delete(static_cast(this)); } } private: - void IncrementRefCount() { gpr_ref(&refs_); } + void IncrementRefCount() { refs_.Ref(); } - gpr_refcount refs_; + grpc_core::RefCount refs_; }; // An alternative version of the InternallyRefCounted base class that @@ -137,16 +138,14 @@ class InternallyRefCountedWithTracing : public Orphanable { : InternallyRefCountedWithTracing(static_cast(nullptr)) {} explicit InternallyRefCountedWithTracing(TraceFlag* trace_flag) - : trace_flag_(trace_flag) { - gpr_ref_init(&refs_, 1); - } + : trace_flag_(trace_flag) {} #ifdef NDEBUG explicit InternallyRefCountedWithTracing(DebugOnlyTraceFlag* trace_flag) : InternallyRefCountedWithTracing() {} #endif - virtual ~InternallyRefCountedWithTracing() {} + virtual ~InternallyRefCountedWithTracing() = default; RefCountedPtr Ref() GRPC_MUST_USE_RESULT { IncrementRefCount(); @@ -156,7 +155,7 @@ class InternallyRefCountedWithTracing : public Orphanable { RefCountedPtr Ref(const DebugLocation& location, const char* reason) GRPC_MUST_USE_RESULT { if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { - gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count); + const grpc_core::RefCount::Value old_refs = refs_.get(); gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s", trace_flag_->name(), this, location.file(), location.line(), old_refs, old_refs + 1, reason); @@ -170,14 +169,14 @@ class InternallyRefCountedWithTracing : public Orphanable { // friend of this class. void Unref() { - if (gpr_unref(&refs_)) { + if (refs_.Unref()) { Delete(static_cast(this)); } } void Unref(const DebugLocation& location, const char* reason) { if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { - gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count); + const grpc_core::RefCount::Value old_refs = refs_.get(); gpr_log(GPR_INFO, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s", trace_flag_->name(), this, location.file(), location.line(), old_refs, old_refs - 1, reason); @@ -186,10 +185,10 @@ class InternallyRefCountedWithTracing : public Orphanable { } private: - void IncrementRefCount() { gpr_ref(&refs_); } + void IncrementRefCount() { refs_.Ref(); } TraceFlag* trace_flag_ = nullptr; - gpr_refcount refs_; + grpc_core::RefCount refs_; }; } // namespace grpc_core From 5ae61f5a5a267f5975248d4262133a740e09a66b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 26 Nov 2018 17:17:09 -0800 Subject: [PATCH 0300/2143] Multiple fixes --- .../GRPCClient/GRPCCall+ChannelArg.m | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 53 +++---- .../GRPCClient/private/ChannelArgsUtil.m | 21 ++- .../GRPCClient/private/GRPCChannel.h | 6 +- .../GRPCClient/private/GRPCChannel.m | 64 ++++---- .../GRPCClient/private/GRPCChannelPool.h | 51 +++--- .../GRPCClient/private/GRPCChannelPool.m | 145 +++++++++--------- .../GRPCClient/private/GRPCWrappedCall.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.m | 38 ++--- .../tests/ChannelTests/ChannelPoolTest.m | 40 +++-- .../tests/ChannelTests/ChannelTests.m | 4 +- src/objective-c/tests/GRPCClientTests.m | 7 +- 12 files changed, 221 insertions(+), 212 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m index 703cff63bb0..ae60d6208e1 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m @@ -36,7 +36,7 @@ } + (void)closeOpenConnections { - [[GRPCChannelPool sharedInstance] closeOpenConnections]; + [[GRPCChannelPool sharedInstance] disconnectAllChannels]; } + (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host { diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 94e470d4ed9..bf9441c27eb 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -69,11 +69,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { NSAssert(host.length != 0 && path.length != 0, @"Host and Path cannot be empty"); - if (host.length == 0) { - host = [NSString string]; - } - if (path.length == 0) { - path = [NSString string]; + if (host.length == 0 || path.length == 0) { + return nil; } if ((self = [super init])) { _host = [host copy]; @@ -173,7 +170,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)start { - GRPCCall *call = nil; + GRPCCall *copiedCall = nil; @synchronized(self) { NSAssert(!_started, @"Call already started."); NSAssert(!_canceled, @"Call already canceled."); @@ -197,7 +194,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (_callOptions.initialMetadata) { [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata]; } - call = _call; + copiedCall = _call; } void (^valueHandler)(id value) = ^(id value) { @@ -235,11 +232,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; }; id responseWriteable = [[GRXWriteable alloc] initWithValueHandler:valueHandler completionHandler:completionHandler]; - [call startWithWriteable:responseWriteable]; + [copiedCall startWithWriteable:responseWriteable]; } - (void)cancel { - GRPCCall *call = nil; + GRPCCall *copiedCall = nil; @synchronized(self) { if (_canceled) { return; @@ -247,7 +244,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _canceled = YES; - call = _call; + copiedCall = _call; _call = nil; _pipe = nil; @@ -268,13 +265,15 @@ const char *kCFStreamVarName = "grpc_cfstream"; @"Canceled by app" }]]; }); + } else { + _handler = nil; } } - [call cancel]; + [copiedCall cancel]; } - (void)writeData:(NSData *)data { - GRXBufferedPipe *pipe = nil; + GRXBufferedPipe *copiedPipe = nil; @synchronized(self) { NSAssert(!_canceled, @"Call arleady canceled."); NSAssert(!_finished, @"Call is half-closed before sending data."); @@ -286,14 +285,14 @@ const char *kCFStreamVarName = "grpc_cfstream"; } if (_pipe) { - pipe = _pipe; + copiedPipe = _pipe; } } - [pipe writeValue:data]; + [copiedPipe writeValue:data]; } - (void)finish { - GRXBufferedPipe *pipe = nil; + GRXBufferedPipe *copiedPipe = nil; @synchronized(self) { NSAssert(_started, @"Call not started."); NSAssert(!_canceled, @"Call arleady canceled."); @@ -309,12 +308,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; } if (_pipe) { - pipe = _pipe; + copiedPipe = _pipe; _pipe = nil; } _finished = YES; } - [pipe writesFinishedWithError:nil]; + [copiedPipe writesFinishedWithError:nil]; } - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { @@ -322,11 +321,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (initialMetadata != nil && [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; } - [handler receivedInitialMetadata:initialMetadata]; + [copiedHandler receivedInitialMetadata:initialMetadata]; }); } } @@ -336,11 +335,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(self) { if (message != nil && [_handler respondsToSelector:@selector(receivedRawMessage:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; } - [handler receivedRawMessage:message]; + [copiedHandler receivedRawMessage:message]; }); } } @@ -350,14 +349,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(self) { if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; } - [handler closedWithTrailingMetadata:trailingMetadata error:error]; + [copiedHandler closedWithTrailingMetadata:trailingMetadata error:error]; }); + } else { + _handler = nil; } } } diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index d9e44b557d1..3135fcff028 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -60,36 +60,35 @@ grpc_channel_args *GRPCBuildChannelArgs(NSDictionary *dictionary) { NSUInteger argCount = [keys count]; grpc_channel_args *channelArgs = gpr_malloc(sizeof(grpc_channel_args)); - channelArgs->num_args = argCount; channelArgs->args = gpr_malloc(argCount * sizeof(grpc_arg)); // TODO(kriswuollett) Check that keys adhere to GRPC core library requirements + NSUInteger j = 0; for (NSUInteger i = 0; i < argCount; ++i) { - grpc_arg *arg = &channelArgs->args[i]; + grpc_arg *arg = &channelArgs->args[j]; arg->key = gpr_strdup([keys[i] UTF8String]); id value = dictionary[keys[i]]; if ([value respondsToSelector:@selector(UTF8String)]) { arg->type = GRPC_ARG_STRING; arg->value.string = gpr_strdup([value UTF8String]); + j++; } else if ([value respondsToSelector:@selector(intValue)]) { - if ([value compare:[NSNumber numberWithInteger:INT_MAX]] == NSOrderedDescending || - [value compare:[NSNumber numberWithInteger:INT_MIN]] == NSOrderedAscending) { - [NSException raise:NSInvalidArgumentException - format:@"Out of range for a value-typed channel argument: %@", value]; + int64_t value64 = [value longLongValue]; + if (value64 <= INT_MAX || value64 >= INT_MIN) { + arg->type = GRPC_ARG_INTEGER; + arg->value.integer = [value intValue]; + j++; } - arg->type = GRPC_ARG_INTEGER; - arg->value.integer = [value intValue]; } else if (value != nil) { arg->type = GRPC_ARG_POINTER; arg->value.pointer.p = (__bridge_retained void *)value; arg->value.pointer.vtable = &objc_arg_vtable; - } else { - [NSException raise:NSInvalidArgumentException - format:@"Invalid channel argument type: %@", [value class]]; + j++; } } + channelArgs->num_args = j; return channelArgs; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 5426b28d758..147015bed10 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -32,6 +32,10 @@ NS_ASSUME_NONNULL_BEGIN /** Caching signature of a channel. */ @interface GRPCChannelConfiguration : NSObject +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype) new NS_UNAVAILABLE; + /** The host that this channel is connected to. */ @property(copy, readonly) NSString *host; @@ -47,7 +51,7 @@ NS_ASSUME_NONNULL_BEGIN /** Acquire the dictionary of channel args with current configurations. */ @property(copy, readonly) NSDictionary *channelArgs; -- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; +- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index e4cefc338c6..24cf670d1b5 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -39,8 +39,9 @@ - (instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { NSAssert(host.length > 0, @"Host must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); - if (host.length == 0) return nil; - if (callOptions == nil) return nil; + if (host.length == 0 || callOptions == nil) { + return nil; + } if ((self = [super init])) { _host = [host copy]; @@ -180,7 +181,9 @@ - (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { NSAssert(channelConfiguration != nil, @"channelConfiguration must not be empty."); - if (channelConfiguration == nil) return nil; + if (channelConfiguration == nil) { + return nil; + } if ((self = [super init])) { _configuration = [channelConfiguration copy]; @@ -218,35 +221,34 @@ if (callOptions == nil) return NULL; grpc_call *call = NULL; - @synchronized(self) { - NSAssert(_unmanagedChannel != NULL, @"Channel should have valid unmanaged channel."); - if (_unmanagedChannel == NULL) return NULL; + // No need to lock here since _unmanagedChannel is only changed in _dealloc + NSAssert(_unmanagedChannel != NULL, @"Channel should have valid unmanaged channel."); + if (_unmanagedChannel == NULL) return NULL; - NSString *serverAuthority = - callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; - NSTimeInterval timeout = callOptions.timeout; - NSAssert(timeout >= 0, @"Invalid timeout"); - if (timeout < 0) return NULL; - grpc_slice host_slice = grpc_empty_slice(); - if (serverAuthority) { - host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); - } - grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); - gpr_timespec deadline_ms = - timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME) - : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); - call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, - queue.unmanagedQueue, path_slice, - serverAuthority ? &host_slice : NULL, deadline_ms, NULL); - if (serverAuthority) { - grpc_slice_unref(host_slice); - } - grpc_slice_unref(path_slice); - NSAssert(call != nil, @"Unable to create call."); - if (call == NULL) { - NSLog(@"Unable to create call."); - } + NSString *serverAuthority = + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; + NSTimeInterval timeout = callOptions.timeout; + NSAssert(timeout >= 0, @"Invalid timeout"); + if (timeout < 0) return NULL; + grpc_slice host_slice = grpc_empty_slice(); + if (serverAuthority) { + host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); + } + grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); + gpr_timespec deadline_ms = + timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME) + : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, + queue.unmanagedQueue, path_slice, + serverAuthority ? &host_slice : NULL, deadline_ms, NULL); + if (serverAuthority) { + grpc_slice_unref(host_slice); + } + grpc_slice_unref(path_slice); + NSAssert(call != nil, @"Unable to create call."); + if (call == NULL) { + NSLog(@"Unable to create call."); } return call; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 1e3c1d7d976..26600ef3a96 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -39,12 +39,16 @@ NS_ASSUME_NONNULL_BEGIN */ @interface GRPCPooledChannel : NSObject +- (nullable instancetype)init NS_UNAVAILABLE; + ++ (nullable instancetype)new NS_UNAVAILABLE; + /** * Initialize with an actual channel object \a channel and a reference to the channel pool. */ - (nullable instancetype)initWithChannelConfiguration: (GRPCChannelConfiguration *)channelConfiguration - channelPool:(GRPCChannelPool *)channelPool; + channelPool:(GRPCChannelPool *)channelPool NS_DESIGNATED_INITIALIZER; /** * Create a grpc core call object (grpc_call) from this channel. If channel is disconnected, get a @@ -59,17 +63,21 @@ NS_ASSUME_NONNULL_BEGIN * \a unmanagedCallWithPath:completionQueue:callOptions: and decrease channel refcount. If refcount * of the channel becomes 0, return the channel object to channel pool. */ -- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall; +- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall; /** - * Force the channel to disconnect immediately. + * Force the channel to disconnect immediately. Subsequent calls to unmanagedCallWithPath: will + * attempt to reconnect to the remote channel. */ - (void)disconnect; -// The following methods and properties are for test only +@end + +/** Test-only interface for \a GRPCPooledChannel. */ +@interface GRPCPooledChannel (Test) /** - * Return the pointer to the real channel wrapped by the proxy. + * Return the pointer to the raw channel wrapped. */ @property(atomic, readonly) GRPCChannel *wrappedChannel; @@ -81,6 +89,10 @@ NS_ASSUME_NONNULL_BEGIN */ @interface GRPCChannelPool : NSObject +- (nullable instancetype)init NS_UNAVAILABLE; + ++ (nullable instancetype)new NS_UNAVAILABLE; + /** * Get the global channel pool. */ @@ -92,31 +104,20 @@ NS_ASSUME_NONNULL_BEGIN - (GRPCPooledChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; /** - * This method is deprecated. - * - * Destroy all open channels and close their connections. - */ -- (void)closeOpenConnections; - -// Test-only methods below - -/** - * Get an instance of pool isolated from the global shared pool. This method is for test only. - * Global pool should be used in production. - */ -- (nullable instancetype)init; - -/** - * Simulate a network transition event and destroy all channels. This method is for internal and - * test only. + * Disconnect all channels in this pool. */ - (void)disconnectAllChannels; +@end + +/** Test-only interface for \a GRPCChannelPool. */ +@interface GRPCChannelPool (Test) + /** - * Set the destroy delay of channels. A channel should be destroyed if it stayed idle (no active - * call on it) for this period of time. This property is for test only. + * Get an instance of pool isolated from the global shared pool with channels' destroy delay being + * \a destroyDelay. */ -@property(atomic) NSTimeInterval destroyDelay; +- (nullable instancetype)initTestPoolWithDestroyDelay:(NSTimeInterval)destroyDelay; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 7c139b37176..f6615b58405 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -52,10 +52,9 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; __weak GRPCChannelPool *_channelPool; GRPCChannelConfiguration *_channelConfiguration; NSMutableSet *_unmanagedCalls; + GRPCChannel *_wrappedChannel; } -@synthesize wrappedChannel = _wrappedChannel; - - (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration channelPool:(GRPCChannelPool *)channelPool { NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); @@ -68,11 +67,17 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; _channelPool = channelPool; _channelConfiguration = channelConfiguration; _unmanagedCalls = [NSMutableSet set]; + _wrappedChannel = nil; } return self; } +- (void)dealloc { + NSAssert([_unmanagedCalls count] == 0 && _wrappedChannel == nil, @"Pooled channel should only be" + "destroyed after the wrapped channel is destroyed"); +} + - (grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions { @@ -99,31 +104,38 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; return call; } -- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall { - if (unmanagedCall == nil) return; +- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall { + if (unmanagedCall == NULL) { + return; + } grpc_call_unref(unmanagedCall); - BOOL timedDestroy = NO; @synchronized(self) { - if ([_unmanagedCalls containsObject:[NSValue valueWithPointer:unmanagedCall]]) { - [_unmanagedCalls removeObject:[NSValue valueWithPointer:unmanagedCall]]; - if ([_unmanagedCalls count] == 0) { - timedDestroy = YES; - } + NSValue *removedCall = [NSValue valueWithPointer:unmanagedCall]; + [_unmanagedCalls removeObject:removedCall]; + if ([_unmanagedCalls count] == 0) { + _wrappedChannel = nil; + GRPCChannelPool *strongPool = _channelPool; + [strongPool unrefChannelWithConfiguration:_channelConfiguration]; } } - if (timedDestroy) { - [self timedDestroy]; - } } - (void)disconnect { @synchronized(self) { - _wrappedChannel = nil; - [_unmanagedCalls removeAllObjects]; + if (_wrappedChannel != nil) { + _wrappedChannel = nil; + [_unmanagedCalls removeAllObjects]; + GRPCChannelPool *strongPool = _channelPool; + [strongPool unrefChannelWithConfiguration:_channelConfiguration]; + } } } +@end + +@implementation GRPCPooledChannel (Test) + - (GRPCChannel *)wrappedChannel { GRPCChannel *channel = nil; @synchronized(self) { @@ -132,67 +144,52 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; return channel; } -- (void)timedDestroy { - __strong GRPCChannelPool *pool = nil; - @synchronized(self) { - // Check if we still want to destroy the channel. - if ([_unmanagedCalls count] == 0) { - pool = _channelPool; - _wrappedChannel = nil; - } - } - [pool unrefChannelWithConfiguration:_channelConfiguration]; -} - @end /** * A convenience value type for cached channel. */ -@interface GRPCChannelRecord : NSObject +@interface GRPCChannelRecord : NSObject /** Pointer to the raw channel. May be nil when the channel has been destroyed. */ @property GRPCChannel *channel; /** Channel proxy corresponding to this channel configuration. */ -@property GRPCPooledChannel *proxy; +@property GRPCPooledChannel *pooledChannel; /** Last time when a timed destroy is initiated on the channel. */ @property NSDate *timedDestroyDate; /** Reference count of the proxy to the channel. */ -@property NSUInteger refcount; +@property NSUInteger refCount; @end @implementation GRPCChannelRecord -- (id)copyWithZone:(NSZone *)zone { - GRPCChannelRecord *newRecord = [[GRPCChannelRecord allocWithZone:zone] init]; - newRecord.channel = _channel; - newRecord.proxy = _proxy; - newRecord.timedDestroyDate = _timedDestroyDate; - newRecord.refcount = _refcount; +@end - return newRecord; -} +@interface GRPCChannelPool () + +- (instancetype)initInstanceWithDestroyDelay:(NSTimeInterval)destroyDelay NS_DESIGNATED_INITIALIZER; @end @implementation GRPCChannelPool { NSMutableDictionary *_channelPool; dispatch_queue_t _dispatchQueue; + NSTimeInterval _destroyDelay; } + (instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ - gChannelPool = [[GRPCChannelPool alloc] init]; + gChannelPool = [[GRPCChannelPool alloc] initInstanceWithDestroyDelay:kDefaultChannelDestroyDelay]; NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); }); return gChannelPool; } -- (instancetype)init { +- (instancetype)initInstanceWithDestroyDelay:(NSTimeInterval)destroyDelay { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 @@ -206,7 +203,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; #endif _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } - _destroyDelay = kDefaultChannelDestroyDelay; + _destroyDelay = destroyDelay; // Connectivity monitor is not required for CFStream char *enableCFStream = getenv(kCFStreamVarName); @@ -217,56 +214,56 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; return self; } +- (void)dealloc { + [GRPCConnectivityMonitor unregisterObserver:self]; +} + - (GRPCPooledChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { NSAssert(host.length > 0, @"Host must not be empty."); NSAssert(callOptions != nil, @"callOptions must not be empty."); - if (host.length == 0) return nil; - if (callOptions == nil) return nil; + if (host.length == 0 || callOptions == nil) { + return nil; + } - GRPCPooledChannel *channelProxy = nil; + GRPCPooledChannel *pooledChannel = nil; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; @synchronized(self) { GRPCChannelRecord *record = _channelPool[configuration]; if (record == nil) { record = [[GRPCChannelRecord alloc] init]; - record.proxy = + record.pooledChannel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:configuration channelPool:self]; - record.timedDestroyDate = nil; _channelPool[configuration] = record; - channelProxy = record.proxy; + pooledChannel = record.pooledChannel; } else { - channelProxy = record.proxy; + pooledChannel = record.pooledChannel; } } - return channelProxy; -} - -- (void)closeOpenConnections { - [self disconnectAllChannels]; + return pooledChannel; } - (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { GRPCChannel *ret = nil; @synchronized(self) { NSAssert(configuration != nil, @"configuration cannot be empty."); - if (configuration == nil) return nil; + if (configuration == nil) { + return nil; + } GRPCChannelRecord *record = _channelPool[configuration]; NSAssert(record != nil, @"No record corresponding to a proxy."); - if (record == nil) return nil; + if (record == nil) { + return nil; + } + record.refCount++; + record.timedDestroyDate = nil; if (record.channel == nil) { // Channel is already destroyed; record.channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration]; - record.timedDestroyDate = nil; - record.refcount = 1; - ret = record.channel; - } else { - ret = record.channel; - record.timedDestroyDate = nil; - record.refcount++; } + ret = record.channel; } return ret; } @@ -275,11 +272,13 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @synchronized(self) { GRPCChannelRecord *record = _channelPool[configuration]; NSAssert(record != nil, @"No record corresponding to a proxy."); - if (record == nil) return; - NSAssert(record.refcount > 0, @"Inconsistent channel refcount."); - if (record.refcount > 0) { - record.refcount--; - if (record.refcount == 0) { + if (record == nil) { + return; + } + NSAssert(record.refCount > 0, @"Inconsistent channel refcount."); + if (record.refCount > 0) { + record.refCount--; + if (record.refCount == 0) { NSDate *now = [NSDate date]; record.timedDestroyDate = now; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_destroyDelay * NSEC_PER_SEC)), @@ -288,7 +287,6 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; if (now == record.timedDestroyDate) { // Destroy the raw channel and reset related records. record.timedDestroyDate = nil; - record.refcount = 0; record.channel = nil; } } @@ -306,8 +304,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; GRPCChannelRecord *_Nonnull obj, BOOL *_Nonnull stop) { obj.channel = nil; obj.timedDestroyDate = nil; - obj.refcount = 0; - [proxySet addObject:obj.proxy]; + [proxySet addObject:obj.pooledChannel]; }]; } // Disconnect proxies @@ -320,8 +317,12 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; [self disconnectAllChannels]; } -- (void)dealloc { - [GRPCConnectivityMonitor unregisterObserver:self]; +@end + +@implementation GRPCChannelPool (Test) + +- (instancetype)initTestPoolWithDestroyDelay:(NSTimeInterval)destroyDelay { + return [self initInstanceWithDestroyDelay:destroyDelay]; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 615dfc85569..5788d0a003f 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -317,7 +317,7 @@ } - (void)dealloc { - [_channel unrefUnmanagedCall:_call]; + [_channel destroyUnmanagedCall:_call]; _channel = nil; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 2de2932072a..dff88b8591f 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -133,18 +133,18 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)cancel { - GRPCCall2 *call; + GRPCCall2 *copiedCall; @synchronized(self) { - call = _call; + copiedCall = _call; _call = nil; if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_handler.dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; self->_handler = nil; } - [handler closedWithTrailingMetadata:nil + [copiedHandler closedWithTrailingMetadata:nil error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled userInfo:@{ @@ -152,9 +152,11 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @"Canceled by app" }]]; }); + } else { + _handler = nil; } } - [call cancel]; + [copiedCall cancel]; } - (void)writeMessage:(GPBMessage *)message { @@ -182,11 +184,11 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @synchronized(self) { if (initialMetadata != nil && [_handler respondsToSelector:@selector(initialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; } - [handler receivedInitialMetadata:initialMetadata]; + [copiedHandler receivedInitialMetadata:initialMetadata]; }); } } @@ -200,21 +202,21 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @synchronized(self) { if (parsed && [_handler respondsToSelector:@selector(receivedProtoMessage:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; } - [handler receivedProtoMessage:parsed]; + [copiedHandler receivedProtoMessage:parsed]; }); } else if (!parsed && [_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; self->_handler = nil; } - [handler closedWithTrailingMetadata:nil + [copiedHandler closedWithTrailingMetadata:nil error:ErrorForBadProto(message, _responseClass, error)]; }); [_call cancel]; @@ -227,12 +229,12 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @synchronized(self) { if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ - id handler = nil; + id copiedHandler = nil; @synchronized(self) { - handler = self->_handler; + copiedHandler = self->_handler; self->_handler = nil; } - [handler closedWithTrailingMetadata:trailingMetadata error:error]; + [copiedHandler closedWithTrailingMetadata:trailingMetadata error:error]; }); } _call = nil; diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index 4424801c110..9461945560a 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -28,6 +28,8 @@ NSString *kDummyHost = @"dummy.host"; NSString *kDummyHost2 = @"dummy.host.2"; NSString *kDummyPath = @"/dummy/path"; +const NSTimeInterval kDestroyDelay = 1.0; + @interface ChannelPoolTest : XCTestCase @end @@ -39,7 +41,7 @@ NSString *kDummyPath = @"/dummy/path"; } - (void)testCreateChannelAndCall { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; @@ -49,12 +51,12 @@ NSString *kDummyPath = @"/dummy/path"; [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssert(call != NULL); XCTAssertNotNil(channel.wrappedChannel); - [channel unrefUnmanagedCall:call]; + [channel destroyUnmanagedCall:call]; XCTAssertNil(channel.wrappedChannel); } - (void)testCacheChannel { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; GRPCCallOptions *options1 = [[GRPCCallOptions alloc] init]; GRPCCallOptions *options2 = [options1 copy]; GRPCMutableCallOptions *options3 = [options1 mutableCopy]; @@ -80,17 +82,14 @@ NSString *kDummyPath = @"/dummy/path"; XCTAssertNotEqual(channel1.wrappedChannel, channel3.wrappedChannel); XCTAssertNotEqual(channel1.wrappedChannel, channel4.wrappedChannel); XCTAssertNotEqual(channel3.wrappedChannel, channel4.wrappedChannel); - [channel1 unrefUnmanagedCall:call1]; - [channel2 unrefUnmanagedCall:call2]; - [channel3 unrefUnmanagedCall:call3]; - [channel4 unrefUnmanagedCall:call4]; + [channel1 destroyUnmanagedCall:call1]; + [channel2 destroyUnmanagedCall:call2]; + [channel3 destroyUnmanagedCall:call3]; + [channel4 destroyUnmanagedCall:call4]; } - (void)testTimedDestroyChannel { - const NSTimeInterval kDestroyDelay = 1.0; - - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; - pool.destroyDelay = kDestroyDelay; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; @@ -99,25 +98,24 @@ NSString *kDummyPath = @"/dummy/path"; [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; GRPCChannel *wrappedChannel = channel.wrappedChannel; - [channel unrefUnmanagedCall:call]; + [channel destroyUnmanagedCall:call]; // Confirm channel is not destroyed at this time call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertEqual(wrappedChannel, channel.wrappedChannel); - [channel unrefUnmanagedCall:call]; + [channel destroyUnmanagedCall:call]; sleep(kDestroyDelay + 1); // Confirm channel is new at this time call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); // Confirm the new channel can create call - call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssert(call != NULL); - [channel unrefUnmanagedCall:call]; + [channel destroyUnmanagedCall:call]; } - (void)testPoolDisconnection { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; @@ -141,12 +139,12 @@ NSString *kDummyPath = @"/dummy/path"; [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); - [channel unrefUnmanagedCall:call]; - [channel unrefUnmanagedCall:call2]; + [channel destroyUnmanagedCall:call]; + [channel destroyUnmanagedCall:call2]; } - (void)testUnrefCallFromStaleChannel { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] init]; + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; GRPCPooledChannel *channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; @@ -163,12 +161,12 @@ NSString *kDummyPath = @"/dummy/path"; // destroy state XCTAssertNotNil(channel.wrappedChannel); GRPCChannel *wrappedChannel = channel.wrappedChannel; - [channel unrefUnmanagedCall:call]; + [channel destroyUnmanagedCall:call]; XCTAssertNotNil(channel.wrappedChannel); XCTAssertEqual(wrappedChannel, channel.wrappedChannel); // Test unref the call of the current channel will cause the channel going into timed destroy // state - [channel unrefUnmanagedCall:call2]; + [channel destroyUnmanagedCall:call2]; XCTAssertNil(channel.wrappedChannel); } diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index c07c8e69834..55474490926 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -35,7 +35,7 @@ completionQueue:(GRPCCompletionQueue *)queue callOptions:(GRPCCallOptions *)callOptions; -- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall; +- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall; @end @@ -66,7 +66,7 @@ return (grpc_call *)(++_grpcCallCounter); } -- (void)unrefUnmanagedCall:(grpc_call *)unmanagedCall { +- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall { if (_unrefExpectation) [_unrefExpectation fulfill]; } diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 834bf6d661a..2cfdd1a003b 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -554,13 +554,14 @@ static GRPCProtoMethod *kFullDuplexCallMethod; __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; NSString *const kDummyAddress = [NSString stringWithFormat:@"8.8.8.8:1"]; - GRPCCall *call = [[GRPCCall alloc] initWithHost:kDummyAddress - path:@"/dummyPath" - requestsWriter:[GRXWriter writerWithValue:[NSData data]]]; + [GRPCCall useInsecureConnectionsForHost:kDummyAddress]; [GRPCCall setMinConnectTimeout:timeout * 1000 initialBackoff:backoff * 1000 maxBackoff:0 forHost:kDummyAddress]; + GRPCCall *call = [[GRPCCall alloc] initWithHost:kDummyAddress + path:@"/dummyPath" + requestsWriter:[GRXWriter writerWithValue:[NSData data]]]; NSDate *startTime = [NSDate date]; id responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(id value) { XCTAssert(NO, @"Received message. Should not reach here"); From fdf4b8f2f76cf13f9d41c24775b78727de3c994b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 26 Nov 2018 17:42:56 -0800 Subject: [PATCH 0301/2143] clang-format --- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 +- src/objective-c/GRPCClient/private/GRPCChannel.h | 3 ++- src/objective-c/GRPCClient/private/GRPCChannel.m | 8 ++++---- .../GRPCClient/private/GRPCChannelPool.h | 7 ++++--- .../GRPCClient/private/GRPCChannelPool.m | 8 +++++--- src/objective-c/ProtoRPC/ProtoRPC.m | 14 +++++++------- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 48bb11aeeb0..158a4745d23 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -64,7 +64,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)getTokenWithHandler:(void (^ _Nullable)(NSString * _Nullable token))handler; +- (void)getTokenWithHandler:(void (^_Nullable)(NSString *_Nullable token))handler; @end @interface GRPCCallOptions : NSObject diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 147015bed10..c01aeccf81f 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -51,7 +51,8 @@ NS_ASSUME_NONNULL_BEGIN /** Acquire the dictionary of channel args with current configurations. */ @property(copy, readonly) NSDictionary *channelArgs; -- (nullable instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 24cf670d1b5..9432e7ab397 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -226,7 +226,7 @@ if (_unmanagedChannel == NULL) return NULL; NSString *serverAuthority = - callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); if (timeout < 0) return NULL; @@ -236,9 +236,9 @@ } grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); gpr_timespec deadline_ms = - timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME) - : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); + timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME) + : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis((int64_t)(timeout * 1000), GPR_TIMESPAN)); call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, queue.unmanagedQueue, path_slice, serverAuthority ? &host_slice : NULL, deadline_ms, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 26600ef3a96..7f8ee19fe59 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -41,14 +41,15 @@ NS_ASSUME_NONNULL_BEGIN - (nullable instancetype)init NS_UNAVAILABLE; -+ (nullable instancetype)new NS_UNAVAILABLE; ++ (nullable instancetype) new NS_UNAVAILABLE; /** * Initialize with an actual channel object \a channel and a reference to the channel pool. */ - (nullable instancetype)initWithChannelConfiguration: (GRPCChannelConfiguration *)channelConfiguration - channelPool:(GRPCChannelPool *)channelPool NS_DESIGNATED_INITIALIZER; + channelPool:(GRPCChannelPool *)channelPool + NS_DESIGNATED_INITIALIZER; /** * Create a grpc core call object (grpc_call) from this channel. If channel is disconnected, get a @@ -91,7 +92,7 @@ NS_ASSUME_NONNULL_BEGIN - (nullable instancetype)init NS_UNAVAILABLE; -+ (nullable instancetype)new NS_UNAVAILABLE; ++ (nullable instancetype) new NS_UNAVAILABLE; /** * Get the global channel pool. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index f6615b58405..646f1e4b86e 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -74,8 +74,9 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (void)dealloc { - NSAssert([_unmanagedCalls count] == 0 && _wrappedChannel == nil, @"Pooled channel should only be" - "destroyed after the wrapped channel is destroyed"); + NSAssert([_unmanagedCalls count] == 0 && _wrappedChannel == nil, + @"Pooled channel should only be" + "destroyed after the wrapped channel is destroyed"); } - (grpc_call *)unmanagedCallWithPath:(NSString *)path @@ -183,7 +184,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; + (instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ - gChannelPool = [[GRPCChannelPool alloc] initInstanceWithDestroyDelay:kDefaultChannelDestroyDelay]; + gChannelPool = + [[GRPCChannelPool alloc] initInstanceWithDestroyDelay:kDefaultChannelDestroyDelay]; NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); }); return gChannelPool; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index dff88b8591f..1db04894d5e 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -145,12 +145,12 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing self->_handler = nil; } [copiedHandler closedWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; }); } else { _handler = nil; @@ -217,7 +217,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing self->_handler = nil; } [copiedHandler closedWithTrailingMetadata:nil - error:ErrorForBadProto(message, _responseClass, error)]; + error:ErrorForBadProto(message, _responseClass, error)]; }); [_call cancel]; _call = nil; From f8f711ae4c6458f4eb72ed524d6a184578a82704 Mon Sep 17 00:00:00 2001 From: Ruslan Nigmatullin Date: Mon, 26 Nov 2018 22:12:16 -0800 Subject: [PATCH 0302/2143] [cython] Declare symbols once --- src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 23428f0b0c0..5aaf31e36c2 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -121,7 +121,6 @@ cdef extern from "grpc/grpc.h": GRPC_STATUS_DATA_LOSS GRPC_STATUS__DO_NOT_USE - const char *GRPC_ARG_PRIMARY_USER_AGENT_STRING const char *GRPC_ARG_ENABLE_CENSUS const char *GRPC_ARG_MAX_CONCURRENT_STREAMS const char *GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH @@ -190,12 +189,6 @@ cdef extern from "grpc/grpc.h": size_t arguments_length "num_args" grpc_arg *arguments "args" - ctypedef enum grpc_compression_level: - GRPC_COMPRESS_LEVEL_NONE - GRPC_COMPRESS_LEVEL_LOW - GRPC_COMPRESS_LEVEL_MED - GRPC_COMPRESS_LEVEL_HIGH - ctypedef enum grpc_stream_compression_level: GRPC_STREAM_COMPRESS_LEVEL_NONE GRPC_STREAM_COMPRESS_LEVEL_LOW From 58beb81d11f708e0a77c737abc5e8556d794c814 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Mon, 26 Nov 2018 17:53:37 -0500 Subject: [PATCH 0303/2143] Move HTTP2 transport and byte stream to grpc_core::RefCount. Also, added a TODO to move `grpc_transport` to C++. I believe that's doable, which would requires significant change in all transports. --- .../chttp2/transport/chttp2_transport.cc | 35 +++++-------------- .../ext/transport/chttp2/transport/internal.h | 22 ++++++++---- 2 files changed, 24 insertions(+), 33 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 4ca0f49adf2..b1b8c0083b1 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -211,32 +211,23 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, const char* reason, const char* file, int line) { if (grpc_trace_chttp2_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&t->refs.count); + const grpc_core::RefCount::Value val = t->refs.get(); gpr_log(GPR_DEBUG, "chttp2:unref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]", t, val, val - 1, reason, file, line); } - if (!gpr_unref(&t->refs)) return; - t->~grpc_chttp2_transport(); - gpr_free(t); + if (!t->refs.Unref()) return; + grpc_core::Delete(t); } void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason, const char* file, int line) { if (grpc_trace_chttp2_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&t->refs.count); + const grpc_core::RefCount::Value val = t->refs.get(); gpr_log(GPR_DEBUG, "chttp2: ref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]", t, val, val + 1, reason, file, line); } - gpr_ref(&t->refs); + t->refs.Ref(); } -#else -void grpc_chttp2_unref_transport(grpc_chttp2_transport* t) { - if (!gpr_unref(&t->refs)) return; - t->~grpc_chttp2_transport(); - gpr_free(t); -} - -void grpc_chttp2_ref_transport(grpc_chttp2_transport* t) { gpr_ref(&t->refs); } #endif static const grpc_transport_vtable* get_vtable(void); @@ -500,8 +491,6 @@ grpc_chttp2_transport::grpc_chttp2_transport( GPR_ASSERT(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) == GRPC_CHTTP2_CLIENT_CONNECT_STRLEN); base.vtable = get_vtable(); - /* one ref is for destroy */ - gpr_ref_init(&refs, 1); /* 8 is a random stab in the dark as to a good initial size: it's small enough that it shouldn't waste memory for infrequently used connections, yet large enough that the exponential growth should happen nicely when it's @@ -2845,8 +2834,8 @@ Chttp2IncomingByteStream::Chttp2IncomingByteStream( : ByteStream(frame_size, flags), transport_(transport), stream_(stream), + refs_(2), remaining_bytes_(frame_size) { - gpr_ref_init(&refs_, 2); GRPC_ERROR_UNREF(stream->byte_stream_error); stream->byte_stream_error = GRPC_ERROR_NONE; } @@ -2871,14 +2860,6 @@ void Chttp2IncomingByteStream::Orphan() { GRPC_ERROR_NONE); } -void Chttp2IncomingByteStream::Unref() { - if (gpr_unref(&refs_)) { - Delete(this); - } -} - -void Chttp2IncomingByteStream::Ref() { gpr_ref(&refs_); } - void Chttp2IncomingByteStream::NextLocked(void* arg, grpc_error* error_ignored) { Chttp2IncomingByteStream* bs = static_cast(arg); @@ -3198,8 +3179,8 @@ intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport) { grpc_transport* grpc_create_chttp2_transport( const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client, grpc_resource_user* resource_user) { - auto t = new (gpr_malloc(sizeof(grpc_chttp2_transport))) - grpc_chttp2_transport(channel_args, ep, is_client, resource_user); + auto t = grpc_core::New(channel_args, ep, is_client, + resource_user); return &t->base; } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 877b8aba77c..1c79cf63531 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -236,8 +236,12 @@ class Chttp2IncomingByteStream : public ByteStream { // alone for now. We can revisit this once we're able to link against // libc++, at which point we can eliminate New<> and Delete<> and // switch to std::shared_ptr<>. - void Ref(); - void Unref(); + void Ref() { refs_.Ref(); } + void Unref() { + if (refs_.Unref()) { + grpc_core::Delete(this); + } + } void PublishError(grpc_error* error); @@ -256,7 +260,7 @@ class Chttp2IncomingByteStream : public ByteStream { grpc_chttp2_transport* transport_; // Immutable. grpc_chttp2_stream* stream_; // Immutable. - gpr_refcount refs_; + grpc_core::RefCount refs_; /* Accessed only by transport thread when stream->pending_byte_stream == false * Accessed only by application thread when stream->pending_byte_stream == @@ -290,7 +294,7 @@ struct grpc_chttp2_transport { ~grpc_chttp2_transport(); grpc_transport base; /* must be first */ - gpr_refcount refs; + grpc_core::RefCount refs; grpc_endpoint* ep; char* peer_string; @@ -793,8 +797,14 @@ void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason, #else #define GRPC_CHTTP2_REF_TRANSPORT(t, r) grpc_chttp2_ref_transport(t) #define GRPC_CHTTP2_UNREF_TRANSPORT(t, r) grpc_chttp2_unref_transport(t) -void grpc_chttp2_unref_transport(grpc_chttp2_transport* t); -void grpc_chttp2_ref_transport(grpc_chttp2_transport* t); +inline void grpc_chttp2_unref_transport(grpc_chttp2_transport* t) { + if (t->refs.Unref()) { + grpc_core::Delete(t); + } +} +inline void grpc_chttp2_ref_transport(grpc_chttp2_transport* t) { + t->refs.Ref(); +} #endif void grpc_chttp2_ack_ping(grpc_chttp2_transport* t, uint64_t id); From 74b780e0968ede809d69ce8c69e7e1e5d8685ce5 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 27 Nov 2018 11:03:51 -0800 Subject: [PATCH 0304/2143] added toolchain_resolution_debug for displaying platform --- tools/remote_build/rbe_common.bazelrc | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index 474f45bf53d..df72f129aba 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -37,6 +37,7 @@ build --verbose_failures=true build --experimental_strict_action_env=true build --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 +build --toolchain_resolution_debug # don't use port server build --define GRPC_PORT_ISOLATED_RUNTIME=1 From 0adcbd501445c61eac6fdf3f44099f5cd78475af Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Tue, 27 Nov 2018 10:18:30 -0800 Subject: [PATCH 0305/2143] gRPC release schedule --- doc/grpc_release_schedule.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 doc/grpc_release_schedule.md diff --git a/doc/grpc_release_schedule.md b/doc/grpc_release_schedule.md new file mode 100644 index 00000000000..bacd3758593 --- /dev/null +++ b/doc/grpc_release_schedule.md @@ -0,0 +1,22 @@ +# gRPC Release Schedule + +Below is the release schedule for gRPC [Java](https://github.com/grpc/grpc-java/releases), [Go](https://github.com/grpc/grpc-go/releases) and [Core](https://github.com/grpc/grpc/releases) and its dependent languages C++, C#, Objective-C, PHP, Python and Ruby. + +Releases are scheduled every six weeks on Tuesdays on a best effort basis. In some unavoidable situations a release may be delayed or a language may skip a release altogether and do the next release to catch up with other languages. See the past releases in the links above. A six-week cycle gives us a good balance between delivering new features/fixes quickly and keeping the release overhead low. + +Releases are cut from release branches. For Core and Java repos, the release branch is cut two weeks before the scheduled release date. For Go, the branch is cut just before the release. An RC (release candidate) is published for Core and its dependent languages just after the branch cut. This RC is later promoted to release version if no further changes are made to the release branch. We do our best to keep head of master branch stable at all times regardless of release schedule. Daily build packages from master branch for C#, PHP, Python, Ruby and Protoc plugins are published on [packages.grpc.io](https://packages.grpc.io/). If you depend on gRPC in production we recommend to set up your CI system to test the RCs and, if possible, the daily builds. + +Names of gRPC releases are [here](https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md). + +Release |Scheduled Branch Cut|Scheduled Release Date +--------|--------------------|------------- +v1.17.0 |Nov 19, 2018 |Dec 4, 2018 +v1.18.0 |Jan 2, 2019 |Jan 15, 2019 +v1.19.0 |Feb 12, 2019 |Feb 26, 2019 +v1.20.0 |Mar 26, 2019 |Apr 9, 2019 +v1.21.0 |May 7, 2019 |May 21, 2019 +v1.22.0 |Jun 18, 2019 |Jul 2, 2019 +v1.23.0 |Jul 30, 2019 |Aug 13, 2019 +v1.24.0 |Sept 10, 2019 |Sept 24, 2019 +v1.25.0 |Oct 22, 2019 |Nov 5, 2019 +v1.26.0 |Dec 3, 2019 |Dec 17, 2019 From 3adca9ff93cc5241c9fc1a7f45315d97daf8e52a Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 27 Nov 2018 12:11:09 -0800 Subject: [PATCH 0306/2143] Surface exceptions from Cython to Python as much as possible --- .../grpc/_cython/_cygrpc/credentials.pxd.pxi | 12 +++---- .../grpc/_cython/_cygrpc/credentials.pyx.pxi | 12 +++---- .../grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi | 2 +- .../grpc/_cython/_cygrpc/metadata.pxd.pxi | 4 +-- .../grpc/_cython/_cygrpc/metadata.pyx.pxi | 4 +-- .../grpc/_cython/_cygrpc/operation.pxd.pxi | 36 +++++++++---------- .../grpc/_cython/_cygrpc/operation.pyx.pxi | 36 +++++++++---------- .../grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi | 4 +-- .../grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi | 4 +-- .../grpcio/grpc/_cython/_cygrpc/time.pxd.pxi | 2 +- .../grpcio/grpc/_cython/_cygrpc/time.pyx.pxi | 2 +- .../tests/unit/_invalid_metadata_test.py | 3 ++ 12 files changed, 62 insertions(+), 59 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi index 8d732152478..1cef7269707 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi @@ -15,7 +15,7 @@ cdef class CallCredentials: - cdef grpc_call_credentials *c(self) + cdef grpc_call_credentials *c(self) except * # TODO(https://github.com/grpc/grpc/issues/12531): remove. cdef grpc_call_credentials *c_credentials @@ -36,7 +36,7 @@ cdef class MetadataPluginCallCredentials(CallCredentials): cdef readonly object _metadata_plugin cdef readonly bytes _name - cdef grpc_call_credentials *c(self) + cdef grpc_call_credentials *c(self) except * cdef grpc_call_credentials *_composition(call_credentialses) @@ -46,12 +46,12 @@ cdef class CompositeCallCredentials(CallCredentials): cdef readonly tuple _call_credentialses - cdef grpc_call_credentials *c(self) + cdef grpc_call_credentials *c(self) except * cdef class ChannelCredentials: - cdef grpc_channel_credentials *c(self) + cdef grpc_channel_credentials *c(self) except * # TODO(https://github.com/grpc/grpc/issues/12531): remove. cdef grpc_channel_credentials *c_credentials @@ -68,7 +68,7 @@ cdef class SSLChannelCredentials(ChannelCredentials): cdef readonly object _private_key cdef readonly object _certificate_chain - cdef grpc_channel_credentials *c(self) + cdef grpc_channel_credentials *c(self) except * cdef class CompositeChannelCredentials(ChannelCredentials): @@ -76,7 +76,7 @@ cdef class CompositeChannelCredentials(ChannelCredentials): cdef readonly tuple _call_credentialses cdef readonly ChannelCredentials _channel_credentials - cdef grpc_channel_credentials *c(self) + cdef grpc_channel_credentials *c(self) except * cdef class ServerCertificateConfig: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index ff523fb256c..034836833e6 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -35,7 +35,7 @@ def _spawn_callback_async(callback, args): cdef class CallCredentials: - cdef grpc_call_credentials *c(self): + cdef grpc_call_credentials *c(self) except *: raise NotImplementedError() @@ -69,7 +69,7 @@ cdef class MetadataPluginCallCredentials(CallCredentials): self._metadata_plugin = metadata_plugin self._name = name - cdef grpc_call_credentials *c(self): + cdef grpc_call_credentials *c(self) except *: cdef grpc_metadata_credentials_plugin c_metadata_plugin c_metadata_plugin.get_metadata = _get_metadata c_metadata_plugin.destroy = _destroy @@ -101,13 +101,13 @@ cdef class CompositeCallCredentials(CallCredentials): def __cinit__(self, call_credentialses): self._call_credentialses = call_credentialses - cdef grpc_call_credentials *c(self): + cdef grpc_call_credentials *c(self) except *: return _composition(self._call_credentialses) cdef class ChannelCredentials: - cdef grpc_channel_credentials *c(self): + cdef grpc_channel_credentials *c(self) except *: raise NotImplementedError() @@ -135,7 +135,7 @@ cdef class SSLChannelCredentials(ChannelCredentials): self._private_key = private_key self._certificate_chain = certificate_chain - cdef grpc_channel_credentials *c(self): + cdef grpc_channel_credentials *c(self) except *: cdef const char *c_pem_root_certificates cdef grpc_ssl_pem_key_cert_pair c_pem_key_certificate_pair if self._pem_root_certificates is None: @@ -164,7 +164,7 @@ cdef class CompositeChannelCredentials(ChannelCredentials): self._call_credentialses = call_credentialses self._channel_credentials = channel_credentials - cdef grpc_channel_credentials *c(self): + cdef grpc_channel_credentials *c(self) except *: cdef grpc_channel_credentials *c_channel_credentials c_channel_credentials = self._channel_credentials.c() cdef grpc_call_credentials *c_call_credentials_composition = _composition( diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi index f9a1b2856d7..a1618d04d0e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi @@ -266,7 +266,7 @@ cdef grpc_error* socket_listen(grpc_custom_socket* socket) with gil: (socket.impl).socket.listen(50) return grpc_error_none() -cdef void accept_callback_cython(SocketWrapper s): +cdef void accept_callback_cython(SocketWrapper s) except *: try: conn, address = s.socket.accept() sw = SocketWrapper() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi index a18c3658077..fc72ac1576b 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi @@ -14,10 +14,10 @@ cdef void _store_c_metadata( - metadata, grpc_metadata **c_metadata, size_t *c_count) + metadata, grpc_metadata **c_metadata, size_t *c_count) except * -cdef void _release_c_metadata(grpc_metadata *c_metadata, int count) +cdef void _release_c_metadata(grpc_metadata *c_metadata, int count) except * cdef tuple _metadatum(grpc_slice key_slice, grpc_slice value_slice) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi index 53f0c7f0bbe..caf867b5696 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi @@ -25,7 +25,7 @@ _Metadatum = collections.namedtuple('_Metadatum', ('key', 'value',)) cdef void _store_c_metadata( - metadata, grpc_metadata **c_metadata, size_t *c_count): + metadata, grpc_metadata **c_metadata, size_t *c_count) except *: if metadata is None: c_count[0] = 0 c_metadata[0] = NULL @@ -45,7 +45,7 @@ cdef void _store_c_metadata( c_metadata[0][index].value = _slice_from_bytes(encoded_value) -cdef void _release_c_metadata(grpc_metadata *c_metadata, int count): +cdef void _release_c_metadata(grpc_metadata *c_metadata, int count) except *: if 0 < count: for index in range(count): grpc_slice_unref(c_metadata[index].key) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/operation.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/operation.pxd.pxi index 69a2a4989ed..c9df32dadf5 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/operation.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/operation.pxd.pxi @@ -15,8 +15,8 @@ cdef class Operation: - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * # TODO(https://github.com/grpc/grpc/issues/7950): Eliminate this! cdef grpc_op c_op @@ -29,8 +29,8 @@ cdef class SendInitialMetadataOperation(Operation): cdef grpc_metadata *_c_initial_metadata cdef size_t _c_initial_metadata_count - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class SendMessageOperation(Operation): @@ -39,16 +39,16 @@ cdef class SendMessageOperation(Operation): cdef readonly int _flags cdef grpc_byte_buffer *_c_message_byte_buffer - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class SendCloseFromClientOperation(Operation): cdef readonly int _flags - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class SendStatusFromServerOperation(Operation): @@ -61,8 +61,8 @@ cdef class SendStatusFromServerOperation(Operation): cdef size_t _c_trailing_metadata_count cdef grpc_slice _c_details - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class ReceiveInitialMetadataOperation(Operation): @@ -71,8 +71,8 @@ cdef class ReceiveInitialMetadataOperation(Operation): cdef tuple _initial_metadata cdef grpc_metadata_array _c_initial_metadata - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class ReceiveMessageOperation(Operation): @@ -81,8 +81,8 @@ cdef class ReceiveMessageOperation(Operation): cdef grpc_byte_buffer *_c_message_byte_buffer cdef bytes _message - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class ReceiveStatusOnClientOperation(Operation): @@ -97,8 +97,8 @@ cdef class ReceiveStatusOnClientOperation(Operation): cdef str _details cdef str _error_string - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class ReceiveCloseOnServerOperation(Operation): @@ -107,5 +107,5 @@ cdef class ReceiveCloseOnServerOperation(Operation): cdef object _cancelled cdef int _c_cancelled - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/operation.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/operation.pyx.pxi index 454627f570a..c8a390106a8 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/operation.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/operation.pyx.pxi @@ -15,10 +15,10 @@ cdef class Operation: - cdef void c(self): + cdef void c(self) except *: raise NotImplementedError() - cdef void un_c(self): + cdef void un_c(self) except *: raise NotImplementedError() @@ -31,7 +31,7 @@ cdef class SendInitialMetadataOperation(Operation): def type(self): return GRPC_OP_SEND_INITIAL_METADATA - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_SEND_INITIAL_METADATA self.c_op.flags = self._flags _store_c_metadata( @@ -41,7 +41,7 @@ cdef class SendInitialMetadataOperation(Operation): self.c_op.data.send_initial_metadata.count = self._c_initial_metadata_count self.c_op.data.send_initial_metadata.maybe_compression_level.is_set = 0 - cdef void un_c(self): + cdef void un_c(self) except *: _release_c_metadata( self._c_initial_metadata, self._c_initial_metadata_count) @@ -55,7 +55,7 @@ cdef class SendMessageOperation(Operation): def type(self): return GRPC_OP_SEND_MESSAGE - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_SEND_MESSAGE self.c_op.flags = self._flags cdef grpc_slice message_slice = grpc_slice_from_copied_buffer( @@ -65,7 +65,7 @@ cdef class SendMessageOperation(Operation): grpc_slice_unref(message_slice) self.c_op.data.send_message.send_message = self._c_message_byte_buffer - cdef void un_c(self): + cdef void un_c(self) except *: grpc_byte_buffer_destroy(self._c_message_byte_buffer) @@ -77,11 +77,11 @@ cdef class SendCloseFromClientOperation(Operation): def type(self): return GRPC_OP_SEND_CLOSE_FROM_CLIENT - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_SEND_CLOSE_FROM_CLIENT self.c_op.flags = self._flags - cdef void un_c(self): + cdef void un_c(self) except *: pass @@ -96,7 +96,7 @@ cdef class SendStatusFromServerOperation(Operation): def type(self): return GRPC_OP_SEND_STATUS_FROM_SERVER - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_SEND_STATUS_FROM_SERVER self.c_op.flags = self._flags _store_c_metadata( @@ -110,7 +110,7 @@ cdef class SendStatusFromServerOperation(Operation): self._c_details = _slice_from_bytes(_encode(self._details)) self.c_op.data.send_status_from_server.status_details = &self._c_details - cdef void un_c(self): + cdef void un_c(self) except *: grpc_slice_unref(self._c_details) _release_c_metadata( self._c_trailing_metadata, self._c_trailing_metadata_count) @@ -124,14 +124,14 @@ cdef class ReceiveInitialMetadataOperation(Operation): def type(self): return GRPC_OP_RECV_INITIAL_METADATA - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_RECV_INITIAL_METADATA self.c_op.flags = self._flags grpc_metadata_array_init(&self._c_initial_metadata) self.c_op.data.receive_initial_metadata.receive_initial_metadata = ( &self._c_initial_metadata) - cdef void un_c(self): + cdef void un_c(self) except *: self._initial_metadata = _metadata(&self._c_initial_metadata) grpc_metadata_array_destroy(&self._c_initial_metadata) @@ -147,13 +147,13 @@ cdef class ReceiveMessageOperation(Operation): def type(self): return GRPC_OP_RECV_MESSAGE - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_RECV_MESSAGE self.c_op.flags = self._flags self.c_op.data.receive_message.receive_message = ( &self._c_message_byte_buffer) - cdef void un_c(self): + cdef void un_c(self) except *: cdef grpc_byte_buffer_reader message_reader cdef bint message_reader_status cdef grpc_slice message_slice @@ -189,7 +189,7 @@ cdef class ReceiveStatusOnClientOperation(Operation): def type(self): return GRPC_OP_RECV_STATUS_ON_CLIENT - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_RECV_STATUS_ON_CLIENT self.c_op.flags = self._flags grpc_metadata_array_init(&self._c_trailing_metadata) @@ -202,7 +202,7 @@ cdef class ReceiveStatusOnClientOperation(Operation): self.c_op.data.receive_status_on_client.error_string = ( &self._c_error_string) - cdef void un_c(self): + cdef void un_c(self) except *: self._trailing_metadata = _metadata(&self._c_trailing_metadata) grpc_metadata_array_destroy(&self._c_trailing_metadata) self._code = self._c_code @@ -235,12 +235,12 @@ cdef class ReceiveCloseOnServerOperation(Operation): def type(self): return GRPC_OP_RECV_CLOSE_ON_SERVER - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_RECV_CLOSE_ON_SERVER self.c_op.flags = self._flags self.c_op.data.receive_close_on_server.cancelled = &self._c_cancelled - cdef void un_c(self): + cdef void un_c(self) except *: self._cancelled = bool(self._c_cancelled) def cancelled(self): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi index f9a3b5e8f40..d8ba1ea9bd5 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi @@ -32,7 +32,7 @@ cdef class _RequestCallTag(_Tag): cdef CallDetails call_details cdef grpc_metadata_array c_invocation_metadata - cdef void prepare(self) + cdef void prepare(self) except * cdef RequestCallEvent event(self, grpc_event c_event) @@ -44,7 +44,7 @@ cdef class _BatchOperationTag(_Tag): cdef grpc_op *c_ops cdef size_t c_nops - cdef void prepare(self) + cdef void prepare(self) except * cdef BatchOperationEvent event(self, grpc_event c_event) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi index aaca458442f..be5013c8f7b 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi @@ -35,7 +35,7 @@ cdef class _RequestCallTag(_Tag): self.call = None self.call_details = None - cdef void prepare(self): + cdef void prepare(self) except *: self.call = Call() self.call_details = CallDetails() grpc_metadata_array_init(&self.c_invocation_metadata) @@ -55,7 +55,7 @@ cdef class _BatchOperationTag: self._operations = operations self._retained_call = call - cdef void prepare(self): + cdef void prepare(self) except *: 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) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi index ce67c61eaf6..1319ac0481d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi @@ -16,4 +16,4 @@ cdef gpr_timespec _timespec_from_time(object time) -cdef double _time_from_timespec(gpr_timespec timespec) +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 7a668680b8f..c452dd54f82 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi @@ -24,7 +24,7 @@ cdef gpr_timespec _timespec_from_time(object time): return timespec -cdef double _time_from_timespec(gpr_timespec timespec): +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 diff --git a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py index 9771764635c..0ff49490d5f 100644 --- a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py +++ b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py @@ -130,6 +130,9 @@ class InvalidMetadataTest(unittest.TestCase): self._stream_stream(request_iterator, metadata=metadata) self.assertIn(expected_error_details, str(exception_context.exception)) + def testInvalidMetadata(self): + self.assertRaises(TypeError, self._unary_unary, b'', metadata=42) + if __name__ == '__main__': logging.basicConfig() From 66b2005cbb322bc1d783b90a574b0e14df906bcb Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 27 Nov 2018 12:56:56 -0800 Subject: [PATCH 0307/2143] Enable errqueue support for linux kernel versions 4.0.0 and above --- src/core/lib/iomgr/ev_posix.cc | 10 +++---- src/core/lib/iomgr/internal_errqueue.cc | 39 +++++++++++++++++++++++-- src/core/lib/iomgr/internal_errqueue.h | 8 ++++- src/core/lib/iomgr/iomgr.cc | 2 ++ src/core/lib/iomgr/port.h | 3 +- 5 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 8a7dc7b004a..ef235894801 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -36,6 +36,7 @@ #include "src/core/lib/iomgr/ev_epoll1_linux.h" #include "src/core/lib/iomgr/ev_epollex_linux.h" #include "src/core/lib/iomgr/ev_poll_posix.h" +#include "src/core/lib/iomgr/internal_errqueue.h" grpc_core::TraceFlag grpc_polling_trace(false, "polling"); /* Disabled by default */ @@ -236,12 +237,11 @@ void grpc_event_engine_shutdown(void) { } bool grpc_event_engine_can_track_errors(void) { -/* Only track errors if platform supports errqueue. */ -#ifdef GRPC_LINUX_ERRQUEUE - return g_event_engine->can_track_err; -#else + /* Only track errors if platform supports errqueue. */ + if (grpc_core::kernel_supports_errqueue()) { + return g_event_engine->can_track_err; + } return false; -#endif /* GRPC_LINUX_ERRQUEUE */ } grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) { diff --git a/src/core/lib/iomgr/internal_errqueue.cc b/src/core/lib/iomgr/internal_errqueue.cc index 99c22e90555..982d709f094 100644 --- a/src/core/lib/iomgr/internal_errqueue.cc +++ b/src/core/lib/iomgr/internal_errqueue.cc @@ -20,17 +20,50 @@ #include "src/core/lib/iomgr/port.h" +#include #include "src/core/lib/iomgr/internal_errqueue.h" #ifdef GRPC_POSIX_SOCKET_TCP -bool kernel_supports_errqueue() { +#include +#include +#include +#include + +namespace grpc_core { +static bool errqueue_supported = false; + +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) - return true; + struct utsname buffer; + if (uname(&buffer) != 0) { + gpr_log(GPR_ERROR, "uname: %s", strerror(errno)); + return; + } + char* release = buffer.release; + if (release == nullptr) { + return; + } + + if (strtol(release, nullptr, 10) >= 4) { + errqueue_supported = true; + } else { + gpr_log(GPR_DEBUG, "ERRQUEUE support not enabled"); + } #endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) */ #endif /* LINUX_VERSION_CODE */ - return false; } +} /* namespace grpc_core */ + +#else + +namespace grpc_core { +void grpc_errqueue_init() {} +} /* namespace grpc_core */ #endif /* GRPC_POSIX_SOCKET_TCP */ diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h index 9d122808f9b..f8644c2536c 100644 --- a/src/core/lib/iomgr/internal_errqueue.h +++ b/src/core/lib/iomgr/internal_errqueue.h @@ -76,8 +76,14 @@ constexpr uint32_t kTimestampingRecordingOptions = * Currently allowing only linux kernels above 4.0.0 */ bool kernel_supports_errqueue(); -} // namespace grpc_core + +} /* namespace grpc_core */ #endif /* GRPC_POSIX_SOCKET_TCP */ +namespace grpc_core { +/* Initializes errqueue support */ +void grpc_errqueue_init(); +} /* namespace grpc_core */ + #endif /* GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H */ diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index 30b68db4df7..fd09a6863b8 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -36,6 +36,7 @@ #include "src/core/lib/iomgr/buffer_list.h" #include "src/core/lib/iomgr/exec_ctx.h" #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" @@ -58,6 +59,7 @@ void grpc_iomgr_init() { g_root_object.name = (char*)"root"; grpc_network_status_init(); grpc_iomgr_platform_init(); + grpc_core::grpc_errqueue_init(); } void grpc_iomgr_start() { grpc_timer_manager_init(); } diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index bf56a7298d2..c8046b21dcd 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -62,8 +62,7 @@ #define GRPC_HAVE_UNIX_SOCKET 1 #ifdef LINUX_VERSION_CODE #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) -/* TODO(yashykt): Re-enable once Fathom changes are commited. -#define GRPC_LINUX_ERRQUEUE 1 */ +#define GRPC_LINUX_ERRQUEUE 1 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */ #endif /* LINUX_VERSION_CODE */ #define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1 From a7b24f511fc7ab5cb41d6aee9838157955f2f9b3 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Tue, 27 Nov 2018 13:18:27 -0800 Subject: [PATCH 0308/2143] Revert "Resolve naming conflicts" This reverts commit c1af11fbd622c640b15a7c8e5977e0c40a546969. --- 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 58e15bf15ee..4d9a66e82c8 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -261,9 +261,9 @@ static void notify_on_write(grpc_tcp* tcp) { gpr_log(GPR_INFO, "TCP:%p notify_on_write", tcp); } - static bool event_engine_run_in_background = + static bool grpc_event_engine_run_in_background = grpc_event_engine_run_in_background(); - if (event_engine_run_in_background) { + if (grpc_event_engine_run_in_background) { // If there is a polling engine always running in the background, there is // no need to run the backup poller. GRPC_CLOSURE_INIT(&tcp->write_done_closure, tcp_handle_write, tcp, From dc9ffa80349498cd80fd316b66571f6e94c2eaa1 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Tue, 27 Nov 2018 13:22:44 -0800 Subject: [PATCH 0309/2143] Revert "Use a static local flag to memorize whether the grpc event engine runs in background or not" This reverts commit 9bbda894cbd845cea48a76c536d9731436c6313f. --- src/core/lib/iomgr/tcp_posix.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 4d9a66e82c8..c802fcca750 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -260,10 +260,7 @@ static void notify_on_write(grpc_tcp* tcp) { if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p notify_on_write", tcp); } - - static bool grpc_event_engine_run_in_background = - grpc_event_engine_run_in_background(); - if (grpc_event_engine_run_in_background) { + if (grpc_event_engine_run_in_background()) { // If there is a polling engine always running in the background, there is // no need to run the backup poller. GRPC_CLOSURE_INIT(&tcp->write_done_closure, tcp_handle_write, tcp, From 49528b9713d0e60cdb7806cb3c10e2e5b9a92f03 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 27 Nov 2018 14:13:28 -0800 Subject: [PATCH 0310/2143] trying highmem machine --- third_party/toolchains/BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 39699f31123..9481d3b1375 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -69,7 +69,7 @@ platform( } properties: { name: "gceMachineType" # Small machines for majority of tests. - value: "n1-standard-8" + value: "n1-highmem-8" } """, ) From cdd698810b99f2be1c67f05c28d031ebddb04cea Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 27 Nov 2018 11:46:05 -0800 Subject: [PATCH 0311/2143] 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 eff3b4ec306e4b7cdedab5b42fbbde8f800208aa Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 27 Nov 2018 15:13:33 -0800 Subject: [PATCH 0312/2143] trying standard-16 machine --- third_party/toolchains/BUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 9481d3b1375..7df0074b402 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -68,8 +68,8 @@ platform( value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:9bd8ba020af33edb5f11eff0af2f63b3bcb168cd6566d7b27c6685e717787928" } properties: { - name: "gceMachineType" # Small machines for majority of tests. - value: "n1-highmem-8" + name: "gceMachineType" # Large machines for some resource demanding tests (TSAN). + value: "n1-standard-16" } """, ) From e00b58ba5aa2e6683b156570eb785e679a628d3b Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 27 Nov 2018 15:25:30 -0800 Subject: [PATCH 0313/2143] trying latest image --- third_party/toolchains/BUILD | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 7df0074b402..2736543fcf9 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -20,17 +20,17 @@ package(default_visibility = ["//visibility:public"]) # Update every time when a new container is released. alias( name = "rbe_ubuntu1604", - actual = ":rbe_ubuntu1604_r340178", + actual = ":rbe_ubuntu1604_r342117", ) alias( name = "rbe_ubuntu1604_large", - actual = ":rbe_ubuntu1604_r340178_large", + actual = ":rbe_ubuntu1604_r342117_large", ) -# RBE Ubuntu16_04 r340178 +# RBE Ubuntu16_04 r342117 platform( - name = "rbe_ubuntu1604_r340178", + name = "rbe_ubuntu1604_r342117", constraint_values = [ "@bazel_tools//platforms:x86_64", "@bazel_tools//platforms:linux", @@ -42,7 +42,7 @@ platform( remote_execution_properties = """ properties: { name: "container-image" - value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:9bd8ba020af33edb5f11eff0af2f63b3bcb168cd6566d7b27c6685e717787928" + value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:f3120a030a19d67626ababdac79cc787e699a1aa924081431285118f87e7b375" } properties: { name: "gceMachineType" # Small machines for majority of tests. @@ -51,9 +51,9 @@ platform( """, ) -# RBE Ubuntu16_04 r340178 large +# RBE Ubuntu16_04 r342117 large platform( - name = "rbe_ubuntu1604_r340178_large", + name = "rbe_ubuntu1604_r342117_large", constraint_values = [ "@bazel_tools//platforms:x86_64", "@bazel_tools//platforms:linux", @@ -65,11 +65,11 @@ platform( remote_execution_properties = """ properties: { name: "container-image" - value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:9bd8ba020af33edb5f11eff0af2f63b3bcb168cd6566d7b27c6685e717787928" + value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:f3120a030a19d67626ababdac79cc787e699a1aa924081431285118f87e7b375" } properties: { name: "gceMachineType" # Large machines for some resource demanding tests (TSAN). - value: "n1-standard-16" + value: "n1-standard-8" } """, ) From cee77cfd38625c49f324d2956937e9d93f33a808 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 26 Nov 2018 01:20:35 -0800 Subject: [PATCH 0314/2143] Add traced information to stream op --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 1 + src/core/lib/transport/transport.h | 6 +++++- 2 files changed, 6 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 b1b8c0083b1..99c675f503a 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1390,6 +1390,7 @@ static void perform_stream_op_locked(void* stream_op, GRPC_STATS_INC_HTTP2_OP_BATCHES(); s->context = op->payload->context; + s->traced = op->is_traced; if (grpc_http_trace.enabled()) { char* str = grpc_transport_stream_op_batch_string(op); gpr_log(GPR_INFO, "perform_stream_op_locked: %s; on_complete = %p", str, diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index edfa7030d13..5ce568834e9 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -129,7 +129,8 @@ struct grpc_transport_stream_op_batch { recv_initial_metadata(false), recv_message(false), recv_trailing_metadata(false), - cancel_stream(false) {} + cancel_stream(false), + is_traced(false) {} /** Should be scheduled when all of the non-recv operations in the batch are complete. @@ -167,6 +168,9 @@ struct grpc_transport_stream_op_batch { /** Cancel this stream with the provided error */ bool cancel_stream : 1; + /** Is this stream traced */ + bool is_traced : 1; + /*************************************************************************** * remaining fields are initialized and used at the discretion of the * current handler of the op */ From 023415c461f72404c598f5ee52a4502a8a14afef Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 27 Nov 2018 15:50:08 -0800 Subject: [PATCH 0315/2143] Circumvent padding issues and make traced the second last field --- src/core/ext/transport/chttp2/transport/internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 1c79cf63531..aeaa4935ad7 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -642,10 +642,10 @@ struct grpc_chttp2_stream { /** Whether bytes stored in unprocessed_incoming_byte_stream is decompressed */ bool unprocessed_incoming_frames_decompressed = false; - /** gRPC header bytes that are already decompressed */ - size_t decompressed_header_bytes = 0; /** Whether the bytes needs to be traced using Fathom */ bool traced = false; + /** gRPC header bytes that are already decompressed */ + size_t decompressed_header_bytes = 0; }; /** Transport writing call flow: From 23a9cf91f292fc1447579a72dc52e9730ece9b57 Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 27 Nov 2018 16:12:44 -0800 Subject: [PATCH 0316/2143] 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 fe9ba9adf8429687ef3d524ec8fc91a18e03f625 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 27 Nov 2018 17:14:08 -0800 Subject: [PATCH 0317/2143] Always set fd to be readable/writable on receiving EPOLLERR --- src/core/lib/iomgr/tcp_posix.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index cb4c9db7a68..4a5ca615e5a 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -740,7 +740,7 @@ static bool process_errors(grpc_tcp* tcp) { } return false; } - process_timestamp(tcp, &msg, cmsg); + cmsg = process_timestamp(tcp, &msg, cmsg); } } } @@ -761,13 +761,11 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { /* We are still interested in collecting timestamps, so let's try reading * them. */ - if (!process_errors(tcp)) { - /* This was not a timestamps error. This was an actual error. Set the - * read and write closures to be ready. - */ - grpc_fd_set_readable(tcp->em_fd); - grpc_fd_set_writable(tcp->em_fd); - } + process_errors(tcp); + /* This might not a timestamps error. Set the read and write closures to be + * ready. */ + grpc_fd_set_readable(tcp->em_fd); + grpc_fd_set_writable(tcp->em_fd); GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, grpc_schedule_on_exec_ctx); grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); From 28ad1bd28e0ea9b372089333c739a2f4746e99c2 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 27 Nov 2018 17:18:19 -0800 Subject: [PATCH 0318/2143] Use grpc_event_engine_can_track_errors --- src/core/lib/iomgr/ev_posix.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index ef235894801..6f6d134cedb 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -247,8 +247,8 @@ bool grpc_event_engine_can_track_errors(void) { grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) { GRPC_POLLING_API_TRACE("fd_create(%d, %s, %d)", fd, name, track_err); GRPC_FD_TRACE("fd_create(%d, %s, %d)", fd, name, track_err); - return g_event_engine->fd_create(fd, name, - track_err && g_event_engine->can_track_err); + return g_event_engine->fd_create( + fd, name, track_err && grpc_event_engine_can_track_errors()); } int grpc_fd_wrapped_fd(grpc_fd* fd) { From 43599facf4c8b42b8a14d0601556f4231d9d10f8 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 20 Nov 2018 16:57:08 -0800 Subject: [PATCH 0319/2143] Channelz Python wrapper implementation * Expose the C-Core API in Cython layer * Handle the object translation * Create a separate package for Channelz specifically * Handle nullptr and raise exception if seen one * Translate C++ Channelz unit tests * Adding 5 more invalid query unit tests Adding peripheral utility for grpcio-channelz package * Add to `pylint_code.sh` * Add to Python build script * Add to artifact build script * Add to Bazel * Add to Sphinx module list --- doc/python/sphinx/conf.py | 3 + doc/python/sphinx/grpc_channelz.rst | 12 + doc/python/sphinx/index.rst | 1 + src/proto/grpc/channelz/BUILD | 7 + src/proto/grpc/health/v1/BUILD | 1 - src/python/grpcio/grpc/_cython/BUILD.bazel | 1 + .../grpc/_cython/_cygrpc/channelz.pyx.pxi | 56 +++ .../grpcio/grpc/_cython/_cygrpc/grpc.pxi | 10 + src/python/grpcio/grpc/_cython/cygrpc.pyx | 1 + src/python/grpcio/grpc/_server.py | 4 +- src/python/grpcio_channelz/.gitignore | 6 + src/python/grpcio_channelz/MANIFEST.in | 3 + src/python/grpcio_channelz/README.rst | 9 + .../grpcio_channelz/channelz_commands.py | 63 +++ .../grpcio_channelz/grpc_channelz/__init__.py | 13 + .../grpc_channelz/v1/BUILD.bazel | 38 ++ .../grpc_channelz/v1/__init__.py | 13 + .../grpc_channelz/v1/channelz.py | 114 +++++ src/python/grpcio_channelz/grpc_version.py | 17 + src/python/grpcio_channelz/setup.py | 96 ++++ src/python/grpcio_tests/setup.py | 1 + .../grpcio_tests/tests/channelz/BUILD.bazel | 15 + .../grpcio_tests/tests/channelz/__init__.py | 13 + .../tests/channelz/_channelz_servicer_test.py | 476 ++++++++++++++++++ src/python/grpcio_tests/tests/tests.json | 1 + .../grpcio_channelz/grpc_version.py.template | 19 + tools/distrib/pylint_code.sh | 1 + .../artifacts/build_artifact_python.sh | 5 + .../run_tests/helper_scripts/build_python.sh | 5 + 29 files changed, 1002 insertions(+), 2 deletions(-) create mode 100644 doc/python/sphinx/grpc_channelz.rst create mode 100644 src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi create mode 100644 src/python/grpcio_channelz/.gitignore create mode 100644 src/python/grpcio_channelz/MANIFEST.in create mode 100644 src/python/grpcio_channelz/README.rst create mode 100644 src/python/grpcio_channelz/channelz_commands.py create mode 100644 src/python/grpcio_channelz/grpc_channelz/__init__.py create mode 100644 src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel create mode 100644 src/python/grpcio_channelz/grpc_channelz/v1/__init__.py create mode 100644 src/python/grpcio_channelz/grpc_channelz/v1/channelz.py create mode 100644 src/python/grpcio_channelz/grpc_version.py create mode 100644 src/python/grpcio_channelz/setup.py create mode 100644 src/python/grpcio_tests/tests/channelz/BUILD.bazel create mode 100644 src/python/grpcio_tests/tests/channelz/__init__.py create mode 100644 src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py create mode 100644 templates/src/python/grpcio_channelz/grpc_version.py.template diff --git a/doc/python/sphinx/conf.py b/doc/python/sphinx/conf.py index 1eb3a5de7fd..307c3bdaf60 100644 --- a/doc/python/sphinx/conf.py +++ b/doc/python/sphinx/conf.py @@ -19,6 +19,7 @@ import sys PYTHON_FOLDER = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', 'src', 'python') 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_testing')) @@ -63,6 +64,8 @@ autodoc_default_options = { autodoc_mock_imports = [ 'grpc._cython', + 'grpc_channelz.v1.channelz_pb2', + 'grpc_channelz.v1.channelz_pb2_grpc', 'grpc_health.v1.health_pb2', 'grpc_health.v1.health_pb2_grpc', 'grpc_reflection.v1alpha.reflection_pb2', diff --git a/doc/python/sphinx/grpc_channelz.rst b/doc/python/sphinx/grpc_channelz.rst new file mode 100644 index 00000000000..f65793a071a --- /dev/null +++ b/doc/python/sphinx/grpc_channelz.rst @@ -0,0 +1,12 @@ +gRPC Channelz +==================== + +What is gRPC Channelz? +--------------------------------------------- + +Design Document `gRPC Channelz `_ + +Module Contents +--------------- + +.. automodule:: grpc_channelz.v1.channelz diff --git a/doc/python/sphinx/index.rst b/doc/python/sphinx/index.rst index 322ca33e157..2f8a47a0747 100644 --- a/doc/python/sphinx/index.rst +++ b/doc/python/sphinx/index.rst @@ -10,6 +10,7 @@ API Reference :caption: Contents: grpc + grpc_channelz grpc_health_checking grpc_reflection grpc_testing diff --git a/src/proto/grpc/channelz/BUILD b/src/proto/grpc/channelz/BUILD index bdb03d5e2d0..b6b485e3e8d 100644 --- a/src/proto/grpc/channelz/BUILD +++ b/src/proto/grpc/channelz/BUILD @@ -24,3 +24,10 @@ grpc_proto_library( has_services = True, well_known_protos = True, ) + +filegroup( + name = "channelz_proto_file", + srcs = [ + "channelz.proto", + ], +) diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD index 97642985c9d..38a7d992e06 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD @@ -29,4 +29,3 @@ filegroup( "health.proto", ], ) - diff --git a/src/python/grpcio/grpc/_cython/BUILD.bazel b/src/python/grpcio/grpc/_cython/BUILD.bazel index cfd3a51d9bb..e318298d0ab 100644 --- a/src/python/grpcio/grpc/_cython/BUILD.bazel +++ b/src/python/grpcio/grpc/_cython/BUILD.bazel @@ -12,6 +12,7 @@ pyx_library( "_cygrpc/grpc_string.pyx.pxi", "_cygrpc/arguments.pyx.pxi", "_cygrpc/call.pyx.pxi", + "_cygrpc/channelz.pyx.pxi", "_cygrpc/channel.pyx.pxi", "_cygrpc/credentials.pyx.pxi", "_cygrpc/completion_queue.pyx.pxi", diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi new file mode 100644 index 00000000000..572a473d3e8 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi @@ -0,0 +1,56 @@ +# 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. + + +def channelz_get_top_channels(start_channel_id): + cdef char *c_returned_str = grpc_channelz_get_top_channels(start_channel_id) + if c_returned_str == NULL: + raise ValueError('Failed to get top channels, please ensure your start_channel_id==%s is valid' % start_channel_id) + return c_returned_str + +def channelz_get_servers(start_server_id): + cdef char *c_returned_str = grpc_channelz_get_servers(start_server_id) + if c_returned_str == NULL: + raise ValueError('Failed to get servers, please ensure your start_server_id==%s is valid' % start_server_id) + return c_returned_str + +def channelz_get_server(server_id): + cdef char *c_returned_str = grpc_channelz_get_server(server_id) + if c_returned_str == NULL: + raise ValueError('Failed to get the server, please ensure your server_id==%s is valid' % server_id) + return c_returned_str + +def channelz_get_server_sockets(server_id, start_socket_id): + cdef char *c_returned_str = grpc_channelz_get_server_sockets(server_id, start_socket_id) + if c_returned_str == NULL: + raise ValueError('Failed to get server sockets, please ensure your server_id==%s and start_socket_id==%s is valid' % (server_id, start_socket_id)) + return c_returned_str + +def channelz_get_channel(channel_id): + cdef char *c_returned_str = grpc_channelz_get_channel(channel_id) + if c_returned_str == NULL: + raise ValueError('Failed to get the channel, please ensure your channel_id==%s is valid' % (channel_id)) + return c_returned_str + +def channelz_get_subchannel(subchannel_id): + cdef char *c_returned_str = grpc_channelz_get_subchannel(subchannel_id) + if c_returned_str == NULL: + raise ValueError('Failed to get the subchannel, please ensure your subchannel_id==%s is valid' % (subchannel_id)) + return c_returned_str + +def channelz_get_socket(socket_id): + cdef char *c_returned_str = grpc_channelz_get_socket(socket_id) + if c_returned_str == NULL: + raise ValueError('Failed to get the socket, please ensure your socket_id==%s is valid' % (socket_id)) + return c_returned_str diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 23428f0b0c0..ccd46dbf92e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -13,6 +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 @@ -391,6 +392,15 @@ cdef extern from "grpc/grpc.h": void grpc_server_cancel_all_calls(grpc_server *server) nogil void grpc_server_destroy(grpc_server *server) nogil + char* grpc_channelz_get_top_channels(intptr_t start_channel_id) + char* grpc_channelz_get_servers(intptr_t start_server_id) + char* grpc_channelz_get_server(intptr_t server_id) + char* grpc_channelz_get_server_sockets(intptr_t server_id, + intptr_t start_socket_id) + char* grpc_channelz_get_channel(intptr_t channel_id) + char* grpc_channelz_get_subchannel(intptr_t subchannel_id) + char* grpc_channelz_get_socket(intptr_t socket_id) + cdef extern from "grpc/grpc_security.h": diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx index ae5c07bfc82..9ab919375c0 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -35,6 +35,7 @@ include "_cygrpc/server.pyx.pxi" include "_cygrpc/tag.pyx.pxi" include "_cygrpc/time.pyx.pxi" include "_cygrpc/_hooks.pyx.pxi" +include "_cygrpc/channelz.pyx.pxi" include "_cygrpc/grpc_gevent.pyx.pxi" diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 7276a7fd90e..fea1ca8da69 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -828,7 +828,9 @@ class _Server(grpc.Server): return _stop(self._state, grace) def __del__(self): - _stop(self._state, None) + if hasattr(self, '_state'): + _stop(self._state, None) + del self._state def create_server(thread_pool, generic_rpc_handlers, interceptors, options, diff --git a/src/python/grpcio_channelz/.gitignore b/src/python/grpcio_channelz/.gitignore new file mode 100644 index 00000000000..0c5da6b5af1 --- /dev/null +++ b/src/python/grpcio_channelz/.gitignore @@ -0,0 +1,6 @@ +*.proto +*_pb2.py +*_pb2_grpc.py +build/ +grpcio_channelz.egg-info/ +dist/ diff --git a/src/python/grpcio_channelz/MANIFEST.in b/src/python/grpcio_channelz/MANIFEST.in new file mode 100644 index 00000000000..5597f375ba6 --- /dev/null +++ b/src/python/grpcio_channelz/MANIFEST.in @@ -0,0 +1,3 @@ +include grpc_version.py +recursive-include grpc_channelz *.py +global-exclude *.pyc diff --git a/src/python/grpcio_channelz/README.rst b/src/python/grpcio_channelz/README.rst new file mode 100644 index 00000000000..efeaa560646 --- /dev/null +++ b/src/python/grpcio_channelz/README.rst @@ -0,0 +1,9 @@ +gRPC Python Channelz package +============================== + +Channelz is a live debug tool in gRPC Python. + +Dependencies +------------ + +Depends on the `grpcio` package, available from PyPI via `pip install grpcio`. diff --git a/src/python/grpcio_channelz/channelz_commands.py b/src/python/grpcio_channelz/channelz_commands.py new file mode 100644 index 00000000000..e9ad3550340 --- /dev/null +++ b/src/python/grpcio_channelz/channelz_commands.py @@ -0,0 +1,63 @@ +# 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__))) +CHANNELZ_PROTO = os.path.join(ROOT_DIR, + '../../proto/grpc/channelz/channelz.proto') + + +class CopyProtoModules(setuptools.Command): + """Command to copy proto modules from grpc/src/proto.""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + if os.path.isfile(CHANNELZ_PROTO): + shutil.copyfile(CHANNELZ_PROTO, + os.path.join(ROOT_DIR, + 'grpc_channelz/v1/channelz.proto')) + + +class BuildPackageProtos(setuptools.Command): + """Command to generate project *_pb2.py modules from proto files.""" + + description = '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). + from grpc_tools import command + command.build_package_protos(self.distribution.package_dir['']) diff --git a/src/python/grpcio_channelz/grpc_channelz/__init__.py b/src/python/grpcio_channelz/grpc_channelz/__init__.py new file mode 100644 index 00000000000..38fdfc9c5cf --- /dev/null +++ b/src/python/grpcio_channelz/grpc_channelz/__init__.py @@ -0,0 +1,13 @@ +# 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. diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel new file mode 100644 index 00000000000..aae8cedb760 --- /dev/null +++ b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel @@ -0,0 +1,38 @@ +load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") + +package(default_visibility = ["//visibility:public"]) + +genrule( + name = "mv_channelz_proto", + srcs = [ + "//src/proto/grpc/channelz:channelz_proto_file", + ], + outs = ["channelz.proto",], + cmd = "cp $< $@", +) + +py_proto_library( + name = "py_channelz_proto", + protos = ["mv_channelz_proto",], + imports = [ + "external/com_google_protobuf/src/", + ], + inputs = [ + "@com_google_protobuf//:well_known_protos", + ], + with_grpc = True, + deps = [ + requirement('protobuf'), + ], +) + +py_library( + name = "grpc_channelz", + srcs = ["channelz.py",], + deps = [ + ":py_channelz_proto", + "//src/python/grpcio/grpc:grpcio", + ], + imports=["../../",], +) diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/__init__.py b/src/python/grpcio_channelz/grpc_channelz/v1/__init__.py new file mode 100644 index 00000000000..38fdfc9c5cf --- /dev/null +++ b/src/python/grpcio_channelz/grpc_channelz/v1/__init__.py @@ -0,0 +1,13 @@ +# 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. diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py new file mode 100644 index 00000000000..bc08562b7b6 --- /dev/null +++ b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py @@ -0,0 +1,114 @@ +# 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. +"""Channelz debug service implementation in gRPC Python.""" + +import grpc +from grpc._cython import cygrpc + +import grpc_channelz.v1.channelz_pb2 as _channelz_pb2 +import grpc_channelz.v1.channelz_pb2_grpc as _channelz_pb2_grpc + +from google.protobuf import json_format + + +class ChannelzServicer(_channelz_pb2_grpc.ChannelzServicer): + """Servicer handling RPCs for service statuses.""" + + # pylint: disable=no-self-use + def GetTopChannels(self, request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_top_channels(request.start_channel_id), + _channelz_pb2.GetTopChannelsResponse(), + ) + except ValueError as e: + context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_details(str(e)) + + # pylint: disable=no-self-use + def GetServers(self, request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_servers(request.start_server_id), + _channelz_pb2.GetServersResponse(), + ) + except ValueError as e: + context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_details(str(e)) + + # pylint: disable=no-self-use + def GetServer(self, request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_server(request.server_id), + _channelz_pb2.GetServerResponse(), + ) + except ValueError as e: + context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_details(str(e)) + + # pylint: disable=no-self-use + def GetServerSockets(self, request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_server_sockets(request.server_id, + request.start_socket_id), + _channelz_pb2.GetServerSocketsResponse(), + ) + except ValueError as e: + context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_details(str(e)) + + # pylint: disable=no-self-use + def GetChannel(self, request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_channel(request.channel_id), + _channelz_pb2.GetChannelResponse(), + ) + except ValueError as e: + context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_details(str(e)) + + # pylint: disable=no-self-use + def GetSubchannel(self, request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_subchannel(request.subchannel_id), + _channelz_pb2.GetSubchannelResponse(), + ) + except ValueError as e: + context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_details(str(e)) + + # pylint: disable=no-self-use + def GetSocket(self, request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_socket(request.socket_id), + _channelz_pb2.GetSocketResponse(), + ) + except ValueError as e: + context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_details(str(e)) + + +def enable_channelz(server): + """Enables Channelz on a server. + + Args: + server: grpc.Server to which Channelz service will be added. + """ + _channelz_pb2_grpc.add_ChannelzServicer_to_server(ChannelzServicer(), + server) diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py new file mode 100644 index 00000000000..16356ea4020 --- /dev/null +++ b/src/python/grpcio_channelz/grpc_version.py @@ -0,0 +1,17 @@ +# 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. + +# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! + +VERSION = '1.18.0.dev0' diff --git a/src/python/grpcio_channelz/setup.py b/src/python/grpcio_channelz/setup.py new file mode 100644 index 00000000000..a495052376d --- /dev/null +++ b/src/python/grpcio_channelz/setup.py @@ -0,0 +1,96 @@ +# 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. +"""Setup module for the GRPC Python package's Channelz.""" + +import os +import sys + +import setuptools + +# Ensure we're in the proper directory whether or not we're being used by pip. +os.chdir(os.path.dirname(os.path.abspath(__file__))) + +# Break import-style to ensure we can actually find our local modules. +import grpc_version + + +class _NoOpCommand(setuptools.Command): + """No-op command.""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + pass + + +CLASSIFIERS = [ + 'Development Status :: 5 - Production/Stable', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'License :: OSI Approved :: Apache Software License', +] + +PACKAGE_DIRECTORIES = { + '': '.', +} + +INSTALL_REQUIRES = ( + 'protobuf>=3.6.0', + 'grpcio>={version}'.format(version=grpc_version.VERSION), +) + +try: + import channelz_commands as _channelz_commands + # we are in the build environment, otherwise the above import fails + SETUP_REQUIRES = ( + 'grpcio-tools=={version}'.format(version=grpc_version.VERSION),) + COMMAND_CLASS = { + # Run preprocess from the repository *before* doing any packaging! + 'preprocess': _channelz_commands.CopyProtoModules, + 'build_package_protos': _channelz_commands.BuildPackageProtos, + } +except ImportError: + SETUP_REQUIRES = () + COMMAND_CLASS = { + # wire up commands to no-op not to break the external dependencies + 'preprocess': _NoOpCommand, + 'build_package_protos': _NoOpCommand, + } + +setuptools.setup( + name='grpcio-channelz', + version=grpc_version.VERSION, + license='Apache License 2.0', + description='Channel Level Live Debug Information Service for gRPC', + author='The gRPC Authors', + author_email='grpc-io@googlegroups.com', + classifiers=CLASSIFIERS, + url='https://grpc.io', + package_dir=PACKAGE_DIRECTORIES, + packages=setuptools.find_packages('.'), + install_requires=INSTALL_REQUIRES, + setup_requires=SETUP_REQUIRES, + cmdclass=COMMAND_CLASS) diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py index 61c98fa038b..f56425ac6d3 100644 --- a/src/python/grpcio_tests/setup.py +++ b/src/python/grpcio_tests/setup.py @@ -39,6 +39,7 @@ PACKAGE_DIRECTORIES = { INSTALL_REQUIRES = ( 'coverage>=4.0', 'enum34>=1.0.4', 'grpcio>={version}'.format(version=grpc_version.VERSION), + 'grpcio-channelz>={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', diff --git a/src/python/grpcio_tests/tests/channelz/BUILD.bazel b/src/python/grpcio_tests/tests/channelz/BUILD.bazel new file mode 100644 index 00000000000..63513616e77 --- /dev/null +++ b/src/python/grpcio_tests/tests/channelz/BUILD.bazel @@ -0,0 +1,15 @@ +package(default_visibility = ["//visibility:public"]) + +py_test( + name = "channelz_servicer_test", + srcs = ["_channelz_servicer_test.py"], + main = "_channelz_servicer_test.py", + size = "small", + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz", + "//src/python/grpcio_tests/tests/unit:test_common", + "//src/python/grpcio_tests/tests/unit/framework/common:common", + ], + imports = ["../../",], +) diff --git a/src/python/grpcio_tests/tests/channelz/__init__.py b/src/python/grpcio_tests/tests/channelz/__init__.py new file mode 100644 index 00000000000..38fdfc9c5cf --- /dev/null +++ b/src/python/grpcio_tests/tests/channelz/__init__.py @@ -0,0 +1,13 @@ +# 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. diff --git a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py new file mode 100644 index 00000000000..103609441e7 --- /dev/null +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -0,0 +1,476 @@ +# 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. +"""Tests of grpc_channelz.v1.channelz.""" + +import unittest + +from concurrent import futures + +import grpc +from grpc_channelz.v1 import channelz +from grpc_channelz.v1 import channelz_pb2 +from grpc_channelz.v1 import channelz_pb2_grpc + +from tests.unit import test_common +from tests.unit.framework.common import test_constants + +_SUCCESSFUL_UNARY_UNARY = '/test/SuccessfulUnaryUnary' +_FAILED_UNARY_UNARY = '/test/FailedUnaryUnary' +_SUCCESSFUL_STREAM_STREAM = '/test/SuccessfulStreamStream' + +_REQUEST = b'\x00\x00\x00' +_RESPONSE = b'\x01\x01\x01' + +_DISABLE_REUSE_PORT = (('grpc.so_reuseport', 0),) +_ENABLE_CHANNELZ = (('grpc.enable_channelz', 1),) +_DISABLE_CHANNELZ = (('grpc.enable_channelz', 0),) + + +def _successful_unary_unary(request, servicer_context): + return _RESPONSE + + +def _failed_unary_unary(request, servicer_context): + servicer_context.set_code(grpc.StatusCode.INTERNAL) + servicer_context.set_details("Channelz Test Intended Failure") + + +def _successful_stream_stream(request_iterator, servicer_context): + for _ in request_iterator: + yield _RESPONSE + + +class _GenericHandler(grpc.GenericRpcHandler): + + def service(self, handler_call_details): + if handler_call_details.method == _SUCCESSFUL_UNARY_UNARY: + return grpc.unary_unary_rpc_method_handler(_successful_unary_unary) + elif handler_call_details.method == _FAILED_UNARY_UNARY: + return grpc.unary_unary_rpc_method_handler(_failed_unary_unary) + elif handler_call_details.method == _SUCCESSFUL_STREAM_STREAM: + return grpc.stream_stream_rpc_method_handler( + _successful_stream_stream) + else: + return None + + +class _ChannelServerPair(object): + + def __init__(self): + # Server will enable channelz service + # Bind as attribute to make it gc properly + self._server = grpc.server( + futures.ThreadPoolExecutor(max_workers=3), + options=_DISABLE_REUSE_PORT + _ENABLE_CHANNELZ) + port = self._server.add_insecure_port('[::]:0') + self._server.add_generic_rpc_handlers((_GenericHandler(),)) + self._server.start() + + # Channel will enable channelz service... + self.channel = grpc.insecure_channel('localhost:%d' % port, + _ENABLE_CHANNELZ) + + def __del__(self): + self._server.__del__() + self.channel.close() + + +def _generate_channel_server_pairs(n): + return [_ChannelServerPair() for i in range(n)] + + +def _clean_channel_server_pairs(pairs): + for pair in pairs: + pair.__del__() + + +class ChannelzServicerTest(unittest.TestCase): + + def _send_successful_unary_unary(self, idx): + _, r = self._pairs[idx].channel.unary_unary( + _SUCCESSFUL_UNARY_UNARY).with_call(_REQUEST) + self.assertEqual(r.code(), grpc.StatusCode.OK) + + def _send_failed_unary_unary(self, idx): + try: + self._pairs[idx].channel.unary_unary(_FAILED_UNARY_UNARY).with_call( + _REQUEST) + except grpc.RpcError: + return + else: + self.fail("This call supposed to fail") + + def _send_successful_stream_stream(self, idx): + response_iterator = self._pairs[idx].channel.stream_stream( + _SUCCESSFUL_STREAM_STREAM).__call__( + iter([_REQUEST] * test_constants.STREAM_LENGTH)) + cnt = 0 + for _ in response_iterator: + cnt += 1 + self.assertEqual(cnt, test_constants.STREAM_LENGTH) + + def _get_channel_id(self, idx): + """Channel id may not be consecutive""" + resp = self._channelz_stub.GetTopChannels( + channelz_pb2.GetTopChannelsRequest(start_channel_id=0)) + self.assertGreater(len(resp.channel), idx) + return resp.channel[idx].ref.channel_id + + def setUp(self): + # This server is for Channelz info fetching only + # It self should not enable Channelz + self._server = grpc.server( + futures.ThreadPoolExecutor(max_workers=3), + options=_DISABLE_REUSE_PORT + _DISABLE_CHANNELZ) + port = self._server.add_insecure_port('[::]:0') + channelz_pb2_grpc.add_ChannelzServicer_to_server( + channelz.ChannelzServicer(), + self._server, + ) + self._server.start() + + # This channel is used to fetch Channelz info only + # Channelz should not be enabled + self._channel = grpc.insecure_channel('localhost:%d' % port, + _DISABLE_CHANNELZ) + self._channelz_stub = channelz_pb2_grpc.ChannelzStub(self._channel) + + def tearDown(self): + self._server.__del__() + self._channel.close() + # _pairs may not exist, if the test crashed during setup + if hasattr(self, '_pairs'): + _clean_channel_server_pairs(self._pairs) + + def test_get_top_channels_basic(self): + self._pairs = _generate_channel_server_pairs(1) + resp = self._channelz_stub.GetTopChannels( + channelz_pb2.GetTopChannelsRequest(start_channel_id=0)) + self.assertEqual(len(resp.channel), 1) + self.assertEqual(resp.end, True) + + def test_get_top_channels_high_start_id(self): + self._pairs = _generate_channel_server_pairs(1) + resp = self._channelz_stub.GetTopChannels( + channelz_pb2.GetTopChannelsRequest(start_channel_id=10000)) + self.assertEqual(len(resp.channel), 0) + self.assertEqual(resp.end, True) + + def test_successful_request(self): + self._pairs = _generate_channel_server_pairs(1) + self._send_successful_unary_unary(0) + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0))) + self.assertEqual(resp.channel.data.calls_started, 1) + self.assertEqual(resp.channel.data.calls_succeeded, 1) + self.assertEqual(resp.channel.data.calls_failed, 0) + + def test_failed_request(self): + self._pairs = _generate_channel_server_pairs(1) + self._send_failed_unary_unary(0) + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0))) + self.assertEqual(resp.channel.data.calls_started, 1) + self.assertEqual(resp.channel.data.calls_succeeded, 0) + self.assertEqual(resp.channel.data.calls_failed, 1) + + def test_many_requests(self): + self._pairs = _generate_channel_server_pairs(1) + k_success = 7 + k_failed = 9 + for i in range(k_success): + self._send_successful_unary_unary(0) + for i in range(k_failed): + self._send_failed_unary_unary(0) + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0))) + self.assertEqual(resp.channel.data.calls_started, k_success + k_failed) + self.assertEqual(resp.channel.data.calls_succeeded, k_success) + self.assertEqual(resp.channel.data.calls_failed, k_failed) + + def test_many_channel(self): + k_channels = 4 + self._pairs = _generate_channel_server_pairs(k_channels) + resp = self._channelz_stub.GetTopChannels( + channelz_pb2.GetTopChannelsRequest(start_channel_id=0)) + self.assertEqual(len(resp.channel), k_channels) + + def test_many_requests_many_channel(self): + k_channels = 4 + self._pairs = _generate_channel_server_pairs(k_channels) + k_success = 11 + k_failed = 13 + for i in range(k_success): + self._send_successful_unary_unary(0) + self._send_successful_unary_unary(2) + for i in range(k_failed): + self._send_failed_unary_unary(1) + self._send_failed_unary_unary(2) + + # The first channel saw only successes + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0))) + self.assertEqual(resp.channel.data.calls_started, k_success) + self.assertEqual(resp.channel.data.calls_succeeded, k_success) + self.assertEqual(resp.channel.data.calls_failed, 0) + + # The second channel saw only failures + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(1))) + self.assertEqual(resp.channel.data.calls_started, k_failed) + self.assertEqual(resp.channel.data.calls_succeeded, 0) + self.assertEqual(resp.channel.data.calls_failed, k_failed) + + # The third channel saw both successes and failures + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(2))) + self.assertEqual(resp.channel.data.calls_started, k_success + k_failed) + self.assertEqual(resp.channel.data.calls_succeeded, k_success) + self.assertEqual(resp.channel.data.calls_failed, k_failed) + + # The fourth channel saw nothing + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(3))) + self.assertEqual(resp.channel.data.calls_started, 0) + self.assertEqual(resp.channel.data.calls_succeeded, 0) + self.assertEqual(resp.channel.data.calls_failed, 0) + + def test_many_subchannels(self): + k_channels = 4 + self._pairs = _generate_channel_server_pairs(k_channels) + k_success = 17 + k_failed = 19 + for i in range(k_success): + self._send_successful_unary_unary(0) + self._send_successful_unary_unary(2) + for i in range(k_failed): + self._send_failed_unary_unary(1) + self._send_failed_unary_unary(2) + + gtc_resp = self._channelz_stub.GetTopChannels( + channelz_pb2.GetTopChannelsRequest(start_channel_id=0)) + self.assertEqual(len(gtc_resp.channel), k_channels) + for i in range(k_channels): + # If no call performed in the channel, there shouldn't be any subchannel + if gtc_resp.channel[i].data.calls_started == 0: + self.assertEqual(len(gtc_resp.channel[i].subchannel_ref), 0) + continue + + # Otherwise, the subchannel should exist + self.assertGreater(len(gtc_resp.channel[i].subchannel_ref), 0) + gsc_resp = self._channelz_stub.GetSubchannel( + channelz_pb2.GetSubchannelRequest( + subchannel_id=gtc_resp.channel[i].subchannel_ref[ + 0].subchannel_id)) + self.assertEqual(gtc_resp.channel[i].data.calls_started, + gsc_resp.subchannel.data.calls_started) + self.assertEqual(gtc_resp.channel[i].data.calls_succeeded, + gsc_resp.subchannel.data.calls_succeeded) + self.assertEqual(gtc_resp.channel[i].data.calls_failed, + gsc_resp.subchannel.data.calls_failed) + + def test_server_basic(self): + self._pairs = _generate_channel_server_pairs(1) + resp = self._channelz_stub.GetServers( + channelz_pb2.GetServersRequest(start_server_id=0)) + self.assertEqual(len(resp.server), 1) + + def test_get_one_server(self): + self._pairs = _generate_channel_server_pairs(1) + gss_resp = self._channelz_stub.GetServers( + channelz_pb2.GetServersRequest(start_server_id=0)) + self.assertEqual(len(gss_resp.server), 1) + gs_resp = self._channelz_stub.GetServer( + channelz_pb2.GetServerRequest( + server_id=gss_resp.server[0].ref.server_id)) + self.assertEqual(gss_resp.server[0].ref.server_id, + gs_resp.server.ref.server_id) + + def test_server_call(self): + self._pairs = _generate_channel_server_pairs(1) + k_success = 23 + k_failed = 29 + for i in range(k_success): + self._send_successful_unary_unary(0) + for i in range(k_failed): + self._send_failed_unary_unary(0) + + resp = self._channelz_stub.GetServers( + channelz_pb2.GetServersRequest(start_server_id=0)) + self.assertEqual(len(resp.server), 1) + self.assertEqual(resp.server[0].data.calls_started, + k_success + k_failed) + self.assertEqual(resp.server[0].data.calls_succeeded, k_success) + self.assertEqual(resp.server[0].data.calls_failed, k_failed) + + def test_many_subchannels_and_sockets(self): + k_channels = 4 + self._pairs = _generate_channel_server_pairs(k_channels) + k_success = 3 + k_failed = 5 + for i in range(k_success): + self._send_successful_unary_unary(0) + self._send_successful_unary_unary(2) + for i in range(k_failed): + self._send_failed_unary_unary(1) + self._send_failed_unary_unary(2) + + gtc_resp = self._channelz_stub.GetTopChannels( + channelz_pb2.GetTopChannelsRequest(start_channel_id=0)) + self.assertEqual(len(gtc_resp.channel), k_channels) + for i in range(k_channels): + # If no call performed in the channel, there shouldn't be any subchannel + if gtc_resp.channel[i].data.calls_started == 0: + self.assertEqual(len(gtc_resp.channel[i].subchannel_ref), 0) + continue + + # Otherwise, the subchannel should exist + self.assertGreater(len(gtc_resp.channel[i].subchannel_ref), 0) + gsc_resp = self._channelz_stub.GetSubchannel( + channelz_pb2.GetSubchannelRequest( + subchannel_id=gtc_resp.channel[i].subchannel_ref[ + 0].subchannel_id)) + self.assertEqual(len(gsc_resp.subchannel.socket_ref), 1) + + gs_resp = self._channelz_stub.GetSocket( + channelz_pb2.GetSocketRequest( + socket_id=gsc_resp.subchannel.socket_ref[0].socket_id)) + self.assertEqual(gsc_resp.subchannel.data.calls_started, + gs_resp.socket.data.streams_started) + self.assertEqual(gsc_resp.subchannel.data.calls_started, + gs_resp.socket.data.streams_succeeded) + # Calls started == messages sent, only valid for unary calls + self.assertEqual(gsc_resp.subchannel.data.calls_started, + gs_resp.socket.data.messages_sent) + # Only receive responses when the RPC was successful + self.assertEqual(gsc_resp.subchannel.data.calls_succeeded, + gs_resp.socket.data.messages_received) + + def test_streaming_rpc(self): + self._pairs = _generate_channel_server_pairs(1) + # In C++, the argument for _send_successful_stream_stream is message length. + # Here the argument is still channel idx, to be consistent with the other two. + self._send_successful_stream_stream(0) + + gc_resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0))) + self.assertEqual(gc_resp.channel.data.calls_started, 1) + self.assertEqual(gc_resp.channel.data.calls_succeeded, 1) + self.assertEqual(gc_resp.channel.data.calls_failed, 0) + # Subchannel exists + self.assertGreater(len(gc_resp.channel.subchannel_ref), 0) + + gsc_resp = self._channelz_stub.GetSubchannel( + channelz_pb2.GetSubchannelRequest( + subchannel_id=gc_resp.channel.subchannel_ref[0].subchannel_id)) + self.assertEqual(gsc_resp.subchannel.data.calls_started, 1) + self.assertEqual(gsc_resp.subchannel.data.calls_succeeded, 1) + self.assertEqual(gsc_resp.subchannel.data.calls_failed, 0) + # Socket exists + self.assertEqual(len(gsc_resp.subchannel.socket_ref), 1) + + gs_resp = self._channelz_stub.GetSocket( + channelz_pb2.GetSocketRequest( + socket_id=gsc_resp.subchannel.socket_ref[0].socket_id)) + self.assertEqual(gs_resp.socket.data.streams_started, 1) + self.assertEqual(gs_resp.socket.data.streams_succeeded, 1) + self.assertEqual(gs_resp.socket.data.streams_failed, 0) + self.assertEqual(gs_resp.socket.data.messages_sent, + test_constants.STREAM_LENGTH) + self.assertEqual(gs_resp.socket.data.messages_received, + test_constants.STREAM_LENGTH) + + def test_server_sockets(self): + self._pairs = _generate_channel_server_pairs(1) + self._send_successful_unary_unary(0) + self._send_failed_unary_unary(0) + + gs_resp = self._channelz_stub.GetServers( + channelz_pb2.GetServersRequest(start_server_id=0)) + self.assertEqual(len(gs_resp.server), 1) + self.assertEqual(gs_resp.server[0].data.calls_started, 2) + self.assertEqual(gs_resp.server[0].data.calls_succeeded, 1) + self.assertEqual(gs_resp.server[0].data.calls_failed, 1) + + gss_resp = self._channelz_stub.GetServerSockets( + channelz_pb2.GetServerSocketsRequest( + server_id=gs_resp.server[0].ref.server_id, start_socket_id=0)) + # If the RPC call failed, it will raise a grpc.RpcError + # So, if there is no exception raised, considered pass + + def test_server_listen_sockets(self): + self._pairs = _generate_channel_server_pairs(1) + + gss_resp = self._channelz_stub.GetServers( + channelz_pb2.GetServersRequest(start_server_id=0)) + self.assertEqual(len(gss_resp.server), 1) + self.assertEqual(len(gss_resp.server[0].listen_socket), 1) + + gs_resp = self._channelz_stub.GetSocket( + channelz_pb2.GetSocketRequest( + socket_id=gss_resp.server[0].listen_socket[0].socket_id)) + # If the RPC call failed, it will raise a grpc.RpcError + # So, if there is no exception raised, considered pass + + def test_invalid_query_get_server(self): + try: + self._channelz_stub.GetServer( + channelz_pb2.GetServerRequest(server_id=10000)) + except BaseException as e: + self.assertIn('StatusCode.INVALID_ARGUMENT', str(e)) + else: + self.fail('Invalid query not detected') + + def test_invalid_query_get_channel(self): + try: + self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=10000)) + except BaseException as e: + self.assertIn('StatusCode.INVALID_ARGUMENT', str(e)) + else: + self.fail('Invalid query not detected') + + def test_invalid_query_get_subchannel(self): + try: + self._channelz_stub.GetSubchannel( + channelz_pb2.GetSubchannelRequest(subchannel_id=10000)) + except BaseException as e: + self.assertIn('StatusCode.INVALID_ARGUMENT', str(e)) + else: + self.fail('Invalid query not detected') + + def test_invalid_query_get_socket(self): + try: + self._channelz_stub.GetSocket( + channelz_pb2.GetSocketRequest(socket_id=10000)) + except BaseException as e: + self.assertIn('StatusCode.INVALID_ARGUMENT', str(e)) + else: + self.fail('Invalid query not detected') + + def test_invalid_query_get_server_sockets(self): + try: + self._channelz_stub.GetServerSockets( + channelz_pb2.GetServerSocketsRequest( + server_id=10000, + start_socket_id=0, + )) + except BaseException as e: + self.assertIn('StatusCode.INVALID_ARGUMENT', str(e)) + else: + self.fail('Invalid query not detected') + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index a3006d9afc2..9cffd3df197 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -1,5 +1,6 @@ [ "_sanity._sanity_test.SanityTest", + "channelz._channelz_servicer_test.ChannelzServicerTest", "health_check._health_servicer_test.HealthServicerTest", "interop._insecure_intraop_test.InsecureIntraopTest", "interop._secure_intraop_test.SecureIntraopTest", diff --git a/templates/src/python/grpcio_channelz/grpc_version.py.template b/templates/src/python/grpcio_channelz/grpc_version.py.template new file mode 100644 index 00000000000..75d510cd17b --- /dev/null +++ b/templates/src/python/grpcio_channelz/grpc_version.py.template @@ -0,0 +1,19 @@ +%YAML 1.2 +--- | + # 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. + + # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! + + VERSION = '${settings.python_version.pep440()}' diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh index 82a818cce5a..d17eb9fdb82 100755 --- a/tools/distrib/pylint_code.sh +++ b/tools/distrib/pylint_code.sh @@ -20,6 +20,7 @@ cd "$(dirname "$0")/../.." DIRS=( 'src/python/grpcio/grpc' + 'src/python/grpcio_channelz/grpc_channelz' 'src/python/grpcio_health_checking/grpc_health' 'src/python/grpcio_reflection/grpc_reflection' 'src/python/grpcio_testing/grpc_testing' diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index 65f2d1c7659..bc6e5582046 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -108,6 +108,11 @@ then ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_testing/setup.py sdist cp -r src/python/grpcio_testing/dist/* "$ARTIFACT_DIR" + # Build grpcio_channelz source distribution + ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_channelz/setup.py \ + preprocess build_package_protos sdist + cp -r src/python/grpcio_channelz/dist/* "$ARTIFACT_DIR" + # Build grpcio_health_checking source distribution ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_health_checking/setup.py \ preprocess build_package_protos sdist diff --git a/tools/run_tests/helper_scripts/build_python.sh b/tools/run_tests/helper_scripts/build_python.sh index 8394f07e518..27acd9664bd 100755 --- a/tools/run_tests/helper_scripts/build_python.sh +++ b/tools/run_tests/helper_scripts/build_python.sh @@ -189,6 +189,11 @@ pip_install_dir "$ROOT" $VENV_PYTHON "$ROOT/tools/distrib/python/make_grpcio_tools.py" pip_install_dir "$ROOT/tools/distrib/python/grpcio_tools" +# Build/install Chaneelz +$VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" preprocess +$VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" build_package_protos +pip_install_dir "$ROOT/src/python/grpcio_channelz" + # Build/install health checking $VENV_PYTHON "$ROOT/src/python/grpcio_health_checking/setup.py" preprocess $VENV_PYTHON "$ROOT/src/python/grpcio_health_checking/setup.py" build_package_protos From fd69f74b2091ae66b609ec7592905d9b20dddf88 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 27 Nov 2018 17:48:55 -0800 Subject: [PATCH 0320/2143] use value64 --- src/objective-c/GRPCClient/private/ChannelArgsUtil.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m index 3135fcff028..c1c65c33841 100644 --- a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -78,7 +78,7 @@ grpc_channel_args *GRPCBuildChannelArgs(NSDictionary *dictionary) { int64_t value64 = [value longLongValue]; if (value64 <= INT_MAX || value64 >= INT_MIN) { arg->type = GRPC_ARG_INTEGER; - arg->value.integer = [value intValue]; + arg->value.integer = (int)value64; j++; } } else if (value != nil) { From b87984bace81d70fba1d593634ff5a1da882d26f Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 27 Nov 2018 19:19:35 -0800 Subject: [PATCH 0321/2143] Stream size needs to be rounded up to alignment --- src/core/lib/transport/transport.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index cbdb77c8441..d9b9a97b0a1 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -149,7 +149,7 @@ void grpc_transport_move_stats(grpc_transport_stream_stats* from, } size_t grpc_transport_stream_size(grpc_transport* transport) { - return transport->vtable->sizeof_stream; + return GPR_ROUND_UP_TO_ALIGNMENT_SIZE(transport->vtable->sizeof_stream); } void grpc_transport_destroy(grpc_transport* transport) { From 90cdbd69aacb54f50b980764e26373a89950a86e Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 27 Nov 2018 22:32:32 -0800 Subject: [PATCH 0322/2143] Fix PHP ZTS build breakage --- src/php/ext/grpc/php_grpc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 492325b1e8b..f7d5a85876b 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -170,12 +170,12 @@ void prefork() { acquire_persistent_locks(); } -void postfork_child() { +void postfork_child(TSRMLS_D) { // loop through persistant list and destroy all underlying grpc_channel objs destroy_grpc_channels(); // clear completion queue - grpc_php_shutdown_completion_queue(); + grpc_php_shutdown_completion_queue(TSRMLS_C); // clean-up grpc_core grpc_shutdown(); @@ -187,7 +187,7 @@ void postfork_child() { // restart grpc_core grpc_init(); - grpc_php_init_completion_queue(); + grpc_php_init_completion_queue(TSRMLS_C); // re-create grpc_channel and point wrapped to it // unlock wrapped grpc channel mutex From f2973917f4a55b3456b506f3bea856fbe38442f2 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 27 Nov 2018 22:36:28 -0800 Subject: [PATCH 0323/2143] Fix PHP ZTS build breakage --- src/php/ext/grpc/php_grpc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 492325b1e8b..f7d5a85876b 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -170,12 +170,12 @@ void prefork() { acquire_persistent_locks(); } -void postfork_child() { +void postfork_child(TSRMLS_D) { // loop through persistant list and destroy all underlying grpc_channel objs destroy_grpc_channels(); // clear completion queue - grpc_php_shutdown_completion_queue(); + grpc_php_shutdown_completion_queue(TSRMLS_C); // clean-up grpc_core grpc_shutdown(); @@ -187,7 +187,7 @@ void postfork_child() { // restart grpc_core grpc_init(); - grpc_php_init_completion_queue(); + grpc_php_init_completion_queue(TSRMLS_C); // re-create grpc_channel and point wrapped to it // unlock wrapped grpc channel mutex From 8199aff7a66460fbc4e9a82ade2e95ef076fd8f9 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Wed, 28 Nov 2018 00:49:36 -0800 Subject: [PATCH 0324/2143] Fix Python blocking interceptors facing RpcError RpcError should be returned from the continuation intact, not raised. --- AUTHORS | 1 + src/python/grpcio/grpc/_interceptor.py | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index 3e130afda2d..0e8797391f2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,2 +1,3 @@ +Dropbox, Inc. Google Inc. WeWork Companies Inc. diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py index 43451140265..2a8ddd8ce42 100644 --- a/src/python/grpcio/grpc/_interceptor.py +++ b/src/python/grpcio/grpc/_interceptor.py @@ -232,8 +232,8 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): credentials=new_credentials, wait_for_ready=new_wait_for_ready) return _UnaryOutcome(response, call) - except grpc.RpcError: - raise + except grpc.RpcError as rpc_error: + return rpc_error except Exception as exception: # pylint:disable=broad-except return _FailureOutcome(exception, sys.exc_info()[2]) @@ -354,8 +354,8 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): credentials=new_credentials, wait_for_ready=new_wait_for_ready) return _UnaryOutcome(response, call) - except grpc.RpcError: - raise + except grpc.RpcError as rpc_error: + return rpc_error except Exception as exception: # pylint:disable=broad-except return _FailureOutcome(exception, sys.exc_info()[2]) From bd3bb8e289e0111a3d4e8282c65d977fe447f6b0 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 28 Nov 2018 09:22:27 -0800 Subject: [PATCH 0325/2143] 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 019feec3d9308717adcda8ee6b01b364ee2d29dd Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 28 Nov 2018 09:23:53 -0800 Subject: [PATCH 0326/2143] Bump to v1.17.0-pre3 --- BUILD | 4 ++-- build.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BUILD b/BUILD index 270c56ff6ed..989bc02a0b8 100644 --- a/BUILD +++ b/BUILD @@ -66,9 +66,9 @@ config_setting( # This should be updated along with build.yaml g_stands_for = "gizmo" -core_version = "7.0.0-pre2" +core_version = "7.0.0-pre3" -version = "1.17.0-pre2" +version = "1.17.0-pre3" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 0a74fd29ffd..b8b002ac149 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-pre2 + core_version: 7.0.0-pre3 g_stands_for: gizmo - version: 1.17.0-pre2 + version: 1.17.0-pre3 filegroups: - name: alts_proto headers: From 698cf221d85f5ad0743487d4577af15d646d7483 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 28 Nov 2018 09:24:31 -0800 Subject: [PATCH 0327/2143] 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_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/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 +- 31 files changed, 37 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 17f5f4ca637..87f0846fd1e 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.17.0-pre2") +set(PACKAGE_VERSION "1.17.0-pre3") 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 3ac25a788dd..1e32de5e6b2 100644 --- a/Makefile +++ b/Makefile @@ -437,9 +437,9 @@ E = @echo Q = @ endif -CORE_VERSION = 7.0.0-pre2 -CPP_VERSION = 1.17.0-pre2 -CSHARP_VERSION = 1.17.0-pre2 +CORE_VERSION = 7.0.0-pre3 +CPP_VERSION = 1.17.0-pre3 +CSHARP_VERSION = 1.17.0-pre3 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 8bacc33966b..35c446ede37 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.17.0-pre2' - version = '0.0.6-pre2' + # version = '1.17.0-pre3' + version = '0.0.6-pre3' 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.17.0-pre2' + grpc_version = '1.17.0-pre3' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 65e0528e572..674ea75243e 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.17.0-pre2' + version = '1.17.0-pre3' 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 719da004785..5f01dbaeef1 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.17.0-pre2' + version = '1.17.0-pre3' 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 56b95d1642a..6289a14205b 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.17.0-pre2' + version = '1.17.0-pre3' 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 9b856456151..42d6819e30c 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.17.0-pre2' + version = '1.17.0-pre3' 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 433fdad8409..aad44ab1398 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.17.0RC2 - 1.17.0RC2 + 1.17.0RC3 + 1.17.0RC3 beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 625c1bd59a2..6fdd2a960a6 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-pre2"; } +const char* grpc_version_string(void) { return "7.0.0-pre3"; } const char* grpc_g_stands_for(void) { return "gizmo"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 33643848fa0..97d7670396a 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.17.0-pre2"; } +grpc::string Version() { return "1.17.0-pre3"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index ade0cfdeecc..183651bfe00 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.17.0-pre2 + 1.17.0-pre3 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 3a060caeb2f..5c28018e433 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.17.0-pre2"; + public const string CurrentVersion = "1.17.0-pre3"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index af3354fa664..4ade233f767 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.17.0-pre2 +set VERSION=1.17.0-pre3 @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 71e3a7302a6..e4b91a626ff 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.17.0-pre2 +set VERSION=1.17.0-pre3 @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 ae5a976ecc6..db1dc596696 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.17.0-pre2' + v = '1.17.0-pre3' 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 2e4f01f9a4e..32e3be3a8a5 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.17.0-pre2" +#define GRPC_OBJC_VERSION_STRING @"1.17.0-pre3" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index cfe1ff98e55..278348c2093 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.17.0-pre2" -#define GRPC_C_VERSION_STRING @"7.0.0-pre2" +#define GRPC_OBJC_VERSION_STRING @"1.17.0-pre3" +#define GRPC_C_VERSION_STRING @"7.0.0-pre3" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 5b6d808c728..e1d36bfc3fc 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.17.0RC2" +#define PHP_GRPC_VERSION "1.17.0RC3" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index cf0f72fe63a..a1e58cc3ed8 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.17.0rc2""" +__version__ = """1.17.0rc3""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index dd0817c1444..2182471388f 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.17.0rc2' +VERSION = '1.17.0rc3' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 1c6f6aa7c23..147e8840a61 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.17.0rc2' +VERSION = '1.17.0rc3' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index cd97840cb4b..ac41352b34b 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.17.0rc2' +VERSION = '1.17.0rc3' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index d019ce75ad3..0083836a337 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.17.0rc2' +VERSION = '1.17.0rc3' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index cc59a197375..e4e5d85764d 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.17.0rc2' +VERSION = '1.17.0rc3' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index d1fa0b60fa2..23906096225 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.17.0.pre2' + VERSION = '1.17.0.pre3' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index f30e5074840..af6255d822a 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.17.0.pre2' + VERSION = '1.17.0.pre3' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 9cad73cb39e..a65fcd36da5 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.17.0rc2' +VERSION = '1.17.0rc3' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index eb41083bc56..766c5aeb77d 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.17.0-pre2 +PROJECT_NUMBER = 1.17.0-pre3 # 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 b888c408307..7968d182c8d 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.17.0-pre2 +PROJECT_NUMBER = 1.17.0-pre3 # 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 29a4ba79b16..85f6bfce56a 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-pre2 +PROJECT_NUMBER = 7.0.0-pre3 # 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 acaf04a7c6c..1ebb0ee8c4d 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-pre2 +PROJECT_NUMBER = 7.0.0-pre3 # 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 f614fa5947e2b1c123e94f67b51acaefb9d1915c Mon Sep 17 00:00:00 2001 From: Vishal Powar Date: Tue, 27 Nov 2018 22:39:00 -0800 Subject: [PATCH 0328/2143] Adding upb as submodule upb will be used for codegen of xDS protos. --- .gitmodules | 3 +++ bazel/grpc_deps.bzl | 12 ++++++++++++ third_party/upb | 1 + tools/run_tests/sanity/check_bazel_workspace.py | 1 + tools/run_tests/sanity/check_submodules.sh | 1 + 5 files changed, 18 insertions(+) create mode 160000 third_party/upb diff --git a/.gitmodules b/.gitmodules index bb4b749beee..06f1394df65 100644 --- a/.gitmodules +++ b/.gitmodules @@ -51,3 +51,6 @@ [submodule "third_party/protoc-gen-validate"] path = third_party/protoc-gen-validate url = https://github.com/lyft/protoc-gen-validate.git +[submodule "third_party/upb"] + path = third_party/upb + url = https://github.com/google/upb.git diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 86268178554..e091e5abc06 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -8,6 +8,11 @@ def grpc_deps(): actual = "@com_github_nanopb_nanopb//:nanopb", ) + native.bind( + name = "upblib", + actual = "@upb//:upb", + ) + native.bind( name = "absl-base", actual = "@com_google_absl//absl/base", @@ -184,6 +189,13 @@ def grpc_deps(): url = "https://github.com/census-instrumentation/opencensus-cpp/archive/fdf0f308b1631bb4a942e32ba5d22536a6170274.tar.gz", ) + if "upb" not in native.existing_rules(): + native.http_archive( + name = "upb", + strip_prefix = "upb-9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3", + url = "https://github.com/google/upb/archive/9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3.tar.gz", + ) + # TODO: move some dependencies from "grpc_deps" here? def grpc_test_only_deps(): diff --git a/third_party/upb b/third_party/upb new file mode 160000 index 00000000000..9ce4a77f61c --- /dev/null +++ b/third_party/upb @@ -0,0 +1 @@ +Subproject commit 9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3 diff --git a/tools/run_tests/sanity/check_bazel_workspace.py b/tools/run_tests/sanity/check_bazel_workspace.py index d562fffc8a9..35da88d70e6 100755 --- a/tools/run_tests/sanity/check_bazel_workspace.py +++ b/tools/run_tests/sanity/check_bazel_workspace.py @@ -42,6 +42,7 @@ _ZOPEFOUNDATION_ZOPE_INTERFACE_DEP_NAME = 'com_github_zopefoundation_zope_interf _TWISTED_CONSTANTLY_DEP_NAME = 'com_github_twisted_constantly' _GRPC_DEP_NAMES = [ + 'upb', 'boringssl', 'com_github_madler_zlib', 'com_google_protobuf', diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index fa2628f18ea..f1103596d51 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -40,6 +40,7 @@ cat << EOF | awk '{ print $1 }' | sort > "$want_submodules" 9245d481eb3e890f708ff2d7dadf2a10c04748ba third_party/libcxxabi (heads/release_60) 48cb18e5c419ddd23d9badcfe4e9df7bde1979b2 third_party/protobuf (v3.6.0.1-37-g48cb18e5) e143189bf6f37b3957fb31743df6a1bcf4a8c685 third_party/protoc-gen-validate (v0.0.10) + 9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3 third_party/upb (heads/upbc-cpp) cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11) EOF From 53476eced45e9a8a4dd57b9519f42328d763f907 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 28 Nov 2018 10:30:39 -0800 Subject: [PATCH 0329/2143] Adopt reviewer's suggestions * Correct the StatusCode * Format code * Use @staticmethod * Fix typo --- .../grpc/_cython/_cygrpc/channelz.pyx.pxi | 31 +++++++--- .../grpc_channelz/v1/channelz.py | 61 ++++++++++++------- .../tests/channelz/_channelz_servicer_test.py | 10 +-- .../run_tests/helper_scripts/build_python.sh | 2 +- 4 files changed, 66 insertions(+), 38 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi index 572a473d3e8..113f7976dd9 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi @@ -14,43 +14,56 @@ def channelz_get_top_channels(start_channel_id): - cdef char *c_returned_str = grpc_channelz_get_top_channels(start_channel_id) + cdef char *c_returned_str = grpc_channelz_get_top_channels( + start_channel_id, + ) if c_returned_str == NULL: - raise ValueError('Failed to get top channels, please ensure your start_channel_id==%s is valid' % start_channel_id) + raise ValueError('Failed to get top channels, please ensure your' \ + ' start_channel_id==%s is valid' % start_channel_id) return c_returned_str def channelz_get_servers(start_server_id): cdef char *c_returned_str = grpc_channelz_get_servers(start_server_id) if c_returned_str == NULL: - raise ValueError('Failed to get servers, please ensure your start_server_id==%s is valid' % start_server_id) + raise ValueError('Failed to get servers, please ensure your' \ + ' start_server_id==%s is valid' % start_server_id) return c_returned_str def channelz_get_server(server_id): cdef char *c_returned_str = grpc_channelz_get_server(server_id) if c_returned_str == NULL: - raise ValueError('Failed to get the server, please ensure your server_id==%s is valid' % server_id) + raise ValueError('Failed to get the server, please ensure your' \ + ' server_id==%s is valid' % server_id) return c_returned_str def channelz_get_server_sockets(server_id, start_socket_id): - cdef char *c_returned_str = grpc_channelz_get_server_sockets(server_id, start_socket_id) + cdef char *c_returned_str = grpc_channelz_get_server_sockets( + server_id, + start_socket_id, + ) if c_returned_str == NULL: - raise ValueError('Failed to get server sockets, please ensure your server_id==%s and start_socket_id==%s is valid' % (server_id, start_socket_id)) + raise ValueError('Failed to get server sockets, please ensure your' \ + ' server_id==%s and start_socket_id==%s is valid' % + (server_id, start_socket_id)) return c_returned_str def channelz_get_channel(channel_id): cdef char *c_returned_str = grpc_channelz_get_channel(channel_id) if c_returned_str == NULL: - raise ValueError('Failed to get the channel, please ensure your channel_id==%s is valid' % (channel_id)) + raise ValueError('Failed to get the channel, please ensure your' \ + ' channel_id==%s is valid' % (channel_id)) return c_returned_str def channelz_get_subchannel(subchannel_id): cdef char *c_returned_str = grpc_channelz_get_subchannel(subchannel_id) if c_returned_str == NULL: - raise ValueError('Failed to get the subchannel, please ensure your subchannel_id==%s is valid' % (subchannel_id)) + raise ValueError('Failed to get the subchannel, please ensure your' \ + ' subchannel_id==%s is valid' % (subchannel_id)) return c_returned_str def channelz_get_socket(socket_id): cdef char *c_returned_str = grpc_channelz_get_socket(socket_id) if c_returned_str == NULL: - raise ValueError('Failed to get the socket, please ensure your socket_id==%s is valid' % (socket_id)) + raise ValueError('Failed to get the socket, please ensure your' \ + ' socket_id==%s is valid' % (socket_id)) return c_returned_str diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py index bc08562b7b6..1ae5e8c140d 100644 --- a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py +++ b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py @@ -25,41 +25,44 @@ from google.protobuf import json_format class ChannelzServicer(_channelz_pb2_grpc.ChannelzServicer): """Servicer handling RPCs for service statuses.""" - # pylint: disable=no-self-use - def GetTopChannels(self, request, context): + @staticmethod + def GetTopChannels(request, context): try: return json_format.Parse( cygrpc.channelz_get_top_channels(request.start_channel_id), _channelz_pb2.GetTopChannelsResponse(), ) - except ValueError as e: - context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + except (ValueError, json_format.ParseError) as e: + context.set_code(grpc.StatusCode.INTERNAL) context.set_details(str(e)) - # pylint: disable=no-self-use - def GetServers(self, request, context): + @staticmethod + def GetServers(request, context): try: return json_format.Parse( cygrpc.channelz_get_servers(request.start_server_id), _channelz_pb2.GetServersResponse(), ) - except ValueError as e: - context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + except (ValueError, json_format.ParseError) as e: + context.set_code(grpc.StatusCode.INTERNAL) context.set_details(str(e)) - # pylint: disable=no-self-use - def GetServer(self, request, context): + @staticmethod + def GetServer(request, context): try: return json_format.Parse( cygrpc.channelz_get_server(request.server_id), _channelz_pb2.GetServerResponse(), ) except ValueError as e: - context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_code(grpc.StatusCode.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) context.set_details(str(e)) - # pylint: disable=no-self-use - def GetServerSockets(self, request, context): + @staticmethod + def GetServerSockets(request, context): try: return json_format.Parse( cygrpc.channelz_get_server_sockets(request.server_id, @@ -67,40 +70,52 @@ class ChannelzServicer(_channelz_pb2_grpc.ChannelzServicer): _channelz_pb2.GetServerSocketsResponse(), ) except ValueError as e: - context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_code(grpc.StatusCode.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) context.set_details(str(e)) - # pylint: disable=no-self-use - def GetChannel(self, request, context): + @staticmethod + def GetChannel(request, context): try: return json_format.Parse( cygrpc.channelz_get_channel(request.channel_id), _channelz_pb2.GetChannelResponse(), ) except ValueError as e: - context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_code(grpc.StatusCode.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) context.set_details(str(e)) - # pylint: disable=no-self-use - def GetSubchannel(self, request, context): + @staticmethod + def GetSubchannel(request, context): try: return json_format.Parse( cygrpc.channelz_get_subchannel(request.subchannel_id), _channelz_pb2.GetSubchannelResponse(), ) except ValueError as e: - context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_code(grpc.StatusCode.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) context.set_details(str(e)) - # pylint: disable=no-self-use - def GetSocket(self, request, context): + @staticmethod + def GetSocket(request, context): try: return json_format.Parse( cygrpc.channelz_get_socket(request.socket_id), _channelz_pb2.GetSocketResponse(), ) except ValueError as e: - context.set_code(grpc.StatusCode.INVALID_ARGUMENT) + context.set_code(grpc.StatusCode.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) context.set_details(str(e)) 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 103609441e7..2549ed76be8 100644 --- a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -428,7 +428,7 @@ class ChannelzServicerTest(unittest.TestCase): self._channelz_stub.GetServer( channelz_pb2.GetServerRequest(server_id=10000)) except BaseException as e: - self.assertIn('StatusCode.INVALID_ARGUMENT', str(e)) + self.assertIn('StatusCode.NOT_FOUND', str(e)) else: self.fail('Invalid query not detected') @@ -437,7 +437,7 @@ class ChannelzServicerTest(unittest.TestCase): self._channelz_stub.GetChannel( channelz_pb2.GetChannelRequest(channel_id=10000)) except BaseException as e: - self.assertIn('StatusCode.INVALID_ARGUMENT', str(e)) + self.assertIn('StatusCode.NOT_FOUND', str(e)) else: self.fail('Invalid query not detected') @@ -446,7 +446,7 @@ class ChannelzServicerTest(unittest.TestCase): self._channelz_stub.GetSubchannel( channelz_pb2.GetSubchannelRequest(subchannel_id=10000)) except BaseException as e: - self.assertIn('StatusCode.INVALID_ARGUMENT', str(e)) + self.assertIn('StatusCode.NOT_FOUND', str(e)) else: self.fail('Invalid query not detected') @@ -455,7 +455,7 @@ class ChannelzServicerTest(unittest.TestCase): self._channelz_stub.GetSocket( channelz_pb2.GetSocketRequest(socket_id=10000)) except BaseException as e: - self.assertIn('StatusCode.INVALID_ARGUMENT', str(e)) + self.assertIn('StatusCode.NOT_FOUND', str(e)) else: self.fail('Invalid query not detected') @@ -467,7 +467,7 @@ class ChannelzServicerTest(unittest.TestCase): start_socket_id=0, )) except BaseException as e: - self.assertIn('StatusCode.INVALID_ARGUMENT', str(e)) + self.assertIn('StatusCode.NOT_FOUND', str(e)) else: self.fail('Invalid query not detected') diff --git a/tools/run_tests/helper_scripts/build_python.sh b/tools/run_tests/helper_scripts/build_python.sh index 27acd9664bd..e43f1fb429c 100755 --- a/tools/run_tests/helper_scripts/build_python.sh +++ b/tools/run_tests/helper_scripts/build_python.sh @@ -189,7 +189,7 @@ pip_install_dir "$ROOT" $VENV_PYTHON "$ROOT/tools/distrib/python/make_grpcio_tools.py" pip_install_dir "$ROOT/tools/distrib/python/grpcio_tools" -# Build/install Chaneelz +# Build/install Channelz $VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" preprocess $VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" build_package_protos pip_install_dir "$ROOT/src/python/grpcio_channelz" From fbd3808d0d2e00c2f070145366a96786dafdc804 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 28 Nov 2018 10:32:00 -0800 Subject: [PATCH 0330/2143] added exec_compatible_with to sh_test --- bazel/grpc_build_system.bzl | 1 + 1 file changed, 1 insertion(+) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 22c77e468fb..65fe5a10aa2 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -163,6 +163,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data "$(location %s)" % name, ] + args["args"], tags = tags, + exec_compatible_with = exec_compatible_with, ) else: native.cc_test(**args) From 527ddd99821cd0e0970fdd5b5b4988394f0ea078 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 28 Nov 2018 11:10:05 -0800 Subject: [PATCH 0331/2143] cleanup --- third_party/toolchains/BUILD | 22 ---------------------- tools/remote_build/rbe_common.bazelrc | 3 +-- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 2736543fcf9..e213461acc9 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -74,28 +74,6 @@ platform( """, ) -platform( - name = "host_platform-large", - constraint_values = [ - "//third_party/toolchains/machine_size:large", - ], - cpu_constraints = [ - "@bazel_tools//platforms:x86_32", - "@bazel_tools//platforms:x86_64", - "@bazel_tools//platforms:ppc", - "@bazel_tools//platforms:arm", - "@bazel_tools//platforms:aarch64", - "@bazel_tools//platforms:s390x", - ], - host_platform = True, - os_constraints = [ - "@bazel_tools//platforms:osx", - "@bazel_tools//platforms:freebsd", - "@bazel_tools//platforms:linux", - "@bazel_tools//platforms:windows", - ], -) - # This target is auto-generated from release/cpp.tpl and should not be # modified directly. toolchain( diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index df72f129aba..aa3ddb050cd 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -21,7 +21,7 @@ startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain build --extra_toolchains=//third_party/toolchains:cc-toolchain-clang-x86_64-default # Use custom execution platforms defined in third_party/toolchains -build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large,//third_party/toolchains:host_platform-large +build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large build --host_platform=//third_party/toolchains:rbe_ubuntu1604 build --platforms=//third_party/toolchains:rbe_ubuntu1604 @@ -37,7 +37,6 @@ build --verbose_failures=true build --experimental_strict_action_env=true build --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 -build --toolchain_resolution_debug # don't use port server build --define GRPC_PORT_ISOLATED_RUNTIME=1 From d9f656a911a6f7a5c1ffcbb38d7758b2b8e0e9dc Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 27 Nov 2018 11:08:20 -0800 Subject: [PATCH 0332/2143] fix docstring on grpc.server --- src/python/grpcio/grpc/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 88c5b6d5be5..6022fc3ef21 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -1723,7 +1723,7 @@ def server(thread_pool, handlers. The interceptors are given control in the order they are specified. This is an EXPERIMENTAL API. options: An optional list of key-value pairs (channel args in gRPC runtime) - to configure the channel. + to configure the channel. maximum_concurrent_rpcs: The maximum number of concurrent RPCs this server will service before returning RESOURCE_EXHAUSTED status, or None to indicate no limit. From a7c41346d8470e7eb5f10234daa08d09a48fa779 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 28 Nov 2018 11:22:33 -0800 Subject: [PATCH 0333/2143] Add one more cancel test --- src/objective-c/tests/InteropTests.m | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index a9f33aab6f1..2492718046f 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -655,6 +655,37 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testCancelAfterFirstRequestWithV2API { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *completionExpectation = + [self expectationWithDescription:@"Call completed."]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = self.class.transportType; + options.PEMRootCertificates = self.class.PEMRootCertificates; + options.hostNameOverride = [[self class] hostNameOverride]; + + id request = + [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTFail(@"Received unexpected response."); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + [completionExpectation fulfill]; + }] + callOptions:options]; + + [call writeMessage:request]; + [call cancel]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testRPCAfterClosingOpenConnections { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = From 9128881b6d97059170270936a13ee7c90f35b30a Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 28 Nov 2018 13:15:24 -0500 Subject: [PATCH 0334/2143] Add GPR_ATM_INC_ADD_THEN to grpc_core::RefCount This is to fix the wrong atomic op counts reported by benchmarks. Also add these macros to windows and gcc-sync headers as noop macros for consistency. --- include/grpc/impl/codegen/atm_gcc_sync.h | 2 ++ include/grpc/impl/codegen/atm_windows.h | 2 ++ src/core/lib/gprpp/ref_counted.h | 11 ++++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/grpc/impl/codegen/atm_gcc_sync.h b/include/grpc/impl/codegen/atm_gcc_sync.h index c0010a3469d..728c3d5412f 100644 --- a/include/grpc/impl/codegen/atm_gcc_sync.h +++ b/include/grpc/impl/codegen/atm_gcc_sync.h @@ -26,6 +26,8 @@ typedef intptr_t gpr_atm; #define GPR_ATM_MAX INTPTR_MAX #define GPR_ATM_MIN INTPTR_MIN +#define GPR_ATM_INC_CAS_THEN(blah) blah +#define GPR_ATM_INC_ADD_THEN(blah) blah #define GPR_ATM_COMPILE_BARRIER_() __asm__ __volatile__("" : : : "memory") diff --git a/include/grpc/impl/codegen/atm_windows.h b/include/grpc/impl/codegen/atm_windows.h index f6b27e5df70..c016b90095f 100644 --- a/include/grpc/impl/codegen/atm_windows.h +++ b/include/grpc/impl/codegen/atm_windows.h @@ -25,6 +25,8 @@ typedef intptr_t gpr_atm; #define GPR_ATM_MAX INTPTR_MAX #define GPR_ATM_MIN INTPTR_MIN +#define GPR_ATM_INC_CAS_THEN(blah) blah +#define GPR_ATM_INC_ADD_THEN(blah) blah #define gpr_atm_full_barrier MemoryBarrier diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index e366445bff4..98de1a3653f 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -21,6 +21,7 @@ #include +#include #include #include @@ -76,12 +77,15 @@ class RefCount { constexpr explicit RefCount(Value init = 1) : value_(init) {} // Increases the ref-count by `n`. - void Ref(Value n = 1) { value_.fetch_add(n, std::memory_order_relaxed); } + void Ref(Value n = 1) { + GPR_ATM_INC_ADD_THEN(value_.fetch_add(n, std::memory_order_relaxed)); + } // Similar to Ref() with an assert on the ref-count being non-zero. void RefNonZero() { #ifndef NDEBUG - const Value prior = value_.fetch_add(1, std::memory_order_relaxed); + const Value prior = + GPR_ATM_INC_ADD_THEN(value_.fetch_add(1, std::memory_order_relaxed)); assert(prior > 0); #else Ref(); @@ -90,7 +94,8 @@ class RefCount { // Decrements the ref-count and returns true if the ref-count reaches 0. bool Unref() { - const Value prior = value_.fetch_sub(1, std::memory_order_acq_rel); + const Value prior = + GPR_ATM_INC_ADD_THEN(value_.fetch_sub(1, std::memory_order_acq_rel)); GPR_DEBUG_ASSERT(prior > 0); return prior == 1; } From 5214f8bc57ed327235bcd949589e6da58b2c10ca Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 28 Nov 2018 14:00:40 -0800 Subject: [PATCH 0335/2143] Fix InlinedVector to use its elements' move and copy methods. --- src/core/lib/gprpp/inlined_vector.h | 68 +++++----- test/core/gprpp/inlined_vector_test.cc | 164 ++++++++++++++++++++++++- 2 files changed, 199 insertions(+), 33 deletions(-) diff --git a/src/core/lib/gprpp/inlined_vector.h b/src/core/lib/gprpp/inlined_vector.h index 65c2b9634f2..66dc751a567 100644 --- a/src/core/lib/gprpp/inlined_vector.h +++ b/src/core/lib/gprpp/inlined_vector.h @@ -100,10 +100,7 @@ class InlinedVector { void reserve(size_t capacity) { if (capacity > capacity_) { T* new_dynamic = static_cast(gpr_malloc(sizeof(T) * capacity)); - for (size_t i = 0; i < size_; ++i) { - new (&new_dynamic[i]) T(std::move(data()[i])); - data()[i].~T(); - } + move_elements(data(), new_dynamic, size_); gpr_free(dynamic_); dynamic_ = new_dynamic; capacity_ = capacity; @@ -131,33 +128,6 @@ class InlinedVector { size_--; } - void copy_from(const InlinedVector& v) { - // if v is allocated, copy over the buffer. - if (v.dynamic_ != nullptr) { - reserve(v.capacity_); - memcpy(dynamic_, v.dynamic_, v.size_ * sizeof(T)); - } else { - memcpy(inline_, v.inline_, v.size_ * sizeof(T)); - } - // copy over metadata - size_ = v.size_; - capacity_ = v.capacity_; - } - - void move_from(InlinedVector& v) { - // if v is allocated, then we steal its buffer, else we copy it. - if (v.dynamic_ != nullptr) { - dynamic_ = v.dynamic_; - } else { - memcpy(inline_, v.inline_, v.size_ * sizeof(T)); - } - // copy over metadata - size_ = v.size_; - capacity_ = v.capacity_; - // null out the original - v.init_data(); - } - size_t size() const { return size_; } bool empty() const { return size_ == 0; } @@ -169,6 +139,42 @@ class InlinedVector { } private: + void copy_from(const InlinedVector& v) { + // if v is allocated, make sure we have enough capacity. + if (v.dynamic_ != nullptr) { + reserve(v.capacity_); + } + // copy over elements + for (size_t i = 0; i < v.size_; ++i) { + new (&(data()[i])) T(v[i]); + } + // copy over metadata + size_ = v.size_; + capacity_ = v.capacity_; + } + + void move_from(InlinedVector& v) { + // if v is allocated, then we steal its dynamic array; otherwise, we + // move the elements individually. + if (v.dynamic_ != nullptr) { + dynamic_ = v.dynamic_; + } else { + move_elements(v.data(), data(), v.size_); + } + // copy over metadata + size_ = v.size_; + capacity_ = v.capacity_; + // null out the original + v.init_data(); + } + + static void move_elements(T* src, T* dst, size_t num_elements) { + for (size_t i = 0; i < num_elements; ++i) { + new (&dst[i]) T(std::move(src[i])); + src[i].~T(); + } + } + void init_data() { dynamic_ = nullptr; size_ = 0; diff --git a/test/core/gprpp/inlined_vector_test.cc b/test/core/gprpp/inlined_vector_test.cc index 73e0773b31d..6abd2e7dfaf 100644 --- a/test/core/gprpp/inlined_vector_test.cc +++ b/test/core/gprpp/inlined_vector_test.cc @@ -116,7 +116,7 @@ typedef InlinedVector IntVec8; const size_t kInlinedFillSize = kInlinedLength - 1; const size_t kAllocatedFillSize = kInlinedLength + 1; -TEST(InlinedVectorTest, CopyConstructerInlined) { +TEST(InlinedVectorTest, CopyConstructorInlined) { IntVec8 original; FillVector(&original, kInlinedFillSize); IntVec8 copy_constructed(original); @@ -125,7 +125,7 @@ TEST(InlinedVectorTest, CopyConstructerInlined) { } } -TEST(InlinedVectorTest, CopyConstructerAllocated) { +TEST(InlinedVectorTest, CopyConstructorAllocated) { IntVec8 original; FillVector(&original, kAllocatedFillSize); IntVec8 copy_constructed(original); @@ -264,6 +264,166 @@ TEST(InlinedVectorTest, MoveAssignmentAllocatedAllocated) { EXPECT_EQ(move_assigned.data(), old_data); } +// A copyable and movable value class, used to test that elements' copy +// and move methods are called correctly. +class Value { + public: + explicit Value(int v) : value_(MakeUnique(v)) {} + + // copyable + Value(const Value& v) { + value_ = MakeUnique(*v.value_); + copied_ = true; + } + Value& operator=(const Value& v) { + value_ = MakeUnique(*v.value_); + copied_ = true; + return *this; + } + + // movable + Value(Value&& v) { + value_ = std::move(v.value_); + moved_ = true; + } + Value& operator=(Value&& v) { + value_ = std::move(v.value_); + moved_ = true; + return *this; + } + + const UniquePtr& value() const { return value_; } + bool copied() const { return copied_; } + bool moved() const { return moved_; } + + private: + UniquePtr value_; + bool copied_ = false; + bool moved_ = false; +}; + +TEST(InlinedVectorTest, CopyConstructorCopiesElementsInlined) { + InlinedVector v1; + v1.emplace_back(3); + InlinedVector v2(v1); + EXPECT_EQ(v2.size(), 1UL); + EXPECT_EQ(*v2[0].value(), 3); + // Addresses should differ. + EXPECT_NE(v1[0].value().get(), v2[0].value().get()); + EXPECT_TRUE(v2[0].copied()); +} + +TEST(InlinedVectorTest, CopyConstructorCopiesElementsAllocated) { + InlinedVector v1; + v1.reserve(2); + v1.emplace_back(3); + v1.emplace_back(5); + InlinedVector v2(v1); + EXPECT_EQ(v2.size(), 2UL); + EXPECT_EQ(*v2[0].value(), 3); + EXPECT_EQ(*v2[1].value(), 5); + // Addresses should differ. + EXPECT_NE(v1[0].value().get(), v2[0].value().get()); + EXPECT_NE(v1[1].value().get(), v2[1].value().get()); + EXPECT_TRUE(v2[0].copied()); + EXPECT_TRUE(v2[1].copied()); +} + +TEST(InlinedVectorTest, CopyAssignmentCopiesElementsInlined) { + InlinedVector v1; + v1.emplace_back(3); + InlinedVector v2; + EXPECT_EQ(v2.size(), 0UL); + v2 = v1; + EXPECT_EQ(v2.size(), 1UL); + EXPECT_EQ(*v2[0].value(), 3); + // Addresses should differ. + EXPECT_NE(v1[0].value().get(), v2[0].value().get()); + EXPECT_TRUE(v2[0].copied()); +} + +TEST(InlinedVectorTest, CopyAssignmentCopiesElementsAllocated) { + InlinedVector v1; + v1.reserve(2); + v1.emplace_back(3); + v1.emplace_back(5); + InlinedVector v2; + EXPECT_EQ(v2.size(), 0UL); + v2 = v1; + EXPECT_EQ(v2.size(), 2UL); + EXPECT_EQ(*v2[0].value(), 3); + EXPECT_EQ(*v2[1].value(), 5); + // Addresses should differ. + EXPECT_NE(v1[0].value().get(), v2[0].value().get()); + EXPECT_NE(v1[1].value().get(), v2[1].value().get()); + EXPECT_TRUE(v2[0].copied()); + EXPECT_TRUE(v2[1].copied()); +} + +TEST(InlinedVectorTest, MoveConstructorMovesElementsInlined) { + InlinedVector v1; + v1.emplace_back(3); + int* addr = v1[0].value().get(); + InlinedVector v2(std::move(v1)); + EXPECT_EQ(v2.size(), 1UL); + EXPECT_EQ(*v2[0].value(), 3); + EXPECT_EQ(addr, v2[0].value().get()); + EXPECT_TRUE(v2[0].moved()); +} + +TEST(InlinedVectorTest, MoveConstructorMovesElementsAllocated) { + InlinedVector v1; + v1.reserve(2); + v1.emplace_back(3); + v1.emplace_back(5); + int* addr1 = v1[0].value().get(); + int* addr2 = v1[1].value().get(); + Value* data1 = v1.data(); + InlinedVector v2(std::move(v1)); + EXPECT_EQ(v2.size(), 2UL); + EXPECT_EQ(*v2[0].value(), 3); + EXPECT_EQ(*v2[1].value(), 5); + EXPECT_EQ(addr1, v2[0].value().get()); + EXPECT_EQ(addr2, v2[1].value().get()); + // In this case, elements won't be moved, because we have just stolen + // the underlying storage. + EXPECT_EQ(data1, v2.data()); +} + +TEST(InlinedVectorTest, MoveAssignmentMovesElementsInlined) { + InlinedVector v1; + v1.emplace_back(3); + int* addr = v1[0].value().get(); + InlinedVector v2; + EXPECT_EQ(v2.size(), 0UL); + v2 = std::move(v1); + EXPECT_EQ(v2.size(), 1UL); + EXPECT_EQ(*v2[0].value(), 3); + EXPECT_EQ(addr, v2[0].value().get()); + EXPECT_TRUE(v2[0].moved()); +} + +TEST(InlinedVectorTest, MoveAssignmentMovesElementsAllocated) { + InlinedVector v1; + v1.reserve(2); + v1.emplace_back(3); + v1.emplace_back(5); + int* addr1 = v1[0].value().get(); + int* addr2 = v1[1].value().get(); + Value* data1 = v1.data(); + InlinedVector v2; + EXPECT_EQ(v2.size(), 0UL); + v2 = std::move(v1); + EXPECT_EQ(v2.size(), 2UL); + EXPECT_EQ(*v2[0].value(), 3); + EXPECT_EQ(*v2[1].value(), 5); + EXPECT_EQ(addr1, v2[0].value().get()); + EXPECT_EQ(addr2, v2[1].value().get()); + // In this case, elements won't be moved, because we have just stolen + // the underlying storage. + EXPECT_EQ(data1, v2.data()); +} + TEST(InlinedVectorTest, PopBackInlined) { InlinedVector, 2> v; // Add two elements, pop one out From d75abb6663e200f24f3aa398800ef3051d65ce50 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 28 Nov 2018 14:32:36 -0800 Subject: [PATCH 0336/2143] Adding comment about `del` about #17258 --- src/python/grpcio/grpc/_server.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index fea1ca8da69..080ef38ea88 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -828,6 +828,8 @@ class _Server(grpc.Server): return _stop(self._state, grace) def __del__(self): + # TODO(lidiz): Depends on issue #17258 which is not solved yet + # The `_state` may not exist when object get deconstructed if hasattr(self, '_state'): _stop(self._state, None) del self._state From 836e143093d29403933e9cf05fa0e82752a3f194 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 28 Nov 2018 14:36:17 -0800 Subject: [PATCH 0337/2143] Add required header --- src/core/lib/transport/transport.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index d9b9a97b0a1..b32f9c6ec1a 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -27,6 +27,7 @@ #include #include +#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/slice/slice_internal.h" From 99f248ae120421bb2a947fff6e757073e78c3bc0 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 28 Nov 2018 14:49:28 -0800 Subject: [PATCH 0338/2143] Remove the `del` hack and skip server related test cases --- src/python/grpcio/grpc/_server.py | 6 +----- .../grpcio_tests/tests/channelz/_channelz_servicer_test.py | 5 +++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 080ef38ea88..7276a7fd90e 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -828,11 +828,7 @@ class _Server(grpc.Server): return _stop(self._state, grace) def __del__(self): - # TODO(lidiz): Depends on issue #17258 which is not solved yet - # The `_state` may not exist when object get deconstructed - if hasattr(self, '_state'): - _stop(self._state, None) - del self._state + _stop(self._state, None) def create_server(thread_pool, generic_rpc_handlers, interceptors, options, 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 2549ed76be8..8fbc779eb97 100644 --- a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -280,12 +280,14 @@ class ChannelzServicerTest(unittest.TestCase): self.assertEqual(gtc_resp.channel[i].data.calls_failed, gsc_resp.subchannel.data.calls_failed) + @unittest.skip('Due to server destruction logic issue #17258') def test_server_basic(self): self._pairs = _generate_channel_server_pairs(1) resp = self._channelz_stub.GetServers( channelz_pb2.GetServersRequest(start_server_id=0)) self.assertEqual(len(resp.server), 1) + @unittest.skip('Due to server destruction logic issue #17258') def test_get_one_server(self): self._pairs = _generate_channel_server_pairs(1) gss_resp = self._channelz_stub.GetServers( @@ -297,6 +299,7 @@ class ChannelzServicerTest(unittest.TestCase): self.assertEqual(gss_resp.server[0].ref.server_id, gs_resp.server.ref.server_id) + @unittest.skip('Due to server destruction logic issue #17258') def test_server_call(self): self._pairs = _generate_channel_server_pairs(1) k_success = 23 @@ -391,6 +394,7 @@ class ChannelzServicerTest(unittest.TestCase): self.assertEqual(gs_resp.socket.data.messages_received, test_constants.STREAM_LENGTH) + @unittest.skip('Due to server destruction logic issue #17258') def test_server_sockets(self): self._pairs = _generate_channel_server_pairs(1) self._send_successful_unary_unary(0) @@ -409,6 +413,7 @@ class ChannelzServicerTest(unittest.TestCase): # If the RPC call failed, it will raise a grpc.RpcError # So, if there is no exception raised, considered pass + @unittest.skip('Due to server destruction logic issue #17258') def test_server_listen_sockets(self): self._pairs = _generate_channel_server_pairs(1) From 460bc6f7ce7b0e00e35a891fd3c12d4738d52142 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 28 Nov 2018 14:57:33 -0800 Subject: [PATCH 0339/2143] PHP: fix ZTS build --- src/php/ext/grpc/php_grpc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index f7d5a85876b..111c6f4867d 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -170,7 +170,9 @@ void prefork() { acquire_persistent_locks(); } -void postfork_child(TSRMLS_D) { +void postfork_child() { + TSRMLS_FETCH(); + // loop through persistant list and destroy all underlying grpc_channel objs destroy_grpc_channels(); From 211419d65c119d5bd3a627de5404f2104ae76523 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 28 Nov 2018 14:59:58 -0800 Subject: [PATCH 0340/2143] PHP: fix ZTS build --- src/php/ext/grpc/php_grpc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index f7d5a85876b..111c6f4867d 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -170,7 +170,9 @@ void prefork() { acquire_persistent_locks(); } -void postfork_child(TSRMLS_D) { +void postfork_child() { + TSRMLS_FETCH(); + // loop through persistant list and destroy all underlying grpc_channel objs destroy_grpc_channels(); From cf104e1ba3ce3bcbeef769dbfa3dc2de6283680a Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Wed, 28 Nov 2018 15:05:06 -0800 Subject: [PATCH 0341/2143] regenerate doxygen files --- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core | 1 + tools/doxygen/Doxyfile.core.internal | 1 + 4 files changed, 4 insertions(+) diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index fbac37e8e75..5c19711ee91 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -777,6 +777,7 @@ doc/environment_variables.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ +doc/grpc_release_schedule.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ doc/http2-interop-test-descriptions.md \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index f7a9c79620b..72b247c48da 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -777,6 +777,7 @@ doc/environment_variables.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ +doc/grpc_release_schedule.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ doc/http2-interop-test-descriptions.md \ diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index b78fb607ad3..8c557383b2e 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -784,6 +784,7 @@ doc/environment_variables.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ +doc/grpc_release_schedule.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ doc/http2-interop-test-descriptions.md \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index b4f15886c66..0f1943de25f 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -784,6 +784,7 @@ doc/environment_variables.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ +doc/grpc_release_schedule.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ doc/http2-interop-test-descriptions.md \ From 2fcf6176fd876028b3a4002bd87c2c6d78aaf655 Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Wed, 28 Nov 2018 16:38:45 -0800 Subject: [PATCH 0342/2143] Adding a line about alphabetical order of AUTHORS --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e8582d9af5e..1d14d5e0e3a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,7 +81,7 @@ How to get your contributions merged smoothly and quickly. copyright holder for the contribution (yourself, if you are signing the individual CLA, or your company, for corporate CLAs) in the same PR as your contribution. This needs to be done only once, for each company, or - individual. + individual. Please keep this file in alphabetical order. - Maintain **clean commit history** and use **meaningful commit messages**. PRs with messy commit history are difficult to review and won't be merged. From 7eddafabdd43751bea39ae63df7d084e22afd9d4 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 28 Nov 2018 17:15:42 -0800 Subject: [PATCH 0343/2143] Disable three subchannel unit tests for gevent --- src/python/grpcio_tests/commands.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index d163f6fb68e..9b69c4e02b1 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -132,7 +132,11 @@ class TestGevent(setuptools.Command): 'unit.beta._beta_features_test', # TODO(https://github.com/grpc/grpc/issues/15411) unpin gevent version # This test will stuck while running higher version of gevent - 'unit._auth_context_test.AuthContextTest.testSessionResumption') + 'unit._auth_context_test.AuthContextTest.testSessionResumption', + # 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') description = 'run tests with gevent. Assumes grpc/gevent are installed' user_options = [] From 7cd7ecc941e921e02a280cb358001076d4469610 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 28 Nov 2018 19:02:23 -0800 Subject: [PATCH 0344/2143] Add the length of the buffer that is traced --- src/core/lib/iomgr/buffer_list.cc | 3 ++- src/core/lib/iomgr/buffer_list.h | 6 ++++-- src/core/lib/iomgr/tcp_posix.cc | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index e20dab15b18..b9e38f7dd21 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -30,9 +30,10 @@ namespace grpc_core { void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, - void* arg) { + uint32_t length, void* arg) { GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* new_elem = New(seq_no, arg); + new_elem->ts_.length = length; /* Store the current time as the sendmsg time. */ new_elem->ts_.sendmsg_time = gpr_now(GPR_CLOCK_REALTIME); if (*head == nullptr) { diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 87d74f9ce27..9e2c1dcb24a 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -37,6 +37,8 @@ struct Timestamps { gpr_timespec scheduled_time; gpr_timespec sent_time; gpr_timespec acked_time; + + uint32_t length; /* The length of the buffer traced */ }; /** TracedBuffer is a class to keep track of timestamps for a specific buffer in @@ -56,7 +58,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); + uint32_t length, void* arg); /** Processes a received timestamp based on sock_extended_err and * scm_timestamping structures. It will invoke the timestamps callback if the @@ -73,7 +75,7 @@ class TracedBuffer { private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW - TracedBuffer(int seq_no, void* arg) + TracedBuffer(uint32_t seq_no, void* arg) : seq_no_(seq_no), arg_(arg), next_(nullptr) {} uint32_t seq_no_; /* The sequence number for the last byte in the buffer */ diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 606bfce6e73..8f3403473eb 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -634,8 +634,8 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, if (sending_length == static_cast(length)) { gpr_mu_lock(&tcp->tb_mu); grpc_core::TracedBuffer::AddNewEntry( - &tcp->tb_head, static_cast(tcp->bytes_counter + length), - tcp->outgoing_buffer_arg); + &tcp->tb_head, static_cast(tcp->bytes_counter + length), + static_cast(length), tcp->outgoing_buffer_arg); gpr_mu_unlock(&tcp->tb_mu); tcp->outgoing_buffer_arg = nullptr; } From af16b2c09d75f56acc9fa2c7d76ebb038e06ea3e Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 28 Nov 2018 20:16:27 -0800 Subject: [PATCH 0345/2143] Return immediately if the first message is empty --- src/core/lib/iomgr/tcp_posix.cc | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 606bfce6e73..84d593426ec 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -686,11 +686,9 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, } /** For linux platforms, reads the socket's error queue and processes error - * messages from the queue. Returns true if all the errors processed were - * timestamps. Returns false if any of the errors were not timestamps. For - * non-linux platforms, error processing is not used/enabled currently. + * messages from the queue. */ -static bool process_errors(grpc_tcp* tcp) { +static void process_errors(grpc_tcp* tcp) { while (true) { struct iovec iov; iov.iov_base = nullptr; @@ -719,10 +717,10 @@ static bool process_errors(grpc_tcp* tcp) { } while (r < 0 && saved_errno == EINTR); if (r == -1 && saved_errno == EAGAIN) { - return true; /* No more errors to process */ + return; /* No more errors to process */ } if (r == -1) { - return false; + return; } if (grpc_tcp_trace.enabled()) { if ((msg.msg_flags & MSG_CTRUNC) == 1) { @@ -732,10 +730,14 @@ static bool process_errors(grpc_tcp* tcp) { if (msg.msg_controllen == 0) { /* There was no control message found. It was probably spurious. */ - return true; + return; } - for (auto cmsg = CMSG_FIRSTHDR(&msg); cmsg && cmsg->cmsg_len; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { + auto cmsg = CMSG_FIRSTHDR(&msg); + if (cmsg == nullptr || cmsg->cmsg_len == 0) { + /* No control message found. */ + return; + } + do { if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_TIMESTAMPING) { /* Got a control message that is not a timestamp. Don't know how to @@ -745,10 +747,10 @@ static bool process_errors(grpc_tcp* tcp) { "unknown control message cmsg_level:%d cmsg_type:%d", cmsg->cmsg_level, cmsg->cmsg_type); } - return false; + return; } - cmsg = process_timestamp(tcp, &msg, cmsg); - } + cmsg = CMSG_NXTHDR(&msg, process_timestamp(tcp, &msg, cmsg)); + } while (cmsg && cmsg->cmsg_len); } } From e57f8aebcb343c36662da042d441a0dfceddbf4c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 28 Nov 2018 20:49:17 -0800 Subject: [PATCH 0346/2143] Update test --- test/core/iomgr/buffer_list_test.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc index e104e8e91a0..a979fde5e46 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, 0, static_cast(&verifier_called[i])); } grpc_core::TracedBuffer::Shutdown(&list, nullptr, GRPC_ERROR_NONE); GPR_ASSERT(list == nullptr); @@ -66,6 +66,7 @@ static void TestVerifierCalledOnAckVerifier(void* arg, 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->length == 789); gpr_atm* done = reinterpret_cast(arg); gpr_atm_rel_store(done, static_cast(1)); } @@ -84,7 +85,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, 789, &verifier_called); grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, &tss); GPR_ASSERT(gpr_atm_acq_load(&verifier_called) == static_cast(1)); GPR_ASSERT(list == nullptr); From a82070dc94086f85dfda485ec0d5aa10c3081bb0 Mon Sep 17 00:00:00 2001 From: kkm Date: Wed, 28 Nov 2018 23:53:21 -0800 Subject: [PATCH 0347/2143] Add explicit ItemGroups to .csproj --- examples/csharp/Helloworld/Greeter/Greeter.csproj | 2 ++ examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/csharp/Helloworld/Greeter/Greeter.csproj b/examples/csharp/Helloworld/Greeter/Greeter.csproj index 3421926dca5..7989f795418 100644 --- a/examples/csharp/Helloworld/Greeter/Greeter.csproj +++ b/examples/csharp/Helloworld/Greeter/Greeter.csproj @@ -8,7 +8,9 @@ +
+ diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj index 2d4f48ec2e9..4c6949488c7 100644 --- a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj +++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj @@ -12,7 +12,10 @@
- + + + + From fe4ef31ac28f702755c67cb0d79140bc9cbaa552 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 29 Nov 2018 00:56:22 -0800 Subject: [PATCH 0348/2143] Do not add the TCP buffer length. --- src/core/lib/iomgr/buffer_list.cc | 3 +-- src/core/lib/iomgr/buffer_list.h | 2 +- src/core/lib/iomgr/tcp_posix.cc | 2 +- test/core/iomgr/buffer_list_test.cc | 5 ++--- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index b9e38f7dd21..e20dab15b18 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -30,10 +30,9 @@ namespace grpc_core { void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, - uint32_t length, void* arg) { + void* arg) { GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* new_elem = New(seq_no, arg); - new_elem->ts_.length = length; /* Store the current time as the sendmsg time. */ new_elem->ts_.sendmsg_time = gpr_now(GPR_CLOCK_REALTIME); if (*head == nullptr) { diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 9e2c1dcb24a..9f62d988cce 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -58,7 +58,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, - uint32_t length, void* arg); + 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 8f3403473eb..ee339cdfc4d 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -635,7 +635,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, gpr_mu_lock(&tcp->tb_mu); grpc_core::TracedBuffer::AddNewEntry( &tcp->tb_head, static_cast(tcp->bytes_counter + length), - static_cast(length), tcp->outgoing_buffer_arg); + 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 a979fde5e46..e104e8e91a0 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, 0, static_cast(&verifier_called[i])); + &list, i, static_cast(&verifier_called[i])); } grpc_core::TracedBuffer::Shutdown(&list, nullptr, GRPC_ERROR_NONE); GPR_ASSERT(list == nullptr); @@ -66,7 +66,6 @@ static void TestVerifierCalledOnAckVerifier(void* arg, 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->length == 789); gpr_atm* done = reinterpret_cast(arg); gpr_atm_rel_store(done, static_cast(1)); } @@ -85,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, 789, &verifier_called); + grpc_core::TracedBuffer::AddNewEntry(&list, 213, &verifier_called); grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, &tss); GPR_ASSERT(gpr_atm_acq_load(&verifier_called) == static_cast(1)); GPR_ASSERT(list == nullptr); From 9506d356740f8375f121e00e057a2eba41c97a98 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 29 Nov 2018 01:26:45 -0800 Subject: [PATCH 0349/2143] Add a byte counter to chttp2_stream and use that for timestamps --- .../ext/transport/chttp2/transport/context_list.cc | 1 + .../ext/transport/chttp2/transport/context_list.h | 2 ++ src/core/ext/transport/chttp2/transport/internal.h | 2 ++ src/core/ext/transport/chttp2/transport/writing.cc | 7 ++++--- src/core/lib/iomgr/buffer_list.h | 2 +- test/core/transport/chttp2/context_list_test.cc | 12 ++++++++---- 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc index 4acd0c95833..89e574ac67f 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.cc +++ b/src/core/ext/transport/chttp2/transport/context_list.cc @@ -32,6 +32,7 @@ void ContextList::Execute(void* arg, grpc_core::Timestamps* ts, while (head != nullptr) { if (error == GRPC_ERROR_NONE && ts != nullptr) { if (write_timestamps_callback_g) { + ts->byte_offset = head->byte_offset_; write_timestamps_callback_g(head->s_->context, ts); } } diff --git a/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h index 68d11e94d86..d8701077494 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.h +++ b/src/core/ext/transport/chttp2/transport/context_list.h @@ -50,6 +50,7 @@ class ContextList { /* Create a new element in the list and add it at the front */ ContextList* elem = grpc_core::New(); elem->s_ = s; + elem->byte_offset_ = s->byte_counter; elem->next_ = *head; *head = elem; } @@ -61,6 +62,7 @@ class ContextList { private: grpc_chttp2_stream* s_ = nullptr; ContextList* next_ = nullptr; + size_t byte_offset_ = 0; }; void grpc_http2_set_write_timestamps_callback( diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index aeaa4935ad7..6aa68f5d4a9 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -646,6 +646,8 @@ struct grpc_chttp2_stream { bool traced = false; /** gRPC header bytes that are already decompressed */ size_t decompressed_header_bytes = 0; + /** Byte counter for number of bytes written */ + size_t byte_counter = 0; }; /** Transport writing call flow: diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index 77320b496f9..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; } @@ -488,9 +489,6 @@ class StreamWriteContext { return; // early out: nothing to do } - if (s_->traced && grpc_endpoint_can_track_err(t_->ep)) { - grpc_core::ContextList::Append(&t_->cl, s_); - } while ((s_->flow_controlled_buffer.length > 0 || s_->compressed_data_buffer.length > 0) && data_send_context.max_outgoing() > 0) { @@ -500,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(); diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 9f62d988cce..627f1bde99a 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -38,7 +38,7 @@ struct Timestamps { gpr_timespec sent_time; gpr_timespec acked_time; - uint32_t length; /* The length of the buffer traced */ + uint32_t byte_offset; /* byte offset relative to the start of the RPC */ }; /** TracedBuffer is a class to keep track of timestamps for a specific buffer in diff --git a/test/core/transport/chttp2/context_list_test.cc b/test/core/transport/chttp2/context_list_test.cc index e2100899d39..d61f32985ec 100644 --- a/test/core/transport/chttp2/context_list_test.cc +++ b/test/core/transport/chttp2/context_list_test.cc @@ -33,8 +33,12 @@ namespace grpc_core { namespace testing { namespace { + +const int kByteOffset = 123; + void TestExecuteFlushesListVerifier(void* arg, grpc_core::Timestamps* ts) { - GPR_ASSERT(arg != nullptr); + ASSERT_NE(arg, nullptr); + EXPECT_EQ(ts->byte_offset, kByteOffset); gpr_atm* done = reinterpret_cast(arg); gpr_atm_rel_store(done, static_cast(1)); } @@ -43,7 +47,7 @@ void discard_write(grpc_slice slice) {} /** Tests that all ContextList elements in the list are flushed out on * execute. - * Also tests that arg is passed correctly. + * Also tests that arg and byte_counter are passed correctly. */ TEST(ContextList, ExecuteFlushesList) { grpc_core::ContextList* list = nullptr; @@ -68,14 +72,14 @@ TEST(ContextList, ExecuteFlushesList) { reinterpret_cast(s[i]), &ref, nullptr, nullptr); s[i]->context = &verifier_called[i]; + s[i]->byte_counter = kByteOffset; gpr_atm_rel_store(&verifier_called[i], static_cast(0)); grpc_core::ContextList::Append(&list, s[i]); } grpc_core::Timestamps ts; grpc_core::ContextList::Execute(list, &ts, GRPC_ERROR_NONE); for (auto i = 0; i < kNumElems; i++) { - GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) == - static_cast(1)); + EXPECT_EQ(gpr_atm_acq_load(&verifier_called[i]), static_cast(1)); grpc_transport_destroy_stream(reinterpret_cast(t), reinterpret_cast(s[i]), nullptr); From 77ba25ab7230546abb3200558b928e0f35c00635 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 29 Nov 2018 02:21:19 -0800 Subject: [PATCH 0350/2143] s/int/uint32_t --- test/core/transport/chttp2/context_list_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/transport/chttp2/context_list_test.cc b/test/core/transport/chttp2/context_list_test.cc index d61f32985ec..e64f1532ecd 100644 --- a/test/core/transport/chttp2/context_list_test.cc +++ b/test/core/transport/chttp2/context_list_test.cc @@ -34,7 +34,7 @@ namespace grpc_core { namespace testing { namespace { -const int kByteOffset = 123; +const uint32_t kByteOffset = 123; void TestExecuteFlushesListVerifier(void* arg, grpc_core::Timestamps* ts) { ASSERT_NE(arg, nullptr); From 93a165ec6ca6d05100492bee739ff918cd280c7a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 29 Nov 2018 02:38:55 -0800 Subject: [PATCH 0351/2143] Initialize all other timestamps (non sendmsg) to gpr_inf_past --- src/core/lib/iomgr/buffer_list.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index e20dab15b18..ace17a108d1 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -35,6 +35,9 @@ void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, 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); if (*head == nullptr) { *head = new_elem; return; From 217de8908526c58d4a6c2c7c403e0d94287da815 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 27 Nov 2018 14:32:42 -0800 Subject: [PATCH 0352/2143] Don't ignore empty serverlists from the grpclb balancer. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 84 ++++++++----------- test/cpp/end2end/grpclb_end2end_test.cc | 8 +- 2 files changed, 41 insertions(+), 51 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 dc0e1f89ce6..7e70f1c28bd 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 @@ -749,7 +749,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( void* arg, grpc_error* error) { BalancerCallState* lb_calld = static_cast(arg); GrpcLb* grpclb_policy = lb_calld->grpclb_policy(); - // Empty payload means the LB call was cancelled. + // Null payload means the LB call was cancelled. if (lb_calld != grpclb_policy->lb_calld_.get() || lb_calld->recv_message_payload_ == nullptr) { lb_calld->Unref(DEBUG_LOCATION, "on_message_received"); @@ -803,54 +803,45 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( gpr_free(ipport); } } - /* update serverlist */ - if (serverlist->num_servers > 0) { - // 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()); - // 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(); - lb_calld->ScheduleNextClientLoadReportLocked(); - } - if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_, - serverlist)) { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] Incoming server list identical to current, " - "ignoring.", - grpclb_policy); - } - 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 { - /* or dispose of the fallback */ - grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_); - grpclb_policy->fallback_backend_addresses_ = nullptr; - if (grpclb_policy->fallback_timer_callback_pending_) { - grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_); - } - } - // and update the copy 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->CreateOrUpdateRoundRobinPolicyLocked(); - } - } else { + // 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()); + // 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(); + lb_calld->ScheduleNextClientLoadReportLocked(); + } + // Check if the serverlist differs from the previous one. + if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_, serverlist)) { if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Received empty server list, ignoring.", + gpr_log(GPR_INFO, + "[grpclb %p] Incoming server list identical to current, " + "ignoring.", grpclb_policy); } 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 { + // Dispose of the fallback. + grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_); + grpclb_policy->fallback_backend_addresses_ = nullptr; + 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 + // GrpcLb instance is destroyed. + grpclb_policy->serverlist_ = serverlist; + grpclb_policy->serverlist_index_ = 0; + grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked(); } } else { // No valid initial response or serverlist found. @@ -1583,7 +1574,7 @@ void GrpcLb::AddPendingPick(PendingPick* pp) { 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) { + 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) { @@ -1681,7 +1672,6 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { grpc_lb_addresses* addresses; bool is_backend_from_grpclb_load_balancer = false; if (serverlist_ != nullptr) { - GPR_ASSERT(serverlist_->num_servers > 0); addresses = ProcessServerlist(serverlist_); is_backend_from_grpclb_load_balancer = true; } else { diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 6ce0696114e..5b304dc16b1 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -553,10 +553,11 @@ class GrpclbEnd2endTest : public ::testing::Test { return status; } - void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000) { + 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); + 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_); @@ -717,10 +718,9 @@ TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) { ScheduleResponseForBalancer( 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), kServerlistDelayMs); - const auto t0 = system_clock::now(); // Client will block: LB will initially send empty serverlist. - CheckRpcSendOk(1, kCallDeadlineMs); + CheckRpcSendOk(1, kCallDeadlineMs, true /* wait_for_ready */); const auto ellapsed_ms = std::chrono::duration_cast( system_clock::now() - t0); From 429dcb228afd79f96c733dc6ad6270e81528eece Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 29 Nov 2018 17:32:39 +0100 Subject: [PATCH 0353/2143] make sure PHP tests work on high sierra kokoro workers --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 24a3545dedc..f5b0b764b14 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -91,3 +91,6 @@ mkdir -p /tmpfs/DerivedData rm -rf ~/Library/Developer/Xcode/DerivedData mkdir -p ~/Library/Developer/Xcode ln -s /tmpfs/DerivedData ~/Library/Developer/Xcode/DerivedData + +# PHP tests currently require using an older version of PHPUnit +ln -sf /usr/local/bin/phpunit-5.7 /usr/local/bin/phpunit From ba45e77413b0475036bf5d22adabf8bd432fd443 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 29 Nov 2018 10:00:57 -0800 Subject: [PATCH 0354/2143] Revert the do while and if --- src/core/lib/iomgr/tcp_posix.cc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 84d593426ec..68c61b1201d 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -732,12 +732,9 @@ static void process_errors(grpc_tcp* tcp) { /* There was no control message found. It was probably spurious. */ return; } - auto cmsg = CMSG_FIRSTHDR(&msg); - if (cmsg == nullptr || cmsg->cmsg_len == 0) { - /* No control message found. */ - return; - } - do { + bool seen = false; + for (auto cmsg = CMSG_FIRSTHDR(&msg); cmsg && cmsg->cmsg_len; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_TIMESTAMPING) { /* Got a control message that is not a timestamp. Don't know how to @@ -749,8 +746,12 @@ static void process_errors(grpc_tcp* tcp) { } return; } - cmsg = CMSG_NXTHDR(&msg, process_timestamp(tcp, &msg, cmsg)); - } while (cmsg && cmsg->cmsg_len); + cmsg = process_timestamp(tcp, &msg, cmsg); + seen = true; + } + if (!seen) { + return; + } } } From 3888f747b49037df4a995d8bf131ba0891f8c042 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 29 Nov 2018 11:15:42 -0800 Subject: [PATCH 0355/2143] log fork compat message at INFO instead of ERROR --- 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 e957bad73d3..05ecd2a49b7 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -60,7 +60,7 @@ void grpc_prefork() { } if (strcmp(grpc_get_poll_strategy_name(), "epoll1") != 0 && strcmp(grpc_get_poll_strategy_name(), "poll") != 0) { - gpr_log(GPR_ERROR, + gpr_log(GPR_INFO, "Fork support is only compatible with the epoll1 and poll polling " "strategies"); } From 864cea208136892f405b54edcedf77c899385393 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 29 Nov 2018 11:18:35 -0800 Subject: [PATCH 0356/2143] 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 575da5118a2f02a9e3473077d4c934eda9c8cd40 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 29 Nov 2018 11:21:15 -0800 Subject: [PATCH 0357/2143] Explicit conversion --- src/core/ext/transport/chttp2/transport/context_list.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc index 89e574ac67f..f30d41c3326 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.cc +++ b/src/core/ext/transport/chttp2/transport/context_list.cc @@ -32,7 +32,7 @@ void ContextList::Execute(void* arg, grpc_core::Timestamps* ts, while (head != nullptr) { if (error == GRPC_ERROR_NONE && ts != nullptr) { if (write_timestamps_callback_g) { - ts->byte_offset = head->byte_offset_; + ts->byte_offset = static_cast(head->byte_offset_); write_timestamps_callback_g(head->s_->context, ts); } } From 8e3234963eeba191f6c011cd0082868ab92c5815 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 29 Nov 2018 11:29:43 -0800 Subject: [PATCH 0358/2143] Update comments && modify function name --- .../grpc_channelz/v1/channelz.py | 2 +- src/python/grpcio_tests/commands.py | 3 +- .../tests/channelz/_channelz_servicer_test.py | 35 +++++++++++++------ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py index 1ae5e8c140d..f03d3b736e2 100644 --- a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py +++ b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py @@ -119,7 +119,7 @@ class ChannelzServicer(_channelz_pb2_grpc.ChannelzServicer): context.set_details(str(e)) -def enable_channelz(server): +def add_channelz_servicer(server): """Enables Channelz on a server. Args: diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 9b69c4e02b1..65e9a99950e 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -136,7 +136,8 @@ 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' + ) description = 'run tests with gevent. Assumes grpc/gevent are installed' user_options = [] 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 8fbc779eb97..f099a2c8cb4 100644 --- a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -69,7 +69,9 @@ class _ChannelServerPair(object): def __init__(self): # Server will enable channelz service - # Bind as attribute to make it gc properly + # Bind as attribute, so its `del` can be called explicitly, during + # the destruction process. Otherwise, if the removal of server + # rely on gc cycle, the test will become non-deterministic. self._server = grpc.server( futures.ThreadPoolExecutor(max_workers=3), options=_DISABLE_REUSE_PORT + _ENABLE_CHANNELZ) @@ -134,10 +136,7 @@ class ChannelzServicerTest(unittest.TestCase): futures.ThreadPoolExecutor(max_workers=3), options=_DISABLE_REUSE_PORT + _DISABLE_CHANNELZ) port = self._server.add_insecure_port('[::]:0') - channelz_pb2_grpc.add_ChannelzServicer_to_server( - channelz.ChannelzServicer(), - self._server, - ) + channelz.add_channelz_servicer(self._server) self._server.start() # This channel is used to fetch Channelz info only @@ -150,6 +149,7 @@ class ChannelzServicerTest(unittest.TestCase): self._server.__del__() self._channel.close() # _pairs may not exist, if the test crashed during setup + # In 'invalid query' tests, _pairs may never get set if hasattr(self, '_pairs'): _clean_channel_server_pairs(self._pairs) @@ -280,14 +280,20 @@ class ChannelzServicerTest(unittest.TestCase): self.assertEqual(gtc_resp.channel[i].data.calls_failed, gsc_resp.subchannel.data.calls_failed) - @unittest.skip('Due to server destruction logic issue #17258') + @unittest.skip('Servers in core are not guaranteed to be destroyed ' \ + 'immediately when the reference goes out of scope, so ' \ + 'servers from multiple test cases are not hermetic. ' \ + 'TODO(https://github.com/grpc/grpc/issues/17258)') def test_server_basic(self): self._pairs = _generate_channel_server_pairs(1) resp = self._channelz_stub.GetServers( channelz_pb2.GetServersRequest(start_server_id=0)) self.assertEqual(len(resp.server), 1) - @unittest.skip('Due to server destruction logic issue #17258') + @unittest.skip('Servers in core are not guaranteed to be destroyed ' \ + 'immediately when the reference goes out of scope, so ' \ + 'servers from multiple test cases are not hermetic. ' \ + 'TODO(https://github.com/grpc/grpc/issues/17258)') def test_get_one_server(self): self._pairs = _generate_channel_server_pairs(1) gss_resp = self._channelz_stub.GetServers( @@ -299,7 +305,10 @@ class ChannelzServicerTest(unittest.TestCase): self.assertEqual(gss_resp.server[0].ref.server_id, gs_resp.server.ref.server_id) - @unittest.skip('Due to server destruction logic issue #17258') + @unittest.skip('Servers in core are not guaranteed to be destroyed ' \ + 'immediately when the reference goes out of scope, so ' \ + 'servers from multiple test cases are not hermetic. ' \ + 'TODO(https://github.com/grpc/grpc/issues/17258)') def test_server_call(self): self._pairs = _generate_channel_server_pairs(1) k_success = 23 @@ -394,7 +403,10 @@ class ChannelzServicerTest(unittest.TestCase): self.assertEqual(gs_resp.socket.data.messages_received, test_constants.STREAM_LENGTH) - @unittest.skip('Due to server destruction logic issue #17258') + @unittest.skip('Servers in core are not guaranteed to be destroyed ' \ + 'immediately when the reference goes out of scope, so ' \ + 'servers from multiple test cases are not hermetic. ' \ + 'TODO(https://github.com/grpc/grpc/issues/17258)') def test_server_sockets(self): self._pairs = _generate_channel_server_pairs(1) self._send_successful_unary_unary(0) @@ -413,7 +425,10 @@ class ChannelzServicerTest(unittest.TestCase): # If the RPC call failed, it will raise a grpc.RpcError # So, if there is no exception raised, considered pass - @unittest.skip('Due to server destruction logic issue #17258') + @unittest.skip('Servers in core are not guaranteed to be destroyed ' \ + 'immediately when the reference goes out of scope, so ' \ + 'servers from multiple test cases are not hermetic. ' \ + 'TODO(https://github.com/grpc/grpc/issues/17258)') def test_server_listen_sockets(self): self._pairs = _generate_channel_server_pairs(1) From b9a98dd2ab3fed4bfaf65e4125b5d3cacc731cfb Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Thu, 29 Nov 2018 12:17:09 -0800 Subject: [PATCH 0359/2143] Fix comment --- include/grpc/impl/codegen/grpc_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 17a43fab0f1..d1cc6af04fb 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -293,7 +293,7 @@ typedef struct { "grpc.max_channel_trace_event_memory_per_node" /** If non-zero, gRPC library will track stats and information at at per channel * level. Disabling channelz naturally disables channel tracing. The default - * is for channelz to be disabled. */ + * is for channelz to be enabled. */ #define GRPC_ARG_ENABLE_CHANNELZ "grpc.enable_channelz" /** If non-zero, Cronet transport will coalesce packets to fewer frames * when possible. */ From 69b6c047bc767b4d80e7af4d00ccb7c45b683dae Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 29 Nov 2018 12:57:00 -0800 Subject: [PATCH 0360/2143] Update docstring of Channelz function && add default variable initialization --- .../grpcio_channelz/grpc_channelz/v1/channelz.py | 14 +++++++++++++- .../tests/channelz/_channelz_servicer_test.py | 6 ++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py index f03d3b736e2..573b9d0d5ac 100644 --- a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py +++ b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py @@ -120,7 +120,19 @@ class ChannelzServicer(_channelz_pb2_grpc.ChannelzServicer): def add_channelz_servicer(server): - """Enables Channelz on a server. + """Add Channelz servicer to a server. Channelz servicer is in charge of + pulling information from C-Core for entire process. It will allow the + server to response to Channelz queries. + + The Channelz statistic is enabled by default inside C-Core. Whether the + statistic is enabled or not is isolated from adding Channelz servicer. + That means you can query Channelz info with a Channelz-disabled channel, + and you can add Channelz servicer to a Channelz-disabled server. + + The Channelz statistic can be enabled or disabled by channel option + 'grpc.enable_channelz'. Set to 1 to enable, set to 0 to disable. + + This is an EXPERIMENTAL API. Args: server: grpc.Server to which Channelz service will be added. 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 f099a2c8cb4..84f85946896 100644 --- a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -130,6 +130,7 @@ class ChannelzServicerTest(unittest.TestCase): return resp.channel[idx].ref.channel_id def setUp(self): + self._pairs = [] # This server is for Channelz info fetching only # It self should not enable Channelz self._server = grpc.server( @@ -148,10 +149,7 @@ class ChannelzServicerTest(unittest.TestCase): def tearDown(self): self._server.__del__() self._channel.close() - # _pairs may not exist, if the test crashed during setup - # In 'invalid query' tests, _pairs may never get set - if hasattr(self, '_pairs'): - _clean_channel_server_pairs(self._pairs) + _clean_channel_server_pairs(self._pairs) def test_get_top_channels_basic(self): self._pairs = _generate_channel_server_pairs(1) From c9309562897a0916837e433fe2b6bb6ad166b084 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 29 Nov 2018 14:25:23 -0800 Subject: [PATCH 0361/2143] 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 470ea1784329ec5637b41455a8dbd2ea2b811b58 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 29 Nov 2018 15:57:53 -0800 Subject: [PATCH 0362/2143] Debugging unimplemented error in CheckClientInitialMetadata --- CMakeLists.txt | 14 ++++++ Makefile | 48 +++++++++++++------ build.yaml | 2 + grpc.gyp | 2 + src/proto/grpc/testing/BUILD | 9 +++- src/proto/grpc/testing/echo.proto | 4 ++ src/proto/grpc/testing/simple_messages.proto | 26 ++++++++++ test/cpp/end2end/BUILD | 1 + .../end2end/client_callback_end2end_test.cc | 34 +++++++++++++ test/cpp/end2end/test_service_impl.cc | 29 +++++++++++ test/cpp/end2end/test_service_impl.h | 7 +++ .../generated/sources_and_headers.json | 6 +++ 12 files changed, 166 insertions(+), 16 deletions(-) create mode 100644 src/proto/grpc/testing/simple_messages.proto diff --git a/CMakeLists.txt b/CMakeLists.txt index 23b4bb77e75..1194d0072e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4020,6 +4020,10 @@ add_library(grpc++_test_util ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h test/cpp/end2end/test_service_impl.cc test/cpp/util/byte_buffer_proto_helper.cc test/cpp/util/channel_trace_proto_helper.cc @@ -4056,6 +4060,9 @@ protobuf_generate_grpc_cpp( protobuf_generate_grpc_cpp( src/proto/grpc/testing/duplicate/echo_duplicate.proto ) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/simple_messages.proto +) target_include_directories(grpc++_test_util PUBLIC $ $ @@ -4213,6 +4220,10 @@ add_library(grpc++_test_util_unsecure ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h test/cpp/end2end/test_service_impl.cc test/cpp/util/byte_buffer_proto_helper.cc test/cpp/util/string_ref_helper.cc @@ -4243,6 +4254,9 @@ protobuf_generate_grpc_cpp( protobuf_generate_grpc_cpp( src/proto/grpc/testing/duplicate/echo_duplicate.proto ) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/simple_messages.proto +) target_include_directories(grpc++_test_util_unsecure PUBLIC $ $ diff --git a/Makefile b/Makefile index 4f7cd130120..7dfce79c922 100644 --- a/Makefile +++ b/Makefile @@ -2743,12 +2743,12 @@ $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: protoc_dep_error else -$(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc +$(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $< -$(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: src/proto/grpc/testing/echo.proto $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc +$(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: src/proto/grpc/testing/echo.proto $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" $(Q) mkdir -p `dirname $@` $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=generate_mock_code=true:$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $< @@ -2850,6 +2850,22 @@ $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc: src/pro $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $< endif +ifeq ($(NO_PROTOC),true) +$(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc: protoc_dep_error +$(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc: protoc_dep_error +else + +$(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc: src/proto/grpc/testing/simple_messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[PROTOC] Generating protobuf CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $< + +$(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc: src/proto/grpc/testing/simple_messages.proto $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $< +endif + ifeq ($(NO_PROTOC),true) $(GENDIR)/src/proto/grpc/testing/stats.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc: protoc_dep_error @@ -6422,6 +6438,7 @@ LIBGRPC++_TEST_UTIL_SRC = \ $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc \ + $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc \ test/cpp/end2end/test_service_impl.cc \ test/cpp/util/byte_buffer_proto_helper.cc \ test/cpp/util/channel_trace_proto_helper.cc \ @@ -6574,14 +6591,14 @@ ifneq ($(NO_DEPS),true) -include $(LIBGRPC++_TEST_UTIL_OBJS:.o=.dep) endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/channel_trace_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/test_credentials_provider.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/channel_trace_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/test_credentials_provider.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc LIBGRPC++_TEST_UTIL_UNSECURE_SRC = \ @@ -6589,6 +6606,7 @@ LIBGRPC++_TEST_UTIL_UNSECURE_SRC = \ $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc \ + $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc \ test/cpp/end2end/test_service_impl.cc \ test/cpp/util/byte_buffer_proto_helper.cc \ test/cpp/util/string_ref_helper.cc \ @@ -6738,11 +6756,11 @@ ifneq ($(NO_DEPS),true) -include $(LIBGRPC++_TEST_UTIL_UNSECURE_OBJS:.o=.dep) endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc LIBGRPC++_UNSECURE_SRC = \ diff --git a/build.yaml b/build.yaml index 381e649b392..41c63d133a9 100644 --- a/build.yaml +++ b/build.yaml @@ -1767,6 +1767,7 @@ libs: - src/proto/grpc/testing/echo_messages.proto - src/proto/grpc/testing/echo.proto - src/proto/grpc/testing/duplicate/echo_duplicate.proto + - src/proto/grpc/testing/simple_messages.proto - test/cpp/end2end/test_service_impl.cc - test/cpp/util/byte_buffer_proto_helper.cc - test/cpp/util/channel_trace_proto_helper.cc @@ -1796,6 +1797,7 @@ libs: - src/proto/grpc/testing/echo_messages.proto - src/proto/grpc/testing/echo.proto - src/proto/grpc/testing/duplicate/echo_duplicate.proto + - src/proto/grpc/testing/simple_messages.proto - test/cpp/end2end/test_service_impl.cc - test/cpp/util/byte_buffer_proto_helper.cc - test/cpp/util/string_ref_helper.cc diff --git a/grpc.gyp b/grpc.gyp index 136867378f6..2b841354baf 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1497,6 +1497,7 @@ 'src/proto/grpc/testing/echo_messages.proto', 'src/proto/grpc/testing/echo.proto', 'src/proto/grpc/testing/duplicate/echo_duplicate.proto', + 'src/proto/grpc/testing/simple_messages.proto', 'test/cpp/end2end/test_service_impl.cc', 'test/cpp/util/byte_buffer_proto_helper.cc', 'test/cpp/util/channel_trace_proto_helper.cc', @@ -1520,6 +1521,7 @@ 'src/proto/grpc/testing/echo_messages.proto', 'src/proto/grpc/testing/echo.proto', 'src/proto/grpc/testing/duplicate/echo_duplicate.proto', + 'src/proto/grpc/testing/simple_messages.proto', 'test/cpp/end2end/test_service_impl.cc', 'test/cpp/util/byte_buffer_proto_helper.cc', 'test/cpp/util/string_ref_helper.cc', diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD index 7048911b9ae..9876d5160a1 100644 --- a/src/proto/grpc/testing/BUILD +++ b/src/proto/grpc/testing/BUILD @@ -50,7 +50,8 @@ grpc_proto_library( grpc_proto_library( name = "echo_proto", srcs = ["echo.proto"], - deps = ["echo_messages_proto"], + deps = ["echo_messages_proto", + "simple_messages_proto"], generate_mocks = True, ) @@ -119,6 +120,12 @@ grpc_proto_library( ], ) +grpc_proto_library( + name = "simple_messages_proto", + srcs = ["simple_messages.proto"], + has_services = False, +) + grpc_proto_library( name = "stats_proto", srcs = ["stats.proto"], diff --git a/src/proto/grpc/testing/echo.proto b/src/proto/grpc/testing/echo.proto index 13e28320fc9..977858f6bc5 100644 --- a/src/proto/grpc/testing/echo.proto +++ b/src/proto/grpc/testing/echo.proto @@ -16,11 +16,15 @@ syntax = "proto3"; import "src/proto/grpc/testing/echo_messages.proto"; +import "src/proto/grpc/testing/simple_messages.proto"; package grpc.testing; service EchoTestService { rpc Echo(EchoRequest) returns (EchoResponse); + // A service which checks that the initial metadata sent over contains some + // expected key value pair + rpc CheckClientInitialMetadata(SimpleRequest) returns (SimpleResponse); rpc RequestStream(stream EchoRequest) returns (EchoResponse); rpc ResponseStream(EchoRequest) returns (stream EchoResponse); rpc BidiStream(stream EchoRequest) returns (stream EchoResponse); diff --git a/src/proto/grpc/testing/simple_messages.proto b/src/proto/grpc/testing/simple_messages.proto new file mode 100644 index 00000000000..8bb334ac278 --- /dev/null +++ b/src/proto/grpc/testing/simple_messages.proto @@ -0,0 +1,26 @@ + +// 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. + +syntax = "proto3"; + +package grpc.testing; + +message SimpleRequest { + string message = 1; +} + +message SimpleResponse { + string message = 1; +} diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 4e3d841db01..446804401a7 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -124,6 +124,7 @@ grpc_cc_test( "//:grpc", "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:simple_messages_proto", "//src/proto/grpc/testing:echo_proto", "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index a35991396ad..e25a6689e5a 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -201,6 +201,40 @@ TEST_P(ClientCallbackEnd2endTest, SequentialRpcs) { SendRpcs(10, false); } +TEST_P(ClientCallbackEnd2endTest, SendClientInitialMetadata) { + ResetStub(); + SimpleRequest request; + SimpleResponse response; + ClientContext cli_ctx; + + cli_ctx.AddMetadata(kCheckClientInitialMetadataKey, + kCheckClientInitialMetadataVal); + + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub_->experimental_async()->CheckClientInitialMetadata( + &cli_ctx, &request, &response, [&done, &mu, &cv](Status s) { + std::cout << s.error_code() << std::endl; + gpr_log(GPR_ERROR, s.error_message().c_str()); + gpr_log(GPR_ERROR, s.error_details().c_str()); + GPR_ASSERT(s.ok()); + std::lock_guard l(mu); + + done = true; + cv.notify_one(); + }); + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } +} + +TEST_P(ClientCallbackEnd2endTest, SimpleRpcWithBinaryMetadata) { + ResetStub(); + SendRpcs(1, true); +} + TEST_P(ClientCallbackEnd2endTest, SequentialRpcsWithVariedBinaryMetadataValue) { ResetStub(); SendRpcs(10, true); diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 605356724fb..a7be8a798ac 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -69,6 +69,22 @@ void CheckServerAuthContext( EXPECT_EQ(expected_client_identity, identity[0]); } } + +// Returns the number of pairs in metadata that exactly match the given +// key-value pair. Returns -1 if the pair wasn't found. +int MetadataMatchCount( + const std::multimap& metadata, + const grpc::string& key, const grpc::string& value) { + int count = 0; + for (std::multimap::const_iterator iter = + metadata.begin(); + iter != metadata.end(); ++iter) { + if (ToString(iter->first) == key && ToString(iter->second) == value) { + count++; + } + } + return count; +} } // namespace Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, @@ -165,6 +181,19 @@ Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, return Status::OK; } +void CallbackTestServiceImpl::CheckClientInitialMetadata( + ServerContext* context, const SimpleRequest* request, + SimpleResponse* response, + experimental::ServerCallbackRpcController* controller) { + EXPECT_EQ(MetadataMatchCount(context->client_metadata(), + kCheckClientInitialMetadataKey, + kCheckClientInitialMetadataVal), + 1); + EXPECT_EQ(1u, + context->client_metadata().count(kCheckClientInitialMetadataKey)); + controller->Finish(Status::OK); +} + void CallbackTestServiceImpl::Echo( ServerContext* context, const EchoRequest* request, EchoResponse* response, experimental::ServerCallbackRpcController* controller) { diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h index ddfe94487e8..124d5e512b6 100644 --- a/test/cpp/end2end/test_service_impl.h +++ b/test/cpp/end2end/test_service_impl.h @@ -36,6 +36,8 @@ const char* const kServerTryCancelRequest = "server_try_cancel"; const char* const kDebugInfoTrailerKey = "debug-info-bin"; const char* const kServerFinishAfterNReads = "server_finish_after_n_reads"; const char* const kServerUseCoalescingApi = "server_use_coalescing_api"; +const char* const kCheckClientInitialMetadataKey = "custom_client_metadata"; +const char* const kCheckClientInitialMetadataVal = "Value for client metadata"; typedef enum { DO_NOT_CANCEL = 0, @@ -95,6 +97,11 @@ class CallbackTestServiceImpl EchoResponse* response, experimental::ServerCallbackRpcController* controller) override; + void CheckClientInitialMetadata( + ServerContext* context, const SimpleRequest* request, + SimpleResponse* response, + experimental::ServerCallbackRpcController* controller) override; + // Unimplemented is left unimplemented to test the returned error. bool signal_client() { std::unique_lock lock(mu_); diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 4d9bbb0f09e..d4d5d14f079 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -7444,6 +7444,9 @@ "src/proto/grpc/testing/echo_messages.pb.h", "src/proto/grpc/testing/echo_messages_mock.grpc.pb.h", "src/proto/grpc/testing/echo_mock.grpc.pb.h", + "src/proto/grpc/testing/simple_messages.grpc.pb.h", + "src/proto/grpc/testing/simple_messages.pb.h", + "src/proto/grpc/testing/simple_messages_mock.grpc.pb.h", "test/cpp/end2end/test_service_impl.h", "test/cpp/util/byte_buffer_proto_helper.h", "test/cpp/util/channel_trace_proto_helper.h", @@ -7497,6 +7500,9 @@ "src/proto/grpc/testing/echo_messages.pb.h", "src/proto/grpc/testing/echo_messages_mock.grpc.pb.h", "src/proto/grpc/testing/echo_mock.grpc.pb.h", + "src/proto/grpc/testing/simple_messages.grpc.pb.h", + "src/proto/grpc/testing/simple_messages.pb.h", + "src/proto/grpc/testing/simple_messages_mock.grpc.pb.h", "test/cpp/end2end/test_service_impl.h", "test/cpp/util/byte_buffer_proto_helper.h", "test/cpp/util/string_ref_helper.h", From de0249ecaf362ed04f1351c57a7c7be9be79bdf8 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 29 Nov 2018 16:08:52 -0800 Subject: [PATCH 0363/2143] Fallback instead of failing for cases where are not able to set the socket options --- src/core/lib/iomgr/tcp_posix.cc | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 606bfce6e73..6f66551a7ee 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -589,7 +589,7 @@ ssize_t tcp_send(int fd, const struct msghdr* msg) { */ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, - ssize_t* sent_length, grpc_error** error); + ssize_t* sent_length); /** The callback function to be invoked when we get an error on the socket. */ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error); @@ -597,13 +597,11 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error); #ifdef GRPC_LINUX_ERRQUEUE static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, - ssize_t* sent_length, - grpc_error** error) { + ssize_t* sent_length) { if (!tcp->socket_ts_enabled) { uint32_t opt = grpc_core::kTimestampingSocketOptions; if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING, static_cast(&opt), sizeof(opt)) != 0) { - *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "setsockopt"), tcp); grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_ERROR, "Failed to set timestamping options on the socket."); @@ -781,8 +779,7 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { #else /* GRPC_LINUX_ERRQUEUE */ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, - ssize_t* sent_length, - grpc_error** error) { + ssize_t* sent_length) { gpr_log(GPR_ERROR, "Write with timestamps not supported for this platform"); GPR_ASSERT(0); return false; @@ -801,7 +798,7 @@ void tcp_shutdown_buffer_list(grpc_tcp* tcp) { 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")); + GRPC_ERROR_CREATE_FROM_STATIC_STRING("TracedBuffer list shutdown")); gpr_mu_unlock(&tcp->tb_mu); tcp->outgoing_buffer_arg = nullptr; } @@ -852,13 +849,17 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { msg.msg_iov = iov; msg.msg_iovlen = iov_size; msg.msg_flags = 0; + bool tried_sending_message = false; if (tcp->outgoing_buffer_arg != nullptr) { - if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length, - error)) { + if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length)) { + /* We could not set socket options to collect Fathom timestamps. + * Fallback on writing without timestamps. */ tcp_shutdown_buffer_list(tcp); - return true; /* something went wrong with timestamps */ + } else { + tried_sending_message = true; } - } else { + } + if (!tried_sending_message) { msg.msg_control = nullptr; msg.msg_controllen = 0; From 606be620d8230f43cfeafb858aa7521db7ac954c Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 29 Nov 2018 16:13:34 -0800 Subject: [PATCH 0364/2143] 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 95f71d8d7fb25c4ca948b0ac58f00c565c95e27e Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 29 Nov 2018 17:36:00 -0800 Subject: [PATCH 0365/2143] Cache result of failing to set timestamping options --- src/core/lib/iomgr/tcp_posix.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 6f66551a7ee..90827033bd1 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -126,6 +126,7 @@ struct grpc_tcp { int bytes_counter; 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 */ @@ -851,9 +852,11 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { msg.msg_flags = 0; bool tried_sending_message = false; if (tcp->outgoing_buffer_arg != nullptr) { - if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length)) { + if (!tcp->ts_capable || + !tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length)) { /* We could not set socket options to collect Fathom timestamps. * Fallback on writing without timestamps. */ + tcp->ts_capable = false; tcp_shutdown_buffer_list(tcp); } else { tried_sending_message = true; @@ -1115,6 +1118,7 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->is_first_read = true; tcp->bytes_counter = -1; tcp->socket_ts_enabled = false; + tcp->ts_capable = true; tcp->outgoing_buffer_arg = nullptr; /* paired with unref in grpc_tcp_destroy */ gpr_ref_init(&tcp->refcount, 1); From 19bc2c2937b4bd5e77757e6cc157e6345f63df65 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 26 Nov 2018 11:13:24 +0100 Subject: [PATCH 0366/2143] switch C# docker images to debian stretch --- .../tools/dockerfile/csharp_deps.include | 23 +++++----------- .../dockerfile/csharp_dotnetcli_deps.include | 26 ++++++++++++------- .../grpc_interop_csharp/Dockerfile.template | 2 +- .../Dockerfile.template | 2 +- .../Dockerfile.template | 4 +-- tools/run_tests/run_tests.py | 2 +- 6 files changed, 29 insertions(+), 30 deletions(-) rename templates/tools/dockerfile/test/{csharp_jessie_x64 => csharp_stretch_x64}/Dockerfile.template (94%) diff --git a/templates/tools/dockerfile/csharp_deps.include b/templates/tools/dockerfile/csharp_deps.include index 7ed00748670..fdede9e840b 100644 --- a/templates/tools/dockerfile/csharp_deps.include +++ b/templates/tools/dockerfile/csharp_deps.include @@ -1,24 +1,15 @@ #================ # C# dependencies -# Update to a newer version of mono -RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF -RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list +# cmake >=3.6 needed to build grpc_csharp_ext +RUN apt-get update && apt-get install -y cmake && apt-get clean -# Install dependencies -RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y ${'\\'} +# Install mono +RUN apt-get update && apt-get install -y apt-transport-https dirmngr && apt-get clean +RUN apt-key adv --no-tty --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF +RUN echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list +RUN apt-get update && apt-get install -y ${'\\'} mono-devel ${'\\'} ca-certificates-mono ${'\\'} nuget ${'\\'} && apt-get clean - -RUN nuget update -self - -#================= -# Use cmake 3.6 from jessie-backports -# needed to build grpc_csharp_ext with cmake - -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean diff --git a/templates/tools/dockerfile/csharp_dotnetcli_deps.include b/templates/tools/dockerfile/csharp_dotnetcli_deps.include index bc88d2bfa39..f3335926402 100644 --- a/templates/tools/dockerfile/csharp_dotnetcli_deps.include +++ b/templates/tools/dockerfile/csharp_dotnetcli_deps.include @@ -1,12 +1,20 @@ -# Install dotnet SDK based on https://www.microsoft.com/net/core#debian -RUN apt-get update && apt-get install -y curl libunwind8 gettext -# dotnet-dev-1.0.0-preview2-003131 -RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530 -RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet -# dotnet-dev-1.0.1 -RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 -RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet -RUN ln -s /opt/dotnet/dotnet /usr/local/bin +# Install dotnet SDK +ENV DOTNET_SDK_VERSION 2.1.500 +RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$DOTNET_SDK_VERSION/dotnet-sdk-$DOTNET_SDK_VERSION-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 + + +# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1) +RUN curl -sSL -o dotnet_old.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/1.1.10/dotnet-debian.9-x64.1.1.10.tar.gz ${'\\'} + && mkdir -p dotnet_old ${'\\'} + && tar zxf dotnet_old.tar.gz -C dotnet_old ${'\\'} + && cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ ${'\\'} + && rm -rf dotnet_old/ dotnet_old.tar.gz +RUN apt-get update && apt-get install -y libunwind8 && apt-get clean + # Trigger the population of the local package cache ENV NUGET_XMLDOC_MODE skip diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template index a1f1283de0f..abf1a3853d3 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + FROM debian:stretch <%include file="../../apt_get_basic.include"/> <%include file="../../python_deps.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template index a1f1283de0f..abf1a3853d3 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + FROM debian:stretch <%include file="../../apt_get_basic.include"/> <%include file="../../python_deps.include"/> diff --git a/templates/tools/dockerfile/test/csharp_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/csharp_stretch_x64/Dockerfile.template similarity index 94% rename from templates/tools/dockerfile/test/csharp_jessie_x64/Dockerfile.template rename to templates/tools/dockerfile/test/csharp_stretch_x64/Dockerfile.template index 432f05442c2..1526d07fc63 100644 --- a/templates/tools/dockerfile/test/csharp_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/csharp_stretch_x64/Dockerfile.template @@ -1,6 +1,6 @@ %YAML 1.2 --- | - # Copyright 2015 gRPC authors. + # 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. @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + FROM debian:stretch <%include file="../../apt_get_basic.include"/> <%include file="../../gcp_api_libraries.include"/> diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index f71be2a65e9..1f756f3c919 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -942,7 +942,7 @@ class CSharpLanguage(object): self._cmake_arch_option = 'x64' else: _check_compiler(self.args.compiler, ['default', 'coreclr']) - self._docker_distro = 'jessie' + self._docker_distro = 'stretch' def test_specs(self): with open('src/csharp/tests.json') as f: From 556a993ef023ee4554f39323b4b6ddbb7701a8d4 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 26 Nov 2018 11:17:56 +0100 Subject: [PATCH 0367/2143] delete csharp_jessie_x64 dockerfile --- .../test/csharp_jessie_x64/Dockerfile | 118 ------------------ 1 file changed, 118 deletions(-) delete mode 100644 tools/dockerfile/test/csharp_jessie_x64/Dockerfile diff --git a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile b/tools/dockerfile/test/csharp_jessie_x64/Dockerfile deleted file mode 100644 index 030d301a40c..00000000000 --- a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile +++ /dev/null @@ -1,118 +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 - -#================ -# C# dependencies - -# Update to a newer version of mono -RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF -RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list - -# Install dependencies -RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ - mono-devel \ - ca-certificates-mono \ - nuget \ - && apt-get clean - -RUN nuget update -self - -#================= -# Use cmake 3.6 from jessie-backports -# needed to build grpc_csharp_ext with cmake - -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean - -# Install dotnet SDK based on https://www.microsoft.com/net/core#debian -RUN apt-get update && apt-get install -y curl libunwind8 gettext -# dotnet-dev-1.0.0-preview2-003131 -RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530 -RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet -# dotnet-dev-1.0.1 -RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 -RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet -RUN ln -s /opt/dotnet/dotnet /usr/local/bin - -# Trigger the population of the local package cache -ENV NUGET_XMLDOC_MODE skip -RUN mkdir warmup \ - && cd warmup \ - && dotnet new \ - && cd .. \ - && rm -rf warmup - - -RUN mkdir /var/local/jenkins - -# Define the default command. -CMD ["bash"] From 8f9dd2a24c11f248a37567c377f8702ee1b09d97 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 26 Nov 2018 12:08:23 +0100 Subject: [PATCH 0368/2143] regenerate dockerfiles --- .../grpc_interop_csharp/Dockerfile | 45 ++++--- .../grpc_interop_csharpcoreclr/Dockerfile | 45 ++++--- .../test/csharp_stretch_x64/Dockerfile | 117 ++++++++++++++++++ 3 files changed, 161 insertions(+), 46 deletions(-) create mode 100644 tools/dockerfile/test/csharp_stretch_x64/Dockerfile diff --git a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile index b2216c79d4c..b49fa104105 100644 --- a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM debian:jessie +FROM debian:stretch # Install Git and basic packages. RUN apt-get update && apt-get install -y \ @@ -67,37 +67,36 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t #================ # C# dependencies -# Update to a newer version of mono -RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF -RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list +# cmake >=3.6 needed to build grpc_csharp_ext +RUN apt-get update && apt-get install -y cmake && apt-get clean -# Install dependencies -RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ +# Install mono +RUN apt-get update && apt-get install -y apt-transport-https dirmngr && apt-get clean +RUN apt-key adv --no-tty --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF +RUN echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list +RUN apt-get update && apt-get install -y \ mono-devel \ ca-certificates-mono \ nuget \ && apt-get clean -RUN nuget update -self +# Install dotnet SDK +ENV DOTNET_SDK_VERSION 2.1.500 +RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$DOTNET_SDK_VERSION/dotnet-sdk-$DOTNET_SDK_VERSION-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 -#================= -# Use cmake 3.6 from jessie-backports -# needed to build grpc_csharp_ext with cmake -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean +# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1) +RUN curl -sSL -o dotnet_old.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/1.1.10/dotnet-debian.9-x64.1.1.10.tar.gz \ + && mkdir -p dotnet_old \ + && tar zxf dotnet_old.tar.gz -C dotnet_old \ + && cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ \ + && rm -rf dotnet_old/ dotnet_old.tar.gz +RUN apt-get update && apt-get install -y libunwind8 && apt-get clean -# Install dotnet SDK based on https://www.microsoft.com/net/core#debian -RUN apt-get update && apt-get install -y curl libunwind8 gettext -# dotnet-dev-1.0.0-preview2-003131 -RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530 -RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet -# dotnet-dev-1.0.1 -RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 -RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet -RUN ln -s /opt/dotnet/dotnet /usr/local/bin # Trigger the population of the local package cache ENV NUGET_XMLDOC_MODE skip diff --git a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile index b2216c79d4c..b49fa104105 100644 --- a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM debian:jessie +FROM debian:stretch # Install Git and basic packages. RUN apt-get update && apt-get install -y \ @@ -67,37 +67,36 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t #================ # C# dependencies -# Update to a newer version of mono -RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF -RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list +# cmake >=3.6 needed to build grpc_csharp_ext +RUN apt-get update && apt-get install -y cmake && apt-get clean -# Install dependencies -RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ +# Install mono +RUN apt-get update && apt-get install -y apt-transport-https dirmngr && apt-get clean +RUN apt-key adv --no-tty --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF +RUN echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list +RUN apt-get update && apt-get install -y \ mono-devel \ ca-certificates-mono \ nuget \ && apt-get clean -RUN nuget update -self +# Install dotnet SDK +ENV DOTNET_SDK_VERSION 2.1.500 +RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$DOTNET_SDK_VERSION/dotnet-sdk-$DOTNET_SDK_VERSION-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 -#================= -# Use cmake 3.6 from jessie-backports -# needed to build grpc_csharp_ext with cmake -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean +# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1) +RUN curl -sSL -o dotnet_old.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/1.1.10/dotnet-debian.9-x64.1.1.10.tar.gz \ + && mkdir -p dotnet_old \ + && tar zxf dotnet_old.tar.gz -C dotnet_old \ + && cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ \ + && rm -rf dotnet_old/ dotnet_old.tar.gz +RUN apt-get update && apt-get install -y libunwind8 && apt-get clean -# Install dotnet SDK based on https://www.microsoft.com/net/core#debian -RUN apt-get update && apt-get install -y curl libunwind8 gettext -# dotnet-dev-1.0.0-preview2-003131 -RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530 -RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet -# dotnet-dev-1.0.1 -RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 -RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet -RUN ln -s /opt/dotnet/dotnet /usr/local/bin # Trigger the population of the local package cache ENV NUGET_XMLDOC_MODE skip diff --git a/tools/dockerfile/test/csharp_stretch_x64/Dockerfile b/tools/dockerfile/test/csharp_stretch_x64/Dockerfile new file mode 100644 index 00000000000..04d25842094 --- /dev/null +++ b/tools/dockerfile/test/csharp_stretch_x64/Dockerfile @@ -0,0 +1,117 @@ +# 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. + +FROM debian:stretch + +# 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 + +#================ +# C# dependencies + +# cmake >=3.6 needed to build grpc_csharp_ext +RUN apt-get update && apt-get install -y cmake && apt-get clean + +# Install mono +RUN apt-get update && apt-get install -y apt-transport-https dirmngr && apt-get clean +RUN apt-key adv --no-tty --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF +RUN echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list +RUN apt-get update && apt-get install -y \ + mono-devel \ + ca-certificates-mono \ + nuget \ + && apt-get clean + +# Install dotnet SDK +ENV DOTNET_SDK_VERSION 2.1.500 +RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$DOTNET_SDK_VERSION/dotnet-sdk-$DOTNET_SDK_VERSION-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 + + +# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1) +RUN curl -sSL -o dotnet_old.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/1.1.10/dotnet-debian.9-x64.1.1.10.tar.gz \ + && mkdir -p dotnet_old \ + && tar zxf dotnet_old.tar.gz -C dotnet_old \ + && cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ \ + && rm -rf dotnet_old/ dotnet_old.tar.gz +RUN apt-get update && apt-get install -y libunwind8 && apt-get clean + + +# Trigger the population of the local package cache +ENV NUGET_XMLDOC_MODE skip +RUN mkdir warmup \ + && cd warmup \ + && dotnet new \ + && cd .. \ + && rm -rf warmup + + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] From ba6b1c215c7249205496d73fcbba94ef111baa29 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 27 Nov 2018 17:58:51 +0100 Subject: [PATCH 0369/2143] switch netcoreapp1.0->1.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 +- .../Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj | 2 +- .../Grpc.IntegrationTesting.Client.csproj | 2 +- .../Grpc.IntegrationTesting.QpsWorker.csproj | 2 +- .../Grpc.IntegrationTesting.Server.csproj | 4 ++-- .../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, 15 insertions(+), 15 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index d58f0468244..178931a3d72 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.0 + net45;netcoreapp1.1 Grpc.Core.Tests Exe Grpc.Core.Tests diff --git a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj index db4e3ef4e3f..1afcd9fba0c 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.0 + net45;netcoreapp1.1 Grpc.Examples.MathClient Exe Grpc.Examples.MathClient diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj index b12b418d015..75ef6d1008b 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.0 + net45;netcoreapp1.1 Grpc.Examples.MathServer Exe Grpc.Examples.MathServer diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj index 7493eb8051d..93d112a0c53 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.0 + net45;netcoreapp1.1 Grpc.Examples.Tests Exe Grpc.Examples.Tests diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj index baa3b4ce6c1..9ce2b59d036 100755 --- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj +++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.0 + 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 616e56df105..2a037a72e51 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.0 + net45;netcoreapp1.1 Grpc.HealthCheck.Tests Exe Grpc.HealthCheck.Tests diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj index 35713156ea2..1cd4b83e1ed 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.0 + net45;netcoreapp1.1 Grpc.IntegrationTesting.Client Exe Grpc.IntegrationTesting.Client diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj index 3ecefe3bc4f..2890a7df588 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.0 + net45;netcoreapp1.1 Grpc.IntegrationTesting.QpsWorker Exe Grpc.IntegrationTesting.QpsWorker diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj index 1092b2c21ef..ee718958bcf 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.0 + net45;netcoreapp1.1 Grpc.IntegrationTesting.Server Exe Grpc.IntegrationTesting.Server @@ -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 22272547f61..99926497e4e 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.0 + net45;netcoreapp1.1 Grpc.IntegrationTesting.StressClient Exe Grpc.IntegrationTesting.StressClient diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index 8daf3fa98bb..c342f8a107c 100755 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.0 + net45;netcoreapp1.1 Grpc.IntegrationTesting Exe Grpc.IntegrationTesting diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index d39d46cf1b0..5b1656080ae 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.0 + net45;netcoreapp1.1 Grpc.Microbenchmarks Exe Grpc.Microbenchmarks diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj index 0c12f38f25a..8b586c6ecb7 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.0 + net45;netcoreapp1.1 Grpc.Reflection.Tests Exe Grpc.Reflection.Tests diff --git a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj index a2d4874eece..cfb40f44ae1 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.0 + net45;netcoreapp1.1 Exe From 2e54a2bc363294d879d435c9b22f02808d371875 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 27 Nov 2018 18:07:33 +0100 Subject: [PATCH 0370/2143] update compiler defines --- src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs | 2 +- src/csharp/Grpc.Core.Tests/NUnitMain.cs | 2 +- src/csharp/Grpc.Core.Tests/SanityTest.cs | 4 ++-- src/csharp/Grpc.Core/Internal/NativeExtension.cs | 4 ++-- src/csharp/Grpc.Examples.Tests/NUnitMain.cs | 2 +- src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs | 2 +- src/csharp/Grpc.IntegrationTesting/NUnitMain.cs | 2 +- src/csharp/Grpc.Reflection.Tests/NUnitMain.cs | 2 +- src/csharp/Grpc.Tools.Tests/NUnitMain.cs | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs index 3a161763fd0..b10d7a10451 100644 --- a/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs +++ b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs @@ -25,7 +25,7 @@ namespace Grpc.Core.Tests { public class AppDomainUnloadTest { -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 || NETCOREAPP2_1 [Test] [Ignore("Not supported for CoreCLR")] public void AppDomainUnloadHookCanCleanupAbandonedCall() diff --git a/src/csharp/Grpc.Core.Tests/NUnitMain.cs b/src/csharp/Grpc.Core.Tests/NUnitMain.cs index 49cb8cd3b99..221a6b823a4 100644 --- a/src/csharp/Grpc.Core.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Core.Tests/NUnitMain.cs @@ -34,7 +34,7 @@ namespace Grpc.Core.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 || NETCOREAPP2_1 return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); #else return new AutoRun().Execute(args); diff --git a/src/csharp/Grpc.Core.Tests/SanityTest.cs b/src/csharp/Grpc.Core.Tests/SanityTest.cs index 0904453b6e9..f785f70f4ce 100644 --- a/src/csharp/Grpc.Core.Tests/SanityTest.cs +++ b/src/csharp/Grpc.Core.Tests/SanityTest.cs @@ -31,7 +31,7 @@ namespace Grpc.Core.Tests public class SanityTest { // TODO: make sanity test work for CoreCLR as well -#if !NETCOREAPP1_0 +#if !NETCOREAPP1_1 && !NETCOREAPP2_1 /// /// Because we depend on a native library, sometimes when things go wrong, the /// entire NUnit test process crashes. To be able to track down problems better, @@ -44,7 +44,7 @@ namespace Grpc.Core.Tests public void TestsJsonUpToDate() { var discoveredTests = DiscoverAllTestClasses(); - var testsFromFile + var testsFromFile = JsonConvert.DeserializeObject>>(ReadTestsJson()); Assert.AreEqual(discoveredTests, testsFromFile); diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs index f526b913af0..5177b69fd90 100644 --- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs +++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs @@ -83,13 +83,13 @@ namespace Grpc.Core.Internal // See https://github.com/grpc/grpc/pull/7303 for one option. var assemblyDirectory = Path.GetDirectoryName(GetAssemblyPath()); - // With old-style VS projects, the native libraries get copied using a .targets rule to the build output folder + // With "classic" VS projects, the native libraries get copied using a .targets rule to the build output folder // alongside the compiled assembly. // With dotnet cli projects targeting net45 framework, the native libraries (just the required ones) // are similarly copied to the built output folder, through the magic of Microsoft.NETCore.Platforms. var classicPath = Path.Combine(assemblyDirectory, GetNativeLibraryFilename()); - // With dotnet cli project targeting netcoreapp1.0, projects will use Grpc.Core assembly directly in the location where it got restored + // With dotnet cli project targeting netcoreappX.Y, projects will use Grpc.Core assembly directly in the location where it got restored // by nuget. We locate the native libraries based on known structure of Grpc.Core nuget package. // When "dotnet publish" is used, the runtimes directory is copied next to the published assemblies. string runtimesDirectory = string.Format("runtimes/{0}/native", GetPlatformString()); diff --git a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs index bcb8b46b644..0b9a5258ef4 100644 --- a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs @@ -34,7 +34,7 @@ namespace Grpc.Examples.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 || NETCOREAPP2_1 return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); #else return new AutoRun().Execute(args); diff --git a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs index 365551e8956..f5091863b84 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs @@ -34,7 +34,7 @@ namespace Grpc.HealthCheck.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 || NETCOREAPP2_1 return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); #else return new AutoRun().Execute(args); diff --git a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs index 9d24762e0ae..6265953622c 100644 --- a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs +++ b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs @@ -34,7 +34,7 @@ namespace Grpc.IntegrationTesting { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 || NETCOREAPP2_1 return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); #else return new AutoRun().Execute(args); diff --git a/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs b/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs index 49ed1cc8d44..1be7f6542b3 100644 --- a/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs @@ -34,7 +34,7 @@ namespace Grpc.Reflection.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 || NETCOREAPP2_1 return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); #else return new AutoRun().Execute(args); diff --git a/src/csharp/Grpc.Tools.Tests/NUnitMain.cs b/src/csharp/Grpc.Tools.Tests/NUnitMain.cs index 418c33820eb..13ba8b51d09 100644 --- a/src/csharp/Grpc.Tools.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Tools.Tests/NUnitMain.cs @@ -24,7 +24,7 @@ namespace Grpc.Tools.Tests static class NUnitMain { public static int Main(string[] args) => -#if NETCOREAPP1_0 || NETCOREAPP1_1 +#if NETCOREAPP1_1 || NETCOREAPP2_1 new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); #else new AutoRun().Execute(args); From 7b9e0db9be4a27e2030607c61fefde46c78aedf8 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 27 Nov 2018 18:10:56 +0100 Subject: [PATCH 0371/2143] update test exec scripts --- tools/run_tests/run_interop_tests.py | 4 ++-- tools/run_tests/run_tests.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 021f21dcd42..d026145d66f 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -141,8 +141,8 @@ class CSharpLanguage: class CSharpCoreCLRLanguage: def __init__(self): - self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0' - self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/netcoreapp1.0' + 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.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 1f756f3c919..a68e0d387ab 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -954,7 +954,7 @@ class CSharpLanguage(object): assembly_extension = '.exe' if self.args.compiler == 'coreclr': - assembly_subdir += '/netcoreapp1.0' + assembly_subdir += '/netcoreapp1.1' runtime_cmd = ['dotnet', 'exec'] assembly_extension = '.dll' else: From d7eb26648d33912199573b842557b0e92ec3071f Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Sun, 4 Nov 2018 23:37:00 -0800 Subject: [PATCH 0372/2143] Client callback streaming --- include/grpcpp/generic/generic_stub.h | 5 + include/grpcpp/impl/codegen/callback_common.h | 8 +- .../grpcpp/impl/codegen/channel_interface.h | 12 + include/grpcpp/impl/codegen/client_callback.h | 505 ++++++++++++++++++ include/grpcpp/impl/codegen/client_context.h | 12 + src/compiler/cpp_generator.cc | 84 ++- src/cpp/client/generic_stub.cc | 12 + test/cpp/codegen/compiler_test_golden | 7 + .../end2end/client_callback_end2end_test.cc | 228 ++++++++ 9 files changed, 860 insertions(+), 13 deletions(-) diff --git a/include/grpcpp/generic/generic_stub.h b/include/grpcpp/generic/generic_stub.h index d509d9a5206..ccbf8a0e55a 100644 --- a/include/grpcpp/generic/generic_stub.h +++ b/include/grpcpp/generic/generic_stub.h @@ -24,6 +24,7 @@ #include #include #include +#include #include namespace grpc { @@ -76,6 +77,10 @@ class GenericStub final { const ByteBuffer* request, ByteBuffer* response, std::function on_completion); + experimental::ClientCallbackReaderWriter* + PrepareBidiStreamingCall(ClientContext* context, const grpc::string& method, + experimental::ClientBidiReactor* reactor); + private: GenericStub* stub_; }; diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index 51367cf550c..f7a24204dc2 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -145,18 +145,19 @@ class CallbackWithSuccessTag // or on a tag that has been Set before unless the tag has been cleared. void Set(grpc_call* call, std::function f, CompletionQueueTag* ops) { + GPR_CODEGEN_ASSERT(call_ == nullptr); + g_core_codegen_interface->grpc_call_ref(call); call_ = call; func_ = std::move(f); ops_ = ops; - g_core_codegen_interface->grpc_call_ref(call); functor_run = &CallbackWithSuccessTag::StaticRun; } void Clear() { if (call_ != nullptr) { - func_ = nullptr; grpc_call* call = call_; call_ = nullptr; + func_ = nullptr; g_core_codegen_interface->grpc_call_unref(call); } } @@ -182,10 +183,9 @@ class CallbackWithSuccessTag } void Run(bool ok) { void* ignored = ops_; - bool new_ok = ok; // Allow a "false" return value from FinalizeResult to silence the // callback, just as it silences a CQ tag in the async cases - bool do_callback = ops_->FinalizeResult(&ignored, &new_ok); + bool do_callback = ops_->FinalizeResult(&ignored, &ok); GPR_CODEGEN_ASSERT(ignored == ops_); if (do_callback) { diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h index 6ec1ffb8c7d..728a7b90496 100644 --- a/include/grpcpp/impl/codegen/channel_interface.h +++ b/include/grpcpp/impl/codegen/channel_interface.h @@ -53,6 +53,12 @@ template class ClientAsyncReaderWriterFactory; template class ClientAsyncResponseReaderFactory; +template +class ClientCallbackReaderWriterFactory; +template +class ClientCallbackReaderFactory; +template +class ClientCallbackWriterFactory; class InterceptedChannel; } // namespace internal @@ -106,6 +112,12 @@ class ChannelInterface { friend class ::grpc::internal::ClientAsyncReaderWriterFactory; template friend class ::grpc::internal::ClientAsyncResponseReaderFactory; + template + friend class ::grpc::internal::ClientCallbackReaderWriterFactory; + template + friend class ::grpc::internal::ClientCallbackReaderFactory; + template + friend class ::grpc::internal::ClientCallbackWriterFactory; template friend class ::grpc::internal::BlockingUnaryCallImpl; template diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 4baa819091c..01a28a9e6fa 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -88,6 +89,510 @@ class CallbackUnaryCallImpl { call.PerformOps(ops); } }; +} // namespace internal + +namespace experimental { + +// 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 + +class ClientBidiReactor { + public: + virtual ~ClientBidiReactor() {} + virtual void OnDone(Status s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + virtual void OnReadDone(bool ok) {} + virtual void OnWriteDone(bool ok) {} + virtual void OnWritesDoneDone(bool ok) {} +}; + +class ClientReadReactor { + public: + virtual ~ClientReadReactor() {} + virtual void OnDone(Status s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + virtual void OnReadDone(bool ok) {} +}; + +class ClientWriteReactor { + public: + virtual ~ClientWriteReactor() {} + virtual void OnDone(Status s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + virtual void OnWriteDone(bool ok) {} + virtual void OnWritesDoneDone(bool ok) {} +}; + +template +class ClientCallbackReaderWriter { + public: + virtual ~ClientCallbackReaderWriter() {} + virtual void StartCall() = 0; + void Write(const Request* req) { Write(req, WriteOptions()); } + virtual void Write(const Request* req, WriteOptions options) = 0; + void WriteLast(const Request* req, WriteOptions options) { + Write(req, options.set_last_message()); + } + virtual void WritesDone() = 0; + virtual void Read(Response* resp) = 0; +}; + +template +class ClientCallbackReader { + public: + virtual ~ClientCallbackReader() {} + virtual void StartCall() = 0; + virtual void Read(Response* resp) = 0; +}; + +template +class ClientCallbackWriter { + public: + virtual ~ClientCallbackWriter() {} + virtual void StartCall() = 0; + void Write(const Request* req) { Write(req, WriteOptions()); } + virtual void Write(const Request* req, WriteOptions options) = 0; + void WriteLast(const Request* req, WriteOptions options) { + Write(req, options.set_last_message()); + } + virtual void WritesDone() = 0; +}; + +} // namespace experimental + +namespace internal { + +// Forward declare factory classes for friendship +template +class ClientCallbackReaderWriterFactory; +template +class ClientCallbackReaderFactory; +template +class ClientCallbackWriterFactory; + +template +class ClientCallbackReaderWriterImpl + : public ::grpc::experimental::ClientCallbackReaderWriter { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackReaderWriterImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void MaybeFinish() { + if (--callbacks_outstanding_ == 0) { + reactor_->OnDone(std::move(finish_status_)); + auto* call = call_.call(); + this->~ClientCallbackReaderWriterImpl(); + g_core_codegen_interface->grpc_call_unref(call); + } + } + + void StartCall() override { + // This call initiates two batches + // 1. Send initial metadata (unless corked)/recv initial metadata + // 2. Recv trailing metadata, on_completion callback + callbacks_outstanding_ = 2; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + start_corked_ = context_->initial_metadata_corked_; + if (!start_corked_) { + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + } + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_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_); + + // Also set up the read and write tags so that they don't have to be set up + // each time + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeFinish(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeFinish(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + } + + void Read(Response* msg) override { + read_ops_.RecvMessage(msg); + callbacks_outstanding_++; + call_.PerformOps(&read_ops_); + } + + void Write(const Request* msg, WriteOptions options) override { + if (start_corked_) { + write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*msg).ok()); + + if (options.is_last_message()) { + options.set_buffer_hint(); + write_ops_.ClientSendClose(); + } + callbacks_outstanding_++; + call_.PerformOps(&write_ops_); + } + void WritesDone() override { + if (start_corked_) { + writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + writes_done_ops_.ClientSendClose(); + writes_done_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWritesDoneDone(ok); + MaybeFinish(); + }, + &writes_done_ops_); + writes_done_ops_.set_core_cq_tag(&writes_done_tag_); + callbacks_outstanding_++; + call_.PerformOps(&writes_done_ops_); + } + + private: + friend class ClientCallbackReaderWriterFactory; + + ClientCallbackReaderWriterImpl( + Call call, ClientContext* context, + ::grpc::experimental::ClientBidiReactor* reactor) + : context_(context), call_(call), reactor_(reactor) {} + + ClientContext* context_; + Call call_; + ::grpc::experimental::ClientBidiReactor* reactor_; + + CallOpSet start_ops_; + CallbackWithSuccessTag start_tag_; + bool start_corked_; + + CallOpSet finish_ops_; + CallbackWithSuccessTag finish_tag_; + Status finish_status_; + + CallOpSet + write_ops_; + CallbackWithSuccessTag write_tag_; + + CallOpSet writes_done_ops_; + CallbackWithSuccessTag writes_done_tag_; + + CallOpSet> read_ops_; + CallbackWithSuccessTag read_tag_; + + std::atomic_int callbacks_outstanding_; +}; + +template +class ClientCallbackReaderWriterFactory { + public: + static experimental::ClientCallbackReaderWriter* Create( + ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, + ClientContext* context, + ::grpc::experimental::ClientBidiReactor* reactor) { + Call call = channel->CreateCall(method, context, channel->CallbackCQ()); + + g_core_codegen_interface->grpc_call_ref(call.call()); + return new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackReaderWriterImpl))) + ClientCallbackReaderWriterImpl(call, context, + reactor); + } +}; + +template +class ClientCallbackReaderImpl + : public ::grpc::experimental::ClientCallbackReader { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackReaderImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void MaybeFinish() { + if (--callbacks_outstanding_ == 0) { + reactor_->OnDone(std::move(finish_status_)); + auto* call = call_.call(); + this->~ClientCallbackReaderImpl(); + g_core_codegen_interface->grpc_call_unref(call); + } + } + + void StartCall() override { + // This call initiates two batches + // 1. Send initial metadata (unless corked)/recv initial metadata + // 2. Recv trailing metadata, on_completion callback + callbacks_outstanding_ = 2; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_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_); + + // Also set up the read tag so it doesn't have to be set up each time + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeFinish(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + } + + void Read(Response* msg) override { + read_ops_.RecvMessage(msg); + callbacks_outstanding_++; + call_.PerformOps(&read_ops_); + } + + private: + friend class ClientCallbackReaderFactory; + + template + ClientCallbackReaderImpl(Call call, ClientContext* context, Request* request, + ::grpc::experimental::ClientReadReactor* reactor) + : context_(context), call_(call), reactor_(reactor) { + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(start_ops_.SendMessage(*request).ok()); + start_ops_.ClientSendClose(); + } + + ClientContext* context_; + Call call_; + ::grpc::experimental::ClientReadReactor* reactor_; + + CallOpSet + start_ops_; + CallbackWithSuccessTag start_tag_; + + CallOpSet finish_ops_; + CallbackWithSuccessTag finish_tag_; + Status finish_status_; + + CallOpSet> read_ops_; + CallbackWithSuccessTag read_tag_; + + std::atomic_int callbacks_outstanding_; +}; + +template +class ClientCallbackReaderFactory { + public: + template + static experimental::ClientCallbackReader* Create( + ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, + ClientContext* context, const Request* request, + ::grpc::experimental::ClientReadReactor* reactor) { + Call call = channel->CreateCall(method, context, channel->CallbackCQ()); + + g_core_codegen_interface->grpc_call_ref(call.call()); + return new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackReaderImpl))) + ClientCallbackReaderImpl(call, context, request, reactor); + } +}; + +template +class ClientCallbackWriterImpl + : public ::grpc::experimental::ClientCallbackWriter { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackWriterImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void MaybeFinish() { + if (--callbacks_outstanding_ == 0) { + reactor_->OnDone(std::move(finish_status_)); + auto* call = call_.call(); + this->~ClientCallbackWriterImpl(); + g_core_codegen_interface->grpc_call_unref(call); + } + } + + void StartCall() override { + // This call initiates two batches + // 1. Send initial metadata (unless corked)/recv initial metadata + // 2. Recv message + trailing metadata, on_completion callback + callbacks_outstanding_ = 2; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + start_corked_ = context_->initial_metadata_corked_; + if (!start_corked_) { + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + } + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_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_); + + // Also set up the read and write tags so that they don't have to be set up + // each time + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeFinish(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + } + + void Write(const Request* msg, WriteOptions options) override { + if (start_corked_) { + write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*msg).ok()); + + if (options.is_last_message()) { + options.set_buffer_hint(); + write_ops_.ClientSendClose(); + } + callbacks_outstanding_++; + call_.PerformOps(&write_ops_); + } + void WritesDone() override { + if (start_corked_) { + writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + writes_done_ops_.ClientSendClose(); + writes_done_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWritesDoneDone(ok); + MaybeFinish(); + }, + &writes_done_ops_); + writes_done_ops_.set_core_cq_tag(&writes_done_tag_); + callbacks_outstanding_++; + call_.PerformOps(&writes_done_ops_); + } + + private: + friend class ClientCallbackWriterFactory; + + template + ClientCallbackWriterImpl(Call call, ClientContext* context, + Response* response, + ::grpc::experimental::ClientWriteReactor* reactor) + : context_(context), call_(call), reactor_(reactor) { + finish_ops_.RecvMessage(response); + finish_ops_.AllowNoMessage(); + } + + ClientContext* context_; + Call call_; + ::grpc::experimental::ClientWriteReactor* reactor_; + + CallOpSet start_ops_; + CallbackWithSuccessTag start_tag_; + bool start_corked_; + + CallOpSet finish_ops_; + CallbackWithSuccessTag finish_tag_; + Status finish_status_; + + CallOpSet + write_ops_; + CallbackWithSuccessTag write_tag_; + + CallOpSet writes_done_ops_; + CallbackWithSuccessTag writes_done_tag_; + + std::atomic_int callbacks_outstanding_; +}; + +template +class ClientCallbackWriterFactory { + public: + template + static experimental::ClientCallbackWriter* Create( + ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, + ClientContext* context, Response* response, + ::grpc::experimental::ClientWriteReactor* reactor) { + Call call = channel->CreateCall(method, context, channel->CallbackCQ()); + + g_core_codegen_interface->grpc_call_ref(call.call()); + return new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackWriterImpl))) + ClientCallbackWriterImpl(call, context, response, reactor); + } +}; } // namespace internal } // namespace grpc diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 75b955e7606..6059c3c58a4 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -71,6 +71,12 @@ template class BlockingUnaryCallImpl; template class CallbackUnaryCallImpl; +template +class ClientCallbackReaderWriterImpl; +template +class ClientCallbackReaderImpl; +template +class ClientCallbackWriterImpl; } // namespace internal template @@ -394,6 +400,12 @@ class ClientContext { friend class ::grpc::internal::BlockingUnaryCallImpl; template friend class ::grpc::internal::CallbackUnaryCallImpl; + template + friend class ::grpc::internal::ClientCallbackReaderWriterImpl; + template + friend class ::grpc::internal::ClientCallbackReaderImpl; + template + friend class ::grpc::internal::ClientCallbackWriterImpl; // Used by friend class CallOpClientRecvStatus void set_debug_error_string(const grpc::string& debug_error_string) { diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 7986aca6960..473e57166fa 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -132,6 +132,7 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, "grpcpp/impl/codegen/async_generic_service.h", "grpcpp/impl/codegen/async_stream.h", "grpcpp/impl/codegen/async_unary_call.h", + "grpcpp/impl/codegen/client_callback.h", "grpcpp/impl/codegen/method_handler_impl.h", "grpcpp/impl/codegen/proto_utils.h", "grpcpp/impl/codegen/rpc_method.h", @@ -580,11 +581,23 @@ void PrintHeaderClientMethodCallbackInterfaces( "const $Request$* request, $Response$* response, " "std::function) = 0;\n"); } else if (ClientOnlyStreaming(method)) { - // TODO(vjpai): Add support for client-side streaming + printer->Print(*vars, + "virtual ::grpc::experimental::ClientCallbackWriter< " + "$Request$>* $Method$(::grpc::ClientContext* context, " + "$Response$* response, " + "::grpc::experimental::ClientWriteReactor* reactor) = 0;\n"); } else if (ServerOnlyStreaming(method)) { - // TODO(vjpai): Add support for server-side streaming + printer->Print(*vars, + "virtual ::grpc::experimental::ClientCallbackReader< " + "$Response$>* $Method$(::grpc::ClientContext* context, " + "$Request$* request, " + "::grpc::experimental::ClientReadReactor* reactor) = 0;\n"); } else if (method->BidiStreaming()) { - // TODO(vjpai): Add support for bidi streaming + printer->Print( + *vars, + "virtual ::grpc::experimental::ClientCallbackReaderWriter< $Request$, " + "$Response$>* $Method$(::grpc::ClientContext* context, " + "::grpc::experimental::ClientBidiReactor* reactor) = 0;\n"); } } @@ -631,11 +644,26 @@ void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer, "const $Request$* request, $Response$* response, " "std::function) override;\n"); } else if (ClientOnlyStreaming(method)) { - // TODO(vjpai): Add support for client-side streaming + printer->Print( + *vars, + "::grpc::experimental::ClientCallbackWriter< $Request$>* " + "$Method$(::grpc::ClientContext* context, " + "$Response$* response, " + "::grpc::experimental::ClientWriteReactor* reactor) override;\n"); } else if (ServerOnlyStreaming(method)) { - // TODO(vjpai): Add support for server-side streaming + printer->Print( + *vars, + "::grpc::experimental::ClientCallbackReader< $Response$>* " + "$Method$(::grpc::ClientContext* context, " + "$Request$* request, " + "::grpc::experimental::ClientReadReactor* reactor) override;\n"); + } else if (method->BidiStreaming()) { - // TODO(vjpai): Add support for bidi streaming + printer->Print( + *vars, + "::grpc::experimental::ClientCallbackReaderWriter< $Request$, " + "$Response$>* $Method$(::grpc::ClientContext* context, " + "::grpc::experimental::ClientBidiReactor* reactor) override;\n"); } } @@ -1607,7 +1635,20 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "context, response);\n" "}\n\n"); - // TODO(vjpai): Add callback version + printer->Print( + *vars, + "::grpc::experimental::ClientCallbackWriter< $Request$>* " + "$ns$$Service$::" + "Stub::experimental_async::$Method$(::grpc::ClientContext* context, " + "$Response$* response, " + "::grpc::experimental::ClientWriteReactor* reactor) {\n"); + printer->Print(*vars, + " return ::grpc::internal::ClientCallbackWriterFactory< " + "$Request$>::Create(" + "stub_->channel_.get(), " + "stub_->rpcmethod_$Method$_, " + "context, response, reactor);\n" + "}\n\n"); for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; @@ -1641,7 +1682,19 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "context, request);\n" "}\n\n"); - // TODO(vjpai): Add callback version + printer->Print(*vars, + "::grpc::experimental::ClientCallbackReader< $Response$>* " + "$ns$$Service$::Stub::experimental_async::$Method$(::grpc::" + "ClientContext* context, " + "$Request$* request, " + "::grpc::experimental::ClientReadReactor* reactor) {\n"); + printer->Print(*vars, + " return ::grpc::internal::ClientCallbackReaderFactory< " + "$Response$>::Create(" + "stub_->channel_.get(), " + "stub_->rpcmethod_$Method$_, " + "context, request, reactor);\n" + "}\n\n"); for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; @@ -1675,7 +1728,20 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "context);\n" "}\n\n"); - // TODO(vjpai): Add callback version + printer->Print(*vars, + "::grpc::experimental::ClientCallbackReaderWriter< " + "$Request$,$Response$>* " + "$ns$$Service$::Stub::experimental_async::$Method$(::grpc::" + "ClientContext* context, " + "::grpc::experimental::ClientBidiReactor* reactor) {\n"); + printer->Print( + *vars, + " return ::grpc::internal::ClientCallbackReaderWriterFactory< " + "$Request$,$Response$>::Create(" + "stub_->channel_.get(), " + "stub_->rpcmethod_$Method$_, " + "context, reactor);\n" + "}\n\n"); for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc index 87902b26f0e..f029daec656 100644 --- a/src/cpp/client/generic_stub.cc +++ b/src/cpp/client/generic_stub.cc @@ -72,4 +72,16 @@ void GenericStub::experimental_type::UnaryCall( context, request, response, std::move(on_completion)); } +experimental::ClientCallbackReaderWriter* +GenericStub::experimental_type::PrepareBidiStreamingCall( + ClientContext* context, const grpc::string& method, + experimental::ClientBidiReactor* reactor) { + return internal::ClientCallbackReaderWriterFactory< + ByteBuffer, ByteBuffer>::Create(stub_->channel_.get(), + internal::RpcMethod( + method.c_str(), + internal::RpcMethod::BIDI_STREAMING), + context, reactor); +} + } // namespace grpc diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index fdc67969d96..7a25f51d103 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -117,10 +118,13 @@ class ServiceA final { // // Method A2 leading comment 1 // Method A2 leading comment 2 + virtual ::grpc::experimental::ClientCallbackWriter< ::grpc::testing::Request>* MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::experimental::ClientWriteReactor* reactor) = 0; // MethodA2 trailing comment 1 // Method A3 leading comment 1 + virtual ::grpc::experimental::ClientCallbackReader< ::grpc::testing::Response>* MethodA3(::grpc::ClientContext* context, ::grpc::testing::Request* request, ::grpc::experimental::ClientReadReactor* reactor) = 0; // Method A3 trailing comment 1 // Method A4 leading comment 1 + virtual ::grpc::experimental::ClientCallbackReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4(::grpc::ClientContext* context, ::grpc::experimental::ClientBidiReactor* reactor) = 0; // Method A4 trailing comment 1 }; virtual class experimental_async_interface* experimental_async() { return nullptr; } @@ -178,6 +182,9 @@ 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; + ::grpc::experimental::ClientCallbackWriter< ::grpc::testing::Request>* MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::experimental::ClientWriteReactor* reactor) override; + ::grpc::experimental::ClientCallbackReader< ::grpc::testing::Response>* MethodA3(::grpc::ClientContext* context, ::grpc::testing::Request* request, ::grpc::experimental::ClientReadReactor* reactor) override; + ::grpc::experimental::ClientCallbackReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4(::grpc::ClientContext* context, ::grpc::experimental::ClientBidiReactor* reactor) override; private: friend class Stub; explicit experimental_async(Stub* stub): stub_(stub) { } diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index a35991396ad..e39fc5aab2a 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -182,6 +182,59 @@ class ClientCallbackEnd2endTest } } + void SendGenericEchoAsBidi(int num_rpcs) { + const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo"); + grpc::string test_string(""); + for (int i = 0; i < num_rpcs; i++) { + test_string += "Hello world. "; + class Client : public grpc::experimental::ClientBidiReactor { + public: + Client(ClientCallbackEnd2endTest* test, const grpc::string& method_name, + const grpc::string& test_str) { + stream_ = + test->generic_stub_->experimental().PrepareBidiStreamingCall( + &cli_ctx_, method_name, this); + stream_->StartCall(); + request_.set_message(test_str); + send_buf_ = SerializeToByteBuffer(&request_); + stream_->Read(&recv_buf_); + stream_->Write(send_buf_.get()); + } + void OnWriteDone(bool ok) override { stream_->WritesDone(); } + void OnReadDone(bool ok) override { + EchoResponse response; + EXPECT_TRUE(ParseFromByteBuffer(&recv_buf_, &response)); + EXPECT_EQ(request_.message(), response.message()); + }; + void OnDone(Status s) override { + // The stream is invalid once OnDone is called + stream_ = nullptr; + 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); + } + } + + EchoRequest request_; + std::unique_ptr send_buf_; + ByteBuffer recv_buf_; + ClientContext cli_ctx_; + experimental::ClientCallbackReaderWriter* + stream_; + std::mutex mu_; + std::condition_variable cv_; + bool done_ = false; + } rpc{this, kMethodName, test_string}; + + rpc.Await(); + } + } bool is_server_started_; std::shared_ptr channel_; std::unique_ptr stub_; @@ -211,6 +264,11 @@ TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcs) { SendRpcsGeneric(10, false); } +TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidi) { + ResetStub(); + SendGenericEchoAsBidi(10); +} + #if GRPC_ALLOW_EXCEPTIONS TEST_P(ClientCallbackEnd2endTest, ExceptingRpc) { ResetStub(); @@ -267,6 +325,176 @@ TEST_P(ClientCallbackEnd2endTest, CancelRpcBeforeStart) { } } +TEST_P(ClientCallbackEnd2endTest, RequestStream) { + // TODO(vjpai): test with callback server once supported + if (GetParam().callback_server) { + return; + } + + ResetStub(); + class Client : public grpc::experimental::ClientWriteReactor { + public: + explicit Client(grpc::testing::EchoTestService::Stub* stub) { + context_.set_initial_metadata_corked(true); + stream_ = stub->experimental_async()->RequestStream(&context_, &response_, + this); + stream_->StartCall(); + request_.set_message("Hello server."); + stream_->Write(&request_); + } + void OnWriteDone(bool ok) override { + writes_left_--; + if (writes_left_ > 1) { + stream_->Write(&request_); + } else if (writes_left_ == 1) { + stream_->WriteLast(&request_, WriteOptions()); + } + } + void OnDone(Status s) override { + stream_ = nullptr; + 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: + ::grpc::experimental::ClientCallbackWriter* stream_; + EchoRequest request_; + EchoResponse response_; + ClientContext context_; + int writes_left_{3}; + std::mutex mu_; + std::condition_variable cv_; + bool done_ = false; + } test{stub_.get()}; + + test.Await(); +} + +TEST_P(ClientCallbackEnd2endTest, ResponseStream) { + // TODO(vjpai): test with callback server once supported + if (GetParam().callback_server) { + return; + } + + ResetStub(); + class Client : public grpc::experimental::ClientReadReactor { + public: + explicit Client(grpc::testing::EchoTestService::Stub* stub) { + request_.set_message("Hello client "); + stream_ = stub->experimental_async()->ResponseStream(&context_, &request_, + this); + stream_->StartCall(); + stream_->Read(&response_); + } + void OnReadDone(bool ok) override { + // Note that != is the boolean XOR operator + EXPECT_NE(ok, reads_complete_ == kServerDefaultResponseStreamsToSend); + if (ok) { + EXPECT_EQ(response_.message(), + request_.message() + grpc::to_string(reads_complete_)); + reads_complete_++; + stream_->Read(&response_); + } + } + void OnDone(Status s) override { + stream_ = nullptr; + 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: + ::grpc::experimental::ClientCallbackReader* stream_; + 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(); +} + +TEST_P(ClientCallbackEnd2endTest, BidiStream) { + // TODO(vjpai): test with callback server once supported + if (GetParam().callback_server) { + return; + } + ResetStub(); + class Client : public grpc::experimental::ClientBidiReactor { + public: + explicit Client(grpc::testing::EchoTestService::Stub* stub) { + request_.set_message("Hello fren "); + stream_ = stub->experimental_async()->BidiStream(&context_, this); + stream_->StartCall(); + stream_->Read(&response_); + stream_->Write(&request_); + } + void OnReadDone(bool ok) override { + // Note that != is the boolean XOR operator + EXPECT_NE(ok, reads_complete_ == kServerDefaultResponseStreamsToSend); + if (ok) { + EXPECT_EQ(response_.message(), request_.message()); + reads_complete_++; + stream_->Read(&response_); + } + } + void OnWriteDone(bool ok) override { + EXPECT_TRUE(ok); + if (++writes_complete_ == kServerDefaultResponseStreamsToSend) { + stream_->WritesDone(); + } else { + stream_->Write(&request_); + } + } + void OnDone(Status s) override { + stream_ = nullptr; + 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: + ::grpc::experimental::ClientCallbackReaderWriter* + stream_; + 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()}; + + test.Await(); +} + TestScenario scenarios[] = {TestScenario{false}, TestScenario{true}}; INSTANTIATE_TEST_CASE_P(ClientCallbackEnd2endTest, ClientCallbackEnd2endTest, From 85128c7f4130178fa0d5fd4706e93fd8be7d64ff Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 13 Nov 2018 21:20:58 -0800 Subject: [PATCH 0373/2143] Improve test readability at suggestion of @ghemawat --- .../end2end/client_callback_end2end_test.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index e39fc5aab2a..5362fc8d3dc 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -197,8 +197,8 @@ class ClientCallbackEnd2endTest stream_->StartCall(); request_.set_message(test_str); send_buf_ = SerializeToByteBuffer(&request_); - stream_->Read(&recv_buf_); stream_->Write(send_buf_.get()); + stream_->Read(&recv_buf_); } void OnWriteDone(bool ok) override { stream_->WritesDone(); } void OnReadDone(bool ok) override { @@ -207,8 +207,6 @@ class ClientCallbackEnd2endTest EXPECT_EQ(request_.message(), response.message()); }; void OnDone(Status s) override { - // The stream is invalid once OnDone is called - stream_ = nullptr; EXPECT_TRUE(s.ok()); std::unique_lock l(mu_); done_ = true; @@ -396,9 +394,10 @@ TEST_P(ClientCallbackEnd2endTest, ResponseStream) { stream_->Read(&response_); } void OnReadDone(bool ok) override { - // Note that != is the boolean XOR operator - EXPECT_NE(ok, reads_complete_ == kServerDefaultResponseStreamsToSend); - if (ok) { + 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_++; @@ -449,9 +448,10 @@ TEST_P(ClientCallbackEnd2endTest, BidiStream) { stream_->Write(&request_); } void OnReadDone(bool ok) override { - // Note that != is the boolean XOR operator - EXPECT_NE(ok, reads_complete_ == kServerDefaultResponseStreamsToSend); - if (ok) { + if (!ok) { + EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend); + } else { + EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend); EXPECT_EQ(response_.message(), request_.message()); reads_complete_++; stream_->Read(&response_); From fa45ffd4180511e0f11588847936741d68d0e6ff Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 13 Nov 2018 21:51:56 -0800 Subject: [PATCH 0374/2143] Address reviewer comments --- include/grpcpp/impl/codegen/client_callback.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 01a28a9e6fa..49ceaf7ca2e 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -96,7 +96,6 @@ namespace experimental { // 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 - class ClientBidiReactor { public: virtual ~ClientBidiReactor() {} @@ -198,8 +197,8 @@ class ClientCallbackReaderWriterImpl } void StartCall() override { - // This call initiates two batches - // 1. Send initial metadata (unless corked)/recv initial metadata + // This call initiates two batches, each with a callback + // 1. Send initial metadata (unless corked) + recv initial metadata // 2. Recv trailing metadata, on_completion callback callbacks_outstanding_ = 2; @@ -359,8 +358,8 @@ class ClientCallbackReaderImpl } void StartCall() override { - // This call initiates two batches - // 1. Send initial metadata (unless corked)/recv initial metadata + // This call initiates two batches, each with a callback + // 1. Send initial metadata (unless corked) + recv initial metadata // 2. Recv trailing metadata, on_completion callback callbacks_outstanding_ = 2; @@ -472,9 +471,9 @@ class ClientCallbackWriterImpl } void StartCall() override { - // This call initiates two batches - // 1. Send initial metadata (unless corked)/recv initial metadata - // 2. Recv message + trailing metadata, on_completion callback + // This call initiates two batches, each with a callback + // 1. Send initial metadata (unless corked) + recv initial metadata + // 2. Recv message + recv trailing metadata, on_completion callback callbacks_outstanding_ = 2; start_tag_.Set(call_.call(), From 5dcfc8be966d31d1daa52882211773913279e592 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 14 Nov 2018 08:48:10 -0800 Subject: [PATCH 0375/2143] More review comments --- test/cpp/end2end/client_callback_end2end_test.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 5362fc8d3dc..58c71f7b4cd 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -349,7 +349,6 @@ TEST_P(ClientCallbackEnd2endTest, RequestStream) { } } void OnDone(Status s) override { - stream_ = nullptr; EXPECT_TRUE(s.ok()); EXPECT_EQ(response_.message(), "Hello server.Hello server.Hello server."); std::unique_lock l(mu_); @@ -405,7 +404,6 @@ TEST_P(ClientCallbackEnd2endTest, ResponseStream) { } } void OnDone(Status s) override { - stream_ = nullptr; EXPECT_TRUE(s.ok()); std::unique_lock l(mu_); done_ = true; @@ -466,7 +464,6 @@ TEST_P(ClientCallbackEnd2endTest, BidiStream) { } } void OnDone(Status s) override { - stream_ = nullptr; EXPECT_TRUE(s.ok()); std::unique_lock l(mu_); done_ = true; From 60949a823267d2bfa783f9488dddff515a7928c1 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 14 Nov 2018 08:56:59 -0800 Subject: [PATCH 0376/2143] Revert an order change --- test/cpp/end2end/client_callback_end2end_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 58c71f7b4cd..31216f72cc9 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -197,8 +197,8 @@ class ClientCallbackEnd2endTest stream_->StartCall(); request_.set_message(test_str); send_buf_ = SerializeToByteBuffer(&request_); - stream_->Write(send_buf_.get()); stream_->Read(&recv_buf_); + stream_->Write(send_buf_.get()); } void OnWriteDone(bool ok) override { stream_->WritesDone(); } void OnReadDone(bool ok) override { From dac2066a1c0df628fefe4144ae0f97337af6324e Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 14 Nov 2018 11:47:15 -0800 Subject: [PATCH 0377/2143] Make StartCall() a releasing operation so that you can pile up ops --- include/grpcpp/impl/codegen/client_callback.h | 150 +++++++++++++----- .../end2end/client_callback_end2end_test.cc | 4 +- test/cpp/end2end/test_service_impl.cc | 1 + 3 files changed, 111 insertions(+), 44 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 49ceaf7ca2e..92a588b3c33 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -197,10 +197,12 @@ class ClientCallbackReaderWriterImpl } void StartCall() override { - // This call initiates two batches, each with a callback + // 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 - callbacks_outstanding_ = 2; + // 2. Any read backlog + // 3. Recv trailing metadata, on_completion callback + // 4. Any write backlog + started_ = true; start_tag_.Set(call_.call(), [this](bool ok) { @@ -208,7 +210,6 @@ class ClientCallbackReaderWriterImpl MaybeFinish(); }, &start_ops_); - start_corked_ = context_->initial_metadata_corked_; if (!start_corked_) { start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, context_->initial_metadata_flags()); @@ -217,12 +218,6 @@ class ClientCallbackReaderWriterImpl start_ops_.set_core_cq_tag(&start_tag_); call_.PerformOps(&start_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_); - // Also set up the read and write tags so that they don't have to be set up // each time write_tag_.Set(call_.call(), @@ -240,12 +235,33 @@ class ClientCallbackReaderWriterImpl }, &read_ops_); read_ops_.set_core_cq_tag(&read_tag_); + if (read_ops_at_start_) { + 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_); + } + + if (writes_done_ops_at_start_) { + call_.PerformOps(&writes_done_ops_); + } } void Read(Response* msg) override { read_ops_.RecvMessage(msg); callbacks_outstanding_++; - call_.PerformOps(&read_ops_); + if (started_) { + call_.PerformOps(&read_ops_); + } else { + read_ops_at_start_ = true; + } } void Write(const Request* msg, WriteOptions options) override { @@ -262,7 +278,11 @@ class ClientCallbackReaderWriterImpl write_ops_.ClientSendClose(); } callbacks_outstanding_++; - call_.PerformOps(&write_ops_); + if (started_) { + call_.PerformOps(&write_ops_); + } else { + write_ops_at_start_ = true; + } } void WritesDone() override { if (start_corked_) { @@ -279,7 +299,11 @@ class ClientCallbackReaderWriterImpl &writes_done_ops_); writes_done_ops_.set_core_cq_tag(&writes_done_tag_); callbacks_outstanding_++; - call_.PerformOps(&writes_done_ops_); + if (started_) { + call_.PerformOps(&writes_done_ops_); + } else { + writes_done_ops_at_start_ = true; + } } private: @@ -288,7 +312,10 @@ class ClientCallbackReaderWriterImpl ClientCallbackReaderWriterImpl( Call call, ClientContext* context, ::grpc::experimental::ClientBidiReactor* reactor) - : context_(context), call_(call), reactor_(reactor) {} + : context_(context), + call_(call), + reactor_(reactor), + start_corked_(context_->initial_metadata_corked_) {} ClientContext* context_; Call call_; @@ -305,14 +332,19 @@ class ClientCallbackReaderWriterImpl CallOpSet write_ops_; CallbackWithSuccessTag write_tag_; + bool write_ops_at_start_{false}; CallOpSet writes_done_ops_; CallbackWithSuccessTag writes_done_tag_; + bool writes_done_ops_at_start_{false}; - CallOpSet> read_ops_; + CallOpSet> read_ops_; CallbackWithSuccessTag read_tag_; + bool read_ops_at_start_{false}; - std::atomic_int callbacks_outstanding_; + // Minimum of 2 outstanding callbacks to pre-register for start and finish + std::atomic_int callbacks_outstanding_{2}; + bool started_{false}; }; template @@ -358,10 +390,11 @@ class ClientCallbackReaderImpl } void StartCall() override { - // This call initiates two batches, each with a callback + // 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 - callbacks_outstanding_ = 2; + // 2. Any backlog + // 3. Recv trailing metadata, on_completion callback + started_ = true; start_tag_.Set(call_.call(), [this](bool ok) { @@ -375,12 +408,6 @@ class ClientCallbackReaderImpl start_ops_.set_core_cq_tag(&start_tag_); call_.PerformOps(&start_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_); - // Also set up the read tag so it doesn't have to be set up each time read_tag_.Set(call_.call(), [this](bool ok) { @@ -389,12 +416,25 @@ class ClientCallbackReaderImpl }, &read_ops_); read_ops_.set_core_cq_tag(&read_tag_); + if (read_ops_at_start_) { + 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_); } void Read(Response* msg) override { read_ops_.RecvMessage(msg); callbacks_outstanding_++; - call_.PerformOps(&read_ops_); + if (started_) { + call_.PerformOps(&read_ops_); + } else { + read_ops_at_start_ = true; + } } private: @@ -422,10 +462,13 @@ class ClientCallbackReaderImpl CallbackWithSuccessTag finish_tag_; Status finish_status_; - CallOpSet> read_ops_; + CallOpSet> read_ops_; CallbackWithSuccessTag read_tag_; + bool read_ops_at_start_{false}; - std::atomic_int callbacks_outstanding_; + // Minimum of 2 outstanding callbacks to pre-register for start and finish + std::atomic_int callbacks_outstanding_{2}; + bool started_{false}; }; template @@ -471,10 +514,11 @@ class ClientCallbackWriterImpl } void StartCall() override { - // This call initiates two batches, each with a callback + // This call initiates two batches, plus any backlog, each with a callback // 1. Send initial metadata (unless corked) + recv initial metadata - // 2. Recv message + recv trailing metadata, on_completion callback - callbacks_outstanding_ = 2; + // 2. Recv trailing metadata, on_completion callback + // 3. Any backlog + started_ = true; start_tag_.Set(call_.call(), [this](bool ok) { @@ -482,7 +526,6 @@ class ClientCallbackWriterImpl MaybeFinish(); }, &start_ops_); - start_corked_ = context_->initial_metadata_corked_; if (!start_corked_) { start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, context_->initial_metadata_flags()); @@ -491,12 +534,6 @@ class ClientCallbackWriterImpl start_ops_.set_core_cq_tag(&start_tag_); call_.PerformOps(&start_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_); - // Also set up the read and write tags so that they don't have to be set up // each time write_tag_.Set(call_.call(), @@ -506,6 +543,20 @@ 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_); + } + + if (writes_done_ops_at_start_) { + call_.PerformOps(&writes_done_ops_); + } } void Write(const Request* msg, WriteOptions options) override { @@ -522,7 +573,11 @@ class ClientCallbackWriterImpl write_ops_.ClientSendClose(); } callbacks_outstanding_++; - call_.PerformOps(&write_ops_); + if (started_) { + call_.PerformOps(&write_ops_); + } else { + write_ops_at_start_ = true; + } } void WritesDone() override { if (start_corked_) { @@ -539,7 +594,11 @@ class ClientCallbackWriterImpl &writes_done_ops_); writes_done_ops_.set_core_cq_tag(&writes_done_tag_); callbacks_outstanding_++; - call_.PerformOps(&writes_done_ops_); + if (started_) { + call_.PerformOps(&writes_done_ops_); + } else { + writes_done_ops_at_start_ = true; + } } private: @@ -549,7 +608,10 @@ class ClientCallbackWriterImpl ClientCallbackWriterImpl(Call call, ClientContext* context, Response* response, ::grpc::experimental::ClientWriteReactor* reactor) - : context_(context), call_(call), reactor_(reactor) { + : context_(context), + call_(call), + reactor_(reactor), + start_corked_(context_->initial_metadata_corked_) { finish_ops_.RecvMessage(response); finish_ops_.AllowNoMessage(); } @@ -569,11 +631,15 @@ class ClientCallbackWriterImpl CallOpSet write_ops_; CallbackWithSuccessTag write_tag_; + bool write_ops_at_start_{false}; CallOpSet writes_done_ops_; CallbackWithSuccessTag writes_done_tag_; + bool writes_done_ops_at_start_{false}; - std::atomic_int callbacks_outstanding_; + // Minimum of 2 outstanding callbacks to pre-register for start and finish + std::atomic_int callbacks_outstanding_{2}; + bool started_{false}; }; template diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 31216f72cc9..57c3cb87f2c 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -194,11 +194,11 @@ class ClientCallbackEnd2endTest stream_ = test->generic_stub_->experimental().PrepareBidiStreamingCall( &cli_ctx_, method_name, this); - stream_->StartCall(); request_.set_message(test_str); send_buf_ = SerializeToByteBuffer(&request_); - stream_->Read(&recv_buf_); stream_->Write(send_buf_.get()); + stream_->Read(&recv_buf_); + stream_->StartCall(); } void OnWriteDone(bool ok) override { stream_->WritesDone(); } void OnReadDone(bool ok) override { diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 605356724fb..1726e87ea66 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -223,6 +223,7 @@ void CallbackTestServiceImpl::EchoNonDelayed( return; } + gpr_log(GPR_DEBUG, "Request message was %s", request->message().c_str()); response->set_message(request->message()); MaybeEchoDeadline(context, request, response); if (host_) { From ea1156da3fb3d6fb8660d078e70cf5486fc71a65 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 30 Nov 2018 02:16:08 -0800 Subject: [PATCH 0378/2143] Stop exposing streaming object class --- include/grpcpp/generic/generic_stub.h | 6 +- include/grpcpp/impl/codegen/client_callback.h | 304 +++-- src/compiler/cpp_generator.cc | 96 +- src/cpp/client/generic_stub.cc | 15 +- test/cpp/codegen/compiler_test_golden | 1059 ++++++++++++----- .../end2end/client_callback_end2end_test.cc | 63 +- 6 files changed, 1031 insertions(+), 512 deletions(-) diff --git a/include/grpcpp/generic/generic_stub.h b/include/grpcpp/generic/generic_stub.h index ccbf8a0e55a..eb014184e4a 100644 --- a/include/grpcpp/generic/generic_stub.h +++ b/include/grpcpp/generic/generic_stub.h @@ -77,9 +77,9 @@ class GenericStub final { const ByteBuffer* request, ByteBuffer* response, std::function on_completion); - experimental::ClientCallbackReaderWriter* - PrepareBidiStreamingCall(ClientContext* context, const grpc::string& method, - experimental::ClientBidiReactor* reactor); + void PrepareBidiStreamingCall( + ClientContext* context, const grpc::string& method, + experimental::ClientBidiReactor* reactor); private: GenericStub* stub_; diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 92a588b3c33..999c1c8a3e9 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -93,48 +93,30 @@ class CallbackUnaryCallImpl { namespace experimental { -// 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 -class ClientBidiReactor { - public: - virtual ~ClientBidiReactor() {} - virtual void OnDone(Status s) {} - virtual void OnReadInitialMetadataDone(bool ok) {} - virtual void OnReadDone(bool ok) {} - virtual void OnWriteDone(bool ok) {} - virtual void OnWritesDoneDone(bool ok) {} -}; - -class ClientReadReactor { - public: - virtual ~ClientReadReactor() {} - virtual void OnDone(Status s) {} - virtual void OnReadInitialMetadataDone(bool ok) {} - virtual void OnReadDone(bool ok) {} -}; - -class ClientWriteReactor { - public: - virtual ~ClientWriteReactor() {} - virtual void OnDone(Status s) {} - virtual void OnReadInitialMetadataDone(bool ok) {} - virtual void OnWriteDone(bool ok) {} - virtual void OnWritesDoneDone(bool ok) {} -}; +// Forward declarations +template +class ClientBidiReactor; +template +class ClientReadReactor; +template +class ClientWriteReactor; +// NOTE: The streaming objects are not actually implemented in the public API. +// These interfaces are provided for mocking only. Typical applications +// will interact exclusively with the reactors that they define. template class ClientCallbackReaderWriter { public: virtual ~ClientCallbackReaderWriter() {} virtual void StartCall() = 0; - void Write(const Request* req) { Write(req, WriteOptions()); } virtual void Write(const Request* req, WriteOptions options) = 0; - void WriteLast(const Request* req, WriteOptions options) { - Write(req, options.set_last_message()); - } virtual void WritesDone() = 0; virtual void Read(Response* resp) = 0; + + protected: + void BindReactor(ClientBidiReactor* reactor) { + reactor->BindStream(this); + } }; template @@ -143,6 +125,11 @@ class ClientCallbackReader { virtual ~ClientCallbackReader() {} virtual void StartCall() = 0; virtual void Read(Response* resp) = 0; + + protected: + void BindReactor(ClientReadReactor* reactor) { + reactor->BindReader(this); + } }; template @@ -156,6 +143,85 @@ class ClientCallbackWriter { Write(req, options.set_last_message()); } virtual void WritesDone() = 0; + + protected: + void BindReactor(ClientWriteReactor* reactor) { + reactor->BindWriter(this); + } +}; + +// 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 +template +class ClientBidiReactor { + public: + virtual ~ClientBidiReactor() {} + virtual void OnDone(Status s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + virtual void OnReadDone(bool ok) {} + virtual void OnWriteDone(bool ok) {} + virtual void OnWritesDoneDone(bool ok) {} + + void StartCall() { stream_->StartCall(); } + void StartRead(Response* resp) { stream_->Read(resp); } + void StartWrite(const Request* req) { StartWrite(req, WriteOptions()); } + void StartWrite(const Request* req, WriteOptions options) { + stream_->Write(req, std::move(options)); + } + void StartWriteLast(const Request* req, WriteOptions options) { + StartWrite(req, std::move(options.set_last_message())); + } + void StartWritesDone() { stream_->WritesDone(); } + + private: + friend class ClientCallbackReaderWriter; + void BindStream(ClientCallbackReaderWriter* stream) { + stream_ = stream; + } + ClientCallbackReaderWriter* stream_; +}; + +template +class ClientReadReactor { + public: + virtual ~ClientReadReactor() {} + virtual void OnDone(Status s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + virtual void OnReadDone(bool ok) {} + + void StartCall() { reader_->StartCall(); } + void StartRead(Response* resp) { reader_->Read(resp); } + + private: + friend class ClientCallbackReader; + void BindReader(ClientCallbackReader* reader) { reader_ = reader; } + ClientCallbackReader* reader_; +}; + +template +class ClientWriteReactor { + public: + virtual ~ClientWriteReactor() {} + virtual void OnDone(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()); } + void StartWrite(const Request* req, WriteOptions options) { + writer_->Write(req, std::move(options)); + } + void StartWriteLast(const Request* req, WriteOptions options) { + StartWrite(req, std::move(options.set_last_message())); + } + void StartWritesDone() { writer_->WritesDone(); } + + private: + friend class ClientCallbackWriter; + void BindWriter(ClientCallbackWriter* writer) { writer_ = writer; } + ClientCallbackWriter* writer_; }; } // namespace experimental @@ -204,12 +270,13 @@ class ClientCallbackReaderWriterImpl // 4. Any write backlog started_ = true; - start_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); + start_tag_.Set( + call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); if (!start_corked_) { start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, context_->initial_metadata_flags()); @@ -220,27 +287,29 @@ class ClientCallbackReaderWriterImpl // Also set up the read and write tags so that they don't have to be set up // each time - write_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWriteDone(ok); - MaybeFinish(); - }, - &write_ops_); + write_tag_.Set( + call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeFinish(); + }, + &write_ops_); write_ops_.set_core_cq_tag(&write_tag_); - read_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadDone(ok); - MaybeFinish(); - }, - &read_ops_); + read_tag_.Set( + call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeFinish(); + }, + &read_ops_); read_ops_.set_core_cq_tag(&read_tag_); if (read_ops_at_start_) { call_.PerformOps(&read_ops_); } - finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, - &finish_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_); @@ -291,12 +360,13 @@ class ClientCallbackReaderWriterImpl start_corked_ = false; } writes_done_ops_.ClientSendClose(); - writes_done_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWritesDoneDone(ok); - MaybeFinish(); - }, - &writes_done_ops_); + writes_done_tag_.Set( + call_.call(), + [this](bool ok) { + reactor_->OnWritesDoneDone(ok); + MaybeFinish(); + }, + &writes_done_ops_); writes_done_ops_.set_core_cq_tag(&writes_done_tag_); callbacks_outstanding_++; if (started_) { @@ -311,15 +381,17 @@ class ClientCallbackReaderWriterImpl ClientCallbackReaderWriterImpl( Call call, ClientContext* context, - ::grpc::experimental::ClientBidiReactor* reactor) + ::grpc::experimental::ClientBidiReactor* reactor) : context_(context), call_(call), reactor_(reactor), - start_corked_(context_->initial_metadata_corked_) {} + start_corked_(context_->initial_metadata_corked_) { + this->BindReactor(reactor); + } ClientContext* context_; Call call_; - ::grpc::experimental::ClientBidiReactor* reactor_; + ::grpc::experimental::ClientBidiReactor* reactor_; CallOpSet start_ops_; CallbackWithSuccessTag start_tag_; @@ -350,14 +422,14 @@ class ClientCallbackReaderWriterImpl template class ClientCallbackReaderWriterFactory { public: - static experimental::ClientCallbackReaderWriter* Create( + static void Create( ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, ClientContext* context, - ::grpc::experimental::ClientBidiReactor* reactor) { + ::grpc::experimental::ClientBidiReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); g_core_codegen_interface->grpc_call_ref(call.call()); - return new (g_core_codegen_interface->grpc_call_arena_alloc( + new (g_core_codegen_interface->grpc_call_arena_alloc( call.call(), sizeof(ClientCallbackReaderWriterImpl))) ClientCallbackReaderWriterImpl(call, context, reactor); @@ -396,12 +468,13 @@ class ClientCallbackReaderImpl // 3. Recv trailing metadata, on_completion callback started_ = true; - start_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); + start_tag_.Set( + call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, context_->initial_metadata_flags()); start_ops_.RecvInitialMetadata(context_); @@ -409,19 +482,20 @@ class ClientCallbackReaderImpl call_.PerformOps(&start_ops_); // Also set up the read tag so it doesn't have to be set up each time - read_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadDone(ok); - MaybeFinish(); - }, - &read_ops_); + read_tag_.Set( + call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeFinish(); + }, + &read_ops_); read_ops_.set_core_cq_tag(&read_tag_); if (read_ops_at_start_) { call_.PerformOps(&read_ops_); } - finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, - &finish_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_); @@ -441,9 +515,11 @@ class ClientCallbackReaderImpl friend class ClientCallbackReaderFactory; template - ClientCallbackReaderImpl(Call call, ClientContext* context, Request* request, - ::grpc::experimental::ClientReadReactor* reactor) + ClientCallbackReaderImpl( + Call call, ClientContext* context, Request* request, + ::grpc::experimental::ClientReadReactor* reactor) : context_(context), call_(call), reactor_(reactor) { + this->BindReactor(reactor); // TODO(vjpai): don't assert GPR_CODEGEN_ASSERT(start_ops_.SendMessage(*request).ok()); start_ops_.ClientSendClose(); @@ -451,7 +527,7 @@ class ClientCallbackReaderImpl ClientContext* context_; Call call_; - ::grpc::experimental::ClientReadReactor* reactor_; + ::grpc::experimental::ClientReadReactor* reactor_; CallOpSet @@ -475,14 +551,14 @@ template class ClientCallbackReaderFactory { public: template - static experimental::ClientCallbackReader* Create( + static void Create( ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, ClientContext* context, const Request* request, - ::grpc::experimental::ClientReadReactor* reactor) { + ::grpc::experimental::ClientReadReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); g_core_codegen_interface->grpc_call_ref(call.call()); - return new (g_core_codegen_interface->grpc_call_arena_alloc( + new (g_core_codegen_interface->grpc_call_arena_alloc( call.call(), sizeof(ClientCallbackReaderImpl))) ClientCallbackReaderImpl(call, context, request, reactor); } @@ -520,12 +596,13 @@ class ClientCallbackWriterImpl // 3. Any backlog started_ = true; - start_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); + start_tag_.Set( + call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); if (!start_corked_) { start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, context_->initial_metadata_flags()); @@ -536,16 +613,17 @@ class ClientCallbackWriterImpl // Also set up the read and write tags so that they don't have to be set up // each time - write_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWriteDone(ok); - MaybeFinish(); - }, - &write_ops_); + write_tag_.Set( + call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeFinish(); + }, + &write_ops_); write_ops_.set_core_cq_tag(&write_tag_); - finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, - &finish_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_); @@ -586,12 +664,13 @@ class ClientCallbackWriterImpl start_corked_ = false; } writes_done_ops_.ClientSendClose(); - writes_done_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWritesDoneDone(ok); - MaybeFinish(); - }, - &writes_done_ops_); + writes_done_tag_.Set( + call_.call(), + [this](bool ok) { + reactor_->OnWritesDoneDone(ok); + MaybeFinish(); + }, + &writes_done_ops_); writes_done_ops_.set_core_cq_tag(&writes_done_tag_); callbacks_outstanding_++; if (started_) { @@ -605,20 +684,21 @@ class ClientCallbackWriterImpl friend class ClientCallbackWriterFactory; template - ClientCallbackWriterImpl(Call call, ClientContext* context, - Response* response, - ::grpc::experimental::ClientWriteReactor* reactor) + ClientCallbackWriterImpl( + Call call, ClientContext* context, Response* response, + ::grpc::experimental::ClientWriteReactor* reactor) : context_(context), call_(call), reactor_(reactor), start_corked_(context_->initial_metadata_corked_) { + this->BindReactor(reactor); finish_ops_.RecvMessage(response); finish_ops_.AllowNoMessage(); } ClientContext* context_; Call call_; - ::grpc::experimental::ClientWriteReactor* reactor_; + ::grpc::experimental::ClientWriteReactor* reactor_; CallOpSet start_ops_; CallbackWithSuccessTag start_tag_; @@ -646,14 +726,14 @@ template class ClientCallbackWriterFactory { public: template - static experimental::ClientCallbackWriter* Create( + static void Create( ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, ClientContext* context, Response* response, - ::grpc::experimental::ClientWriteReactor* reactor) { + ::grpc::experimental::ClientWriteReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); g_core_codegen_interface->grpc_call_ref(call.call()); - return new (g_core_codegen_interface->grpc_call_arena_alloc( + new (g_core_codegen_interface->grpc_call_arena_alloc( call.call(), sizeof(ClientCallbackWriterImpl))) ClientCallbackWriterImpl(call, context, response, reactor); } diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 473e57166fa..a368b47f016 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -582,22 +582,21 @@ void PrintHeaderClientMethodCallbackInterfaces( "std::function) = 0;\n"); } else if (ClientOnlyStreaming(method)) { printer->Print(*vars, - "virtual ::grpc::experimental::ClientCallbackWriter< " - "$Request$>* $Method$(::grpc::ClientContext* context, " + "virtual void $Method$(::grpc::ClientContext* context, " "$Response$* response, " - "::grpc::experimental::ClientWriteReactor* reactor) = 0;\n"); + "::grpc::experimental::ClientWriteReactor< $Request$>* " + "reactor) = 0;\n"); } else if (ServerOnlyStreaming(method)) { printer->Print(*vars, - "virtual ::grpc::experimental::ClientCallbackReader< " - "$Response$>* $Method$(::grpc::ClientContext* context, " + "virtual void $Method$(::grpc::ClientContext* context, " "$Request$* request, " - "::grpc::experimental::ClientReadReactor* reactor) = 0;\n"); + "::grpc::experimental::ClientReadReactor< $Response$>* " + "reactor) = 0;\n"); } else if (method->BidiStreaming()) { - printer->Print( - *vars, - "virtual ::grpc::experimental::ClientCallbackReaderWriter< $Request$, " - "$Response$>* $Method$(::grpc::ClientContext* context, " - "::grpc::experimental::ClientBidiReactor* reactor) = 0;\n"); + printer->Print(*vars, + "virtual void $Method$(::grpc::ClientContext* context, " + "::grpc::experimental::ClientBidiReactor< " + "$Request$,$Response$>* reactor) = 0;\n"); } } @@ -644,26 +643,23 @@ void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer, "const $Request$* request, $Response$* response, " "std::function) override;\n"); } else if (ClientOnlyStreaming(method)) { - printer->Print( - *vars, - "::grpc::experimental::ClientCallbackWriter< $Request$>* " - "$Method$(::grpc::ClientContext* context, " - "$Response$* response, " - "::grpc::experimental::ClientWriteReactor* reactor) override;\n"); + printer->Print(*vars, + "void $Method$(::grpc::ClientContext* context, " + "$Response$* response, " + "::grpc::experimental::ClientWriteReactor< $Request$>* " + "reactor) override;\n"); } else if (ServerOnlyStreaming(method)) { - printer->Print( - *vars, - "::grpc::experimental::ClientCallbackReader< $Response$>* " - "$Method$(::grpc::ClientContext* context, " - "$Request$* request, " - "::grpc::experimental::ClientReadReactor* reactor) override;\n"); + printer->Print(*vars, + "void $Method$(::grpc::ClientContext* context, " + "$Request$* request, " + "::grpc::experimental::ClientReadReactor< $Response$>* " + "reactor) override;\n"); } else if (method->BidiStreaming()) { - printer->Print( - *vars, - "::grpc::experimental::ClientCallbackReaderWriter< $Request$, " - "$Response$>* $Method$(::grpc::ClientContext* context, " - "::grpc::experimental::ClientBidiReactor* reactor) override;\n"); + printer->Print(*vars, + "void $Method$(::grpc::ClientContext* context, " + "::grpc::experimental::ClientBidiReactor< " + "$Request$,$Response$>* reactor) override;\n"); } } @@ -1637,13 +1633,12 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, printer->Print( *vars, - "::grpc::experimental::ClientCallbackWriter< $Request$>* " - "$ns$$Service$::" + "void $ns$$Service$::" "Stub::experimental_async::$Method$(::grpc::ClientContext* context, " "$Response$* response, " - "::grpc::experimental::ClientWriteReactor* reactor) {\n"); + "::grpc::experimental::ClientWriteReactor< $Request$>* reactor) {\n"); printer->Print(*vars, - " return ::grpc::internal::ClientCallbackWriterFactory< " + " ::grpc::internal::ClientCallbackWriterFactory< " "$Request$>::Create(" "stub_->channel_.get(), " "stub_->rpcmethod_$Method$_, " @@ -1682,14 +1677,14 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "context, request);\n" "}\n\n"); + printer->Print( + *vars, + "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::" + "ClientContext* context, " + "$Request$* request, " + "::grpc::experimental::ClientReadReactor< $Response$>* reactor) {\n"); printer->Print(*vars, - "::grpc::experimental::ClientCallbackReader< $Response$>* " - "$ns$$Service$::Stub::experimental_async::$Method$(::grpc::" - "ClientContext* context, " - "$Request$* request, " - "::grpc::experimental::ClientReadReactor* reactor) {\n"); - printer->Print(*vars, - " return ::grpc::internal::ClientCallbackReaderFactory< " + " ::grpc::internal::ClientCallbackReaderFactory< " "$Response$>::Create(" "stub_->channel_.get(), " "stub_->rpcmethod_$Method$_, " @@ -1728,20 +1723,19 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "context);\n" "}\n\n"); - printer->Print(*vars, - "::grpc::experimental::ClientCallbackReaderWriter< " - "$Request$,$Response$>* " - "$ns$$Service$::Stub::experimental_async::$Method$(::grpc::" - "ClientContext* context, " - "::grpc::experimental::ClientBidiReactor* reactor) {\n"); printer->Print( *vars, - " return ::grpc::internal::ClientCallbackReaderWriterFactory< " - "$Request$,$Response$>::Create(" - "stub_->channel_.get(), " - "stub_->rpcmethod_$Method$_, " - "context, reactor);\n" - "}\n\n"); + "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::" + "ClientContext* context, " + "::grpc::experimental::ClientBidiReactor< $Request$,$Response$>* " + "reactor) {\n"); + printer->Print(*vars, + " ::grpc::internal::ClientCallbackReaderWriterFactory< " + "$Request$,$Response$>::Create(" + "stub_->channel_.get(), " + "stub_->rpcmethod_$Method$_, " + "context, reactor);\n" + "}\n\n"); for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc index f029daec656..f61c1b5317b 100644 --- a/src/cpp/client/generic_stub.cc +++ b/src/cpp/client/generic_stub.cc @@ -72,16 +72,13 @@ void GenericStub::experimental_type::UnaryCall( context, request, response, std::move(on_completion)); } -experimental::ClientCallbackReaderWriter* -GenericStub::experimental_type::PrepareBidiStreamingCall( +void GenericStub::experimental_type::PrepareBidiStreamingCall( ClientContext* context, const grpc::string& method, - experimental::ClientBidiReactor* reactor) { - return internal::ClientCallbackReaderWriterFactory< - ByteBuffer, ByteBuffer>::Create(stub_->channel_.get(), - internal::RpcMethod( - method.c_str(), - internal::RpcMethod::BIDI_STREAMING), - context, reactor); + experimental::ClientBidiReactor* reactor) { + internal::ClientCallbackReaderWriterFactory::Create( + stub_->channel_.get(), + internal::RpcMethod(method.c_str(), internal::RpcMethod::BIDI_STREAMING), + context, reactor); } } // namespace grpc diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 7a25f51d103..1a5fe279328 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -26,7 +26,6 @@ #include "src/proto/grpc/testing/compiler_test.pb.h" -#include #include #include #include @@ -39,6 +38,7 @@ #include #include #include +#include namespace grpc { class CompletionQueue; @@ -64,294 +64,556 @@ class ServiceA final { public: virtual ~StubInterface() {} // MethodA1 leading comment 1 - virtual ::grpc::Status MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response) = 0; - std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>> AsyncMethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>>(AsyncMethodA1Raw(context, request, cq)); + virtual ::grpc::Status MethodA1(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::testing::Response* response) = 0; + std::unique_ptr< + ::grpc::ClientAsyncResponseReaderInterface<::grpc::testing::Response>> + AsyncMethodA1(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface< + ::grpc::testing::Response>>(AsyncMethodA1Raw(context, request, cq)); } - std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>> PrepareAsyncMethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>>(PrepareAsyncMethodA1Raw(context, request, cq)); + std::unique_ptr< + ::grpc::ClientAsyncResponseReaderInterface<::grpc::testing::Response>> + PrepareAsyncMethodA1(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface< + ::grpc::testing::Response>>( + PrepareAsyncMethodA1Raw(context, request, cq)); } // MethodA1 trailing comment 1 // MethodA2 detached leading comment 1 // // Method A2 leading comment 1 // Method A2 leading comment 2 - std::unique_ptr< ::grpc::ClientWriterInterface< ::grpc::testing::Request>> MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response) { - return std::unique_ptr< ::grpc::ClientWriterInterface< ::grpc::testing::Request>>(MethodA2Raw(context, response)); + std::unique_ptr<::grpc::ClientWriterInterface<::grpc::testing::Request>> + MethodA2(::grpc::ClientContext* context, + ::grpc::testing::Response* response) { + return std::unique_ptr< + ::grpc::ClientWriterInterface<::grpc::testing::Request>>( + MethodA2Raw(context, response)); } - std::unique_ptr< ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>> AsyncMethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) { - return std::unique_ptr< ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>>(AsyncMethodA2Raw(context, response, cq, tag)); + std::unique_ptr< + ::grpc::ClientAsyncWriterInterface<::grpc::testing::Request>> + AsyncMethodA2(::grpc::ClientContext* context, + ::grpc::testing::Response* response, + ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< + ::grpc::ClientAsyncWriterInterface<::grpc::testing::Request>>( + AsyncMethodA2Raw(context, response, cq, tag)); } - std::unique_ptr< ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>> PrepareAsyncMethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>>(PrepareAsyncMethodA2Raw(context, response, cq)); + std::unique_ptr< + ::grpc::ClientAsyncWriterInterface<::grpc::testing::Request>> + PrepareAsyncMethodA2(::grpc::ClientContext* context, + ::grpc::testing::Response* response, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr< + ::grpc::ClientAsyncWriterInterface<::grpc::testing::Request>>( + PrepareAsyncMethodA2Raw(context, response, cq)); } // MethodA2 trailing comment 1 // Method A3 leading comment 1 - std::unique_ptr< ::grpc::ClientReaderInterface< ::grpc::testing::Response>> MethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request) { - return std::unique_ptr< ::grpc::ClientReaderInterface< ::grpc::testing::Response>>(MethodA3Raw(context, request)); + std::unique_ptr<::grpc::ClientReaderInterface<::grpc::testing::Response>> + MethodA3(::grpc::ClientContext* context, + const ::grpc::testing::Request& request) { + return std::unique_ptr< + ::grpc::ClientReaderInterface<::grpc::testing::Response>>( + MethodA3Raw(context, request)); } - std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>> AsyncMethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) { - return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>>(AsyncMethodA3Raw(context, request, cq, tag)); + std::unique_ptr< + ::grpc::ClientAsyncReaderInterface<::grpc::testing::Response>> + AsyncMethodA3(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< + ::grpc::ClientAsyncReaderInterface<::grpc::testing::Response>>( + AsyncMethodA3Raw(context, request, cq, tag)); } - std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>> PrepareAsyncMethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>>(PrepareAsyncMethodA3Raw(context, request, cq)); + std::unique_ptr< + ::grpc::ClientAsyncReaderInterface<::grpc::testing::Response>> + PrepareAsyncMethodA3(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr< + ::grpc::ClientAsyncReaderInterface<::grpc::testing::Response>>( + PrepareAsyncMethodA3Raw(context, request, cq)); } // Method A3 trailing comment 1 // Method A4 leading comment 1 - std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>> MethodA4(::grpc::ClientContext* context) { - return std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>>(MethodA4Raw(context)); + std::unique_ptr<::grpc::ClientReaderWriterInterface< + ::grpc::testing::Request, ::grpc::testing::Response>> + MethodA4(::grpc::ClientContext* context) { + return std::unique_ptr<::grpc::ClientReaderWriterInterface< + ::grpc::testing::Request, ::grpc::testing::Response>>( + MethodA4Raw(context)); } - std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>> AsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { - return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>>(AsyncMethodA4Raw(context, cq, tag)); + std::unique_ptr<::grpc::ClientAsyncReaderWriterInterface< + ::grpc::testing::Request, ::grpc::testing::Response>> + AsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, + void* tag) { + return std::unique_ptr<::grpc::ClientAsyncReaderWriterInterface< + ::grpc::testing::Request, ::grpc::testing::Response>>( + AsyncMethodA4Raw(context, cq, tag)); } - std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>> PrepareAsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>>(PrepareAsyncMethodA4Raw(context, cq)); + std::unique_ptr<::grpc::ClientAsyncReaderWriterInterface< + ::grpc::testing::Request, ::grpc::testing::Response>> + PrepareAsyncMethodA4(::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr<::grpc::ClientAsyncReaderWriterInterface< + ::grpc::testing::Request, ::grpc::testing::Response>>( + PrepareAsyncMethodA4Raw(context, cq)); } // Method A4 trailing comment 1 class experimental_async_interface { public: 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::testing::Request* request, + ::grpc::testing::Response* response, + std::function) = 0; // MethodA1 trailing comment 1 // MethodA2 detached leading comment 1 // // Method A2 leading comment 1 // Method A2 leading comment 2 - virtual ::grpc::experimental::ClientCallbackWriter< ::grpc::testing::Request>* MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::experimental::ClientWriteReactor* reactor) = 0; + virtual void MethodA2( + ::grpc::ClientContext* context, ::grpc::testing::Response* response, + ::grpc::experimental::ClientWriteReactor<::grpc::testing::Request>* + reactor) = 0; // MethodA2 trailing comment 1 // Method A3 leading comment 1 - virtual ::grpc::experimental::ClientCallbackReader< ::grpc::testing::Response>* MethodA3(::grpc::ClientContext* context, ::grpc::testing::Request* request, ::grpc::experimental::ClientReadReactor* reactor) = 0; + virtual void MethodA3( + ::grpc::ClientContext* context, ::grpc::testing::Request* request, + ::grpc::experimental::ClientReadReactor<::grpc::testing::Response>* + reactor) = 0; // Method A3 trailing comment 1 // Method A4 leading comment 1 - virtual ::grpc::experimental::ClientCallbackReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4(::grpc::ClientContext* context, ::grpc::experimental::ClientBidiReactor* reactor) = 0; + virtual void MethodA4( + ::grpc::ClientContext* context, + ::grpc::experimental::ClientBidiReactor<::grpc::testing::Request, + ::grpc::testing::Response>* + reactor) = 0; // Method A4 trailing comment 1 }; - virtual class experimental_async_interface* experimental_async() { return nullptr; } - private: - virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; - virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* PrepareAsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; - virtual ::grpc::ClientWriterInterface< ::grpc::testing::Request>* MethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response) = 0; - virtual ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>* AsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) = 0; - virtual ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>* PrepareAsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq) = 0; - virtual ::grpc::ClientReaderInterface< ::grpc::testing::Response>* MethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request) = 0; - virtual ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>* AsyncMethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) = 0; - virtual ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>* PrepareAsyncMethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; - virtual ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4Raw(::grpc::ClientContext* context) = 0; - virtual ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>* AsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) = 0; - virtual ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>* PrepareAsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) = 0; + virtual class experimental_async_interface* experimental_async() { + return nullptr; + } + + private: + virtual ::grpc::ClientAsyncResponseReaderInterface< + ::grpc::testing::Response>* + AsyncMethodA1Raw(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< + ::grpc::testing::Response>* + PrepareAsyncMethodA1Raw(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientWriterInterface<::grpc::testing::Request>* + MethodA2Raw(::grpc::ClientContext* context, + ::grpc::testing::Response* response) = 0; + virtual ::grpc::ClientAsyncWriterInterface<::grpc::testing::Request>* + AsyncMethodA2Raw(::grpc::ClientContext* context, + ::grpc::testing::Response* response, + ::grpc::CompletionQueue* cq, void* tag) = 0; + virtual ::grpc::ClientAsyncWriterInterface<::grpc::testing::Request>* + PrepareAsyncMethodA2Raw(::grpc::ClientContext* context, + ::grpc::testing::Response* response, + ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientReaderInterface<::grpc::testing::Response>* + MethodA3Raw(::grpc::ClientContext* context, + const ::grpc::testing::Request& request) = 0; + virtual ::grpc::ClientAsyncReaderInterface<::grpc::testing::Response>* + AsyncMethodA3Raw(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq, void* tag) = 0; + virtual ::grpc::ClientAsyncReaderInterface<::grpc::testing::Response>* + PrepareAsyncMethodA3Raw(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientReaderWriterInterface<::grpc::testing::Request, + ::grpc::testing::Response>* + MethodA4Raw(::grpc::ClientContext* context) = 0; + virtual ::grpc::ClientAsyncReaderWriterInterface<::grpc::testing::Request, + ::grpc::testing::Response>* + AsyncMethodA4Raw(::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq, void* tag) = 0; + virtual ::grpc::ClientAsyncReaderWriterInterface<::grpc::testing::Request, + ::grpc::testing::Response>* + PrepareAsyncMethodA4Raw(::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq) = 0; }; class Stub final : public StubInterface { public: - Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); - ::grpc::Status MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response) override; - std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>> AsyncMethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>>(AsyncMethodA1Raw(context, request, cq)); + Stub(const std::shared_ptr<::grpc::ChannelInterface>& channel); + ::grpc::Status MethodA1(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::testing::Response* response) override; + std::unique_ptr< + ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>> + AsyncMethodA1(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr< + ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>>( + AsyncMethodA1Raw(context, request, cq)); } - std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>> PrepareAsyncMethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>>(PrepareAsyncMethodA1Raw(context, request, cq)); + std::unique_ptr< + ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>> + PrepareAsyncMethodA1(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr< + ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>>( + PrepareAsyncMethodA1Raw(context, request, cq)); } - std::unique_ptr< ::grpc::ClientWriter< ::grpc::testing::Request>> MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response) { - return std::unique_ptr< ::grpc::ClientWriter< ::grpc::testing::Request>>(MethodA2Raw(context, response)); + std::unique_ptr<::grpc::ClientWriter<::grpc::testing::Request>> MethodA2( + ::grpc::ClientContext* context, ::grpc::testing::Response* response) { + return std::unique_ptr<::grpc::ClientWriter<::grpc::testing::Request>>( + MethodA2Raw(context, response)); } - std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>> AsyncMethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) { - return std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>>(AsyncMethodA2Raw(context, response, cq, tag)); + std::unique_ptr<::grpc::ClientAsyncWriter<::grpc::testing::Request>> + AsyncMethodA2(::grpc::ClientContext* context, + ::grpc::testing::Response* response, + ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< + ::grpc::ClientAsyncWriter<::grpc::testing::Request>>( + AsyncMethodA2Raw(context, response, cq, tag)); } - std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>> PrepareAsyncMethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>>(PrepareAsyncMethodA2Raw(context, response, cq)); + std::unique_ptr<::grpc::ClientAsyncWriter<::grpc::testing::Request>> + PrepareAsyncMethodA2(::grpc::ClientContext* context, + ::grpc::testing::Response* response, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr< + ::grpc::ClientAsyncWriter<::grpc::testing::Request>>( + PrepareAsyncMethodA2Raw(context, response, cq)); } - std::unique_ptr< ::grpc::ClientReader< ::grpc::testing::Response>> MethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request) { - return std::unique_ptr< ::grpc::ClientReader< ::grpc::testing::Response>>(MethodA3Raw(context, request)); + std::unique_ptr<::grpc::ClientReader<::grpc::testing::Response>> MethodA3( + ::grpc::ClientContext* context, + const ::grpc::testing::Request& request) { + return std::unique_ptr<::grpc::ClientReader<::grpc::testing::Response>>( + MethodA3Raw(context, request)); } - std::unique_ptr< ::grpc::ClientAsyncReader< ::grpc::testing::Response>> AsyncMethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) { - return std::unique_ptr< ::grpc::ClientAsyncReader< ::grpc::testing::Response>>(AsyncMethodA3Raw(context, request, cq, tag)); + std::unique_ptr<::grpc::ClientAsyncReader<::grpc::testing::Response>> + AsyncMethodA3(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< + ::grpc::ClientAsyncReader<::grpc::testing::Response>>( + AsyncMethodA3Raw(context, request, cq, tag)); } - std::unique_ptr< ::grpc::ClientAsyncReader< ::grpc::testing::Response>> PrepareAsyncMethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncReader< ::grpc::testing::Response>>(PrepareAsyncMethodA3Raw(context, request, cq)); + std::unique_ptr<::grpc::ClientAsyncReader<::grpc::testing::Response>> + PrepareAsyncMethodA3(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr< + ::grpc::ClientAsyncReader<::grpc::testing::Response>>( + PrepareAsyncMethodA3Raw(context, request, cq)); } - std::unique_ptr< ::grpc::ClientReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>> MethodA4(::grpc::ClientContext* context) { - return std::unique_ptr< ::grpc::ClientReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>>(MethodA4Raw(context)); + std::unique_ptr<::grpc::ClientReaderWriter<::grpc::testing::Request, + ::grpc::testing::Response>> + MethodA4(::grpc::ClientContext* context) { + return std::unique_ptr<::grpc::ClientReaderWriter< + ::grpc::testing::Request, ::grpc::testing::Response>>( + MethodA4Raw(context)); } - std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>> AsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { - return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>>(AsyncMethodA4Raw(context, cq, tag)); + std::unique_ptr<::grpc::ClientAsyncReaderWriter<::grpc::testing::Request, + ::grpc::testing::Response>> + AsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, + void* tag) { + return std::unique_ptr<::grpc::ClientAsyncReaderWriter< + ::grpc::testing::Request, ::grpc::testing::Response>>( + AsyncMethodA4Raw(context, cq, tag)); } - std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>> PrepareAsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>>(PrepareAsyncMethodA4Raw(context, cq)); + std::unique_ptr<::grpc::ClientAsyncReaderWriter<::grpc::testing::Request, + ::grpc::testing::Response>> + PrepareAsyncMethodA4(::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr<::grpc::ClientAsyncReaderWriter< + ::grpc::testing::Request, ::grpc::testing::Response>>( + PrepareAsyncMethodA4Raw(context, cq)); } - class experimental_async final : - public StubInterface::experimental_async_interface { + class experimental_async final + : public StubInterface::experimental_async_interface { public: - void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) override; - ::grpc::experimental::ClientCallbackWriter< ::grpc::testing::Request>* MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::experimental::ClientWriteReactor* reactor) override; - ::grpc::experimental::ClientCallbackReader< ::grpc::testing::Response>* MethodA3(::grpc::ClientContext* context, ::grpc::testing::Request* request, ::grpc::experimental::ClientReadReactor* reactor) override; - ::grpc::experimental::ClientCallbackReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4(::grpc::ClientContext* context, ::grpc::experimental::ClientBidiReactor* reactor) override; + void MethodA1(::grpc::ClientContext* context, + const ::grpc::testing::Request* 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; + private: friend class Stub; - explicit experimental_async(Stub* stub): stub_(stub) { } + explicit experimental_async(Stub* stub) : stub_(stub) {} Stub* stub() { return stub_; } Stub* stub_; }; - class experimental_async_interface* experimental_async() override { return &async_stub_; } + class experimental_async_interface* experimental_async() override { + return &async_stub_; + } private: - std::shared_ptr< ::grpc::ChannelInterface> channel_; - class experimental_async async_stub_{this}; - ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; - ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* PrepareAsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; - ::grpc::ClientWriter< ::grpc::testing::Request>* MethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response) override; - ::grpc::ClientAsyncWriter< ::grpc::testing::Request>* AsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) override; - ::grpc::ClientAsyncWriter< ::grpc::testing::Request>* PrepareAsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq) override; - ::grpc::ClientReader< ::grpc::testing::Response>* MethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request) override; - ::grpc::ClientAsyncReader< ::grpc::testing::Response>* AsyncMethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) override; - ::grpc::ClientAsyncReader< ::grpc::testing::Response>* PrepareAsyncMethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; - ::grpc::ClientReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4Raw(::grpc::ClientContext* context) override; - ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* AsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) override; - ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* PrepareAsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) override; + std::shared_ptr<::grpc::ChannelInterface> channel_; + class experimental_async async_stub_ { + this + }; + ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>* + AsyncMethodA1Raw(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) override; + ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>* + PrepareAsyncMethodA1Raw(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) override; + ::grpc::ClientWriter<::grpc::testing::Request>* MethodA2Raw( + ::grpc::ClientContext* context, + ::grpc::testing::Response* response) override; + ::grpc::ClientAsyncWriter<::grpc::testing::Request>* AsyncMethodA2Raw( + ::grpc::ClientContext* context, ::grpc::testing::Response* response, + ::grpc::CompletionQueue* cq, void* tag) override; + ::grpc::ClientAsyncWriter<::grpc::testing::Request>* + PrepareAsyncMethodA2Raw(::grpc::ClientContext* context, + ::grpc::testing::Response* response, + ::grpc::CompletionQueue* cq) override; + ::grpc::ClientReader<::grpc::testing::Response>* MethodA3Raw( + ::grpc::ClientContext* context, + const ::grpc::testing::Request& request) override; + ::grpc::ClientAsyncReader<::grpc::testing::Response>* AsyncMethodA3Raw( + ::grpc::ClientContext* context, const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq, void* tag) override; + ::grpc::ClientAsyncReader<::grpc::testing::Response>* + PrepareAsyncMethodA3Raw(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) override; + ::grpc::ClientReaderWriter<::grpc::testing::Request, + ::grpc::testing::Response>* + MethodA4Raw(::grpc::ClientContext* context) override; + ::grpc::ClientAsyncReaderWriter<::grpc::testing::Request, + ::grpc::testing::Response>* + AsyncMethodA4Raw(::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq, void* tag) override; + ::grpc::ClientAsyncReaderWriter<::grpc::testing::Request, + ::grpc::testing::Response>* + PrepareAsyncMethodA4Raw(::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq) override; const ::grpc::internal::RpcMethod rpcmethod_MethodA1_; const ::grpc::internal::RpcMethod rpcmethod_MethodA2_; const ::grpc::internal::RpcMethod rpcmethod_MethodA3_; const ::grpc::internal::RpcMethod rpcmethod_MethodA4_; }; - static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); + static std::unique_ptr NewStub( + const std::shared_ptr<::grpc::ChannelInterface>& channel, + const ::grpc::StubOptions& options = ::grpc::StubOptions()); class Service : public ::grpc::Service { public: Service(); virtual ~Service(); // MethodA1 leading comment 1 - virtual ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response); + virtual ::grpc::Status MethodA1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response); // MethodA1 trailing comment 1 // MethodA2 detached leading comment 1 // // Method A2 leading comment 1 // Method A2 leading comment 2 - virtual ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response); + virtual ::grpc::Status MethodA2( + ::grpc::ServerContext* context, + ::grpc::ServerReader<::grpc::testing::Request>* reader, + ::grpc::testing::Response* response); // MethodA2 trailing comment 1 // Method A3 leading comment 1 - virtual ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer); + virtual ::grpc::Status MethodA3( + ::grpc::ServerContext* context, const ::grpc::testing::Request* request, + ::grpc::ServerWriter<::grpc::testing::Response>* writer); // Method A3 trailing comment 1 // Method A4 leading comment 1 - virtual ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream); + virtual ::grpc::Status MethodA4( + ::grpc::ServerContext* context, + ::grpc::ServerReaderWriter<::grpc::testing::Response, + ::grpc::testing::Request>* stream); // Method A4 trailing comment 1 }; template class WithAsyncMethod_MethodA1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithAsyncMethod_MethodA1() { - ::grpc::Service::MarkMethodAsync(0); - } + WithAsyncMethod_MethodA1() { ::grpc::Service::MarkMethodAsync(0); } ~WithAsyncMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { + ::grpc::Status MethodA1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA1(::grpc::ServerContext* context, ::grpc::testing::Request* request, ::grpc::ServerAsyncResponseWriter< ::grpc::testing::Response>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); + void RequestMethodA1( + ::grpc::ServerContext* context, ::grpc::testing::Request* request, + ::grpc::ServerAsyncResponseWriter<::grpc::testing::Response>* response, + ::grpc::CompletionQueue* new_call_cq, + ::grpc::ServerCompletionQueue* notification_cq, void* tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, + new_call_cq, notification_cq, tag); } }; template class WithAsyncMethod_MethodA2 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithAsyncMethod_MethodA2() { - ::grpc::Service::MarkMethodAsync(1); - } + WithAsyncMethod_MethodA2() { ::grpc::Service::MarkMethodAsync(1); } ~WithAsyncMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) override { + ::grpc::Status MethodA2( + ::grpc::ServerContext* context, + ::grpc::ServerReader<::grpc::testing::Request>* reader, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA2(::grpc::ServerContext* context, ::grpc::ServerAsyncReader< ::grpc::testing::Response, ::grpc::testing::Request>* reader, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncClientStreaming(1, context, reader, new_call_cq, notification_cq, tag); + void RequestMethodA2( + ::grpc::ServerContext* context, + ::grpc::ServerAsyncReader<::grpc::testing::Response, + ::grpc::testing::Request>* reader, + ::grpc::CompletionQueue* new_call_cq, + ::grpc::ServerCompletionQueue* notification_cq, void* tag) { + ::grpc::Service::RequestAsyncClientStreaming( + 1, context, reader, new_call_cq, notification_cq, tag); } }; template class WithAsyncMethod_MethodA3 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithAsyncMethod_MethodA3() { - ::grpc::Service::MarkMethodAsync(2); - } + WithAsyncMethod_MethodA3() { ::grpc::Service::MarkMethodAsync(2); } ~WithAsyncMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override { + ::grpc::Status MethodA3( + ::grpc::ServerContext* context, const ::grpc::testing::Request* request, + ::grpc::ServerWriter<::grpc::testing::Response>* writer) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA3(::grpc::ServerContext* context, ::grpc::testing::Request* request, ::grpc::ServerAsyncWriter< ::grpc::testing::Response>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncServerStreaming(2, context, request, writer, new_call_cq, notification_cq, tag); + void RequestMethodA3( + ::grpc::ServerContext* context, ::grpc::testing::Request* request, + ::grpc::ServerAsyncWriter<::grpc::testing::Response>* writer, + ::grpc::CompletionQueue* new_call_cq, + ::grpc::ServerCompletionQueue* notification_cq, void* tag) { + ::grpc::Service::RequestAsyncServerStreaming( + 2, context, request, writer, new_call_cq, notification_cq, tag); } }; template class WithAsyncMethod_MethodA4 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithAsyncMethod_MethodA4() { - ::grpc::Service::MarkMethodAsync(3); - } + WithAsyncMethod_MethodA4() { ::grpc::Service::MarkMethodAsync(3); } ~WithAsyncMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) override { + ::grpc::Status MethodA4( + ::grpc::ServerContext* context, + ::grpc::ServerReaderWriter<::grpc::testing::Response, + ::grpc::testing::Request>* stream) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA4(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncBidiStreaming(3, context, stream, new_call_cq, notification_cq, tag); + void RequestMethodA4( + ::grpc::ServerContext* context, + ::grpc::ServerAsyncReaderWriter<::grpc::testing::Response, + ::grpc::testing::Request>* stream, + ::grpc::CompletionQueue* new_call_cq, + ::grpc::ServerCompletionQueue* notification_cq, void* tag) { + ::grpc::Service::RequestAsyncBidiStreaming( + 3, context, stream, new_call_cq, notification_cq, tag); } }; - typedef WithAsyncMethod_MethodA1 > > > AsyncService; + typedef WithAsyncMethod_MethodA1>>> + AsyncService; template class ExperimentalWithCallbackMethod_MethodA1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: ExperimentalWithCallbackMethod_MethodA1() { - ::grpc::Service::experimental().MarkMethodCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithCallbackMethod_MethodA1, ::grpc::testing::Request, ::grpc::testing::Response>( - [this](::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response, - ::grpc::experimental::ServerCallbackRpcController* controller) { + ::grpc::Service::experimental().MarkMethodCallback( + 0, new ::grpc::internal::CallbackUnaryHandler< + ExperimentalWithCallbackMethod_MethodA1, + ::grpc::testing::Request, ::grpc::testing::Response>( + [this](::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response, + ::grpc::experimental::ServerCallbackRpcController* + controller) { this->MethodA1(context, request, response, controller); - }, this)); + }, + this)); } ~ExperimentalWithCallbackMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { + ::grpc::Status MethodA1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - virtual void MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ServerCallbackRpcController* controller) { controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); } + virtual void MethodA1( + ::grpc::ServerContext* context, const ::grpc::testing::Request* request, + ::grpc::testing::Response* response, + ::grpc::experimental::ServerCallbackRpcController* controller) { + controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); + } }; template class ExperimentalWithCallbackMethod_MethodA2 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - ExperimentalWithCallbackMethod_MethodA2() { - } + ExperimentalWithCallbackMethod_MethodA2() {} ~ExperimentalWithCallbackMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) override { + ::grpc::Status MethodA2( + ::grpc::ServerContext* context, + ::grpc::ServerReader<::grpc::testing::Request>* reader, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -359,15 +621,17 @@ class ServiceA final { template class ExperimentalWithCallbackMethod_MethodA3 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - ExperimentalWithCallbackMethod_MethodA3() { - } + ExperimentalWithCallbackMethod_MethodA3() {} ~ExperimentalWithCallbackMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override { + ::grpc::Status MethodA3( + ::grpc::ServerContext* context, const ::grpc::testing::Request* request, + ::grpc::ServerWriter<::grpc::testing::Response>* writer) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -375,33 +639,41 @@ class ServiceA final { template class ExperimentalWithCallbackMethod_MethodA4 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - ExperimentalWithCallbackMethod_MethodA4() { - } + ExperimentalWithCallbackMethod_MethodA4() {} ~ExperimentalWithCallbackMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) override { + ::grpc::Status MethodA4( + ::grpc::ServerContext* context, + ::grpc::ServerReaderWriter<::grpc::testing::Response, + ::grpc::testing::Request>* stream) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } }; - typedef ExperimentalWithCallbackMethod_MethodA1 > > > ExperimentalCallbackService; + typedef ExperimentalWithCallbackMethod_MethodA1< + ExperimentalWithCallbackMethod_MethodA2< + ExperimentalWithCallbackMethod_MethodA3< + ExperimentalWithCallbackMethod_MethodA4>>> + ExperimentalCallbackService; template class WithGenericMethod_MethodA1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithGenericMethod_MethodA1() { - ::grpc::Service::MarkMethodGeneric(0); - } + WithGenericMethod_MethodA1() { ::grpc::Service::MarkMethodGeneric(0); } ~WithGenericMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { + ::grpc::Status MethodA1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -409,16 +681,18 @@ class ServiceA final { template class WithGenericMethod_MethodA2 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithGenericMethod_MethodA2() { - ::grpc::Service::MarkMethodGeneric(1); - } + WithGenericMethod_MethodA2() { ::grpc::Service::MarkMethodGeneric(1); } ~WithGenericMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) override { + ::grpc::Status MethodA2( + ::grpc::ServerContext* context, + ::grpc::ServerReader<::grpc::testing::Request>* reader, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -426,16 +700,17 @@ class ServiceA final { template class WithGenericMethod_MethodA3 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithGenericMethod_MethodA3() { - ::grpc::Service::MarkMethodGeneric(2); - } + WithGenericMethod_MethodA3() { ::grpc::Service::MarkMethodGeneric(2); } ~WithGenericMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override { + ::grpc::Status MethodA3( + ::grpc::ServerContext* context, const ::grpc::testing::Request* request, + ::grpc::ServerWriter<::grpc::testing::Response>* writer) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -443,16 +718,18 @@ class ServiceA final { template class WithGenericMethod_MethodA4 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithGenericMethod_MethodA4() { - ::grpc::Service::MarkMethodGeneric(3); - } + WithGenericMethod_MethodA4() { ::grpc::Service::MarkMethodGeneric(3); } ~WithGenericMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) override { + ::grpc::Status MethodA4( + ::grpc::ServerContext* context, + ::grpc::ServerReaderWriter<::grpc::testing::Response, + ::grpc::testing::Request>* stream) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -460,120 +737,164 @@ class ServiceA final { template class WithRawMethod_MethodA1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithRawMethod_MethodA1() { - ::grpc::Service::MarkMethodRaw(0); - } + WithRawMethod_MethodA1() { ::grpc::Service::MarkMethodRaw(0); } ~WithRawMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { + ::grpc::Status MethodA1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA1(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); + void RequestMethodA1( + ::grpc::ServerContext* context, ::grpc::ByteBuffer* request, + ::grpc::ServerAsyncResponseWriter<::grpc::ByteBuffer>* response, + ::grpc::CompletionQueue* new_call_cq, + ::grpc::ServerCompletionQueue* notification_cq, void* tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, + new_call_cq, notification_cq, tag); } }; template class WithRawMethod_MethodA2 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithRawMethod_MethodA2() { - ::grpc::Service::MarkMethodRaw(1); - } + WithRawMethod_MethodA2() { ::grpc::Service::MarkMethodRaw(1); } ~WithRawMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) override { + ::grpc::Status MethodA2( + ::grpc::ServerContext* context, + ::grpc::ServerReader<::grpc::testing::Request>* reader, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA2(::grpc::ServerContext* context, ::grpc::ServerAsyncReader< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* reader, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncClientStreaming(1, context, reader, new_call_cq, notification_cq, tag); + void RequestMethodA2(::grpc::ServerContext* context, + ::grpc::ServerAsyncReader<::grpc::ByteBuffer, + ::grpc::ByteBuffer>* reader, + ::grpc::CompletionQueue* new_call_cq, + ::grpc::ServerCompletionQueue* notification_cq, + void* tag) { + ::grpc::Service::RequestAsyncClientStreaming( + 1, context, reader, new_call_cq, notification_cq, tag); } }; template class WithRawMethod_MethodA3 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithRawMethod_MethodA3() { - ::grpc::Service::MarkMethodRaw(2); - } + WithRawMethod_MethodA3() { ::grpc::Service::MarkMethodRaw(2); } ~WithRawMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override { + ::grpc::Status MethodA3( + ::grpc::ServerContext* context, const ::grpc::testing::Request* request, + ::grpc::ServerWriter<::grpc::testing::Response>* writer) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA3(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncServerStreaming(2, context, request, writer, new_call_cq, notification_cq, tag); + void RequestMethodA3(::grpc::ServerContext* context, + ::grpc::ByteBuffer* request, + ::grpc::ServerAsyncWriter<::grpc::ByteBuffer>* writer, + ::grpc::CompletionQueue* new_call_cq, + ::grpc::ServerCompletionQueue* notification_cq, + void* tag) { + ::grpc::Service::RequestAsyncServerStreaming( + 2, context, request, writer, new_call_cq, notification_cq, tag); } }; template class WithRawMethod_MethodA4 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithRawMethod_MethodA4() { - ::grpc::Service::MarkMethodRaw(3); - } + WithRawMethod_MethodA4() { ::grpc::Service::MarkMethodRaw(3); } ~WithRawMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) override { + ::grpc::Status MethodA4( + ::grpc::ServerContext* context, + ::grpc::ServerReaderWriter<::grpc::testing::Response, + ::grpc::testing::Request>* stream) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA4(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncBidiStreaming(3, context, stream, new_call_cq, notification_cq, tag); + void RequestMethodA4( + ::grpc::ServerContext* context, + ::grpc::ServerAsyncReaderWriter<::grpc::ByteBuffer, ::grpc::ByteBuffer>* + stream, + ::grpc::CompletionQueue* new_call_cq, + ::grpc::ServerCompletionQueue* notification_cq, void* tag) { + ::grpc::Service::RequestAsyncBidiStreaming( + 3, context, stream, new_call_cq, notification_cq, tag); } }; template class ExperimentalWithRawCallbackMethod_MethodA1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: ExperimentalWithRawCallbackMethod_MethodA1() { - ::grpc::Service::experimental().MarkMethodRawCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithRawCallbackMethod_MethodA1, ::grpc::ByteBuffer, ::grpc::ByteBuffer>( - [this](::grpc::ServerContext* context, - const ::grpc::ByteBuffer* request, - ::grpc::ByteBuffer* response, - ::grpc::experimental::ServerCallbackRpcController* controller) { + ::grpc::Service::experimental().MarkMethodRawCallback( + 0, new ::grpc::internal::CallbackUnaryHandler< + ExperimentalWithRawCallbackMethod_MethodA1, + ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this](::grpc::ServerContext* context, + const ::grpc::ByteBuffer* request, + ::grpc::ByteBuffer* response, + ::grpc::experimental::ServerCallbackRpcController* + controller) { this->MethodA1(context, request, response, controller); - }, this)); + }, + this)); } ~ExperimentalWithRawCallbackMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { + ::grpc::Status MethodA1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - virtual void MethodA1(::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response, ::grpc::experimental::ServerCallbackRpcController* controller) { controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); } + virtual void MethodA1( + ::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, + ::grpc::ByteBuffer* response, + ::grpc::experimental::ServerCallbackRpcController* controller) { + controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); + } }; template class ExperimentalWithRawCallbackMethod_MethodA2 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - ExperimentalWithRawCallbackMethod_MethodA2() { - } + ExperimentalWithRawCallbackMethod_MethodA2() {} ~ExperimentalWithRawCallbackMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) override { + ::grpc::Status MethodA2( + ::grpc::ServerContext* context, + ::grpc::ServerReader<::grpc::testing::Request>* reader, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -581,15 +902,17 @@ class ServiceA final { template class ExperimentalWithRawCallbackMethod_MethodA3 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - ExperimentalWithRawCallbackMethod_MethodA3() { - } + ExperimentalWithRawCallbackMethod_MethodA3() {} ~ExperimentalWithRawCallbackMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override { + ::grpc::Status MethodA3( + ::grpc::ServerContext* context, const ::grpc::testing::Request* request, + ::grpc::ServerWriter<::grpc::testing::Response>* writer) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -597,15 +920,18 @@ class ServiceA final { template class ExperimentalWithRawCallbackMethod_MethodA4 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - ExperimentalWithRawCallbackMethod_MethodA4() { - } + ExperimentalWithRawCallbackMethod_MethodA4() {} ~ExperimentalWithRawCallbackMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) override { + ::grpc::Status MethodA4( + ::grpc::ServerContext* context, + ::grpc::ServerReaderWriter<::grpc::testing::Response, + ::grpc::testing::Request>* stream) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -613,46 +939,69 @@ class ServiceA final { template class WithStreamedUnaryMethod_MethodA1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: WithStreamedUnaryMethod_MethodA1() { - ::grpc::Service::MarkMethodStreamed(0, - new ::grpc::internal::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodA1::StreamedMethodA1, this, std::placeholders::_1, std::placeholders::_2))); + ::grpc::Service::MarkMethodStreamed( + 0, new ::grpc::internal::StreamedUnaryHandler< + ::grpc::testing::Request, ::grpc::testing::Response>(std::bind( + &WithStreamedUnaryMethod_MethodA1::StreamedMethodA1, + this, std::placeholders::_1, std::placeholders::_2))); } ~WithStreamedUnaryMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); } // disable regular version of this method - ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { + ::grpc::Status MethodA1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } // replace default version of method with streamed unary - virtual ::grpc::Status StreamedMethodA1(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_unary_streamer) = 0; + virtual ::grpc::Status StreamedMethodA1( + ::grpc::ServerContext* context, + ::grpc::ServerUnaryStreamer<::grpc::testing::Request, + ::grpc::testing::Response>* + server_unary_streamer) = 0; }; - typedef WithStreamedUnaryMethod_MethodA1 StreamedUnaryService; + typedef WithStreamedUnaryMethod_MethodA1 StreamedUnaryService; template class WithSplitStreamingMethod_MethodA3 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: WithSplitStreamingMethod_MethodA3() { - ::grpc::Service::MarkMethodStreamed(2, - new ::grpc::internal::SplitServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithSplitStreamingMethod_MethodA3::StreamedMethodA3, this, std::placeholders::_1, std::placeholders::_2))); + ::grpc::Service::MarkMethodStreamed( + 2, + new ::grpc::internal::SplitServerStreamingHandler< + ::grpc::testing::Request, ::grpc::testing::Response>(std::bind( + &WithSplitStreamingMethod_MethodA3::StreamedMethodA3, + this, std::placeholders::_1, std::placeholders::_2))); } ~WithSplitStreamingMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); } // disable regular version of this method - ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override { + ::grpc::Status MethodA3( + ::grpc::ServerContext* context, const ::grpc::testing::Request* request, + ::grpc::ServerWriter<::grpc::testing::Response>* writer) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } // replace default version of method with split streamed - virtual ::grpc::Status StreamedMethodA3(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_split_streamer) = 0; + virtual ::grpc::Status StreamedMethodA3( + ::grpc::ServerContext* context, + ::grpc::ServerSplitStreamer<::grpc::testing::Request, + ::grpc::testing::Response>* + server_split_streamer) = 0; }; - typedef WithSplitStreamingMethod_MethodA3 SplitStreamedService; - typedef WithStreamedUnaryMethod_MethodA1 > StreamedService; + typedef WithSplitStreamingMethod_MethodA3 SplitStreamedService; + typedef WithStreamedUnaryMethod_MethodA1< + WithSplitStreamingMethod_MethodA3> + StreamedService; }; // ServiceB leading comment 1 @@ -665,125 +1014,204 @@ class ServiceB final { public: virtual ~StubInterface() {} // MethodB1 leading comment 1 - virtual ::grpc::Status MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response) = 0; - std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>> AsyncMethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>>(AsyncMethodB1Raw(context, request, cq)); + virtual ::grpc::Status MethodB1(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::testing::Response* response) = 0; + std::unique_ptr< + ::grpc::ClientAsyncResponseReaderInterface<::grpc::testing::Response>> + AsyncMethodB1(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface< + ::grpc::testing::Response>>(AsyncMethodB1Raw(context, request, cq)); } - std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>> PrepareAsyncMethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>>(PrepareAsyncMethodB1Raw(context, request, cq)); + std::unique_ptr< + ::grpc::ClientAsyncResponseReaderInterface<::grpc::testing::Response>> + PrepareAsyncMethodB1(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface< + ::grpc::testing::Response>>( + PrepareAsyncMethodB1Raw(context, request, cq)); } // MethodB1 trailing comment 1 class experimental_async_interface { public: 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::testing::Request* request, + ::grpc::testing::Response* response, + std::function) = 0; // MethodB1 trailing comment 1 }; - virtual class experimental_async_interface* experimental_async() { return nullptr; } - private: - virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* AsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; - virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* PrepareAsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; + virtual class experimental_async_interface* experimental_async() { + return nullptr; + } + + private: + virtual ::grpc::ClientAsyncResponseReaderInterface< + ::grpc::testing::Response>* + AsyncMethodB1Raw(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< + ::grpc::testing::Response>* + PrepareAsyncMethodB1Raw(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) = 0; }; class Stub final : public StubInterface { public: - Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); - ::grpc::Status MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response) override; - std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>> AsyncMethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>>(AsyncMethodB1Raw(context, request, cq)); + Stub(const std::shared_ptr<::grpc::ChannelInterface>& channel); + ::grpc::Status MethodB1(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::testing::Response* response) override; + std::unique_ptr< + ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>> + AsyncMethodB1(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr< + ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>>( + AsyncMethodB1Raw(context, request, cq)); } - std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>> PrepareAsyncMethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>>(PrepareAsyncMethodB1Raw(context, request, cq)); + std::unique_ptr< + ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>> + PrepareAsyncMethodB1(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) { + return std::unique_ptr< + ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>>( + PrepareAsyncMethodB1Raw(context, request, cq)); } - class experimental_async final : - public StubInterface::experimental_async_interface { + class experimental_async 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::testing::Request* request, + ::grpc::testing::Response* response, + std::function) override; + private: friend class Stub; - explicit experimental_async(Stub* stub): stub_(stub) { } + explicit experimental_async(Stub* stub) : stub_(stub) {} Stub* stub() { return stub_; } Stub* stub_; }; - class experimental_async_interface* experimental_async() override { return &async_stub_; } + class experimental_async_interface* experimental_async() override { + return &async_stub_; + } private: - std::shared_ptr< ::grpc::ChannelInterface> channel_; - class experimental_async async_stub_{this}; - ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* AsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; - ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* PrepareAsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; + std::shared_ptr<::grpc::ChannelInterface> channel_; + class experimental_async async_stub_ { + this + }; + ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>* + AsyncMethodB1Raw(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) override; + ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>* + PrepareAsyncMethodB1Raw(::grpc::ClientContext* context, + const ::grpc::testing::Request& request, + ::grpc::CompletionQueue* cq) override; const ::grpc::internal::RpcMethod rpcmethod_MethodB1_; }; - static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); + static std::unique_ptr NewStub( + const std::shared_ptr<::grpc::ChannelInterface>& channel, + const ::grpc::StubOptions& options = ::grpc::StubOptions()); class Service : public ::grpc::Service { public: Service(); virtual ~Service(); // MethodB1 leading comment 1 - virtual ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response); + virtual ::grpc::Status MethodB1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response); // MethodB1 trailing comment 1 }; template class WithAsyncMethod_MethodB1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithAsyncMethod_MethodB1() { - ::grpc::Service::MarkMethodAsync(0); - } + WithAsyncMethod_MethodB1() { ::grpc::Service::MarkMethodAsync(0); } ~WithAsyncMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { + ::grpc::Status MethodB1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodB1(::grpc::ServerContext* context, ::grpc::testing::Request* request, ::grpc::ServerAsyncResponseWriter< ::grpc::testing::Response>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); + void RequestMethodB1( + ::grpc::ServerContext* context, ::grpc::testing::Request* request, + ::grpc::ServerAsyncResponseWriter<::grpc::testing::Response>* response, + ::grpc::CompletionQueue* new_call_cq, + ::grpc::ServerCompletionQueue* notification_cq, void* tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, + new_call_cq, notification_cq, tag); } }; - typedef WithAsyncMethod_MethodB1 AsyncService; + typedef WithAsyncMethod_MethodB1 AsyncService; template class ExperimentalWithCallbackMethod_MethodB1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: ExperimentalWithCallbackMethod_MethodB1() { - ::grpc::Service::experimental().MarkMethodCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithCallbackMethod_MethodB1, ::grpc::testing::Request, ::grpc::testing::Response>( - [this](::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response, - ::grpc::experimental::ServerCallbackRpcController* controller) { + ::grpc::Service::experimental().MarkMethodCallback( + 0, new ::grpc::internal::CallbackUnaryHandler< + ExperimentalWithCallbackMethod_MethodB1, + ::grpc::testing::Request, ::grpc::testing::Response>( + [this](::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response, + ::grpc::experimental::ServerCallbackRpcController* + controller) { this->MethodB1(context, request, response, controller); - }, this)); + }, + this)); } ~ExperimentalWithCallbackMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { + ::grpc::Status MethodB1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - virtual void MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ServerCallbackRpcController* controller) { controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); } + virtual void MethodB1( + ::grpc::ServerContext* context, const ::grpc::testing::Request* request, + ::grpc::testing::Response* response, + ::grpc::experimental::ServerCallbackRpcController* controller) { + controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); + } }; - typedef ExperimentalWithCallbackMethod_MethodB1 ExperimentalCallbackService; + typedef ExperimentalWithCallbackMethod_MethodB1 + ExperimentalCallbackService; template class WithGenericMethod_MethodB1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithGenericMethod_MethodB1() { - ::grpc::Service::MarkMethodGeneric(0); - } + WithGenericMethod_MethodB1() { ::grpc::Service::MarkMethodGeneric(0); } ~WithGenericMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { + ::grpc::Status MethodB1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -791,76 +1219,103 @@ class ServiceB final { template class WithRawMethod_MethodB1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: - WithRawMethod_MethodB1() { - ::grpc::Service::MarkMethodRaw(0); - } + WithRawMethod_MethodB1() { ::grpc::Service::MarkMethodRaw(0); } ~WithRawMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { + ::grpc::Status MethodB1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodB1(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); + void RequestMethodB1( + ::grpc::ServerContext* context, ::grpc::ByteBuffer* request, + ::grpc::ServerAsyncResponseWriter<::grpc::ByteBuffer>* response, + ::grpc::CompletionQueue* new_call_cq, + ::grpc::ServerCompletionQueue* notification_cq, void* tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, + new_call_cq, notification_cq, tag); } }; template class ExperimentalWithRawCallbackMethod_MethodB1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: ExperimentalWithRawCallbackMethod_MethodB1() { - ::grpc::Service::experimental().MarkMethodRawCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithRawCallbackMethod_MethodB1, ::grpc::ByteBuffer, ::grpc::ByteBuffer>( - [this](::grpc::ServerContext* context, - const ::grpc::ByteBuffer* request, - ::grpc::ByteBuffer* response, - ::grpc::experimental::ServerCallbackRpcController* controller) { + ::grpc::Service::experimental().MarkMethodRawCallback( + 0, new ::grpc::internal::CallbackUnaryHandler< + ExperimentalWithRawCallbackMethod_MethodB1, + ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this](::grpc::ServerContext* context, + const ::grpc::ByteBuffer* request, + ::grpc::ByteBuffer* response, + ::grpc::experimental::ServerCallbackRpcController* + controller) { this->MethodB1(context, request, response, controller); - }, this)); + }, + this)); } ~ExperimentalWithRawCallbackMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { + ::grpc::Status MethodB1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - virtual void MethodB1(::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response, ::grpc::experimental::ServerCallbackRpcController* controller) { controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); } + virtual void MethodB1( + ::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, + ::grpc::ByteBuffer* response, + ::grpc::experimental::ServerCallbackRpcController* controller) { + controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); + } }; template class WithStreamedUnaryMethod_MethodB1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service *service) {} + void BaseClassMustBeDerivedFromService(const Service* service) {} + public: WithStreamedUnaryMethod_MethodB1() { - ::grpc::Service::MarkMethodStreamed(0, - new ::grpc::internal::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodB1::StreamedMethodB1, this, std::placeholders::_1, std::placeholders::_2))); + ::grpc::Service::MarkMethodStreamed( + 0, new ::grpc::internal::StreamedUnaryHandler< + ::grpc::testing::Request, ::grpc::testing::Response>(std::bind( + &WithStreamedUnaryMethod_MethodB1::StreamedMethodB1, + this, std::placeholders::_1, std::placeholders::_2))); } ~WithStreamedUnaryMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); } // disable regular version of this method - ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { + ::grpc::Status MethodB1(::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } // replace default version of method with streamed unary - virtual ::grpc::Status StreamedMethodB1(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_unary_streamer) = 0; + virtual ::grpc::Status StreamedMethodB1( + ::grpc::ServerContext* context, + ::grpc::ServerUnaryStreamer<::grpc::testing::Request, + ::grpc::testing::Response>* + server_unary_streamer) = 0; }; - typedef WithStreamedUnaryMethod_MethodB1 StreamedUnaryService; + typedef WithStreamedUnaryMethod_MethodB1 StreamedUnaryService; typedef Service SplitStreamedService; - typedef WithStreamedUnaryMethod_MethodB1 StreamedService; + typedef WithStreamedUnaryMethod_MethodB1 StreamedService; }; // ServiceB trailing comment 1 } // namespace testing } // namespace grpc - #endif // GRPC_src_2fproto_2fgrpc_2ftesting_2fcompiler_5ftest_2eproto__INCLUDED diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 57c3cb87f2c..a1fe199b546 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -187,20 +187,20 @@ class ClientCallbackEnd2endTest grpc::string test_string(""); for (int i = 0; i < num_rpcs; i++) { test_string += "Hello world. "; - class Client : public grpc::experimental::ClientBidiReactor { + class Client : public grpc::experimental::ClientBidiReactor { public: Client(ClientCallbackEnd2endTest* test, const grpc::string& method_name, const grpc::string& test_str) { - stream_ = - test->generic_stub_->experimental().PrepareBidiStreamingCall( - &cli_ctx_, method_name, this); + test->generic_stub_->experimental().PrepareBidiStreamingCall( + &cli_ctx_, method_name, this); request_.set_message(test_str); send_buf_ = SerializeToByteBuffer(&request_); - stream_->Write(send_buf_.get()); - stream_->Read(&recv_buf_); - stream_->StartCall(); + StartWrite(send_buf_.get()); + StartRead(&recv_buf_); + StartCall(); } - void OnWriteDone(bool ok) override { stream_->WritesDone(); } + void OnWriteDone(bool ok) override { StartWritesDone(); } void OnReadDone(bool ok) override { EchoResponse response; EXPECT_TRUE(ParseFromByteBuffer(&recv_buf_, &response)); @@ -223,8 +223,6 @@ class ClientCallbackEnd2endTest std::unique_ptr send_buf_; ByteBuffer recv_buf_; ClientContext cli_ctx_; - experimental::ClientCallbackReaderWriter* - stream_; std::mutex mu_; std::condition_variable cv_; bool done_ = false; @@ -330,22 +328,21 @@ TEST_P(ClientCallbackEnd2endTest, RequestStream) { } ResetStub(); - class Client : public grpc::experimental::ClientWriteReactor { + class Client : public grpc::experimental::ClientWriteReactor { public: explicit Client(grpc::testing::EchoTestService::Stub* stub) { context_.set_initial_metadata_corked(true); - stream_ = stub->experimental_async()->RequestStream(&context_, &response_, - this); - stream_->StartCall(); + stub->experimental_async()->RequestStream(&context_, &response_, this); + StartCall(); request_.set_message("Hello server."); - stream_->Write(&request_); + StartWrite(&request_); } void OnWriteDone(bool ok) override { writes_left_--; if (writes_left_ > 1) { - stream_->Write(&request_); + StartWrite(&request_); } else if (writes_left_ == 1) { - stream_->WriteLast(&request_, WriteOptions()); + StartWriteLast(&request_, WriteOptions()); } } void OnDone(Status s) override { @@ -363,7 +360,6 @@ TEST_P(ClientCallbackEnd2endTest, RequestStream) { } private: - ::grpc::experimental::ClientCallbackWriter* stream_; EchoRequest request_; EchoResponse response_; ClientContext context_; @@ -383,14 +379,13 @@ TEST_P(ClientCallbackEnd2endTest, ResponseStream) { } ResetStub(); - class Client : public grpc::experimental::ClientReadReactor { + class Client : public grpc::experimental::ClientReadReactor { public: explicit Client(grpc::testing::EchoTestService::Stub* stub) { request_.set_message("Hello client "); - stream_ = stub->experimental_async()->ResponseStream(&context_, &request_, - this); - stream_->StartCall(); - stream_->Read(&response_); + stub->experimental_async()->ResponseStream(&context_, &request_, this); + StartCall(); + StartRead(&response_); } void OnReadDone(bool ok) override { if (!ok) { @@ -400,7 +395,7 @@ TEST_P(ClientCallbackEnd2endTest, ResponseStream) { EXPECT_EQ(response_.message(), request_.message() + grpc::to_string(reads_complete_)); reads_complete_++; - stream_->Read(&response_); + StartRead(&response_); } } void OnDone(Status s) override { @@ -417,7 +412,6 @@ TEST_P(ClientCallbackEnd2endTest, ResponseStream) { } private: - ::grpc::experimental::ClientCallbackReader* stream_; EchoRequest request_; EchoResponse response_; ClientContext context_; @@ -436,14 +430,15 @@ TEST_P(ClientCallbackEnd2endTest, BidiStream) { return; } ResetStub(); - class Client : public grpc::experimental::ClientBidiReactor { + class Client : public grpc::experimental::ClientBidiReactor { public: explicit Client(grpc::testing::EchoTestService::Stub* stub) { request_.set_message("Hello fren "); - stream_ = stub->experimental_async()->BidiStream(&context_, this); - stream_->StartCall(); - stream_->Read(&response_); - stream_->Write(&request_); + stub->experimental_async()->BidiStream(&context_, this); + StartCall(); + StartRead(&response_); + StartWrite(&request_); } void OnReadDone(bool ok) override { if (!ok) { @@ -452,15 +447,15 @@ TEST_P(ClientCallbackEnd2endTest, BidiStream) { EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend); EXPECT_EQ(response_.message(), request_.message()); reads_complete_++; - stream_->Read(&response_); + StartRead(&response_); } } void OnWriteDone(bool ok) override { EXPECT_TRUE(ok); if (++writes_complete_ == kServerDefaultResponseStreamsToSend) { - stream_->WritesDone(); + StartWritesDone(); } else { - stream_->Write(&request_); + StartWrite(&request_); } } void OnDone(Status s) override { @@ -477,8 +472,6 @@ TEST_P(ClientCallbackEnd2endTest, BidiStream) { } private: - ::grpc::experimental::ClientCallbackReaderWriter* - stream_; EchoRequest request_; EchoResponse response_; ClientContext context_; From 28dd7981d61645b17d91f754ecd85c3cede1bea7 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 30 Nov 2018 02:17:01 -0800 Subject: [PATCH 0379/2143] clang-format --- include/grpcpp/impl/codegen/client_callback.h | 129 ++++++++---------- 1 file changed, 60 insertions(+), 69 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 999c1c8a3e9..93266b8aa33 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -270,13 +270,12 @@ class ClientCallbackReaderWriterImpl // 4. Any write backlog started_ = true; - start_tag_.Set( - call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); if (!start_corked_) { start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, context_->initial_metadata_flags()); @@ -287,29 +286,27 @@ class ClientCallbackReaderWriterImpl // Also set up the read and write tags so that they don't have to be set up // each time - write_tag_.Set( - call_.call(), - [this](bool ok) { - reactor_->OnWriteDone(ok); - MaybeFinish(); - }, - &write_ops_); + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeFinish(); + }, + &write_ops_); write_ops_.set_core_cq_tag(&write_tag_); - read_tag_.Set( - call_.call(), - [this](bool ok) { - reactor_->OnReadDone(ok); - MaybeFinish(); - }, - &read_ops_); + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeFinish(); + }, + &read_ops_); read_ops_.set_core_cq_tag(&read_tag_); if (read_ops_at_start_) { call_.PerformOps(&read_ops_); } - finish_tag_.Set( - call_.call(), [this](bool ok) { MaybeFinish(); }, &finish_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_); @@ -360,13 +357,12 @@ class ClientCallbackReaderWriterImpl start_corked_ = false; } writes_done_ops_.ClientSendClose(); - writes_done_tag_.Set( - call_.call(), - [this](bool ok) { - reactor_->OnWritesDoneDone(ok); - MaybeFinish(); - }, - &writes_done_ops_); + writes_done_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWritesDoneDone(ok); + MaybeFinish(); + }, + &writes_done_ops_); writes_done_ops_.set_core_cq_tag(&writes_done_tag_); callbacks_outstanding_++; if (started_) { @@ -468,13 +464,12 @@ class ClientCallbackReaderImpl // 3. Recv trailing metadata, on_completion callback started_ = true; - start_tag_.Set( - call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, context_->initial_metadata_flags()); start_ops_.RecvInitialMetadata(context_); @@ -482,20 +477,19 @@ class ClientCallbackReaderImpl call_.PerformOps(&start_ops_); // Also set up the read tag so it doesn't have to be set up each time - read_tag_.Set( - call_.call(), - [this](bool ok) { - reactor_->OnReadDone(ok); - MaybeFinish(); - }, - &read_ops_); + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeFinish(); + }, + &read_ops_); read_ops_.set_core_cq_tag(&read_tag_); if (read_ops_at_start_) { call_.PerformOps(&read_ops_); } - finish_tag_.Set( - call_.call(), [this](bool ok) { MaybeFinish(); }, &finish_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_); @@ -596,13 +590,12 @@ class ClientCallbackWriterImpl // 3. Any backlog started_ = true; - start_tag_.Set( - call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); if (!start_corked_) { start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, context_->initial_metadata_flags()); @@ -613,17 +606,16 @@ class ClientCallbackWriterImpl // Also set up the read and write tags so that they don't have to be set up // each time - write_tag_.Set( - call_.call(), - [this](bool ok) { - reactor_->OnWriteDone(ok); - MaybeFinish(); - }, - &write_ops_); + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeFinish(); + }, + &write_ops_); write_ops_.set_core_cq_tag(&write_tag_); - finish_tag_.Set( - call_.call(), [this](bool ok) { MaybeFinish(); }, &finish_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_); @@ -664,13 +656,12 @@ class ClientCallbackWriterImpl start_corked_ = false; } writes_done_ops_.ClientSendClose(); - writes_done_tag_.Set( - call_.call(), - [this](bool ok) { - reactor_->OnWritesDoneDone(ok); - MaybeFinish(); - }, - &writes_done_ops_); + writes_done_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWritesDoneDone(ok); + MaybeFinish(); + }, + &writes_done_ops_); writes_done_ops_.set_core_cq_tag(&writes_done_tag_); callbacks_outstanding_++; if (started_) { From 2b5d45ab381c5f455e16f49276ef22998c9d659b Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 30 Nov 2018 02:42:13 -0800 Subject: [PATCH 0380/2143] Fix clang-tidy and golden file issues --- include/grpcpp/impl/codegen/client_callback.h | 12 +- test/cpp/codegen/compiler_test_golden | 1059 +++++------------ .../end2end/client_callback_end2end_test.cc | 8 +- 3 files changed, 312 insertions(+), 767 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 93266b8aa33..4d9579fd6ab 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -157,7 +157,7 @@ template class ClientBidiReactor { public: virtual ~ClientBidiReactor() {} - virtual void OnDone(Status s) {} + virtual void OnDone(const Status& s) {} virtual void OnReadInitialMetadataDone(bool ok) {} virtual void OnReadDone(bool ok) {} virtual void OnWriteDone(bool ok) {} @@ -186,7 +186,7 @@ template class ClientReadReactor { public: virtual ~ClientReadReactor() {} - virtual void OnDone(Status s) {} + virtual void OnDone(const Status& s) {} virtual void OnReadInitialMetadataDone(bool ok) {} virtual void OnReadDone(bool ok) {} @@ -203,7 +203,7 @@ template class ClientWriteReactor { public: virtual ~ClientWriteReactor() {} - virtual void OnDone(Status s) {} + virtual void OnDone(const Status& s) {} virtual void OnReadInitialMetadataDone(bool ok) {} virtual void OnWriteDone(bool ok) {} virtual void OnWritesDoneDone(bool ok) {} @@ -255,7 +255,7 @@ class ClientCallbackReaderWriterImpl void MaybeFinish() { if (--callbacks_outstanding_ == 0) { - reactor_->OnDone(std::move(finish_status_)); + reactor_->OnDone(finish_status_); auto* call = call_.call(); this->~ClientCallbackReaderWriterImpl(); g_core_codegen_interface->grpc_call_unref(call); @@ -450,7 +450,7 @@ class ClientCallbackReaderImpl void MaybeFinish() { if (--callbacks_outstanding_ == 0) { - reactor_->OnDone(std::move(finish_status_)); + reactor_->OnDone(finish_status_); auto* call = call_.call(); this->~ClientCallbackReaderImpl(); g_core_codegen_interface->grpc_call_unref(call); @@ -576,7 +576,7 @@ class ClientCallbackWriterImpl void MaybeFinish() { if (--callbacks_outstanding_ == 0) { - reactor_->OnDone(std::move(finish_status_)); + reactor_->OnDone(finish_status_); auto* call = call_.call(); this->~ClientCallbackWriterImpl(); g_core_codegen_interface->grpc_call_unref(call); diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 1a5fe279328..5f0eb6c35ce 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -26,6 +26,7 @@ #include "src/proto/grpc/testing/compiler_test.pb.h" +#include #include #include #include @@ -38,7 +39,6 @@ #include #include #include -#include namespace grpc { class CompletionQueue; @@ -64,556 +64,294 @@ class ServiceA final { public: virtual ~StubInterface() {} // MethodA1 leading comment 1 - virtual ::grpc::Status MethodA1(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::testing::Response* response) = 0; - std::unique_ptr< - ::grpc::ClientAsyncResponseReaderInterface<::grpc::testing::Response>> - AsyncMethodA1(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface< - ::grpc::testing::Response>>(AsyncMethodA1Raw(context, request, cq)); + virtual ::grpc::Status MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response) = 0; + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>> AsyncMethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>>(AsyncMethodA1Raw(context, request, cq)); } - std::unique_ptr< - ::grpc::ClientAsyncResponseReaderInterface<::grpc::testing::Response>> - PrepareAsyncMethodA1(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface< - ::grpc::testing::Response>>( - PrepareAsyncMethodA1Raw(context, request, cq)); + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>> PrepareAsyncMethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>>(PrepareAsyncMethodA1Raw(context, request, cq)); } // MethodA1 trailing comment 1 // MethodA2 detached leading comment 1 // // Method A2 leading comment 1 // Method A2 leading comment 2 - std::unique_ptr<::grpc::ClientWriterInterface<::grpc::testing::Request>> - MethodA2(::grpc::ClientContext* context, - ::grpc::testing::Response* response) { - return std::unique_ptr< - ::grpc::ClientWriterInterface<::grpc::testing::Request>>( - MethodA2Raw(context, response)); + std::unique_ptr< ::grpc::ClientWriterInterface< ::grpc::testing::Request>> MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response) { + return std::unique_ptr< ::grpc::ClientWriterInterface< ::grpc::testing::Request>>(MethodA2Raw(context, response)); } - std::unique_ptr< - ::grpc::ClientAsyncWriterInterface<::grpc::testing::Request>> - AsyncMethodA2(::grpc::ClientContext* context, - ::grpc::testing::Response* response, - ::grpc::CompletionQueue* cq, void* tag) { - return std::unique_ptr< - ::grpc::ClientAsyncWriterInterface<::grpc::testing::Request>>( - AsyncMethodA2Raw(context, response, cq, tag)); + std::unique_ptr< ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>> AsyncMethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>>(AsyncMethodA2Raw(context, response, cq, tag)); } - std::unique_ptr< - ::grpc::ClientAsyncWriterInterface<::grpc::testing::Request>> - PrepareAsyncMethodA2(::grpc::ClientContext* context, - ::grpc::testing::Response* response, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr< - ::grpc::ClientAsyncWriterInterface<::grpc::testing::Request>>( - PrepareAsyncMethodA2Raw(context, response, cq)); + std::unique_ptr< ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>> PrepareAsyncMethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>>(PrepareAsyncMethodA2Raw(context, response, cq)); } // MethodA2 trailing comment 1 // Method A3 leading comment 1 - std::unique_ptr<::grpc::ClientReaderInterface<::grpc::testing::Response>> - MethodA3(::grpc::ClientContext* context, - const ::grpc::testing::Request& request) { - return std::unique_ptr< - ::grpc::ClientReaderInterface<::grpc::testing::Response>>( - MethodA3Raw(context, request)); + std::unique_ptr< ::grpc::ClientReaderInterface< ::grpc::testing::Response>> MethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request) { + return std::unique_ptr< ::grpc::ClientReaderInterface< ::grpc::testing::Response>>(MethodA3Raw(context, request)); } - std::unique_ptr< - ::grpc::ClientAsyncReaderInterface<::grpc::testing::Response>> - AsyncMethodA3(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq, void* tag) { - return std::unique_ptr< - ::grpc::ClientAsyncReaderInterface<::grpc::testing::Response>>( - AsyncMethodA3Raw(context, request, cq, tag)); + std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>> AsyncMethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>>(AsyncMethodA3Raw(context, request, cq, tag)); } - std::unique_ptr< - ::grpc::ClientAsyncReaderInterface<::grpc::testing::Response>> - PrepareAsyncMethodA3(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr< - ::grpc::ClientAsyncReaderInterface<::grpc::testing::Response>>( - PrepareAsyncMethodA3Raw(context, request, cq)); + std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>> PrepareAsyncMethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>>(PrepareAsyncMethodA3Raw(context, request, cq)); } // Method A3 trailing comment 1 // Method A4 leading comment 1 - std::unique_ptr<::grpc::ClientReaderWriterInterface< - ::grpc::testing::Request, ::grpc::testing::Response>> - MethodA4(::grpc::ClientContext* context) { - return std::unique_ptr<::grpc::ClientReaderWriterInterface< - ::grpc::testing::Request, ::grpc::testing::Response>>( - MethodA4Raw(context)); + std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>> MethodA4(::grpc::ClientContext* context) { + return std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>>(MethodA4Raw(context)); } - std::unique_ptr<::grpc::ClientAsyncReaderWriterInterface< - ::grpc::testing::Request, ::grpc::testing::Response>> - AsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, - void* tag) { - return std::unique_ptr<::grpc::ClientAsyncReaderWriterInterface< - ::grpc::testing::Request, ::grpc::testing::Response>>( - AsyncMethodA4Raw(context, cq, tag)); + std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>> AsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>>(AsyncMethodA4Raw(context, cq, tag)); } - std::unique_ptr<::grpc::ClientAsyncReaderWriterInterface< - ::grpc::testing::Request, ::grpc::testing::Response>> - PrepareAsyncMethodA4(::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr<::grpc::ClientAsyncReaderWriterInterface< - ::grpc::testing::Request, ::grpc::testing::Response>>( - PrepareAsyncMethodA4Raw(context, cq)); + std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>> PrepareAsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>>(PrepareAsyncMethodA4Raw(context, cq)); } // Method A4 trailing comment 1 class experimental_async_interface { public: 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::testing::Request* request, ::grpc::testing::Response* response, std::function) = 0; // MethodA1 trailing comment 1 // MethodA2 detached leading comment 1 // // Method A2 leading comment 1 // Method A2 leading comment 2 - virtual void MethodA2( - ::grpc::ClientContext* context, ::grpc::testing::Response* response, - ::grpc::experimental::ClientWriteReactor<::grpc::testing::Request>* - reactor) = 0; + virtual void MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::experimental::ClientWriteReactor< ::grpc::testing::Request>* reactor) = 0; // MethodA2 trailing comment 1 // Method A3 leading comment 1 - virtual void MethodA3( - ::grpc::ClientContext* context, ::grpc::testing::Request* request, - ::grpc::experimental::ClientReadReactor<::grpc::testing::Response>* - reactor) = 0; + virtual void MethodA3(::grpc::ClientContext* context, ::grpc::testing::Request* request, ::grpc::experimental::ClientReadReactor< ::grpc::testing::Response>* reactor) = 0; // Method A3 trailing comment 1 // Method A4 leading comment 1 - virtual void MethodA4( - ::grpc::ClientContext* context, - ::grpc::experimental::ClientBidiReactor<::grpc::testing::Request, - ::grpc::testing::Response>* - reactor) = 0; + virtual void MethodA4(::grpc::ClientContext* context, ::grpc::experimental::ClientBidiReactor< ::grpc::testing::Request,::grpc::testing::Response>* reactor) = 0; // Method A4 trailing comment 1 }; - virtual class experimental_async_interface* experimental_async() { - return nullptr; - } - - private: - virtual ::grpc::ClientAsyncResponseReaderInterface< - ::grpc::testing::Response>* - AsyncMethodA1Raw(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) = 0; - virtual ::grpc::ClientAsyncResponseReaderInterface< - ::grpc::testing::Response>* - PrepareAsyncMethodA1Raw(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) = 0; - virtual ::grpc::ClientWriterInterface<::grpc::testing::Request>* - MethodA2Raw(::grpc::ClientContext* context, - ::grpc::testing::Response* response) = 0; - virtual ::grpc::ClientAsyncWriterInterface<::grpc::testing::Request>* - AsyncMethodA2Raw(::grpc::ClientContext* context, - ::grpc::testing::Response* response, - ::grpc::CompletionQueue* cq, void* tag) = 0; - virtual ::grpc::ClientAsyncWriterInterface<::grpc::testing::Request>* - PrepareAsyncMethodA2Raw(::grpc::ClientContext* context, - ::grpc::testing::Response* response, - ::grpc::CompletionQueue* cq) = 0; - virtual ::grpc::ClientReaderInterface<::grpc::testing::Response>* - MethodA3Raw(::grpc::ClientContext* context, - const ::grpc::testing::Request& request) = 0; - virtual ::grpc::ClientAsyncReaderInterface<::grpc::testing::Response>* - AsyncMethodA3Raw(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq, void* tag) = 0; - virtual ::grpc::ClientAsyncReaderInterface<::grpc::testing::Response>* - PrepareAsyncMethodA3Raw(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) = 0; - virtual ::grpc::ClientReaderWriterInterface<::grpc::testing::Request, - ::grpc::testing::Response>* - MethodA4Raw(::grpc::ClientContext* context) = 0; - virtual ::grpc::ClientAsyncReaderWriterInterface<::grpc::testing::Request, - ::grpc::testing::Response>* - AsyncMethodA4Raw(::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq, void* tag) = 0; - virtual ::grpc::ClientAsyncReaderWriterInterface<::grpc::testing::Request, - ::grpc::testing::Response>* - PrepareAsyncMethodA4Raw(::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq) = 0; + virtual class experimental_async_interface* experimental_async() { return nullptr; } + private: + virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* PrepareAsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientWriterInterface< ::grpc::testing::Request>* MethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response) = 0; + virtual ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>* AsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) = 0; + virtual ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>* PrepareAsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientReaderInterface< ::grpc::testing::Response>* MethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request) = 0; + virtual ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>* AsyncMethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) = 0; + virtual ::grpc::ClientAsyncReaderInterface< ::grpc::testing::Response>* PrepareAsyncMethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4Raw(::grpc::ClientContext* context) = 0; + virtual ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>* AsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) = 0; + virtual ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>* PrepareAsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) = 0; }; class Stub final : public StubInterface { public: - Stub(const std::shared_ptr<::grpc::ChannelInterface>& channel); - ::grpc::Status MethodA1(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::testing::Response* response) override; - std::unique_ptr< - ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>> - AsyncMethodA1(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr< - ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>>( - AsyncMethodA1Raw(context, request, cq)); + Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); + ::grpc::Status MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response) override; + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>> AsyncMethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>>(AsyncMethodA1Raw(context, request, cq)); } - std::unique_ptr< - ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>> - PrepareAsyncMethodA1(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr< - ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>>( - PrepareAsyncMethodA1Raw(context, request, cq)); + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>> PrepareAsyncMethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>>(PrepareAsyncMethodA1Raw(context, request, cq)); } - std::unique_ptr<::grpc::ClientWriter<::grpc::testing::Request>> MethodA2( - ::grpc::ClientContext* context, ::grpc::testing::Response* response) { - return std::unique_ptr<::grpc::ClientWriter<::grpc::testing::Request>>( - MethodA2Raw(context, response)); + std::unique_ptr< ::grpc::ClientWriter< ::grpc::testing::Request>> MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response) { + return std::unique_ptr< ::grpc::ClientWriter< ::grpc::testing::Request>>(MethodA2Raw(context, response)); } - std::unique_ptr<::grpc::ClientAsyncWriter<::grpc::testing::Request>> - AsyncMethodA2(::grpc::ClientContext* context, - ::grpc::testing::Response* response, - ::grpc::CompletionQueue* cq, void* tag) { - return std::unique_ptr< - ::grpc::ClientAsyncWriter<::grpc::testing::Request>>( - AsyncMethodA2Raw(context, response, cq, tag)); + std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>> AsyncMethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>>(AsyncMethodA2Raw(context, response, cq, tag)); } - std::unique_ptr<::grpc::ClientAsyncWriter<::grpc::testing::Request>> - PrepareAsyncMethodA2(::grpc::ClientContext* context, - ::grpc::testing::Response* response, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr< - ::grpc::ClientAsyncWriter<::grpc::testing::Request>>( - PrepareAsyncMethodA2Raw(context, response, cq)); + std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>> PrepareAsyncMethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncWriter< ::grpc::testing::Request>>(PrepareAsyncMethodA2Raw(context, response, cq)); } - std::unique_ptr<::grpc::ClientReader<::grpc::testing::Response>> MethodA3( - ::grpc::ClientContext* context, - const ::grpc::testing::Request& request) { - return std::unique_ptr<::grpc::ClientReader<::grpc::testing::Response>>( - MethodA3Raw(context, request)); + std::unique_ptr< ::grpc::ClientReader< ::grpc::testing::Response>> MethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request) { + return std::unique_ptr< ::grpc::ClientReader< ::grpc::testing::Response>>(MethodA3Raw(context, request)); } - std::unique_ptr<::grpc::ClientAsyncReader<::grpc::testing::Response>> - AsyncMethodA3(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq, void* tag) { - return std::unique_ptr< - ::grpc::ClientAsyncReader<::grpc::testing::Response>>( - AsyncMethodA3Raw(context, request, cq, tag)); + std::unique_ptr< ::grpc::ClientAsyncReader< ::grpc::testing::Response>> AsyncMethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncReader< ::grpc::testing::Response>>(AsyncMethodA3Raw(context, request, cq, tag)); } - std::unique_ptr<::grpc::ClientAsyncReader<::grpc::testing::Response>> - PrepareAsyncMethodA3(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr< - ::grpc::ClientAsyncReader<::grpc::testing::Response>>( - PrepareAsyncMethodA3Raw(context, request, cq)); + std::unique_ptr< ::grpc::ClientAsyncReader< ::grpc::testing::Response>> PrepareAsyncMethodA3(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncReader< ::grpc::testing::Response>>(PrepareAsyncMethodA3Raw(context, request, cq)); } - std::unique_ptr<::grpc::ClientReaderWriter<::grpc::testing::Request, - ::grpc::testing::Response>> - MethodA4(::grpc::ClientContext* context) { - return std::unique_ptr<::grpc::ClientReaderWriter< - ::grpc::testing::Request, ::grpc::testing::Response>>( - MethodA4Raw(context)); + std::unique_ptr< ::grpc::ClientReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>> MethodA4(::grpc::ClientContext* context) { + return std::unique_ptr< ::grpc::ClientReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>>(MethodA4Raw(context)); } - std::unique_ptr<::grpc::ClientAsyncReaderWriter<::grpc::testing::Request, - ::grpc::testing::Response>> - AsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, - void* tag) { - return std::unique_ptr<::grpc::ClientAsyncReaderWriter< - ::grpc::testing::Request, ::grpc::testing::Response>>( - AsyncMethodA4Raw(context, cq, tag)); + std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>> AsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>>(AsyncMethodA4Raw(context, cq, tag)); } - std::unique_ptr<::grpc::ClientAsyncReaderWriter<::grpc::testing::Request, - ::grpc::testing::Response>> - PrepareAsyncMethodA4(::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr<::grpc::ClientAsyncReaderWriter< - ::grpc::testing::Request, ::grpc::testing::Response>>( - PrepareAsyncMethodA4Raw(context, cq)); + std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>> PrepareAsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>>(PrepareAsyncMethodA4Raw(context, cq)); } - class experimental_async final - : public StubInterface::experimental_async_interface { + class experimental_async 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 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; - + void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* 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; private: friend class Stub; - explicit experimental_async(Stub* stub) : stub_(stub) {} + explicit experimental_async(Stub* stub): stub_(stub) { } Stub* stub() { return stub_; } Stub* stub_; }; - class experimental_async_interface* experimental_async() override { - return &async_stub_; - } + class experimental_async_interface* experimental_async() override { return &async_stub_; } private: - std::shared_ptr<::grpc::ChannelInterface> channel_; - class experimental_async async_stub_ { - this - }; - ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>* - AsyncMethodA1Raw(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) override; - ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>* - PrepareAsyncMethodA1Raw(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) override; - ::grpc::ClientWriter<::grpc::testing::Request>* MethodA2Raw( - ::grpc::ClientContext* context, - ::grpc::testing::Response* response) override; - ::grpc::ClientAsyncWriter<::grpc::testing::Request>* AsyncMethodA2Raw( - ::grpc::ClientContext* context, ::grpc::testing::Response* response, - ::grpc::CompletionQueue* cq, void* tag) override; - ::grpc::ClientAsyncWriter<::grpc::testing::Request>* - PrepareAsyncMethodA2Raw(::grpc::ClientContext* context, - ::grpc::testing::Response* response, - ::grpc::CompletionQueue* cq) override; - ::grpc::ClientReader<::grpc::testing::Response>* MethodA3Raw( - ::grpc::ClientContext* context, - const ::grpc::testing::Request& request) override; - ::grpc::ClientAsyncReader<::grpc::testing::Response>* AsyncMethodA3Raw( - ::grpc::ClientContext* context, const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq, void* tag) override; - ::grpc::ClientAsyncReader<::grpc::testing::Response>* - PrepareAsyncMethodA3Raw(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) override; - ::grpc::ClientReaderWriter<::grpc::testing::Request, - ::grpc::testing::Response>* - MethodA4Raw(::grpc::ClientContext* context) override; - ::grpc::ClientAsyncReaderWriter<::grpc::testing::Request, - ::grpc::testing::Response>* - AsyncMethodA4Raw(::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq, void* tag) override; - ::grpc::ClientAsyncReaderWriter<::grpc::testing::Request, - ::grpc::testing::Response>* - PrepareAsyncMethodA4Raw(::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq) override; + std::shared_ptr< ::grpc::ChannelInterface> channel_; + class experimental_async async_stub_{this}; + ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* PrepareAsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientWriter< ::grpc::testing::Request>* MethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response) override; + ::grpc::ClientAsyncWriter< ::grpc::testing::Request>* AsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag) override; + ::grpc::ClientAsyncWriter< ::grpc::testing::Request>* PrepareAsyncMethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientReader< ::grpc::testing::Response>* MethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request) override; + ::grpc::ClientAsyncReader< ::grpc::testing::Response>* AsyncMethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq, void* tag) override; + ::grpc::ClientAsyncReader< ::grpc::testing::Response>* PrepareAsyncMethodA3Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4Raw(::grpc::ClientContext* context) override; + ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* AsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) override; + ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>* PrepareAsyncMethodA4Raw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) override; const ::grpc::internal::RpcMethod rpcmethod_MethodA1_; const ::grpc::internal::RpcMethod rpcmethod_MethodA2_; const ::grpc::internal::RpcMethod rpcmethod_MethodA3_; const ::grpc::internal::RpcMethod rpcmethod_MethodA4_; }; - static std::unique_ptr NewStub( - const std::shared_ptr<::grpc::ChannelInterface>& channel, - const ::grpc::StubOptions& options = ::grpc::StubOptions()); + static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); class Service : public ::grpc::Service { public: Service(); virtual ~Service(); // MethodA1 leading comment 1 - virtual ::grpc::Status MethodA1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response); + virtual ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response); // MethodA1 trailing comment 1 // MethodA2 detached leading comment 1 // // Method A2 leading comment 1 // Method A2 leading comment 2 - virtual ::grpc::Status MethodA2( - ::grpc::ServerContext* context, - ::grpc::ServerReader<::grpc::testing::Request>* reader, - ::grpc::testing::Response* response); + virtual ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response); // MethodA2 trailing comment 1 // Method A3 leading comment 1 - virtual ::grpc::Status MethodA3( - ::grpc::ServerContext* context, const ::grpc::testing::Request* request, - ::grpc::ServerWriter<::grpc::testing::Response>* writer); + virtual ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer); // Method A3 trailing comment 1 // Method A4 leading comment 1 - virtual ::grpc::Status MethodA4( - ::grpc::ServerContext* context, - ::grpc::ServerReaderWriter<::grpc::testing::Response, - ::grpc::testing::Request>* stream); + virtual ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream); // Method A4 trailing comment 1 }; template class WithAsyncMethod_MethodA1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithAsyncMethod_MethodA1() { ::grpc::Service::MarkMethodAsync(0); } + WithAsyncMethod_MethodA1() { + ::grpc::Service::MarkMethodAsync(0); + } ~WithAsyncMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA1( - ::grpc::ServerContext* context, ::grpc::testing::Request* request, - ::grpc::ServerAsyncResponseWriter<::grpc::testing::Response>* response, - ::grpc::CompletionQueue* new_call_cq, - ::grpc::ServerCompletionQueue* notification_cq, void* tag) { - ::grpc::Service::RequestAsyncUnary(0, context, request, response, - new_call_cq, notification_cq, tag); + void RequestMethodA1(::grpc::ServerContext* context, ::grpc::testing::Request* request, ::grpc::ServerAsyncResponseWriter< ::grpc::testing::Response>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); } }; template class WithAsyncMethod_MethodA2 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithAsyncMethod_MethodA2() { ::grpc::Service::MarkMethodAsync(1); } + WithAsyncMethod_MethodA2() { + ::grpc::Service::MarkMethodAsync(1); + } ~WithAsyncMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA2( - ::grpc::ServerContext* context, - ::grpc::ServerReader<::grpc::testing::Request>* reader, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA2( - ::grpc::ServerContext* context, - ::grpc::ServerAsyncReader<::grpc::testing::Response, - ::grpc::testing::Request>* reader, - ::grpc::CompletionQueue* new_call_cq, - ::grpc::ServerCompletionQueue* notification_cq, void* tag) { - ::grpc::Service::RequestAsyncClientStreaming( - 1, context, reader, new_call_cq, notification_cq, tag); + void RequestMethodA2(::grpc::ServerContext* context, ::grpc::ServerAsyncReader< ::grpc::testing::Response, ::grpc::testing::Request>* reader, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncClientStreaming(1, context, reader, new_call_cq, notification_cq, tag); } }; template class WithAsyncMethod_MethodA3 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithAsyncMethod_MethodA3() { ::grpc::Service::MarkMethodAsync(2); } + WithAsyncMethod_MethodA3() { + ::grpc::Service::MarkMethodAsync(2); + } ~WithAsyncMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA3( - ::grpc::ServerContext* context, const ::grpc::testing::Request* request, - ::grpc::ServerWriter<::grpc::testing::Response>* writer) override { + ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA3( - ::grpc::ServerContext* context, ::grpc::testing::Request* request, - ::grpc::ServerAsyncWriter<::grpc::testing::Response>* writer, - ::grpc::CompletionQueue* new_call_cq, - ::grpc::ServerCompletionQueue* notification_cq, void* tag) { - ::grpc::Service::RequestAsyncServerStreaming( - 2, context, request, writer, new_call_cq, notification_cq, tag); + void RequestMethodA3(::grpc::ServerContext* context, ::grpc::testing::Request* request, ::grpc::ServerAsyncWriter< ::grpc::testing::Response>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncServerStreaming(2, context, request, writer, new_call_cq, notification_cq, tag); } }; template class WithAsyncMethod_MethodA4 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithAsyncMethod_MethodA4() { ::grpc::Service::MarkMethodAsync(3); } + WithAsyncMethod_MethodA4() { + ::grpc::Service::MarkMethodAsync(3); + } ~WithAsyncMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA4( - ::grpc::ServerContext* context, - ::grpc::ServerReaderWriter<::grpc::testing::Response, - ::grpc::testing::Request>* stream) override { + ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA4( - ::grpc::ServerContext* context, - ::grpc::ServerAsyncReaderWriter<::grpc::testing::Response, - ::grpc::testing::Request>* stream, - ::grpc::CompletionQueue* new_call_cq, - ::grpc::ServerCompletionQueue* notification_cq, void* tag) { - ::grpc::Service::RequestAsyncBidiStreaming( - 3, context, stream, new_call_cq, notification_cq, tag); + void RequestMethodA4(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncBidiStreaming(3, context, stream, new_call_cq, notification_cq, tag); } }; - typedef WithAsyncMethod_MethodA1>>> - AsyncService; + typedef WithAsyncMethod_MethodA1 > > > AsyncService; template class ExperimentalWithCallbackMethod_MethodA1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithCallbackMethod_MethodA1() { - ::grpc::Service::experimental().MarkMethodCallback( - 0, new ::grpc::internal::CallbackUnaryHandler< - ExperimentalWithCallbackMethod_MethodA1, - ::grpc::testing::Request, ::grpc::testing::Response>( - [this](::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response, - ::grpc::experimental::ServerCallbackRpcController* - controller) { + ::grpc::Service::experimental().MarkMethodCallback(0, + new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithCallbackMethod_MethodA1, ::grpc::testing::Request, ::grpc::testing::Response>( + [this](::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response, + ::grpc::experimental::ServerCallbackRpcController* controller) { this->MethodA1(context, request, response, controller); - }, - this)); + }, this)); } ~ExperimentalWithCallbackMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - virtual void MethodA1( - ::grpc::ServerContext* context, const ::grpc::testing::Request* request, - ::grpc::testing::Response* response, - ::grpc::experimental::ServerCallbackRpcController* controller) { - controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); - } + virtual void MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ServerCallbackRpcController* controller) { controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); } }; template class ExperimentalWithCallbackMethod_MethodA2 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - ExperimentalWithCallbackMethod_MethodA2() {} + ExperimentalWithCallbackMethod_MethodA2() { + } ~ExperimentalWithCallbackMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA2( - ::grpc::ServerContext* context, - ::grpc::ServerReader<::grpc::testing::Request>* reader, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -621,17 +359,15 @@ class ServiceA final { template class ExperimentalWithCallbackMethod_MethodA3 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - ExperimentalWithCallbackMethod_MethodA3() {} + ExperimentalWithCallbackMethod_MethodA3() { + } ~ExperimentalWithCallbackMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA3( - ::grpc::ServerContext* context, const ::grpc::testing::Request* request, - ::grpc::ServerWriter<::grpc::testing::Response>* writer) override { + ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -639,41 +375,33 @@ class ServiceA final { template class ExperimentalWithCallbackMethod_MethodA4 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - ExperimentalWithCallbackMethod_MethodA4() {} + ExperimentalWithCallbackMethod_MethodA4() { + } ~ExperimentalWithCallbackMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA4( - ::grpc::ServerContext* context, - ::grpc::ServerReaderWriter<::grpc::testing::Response, - ::grpc::testing::Request>* stream) override { + ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } }; - typedef ExperimentalWithCallbackMethod_MethodA1< - ExperimentalWithCallbackMethod_MethodA2< - ExperimentalWithCallbackMethod_MethodA3< - ExperimentalWithCallbackMethod_MethodA4>>> - ExperimentalCallbackService; + typedef ExperimentalWithCallbackMethod_MethodA1 > > > ExperimentalCallbackService; template class WithGenericMethod_MethodA1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithGenericMethod_MethodA1() { ::grpc::Service::MarkMethodGeneric(0); } + WithGenericMethod_MethodA1() { + ::grpc::Service::MarkMethodGeneric(0); + } ~WithGenericMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -681,18 +409,16 @@ class ServiceA final { template class WithGenericMethod_MethodA2 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithGenericMethod_MethodA2() { ::grpc::Service::MarkMethodGeneric(1); } + WithGenericMethod_MethodA2() { + ::grpc::Service::MarkMethodGeneric(1); + } ~WithGenericMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA2( - ::grpc::ServerContext* context, - ::grpc::ServerReader<::grpc::testing::Request>* reader, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -700,17 +426,16 @@ class ServiceA final { template class WithGenericMethod_MethodA3 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithGenericMethod_MethodA3() { ::grpc::Service::MarkMethodGeneric(2); } + WithGenericMethod_MethodA3() { + ::grpc::Service::MarkMethodGeneric(2); + } ~WithGenericMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA3( - ::grpc::ServerContext* context, const ::grpc::testing::Request* request, - ::grpc::ServerWriter<::grpc::testing::Response>* writer) override { + ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -718,18 +443,16 @@ class ServiceA final { template class WithGenericMethod_MethodA4 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithGenericMethod_MethodA4() { ::grpc::Service::MarkMethodGeneric(3); } + WithGenericMethod_MethodA4() { + ::grpc::Service::MarkMethodGeneric(3); + } ~WithGenericMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA4( - ::grpc::ServerContext* context, - ::grpc::ServerReaderWriter<::grpc::testing::Response, - ::grpc::testing::Request>* stream) override { + ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -737,164 +460,120 @@ class ServiceA final { template class WithRawMethod_MethodA1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithRawMethod_MethodA1() { ::grpc::Service::MarkMethodRaw(0); } + WithRawMethod_MethodA1() { + ::grpc::Service::MarkMethodRaw(0); + } ~WithRawMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA1( - ::grpc::ServerContext* context, ::grpc::ByteBuffer* request, - ::grpc::ServerAsyncResponseWriter<::grpc::ByteBuffer>* response, - ::grpc::CompletionQueue* new_call_cq, - ::grpc::ServerCompletionQueue* notification_cq, void* tag) { - ::grpc::Service::RequestAsyncUnary(0, context, request, response, - new_call_cq, notification_cq, tag); + void RequestMethodA1(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); } }; template class WithRawMethod_MethodA2 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithRawMethod_MethodA2() { ::grpc::Service::MarkMethodRaw(1); } + WithRawMethod_MethodA2() { + ::grpc::Service::MarkMethodRaw(1); + } ~WithRawMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA2( - ::grpc::ServerContext* context, - ::grpc::ServerReader<::grpc::testing::Request>* reader, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA2(::grpc::ServerContext* context, - ::grpc::ServerAsyncReader<::grpc::ByteBuffer, - ::grpc::ByteBuffer>* reader, - ::grpc::CompletionQueue* new_call_cq, - ::grpc::ServerCompletionQueue* notification_cq, - void* tag) { - ::grpc::Service::RequestAsyncClientStreaming( - 1, context, reader, new_call_cq, notification_cq, tag); + void RequestMethodA2(::grpc::ServerContext* context, ::grpc::ServerAsyncReader< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* reader, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncClientStreaming(1, context, reader, new_call_cq, notification_cq, tag); } }; template class WithRawMethod_MethodA3 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithRawMethod_MethodA3() { ::grpc::Service::MarkMethodRaw(2); } + WithRawMethod_MethodA3() { + ::grpc::Service::MarkMethodRaw(2); + } ~WithRawMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA3( - ::grpc::ServerContext* context, const ::grpc::testing::Request* request, - ::grpc::ServerWriter<::grpc::testing::Response>* writer) override { + ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA3(::grpc::ServerContext* context, - ::grpc::ByteBuffer* request, - ::grpc::ServerAsyncWriter<::grpc::ByteBuffer>* writer, - ::grpc::CompletionQueue* new_call_cq, - ::grpc::ServerCompletionQueue* notification_cq, - void* tag) { - ::grpc::Service::RequestAsyncServerStreaming( - 2, context, request, writer, new_call_cq, notification_cq, tag); + void RequestMethodA3(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncServerStreaming(2, context, request, writer, new_call_cq, notification_cq, tag); } }; template class WithRawMethod_MethodA4 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithRawMethod_MethodA4() { ::grpc::Service::MarkMethodRaw(3); } + WithRawMethod_MethodA4() { + ::grpc::Service::MarkMethodRaw(3); + } ~WithRawMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA4( - ::grpc::ServerContext* context, - ::grpc::ServerReaderWriter<::grpc::testing::Response, - ::grpc::testing::Request>* stream) override { + ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodA4( - ::grpc::ServerContext* context, - ::grpc::ServerAsyncReaderWriter<::grpc::ByteBuffer, ::grpc::ByteBuffer>* - stream, - ::grpc::CompletionQueue* new_call_cq, - ::grpc::ServerCompletionQueue* notification_cq, void* tag) { - ::grpc::Service::RequestAsyncBidiStreaming( - 3, context, stream, new_call_cq, notification_cq, tag); + void RequestMethodA4(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncBidiStreaming(3, context, stream, new_call_cq, notification_cq, tag); } }; template class ExperimentalWithRawCallbackMethod_MethodA1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithRawCallbackMethod_MethodA1() { - ::grpc::Service::experimental().MarkMethodRawCallback( - 0, new ::grpc::internal::CallbackUnaryHandler< - ExperimentalWithRawCallbackMethod_MethodA1, - ::grpc::ByteBuffer, ::grpc::ByteBuffer>( - [this](::grpc::ServerContext* context, - const ::grpc::ByteBuffer* request, - ::grpc::ByteBuffer* response, - ::grpc::experimental::ServerCallbackRpcController* - controller) { + ::grpc::Service::experimental().MarkMethodRawCallback(0, + new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithRawCallbackMethod_MethodA1, ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this](::grpc::ServerContext* context, + const ::grpc::ByteBuffer* request, + ::grpc::ByteBuffer* response, + ::grpc::experimental::ServerCallbackRpcController* controller) { this->MethodA1(context, request, response, controller); - }, - this)); + }, this)); } ~ExperimentalWithRawCallbackMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - virtual void MethodA1( - ::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, - ::grpc::ByteBuffer* response, - ::grpc::experimental::ServerCallbackRpcController* controller) { - controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); - } + virtual void MethodA1(::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response, ::grpc::experimental::ServerCallbackRpcController* controller) { controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); } }; template class ExperimentalWithRawCallbackMethod_MethodA2 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - ExperimentalWithRawCallbackMethod_MethodA2() {} + ExperimentalWithRawCallbackMethod_MethodA2() { + } ~ExperimentalWithRawCallbackMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA2( - ::grpc::ServerContext* context, - ::grpc::ServerReader<::grpc::testing::Request>* reader, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodA2(::grpc::ServerContext* context, ::grpc::ServerReader< ::grpc::testing::Request>* reader, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -902,17 +581,15 @@ class ServiceA final { template class ExperimentalWithRawCallbackMethod_MethodA3 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - ExperimentalWithRawCallbackMethod_MethodA3() {} + ExperimentalWithRawCallbackMethod_MethodA3() { + } ~ExperimentalWithRawCallbackMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA3( - ::grpc::ServerContext* context, const ::grpc::testing::Request* request, - ::grpc::ServerWriter<::grpc::testing::Response>* writer) override { + ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -920,18 +597,15 @@ class ServiceA final { template class ExperimentalWithRawCallbackMethod_MethodA4 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - ExperimentalWithRawCallbackMethod_MethodA4() {} + ExperimentalWithRawCallbackMethod_MethodA4() { + } ~ExperimentalWithRawCallbackMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodA4( - ::grpc::ServerContext* context, - ::grpc::ServerReaderWriter<::grpc::testing::Response, - ::grpc::testing::Request>* stream) override { + ::grpc::Status MethodA4(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::testing::Response, ::grpc::testing::Request>* stream) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -939,69 +613,46 @@ class ServiceA final { template class WithStreamedUnaryMethod_MethodA1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: WithStreamedUnaryMethod_MethodA1() { - ::grpc::Service::MarkMethodStreamed( - 0, new ::grpc::internal::StreamedUnaryHandler< - ::grpc::testing::Request, ::grpc::testing::Response>(std::bind( - &WithStreamedUnaryMethod_MethodA1::StreamedMethodA1, - this, std::placeholders::_1, std::placeholders::_2))); + ::grpc::Service::MarkMethodStreamed(0, + new ::grpc::internal::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodA1::StreamedMethodA1, this, std::placeholders::_1, std::placeholders::_2))); } ~WithStreamedUnaryMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); } // disable regular version of this method - ::grpc::Status MethodA1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } // replace default version of method with streamed unary - virtual ::grpc::Status StreamedMethodA1( - ::grpc::ServerContext* context, - ::grpc::ServerUnaryStreamer<::grpc::testing::Request, - ::grpc::testing::Response>* - server_unary_streamer) = 0; + virtual ::grpc::Status StreamedMethodA1(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_unary_streamer) = 0; }; - typedef WithStreamedUnaryMethod_MethodA1 StreamedUnaryService; + typedef WithStreamedUnaryMethod_MethodA1 StreamedUnaryService; template class WithSplitStreamingMethod_MethodA3 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: WithSplitStreamingMethod_MethodA3() { - ::grpc::Service::MarkMethodStreamed( - 2, - new ::grpc::internal::SplitServerStreamingHandler< - ::grpc::testing::Request, ::grpc::testing::Response>(std::bind( - &WithSplitStreamingMethod_MethodA3::StreamedMethodA3, - this, std::placeholders::_1, std::placeholders::_2))); + ::grpc::Service::MarkMethodStreamed(2, + new ::grpc::internal::SplitServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithSplitStreamingMethod_MethodA3::StreamedMethodA3, this, std::placeholders::_1, std::placeholders::_2))); } ~WithSplitStreamingMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); } // disable regular version of this method - ::grpc::Status MethodA3( - ::grpc::ServerContext* context, const ::grpc::testing::Request* request, - ::grpc::ServerWriter<::grpc::testing::Response>* writer) override { + ::grpc::Status MethodA3(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::ServerWriter< ::grpc::testing::Response>* writer) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } // replace default version of method with split streamed - virtual ::grpc::Status StreamedMethodA3( - ::grpc::ServerContext* context, - ::grpc::ServerSplitStreamer<::grpc::testing::Request, - ::grpc::testing::Response>* - server_split_streamer) = 0; + virtual ::grpc::Status StreamedMethodA3(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_split_streamer) = 0; }; - typedef WithSplitStreamingMethod_MethodA3 SplitStreamedService; - typedef WithStreamedUnaryMethod_MethodA1< - WithSplitStreamingMethod_MethodA3> - StreamedService; + typedef WithSplitStreamingMethod_MethodA3 SplitStreamedService; + typedef WithStreamedUnaryMethod_MethodA1 > StreamedService; }; // ServiceB leading comment 1 @@ -1014,204 +665,125 @@ class ServiceB final { public: virtual ~StubInterface() {} // MethodB1 leading comment 1 - virtual ::grpc::Status MethodB1(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::testing::Response* response) = 0; - std::unique_ptr< - ::grpc::ClientAsyncResponseReaderInterface<::grpc::testing::Response>> - AsyncMethodB1(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface< - ::grpc::testing::Response>>(AsyncMethodB1Raw(context, request, cq)); + virtual ::grpc::Status MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response) = 0; + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>> AsyncMethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>>(AsyncMethodB1Raw(context, request, cq)); } - std::unique_ptr< - ::grpc::ClientAsyncResponseReaderInterface<::grpc::testing::Response>> - PrepareAsyncMethodB1(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr<::grpc::ClientAsyncResponseReaderInterface< - ::grpc::testing::Response>>( - PrepareAsyncMethodB1Raw(context, request, cq)); + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>> PrepareAsyncMethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>>(PrepareAsyncMethodB1Raw(context, request, cq)); } // MethodB1 trailing comment 1 class experimental_async_interface { public: 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::testing::Request* request, ::grpc::testing::Response* response, std::function) = 0; // MethodB1 trailing comment 1 }; - virtual class experimental_async_interface* experimental_async() { - return nullptr; - } - - private: - virtual ::grpc::ClientAsyncResponseReaderInterface< - ::grpc::testing::Response>* - AsyncMethodB1Raw(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) = 0; - virtual ::grpc::ClientAsyncResponseReaderInterface< - ::grpc::testing::Response>* - PrepareAsyncMethodB1Raw(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) = 0; + virtual class experimental_async_interface* experimental_async() { return nullptr; } + private: + virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* AsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* PrepareAsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; }; class Stub final : public StubInterface { public: - Stub(const std::shared_ptr<::grpc::ChannelInterface>& channel); - ::grpc::Status MethodB1(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::testing::Response* response) override; - std::unique_ptr< - ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>> - AsyncMethodB1(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr< - ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>>( - AsyncMethodB1Raw(context, request, cq)); + Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); + ::grpc::Status MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response) override; + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>> AsyncMethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>>(AsyncMethodB1Raw(context, request, cq)); } - std::unique_ptr< - ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>> - PrepareAsyncMethodB1(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) { - return std::unique_ptr< - ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>>( - PrepareAsyncMethodB1Raw(context, request, cq)); + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>> PrepareAsyncMethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>>(PrepareAsyncMethodB1Raw(context, request, cq)); } - class experimental_async final - : public StubInterface::experimental_async_interface { + class experimental_async 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::testing::Request* request, ::grpc::testing::Response* response, std::function) override; private: friend class Stub; - explicit experimental_async(Stub* stub) : stub_(stub) {} + explicit experimental_async(Stub* stub): stub_(stub) { } Stub* stub() { return stub_; } Stub* stub_; }; - class experimental_async_interface* experimental_async() override { - return &async_stub_; - } + class experimental_async_interface* experimental_async() override { return &async_stub_; } private: - std::shared_ptr<::grpc::ChannelInterface> channel_; - class experimental_async async_stub_ { - this - }; - ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>* - AsyncMethodB1Raw(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) override; - ::grpc::ClientAsyncResponseReader<::grpc::testing::Response>* - PrepareAsyncMethodB1Raw(::grpc::ClientContext* context, - const ::grpc::testing::Request& request, - ::grpc::CompletionQueue* cq) override; + std::shared_ptr< ::grpc::ChannelInterface> channel_; + class experimental_async async_stub_{this}; + ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* AsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* PrepareAsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; const ::grpc::internal::RpcMethod rpcmethod_MethodB1_; }; - static std::unique_ptr NewStub( - const std::shared_ptr<::grpc::ChannelInterface>& channel, - const ::grpc::StubOptions& options = ::grpc::StubOptions()); + static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); class Service : public ::grpc::Service { public: Service(); virtual ~Service(); // MethodB1 leading comment 1 - virtual ::grpc::Status MethodB1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response); + virtual ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response); // MethodB1 trailing comment 1 }; template class WithAsyncMethod_MethodB1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithAsyncMethod_MethodB1() { ::grpc::Service::MarkMethodAsync(0); } + WithAsyncMethod_MethodB1() { + ::grpc::Service::MarkMethodAsync(0); + } ~WithAsyncMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodB1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodB1( - ::grpc::ServerContext* context, ::grpc::testing::Request* request, - ::grpc::ServerAsyncResponseWriter<::grpc::testing::Response>* response, - ::grpc::CompletionQueue* new_call_cq, - ::grpc::ServerCompletionQueue* notification_cq, void* tag) { - ::grpc::Service::RequestAsyncUnary(0, context, request, response, - new_call_cq, notification_cq, tag); + void RequestMethodB1(::grpc::ServerContext* context, ::grpc::testing::Request* request, ::grpc::ServerAsyncResponseWriter< ::grpc::testing::Response>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); } }; - typedef WithAsyncMethod_MethodB1 AsyncService; + typedef WithAsyncMethod_MethodB1 AsyncService; template class ExperimentalWithCallbackMethod_MethodB1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithCallbackMethod_MethodB1() { - ::grpc::Service::experimental().MarkMethodCallback( - 0, new ::grpc::internal::CallbackUnaryHandler< - ExperimentalWithCallbackMethod_MethodB1, - ::grpc::testing::Request, ::grpc::testing::Response>( - [this](::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response, - ::grpc::experimental::ServerCallbackRpcController* - controller) { + ::grpc::Service::experimental().MarkMethodCallback(0, + new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithCallbackMethod_MethodB1, ::grpc::testing::Request, ::grpc::testing::Response>( + [this](::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response, + ::grpc::experimental::ServerCallbackRpcController* controller) { this->MethodB1(context, request, response, controller); - }, - this)); + }, this)); } ~ExperimentalWithCallbackMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodB1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - virtual void MethodB1( - ::grpc::ServerContext* context, const ::grpc::testing::Request* request, - ::grpc::testing::Response* response, - ::grpc::experimental::ServerCallbackRpcController* controller) { - controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); - } + virtual void MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ServerCallbackRpcController* controller) { controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); } }; - typedef ExperimentalWithCallbackMethod_MethodB1 - ExperimentalCallbackService; + typedef ExperimentalWithCallbackMethod_MethodB1 ExperimentalCallbackService; template class WithGenericMethod_MethodB1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithGenericMethod_MethodB1() { ::grpc::Service::MarkMethodGeneric(0); } + WithGenericMethod_MethodB1() { + ::grpc::Service::MarkMethodGeneric(0); + } ~WithGenericMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodB1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } @@ -1219,103 +791,76 @@ class ServiceB final { template class WithRawMethod_MethodB1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: - WithRawMethod_MethodB1() { ::grpc::Service::MarkMethodRaw(0); } + WithRawMethod_MethodB1() { + ::grpc::Service::MarkMethodRaw(0); + } ~WithRawMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodB1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - void RequestMethodB1( - ::grpc::ServerContext* context, ::grpc::ByteBuffer* request, - ::grpc::ServerAsyncResponseWriter<::grpc::ByteBuffer>* response, - ::grpc::CompletionQueue* new_call_cq, - ::grpc::ServerCompletionQueue* notification_cq, void* tag) { - ::grpc::Service::RequestAsyncUnary(0, context, request, response, - new_call_cq, notification_cq, tag); + void RequestMethodB1(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); } }; template class ExperimentalWithRawCallbackMethod_MethodB1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithRawCallbackMethod_MethodB1() { - ::grpc::Service::experimental().MarkMethodRawCallback( - 0, new ::grpc::internal::CallbackUnaryHandler< - ExperimentalWithRawCallbackMethod_MethodB1, - ::grpc::ByteBuffer, ::grpc::ByteBuffer>( - [this](::grpc::ServerContext* context, - const ::grpc::ByteBuffer* request, - ::grpc::ByteBuffer* response, - ::grpc::experimental::ServerCallbackRpcController* - controller) { + ::grpc::Service::experimental().MarkMethodRawCallback(0, + new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithRawCallbackMethod_MethodB1, ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this](::grpc::ServerContext* context, + const ::grpc::ByteBuffer* request, + ::grpc::ByteBuffer* response, + ::grpc::experimental::ServerCallbackRpcController* controller) { this->MethodB1(context, request, response, controller); - }, - this)); + }, this)); } ~ExperimentalWithRawCallbackMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); } // disable synchronous version of this method - ::grpc::Status MethodB1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } - virtual void MethodB1( - ::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, - ::grpc::ByteBuffer* response, - ::grpc::experimental::ServerCallbackRpcController* controller) { - controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); - } + virtual void MethodB1(::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response, ::grpc::experimental::ServerCallbackRpcController* controller) { controller->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); } }; template class WithStreamedUnaryMethod_MethodB1 : public BaseClass { private: - void BaseClassMustBeDerivedFromService(const Service* service) {} - + void BaseClassMustBeDerivedFromService(const Service *service) {} public: WithStreamedUnaryMethod_MethodB1() { - ::grpc::Service::MarkMethodStreamed( - 0, new ::grpc::internal::StreamedUnaryHandler< - ::grpc::testing::Request, ::grpc::testing::Response>(std::bind( - &WithStreamedUnaryMethod_MethodB1::StreamedMethodB1, - this, std::placeholders::_1, std::placeholders::_2))); + ::grpc::Service::MarkMethodStreamed(0, + new ::grpc::internal::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodB1::StreamedMethodB1, this, std::placeholders::_1, std::placeholders::_2))); } ~WithStreamedUnaryMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); } // disable regular version of this method - ::grpc::Status MethodB1(::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response) override { + ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) override { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } // replace default version of method with streamed unary - virtual ::grpc::Status StreamedMethodB1( - ::grpc::ServerContext* context, - ::grpc::ServerUnaryStreamer<::grpc::testing::Request, - ::grpc::testing::Response>* - server_unary_streamer) = 0; + virtual ::grpc::Status StreamedMethodB1(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_unary_streamer) = 0; }; - typedef WithStreamedUnaryMethod_MethodB1 StreamedUnaryService; + typedef WithStreamedUnaryMethod_MethodB1 StreamedUnaryService; typedef Service SplitStreamedService; - typedef WithStreamedUnaryMethod_MethodB1 StreamedService; + typedef WithStreamedUnaryMethod_MethodB1 StreamedService; }; // ServiceB trailing comment 1 } // namespace testing } // namespace grpc + #endif // GRPC_src_2fproto_2fgrpc_2ftesting_2fcompiler_5ftest_2eproto__INCLUDED diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index a1fe199b546..6c18703f06b 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -206,7 +206,7 @@ class ClientCallbackEnd2endTest EXPECT_TRUE(ParseFromByteBuffer(&recv_buf_, &response)); EXPECT_EQ(request_.message(), response.message()); }; - void OnDone(Status s) override { + void OnDone(const Status& s) override { EXPECT_TRUE(s.ok()); std::unique_lock l(mu_); done_ = true; @@ -345,7 +345,7 @@ TEST_P(ClientCallbackEnd2endTest, RequestStream) { StartWriteLast(&request_, WriteOptions()); } } - void OnDone(Status s) override { + 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_); @@ -398,7 +398,7 @@ TEST_P(ClientCallbackEnd2endTest, ResponseStream) { StartRead(&response_); } } - void OnDone(Status s) override { + void OnDone(const Status& s) override { EXPECT_TRUE(s.ok()); std::unique_lock l(mu_); done_ = true; @@ -458,7 +458,7 @@ TEST_P(ClientCallbackEnd2endTest, BidiStream) { StartWrite(&request_); } } - void OnDone(Status s) override { + void OnDone(const Status& s) override { EXPECT_TRUE(s.ok()); std::unique_lock l(mu_); done_ = true; From f596b957105f9e4dd11fe48cc2b2e458073d6bcc Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 30 Nov 2018 13:20:21 +0100 Subject: [PATCH 0381/2143] cleanup references to removed multilang docker image --- tools/run_tests/run_tests.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index f71be2a65e9..5fcb3b71243 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1550,16 +1550,9 @@ if args.use_docker: dockerfile_dirs = set([l.dockerfile_dir() for l in languages]) if len(dockerfile_dirs) > 1: - if 'gcov' in args.config: - dockerfile_dir = 'tools/dockerfile/test/multilang_jessie_x64' - print( - 'Using multilang_jessie_x64 docker image for code coverage for ' - 'all languages.') - else: - print( - 'Languages to be tested require running under different docker ' - 'images.') - sys.exit(1) + print('Languages to be tested require running under different docker ' + 'images.') + sys.exit(1) else: dockerfile_dir = next(iter(dockerfile_dirs)) From b26d24df859562387bc0ef5cd81ca18fea5b72e5 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 30 Nov 2018 08:50:20 -0800 Subject: [PATCH 0382/2143] Stop passing ExecCtx as avl user_data. --- .../client_channel/subchannel_index.cc | 47 ++++++++----------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc index 1c23a6c4be4..aa8441f17b0 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.cc +++ b/src/core/ext/filters/client_channel/subchannel_index.cc @@ -91,7 +91,7 @@ void grpc_subchannel_key_destroy(grpc_subchannel_key* k) { gpr_free(k); } -static void sck_avl_destroy(void* p, void* user_data) { +static void sck_avl_destroy(void* p, void* unused) { grpc_subchannel_key_destroy(static_cast(p)); } @@ -104,7 +104,7 @@ static long sck_avl_compare(void* a, void* b, void* unused) { static_cast(b)); } -static void scv_avl_destroy(void* p, void* user_data) { +static void scv_avl_destroy(void* p, void* unused) { GRPC_SUBCHANNEL_WEAK_UNREF((grpc_subchannel*)p, "subchannel_index"); } @@ -137,7 +137,7 @@ void grpc_subchannel_index_shutdown(void) { void grpc_subchannel_index_unref(void) { if (gpr_unref(&g_refcount)) { gpr_mu_destroy(&g_mu); - grpc_avl_unref(g_subchannel_index, grpc_core::ExecCtx::Get()); + grpc_avl_unref(g_subchannel_index, nullptr); } } @@ -147,13 +147,12 @@ 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, grpc_core::ExecCtx::Get()); + 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, grpc_core::ExecCtx::Get()), - "index_find"); - grpc_avl_unref(index, grpc_core::ExecCtx::Get()); + (grpc_subchannel*)grpc_avl_get(index, key, nullptr), "index_find"); + grpc_avl_unref(index, nullptr); return c; } @@ -169,13 +168,11 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key, // 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, grpc_core::ExecCtx::Get()); + 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, grpc_core::ExecCtx::Get())); + c = static_cast(grpc_avl_get(index, key, nullptr)); if (c != nullptr) { c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "index_register"); } @@ -184,11 +181,9 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key, need_to_unref_constructed = true; } else { // no -> update the avl and compare/swap - grpc_avl updated = - grpc_avl_add(grpc_avl_ref(index, grpc_core::ExecCtx::Get()), - subchannel_key_copy(key), - GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register"), - grpc_core::ExecCtx::Get()); + 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: @@ -200,9 +195,9 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key, } gpr_mu_unlock(&g_mu); - grpc_avl_unref(updated, grpc_core::ExecCtx::Get()); + grpc_avl_unref(updated, nullptr); } - grpc_avl_unref(index, grpc_core::ExecCtx::Get()); + grpc_avl_unref(index, nullptr); } if (need_to_unref_constructed) { @@ -219,24 +214,22 @@ void grpc_subchannel_index_unregister(grpc_subchannel_key* key, // 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, grpc_core::ExecCtx::Get()); + 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, grpc_core::ExecCtx::Get())); + grpc_subchannel* c = + static_cast(grpc_avl_get(index, key, nullptr)); if (c != constructed) { - grpc_avl_unref(index, grpc_core::ExecCtx::Get()); + 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, grpc_core::ExecCtx::Get()), key, - grpc_core::ExecCtx::Get()); + grpc_avl_remove(grpc_avl_ref(index, nullptr), key, nullptr); gpr_mu_lock(&g_mu); if (index.root == g_subchannel_index.root) { @@ -245,8 +238,8 @@ void grpc_subchannel_index_unregister(grpc_subchannel_key* key, } gpr_mu_unlock(&g_mu); - grpc_avl_unref(updated, grpc_core::ExecCtx::Get()); - grpc_avl_unref(index, grpc_core::ExecCtx::Get()); + grpc_avl_unref(updated, nullptr); + grpc_avl_unref(index, nullptr); } } From 2a938b0006c098cba1c559afacdd311c55afa723 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 30 Nov 2018 08:53:08 -0800 Subject: [PATCH 0383/2143] Add a class to wrap grpc_test_init --- test/core/util/test_config.cc | 12 ++++++++++++ test/core/util/test_config.h | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index 6a0d444a732..115d89b6b42 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -397,3 +397,15 @@ void grpc_test_init(int argc, char** argv) { concurrently running test binary */ srand(seed()); } + +namespace grpc { +namespace testing { + +TestEnvironment::TestEnvironment(int argc, char **argv) { + grpc_test_init(argc, argv); +} + +TestEnvironment::~TestEnvironment() {} + +} // namespace testing +} // namespace grpc diff --git a/test/core/util/test_config.h b/test/core/util/test_config.h index 5b3d34799ee..a8a2d32aaf0 100644 --- a/test/core/util/test_config.h +++ b/test/core/util/test_config.h @@ -37,6 +37,21 @@ gpr_timespec grpc_timeout_milliseconds_to_deadline(int64_t time_ms); #define GRPC_TEST_PICK_PORT #endif +// Prefer TestEnvironment below. void grpc_test_init(int argc, char** argv); +namespace grpc { +namespace testing { + +// A TestEnvironment object should be alive in the main function of a test. It +// provides test init and shutdown inside. +class TestEnvironment { +public: + TestEnvironment(int argc, char **argv); + ~TestEnvironment(); +}; + +} // namespace testing +} // namespace grpc + #endif /* GRPC_TEST_CORE_UTIL_TEST_CONFIG_H */ From e75fc243daa36e6eee8742289ee47101f4a82afe Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 30 Nov 2018 08:57:28 -0800 Subject: [PATCH 0384/2143] change tests to use the new class instead of grpc_test_init --- test/core/avl/avl_test.cc | 2 +- test/core/backoff/backoff_test.cc | 2 +- test/core/bad_client/tests/badreq.cc | 2 +- test/core/bad_client/tests/connection_prefix.cc | 2 +- test/core/bad_client/tests/duplicate_header.cc | 2 +- test/core/bad_client/tests/head_of_line_blocking.cc | 2 +- test/core/bad_client/tests/headers.cc | 2 +- test/core/bad_client/tests/initial_settings_frame.cc | 2 +- test/core/bad_client/tests/large_metadata.cc | 2 +- test/core/bad_client/tests/server_registered_method.cc | 2 +- test/core/bad_client/tests/simple_request.cc | 2 +- test/core/bad_client/tests/unknown_frame.cc | 2 +- test/core/bad_client/tests/window_overflow.cc | 2 +- test/core/channel/channel_args_test.cc | 2 +- test/core/channel/channel_stack_builder_test.cc | 2 +- test/core/channel/channel_stack_test.cc | 2 +- test/core/channel/channel_trace_test.cc | 2 +- test/core/channel/channelz_registry_test.cc | 2 +- test/core/channel/channelz_test.cc | 2 +- test/core/channel/minimal_stack_is_minimal_test.cc | 2 +- test/core/client_channel/parse_address_test.cc | 2 +- .../resolvers/dns_resolver_connectivity_test.cc | 2 +- .../client_channel/resolvers/dns_resolver_cooldown_test.cc | 2 +- test/core/client_channel/resolvers/dns_resolver_test.cc | 2 +- test/core/client_channel/resolvers/fake_resolver_test.cc | 2 +- test/core/client_channel/resolvers/sockaddr_resolver_test.cc | 2 +- test/core/client_channel/retry_throttle_test.cc | 2 +- test/core/client_channel/uri_parser_test.cc | 2 +- test/core/compression/algorithm_test.cc | 2 +- test/core/compression/message_compress_test.cc | 2 +- test/core/end2end/bad_server_response_test.cc | 2 +- test/core/end2end/connection_refused_test.cc | 2 +- test/core/end2end/dualstack_socket_test.cc | 2 +- test/core/end2end/fixtures/h2_census.cc | 2 +- test/core/end2end/fixtures/h2_compress.cc | 2 +- test/core/end2end/fixtures/h2_fakesec.cc | 2 +- test/core/end2end/fixtures/h2_fd.cc | 2 +- test/core/end2end/fixtures/h2_full+pipe.cc | 2 +- test/core/end2end/fixtures/h2_full+trace.cc | 2 +- test/core/end2end/fixtures/h2_full+workarounds.cc | 2 +- test/core/end2end/fixtures/h2_full.cc | 2 +- test/core/end2end/fixtures/h2_http_proxy.cc | 2 +- test/core/end2end/fixtures/h2_local.cc | 2 +- test/core/end2end/fixtures/h2_oauth2.cc | 2 +- test/core/end2end/fixtures/h2_proxy.cc | 2 +- test/core/end2end/fixtures/h2_sockpair+trace.cc | 2 +- test/core/end2end/fixtures/h2_sockpair.cc | 2 +- test/core/end2end/fixtures/h2_sockpair_1byte.cc | 2 +- test/core/end2end/fixtures/h2_ssl.cc | 2 +- test/core/end2end/fixtures/h2_ssl_proxy.cc | 2 +- test/core/end2end/fixtures/h2_uds.cc | 2 +- test/core/end2end/fixtures/inproc.cc | 2 +- test/core/end2end/goaway_server_test.cc | 2 +- test/core/end2end/h2_ssl_cert_test.cc | 2 +- test/core/end2end/h2_ssl_session_reuse_test.cc | 2 +- test/core/end2end/inproc_callback_test.cc | 2 +- test/core/end2end/invalid_call_argument_test.cc | 2 +- test/core/end2end/multiple_server_queues_test.cc | 2 +- test/core/end2end/no_server_test.cc | 2 +- test/core/gpr/alloc_test.cc | 2 +- test/core/gpr/arena_test.cc | 2 +- test/core/gpr/cpu_test.cc | 2 +- test/core/gpr/env_test.cc | 2 +- test/core/gpr/host_port_test.cc | 2 +- test/core/gpr/log_test.cc | 2 +- test/core/gpr/mpscq_test.cc | 2 +- test/core/gpr/murmur_hash_test.cc | 2 +- test/core/gpr/spinlock_test.cc | 2 +- test/core/gpr/string_test.cc | 2 +- test/core/gpr/sync_test.cc | 2 +- test/core/gpr/time_test.cc | 2 +- test/core/gpr/tls_test.cc | 2 +- test/core/gpr/useful_test.cc | 2 +- test/core/gprpp/fork_test.cc | 2 +- test/core/gprpp/inlined_vector_test.cc | 2 +- test/core/gprpp/manual_constructor_test.cc | 2 +- test/core/gprpp/memory_test.cc | 2 +- test/core/gprpp/orphanable_test.cc | 2 +- test/core/gprpp/ref_counted_ptr_test.cc | 2 +- test/core/gprpp/ref_counted_test.cc | 2 +- test/core/gprpp/thd_test.cc | 2 +- test/core/http/format_request_test.cc | 2 +- test/core/http/httpcli_test.cc | 2 +- test/core/http/httpscli_test.cc | 2 +- test/core/http/parser_test.cc | 2 +- test/core/iomgr/buffer_list_test.cc | 2 +- test/core/iomgr/combiner_test.cc | 2 +- test/core/iomgr/endpoint_pair_test.cc | 2 +- test/core/iomgr/error_test.cc | 2 +- test/core/iomgr/ev_epollex_linux_test.cc | 2 +- test/core/iomgr/fd_conservation_posix_test.cc | 2 +- test/core/iomgr/fd_posix_test.cc | 2 +- test/core/iomgr/grpc_ipv6_loopback_available_test.cc | 2 +- test/core/iomgr/load_file_test.cc | 2 +- test/core/iomgr/resolve_address_posix_test.cc | 2 +- test/core/iomgr/resolve_address_test.cc | 2 +- test/core/iomgr/resource_quota_test.cc | 2 +- test/core/iomgr/sockaddr_utils_test.cc | 2 +- test/core/iomgr/socket_utils_test.cc | 2 +- test/core/iomgr/tcp_client_posix_test.cc | 2 +- test/core/iomgr/tcp_client_uv_test.cc | 2 +- test/core/iomgr/tcp_posix_test.cc | 2 +- test/core/iomgr/tcp_server_posix_test.cc | 2 +- test/core/iomgr/tcp_server_uv_test.cc | 2 +- test/core/iomgr/time_averaged_stats_test.cc | 2 +- test/core/iomgr/timer_heap_test.cc | 2 +- test/core/iomgr/timer_list_test.cc | 4 ++-- test/core/iomgr/udp_server_test.cc | 2 +- test/core/json/json_rewrite_test.cc | 2 +- test/core/json/json_stream_error_test.cc | 2 +- test/core/json/json_test.cc | 2 +- test/core/security/auth_context_test.cc | 2 +- test/core/security/credentials_test.cc | 2 +- test/core/security/json_token_test.cc | 2 +- test/core/security/jwt_verifier_test.cc | 2 +- test/core/security/linux_system_roots_test.cc | 2 +- test/core/security/secure_endpoint_test.cc | 2 +- test/core/security/security_connector_test.cc | 2 +- test/core/security/ssl_credentials_test.cc | 2 +- test/core/slice/b64_test.cc | 2 +- test/core/slice/percent_encoding_test.cc | 2 +- test/core/slice/slice_buffer_test.cc | 2 +- test/core/slice/slice_hash_table_test.cc | 2 +- test/core/slice/slice_string_helpers_test.cc | 2 +- test/core/slice/slice_test.cc | 2 +- test/core/slice/slice_weak_hash_table_test.cc | 2 +- test/core/surface/byte_buffer_reader_test.cc | 2 +- test/core/surface/channel_create_test.cc | 2 +- test/core/surface/completion_queue_test.cc | 2 +- test/core/surface/completion_queue_threading_test.cc | 2 +- test/core/surface/concurrent_connectivity_test.cc | 2 +- test/core/surface/init_test.cc | 2 +- test/core/surface/lame_client_test.cc | 2 +- test/core/surface/num_external_connectivity_watchers_test.cc | 2 +- test/core/surface/secure_channel_create_test.cc | 2 +- test/core/surface/sequential_connectivity_test.cc | 2 +- test/core/surface/server_chttp2_test.cc | 2 +- test/core/surface/server_test.cc | 2 +- test/core/transport/bdp_estimator_test.cc | 2 +- test/core/transport/byte_stream_test.cc | 2 +- test/core/transport/chttp2/alpn_test.cc | 2 +- test/core/transport/chttp2/context_list_test.cc | 2 +- test/core/transport/chttp2/hpack_encoder_test.cc | 2 +- test/core/transport/chttp2/hpack_parser_test.cc | 2 +- test/core/transport/chttp2/hpack_table_test.cc | 2 +- test/core/transport/chttp2/settings_timeout_test.cc | 2 +- test/core/transport/chttp2/stream_map_test.cc | 2 +- test/core/transport/chttp2/varint_test.cc | 2 +- test/core/transport/connectivity_state_test.cc | 2 +- test/core/transport/metadata_test.cc | 2 +- test/core/transport/pid_controller_test.cc | 2 +- test/core/transport/status_conversion_test.cc | 2 +- test/core/transport/stream_owned_slice_test.cc | 2 +- test/core/transport/timeout_encoding_test.cc | 2 +- test/core/tsi/fake_transport_security_test.cc | 2 +- test/core/tsi/ssl_session_cache_test.cc | 2 +- test/core/tsi/ssl_transport_security_test.cc | 2 +- test/core/tsi/transport_security_test.cc | 2 +- test/core/util/cmdline_test.cc | 2 +- test/core/util/fuzzer_corpus_test.cc | 2 +- test/cpp/client/client_channel_stress_test.cc | 2 +- test/cpp/common/alarm_test.cc | 2 +- test/cpp/end2end/async_end2end_test.cc | 2 +- test/cpp/end2end/channelz_service_test.cc | 2 +- test/cpp/end2end/client_callback_end2end_test.cc | 2 +- test/cpp/end2end/client_crash_test.cc | 2 +- test/cpp/end2end/client_interceptors_end2end_test.cc | 2 +- test/cpp/end2end/client_lb_end2end_test.cc | 2 +- test/cpp/end2end/end2end_test.cc | 2 +- test/cpp/end2end/exception_test.cc | 2 +- test/cpp/end2end/filter_end2end_test.cc | 2 +- test/cpp/end2end/generic_end2end_test.cc | 2 +- test/cpp/end2end/grpclb_end2end_test.cc | 2 +- test/cpp/end2end/health_service_end2end_test.cc | 2 +- test/cpp/end2end/hybrid_end2end_test.cc | 2 +- test/cpp/end2end/mock_test.cc | 2 +- test/cpp/end2end/nonblocking_test.cc | 2 +- test/cpp/end2end/proto_server_reflection_test.cc | 2 +- test/cpp/end2end/raw_end2end_test.cc | 2 +- test/cpp/end2end/server_builder_plugin_test.cc | 2 +- test/cpp/end2end/server_crash_test.cc | 2 +- test/cpp/end2end/server_early_return_test.cc | 2 +- test/cpp/end2end/server_interceptors_end2end_test.cc | 2 +- test/cpp/end2end/shutdown_test.cc | 2 +- test/cpp/end2end/streaming_throughput_test.cc | 2 +- test/cpp/end2end/thread_stress_test.cc | 2 +- test/cpp/ext/filters/census/stats_plugin_end2end_test.cc | 2 +- test/cpp/naming/address_sorting_test.cc | 2 +- test/cpp/naming/cancel_ares_query_test.cc | 2 +- test/cpp/naming/resolver_component_test.cc | 2 +- test/cpp/performance/writes_per_rpc_test.cc | 2 +- test/cpp/server/load_reporter/get_cpu_stats_test.cc | 2 +- test/cpp/server/load_reporter/load_data_store_test.cc | 2 +- test/cpp/server/load_reporter/load_reporter_test.cc | 2 +- test/cpp/util/cli_call_test.cc | 2 +- test/cpp/util/grpc_tool_test.cc | 2 +- 196 files changed, 197 insertions(+), 197 deletions(-) diff --git a/test/core/avl/avl_test.cc b/test/core/avl/avl_test.cc index 01002fec72a..769e67563dc 100644 --- a/test/core/avl/avl_test.cc +++ b/test/core/avl/avl_test.cc @@ -283,7 +283,7 @@ static void test_stress(int amount_of_stress) { } int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_get(); test_ll(); diff --git a/test/core/backoff/backoff_test.cc b/test/core/backoff/backoff_test.cc index 1998a839778..8fd120e0428 100644 --- a/test/core/backoff/backoff_test.cc +++ b/test/core/backoff/backoff_test.cc @@ -171,7 +171,7 @@ TEST(BackOffTest, JitterBackOff) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/bad_client/tests/badreq.cc b/test/core/bad_client/tests/badreq.cc index eeaf4c99748..c560dc5561c 100644 --- a/test/core/bad_client/tests/badreq.cc +++ b/test/core/bad_client/tests/badreq.cc @@ -39,7 +39,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* invalid content type */ diff --git a/test/core/bad_client/tests/connection_prefix.cc b/test/core/bad_client/tests/connection_prefix.cc index 4aab234d3e5..286a3ccafbb 100644 --- a/test/core/bad_client/tests/connection_prefix.cc +++ b/test/core/bad_client/tests/connection_prefix.cc @@ -29,7 +29,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr, "X", 0); diff --git a/test/core/bad_client/tests/duplicate_header.cc b/test/core/bad_client/tests/duplicate_header.cc index e3cae8b5952..dfa6e518114 100644 --- a/test/core/bad_client/tests/duplicate_header.cc +++ b/test/core/bad_client/tests/duplicate_header.cc @@ -122,7 +122,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* Verify that sending multiple headers doesn't segfault */ diff --git a/test/core/bad_client/tests/head_of_line_blocking.cc b/test/core/bad_client/tests/head_of_line_blocking.cc index 427db464462..c856b9b122c 100644 --- a/test/core/bad_client/tests/head_of_line_blocking.cc +++ b/test/core/bad_client/tests/head_of_line_blocking.cc @@ -109,7 +109,7 @@ static void addbuf(const void* data, size_t len) { int main(int argc, char** argv) { int i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); #define NUM_FRAMES 10 diff --git a/test/core/bad_client/tests/headers.cc b/test/core/bad_client/tests/headers.cc index 2aa1b280cee..02ea7597502 100644 --- a/test/core/bad_client/tests/headers.cc +++ b/test/core/bad_client/tests/headers.cc @@ -33,7 +33,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* partial http2 header prefixes */ diff --git a/test/core/bad_client/tests/initial_settings_frame.cc b/test/core/bad_client/tests/initial_settings_frame.cc index 0220000ecea..fcbb841331f 100644 --- a/test/core/bad_client/tests/initial_settings_frame.cc +++ b/test/core/bad_client/tests/initial_settings_frame.cc @@ -32,7 +32,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* various partial prefixes */ diff --git a/test/core/bad_client/tests/large_metadata.cc b/test/core/bad_client/tests/large_metadata.cc index d534753f536..520a1af0c2d 100644 --- a/test/core/bad_client/tests/large_metadata.cc +++ b/test/core/bad_client/tests/large_metadata.cc @@ -141,7 +141,7 @@ static void server_verifier_sends_too_much_metadata(grpc_server* server, int main(int argc, char** argv) { int i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); // Test sending more metadata than the server will accept. gpr_strvec headers; diff --git a/test/core/bad_client/tests/server_registered_method.cc b/test/core/bad_client/tests/server_registered_method.cc index c2dc9c66af1..834142ac1b4 100644 --- a/test/core/bad_client/tests/server_registered_method.cc +++ b/test/core/bad_client/tests/server_registered_method.cc @@ -76,7 +76,7 @@ static void verifier_fails(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* body generated with diff --git a/test/core/bad_client/tests/simple_request.cc b/test/core/bad_client/tests/simple_request.cc index c80fc5cb4af..34049aaaffc 100644 --- a/test/core/bad_client/tests/simple_request.cc +++ b/test/core/bad_client/tests/simple_request.cc @@ -123,7 +123,7 @@ static void failure_verifier(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* basic request: check that things are working */ diff --git a/test/core/bad_client/tests/unknown_frame.cc b/test/core/bad_client/tests/unknown_frame.cc index b1b618a43f3..9e0cf3f6a90 100644 --- a/test/core/bad_client/tests/unknown_frame.cc +++ b/test/core/bad_client/tests/unknown_frame.cc @@ -34,7 +34,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, int main(int argc, char** argv) { grpc_init(); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); /* test adding prioritization data */ GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr, diff --git a/test/core/bad_client/tests/window_overflow.cc b/test/core/bad_client/tests/window_overflow.cc index b552704e9c5..87042a46f20 100644 --- a/test/core/bad_client/tests/window_overflow.cc +++ b/test/core/bad_client/tests/window_overflow.cc @@ -71,7 +71,7 @@ int main(int argc, char** argv) { #define FRAME_SIZE (MESSAGES_PER_FRAME * 5) #define SEND_SIZE (4 * 1024 * 1024) #define NUM_FRAMES (SEND_SIZE / FRAME_SIZE + 1) - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); addbuf(PFX_STR, sizeof(PFX_STR) - 1); diff --git a/test/core/channel/channel_args_test.cc b/test/core/channel/channel_args_test.cc index 41c62a8f16e..087a7679bf8 100644 --- a/test/core/channel/channel_args_test.cc +++ b/test/core/channel/channel_args_test.cc @@ -231,7 +231,7 @@ static void test_server_create_with_args(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_create(); test_set_compression_algorithm(); diff --git a/test/core/channel/channel_stack_builder_test.cc b/test/core/channel/channel_stack_builder_test.cc index aad6d6eee9a..b5598e63f9f 100644 --- a/test/core/channel/channel_stack_builder_test.cc +++ b/test/core/channel/channel_stack_builder_test.cc @@ -132,7 +132,7 @@ static void init_plugin(void) { static void destroy_plugin(void) {} int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_register_plugin(init_plugin, destroy_plugin); grpc_init(); test_channel_stack_builder_filter_replace(); diff --git a/test/core/channel/channel_stack_test.cc b/test/core/channel/channel_stack_test.cc index 6f0bfa06d21..14726336f92 100644 --- a/test/core/channel/channel_stack_test.cc +++ b/test/core/channel/channel_stack_test.cc @@ -147,7 +147,7 @@ static void test_create_channel_stack(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_create_channel_stack(); grpc_shutdown(); diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index 3d8de79e376..b3c0b368982 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -342,7 +342,7 @@ TEST(ChannelTracerTest, TestTotalEviction) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); diff --git a/test/core/channel/channelz_registry_test.cc b/test/core/channel/channelz_registry_test.cc index fdfc8eec94a..ed3d629dc99 100644 --- a/test/core/channel/channelz_registry_test.cc +++ b/test/core/channel/channelz_registry_test.cc @@ -195,7 +195,7 @@ TEST_F(ChannelzRegistryTest, TestAddAfterCompaction) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); return ret; diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index 4d4b0770022..abd1601ad14 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -541,7 +541,7 @@ INSTANTIATE_TEST_CASE_P(ChannelzChannelTestSweep, ChannelzChannelTest, } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); diff --git a/test/core/channel/minimal_stack_is_minimal_test.cc b/test/core/channel/minimal_stack_is_minimal_test.cc index e5953acedcf..bee0bfb41f2 100644 --- a/test/core/channel/minimal_stack_is_minimal_test.cc +++ b/test/core/channel/minimal_stack_is_minimal_test.cc @@ -56,7 +56,7 @@ static int check_stack(const char* file, int line, const char* transport_name, #define CHECK_STACK(...) check_stack(__FILE__, __LINE__, __VA_ARGS__) int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); int errors = 0; diff --git a/test/core/client_channel/parse_address_test.cc b/test/core/client_channel/parse_address_test.cc index 004549fa621..b77a51a9e49 100644 --- a/test/core/client_channel/parse_address_test.cc +++ b/test/core/client_channel/parse_address_test.cc @@ -101,7 +101,7 @@ static void test_grpc_parse_ipv6_invalid(const char* uri_text) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_grpc_parse_unix("unix:/path/name", "/path/name"); 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 eb5a9117484..12c66ad2a56 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -145,7 +145,7 @@ static void call_resolver_next_after_locking(grpc_core::Resolver* resolver, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); gpr_mu_init(&g_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 1a7db40f598..4fbecea121e 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -262,7 +262,7 @@ static void test_cooldown() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); g_combiner = grpc_combiner_create(); diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc index 103b2916c46..571746abe86 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -60,7 +60,7 @@ static void test_fails(grpc_core::ResolverFactory* factory, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); g_combiner = grpc_combiner_create(); diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc index f6696bf1278..6362b95e50e 100644 --- a/test/core/client_channel/resolvers/fake_resolver_test.cc +++ b/test/core/client_channel/resolvers/fake_resolver_test.cc @@ -213,7 +213,7 @@ static void test_fake_resolver() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); 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 b9287c24688..ff7db6046d7 100644 --- a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc +++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc @@ -84,7 +84,7 @@ static void test_fails(grpc_core::ResolverFactory* factory, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); g_combiner = grpc_combiner_create(); diff --git a/test/core/client_channel/retry_throttle_test.cc b/test/core/client_channel/retry_throttle_test.cc index c6d5d3ebbb8..793e86dc065 100644 --- a/test/core/client_channel/retry_throttle_test.cc +++ b/test/core/client_channel/retry_throttle_test.cc @@ -136,7 +136,7 @@ TEST(ServerRetryThrottleMap, Replacement) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/client_channel/uri_parser_test.cc b/test/core/client_channel/uri_parser_test.cc index ec4f755dda8..713ec32e5e8 100644 --- a/test/core/client_channel/uri_parser_test.cc +++ b/test/core/client_channel/uri_parser_test.cc @@ -119,7 +119,7 @@ static void test_query_parts() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_succeeds("http://www.google.com", "http", "www.google.com", "", "", ""); test_succeeds("dns:///foo", "dns", "", "/foo", "", ""); diff --git a/test/core/compression/algorithm_test.cc b/test/core/compression/algorithm_test.cc index 8989a419897..24fe83774b8 100644 --- a/test/core/compression/algorithm_test.cc +++ b/test/core/compression/algorithm_test.cc @@ -105,7 +105,7 @@ static void test_algorithm_failure(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_algorithm_mesh(); diff --git a/test/core/compression/message_compress_test.cc b/test/core/compression/message_compress_test.cc index e3fe825fdf6..e2abf2d3215 100644 --- a/test/core/compression/message_compress_test.cc +++ b/test/core/compression/message_compress_test.cc @@ -292,7 +292,7 @@ int main(int argc, char** argv) { GRPC_SLICE_SPLIT_IDENTITY, GRPC_SLICE_SPLIT_ONE_BYTE}; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); for (i = 0; i < GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT; i++) { diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index f7396a16845..f8ffb551805 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -302,7 +302,7 @@ static void run_test(const char* response_payload, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* status defined in hpack static table */ diff --git a/test/core/end2end/connection_refused_test.cc b/test/core/end2end/connection_refused_test.cc index 33812ec8e5e..4318811b818 100644 --- a/test/core/end2end/connection_refused_test.cc +++ b/test/core/end2end/connection_refused_test.cc @@ -142,7 +142,7 @@ static void run_test(bool wait_for_ready, bool use_service_config) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); run_test(false /* wait_for_ready */, false /* use_service_config */); run_test(true /* wait_for_ready */, false /* use_service_config */); run_test(true /* wait_for_ready */, true /* use_service_config */); diff --git a/test/core/end2end/dualstack_socket_test.cc b/test/core/end2end/dualstack_socket_test.cc index eb1d043fb29..330af8fce07 100644 --- a/test/core/end2end/dualstack_socket_test.cc +++ b/test/core/end2end/dualstack_socket_test.cc @@ -303,7 +303,7 @@ int external_dns_works(const char* host) { int main(int argc, char** argv) { int do_ipv6 = 1; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); if (!grpc_ipv6_loopback_available()) { diff --git a/test/core/end2end/fixtures/h2_census.cc b/test/core/end2end/fixtures/h2_census.cc index 29b1d6d8839..60442ddcc77 100644 --- a/test/core/end2end/fixtures/h2_census.cc +++ b/test/core/end2end/fixtures/h2_census.cc @@ -118,7 +118,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_compress.cc b/test/core/end2end/fixtures/h2_compress.cc index 4aaadf715c0..04142daf63f 100644 --- a/test/core/end2end/fixtures/h2_compress.cc +++ b/test/core/end2end/fixtures/h2_compress.cc @@ -118,7 +118,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_fakesec.cc b/test/core/end2end/fixtures/h2_fakesec.cc index a653d7c477f..ad83aab39f4 100644 --- a/test/core/end2end/fixtures/h2_fakesec.cc +++ b/test/core/end2end/fixtures/h2_fakesec.cc @@ -142,7 +142,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_fd.cc b/test/core/end2end/fixtures/h2_fd.cc index 52be0f7fd51..5d06bd5f3be 100644 --- a/test/core/end2end/fixtures/h2_fd.cc +++ b/test/core/end2end/fixtures/h2_fd.cc @@ -104,7 +104,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_full+pipe.cc b/test/core/end2end/fixtures/h2_full+pipe.cc index c5329640dcd..6d559c4e516 100644 --- a/test/core/end2end/fixtures/h2_full+pipe.cc +++ b/test/core/end2end/fixtures/h2_full+pipe.cc @@ -105,7 +105,7 @@ int main(int argc, char** argv) { grpc_allow_specialized_wakeup_fd = 0; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc index ba7a7803049..2bbad487013 100644 --- a/test/core/end2end/fixtures/h2_full+trace.cc +++ b/test/core/end2end/fixtures/h2_full+trace.cc @@ -113,7 +113,7 @@ int main(int argc, char** argv) { g_fixture_slowdown_factor = 10; #endif - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_full+workarounds.cc b/test/core/end2end/fixtures/h2_full+workarounds.cc index 78da8418f6c..cb0f7d275b3 100644 --- a/test/core/end2end/fixtures/h2_full+workarounds.cc +++ b/test/core/end2end/fixtures/h2_full+workarounds.cc @@ -114,7 +114,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_full.cc b/test/core/end2end/fixtures/h2_full.cc index 0c826b68368..c0d21288c7e 100644 --- a/test/core/end2end/fixtures/h2_full.cc +++ b/test/core/end2end/fixtures/h2_full.cc @@ -97,7 +97,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_http_proxy.cc b/test/core/end2end/fixtures/h2_http_proxy.cc index 0af8a29a152..9b6a81494e1 100644 --- a/test/core/end2end/fixtures/h2_http_proxy.cc +++ b/test/core/end2end/fixtures/h2_http_proxy.cc @@ -120,7 +120,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_local.cc b/test/core/end2end/fixtures/h2_local.cc index cce8f1745a8..18d690ff222 100644 --- a/test/core/end2end/fixtures/h2_local.cc +++ b/test/core/end2end/fixtures/h2_local.cc @@ -140,7 +140,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_oauth2.cc b/test/core/end2end/fixtures/h2_oauth2.cc index 37397d6450a..113a6b11732 100644 --- a/test/core/end2end/fixtures/h2_oauth2.cc +++ b/test/core/end2end/fixtures/h2_oauth2.cc @@ -224,7 +224,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_proxy.cc b/test/core/end2end/fixtures/h2_proxy.cc index a32000061a3..e334396ea7c 100644 --- a/test/core/end2end/fixtures/h2_proxy.cc +++ b/test/core/end2end/fixtures/h2_proxy.cc @@ -124,7 +124,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc index eb71e24c772..4f393b22d05 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.cc +++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc @@ -140,7 +140,7 @@ int main(int argc, char** argv) { g_fixture_slowdown_factor = 10; #endif - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_sockpair.cc b/test/core/end2end/fixtures/h2_sockpair.cc index 904bda54586..1627fe0eb49 100644 --- a/test/core/end2end/fixtures/h2_sockpair.cc +++ b/test/core/end2end/fixtures/h2_sockpair.cc @@ -126,7 +126,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.cc b/test/core/end2end/fixtures/h2_sockpair_1byte.cc index 45f7f254ac5..8f1024b774d 100644 --- a/test/core/end2end/fixtures/h2_sockpair_1byte.cc +++ b/test/core/end2end/fixtures/h2_sockpair_1byte.cc @@ -140,7 +140,7 @@ int main(int argc, char** argv) { g_fixture_slowdown_factor = 2; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc index 4d6c8157164..1fcd785e251 100644 --- a/test/core/end2end/fixtures/h2_ssl.cc +++ b/test/core/end2end/fixtures/h2_ssl.cc @@ -158,7 +158,7 @@ int main(int argc, char** argv) { size_t roots_size = strlen(test_root_cert); char* roots_filename; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); /* Set the SSL roots env var. */ diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc index 09cbf974b61..f1858079426 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.cc +++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc @@ -199,7 +199,7 @@ int main(int argc, char** argv) { size_t roots_size = strlen(test_root_cert); char* roots_filename; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); /* Set the SSL roots env var. */ diff --git a/test/core/end2end/fixtures/h2_uds.cc b/test/core/end2end/fixtures/h2_uds.cc index 2c81c3d3622..f251bbd28c5 100644 --- a/test/core/end2end/fixtures/h2_uds.cc +++ b/test/core/end2end/fixtures/h2_uds.cc @@ -102,7 +102,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/inproc.cc b/test/core/end2end/fixtures/inproc.cc index be6eda84836..dadf3ef455d 100644 --- a/test/core/end2end/fixtures/inproc.cc +++ b/test/core/end2end/fixtures/inproc.cc @@ -83,7 +83,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 3f1c5596ad9..a8fbbde16b4 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -144,7 +144,7 @@ int main(int argc, char** argv) { grpc_op ops[6]; grpc_op* op; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); gpr_mu_init(&g_mu); grpc_init(); diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc index 2c5ee3b156e..cb0800bf899 100644 --- a/test/core/end2end/h2_ssl_cert_test.cc +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -358,7 +358,7 @@ int main(int argc, char** argv) { size_t roots_size = strlen(test_root_cert); char* roots_filename; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); /* Set the SSL roots env var. */ roots_file = gpr_tmpfile("chttp2_simple_ssl_cert_fullstack_test", &roots_filename); diff --git a/test/core/end2end/h2_ssl_session_reuse_test.cc b/test/core/end2end/h2_ssl_session_reuse_test.cc index b2f398625ab..fbcdcc4b3f3 100644 --- a/test/core/end2end/h2_ssl_session_reuse_test.cc +++ b/test/core/end2end/h2_ssl_session_reuse_test.cc @@ -258,7 +258,7 @@ int main(int argc, char** argv) { size_t roots_size = strlen(test_root_cert); char* roots_filename; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); /* Set the SSL roots env var. */ roots_file = gpr_tmpfile("chttp2_ssl_session_reuse_test", &roots_filename); GPR_ASSERT(roots_filename != nullptr); diff --git a/test/core/end2end/inproc_callback_test.cc b/test/core/end2end/inproc_callback_test.cc index 310030046af..72ad992d54c 100644 --- a/test/core/end2end/inproc_callback_test.cc +++ b/test/core/end2end/inproc_callback_test.cc @@ -495,7 +495,7 @@ static grpc_end2end_test_config configs[] = { }; int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); simple_request_pre_init(); diff --git a/test/core/end2end/invalid_call_argument_test.cc b/test/core/end2end/invalid_call_argument_test.cc index 6cb2e3ee806..bd28d192984 100644 --- a/test/core/end2end/invalid_call_argument_test.cc +++ b/test/core/end2end/invalid_call_argument_test.cc @@ -609,7 +609,7 @@ static void test_invalid_initial_metadata_reserved_key() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_invalid_initial_metadata_reserved_key(); test_non_null_reserved_on_start_batch(); diff --git a/test/core/end2end/multiple_server_queues_test.cc b/test/core/end2end/multiple_server_queues_test.cc index dfa3b48b52d..5ae828c1e39 100644 --- a/test/core/end2end/multiple_server_queues_test.cc +++ b/test/core/end2end/multiple_server_queues_test.cc @@ -27,7 +27,7 @@ int main(int argc, char** argv) { grpc_server* server; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); attr.version = 1; diff --git a/test/core/end2end/no_server_test.cc b/test/core/end2end/no_server_test.cc index e8ce4032e0f..5dda748f5a5 100644 --- a/test/core/end2end/no_server_test.cc +++ b/test/core/end2end/no_server_test.cc @@ -107,7 +107,7 @@ void run_test(bool wait_for_ready) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); run_test(true /* wait_for_ready */); run_test(false /* wait_for_ready */); return 0; diff --git a/test/core/gpr/alloc_test.cc b/test/core/gpr/alloc_test.cc index 36cdc02ff22..0b110e2b77d 100644 --- a/test/core/gpr/alloc_test.cc +++ b/test/core/gpr/alloc_test.cc @@ -64,7 +64,7 @@ static void test_malloc_aligned() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_custom_allocs(); test_malloc_aligned(); return 0; diff --git a/test/core/gpr/arena_test.cc b/test/core/gpr/arena_test.cc index 3e7c9065915..de4bd9804eb 100644 --- a/test/core/gpr/arena_test.cc +++ b/test/core/gpr/arena_test.cc @@ -116,7 +116,7 @@ static void concurrent_test(void) { } int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_noop(); TEST(0_1, 0, 1); diff --git a/test/core/gpr/cpu_test.cc b/test/core/gpr/cpu_test.cc index 1052d40b421..dbaeb08c183 100644 --- a/test/core/gpr/cpu_test.cc +++ b/test/core/gpr/cpu_test.cc @@ -144,7 +144,7 @@ static void cpu_test(void) { } int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); cpu_test(); return 0; } diff --git a/test/core/gpr/env_test.cc b/test/core/gpr/env_test.cc index 3f4b4932394..a8206bd3cfd 100644 --- a/test/core/gpr/env_test.cc +++ b/test/core/gpr/env_test.cc @@ -43,7 +43,7 @@ static void test_setenv_getenv(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_setenv_getenv(); return 0; } diff --git a/test/core/gpr/host_port_test.cc b/test/core/gpr/host_port_test.cc index b5d88b2b011..b01bbf4b695 100644 --- a/test/core/gpr/host_port_test.cc +++ b/test/core/gpr/host_port_test.cc @@ -50,7 +50,7 @@ static void test_join_host_port_garbage(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_join_host_port(); test_join_host_port_garbage(); diff --git a/test/core/gpr/log_test.cc b/test/core/gpr/log_test.cc index 839ff0aef94..f96257738b2 100644 --- a/test/core/gpr/log_test.cc +++ b/test/core/gpr/log_test.cc @@ -53,7 +53,7 @@ static void test_should_not_log(gpr_log_func_args* args) { GPR_ASSERT(false); } gpr_log(SEVERITY, "hello %d %d %d", 1, 2, 3); int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); /* test logging at various verbosity levels */ gpr_log(GPR_DEBUG, "%s", "hello world"); gpr_log(GPR_INFO, "%s", "hello world"); diff --git a/test/core/gpr/mpscq_test.cc b/test/core/gpr/mpscq_test.cc index f51bdf8c502..c826ccb498b 100644 --- a/test/core/gpr/mpscq_test.cc +++ b/test/core/gpr/mpscq_test.cc @@ -182,7 +182,7 @@ static void test_mt_multipop(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_serial(); test_mt(); test_mt_multipop(); diff --git a/test/core/gpr/murmur_hash_test.cc b/test/core/gpr/murmur_hash_test.cc index 2d2fa72cfbc..fdc2cfa76b3 100644 --- a/test/core/gpr/murmur_hash_test.cc +++ b/test/core/gpr/murmur_hash_test.cc @@ -64,7 +64,7 @@ static void verification_test(hash_func hash, uint32_t expected) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); /* basic tests to verify that things don't crash */ gpr_murmur_hash3("", 0, 0); gpr_murmur_hash3("xyz", 3, 0); diff --git a/test/core/gpr/spinlock_test.cc b/test/core/gpr/spinlock_test.cc index 0ee72edb153..8bd9396da6e 100644 --- a/test/core/gpr/spinlock_test.cc +++ b/test/core/gpr/spinlock_test.cc @@ -149,7 +149,7 @@ static void inctry(void* v /*=m*/) { /* ------------------------------------------------- */ int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test("spinlock", &inc, 1, 1); test("spinlock try", &inctry, 1, 1); return 0; diff --git a/test/core/gpr/string_test.cc b/test/core/gpr/string_test.cc index 9f3b3124658..7da7b18778b 100644 --- a/test/core/gpr/string_test.cc +++ b/test/core/gpr/string_test.cc @@ -295,7 +295,7 @@ static void test_is_true(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_strdup(); test_dump(); test_parse_uint32(); diff --git a/test/core/gpr/sync_test.cc b/test/core/gpr/sync_test.cc index 24b4562819f..fc7216e3601 100644 --- a/test/core/gpr/sync_test.cc +++ b/test/core/gpr/sync_test.cc @@ -458,7 +458,7 @@ static void refcheck(void* v /*=m*/) { /* ------------------------------------------------- */ int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test("mutex", &inc, nullptr, 1, 1); test("mutex try", &inctry, nullptr, 1, 1); test("cv", &inc_by_turns, nullptr, 1, 1); diff --git a/test/core/gpr/time_test.cc b/test/core/gpr/time_test.cc index 6f070f58df1..a32cbfb09aa 100644 --- a/test/core/gpr/time_test.cc +++ b/test/core/gpr/time_test.cc @@ -254,7 +254,7 @@ static void test_cmp_extreme(void) { } int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_values(); test_add_sub(); diff --git a/test/core/gpr/tls_test.cc b/test/core/gpr/tls_test.cc index 0502fc7ef4d..d1bed0aafe3 100644 --- a/test/core/gpr/tls_test.cc +++ b/test/core/gpr/tls_test.cc @@ -50,7 +50,7 @@ static void thd_body(void* arg) { int main(int argc, char* argv[]) { grpc_core::Thread threads[NUM_THREADS]; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); gpr_tls_init(&test_var); diff --git a/test/core/gpr/useful_test.cc b/test/core/gpr/useful_test.cc index 619c800c4d9..4f8582ab415 100644 --- a/test/core/gpr/useful_test.cc +++ b/test/core/gpr/useful_test.cc @@ -26,7 +26,7 @@ int main(int argc, char** argv) { int four[4]; int five[5]; uint32_t bitset = 0; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); GPR_ASSERT(GPR_MIN(1, 2) == 1); GPR_ASSERT(GPR_MAX(1, 2) == 2); diff --git a/test/core/gprpp/fork_test.cc b/test/core/gprpp/fork_test.cc index 642f910489c..0f56eead49d 100644 --- a/test/core/gprpp/fork_test.cc +++ b/test/core/gprpp/fork_test.cc @@ -130,7 +130,7 @@ static void test_exec_count() { } int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_init(); test_thd_count(); test_exec_count(); diff --git a/test/core/gprpp/inlined_vector_test.cc b/test/core/gprpp/inlined_vector_test.cc index 6abd2e7dfaf..f943128f53c 100644 --- a/test/core/gprpp/inlined_vector_test.cc +++ b/test/core/gprpp/inlined_vector_test.cc @@ -454,7 +454,7 @@ TEST(InlinedVectorTest, PopBackAllocated) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/gprpp/manual_constructor_test.cc b/test/core/gprpp/manual_constructor_test.cc index af162ae8e8a..a5a45133d86 100644 --- a/test/core/gprpp/manual_constructor_test.cc +++ b/test/core/gprpp/manual_constructor_test.cc @@ -92,7 +92,7 @@ static void complex_test() { /* ------------------------------------------------- */ int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); basic_test(); complex_test(); return 0; diff --git a/test/core/gprpp/memory_test.cc b/test/core/gprpp/memory_test.cc index 180c36fad7f..bb6a219a848 100644 --- a/test/core/gprpp/memory_test.cc +++ b/test/core/gprpp/memory_test.cc @@ -68,7 +68,7 @@ TEST(MemoryTest, UniquePtrWithCustomDeleter) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/gprpp/orphanable_test.cc b/test/core/gprpp/orphanable_test.cc index ad6b9ac8674..546f395cef6 100644 --- a/test/core/gprpp/orphanable_test.cc +++ b/test/core/gprpp/orphanable_test.cc @@ -114,7 +114,7 @@ TEST(OrphanablePtr, InternallyRefCountedWithTracing) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/gprpp/ref_counted_ptr_test.cc b/test/core/gprpp/ref_counted_ptr_test.cc index 463b5e89667..512687eb679 100644 --- a/test/core/gprpp/ref_counted_ptr_test.cc +++ b/test/core/gprpp/ref_counted_ptr_test.cc @@ -241,7 +241,7 @@ TEST(RefCountedPtr, CanPassSubclassToFunctionExpectingSubclass) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/gprpp/ref_counted_test.cc b/test/core/gprpp/ref_counted_test.cc index 62a3ea4d53e..5aba1634efb 100644 --- a/test/core/gprpp/ref_counted_test.cc +++ b/test/core/gprpp/ref_counted_test.cc @@ -116,7 +116,7 @@ TEST(RefCountedNonPolymorphicWithTracing, Basic) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/gprpp/thd_test.cc b/test/core/gprpp/thd_test.cc index 82dd681049b..06aa58984b0 100644 --- a/test/core/gprpp/thd_test.cc +++ b/test/core/gprpp/thd_test.cc @@ -92,7 +92,7 @@ static void test2(void) { /* ------------------------------------------------- */ int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test1(); test2(); return 0; diff --git a/test/core/http/format_request_test.cc b/test/core/http/format_request_test.cc index 353e138b2a1..b0a90c4613b 100644 --- a/test/core/http/format_request_test.cc +++ b/test/core/http/format_request_test.cc @@ -138,7 +138,7 @@ static void test_format_post_request_content_type_override(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_format_get_request(); diff --git a/test/core/http/httpcli_test.cc b/test/core/http/httpcli_test.cc index a51a0a5f6d7..bfd75f86491 100644 --- a/test/core/http/httpcli_test.cc +++ b/test/core/http/httpcli_test.cc @@ -145,7 +145,7 @@ static void destroy_pops(void* p, grpc_error* error) { int main(int argc, char** argv) { gpr_subprocess* server; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_closure destroyed; diff --git a/test/core/http/httpscli_test.cc b/test/core/http/httpscli_test.cc index 3fecf2b08bb..326b0e95e25 100644 --- a/test/core/http/httpscli_test.cc +++ b/test/core/http/httpscli_test.cc @@ -201,7 +201,7 @@ int main(int argc, char** argv) { gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(5, GPR_TIMESPAN))); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); grpc_httpcli_context_init(&g_context); grpc_pollset* pollset = diff --git a/test/core/http/parser_test.cc b/test/core/http/parser_test.cc index fe824f57fce..d105b40bcd6 100644 --- a/test/core/http/parser_test.cc +++ b/test/core/http/parser_test.cc @@ -218,7 +218,7 @@ int main(int argc, char** argv) { GRPC_SLICE_SPLIT_ONE_BYTE}; char *tmp1, *tmp2; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); for (i = 0; i < GPR_ARRAY_SIZE(split_modes); i++) { diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc index e104e8e91a0..eca8f76e673 100644 --- a/test/core/iomgr/buffer_list_test.cc +++ b/test/core/iomgr/buffer_list_test.cc @@ -97,7 +97,7 @@ static void TestTcpBufferList() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); TestTcpBufferList(); grpc_shutdown(); diff --git a/test/core/iomgr/combiner_test.cc b/test/core/iomgr/combiner_test.cc index cf2c7db8462..c39c3fc8fce 100644 --- a/test/core/iomgr/combiner_test.cc +++ b/test/core/iomgr/combiner_test.cc @@ -144,7 +144,7 @@ static void test_execute_finally(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_no_op(); test_execute_one(); diff --git a/test/core/iomgr/endpoint_pair_test.cc b/test/core/iomgr/endpoint_pair_test.cc index ad38076b516..3ddbe7f2fc0 100644 --- a/test/core/iomgr/endpoint_pair_test.cc +++ b/test/core/iomgr/endpoint_pair_test.cc @@ -60,7 +60,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/error_test.cc b/test/core/iomgr/error_test.cc index d78a8c2af39..3ba90147aad 100644 --- a/test/core/iomgr/error_test.cc +++ b/test/core/iomgr/error_test.cc @@ -215,7 +215,7 @@ static void test_overflow() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_set_get_int(); test_set_get_str(); diff --git a/test/core/iomgr/ev_epollex_linux_test.cc b/test/core/iomgr/ev_epollex_linux_test.cc index 08d1e68b398..faa3ef344a1 100644 --- a/test/core/iomgr/ev_epollex_linux_test.cc +++ b/test/core/iomgr/ev_epollex_linux_test.cc @@ -92,7 +92,7 @@ static void test_pollable_owner_fd() { int main(int argc, char** argv) { const char* poll_strategy = nullptr; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/fd_conservation_posix_test.cc b/test/core/iomgr/fd_conservation_posix_test.cc index 4866e350d53..0d27b94dc2d 100644 --- a/test/core/iomgr/fd_conservation_posix_test.cc +++ b/test/core/iomgr/fd_conservation_posix_test.cc @@ -29,7 +29,7 @@ int main(int argc, char** argv) { struct rlimit rlim; grpc_endpoint_pair p; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/fd_posix_test.cc b/test/core/iomgr/fd_posix_test.cc index 4ea2389bbd8..cf5ffc63543 100644 --- a/test/core/iomgr/fd_posix_test.cc +++ b/test/core/iomgr/fd_posix_test.cc @@ -515,7 +515,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/grpc_ipv6_loopback_available_test.cc b/test/core/iomgr/grpc_ipv6_loopback_available_test.cc index 329aa9a8517..2ef1f1978d6 100644 --- a/test/core/iomgr/grpc_ipv6_loopback_available_test.cc +++ b/test/core/iomgr/grpc_ipv6_loopback_available_test.cc @@ -32,7 +32,7 @@ #endif int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); // This test assumes that the ipv6 loopback is available // in all environments in which grpc tests run in. diff --git a/test/core/iomgr/load_file_test.cc b/test/core/iomgr/load_file_test.cc index 38c8710535b..a0e0e4d7a74 100644 --- a/test/core/iomgr/load_file_test.cc +++ b/test/core/iomgr/load_file_test.cc @@ -152,7 +152,7 @@ static void test_load_big_file(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_load_empty_file(); test_load_failure(); diff --git a/test/core/iomgr/resolve_address_posix_test.cc b/test/core/iomgr/resolve_address_posix_test.cc index e495e4c8770..ceeb70a1086 100644 --- a/test/core/iomgr/resolve_address_posix_test.cc +++ b/test/core/iomgr/resolve_address_posix_test.cc @@ -158,7 +158,7 @@ static void test_unix_socket_path_name_too_long(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index 8d69bab5b12..1d9e1ee27e2 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -271,7 +271,7 @@ int main(int argc, char** argv) { abort(); } // Run the test. - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/resource_quota_test.cc b/test/core/iomgr/resource_quota_test.cc index f3b35fed327..4cbc016d587 100644 --- a/test/core/iomgr/resource_quota_test.cc +++ b/test/core/iomgr/resource_quota_test.cc @@ -891,7 +891,7 @@ static void test_thread_maxquota_change() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); gpr_mu_init(&g_mu); gpr_cv_init(&g_cv); diff --git a/test/core/iomgr/sockaddr_utils_test.cc b/test/core/iomgr/sockaddr_utils_test.cc index 3783f968b7d..250d36a74a6 100644 --- a/test/core/iomgr/sockaddr_utils_test.cc +++ b/test/core/iomgr/sockaddr_utils_test.cc @@ -270,7 +270,7 @@ static void test_sockaddr_set_get_port(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_sockaddr_is_v4mapped(); test_sockaddr_to_v4mapped(); diff --git a/test/core/iomgr/socket_utils_test.cc b/test/core/iomgr/socket_utils_test.cc index a21f3fac62e..420873734de 100644 --- a/test/core/iomgr/socket_utils_test.cc +++ b/test/core/iomgr/socket_utils_test.cc @@ -80,7 +80,7 @@ static const grpc_socket_mutator_vtable mutator_vtable = { int main(int argc, char** argv) { int sock; grpc_error* err; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); sock = socket(PF_INET, SOCK_STREAM, 0); GPR_ASSERT(sock > 0); diff --git a/test/core/iomgr/tcp_client_posix_test.cc b/test/core/iomgr/tcp_client_posix_test.cc index 90fc5aecfc6..5cf3530c77a 100644 --- a/test/core/iomgr/tcp_client_posix_test.cc +++ b/test/core/iomgr/tcp_client_posix_test.cc @@ -191,7 +191,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { diff --git a/test/core/iomgr/tcp_client_uv_test.cc b/test/core/iomgr/tcp_client_uv_test.cc index 27f894e3f3c..bde8c2f3539 100644 --- a/test/core/iomgr/tcp_client_uv_test.cc +++ b/test/core/iomgr/tcp_client_uv_test.cc @@ -188,7 +188,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/tcp_posix_test.cc b/test/core/iomgr/tcp_posix_test.cc index 6447cc234db..80f17a914fa 100644 --- a/test/core/iomgr/tcp_posix_test.cc +++ b/test/core/iomgr/tcp_posix_test.cc @@ -623,7 +623,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); grpc_core::grpc_tcp_set_write_timestamps_callback(timestamps_verifier); { diff --git a/test/core/iomgr/tcp_server_posix_test.cc b/test/core/iomgr/tcp_server_posix_test.cc index d646df1daef..2c66cdec77f 100644 --- a/test/core/iomgr/tcp_server_posix_test.cc +++ b/test/core/iomgr/tcp_server_posix_test.cc @@ -437,7 +437,7 @@ int main(int argc, char** argv) { // Zalloc dst_addrs to avoid oversized frames. test_addrs* dst_addrs = static_cast(gpr_zalloc(sizeof(*dst_addrs))); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/tcp_server_uv_test.cc b/test/core/iomgr/tcp_server_uv_test.cc index e99fa79bfd8..625a18c0cc7 100644 --- a/test/core/iomgr/tcp_server_uv_test.cc +++ b/test/core/iomgr/tcp_server_uv_test.cc @@ -288,7 +288,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/time_averaged_stats_test.cc b/test/core/iomgr/time_averaged_stats_test.cc index b932e62d1f6..2923a35d1b6 100644 --- a/test/core/iomgr/time_averaged_stats_test.cc +++ b/test/core/iomgr/time_averaged_stats_test.cc @@ -180,7 +180,7 @@ static void some_regress_some_persist_test(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); no_regress_no_persist_test_1(); no_regress_no_persist_test_2(); no_regress_no_persist_test_3(); diff --git a/test/core/iomgr/timer_heap_test.cc b/test/core/iomgr/timer_heap_test.cc index ebe5e6610d1..872cf17486f 100644 --- a/test/core/iomgr/timer_heap_test.cc +++ b/test/core/iomgr/timer_heap_test.cc @@ -286,7 +286,7 @@ static void shrink_test(void) { int main(int argc, char** argv) { int i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); for (i = 0; i < 5; i++) { test1(); diff --git a/test/core/iomgr/timer_list_test.cc b/test/core/iomgr/timer_list_test.cc index fd65d1abf1f..fa2444948b6 100644 --- a/test/core/iomgr/timer_list_test.cc +++ b/test/core/iomgr/timer_list_test.cc @@ -221,7 +221,7 @@ void long_running_service_cleanup_test(void) { int main(int argc, char** argv) { /* Tests with default g_start_time */ { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_core::ExecCtx::GlobalInit(); grpc_core::ExecCtx exec_ctx; grpc_determine_iomgr_platform(); @@ -235,7 +235,7 @@ int main(int argc, char** argv) { /* Begin long running service tests */ { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); /* Set g_start_time back 25 days. */ /* We set g_start_time here in case there are any initialization dependencies that use g_start_time. */ diff --git a/test/core/iomgr/udp_server_test.cc b/test/core/iomgr/udp_server_test.cc index d167c0131f3..f65783a0174 100644 --- a/test/core/iomgr/udp_server_test.cc +++ b/test/core/iomgr/udp_server_test.cc @@ -360,7 +360,7 @@ static void test_receive(int number_of_clients) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); if (grpc_is_socket_reuse_port_supported()) { g_num_listeners = 10; diff --git a/test/core/json/json_rewrite_test.cc b/test/core/json/json_rewrite_test.cc index 2fade12e13f..b7e89cdb1a3 100644 --- a/test/core/json/json_rewrite_test.cc +++ b/test/core/json/json_rewrite_test.cc @@ -287,7 +287,7 @@ void test_rewrites() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_rewrites(); gpr_log(GPR_INFO, "json_rewrite_test success"); return 0; diff --git a/test/core/json/json_stream_error_test.cc b/test/core/json/json_stream_error_test.cc index 00288d6d5ea..53e20be2069 100644 --- a/test/core/json/json_stream_error_test.cc +++ b/test/core/json/json_stream_error_test.cc @@ -49,7 +49,7 @@ static void read_error() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); read_error(); gpr_log(GPR_INFO, "json_stream_error success"); return 0; diff --git a/test/core/json/json_test.cc b/test/core/json/json_test.cc index 7f1dbb774a6..03dd96a8ae1 100644 --- a/test/core/json/json_test.cc +++ b/test/core/json/json_test.cc @@ -184,7 +184,7 @@ static void test_atypical() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_pairs(); test_atypical(); gpr_log(GPR_INFO, "json_test success"); diff --git a/test/core/security/auth_context_test.cc b/test/core/security/auth_context_test.cc index 58f0d8e1c27..9a39afb8006 100644 --- a/test/core/security/auth_context_test.cc +++ b/test/core/security/auth_context_test.cc @@ -130,7 +130,7 @@ static void test_chained_context(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_empty_context(); test_simple_context(); test_chained_context(); diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index 56c4c9c0ae1..b3e3c3c7415 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -1206,7 +1206,7 @@ static void test_auth_metadata_context(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_empty_md_array(); test_add_to_empty_md_array(); diff --git a/test/core/security/json_token_test.cc b/test/core/security/json_token_test.cc index 7a5b3355fec..a3ae18e6abd 100644 --- a/test/core/security/json_token_test.cc +++ b/test/core/security/json_token_test.cc @@ -482,7 +482,7 @@ static void test_parse_refresh_token_failure_no_refresh_token(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_parse_json_key_success(); test_parse_json_key_failure_bad_json(); diff --git a/test/core/security/jwt_verifier_test.cc b/test/core/security/jwt_verifier_test.cc index 9718580a08d..70155cdd065 100644 --- a/test/core/security/jwt_verifier_test.cc +++ b/test/core/security/jwt_verifier_test.cc @@ -600,7 +600,7 @@ static void test_jwt_verifier_bad_format(void) { /* bad key */ int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_jwt_issuer_email_domain(); test_claims_success(); diff --git a/test/core/security/linux_system_roots_test.cc b/test/core/security/linux_system_roots_test.cc index 24d446de359..cd8bd3beb77 100644 --- a/test/core/security/linux_system_roots_test.cc +++ b/test/core/security/linux_system_roots_test.cc @@ -86,7 +86,7 @@ TEST(CreateRootCertsBundleTest, BundlesCorrectly) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/security/secure_endpoint_test.cc b/test/core/security/secure_endpoint_test.cc index 23cef99dfa8..f6d02895b5f 100644 --- a/test/core/security/secure_endpoint_test.cc +++ b/test/core/security/secure_endpoint_test.cc @@ -208,7 +208,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index fef0ea71f7d..e82a8627d40 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -430,7 +430,7 @@ static void test_default_ssl_roots(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_unauthenticated_ssl_peer(); diff --git a/test/core/security/ssl_credentials_test.cc b/test/core/security/ssl_credentials_test.cc index 9edcf42d3a4..7c9f5616654 100644 --- a/test/core/security/ssl_credentials_test.cc +++ b/test/core/security/ssl_credentials_test.cc @@ -56,7 +56,7 @@ static void test_convert_grpc_to_tsi_cert_pairs() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_convert_grpc_to_tsi_cert_pairs(); diff --git a/test/core/slice/b64_test.cc b/test/core/slice/b64_test.cc index 6b29443ba10..6677150c231 100644 --- a/test/core/slice/b64_test.cc +++ b/test/core/slice/b64_test.cc @@ -201,7 +201,7 @@ static void test_unpadded_decode(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_simple_encode_decode_b64_no_multiline(); test_simple_encode_decode_b64_multiline(); diff --git a/test/core/slice/percent_encoding_test.cc b/test/core/slice/percent_encoding_test.cc index e8d04fcc83c..ae6c39eb266 100644 --- a/test/core/slice/percent_encoding_test.cc +++ b/test/core/slice/percent_encoding_test.cc @@ -118,7 +118,7 @@ static void test_nonconformant_vector(const char* encoded, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); TEST_VECTOR( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~", diff --git a/test/core/slice/slice_buffer_test.cc b/test/core/slice/slice_buffer_test.cc index e59986730b8..b53e3312df1 100644 --- a/test/core/slice/slice_buffer_test.cc +++ b/test/core/slice/slice_buffer_test.cc @@ -106,7 +106,7 @@ void test_slice_buffer_move_first() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_slice_buffer_add(); diff --git a/test/core/slice/slice_hash_table_test.cc b/test/core/slice/slice_hash_table_test.cc index 43ddfe9bf2c..08cfe91e5a1 100644 --- a/test/core/slice/slice_hash_table_test.cc +++ b/test/core/slice/slice_hash_table_test.cc @@ -217,7 +217,7 @@ TEST(SliceHashTable, CmpEmptyKeysDifferentValue) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_core::ExecCtx::GlobalInit(); int result = RUN_ALL_TESTS(); grpc_core::ExecCtx::GlobalShutdown(); diff --git a/test/core/slice/slice_string_helpers_test.cc b/test/core/slice/slice_string_helpers_test.cc index 860a1bfe034..1bbc0947bc6 100644 --- a/test/core/slice/slice_string_helpers_test.cc +++ b/test/core/slice/slice_string_helpers_test.cc @@ -195,7 +195,7 @@ static void test_strsplit_nospace(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_dump_slice(); test_strsplit(); test_strsplit_nospace(); diff --git a/test/core/slice/slice_test.cc b/test/core/slice/slice_test.cc index e683c41f312..1e53a1951c4 100644 --- a/test/core/slice/slice_test.cc +++ b/test/core/slice/slice_test.cc @@ -294,7 +294,7 @@ static void test_static_slice_copy_interning(void) { int main(int argc, char** argv) { unsigned length; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_slice_malloc_returns_something_sensible(); test_slice_new_returns_something_sensible(); diff --git a/test/core/slice/slice_weak_hash_table_test.cc b/test/core/slice/slice_weak_hash_table_test.cc index b0a243d572e..ab0a648727d 100644 --- a/test/core/slice/slice_weak_hash_table_test.cc +++ b/test/core/slice/slice_weak_hash_table_test.cc @@ -98,7 +98,7 @@ TEST(SliceWeakHashTable, ForceOverload) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_core::ExecCtx::GlobalInit(); int result = RUN_ALL_TESTS(); grpc_core::ExecCtx::GlobalShutdown(); diff --git a/test/core/surface/byte_buffer_reader_test.cc b/test/core/surface/byte_buffer_reader_test.cc index cff05caec14..301a1e283ba 100644 --- a/test/core/surface/byte_buffer_reader_test.cc +++ b/test/core/surface/byte_buffer_reader_test.cc @@ -267,7 +267,7 @@ static void test_byte_buffer_copy(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_read_one_slice(); test_read_one_slice_malloc(); test_read_none_compressed_slice(); diff --git a/test/core/surface/channel_create_test.cc b/test/core/surface/channel_create_test.cc index 56f4f602e87..5f109c0f840 100644 --- a/test/core/surface/channel_create_test.cc +++ b/test/core/surface/channel_create_test.cc @@ -44,7 +44,7 @@ void test_unknown_scheme_target(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_unknown_scheme_target(); grpc_shutdown(); diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc index f7ce8a7042e..a157d75edab 100644 --- a/test/core/surface/completion_queue_test.cc +++ b/test/core/surface/completion_queue_test.cc @@ -440,7 +440,7 @@ struct thread_state { }; int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_no_op(); test_pollset_conversion(); diff --git a/test/core/surface/completion_queue_threading_test.cc b/test/core/surface/completion_queue_threading_test.cc index 0b82803af6f..4215aad14af 100644 --- a/test/core/surface/completion_queue_threading_test.cc +++ b/test/core/surface/completion_queue_threading_test.cc @@ -288,7 +288,7 @@ static void test_threading(size_t producers, size_t consumers) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_too_many_plucks(); test_threading(1, 1); diff --git a/test/core/surface/concurrent_connectivity_test.cc b/test/core/surface/concurrent_connectivity_test.cc index fbc5ec4c541..f606e89ac8d 100644 --- a/test/core/surface/concurrent_connectivity_test.cc +++ b/test/core/surface/concurrent_connectivity_test.cc @@ -300,7 +300,7 @@ int run_concurrent_watches_with_short_timeouts_test() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); run_concurrent_connectivity_test(); run_concurrent_watches_with_short_timeouts_test(); diff --git a/test/core/surface/init_test.cc b/test/core/surface/init_test.cc index 5749bc8b36d..1bcd13a0b89 100644 --- a/test/core/surface/init_test.cc +++ b/test/core/surface/init_test.cc @@ -60,7 +60,7 @@ static void test_repeatedly() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test(1); test(2); test(3); diff --git a/test/core/surface/lame_client_test.cc b/test/core/surface/lame_client_test.cc index fac5ca8f7f6..09c3d431977 100644 --- a/test/core/surface/lame_client_test.cc +++ b/test/core/surface/lame_client_test.cc @@ -75,7 +75,7 @@ int main(int argc, char** argv) { grpc_slice details; char* peer; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); grpc_metadata_array_init(&initial_metadata_recv); diff --git a/test/core/surface/num_external_connectivity_watchers_test.cc b/test/core/surface/num_external_connectivity_watchers_test.cc index 7b7a0b6dfc0..454cbd5747e 100644 --- a/test/core/surface/num_external_connectivity_watchers_test.cc +++ b/test/core/surface/num_external_connectivity_watchers_test.cc @@ -191,7 +191,7 @@ static const test_fixture secure_test = { }; int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); run_timeouts_test(&insecure_test); run_timeouts_test(&secure_test); diff --git a/test/core/surface/secure_channel_create_test.cc b/test/core/surface/secure_channel_create_test.cc index 06962179a23..5610d1ec4ab 100644 --- a/test/core/surface/secure_channel_create_test.cc +++ b/test/core/surface/secure_channel_create_test.cc @@ -70,7 +70,7 @@ void test_null_creds(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_security_connector_already_in_arg(); test_null_creds(); diff --git a/test/core/surface/sequential_connectivity_test.cc b/test/core/surface/sequential_connectivity_test.cc index 10562b3be9c..3f9a7baf98b 100644 --- a/test/core/surface/sequential_connectivity_test.cc +++ b/test/core/surface/sequential_connectivity_test.cc @@ -168,7 +168,7 @@ static const test_fixture secure_test = { }; int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); run_test(&insecure_test); run_test(&secure_test); diff --git a/test/core/surface/server_chttp2_test.cc b/test/core/surface/server_chttp2_test.cc index fd8ab9cd3d5..ffb7f14f987 100644 --- a/test/core/surface/server_chttp2_test.cc +++ b/test/core/surface/server_chttp2_test.cc @@ -67,7 +67,7 @@ void test_add_same_port_twice() { #endif int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_unparsable_target(); #ifndef GRPC_UV diff --git a/test/core/surface/server_test.cc b/test/core/surface/server_test.cc index b4eabd8d4d8..2fc166546b0 100644 --- a/test/core/surface/server_test.cc +++ b/test/core/surface/server_test.cc @@ -148,7 +148,7 @@ static void test_bind_server_to_addrs(const char** addrs, size_t n) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_register_method_fail(); test_request_call_on_no_server_cq(); diff --git a/test/core/transport/bdp_estimator_test.cc b/test/core/transport/bdp_estimator_test.cc index c7e6b2bd841..a795daaead7 100644 --- a/test/core/transport/bdp_estimator_test.cc +++ b/test/core/transport/bdp_estimator_test.cc @@ -139,7 +139,7 @@ INSTANTIATE_TEST_CASE_P(TooManyNames, BdpEstimatorRandomTest, } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); gpr_now_impl = grpc_core::testing::fake_gpr_now; grpc_init(); grpc_timer_manager_set_threading(false); diff --git a/test/core/transport/byte_stream_test.cc b/test/core/transport/byte_stream_test.cc index df096372498..6c543892d0a 100644 --- a/test/core/transport/byte_stream_test.cc +++ b/test/core/transport/byte_stream_test.cc @@ -245,7 +245,7 @@ TEST(CachingByteStream, SharedCache) { int main(int argc, char** argv) { grpc_init(); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); int retval = RUN_ALL_TESTS(); grpc_shutdown(); diff --git a/test/core/transport/chttp2/alpn_test.cc b/test/core/transport/chttp2/alpn_test.cc index a43377393e1..6da5299363b 100644 --- a/test/core/transport/chttp2/alpn_test.cc +++ b/test/core/transport/chttp2/alpn_test.cc @@ -49,7 +49,7 @@ static void test_alpn_grpc_before_h2(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_alpn_success(); test_alpn_failure(); test_alpn_grpc_before_h2(); diff --git a/test/core/transport/chttp2/context_list_test.cc b/test/core/transport/chttp2/context_list_test.cc index e64f1532ecd..edbe658a89f 100644 --- a/test/core/transport/chttp2/context_list_test.cc +++ b/test/core/transport/chttp2/context_list_test.cc @@ -95,7 +95,7 @@ TEST(ContextList, ExecuteFlushesList) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/core/transport/chttp2/hpack_encoder_test.cc b/test/core/transport/chttp2/hpack_encoder_test.cc index ab819f90923..6cbc914c7fa 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.cc +++ b/test/core/transport/chttp2/hpack_encoder_test.cc @@ -261,7 +261,7 @@ static void run_test(void (*test)(), const char* name) { int main(int argc, char** argv) { size_t i; grpc_test_only_set_slice_hash_seed(0); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); TEST(test_basic_headers); TEST(test_decode_table_overflow); diff --git a/test/core/transport/chttp2/hpack_parser_test.cc b/test/core/transport/chttp2/hpack_parser_test.cc index 43b6c79e8a9..882ad726b5a 100644 --- a/test/core/transport/chttp2/hpack_parser_test.cc +++ b/test/core/transport/chttp2/hpack_parser_test.cc @@ -208,7 +208,7 @@ static void test_vectors(grpc_slice_split_mode mode) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_vectors(GRPC_SLICE_SPLIT_MERGE_ALL); test_vectors(GRPC_SLICE_SPLIT_ONE_BYTE); diff --git a/test/core/transport/chttp2/hpack_table_test.cc b/test/core/transport/chttp2/hpack_table_test.cc index 3ab463b6312..c31975786f0 100644 --- a/test/core/transport/chttp2/hpack_table_test.cc +++ b/test/core/transport/chttp2/hpack_table_test.cc @@ -268,7 +268,7 @@ static void test_find(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_static_lookup(); test_many_additions(); diff --git a/test/core/transport/chttp2/settings_timeout_test.cc b/test/core/transport/chttp2/settings_timeout_test.cc index 2d6f0a9a629..a9789edbf2b 100644 --- a/test/core/transport/chttp2/settings_timeout_test.cc +++ b/test/core/transport/chttp2/settings_timeout_test.cc @@ -248,7 +248,7 @@ TEST(SettingsTimeout, Basic) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); int result = RUN_ALL_TESTS(); grpc_shutdown(); diff --git a/test/core/transport/chttp2/stream_map_test.cc b/test/core/transport/chttp2/stream_map_test.cc index 773eb3a35f6..a36c496eb1e 100644 --- a/test/core/transport/chttp2/stream_map_test.cc +++ b/test/core/transport/chttp2/stream_map_test.cc @@ -193,7 +193,7 @@ int main(int argc, char** argv) { uint32_t prev = 1; uint32_t tmp; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_no_op(); test_empty_find(); diff --git a/test/core/transport/chttp2/varint_test.cc b/test/core/transport/chttp2/varint_test.cc index 36760d0c723..5e00cc376af 100644 --- a/test/core/transport/chttp2/varint_test.cc +++ b/test/core/transport/chttp2/varint_test.cc @@ -44,7 +44,7 @@ static void test_varint(uint32_t value, uint32_t prefix_bits, uint8_t prefix_or, test_varint(value, prefix_bits, prefix_or, expect, sizeof(expect) - 1) int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); TEST_VARINT(0, 1, 0, "\x00"); TEST_VARINT(128, 1, 0, "\x7f\x01"); diff --git a/test/core/transport/connectivity_state_test.cc b/test/core/transport/connectivity_state_test.cc index cbd6318f528..7c7e3084bf5 100644 --- a/test/core/transport/connectivity_state_test.cc +++ b/test/core/transport/connectivity_state_test.cc @@ -134,7 +134,7 @@ static void test_subscribe_with_failure_then_destroy(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); grpc_core::testing::grpc_tracer_enable_flag(&grpc_connectivity_state_trace); test_connectivity_state_name(); diff --git a/test/core/transport/metadata_test.cc b/test/core/transport/metadata_test.cc index 8ab9639dfa2..9a49d28ccce 100644 --- a/test/core/transport/metadata_test.cc +++ b/test/core/transport/metadata_test.cc @@ -370,7 +370,7 @@ static void test_copied_static_metadata(bool dup_key, bool dup_value) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_no_op(); for (int k = 0; k <= 1; k++) { diff --git a/test/core/transport/pid_controller_test.cc b/test/core/transport/pid_controller_test.cc index 8d2cec40421..f6235244f60 100644 --- a/test/core/transport/pid_controller_test.cc +++ b/test/core/transport/pid_controller_test.cc @@ -85,7 +85,7 @@ INSTANTIATE_TEST_CASE_P( } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/transport/status_conversion_test.cc b/test/core/transport/status_conversion_test.cc index f7b3c62a40d..949be42aeb4 100644 --- a/test/core/transport/status_conversion_test.cc +++ b/test/core/transport/status_conversion_test.cc @@ -163,7 +163,7 @@ static void test_http2_status_to_grpc_status() { int main(int argc, char** argv) { int i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_grpc_status_to_http2_error(); diff --git a/test/core/transport/stream_owned_slice_test.cc b/test/core/transport/stream_owned_slice_test.cc index 7831f67a048..48a77db9a50 100644 --- a/test/core/transport/stream_owned_slice_test.cc +++ b/test/core/transport/stream_owned_slice_test.cc @@ -26,7 +26,7 @@ static void do_nothing(void* arg, grpc_error* error) {} int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); uint8_t buffer[] = "abc123"; diff --git a/test/core/transport/timeout_encoding_test.cc b/test/core/transport/timeout_encoding_test.cc index b7044b5b410..22e68fe5540 100644 --- a/test/core/transport/timeout_encoding_test.cc +++ b/test/core/transport/timeout_encoding_test.cc @@ -156,7 +156,7 @@ void test_decoding_fails(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_encoding(); test_decoding(); test_decoding_fails(); diff --git a/test/core/tsi/fake_transport_security_test.cc b/test/core/tsi/fake_transport_security_test.cc index 587d8f5dda5..32361f19d3f 100644 --- a/test/core/tsi/fake_transport_security_test.cc +++ b/test/core/tsi/fake_transport_security_test.cc @@ -139,7 +139,7 @@ void fake_tsi_test_do_round_trip_odd_buffer_size() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); fake_tsi_test_do_handshake_tiny_handshake_buffer(); fake_tsi_test_do_handshake_small_handshake_buffer(); diff --git a/test/core/tsi/ssl_session_cache_test.cc b/test/core/tsi/ssl_session_cache_test.cc index c86cefb3ff4..b9c98c0b57c 100644 --- a/test/core/tsi/ssl_session_cache_test.cc +++ b/test/core/tsi/ssl_session_cache_test.cc @@ -145,7 +145,7 @@ TEST(SslSessionCacheTest, LruCache) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); int ret = RUN_ALL_TESTS(); grpc_shutdown(); diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index baffad6ea36..fc6c6ba3208 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() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); ssl_tsi_test_do_handshake_tiny_handshake_buffer(); diff --git a/test/core/tsi/transport_security_test.cc b/test/core/tsi/transport_security_test.cc index 5c92912f6f6..150e5745a8d 100644 --- a/test/core/tsi/transport_security_test.cc +++ b/test/core/tsi/transport_security_test.cc @@ -381,7 +381,7 @@ static void test_handshaker_invalid_state(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_peer_matches_name(); test_result_strings(); test_protector_invalid_args(); diff --git a/test/core/util/cmdline_test.cc b/test/core/util/cmdline_test.cc index 9f5ad88d573..59e1bbff34e 100644 --- a/test/core/util/cmdline_test.cc +++ b/test/core/util/cmdline_test.cc @@ -463,7 +463,7 @@ static void test_badargs4(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_simple_int(); test_eq_int(); test_2dash_int(); diff --git a/test/core/util/fuzzer_corpus_test.cc b/test/core/util/fuzzer_corpus_test.cc index ebf19131371..6e3785c4f74 100644 --- a/test/core/util/fuzzer_corpus_test.cc +++ b/test/core/util/fuzzer_corpus_test.cc @@ -144,7 +144,7 @@ INSTANTIATE_TEST_CASE_P( ::testing::internal::ParamGenerator(new ExampleGenerator)); int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ParseCommandLineFlags(&argc, &argv, true); ::testing::InitGoogleTest(&argc, argv); diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index 976eeb6aeab..bf321d8a89e 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -321,7 +321,7 @@ class ClientChannelStressTest { int main(int argc, char** argv) { grpc_init(); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc::testing::ClientChannelStressTest test; test.Run(); grpc_shutdown(); diff --git a/test/cpp/common/alarm_test.cc b/test/cpp/common/alarm_test.cc index e909d03658c..802cdc209a0 100644 --- a/test/cpp/common/alarm_test.cc +++ b/test/cpp/common/alarm_test.cc @@ -313,7 +313,7 @@ TEST(AlarmTest, UnsetDestruction) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 6ecb9578015..e09f54dcc3f 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -1884,7 +1884,7 @@ int main(int argc, char** argv) { // Change the backup poll interval from 5s to 100ms to speed up the // ReconnectChannel test gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "100"); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); return ret; diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index f04ffe4f2d5..29b59e4e5e1 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -677,7 +677,7 @@ TEST_F(ChannelzServerTest, GetServerListenSocketsTest) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index a35991396ad..b5bea66aca5 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -277,7 +277,7 @@ INSTANTIATE_TEST_CASE_P(ClientCallbackEnd2endTest, ClientCallbackEnd2endTest, } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/client_crash_test.cc b/test/cpp/end2end/client_crash_test.cc index 2a06f44c608..992f3c488f9 100644 --- a/test/cpp/end2end/client_crash_test.cc +++ b/test/cpp/end2end/client_crash_test.cc @@ -135,7 +135,7 @@ int main(int argc, char** argv) { g_root = "."; } - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); // Order seems to matter on these tests: run three times to eliminate that for (int i = 0; i < 3; i++) { diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 60e8b051ab8..3a191d1e038 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -639,7 +639,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 312065a2dfe..b667460cf08 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -1153,7 +1153,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); const auto result = RUN_ALL_TESTS(); return result; } diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 03291e1785c..e5f117ec561 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -1899,7 +1899,7 @@ INSTANTIATE_TEST_CASE_P(ResourceQuotaEnd2end, ResourceQuotaEnd2endTest, int main(int argc, char** argv) { gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "200"); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/exception_test.cc b/test/cpp/end2end/exception_test.cc index 5343997663e..0d2c00263b7 100644 --- a/test/cpp/end2end/exception_test.cc +++ b/test/cpp/end2end/exception_test.cc @@ -117,7 +117,7 @@ TEST_F(ExceptionTest, RequestStream) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index 88f8f380c3a..ad67402e3df 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -331,7 +331,7 @@ void RegisterFilter() { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); grpc::testing::RegisterFilter(); return RUN_ALL_TESTS(); diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index 88a1227ca2e..015862bfe81 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -333,7 +333,7 @@ TEST_F(GenericEnd2endTest, Deadline) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 5b304dc16b1..9c4cd050619 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -1518,7 +1518,7 @@ TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) { int main(int argc, char** argv) { grpc_init(); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); const auto result = RUN_ALL_TESTS(); grpc_shutdown(); diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index fca65dfc13b..89c4bef09cf 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -331,7 +331,7 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc index 339eadde92e..18bb1ff4b96 100644 --- a/test/cpp/end2end/hybrid_end2end_test.cc +++ b/test/cpp/end2end/hybrid_end2end_test.cc @@ -894,7 +894,7 @@ TEST_F(HybridEnd2endTest, GenericMethodWithoutGenericService) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc index ba3122c895f..917ca28020a 100644 --- a/test/cpp/end2end/mock_test.cc +++ b/test/cpp/end2end/mock_test.cc @@ -345,7 +345,7 @@ TEST_F(MockTest, BidiStream) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/nonblocking_test.cc b/test/cpp/end2end/nonblocking_test.cc index d8337baca22..36dea1fcb31 100644 --- a/test/cpp/end2end/nonblocking_test.cc +++ b/test/cpp/end2end/nonblocking_test.cc @@ -187,7 +187,7 @@ int main(int argc, char** argv) { grpc_poll_function = maybe_assert_non_blocking_poll; #endif // GRPC_POSIX_SOCKET - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); return ret; diff --git a/test/cpp/end2end/proto_server_reflection_test.cc b/test/cpp/end2end/proto_server_reflection_test.cc index 21a275ef62c..ff097aa9a77 100644 --- a/test/cpp/end2end/proto_server_reflection_test.cc +++ b/test/cpp/end2end/proto_server_reflection_test.cc @@ -144,7 +144,7 @@ TEST_F(ProtoServerReflectionTest, CheckResponseWithLocalDescriptorPool) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/raw_end2end_test.cc b/test/cpp/end2end/raw_end2end_test.cc index a413905ef7a..c8556bae954 100644 --- a/test/cpp/end2end/raw_end2end_test.cc +++ b/test/cpp/end2end/raw_end2end_test.cc @@ -363,7 +363,7 @@ TEST_F(RawEnd2EndTest, CompileTest) { int main(int argc, char** argv) { // Change the backup poll interval from 5s to 100ms to speed up the // ReconnectChannel test - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); return ret; diff --git a/test/cpp/end2end/server_builder_plugin_test.cc b/test/cpp/end2end/server_builder_plugin_test.cc index d54523fcbb1..d744a93912e 100644 --- a/test/cpp/end2end/server_builder_plugin_test.cc +++ b/test/cpp/end2end/server_builder_plugin_test.cc @@ -264,7 +264,7 @@ INSTANTIATE_TEST_CASE_P(ServerBuilderPluginTest, ServerBuilderPluginTest, } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/server_crash_test.cc b/test/cpp/end2end/server_crash_test.cc index 93257b2705c..353ebf713a0 100644 --- a/test/cpp/end2end/server_crash_test.cc +++ b/test/cpp/end2end/server_crash_test.cc @@ -153,7 +153,7 @@ int main(int argc, char** argv) { g_root = "."; } - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/server_early_return_test.cc b/test/cpp/end2end/server_early_return_test.cc index 8948e5b8546..c47e25052e2 100644 --- a/test/cpp/end2end/server_early_return_test.cc +++ b/test/cpp/end2end/server_early_return_test.cc @@ -226,7 +226,7 @@ TEST_F(ServerEarlyReturnTest, RequestStreamEarlyCancel) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 295d63516bd..c98b6143c66 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -577,7 +577,7 @@ TEST_F(ServerInterceptorsSyncUnimplementedEnd2endTest, UnimplementedRpcTest) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/shutdown_test.cc b/test/cpp/end2end/shutdown_test.cc index a53de691bcd..da42178d67c 100644 --- a/test/cpp/end2end/shutdown_test.cc +++ b/test/cpp/end2end/shutdown_test.cc @@ -164,7 +164,7 @@ TEST_P(ShutdownTest, ShutdownTest) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/streaming_throughput_test.cc b/test/cpp/end2end/streaming_throughput_test.cc index 898d1ec1188..440656588b2 100644 --- a/test/cpp/end2end/streaming_throughput_test.cc +++ b/test/cpp/end2end/streaming_throughput_test.cc @@ -187,7 +187,7 @@ TEST_F(End2endTest, StreamingThroughput) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index 1a5ed28a2cc..e30ce0dbcbf 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -429,7 +429,7 @@ TYPED_TEST(AsyncClientEnd2endTest, ThreadStress) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } 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 664504a0903..73394028309 100644 --- a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc +++ b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc @@ -370,7 +370,7 @@ TEST_F(StatsPluginEnd2EndTest, RequestReceivedMessagesPerRpc) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index fc6721d0ba8..3eb0e7d7254 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -838,7 +838,7 @@ int main(int argc, char** argv) { gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver); } gpr_free(resolver); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); auto result = RUN_ALL_TESTS(); // Test sequential and nested inits and shutdowns. diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index dec7c171dc0..8cfaf545efb 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -341,7 +341,7 @@ TEST(CancelDuringAresQuery, } // namespace int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); gpr_setenv("GRPC_DNS_RESOLVER", "ares"); // Sanity check the time that it takes to run the test diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 3dc6e7178cc..fe6fcb8d9cb 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -477,7 +477,7 @@ TEST(ResolverComponentTest, TestResolvesRelevantRecordsWithConcurrentFdStress) { int main(int argc, char** argv) { grpc_init(); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); ParseCommandLineFlags(&argc, &argv, true); if (FLAGS_target_name == "") { diff --git a/test/cpp/performance/writes_per_rpc_test.cc b/test/cpp/performance/writes_per_rpc_test.cc index baeede34ea4..3c5b3468848 100644 --- a/test/cpp/performance/writes_per_rpc_test.cc +++ b/test/cpp/performance/writes_per_rpc_test.cc @@ -255,7 +255,7 @@ TEST(WritesPerRpcTest, UnaryPingPong) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/server/load_reporter/get_cpu_stats_test.cc b/test/cpp/server/load_reporter/get_cpu_stats_test.cc index 5b1d5fa3a49..98c15b2c69b 100644 --- a/test/cpp/server/load_reporter/get_cpu_stats_test.cc +++ b/test/cpp/server/load_reporter/get_cpu_stats_test.cc @@ -55,7 +55,7 @@ TEST(GetCpuStatsTest, Ascending) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/server/load_reporter/load_data_store_test.cc b/test/cpp/server/load_reporter/load_data_store_test.cc index c92c407e4f8..a3a67a28516 100644 --- a/test/cpp/server/load_reporter/load_data_store_test.cc +++ b/test/cpp/server/load_reporter/load_data_store_test.cc @@ -475,7 +475,7 @@ TEST_F(PerBalancerStoreTest, DataAggregation) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/server/load_reporter/load_reporter_test.cc b/test/cpp/server/load_reporter/load_reporter_test.cc index 0d56cdf431d..9d2ebfb0b4f 100644 --- a/test/cpp/server/load_reporter/load_reporter_test.cc +++ b/test/cpp/server/load_reporter/load_reporter_test.cc @@ -501,7 +501,7 @@ TEST_F(LoadReportTest, BasicReport) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc index 516f3fa53dc..1d641535e29 100644 --- a/test/cpp/util/cli_call_test.cc +++ b/test/cpp/util/cli_call_test.cc @@ -122,7 +122,7 @@ TEST_F(CliCallTest, SimpleRpc) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index be9a624a2c2..4ddc11c5a64 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -1173,7 +1173,7 @@ TEST_F(GrpcToolTest, ListCommand_OverrideSslHostName) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); ::testing::FLAGS_gtest_death_test_style = "threadsafe"; return RUN_ALL_TESTS(); From aa66d8669eecd69a4559319e5a3a730e3efb2a5a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 21 Nov 2018 13:04:16 +0100 Subject: [PATCH 0385/2143] remove google-api-python-client pin --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index f5b0b764b14..eba05449e83 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -28,8 +28,7 @@ sudo systemsetup -setusingnetworktime on date # Add GCP credentials for BQ access -# pin google-api-python-client to avoid https://github.com/grpc/grpc/issues/15600 -pip install google-api-python-client==1.6.7 --user python +pip install google-api-python-client oauth2client --user python export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests From 0e11f2ebd05bd9095817890eae056feeb80faec1 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 30 Nov 2018 09:11:04 -0800 Subject: [PATCH 0386/2143] convert more tests --- test/core/fling/client.cc | 6 +++--- test/core/memory_usage/client.cc | 6 +++--- test/core/memory_usage/server.cc | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/core/fling/client.cc b/test/core/fling/client.cc index 05dc3052d1b..2a7a5ca6232 100644 --- a/test/core/fling/client.cc +++ b/test/core/fling/client.cc @@ -158,11 +158,11 @@ int main(int argc, char** argv) { gpr_timers_set_log_filename("latency_trace.fling_client.txt"); - grpc_init(); - GPR_ASSERT(argc >= 1); fake_argv[0] = argv[0]; - grpc_test_init(1, fake_argv); + grpc::testing::TestEnvironment env(1, fake_argv); + + grpc_init(); int warmup_seconds = 1; int benchmark_seconds = 5; diff --git a/test/core/memory_usage/client.cc b/test/core/memory_usage/client.cc index 3c3fa53b515..467586ea5f4 100644 --- a/test/core/memory_usage/client.cc +++ b/test/core/memory_usage/client.cc @@ -193,11 +193,11 @@ int main(int argc, char** argv) { gpr_cmdline* cl; grpc_event event; - grpc_init(); - GPR_ASSERT(argc >= 1); fake_argv[0] = argv[0]; - grpc_test_init(1, fake_argv); + grpc::testing::TestEnvironment env(1, fake_argv); + + grpc_init(); int warmup_iterations = 100; int benchmark_iterations = 1000; diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index 6f8a9bc0d46..7424797e6f5 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -162,7 +162,7 @@ int main(int argc, char** argv) { GPR_ASSERT(argc >= 1); fake_argv[0] = argv[0]; - grpc_test_init(1, fake_argv); + grpc::testing::TestEnvironment env(1, fake_argv); grpc_init(); srand(static_cast(clock())); From 5fc0547a94ce125e952a1782c4691e3902892ed4 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 28 Nov 2018 11:05:09 -0800 Subject: [PATCH 0387/2143] Add basicConfig to prepare to log future exception --- examples/python/helloworld/greeter_client.py | 2 ++ examples/python/helloworld/greeter_client_with_options.py | 2 ++ examples/python/helloworld/greeter_server.py | 2 ++ examples/python/helloworld/greeter_server_with_reflection.py | 2 ++ examples/python/interceptors/default_value/greeter_client.py | 2 ++ examples/python/interceptors/headers/greeter_client.py | 2 ++ examples/python/interceptors/headers/greeter_server.py | 2 ++ examples/python/multiplex/multiplex_client.py | 2 ++ examples/python/multiplex/multiplex_server.py | 2 ++ examples/python/route_guide/route_guide_client.py | 2 ++ examples/python/route_guide/route_guide_server.py | 2 ++ 11 files changed, 22 insertions(+) diff --git a/examples/python/helloworld/greeter_client.py b/examples/python/helloworld/greeter_client.py index 24b49ac2336..ee2032a9e6e 100644 --- a/examples/python/helloworld/greeter_client.py +++ b/examples/python/helloworld/greeter_client.py @@ -14,6 +14,7 @@ """The Python implementation of the GRPC helloworld.Greeter client.""" from __future__ import print_function +import logging import grpc @@ -32,4 +33,5 @@ def run(): if __name__ == '__main__': + logging.basicConfig() run() diff --git a/examples/python/helloworld/greeter_client_with_options.py b/examples/python/helloworld/greeter_client_with_options.py index 7eda8c9066f..d15871b5195 100644 --- a/examples/python/helloworld/greeter_client_with_options.py +++ b/examples/python/helloworld/greeter_client_with_options.py @@ -14,6 +14,7 @@ """The Python implementation of the GRPC helloworld.Greeter client with channel options and call timeout parameters.""" from __future__ import print_function +import logging import grpc @@ -41,4 +42,5 @@ def run(): if __name__ == '__main__': + logging.basicConfig() run() diff --git a/examples/python/helloworld/greeter_server.py b/examples/python/helloworld/greeter_server.py index c355662ef86..e3b4f2c1ff9 100644 --- a/examples/python/helloworld/greeter_server.py +++ b/examples/python/helloworld/greeter_server.py @@ -15,6 +15,7 @@ from concurrent import futures import time +import logging import grpc @@ -43,4 +44,5 @@ def serve(): if __name__ == '__main__': + logging.basicConfig() serve() diff --git a/examples/python/helloworld/greeter_server_with_reflection.py b/examples/python/helloworld/greeter_server_with_reflection.py index 5ba8782dfca..5acedbcb71f 100644 --- a/examples/python/helloworld/greeter_server_with_reflection.py +++ b/examples/python/helloworld/greeter_server_with_reflection.py @@ -15,6 +15,7 @@ from concurrent import futures import time +import logging import grpc from grpc_reflection.v1alpha import reflection @@ -49,4 +50,5 @@ def serve(): if __name__ == '__main__': + logging.basicConfig() serve() diff --git a/examples/python/interceptors/default_value/greeter_client.py b/examples/python/interceptors/default_value/greeter_client.py index da21ac68ec5..25834c2bbdd 100644 --- a/examples/python/interceptors/default_value/greeter_client.py +++ b/examples/python/interceptors/default_value/greeter_client.py @@ -14,6 +14,7 @@ """The Python implementation of the gRPC helloworld.Greeter client.""" from __future__ import print_function +import logging import grpc @@ -39,4 +40,5 @@ def run(): if __name__ == '__main__': + logging.basicConfig() run() diff --git a/examples/python/interceptors/headers/greeter_client.py b/examples/python/interceptors/headers/greeter_client.py index 6a09a3b9c50..712539850d3 100644 --- a/examples/python/interceptors/headers/greeter_client.py +++ b/examples/python/interceptors/headers/greeter_client.py @@ -14,6 +14,7 @@ """The Python implementation of the GRPC helloworld.Greeter client.""" from __future__ import print_function +import logging import grpc @@ -37,4 +38,5 @@ def run(): if __name__ == '__main__': + logging.basicConfig() run() diff --git a/examples/python/interceptors/headers/greeter_server.py b/examples/python/interceptors/headers/greeter_server.py index 01968609b53..6b0f4058bcd 100644 --- a/examples/python/interceptors/headers/greeter_server.py +++ b/examples/python/interceptors/headers/greeter_server.py @@ -15,6 +15,7 @@ from concurrent import futures import time +import logging import grpc @@ -49,4 +50,5 @@ def serve(): if __name__ == '__main__': + logging.basicConfig() serve() diff --git a/examples/python/multiplex/multiplex_client.py b/examples/python/multiplex/multiplex_client.py index 19d39ce66eb..155f85c4b0c 100644 --- a/examples/python/multiplex/multiplex_client.py +++ b/examples/python/multiplex/multiplex_client.py @@ -17,6 +17,7 @@ from __future__ import print_function import random import time +import logging import grpc @@ -126,4 +127,5 @@ def run(): if __name__ == '__main__': + logging.basicConfig() run() diff --git a/examples/python/multiplex/multiplex_server.py b/examples/python/multiplex/multiplex_server.py index 70dec3c9390..c01824b3a97 100644 --- a/examples/python/multiplex/multiplex_server.py +++ b/examples/python/multiplex/multiplex_server.py @@ -16,6 +16,7 @@ from concurrent import futures import time import math +import logging import grpc @@ -136,4 +137,5 @@ def serve(): if __name__ == '__main__': + logging.basicConfig() serve() diff --git a/examples/python/route_guide/route_guide_client.py b/examples/python/route_guide/route_guide_client.py index b4ff3239ba8..dc93fb44379 100644 --- a/examples/python/route_guide/route_guide_client.py +++ b/examples/python/route_guide/route_guide_client.py @@ -16,6 +16,7 @@ from __future__ import print_function import random +import logging import grpc @@ -116,4 +117,5 @@ def run(): if __name__ == '__main__': + logging.basicConfig() run() diff --git a/examples/python/route_guide/route_guide_server.py b/examples/python/route_guide/route_guide_server.py index 1969fdd378d..e00cb699084 100644 --- a/examples/python/route_guide/route_guide_server.py +++ b/examples/python/route_guide/route_guide_server.py @@ -16,6 +16,7 @@ from concurrent import futures import time import math +import logging import grpc @@ -126,4 +127,5 @@ def serve(): if __name__ == '__main__': + logging.basicConfig() serve() From 4a6e16532834bc8c80f248da27b6d1447563f939 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Fri, 30 Nov 2018 10:26:31 -0800 Subject: [PATCH 0388/2143] Add service definition to sync server --- .../end2end/client_callback_end2end_test.cc | 2 +- test/cpp/end2end/test_service_impl.cc | 20 +++++++++++++++---- test/cpp/end2end/test_service_impl.h | 4 ++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index e25a6689e5a..3871c644be4 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -219,8 +219,8 @@ TEST_P(ClientCallbackEnd2endTest, SendClientInitialMetadata) { gpr_log(GPR_ERROR, s.error_message().c_str()); gpr_log(GPR_ERROR, s.error_details().c_str()); GPR_ASSERT(s.ok()); + std::lock_guard l(mu); - done = true; cv.notify_one(); }); diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index a7be8a798ac..8f973182520 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -181,17 +181,16 @@ Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, return Status::OK; } -void CallbackTestServiceImpl::CheckClientInitialMetadata( +Status TestServiceImpl::CheckClientInitialMetadata( ServerContext* context, const SimpleRequest* request, - SimpleResponse* response, - experimental::ServerCallbackRpcController* controller) { + SimpleResponse* response) { EXPECT_EQ(MetadataMatchCount(context->client_metadata(), kCheckClientInitialMetadataKey, kCheckClientInitialMetadataVal), 1); EXPECT_EQ(1u, context->client_metadata().count(kCheckClientInitialMetadataKey)); - controller->Finish(Status::OK); + return Status::OK; } void CallbackTestServiceImpl::Echo( @@ -212,6 +211,19 @@ void CallbackTestServiceImpl::Echo( } } +void CallbackTestServiceImpl::CheckClientInitialMetadata( + ServerContext* context, const SimpleRequest* request, + SimpleResponse* response, + experimental::ServerCallbackRpcController* controller) { + EXPECT_EQ(MetadataMatchCount(context->client_metadata(), + kCheckClientInitialMetadataKey, + kCheckClientInitialMetadataVal), + 1); + EXPECT_EQ(1u, + context->client_metadata().count(kCheckClientInitialMetadataKey)); + controller->Finish(Status::OK); +} + void CallbackTestServiceImpl::EchoNonDelayed( ServerContext* context, const EchoRequest* request, EchoResponse* response, experimental::ServerCallbackRpcController* controller) { diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h index 124d5e512b6..2c63aa4dab3 100644 --- a/test/cpp/end2end/test_service_impl.h +++ b/test/cpp/end2end/test_service_impl.h @@ -55,6 +55,10 @@ class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { Status Echo(ServerContext* context, const EchoRequest* request, EchoResponse* response) override; + Status CheckClientInitialMetadata( + ServerContext* context, const SimpleRequest* request, + SimpleResponse* response) override; + // Unimplemented is left unimplemented to test the returned error. Status RequestStream(ServerContext* context, From 12d9d04cb4768c1721bc8114451f54cc945d1b95 Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Mon, 15 Oct 2018 06:39:18 -0700 Subject: [PATCH 0389/2143] Make microbenchmarks test targets --- test/cpp/microbenchmarks/BUILD | 44 ++++++++++------------------------ 1 file changed, 13 insertions(+), 31 deletions(-) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 097e92f5836..5d12ffd20c9 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -29,7 +29,6 @@ grpc_cc_test( grpc_cc_library( name = "helpers", - testonly = 1, srcs = ["helpers.cc"], hdrs = [ "fullstack_context_mutators.h", @@ -47,67 +46,58 @@ grpc_cc_library( ], ) -grpc_cc_binary( +grpc_cc_test( name = "bm_closure", - testonly = 1, srcs = ["bm_closure.cc"], deps = [":helpers"], ) -grpc_cc_binary( +grpc_cc_test( name = "bm_arena", - testonly = 1, srcs = ["bm_arena.cc"], deps = [":helpers"], ) -grpc_cc_binary( +grpc_cc_test( name = "bm_channel", - testonly = 1, srcs = ["bm_channel.cc"], deps = [":helpers"], ) -grpc_cc_binary( +grpc_cc_test( name = "bm_call_create", - testonly = 1, srcs = ["bm_call_create.cc"], deps = [":helpers"], ) -grpc_cc_binary( +grpc_cc_test( name = "bm_cq", - testonly = 1, srcs = ["bm_cq.cc"], deps = [":helpers"], ) -grpc_cc_binary( +grpc_cc_test( name = "bm_cq_multiple_threads", - testonly = 1, srcs = ["bm_cq_multiple_threads.cc"], deps = [":helpers"], ) -grpc_cc_binary( +grpc_cc_test( name = "bm_error", - testonly = 1, srcs = ["bm_error.cc"], deps = [":helpers"], ) grpc_cc_library( name = "fullstack_streaming_ping_pong_h", - testonly = 1, hdrs = [ "fullstack_streaming_ping_pong.h", ], deps = [":helpers"], ) -grpc_cc_binary( +grpc_cc_test( name = "bm_fullstack_streaming_ping_pong", - testonly = 1, srcs = [ "bm_fullstack_streaming_ping_pong.cc", ], @@ -116,16 +106,14 @@ grpc_cc_binary( grpc_cc_library( name = "fullstack_streaming_pump_h", - testonly = 1, hdrs = [ "fullstack_streaming_pump.h", ], deps = [":helpers"], ) -grpc_cc_binary( +grpc_cc_test( name = "bm_fullstack_streaming_pump", - testonly = 1, srcs = [ "bm_fullstack_streaming_pump.cc", ], @@ -134,46 +122,40 @@ grpc_cc_binary( grpc_cc_binary( name = "bm_fullstack_trickle", - testonly = 1, srcs = ["bm_fullstack_trickle.cc"], deps = [":helpers"], ) grpc_cc_library( name = "fullstack_unary_ping_pong_h", - testonly = 1, hdrs = [ "fullstack_unary_ping_pong.h", ], deps = [":helpers"], ) -grpc_cc_binary( +grpc_cc_test( name = "bm_fullstack_unary_ping_pong", - testonly = 1, srcs = [ "bm_fullstack_unary_ping_pong.cc", ], deps = [":fullstack_unary_ping_pong_h"], ) -grpc_cc_binary( +grpc_cc_test( name = "bm_metadata", - testonly = 1, srcs = ["bm_metadata.cc"], deps = [":helpers"], ) -grpc_cc_binary( +grpc_cc_test( name = "bm_chttp2_hpack", - testonly = 1, srcs = ["bm_chttp2_hpack.cc"], deps = [":helpers"], ) -grpc_cc_binary( +grpc_cc_test( name = "bm_opencensus_plugin", - testonly = 1, srcs = ["bm_opencensus_plugin.cc"], language = "C++", deps = [ From bdd0d47e07f324ee922f9cb05365a7e9c3cb45ea Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 16 Oct 2018 08:00:32 -0700 Subject: [PATCH 0390/2143] microbenchmarks don't use polling --- test/cpp/microbenchmarks/BUILD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 5d12ffd20c9..cbfc8021d01 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -50,18 +50,21 @@ grpc_cc_test( name = "bm_closure", srcs = ["bm_closure.cc"], deps = [":helpers"], + uses_polling = False, ) grpc_cc_test( name = "bm_arena", srcs = ["bm_arena.cc"], deps = [":helpers"], + uses_polling = False, ) grpc_cc_test( name = "bm_channel", srcs = ["bm_channel.cc"], deps = [":helpers"], + uses_polling = False, ) grpc_cc_test( @@ -74,18 +77,21 @@ grpc_cc_test( name = "bm_cq", srcs = ["bm_cq.cc"], deps = [":helpers"], + uses_polling = False, ) grpc_cc_test( name = "bm_cq_multiple_threads", srcs = ["bm_cq_multiple_threads.cc"], deps = [":helpers"], + uses_polling = False, ) grpc_cc_test( name = "bm_error", srcs = ["bm_error.cc"], deps = [":helpers"], + uses_polling = False, ) grpc_cc_library( @@ -146,12 +152,14 @@ grpc_cc_test( name = "bm_metadata", srcs = ["bm_metadata.cc"], deps = [":helpers"], + uses_polling = False, ) grpc_cc_test( name = "bm_chttp2_hpack", srcs = ["bm_chttp2_hpack.cc"], deps = [":helpers"], + uses_polling = False, ) grpc_cc_test( @@ -163,4 +171,5 @@ grpc_cc_test( "//:grpc_opencensus_plugin", "//src/proto/grpc/testing:echo_proto", ], + uses_polling = False, ) From 3eb6c4779d0d132d1d5c7e17f7ef14812324c820 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 16 Oct 2018 09:20:02 -0700 Subject: [PATCH 0391/2143] Exclude census --- test/cpp/microbenchmarks/BUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index cbfc8021d01..671e7f1096a 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -162,8 +162,9 @@ grpc_cc_test( uses_polling = False, ) -grpc_cc_test( +grpc_cc_binary( name = "bm_opencensus_plugin", + testonly = 1, srcs = ["bm_opencensus_plugin.cc"], language = "C++", deps = [ @@ -171,5 +172,4 @@ grpc_cc_test( "//:grpc_opencensus_plugin", "//src/proto/grpc/testing:echo_proto", ], - uses_polling = False, ) From 475ccfd110c6dfd0232cd8feedea7e4b8c42a82a Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 30 Nov 2018 10:26:38 -0800 Subject: [PATCH 0392/2143] Fix ubsan --- test/cpp/microbenchmarks/bm_call_create.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 8d12606434b..a0157c66c25 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -526,7 +526,7 @@ static void BM_IsolatedFilter(benchmark::State& state) { grpc_core::ExecCtx exec_ctx; size_t channel_size = grpc_channel_stack_size( - filters.size() == 0 ? nullptr : &filters[0], filters.size()); + filters.size() == 0 ? nullptr : filters.data(), filters.size()); grpc_channel_stack* channel_stack = static_cast(gpr_zalloc(channel_size)); GPR_ASSERT(GRPC_LOG_IF_ERROR( From aa67cb24a7d82b74c938e769fb1fa56794efd8e1 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 30 Nov 2018 10:40:39 -0800 Subject: [PATCH 0393/2143] Allow building only the Python/Cython code in setup.py via new flag --- setup.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ae86e6c9fb7..7bdfc99e24b 100644 --- a/setup.py +++ b/setup.py @@ -87,6 +87,7 @@ CLASSIFIERS = [ # present, then it will still attempt to use Cython. BUILD_WITH_CYTHON = os.environ.get('GRPC_PYTHON_BUILD_WITH_CYTHON', False) + # Export this variable to use the system installation of openssl. You need to # have the header files installed (in /usr/include/openssl) and during # runtime, the shared library must be installed @@ -105,6 +106,21 @@ BUILD_WITH_SYSTEM_ZLIB = os.environ.get('GRPC_PYTHON_BUILD_SYSTEM_ZLIB', BUILD_WITH_SYSTEM_CARES = os.environ.get('GRPC_PYTHON_BUILD_SYSTEM_CARES', False) +# For local development use only: This skips building gRPC Core and its +# dependencies, including protobuf and boringssl. This allows "incremental" +# compilation by first building gRPC Core using make, then building only the +# Python/Cython layers here. +# +# Note that this requires libboringssl.a in the libs/{dbg,opt}/ directory, which +# may require configuring make to not use the system openssl implementation: +# +# make HAS_SYSTEM_OPENSSL_ALPN=0 +# +# TODO(ericgribkoff) Respect the BUILD_WITH_SYSTEM_* flags alongside this option +USE_PREBUILT_GRPC_CORE = os.environ.get( + 'GRPC_PYTHON_USE_PREBUILT_GRPC_CORE', False) + + # If this environmental variable is set, GRPC will not try to be compatible with # libc versions old than the one it was compiled against. DISABLE_LIBC_COMPATIBILITY = os.environ.get('GRPC_PYTHON_DISABLE_LIBC_COMPATIBILITY', False) @@ -249,7 +265,7 @@ 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: + if "darwin" in sys.platform or USE_PREBUILT_GRPC_CORE: extra_objects = [prefix + 'libares.a', prefix + 'libboringssl.a', prefix + 'libgpr.a', From 32736c52c49637556898aed2b19076f297a3911a Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 30 Nov 2018 12:06:27 -0800 Subject: [PATCH 0394/2143] Comment about comments --- src/proto/grpc/testing/compiler_test.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/proto/grpc/testing/compiler_test.proto b/src/proto/grpc/testing/compiler_test.proto index db5ca483312..9fa5590a594 100644 --- a/src/proto/grpc/testing/compiler_test.proto +++ b/src/proto/grpc/testing/compiler_test.proto @@ -20,6 +20,9 @@ syntax = "proto3"; // Ignored detached comment +// The comments in this file are not meant for readability +// but rather to test to make sure that the code generator +// properly preserves comments on files, services, and RPCs // Ignored package leading comment package grpc.testing; From 459da578db5ae9bd95f91be2888236c4870a7314 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 30 Nov 2018 13:43:56 -0800 Subject: [PATCH 0395/2143] Refactor channel pool --- src/objective-c/GRPCClient/GRPCCall.m | 15 +- .../GRPCClient/private/GRPCChannelPool.h | 35 ++- .../GRPCClient/private/GRPCChannelPool.m | 276 +++++++----------- .../GRPCClient/private/GRPCWrappedCall.h | 13 +- .../GRPCClient/private/GRPCWrappedCall.m | 115 ++++---- .../tests/ChannelTests/ChannelPoolTest.m | 144 ++------- .../tests/ChannelTests/ChannelTests.m | 158 +++++----- .../xcschemes/ChannelTests.xcscheme | 5 - 8 files changed, 307 insertions(+), 454 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index bf9441c27eb..dad8594a264 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -36,6 +36,8 @@ #import "private/NSDictionary+GRPC.h" #import "private/NSError+GRPC.h" #import "private/utilities.h" +#import "private/GRPCChannelPool.h" +#import "private/GRPCCompletionQueue.h" // At most 6 ops can be in an op batch for a client: SEND_INITIAL_METADATA, // SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT, RECV_INITIAL_METADATA, RECV_MESSAGE, @@ -819,8 +821,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; - GRPCWrappedCall *wrappedCall = - [[GRPCWrappedCall alloc] initWithHost:_host path:_path callOptions:_callOptions]; + GRPCPooledChannel *channel = [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; + GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:_path + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:_callOptions]; + if (wrappedCall == nil) { [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable @@ -837,12 +842,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self sendHeaders]; [self invokeCall]; - - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; - } } - (void)startWithWriteable:(id)writeable { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 7f8ee19fe59..338b6e440f3 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -32,10 +32,13 @@ NS_ASSUME_NONNULL_BEGIN @class GRPCChannelPool; @class GRPCCompletionQueue; @class GRPCChannelConfiguration; +@class GRPCWrappedCall; /** - * Channel proxy that can be retained and automatically reestablish connection when the channel is - * disconnected. + * A proxied channel object that can be retained and creates GRPCWrappedCall object from. If a + * raw channel is not present (i.e. no tcp connection to the server) when a GRPCWrappedCall object + * is requested, it issues a connection/reconnection. The behavior of this object is to mimic that + * of gRPC core's channel object. */ @interface GRPCPooledChannel : NSObject @@ -47,24 +50,21 @@ NS_ASSUME_NONNULL_BEGIN * Initialize with an actual channel object \a channel and a reference to the channel pool. */ - (nullable instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration - channelPool:(GRPCChannelPool *)channelPool - NS_DESIGNATED_INITIALIZER; + (GRPCChannelConfiguration *)channelConfiguration; /** - * Create a grpc core call object (grpc_call) from this channel. If channel is disconnected, get a + * Create a GRPCWrappedCall object (grpc_call) from this channel. If channel is disconnected, get a * new channel object from the channel pool. */ -- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path - completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions; +- (nullable GRPCWrappedCall *)wrappedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions; /** - * Return ownership and destroy the grpc_call object created by - * \a unmanagedCallWithPath:completionQueue:callOptions: and decrease channel refcount. If refcount - * of the channel becomes 0, return the channel object to channel pool. + * Notify the pooled channel that a wrapped call object is no longer referenced and will be + * dealloc'ed. */ -- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall; +- (void)notifyWrappedCallDealloc:(GRPCWrappedCall *)wrappedCall; /** * Force the channel to disconnect immediately. Subsequent calls to unmanagedCallWithPath: will @@ -77,6 +77,13 @@ NS_ASSUME_NONNULL_BEGIN /** Test-only interface for \a GRPCPooledChannel. */ @interface GRPCPooledChannel (Test) +/** + * Initialize a pooled channel with non-default destroy delay for testing purpose. + */ +- (nullable instancetype)initWithChannelConfiguration: +(GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay; + /** * Return the pointer to the raw channel wrapped. */ @@ -118,7 +125,7 @@ NS_ASSUME_NONNULL_BEGIN * Get an instance of pool isolated from the global shared pool with channels' destroy delay being * \a destroyDelay. */ -- (nullable instancetype)initTestPoolWithDestroyDelay:(NSTimeInterval)destroyDelay; +- (nullable instancetype)initTestPool; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 646f1e4b86e..488766c0edc 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -28,6 +28,8 @@ #import "GRPCSecureChannelFactory.h" #import "utilities.h" #import "version.h" +#import "GRPCWrappedCall.h" +#import "GRPCCompletionQueue.h" #import #include @@ -40,103 +42,139 @@ static dispatch_once_t gInitChannelPool; /** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; -@interface GRPCChannelPool () - -- (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; - -- (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration; - -@end - @implementation GRPCPooledChannel { - __weak GRPCChannelPool *_channelPool; GRPCChannelConfiguration *_channelConfiguration; - NSMutableSet *_unmanagedCalls; + NSTimeInterval _destroyDelay; + + NSHashTable *_wrappedCalls; GRPCChannel *_wrappedChannel; + NSDate *_lastTimedDestroy; + dispatch_queue_t _timerQueue; } -- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration - channelPool:(GRPCChannelPool *)channelPool { - NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); - NSAssert(channelPool != nil, @"channelPool cannot be empty."); - if (channelPool == nil || channelConfiguration == nil) { - return nil; - } - - if ((self = [super init])) { - _channelPool = channelPool; - _channelConfiguration = channelConfiguration; - _unmanagedCalls = [NSMutableSet set]; - _wrappedChannel = nil; - } - - return self; +- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { + return [self initWithChannelConfiguration:channelConfiguration destroyDelay:kDefaultChannelDestroyDelay]; } - (void)dealloc { - NSAssert([_unmanagedCalls count] == 0 && _wrappedChannel == nil, - @"Pooled channel should only be" - "destroyed after the wrapped channel is destroyed"); + if ([_wrappedCalls objectEnumerator].allObjects.count != 0) { + NSEnumerator *enumerator = [_wrappedCalls objectEnumerator]; + GRPCWrappedCall *wrappedCall; + while ((wrappedCall = [enumerator nextObject])) { + [wrappedCall channelDisconnected]; + }; + } } -- (grpc_call *)unmanagedCallWithPath:(NSString *)path - completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions { +- (GRPCWrappedCall *)wrappedCallWithPath:(NSString *)path +completionQueue:(GRPCCompletionQueue *)queue +callOptions:(GRPCCallOptions *)callOptions { NSAssert(path.length > 0, @"path must not be empty."); NSAssert(queue != nil, @"completionQueue must not be empty."); NSAssert(callOptions, @"callOptions must not be empty."); if (path.length == 0 || queue == nil || callOptions == nil) return NULL; - grpc_call *call = NULL; + GRPCWrappedCall *call = nil; + @synchronized(self) { if (_wrappedChannel == nil) { - __strong GRPCChannelPool *strongPool = _channelPool; - if (strongPool) { - _wrappedChannel = [strongPool refChannelWithConfiguration:_channelConfiguration]; + _wrappedChannel = [[GRPCChannel alloc] initWithChannelConfiguration:_channelConfiguration]; + if (_wrappedChannel == nil) { + NSAssert(_wrappedChannel != nil, @"Unable to get a raw channel for proxy."); + return nil; } - NSAssert(_wrappedChannel != nil, @"Unable to get a raw channel for proxy."); } - call = - [_wrappedChannel unmanagedCallWithPath:path completionQueue:queue callOptions:callOptions]; - if (call != NULL) { - [_unmanagedCalls addObject:[NSValue valueWithPointer:call]]; + _lastTimedDestroy = nil; + + grpc_call *unmanagedCall = [_wrappedChannel unmanagedCallWithPath:path + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:callOptions]; + if (unmanagedCall == NULL) { + NSAssert(unmanagedCall != NULL, @"Unable to create grpc_call object"); + return nil; } + + call = [[GRPCWrappedCall alloc] initWithUnmanagedCall:unmanagedCall pooledChannel:self]; + if (call == nil) { + NSAssert(call != nil, @"Unable to create GRPCWrappedCall object"); + return nil; + } + + [_wrappedCalls addObject:call]; } return call; } -- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall { - if (unmanagedCall == NULL) { +- (void)notifyWrappedCallDealloc:(GRPCWrappedCall *)wrappedCall { + NSAssert(wrappedCall != nil, @"wrappedCall cannot be empty."); + if (wrappedCall == nil) { return; } - - grpc_call_unref(unmanagedCall); @synchronized(self) { - NSValue *removedCall = [NSValue valueWithPointer:unmanagedCall]; - [_unmanagedCalls removeObject:removedCall]; - if ([_unmanagedCalls count] == 0) { - _wrappedChannel = nil; - GRPCChannelPool *strongPool = _channelPool; - [strongPool unrefChannelWithConfiguration:_channelConfiguration]; + if ([_wrappedCalls objectEnumerator].allObjects.count == 0) { + NSDate *now = [NSDate date]; + _lastTimedDestroy = now; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)_destroyDelay * NSEC_PER_SEC), + _timerQueue, ^{ + @synchronized(self) { + if (self->_lastTimedDestroy == now) { + self->_wrappedChannel = nil; + self->_lastTimedDestroy = nil; + } + } + }); } } } - (void)disconnect { + NSHashTable *copiedWrappedCalls = nil; @synchronized(self) { if (_wrappedChannel != nil) { _wrappedChannel = nil; - [_unmanagedCalls removeAllObjects]; - GRPCChannelPool *strongPool = _channelPool; - [strongPool unrefChannelWithConfiguration:_channelConfiguration]; + copiedWrappedCalls = [_wrappedCalls copy]; + [_wrappedCalls removeAllObjects]; } } + NSEnumerator *enumerator = [copiedWrappedCalls objectEnumerator]; + GRPCWrappedCall *wrappedCall; + while ((wrappedCall = [enumerator nextObject])) { + [wrappedCall channelDisconnected]; + } } @end @implementation GRPCPooledChannel (Test) +- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay { + NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); + if (channelConfiguration == nil) { + return nil; + } + + if ((self = [super init])) { + _channelConfiguration = channelConfiguration; + _destroyDelay = destroyDelay; + _wrappedCalls = [[NSHashTable alloc] initWithOptions:NSHashTableWeakMemory capacity:1]; + _wrappedChannel = nil; + _lastTimedDestroy = nil; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { + _timerQueue = dispatch_queue_create(NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + } else { +#else + { +#endif + _timerQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } + } + + return self; +} + - (GRPCChannel *)wrappedChannel { GRPCChannel *channel = nil; @synchronized(self) { @@ -147,65 +185,28 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @end -/** - * A convenience value type for cached channel. - */ -@interface GRPCChannelRecord : NSObject - -/** Pointer to the raw channel. May be nil when the channel has been destroyed. */ -@property GRPCChannel *channel; - -/** Channel proxy corresponding to this channel configuration. */ -@property GRPCPooledChannel *pooledChannel; - -/** Last time when a timed destroy is initiated on the channel. */ -@property NSDate *timedDestroyDate; - -/** Reference count of the proxy to the channel. */ -@property NSUInteger refCount; - -@end - -@implementation GRPCChannelRecord - -@end - @interface GRPCChannelPool () -- (instancetype)initInstanceWithDestroyDelay:(NSTimeInterval)destroyDelay NS_DESIGNATED_INITIALIZER; +- (instancetype)initInstance NS_DESIGNATED_INITIALIZER; @end @implementation GRPCChannelPool { - NSMutableDictionary *_channelPool; - dispatch_queue_t _dispatchQueue; - NSTimeInterval _destroyDelay; + NSMutableDictionary *_channelPool; } + (instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ gChannelPool = - [[GRPCChannelPool alloc] initInstanceWithDestroyDelay:kDefaultChannelDestroyDelay]; + [[GRPCChannelPool alloc] initInstance]; NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); }); return gChannelPool; } -- (instancetype)initInstanceWithDestroyDelay:(NSTimeInterval)destroyDelay { +- (instancetype)initInstance { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 - if (@available(iOS 8.0, macOS 10.10, *)) { - _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); - } else { -#else - { -#endif - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - } - _destroyDelay = destroyDelay; // Connectivity monitor is not required for CFStream char *enableCFStream = getenv(kCFStreamVarName); @@ -231,86 +232,23 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; @synchronized(self) { - GRPCChannelRecord *record = _channelPool[configuration]; - if (record == nil) { - record = [[GRPCChannelRecord alloc] init]; - record.pooledChannel = - [[GRPCPooledChannel alloc] initWithChannelConfiguration:configuration channelPool:self]; - _channelPool[configuration] = record; - pooledChannel = record.pooledChannel; - } else { - pooledChannel = record.pooledChannel; + pooledChannel = _channelPool[configuration]; + if (pooledChannel == nil) { + pooledChannel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:configuration]; + _channelPool[configuration] = pooledChannel; } } return pooledChannel; } -- (GRPCChannel *)refChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { - GRPCChannel *ret = nil; - @synchronized(self) { - NSAssert(configuration != nil, @"configuration cannot be empty."); - if (configuration == nil) { - return nil; - } - - GRPCChannelRecord *record = _channelPool[configuration]; - NSAssert(record != nil, @"No record corresponding to a proxy."); - if (record == nil) { - return nil; - } - - record.refCount++; - record.timedDestroyDate = nil; - if (record.channel == nil) { - // Channel is already destroyed; - record.channel = [[GRPCChannel alloc] initWithChannelConfiguration:configuration]; - } - ret = record.channel; - } - return ret; -} - -- (void)unrefChannelWithConfiguration:(GRPCChannelConfiguration *)configuration { - @synchronized(self) { - GRPCChannelRecord *record = _channelPool[configuration]; - NSAssert(record != nil, @"No record corresponding to a proxy."); - if (record == nil) { - return; - } - NSAssert(record.refCount > 0, @"Inconsistent channel refcount."); - if (record.refCount > 0) { - record.refCount--; - if (record.refCount == 0) { - NSDate *now = [NSDate date]; - record.timedDestroyDate = now; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_destroyDelay * NSEC_PER_SEC)), - _dispatchQueue, ^{ - @synchronized(self) { - if (now == record.timedDestroyDate) { - // Destroy the raw channel and reset related records. - record.timedDestroyDate = nil; - record.channel = nil; - } - } - }); - } - } - } -} - - (void)disconnectAllChannels { - NSMutableSet *proxySet = [NSMutableSet set]; + NSDictionary *copiedPooledChannels; @synchronized(self) { - [_channelPool - enumerateKeysAndObjectsUsingBlock:^(GRPCChannelConfiguration *_Nonnull key, - GRPCChannelRecord *_Nonnull obj, BOOL *_Nonnull stop) { - obj.channel = nil; - obj.timedDestroyDate = nil; - [proxySet addObject:obj.pooledChannel]; - }]; + copiedPooledChannels = [NSDictionary dictionaryWithDictionary:_channelPool]; } - // Disconnect proxies - [proxySet enumerateObjectsUsingBlock:^(GRPCPooledChannel *_Nonnull obj, BOOL *_Nonnull stop) { + + // Disconnect pooled channels. + [copiedPooledChannels enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { [obj disconnect]; }]; } @@ -323,8 +261,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; @implementation GRPCChannelPool (Test) -- (instancetype)initTestPoolWithDestroyDelay:(NSTimeInterval)destroyDelay { - return [self initInstanceWithDestroyDelay:destroyDelay]; +- (instancetype)initTestPool { + return [self initInstance]; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h index 19aa5367c77..0432190528f 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h @@ -71,11 +71,16 @@ #pragma mark GRPCWrappedCall +@class GRPCPooledChannel; + @interface GRPCWrappedCall : NSObject -- (instancetype)initWithHost:(NSString *)host - path:(NSString *)path - callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + +- (instancetype)initWithUnmanagedCall:(grpc_call *)unmanagedCall + pooledChannel:(GRPCPooledChannel *)pooledChannel NS_DESIGNATED_INITIALIZER; - (void)startBatchWithOperations:(NSArray *)ops errorHandler:(void (^)(void))errorHandler; @@ -83,4 +88,6 @@ - (void)cancel; +- (void)channelDisconnected; + @end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 5788d0a003f..7e2d9d3c6d3 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -237,37 +237,21 @@ #pragma mark GRPCWrappedCall @implementation GRPCWrappedCall { - GRPCCompletionQueue *_queue; - GRPCPooledChannel *_channel; + __weak GRPCPooledChannel *_channel; grpc_call *_call; } -- (instancetype)init { - return [self initWithHost:nil path:nil callOptions:[[GRPCCallOptions alloc] init]]; -} - -- (instancetype)initWithHost:(NSString *)host - path:(NSString *)path - callOptions:(GRPCCallOptions *)callOptions { - NSAssert(host.length != 0 && path.length != 0, @"path and host cannot be nil."); +- (instancetype)initWithUnmanagedCall:(grpc_call *)unmanagedCall + pooledChannel:(GRPCPooledChannel *)pooledChannel { + NSAssert(unmanagedCall != NULL, @"unmanagedCall cannot be empty."); + NSAssert(pooledChannel != nil, @"pooledChannel cannot be empty."); + if (unmanagedCall == NULL || pooledChannel == nil) { + return nil; + } if ((self = [super init])) { - // Each completion queue consumes one thread. There's a trade to be made between creating and - // consuming too many threads and having contention of multiple calls in a single completion - // queue. Currently we use a singleton queue. - _queue = [GRPCCompletionQueue completionQueue]; - _channel = [[GRPCChannelPool sharedInstance] channelWithHost:host callOptions:callOptions]; - if (_channel == nil) { - NSAssert(_channel != nil, @"Failed to get a channel for the host."); - NSLog(@"Failed to get a channel for the host."); - return nil; - } - _call = [_channel unmanagedCallWithPath:path completionQueue:_queue callOptions:callOptions]; - if (_call == nil) { - NSAssert(_channel != nil, @"Failed to get a channel for the host."); - NSLog(@"Failed to create a call."); - return nil; - } + _call = unmanagedCall; + _channel = pooledChannel; } return self; } @@ -283,42 +267,67 @@ [GRPCOpBatchLog addOpBatchToLog:operations]; #endif - size_t nops = operations.count; - grpc_op *ops_array = gpr_malloc(nops * sizeof(grpc_op)); - size_t i = 0; - for (GRPCOperation *operation in operations) { - ops_array[i++] = operation.op; - } - grpc_call_error error = - grpc_call_start_batch(_call, ops_array, nops, (__bridge_retained void *)(^(bool success) { - if (!success) { - if (errorHandler) { - errorHandler(); - } else { - return; - } - } - for (GRPCOperation *operation in operations) { - [operation finish]; - } - }), - NULL); - gpr_free(ops_array); + @synchronized (self) { + if (_call != NULL) { + size_t nops = operations.count; + grpc_op *ops_array = gpr_malloc(nops * sizeof(grpc_op)); + size_t i = 0; + for (GRPCOperation *operation in operations) { + ops_array[i++] = operation.op; + } + grpc_call_error error; + error = grpc_call_start_batch(_call, ops_array, nops, (__bridge_retained void *)(^(bool success) { + if (!success) { + if (errorHandler) { + errorHandler(); + } else { + return; + } + } + for (GRPCOperation *operation in operations) { + [operation finish]; + } + }), + NULL); + gpr_free(ops_array); - if (error != GRPC_CALL_OK) { - [NSException + if (error != GRPC_CALL_OK) { + [NSException raise:NSInternalInconsistencyException - format:@"A precondition for calling grpc_call_start_batch wasn't met. Error %i", error]; + format:@"A precondition for calling grpc_call_start_batch wasn't met. Error %i", error]; + } + } } } - (void)cancel { - grpc_call_cancel(_call, NULL); + @synchronized (self) { + if (_call != NULL) { + grpc_call_cancel(_call, NULL); + } + } +} + +- (void)channelDisconnected { + @synchronized (self) { + if (_call != NULL) { + grpc_call_unref(_call); + _call = NULL; + } + } } - (void)dealloc { - [_channel destroyUnmanagedCall:_call]; - _channel = nil; + @synchronized (self) { + if (_call != NULL) { + grpc_call_unref(_call); + _call = NULL; + } + } + __strong GRPCPooledChannel *channel = _channel; + if (channel != nil) { + [channel notifyWrappedCallDealloc:self]; + } } @end diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index 9461945560a..dc42d7c341d 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -24,11 +24,9 @@ #define TEST_TIMEOUT 32 -NSString *kDummyHost = @"dummy.host"; -NSString *kDummyHost2 = @"dummy.host.2"; -NSString *kDummyPath = @"/dummy/path"; - -const NSTimeInterval kDestroyDelay = 1.0; +static NSString *kDummyHost = @"dummy.host"; +static NSString *kDummyHost2 = @"dummy.host.2"; +static NSString *kDummyPath = @"/dummy/path"; @interface ChannelPoolTest : XCTestCase @@ -40,134 +38,26 @@ const NSTimeInterval kDestroyDelay = 1.0; grpc_init(); } -- (void)testCreateChannelAndCall { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - XCTAssertNil(channel.wrappedChannel); - GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = - [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - XCTAssert(call != NULL); - XCTAssertNotNil(channel.wrappedChannel); - [channel destroyUnmanagedCall:call]; - XCTAssertNil(channel.wrappedChannel); -} - -- (void)testCacheChannel { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; +- (void)testCreateAndCacheChannel { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPool]; GRPCCallOptions *options1 = [[GRPCCallOptions alloc] init]; GRPCCallOptions *options2 = [options1 copy]; GRPCMutableCallOptions *options3 = [options1 mutableCopy]; options3.transportType = GRPCTransportTypeInsecure; - GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - GRPCPooledChannel *channel1 = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options1]; - grpc_call *call1 = - [channel1 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options1]; - GRPCPooledChannel *channel2 = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options2]; - grpc_call *call2 = - [channel2 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options2]; - GRPCPooledChannel *channel3 = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options3]; - grpc_call *call3 = - [channel3 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options3]; - GRPCPooledChannel *channel4 = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost2 callOptions:options1]; - grpc_call *call4 = - [channel4 unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options1]; - XCTAssertEqual(channel1.wrappedChannel, channel2.wrappedChannel); - XCTAssertNotEqual(channel1.wrappedChannel, channel3.wrappedChannel); - XCTAssertNotEqual(channel1.wrappedChannel, channel4.wrappedChannel); - XCTAssertNotEqual(channel3.wrappedChannel, channel4.wrappedChannel); - [channel1 destroyUnmanagedCall:call1]; - [channel2 destroyUnmanagedCall:call2]; - [channel3 destroyUnmanagedCall:call3]; - [channel4 destroyUnmanagedCall:call4]; -} -- (void)testTimedDestroyChannel { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = - [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - GRPCChannel *wrappedChannel = channel.wrappedChannel; + GRPCPooledChannel *channel1 = [pool channelWithHost:kDummyHost callOptions:options1]; + GRPCPooledChannel *channel2 = [pool channelWithHost:kDummyHost callOptions:options2]; + GRPCPooledChannel *channel3 = [pool channelWithHost:kDummyHost callOptions:options3]; + GRPCPooledChannel *channel4 = [pool channelWithHost:kDummyHost2 callOptions:options1]; - [channel destroyUnmanagedCall:call]; - // Confirm channel is not destroyed at this time - call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - XCTAssertEqual(wrappedChannel, channel.wrappedChannel); - - [channel destroyUnmanagedCall:call]; - sleep(kDestroyDelay + 1); - // Confirm channel is new at this time - call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); - - // Confirm the new channel can create call - XCTAssert(call != NULL); - [channel destroyUnmanagedCall:call]; -} - -- (void)testPoolDisconnection { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = - [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - XCTAssertNotNil(channel.wrappedChannel); - GRPCChannel *wrappedChannel = channel.wrappedChannel; - - // Test a new channel is created by requesting a channel from pool - [pool disconnectAllChannels]; - channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - call = [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - XCTAssertNotNil(channel.wrappedChannel); - XCTAssertNotEqual(wrappedChannel, channel.wrappedChannel); - wrappedChannel = channel.wrappedChannel; - - // Test a new channel is created by requesting a new call from the previous proxy - [pool disconnectAllChannels]; - grpc_call *call2 = - [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - XCTAssertNotNil(channel.wrappedChannel); - XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); - [channel destroyUnmanagedCall:call]; - [channel destroyUnmanagedCall:call2]; -} - -- (void)testUnrefCallFromStaleChannel { - GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPoolWithDestroyDelay:kDestroyDelay]; - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCPooledChannel *channel = - (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - grpc_call *call = - [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - - [pool disconnectAllChannels]; - channel = (GRPCPooledChannel *)[pool channelWithHost:kDummyHost callOptions:options]; - - grpc_call *call2 = - [channel unmanagedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; - // Test unref the call of a stale channel will not cause the current channel going into timed - // destroy state - XCTAssertNotNil(channel.wrappedChannel); - GRPCChannel *wrappedChannel = channel.wrappedChannel; - [channel destroyUnmanagedCall:call]; - XCTAssertNotNil(channel.wrappedChannel); - XCTAssertEqual(wrappedChannel, channel.wrappedChannel); - // Test unref the call of the current channel will cause the channel going into timed destroy - // state - [channel destroyUnmanagedCall:call2]; - XCTAssertNil(channel.wrappedChannel); + XCTAssertNotNil(channel1); + XCTAssertNotNil(channel2); + XCTAssertNotNil(channel3); + XCTAssertNotNil(channel4); + XCTAssertEqual(channel1, channel2); + XCTAssertNotEqual(channel1, channel3); + XCTAssertNotEqual(channel1, channel4); + XCTAssertNotEqual(channel3, channel4); } @end diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 55474490926..ee7f8b6fddb 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -22,82 +22,10 @@ #import "../../GRPCClient/private/GRPCChannel.h" #import "../../GRPCClient/private/GRPCChannelPool.h" #import "../../GRPCClient/private/GRPCCompletionQueue.h" +#import "../../GRPCClient/private/GRPCWrappedCall.h" -/* -#define TEST_TIMEOUT 8 - -@interface GRPCChannelFake : NSObject - -- (instancetype)initWithCreateExpectation:(XCTestExpectation *)createExpectation - unrefExpectation:(XCTestExpectation *)unrefExpectation; - -- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path - completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions; - -- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall; - -@end - -@implementation GRPCChannelFake { - __weak XCTestExpectation *_createExpectation; - __weak XCTestExpectation *_unrefExpectation; - long _grpcCallCounter; -} - -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration -*)channelConfiguration { return nil; -} - -- (instancetype)initWithCreateExpectation:(XCTestExpectation *)createExpectation - unrefExpectation:(XCTestExpectation *)unrefExpectation { - if ((self = [super init])) { - _createExpectation = createExpectation; - _unrefExpectation = unrefExpectation; - _grpcCallCounter = 0; - } - return self; -} - -- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path - completionQueue:(GRPCCompletionQueue *)queue - callOptions:(GRPCCallOptions *)callOptions { - if (_createExpectation) [_createExpectation fulfill]; - return (grpc_call *)(++_grpcCallCounter); -} - -- (void)destroyUnmanagedCall:(grpc_call *)unmanagedCall { - if (_unrefExpectation) [_unrefExpectation fulfill]; -} - -@end - -@interface GRPCChannelPoolFake : NSObject - -- (instancetype)initWithDelayedDestroyExpectation:(XCTestExpectation *)delayedDestroyExpectation; - -- (GRPCChannel *)rawChannelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; - -- (void)delayedDestroyChannel; - -@end - -@implementation GRPCChannelPoolFake { - __weak XCTestExpectation *_delayedDestroyExpectation; -} - -- (instancetype)initWithDelayedDestroyExpectation:(XCTestExpectation *)delayedDestroyExpectation { - if ((self = [super init])) { - _delayedDestroyExpectation = delayedDestroyExpectation; - } - return self; -} - -- (void)delayedDestroyChannel { - if (_delayedDestroyExpectation) [_delayedDestroyExpectation fulfill]; -} - -@end */ +static NSString *kDummyHost = @"dummy.host"; +static NSString *kDummyPath = @"/dummy/path"; @interface ChannelTests : XCTestCase @@ -109,4 +37,84 @@ grpc_init(); } +- (void)testPooledChannelCreatingChannel { + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost + callOptions:options]; + GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + (void)wrappedCall; +} + +- (void)testTimedDestroyChannel { + const NSTimeInterval kDestroyDelay = 1.0; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost + callOptions:options]; + GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config + destroyDelay:kDestroyDelay]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + GRPCWrappedCall *wrappedCall; + GRPCChannel *wrappedChannel; + @autoreleasepool { + wrappedCall = [channel wrappedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + + // Unref and ref channel immediately; expect using the same raw channel. + wrappedChannel = channel.wrappedChannel; + + wrappedCall = nil; + wrappedCall = [channel wrappedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertEqual(channel.wrappedChannel, wrappedChannel); + + // Unref and ref channel after destroy delay; expect a new raw channel. + wrappedCall = nil; + } + sleep(kDestroyDelay + 1); + XCTAssertNil(channel.wrappedChannel); + wrappedCall = [channel wrappedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); +} + +- (void)testDisconnect { + const NSTimeInterval kDestroyDelay = 1.0; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost + callOptions:options]; + GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config + destroyDelay:kDestroyDelay]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + + // Disconnect; expect wrapped channel to be dropped + [channel disconnect]; + XCTAssertNil(channel.wrappedChannel); + + // Create a new call and unref the old call; confirm that destroy of the old call does not make + // the channel disconnect, even after the destroy delay. + GRPCWrappedCall *wrappedCall2 = [channel wrappedCallWithPath:kDummyPath + completionQueue:cq + callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + GRPCChannel *wrappedChannel = channel.wrappedChannel; + wrappedCall = nil; + sleep(kDestroyDelay + 1); + XCTAssertNotNil(channel.wrappedChannel); + XCTAssertEqual(wrappedChannel, channel.wrappedChannel); + (void)wrappedCall2; +} + @end diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme index 8c8623d7b21..acae965bed0 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme @@ -37,11 +37,6 @@ BlueprintName = "ChannelTests" ReferencedContainer = "container:Tests.xcodeproj"> - - - - From f0fbee59326402e6c1f0a7c6a1f8899fd2b0025a Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 30 Nov 2018 23:24:59 +0100 Subject: [PATCH 0396/2143] Bazel 0.20.0 workspace fixes. --- WORKSPACE | 2 ++ bazel/grpc_deps.bzl | 35 +++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index a547c24cbe2..c1e63d86e50 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,6 +1,8 @@ workspace(name="com_github_grpc_grpc") load("//bazel:grpc_deps.bzl", "grpc_deps", "grpc_test_only_deps") +load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") + grpc_deps() grpc_test_only_deps() diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 86268178554..82aada24629 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -1,5 +1,8 @@ """Load dependencies needed to compile and test the grpc library as a 3rd-party consumer.""" +load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + def grpc_deps(): """Loads dependencies need to compile and test the grpc library.""" @@ -99,14 +102,14 @@ def grpc_deps(): ) if "boringssl" not in native.existing_rules(): - native.http_archive( + http_archive( name = "boringssl", # on the chromium-stable-with-bazel branch url = "https://boringssl.googlesource.com/boringssl/+archive/afc30d43eef92979b05776ec0963c9cede5fb80f.tar.gz", ) if "com_github_madler_zlib" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_madler_zlib", build_file = "@com_github_grpc_grpc//third_party:zlib.BUILD", strip_prefix = "zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f", @@ -114,14 +117,14 @@ def grpc_deps(): ) if "com_google_protobuf" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_google_protobuf", strip_prefix = "protobuf-48cb18e5c419ddd23d9badcfe4e9df7bde1979b2", url = "https://github.com/google/protobuf/archive/48cb18e5c419ddd23d9badcfe4e9df7bde1979b2.tar.gz", ) if "com_github_nanopb_nanopb" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_nanopb_nanopb", build_file = "@com_github_grpc_grpc//third_party:nanopb.BUILD", strip_prefix = "nanopb-f8ac463766281625ad710900479130c7fcb4d63b", @@ -129,7 +132,7 @@ def grpc_deps(): ) if "com_github_google_googletest" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_google_googletest", build_file = "@com_github_grpc_grpc//third_party:gtest.BUILD", strip_prefix = "googletest-ec44c6c1675c25b9827aacd08c02433cccde7780", @@ -137,14 +140,14 @@ def grpc_deps(): ) if "com_github_gflags_gflags" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_github_gflags_gflags", strip_prefix = "gflags-30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e", url = "https://github.com/gflags/gflags/archive/30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e.tar.gz", ) if "com_github_google_benchmark" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_google_benchmark", build_file = "@com_github_grpc_grpc//third_party:benchmark.BUILD", strip_prefix = "benchmark-9913418d323e64a0111ca0da81388260c2bbe1e9", @@ -152,7 +155,7 @@ def grpc_deps(): ) if "com_github_cares_cares" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_cares_cares", build_file = "@com_github_grpc_grpc//third_party:cares/cares.BUILD", strip_prefix = "c-ares-3be1924221e1326df520f8498d704a5c4c8d0cce", @@ -160,14 +163,14 @@ def grpc_deps(): ) if "com_google_absl" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_google_absl", strip_prefix = "abseil-cpp-cd95e71df6eaf8f2a282b1da556c2cf1c9b09207", url = "https://github.com/abseil/abseil-cpp/archive/cd95e71df6eaf8f2a282b1da556c2cf1c9b09207.tar.gz", ) if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_github_bazelbuild_bazeltoolchains", strip_prefix = "bazel-toolchains-280edaa6f93623074513d2b426068de42e62ea4d", urls = [ @@ -178,7 +181,7 @@ def grpc_deps(): ) if "io_opencensus_cpp" not in native.existing_rules(): - native.http_archive( + http_archive( name = "io_opencensus_cpp", strip_prefix = "opencensus-cpp-fdf0f308b1631bb4a942e32ba5d22536a6170274", url = "https://github.com/census-instrumentation/opencensus-cpp/archive/fdf0f308b1631bb4a942e32ba5d22536a6170274.tar.gz", @@ -200,7 +203,7 @@ def grpc_test_only_deps(): ) if "com_github_twisted_twisted" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_twisted_twisted", strip_prefix = "twisted-twisted-17.5.0", url = "https://github.com/twisted/twisted/archive/twisted-17.5.0.zip", @@ -208,7 +211,7 @@ def grpc_test_only_deps(): ) if "com_github_yaml_pyyaml" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_yaml_pyyaml", strip_prefix = "pyyaml-3.12", url = "https://github.com/yaml/pyyaml/archive/3.12.zip", @@ -216,7 +219,7 @@ def grpc_test_only_deps(): ) if "com_github_twisted_incremental" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_twisted_incremental", strip_prefix = "incremental-incremental-17.5.0", url = "https://github.com/twisted/incremental/archive/incremental-17.5.0.zip", @@ -224,7 +227,7 @@ def grpc_test_only_deps(): ) if "com_github_zopefoundation_zope_interface" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_zopefoundation_zope_interface", strip_prefix = "zope.interface-4.4.3", url = "https://github.com/zopefoundation/zope.interface/archive/4.4.3.zip", @@ -232,7 +235,7 @@ def grpc_test_only_deps(): ) if "com_github_twisted_constantly" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_twisted_constantly", strip_prefix = "constantly-15.1.0", url = "https://github.com/twisted/constantly/archive/15.1.0.zip", From b203ed3c071361826f3b24d940e6bfa1c3d19f81 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 30 Nov 2018 01:59:15 -0800 Subject: [PATCH 0397/2143] Cancel still-active c-ares queries after 10 seconds to avoid chance of deadlock --- include/grpc/impl/codegen/grpc_types.h | 5 ++ .../resolver/dns/c_ares/dns_resolver_ares.cc | 10 +++- .../dns/c_ares/grpc_ares_ev_driver.cc | 36 +++++++++++ .../resolver/dns/c_ares/grpc_ares_ev_driver.h | 1 + .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 12 ++-- .../resolver/dns/c_ares/grpc_ares_wrapper.h | 4 +- .../dns/c_ares/grpc_ares_wrapper_fallback.cc | 3 +- src/core/lib/iomgr/resolve_address.h | 2 +- .../dns_resolver_connectivity_test.cc | 2 +- .../resolvers/dns_resolver_cooldown_test.cc | 6 +- test/core/end2end/fuzzers/api_fuzzer.cc | 2 +- test/core/end2end/goaway_server_test.cc | 6 +- test/cpp/naming/cancel_ares_query_test.cc | 59 +++++++++++++++++-- 13 files changed, 126 insertions(+), 22 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index d1cc6af04fb..a9fb27946e0 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, 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 + * entirely. */ +#define GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS "grpc.dns_ares_query_timeout" /** \} */ /** Result of a grpc call. If the caller satisfies the prerequisites of a 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 90bc88961d9..4ebc2c8161c 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 @@ -122,6 +122,8 @@ class AresDnsResolver : public Resolver { char* service_config_json_ = nullptr; // has shutdown been initiated bool shutdown_initiated_ = false; + // timeout in milliseconds for active DNS queries + int query_timeout_ms_; }; AresDnsResolver::AresDnsResolver(const ResolverArgs& args) @@ -159,6 +161,11 @@ AresDnsResolver::AresDnsResolver(const ResolverArgs& args) grpc_combiner_scheduler(combiner())); GRPC_CLOSURE_INIT(&on_resolved_, OnResolvedLocked, this, grpc_combiner_scheduler(combiner())); + const grpc_arg* query_timeout_ms_arg = + grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS); + query_timeout_ms_ = grpc_channel_arg_get_integer( + query_timeout_ms_arg, + {GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, 0, INT_MAX}); } AresDnsResolver::~AresDnsResolver() { @@ -410,7 +417,8 @@ void AresDnsResolver::StartResolvingLocked() { pending_request_ = grpc_dns_lookup_ares_locked( dns_server_, name_to_resolve_, kDefaultPort, interested_parties_, &on_resolved_, &lb_addresses_, true /* check_grpclb */, - request_service_config_ ? &service_config_json_ : nullptr, combiner()); + request_service_config_ ? &service_config_json_ : nullptr, + query_timeout_ms_, combiner()); last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc index fdbd07ebf51..f42b1e309df 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -33,6 +33,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/timer.h" typedef struct fd_node { /** the owner of this fd node */ @@ -76,6 +77,12 @@ struct grpc_ares_ev_driver { grpc_ares_request* request; /** Owned by the ev_driver. Creates new GrpcPolledFd's */ grpc_core::UniquePtr polled_fd_factory; + /** query timeout in milliseconds */ + int query_timeout_ms; + /** alarm to cancel active queries */ + grpc_timer query_timeout; + /** cancels queries on a timeout */ + grpc_closure on_timeout_locked; }; static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver); @@ -116,8 +123,11 @@ static void fd_node_shutdown_locked(fd_node* fdn, const char* reason) { } } +static void on_timeout_locked(void* arg, grpc_error* error); + grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set, + int query_timeout_ms, grpc_combiner* combiner, grpc_ares_request* request) { *ev_driver = grpc_core::New(); @@ -146,6 +156,9 @@ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, grpc_core::NewGrpcPolledFdFactory((*ev_driver)->combiner); (*ev_driver) ->polled_fd_factory->ConfigureAresChannelLocked((*ev_driver)->channel); + GRPC_CLOSURE_INIT(&(*ev_driver)->on_timeout_locked, on_timeout_locked, + *ev_driver, grpc_combiner_scheduler(combiner)); + (*ev_driver)->query_timeout_ms = query_timeout_ms; return GRPC_ERROR_NONE; } @@ -155,6 +168,7 @@ void grpc_ares_ev_driver_on_queries_complete_locked( // is working, grpc_ares_notify_on_event_locked will shut down the // fds; if it's not working, there are no fds to shut down. ev_driver->shutting_down = true; + grpc_timer_cancel(&ev_driver->query_timeout); grpc_ares_ev_driver_unref(ev_driver); } @@ -185,6 +199,17 @@ static fd_node* pop_fd_node_locked(fd_node** head, ares_socket_t as) { return nullptr; } +static void on_timeout_locked(void* arg, grpc_error* error) { + grpc_ares_ev_driver* driver = static_cast(arg); + GRPC_CARES_TRACE_LOG( + "ev_driver=%p on_timeout_locked. driver->shutting_down=%d. err=%s", + driver, driver->shutting_down, grpc_error_string(error)); + if (!driver->shutting_down && error == GRPC_ERROR_NONE) { + grpc_ares_ev_driver_shutdown_locked(driver); + } + grpc_ares_ev_driver_unref(driver); +} + static void on_readable_locked(void* arg, grpc_error* error) { fd_node* fdn = static_cast(arg); grpc_ares_ev_driver* ev_driver = fdn->ev_driver; @@ -314,6 +339,17 @@ void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) { if (!ev_driver->working) { ev_driver->working = true; grpc_ares_notify_on_event_locked(ev_driver); + grpc_millis timeout = + ev_driver->query_timeout_ms == 0 + ? GRPC_MILLIS_INF_FUTURE + : ev_driver->query_timeout_ms + grpc_core::ExecCtx::Get()->Now(); + GRPC_CARES_TRACE_LOG( + "ev_driver=%p grpc_ares_ev_driver_start_locked. timeout in %" PRId64 + " ms", + ev_driver, timeout); + grpc_ares_ev_driver_ref(ev_driver); + grpc_timer_init(&ev_driver->query_timeout, timeout, + &ev_driver->on_timeout_locked); } } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h index 671c537fe72..b8cefd9470e 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h @@ -43,6 +43,7 @@ ares_channel* grpc_ares_ev_driver_get_channel_locked( created successfully. */ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set, + int query_timeout_ms, grpc_combiner* combiner, grpc_ares_request* request); 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 582e2203fc7..55715869b63 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 @@ -359,7 +359,7 @@ done: void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( grpc_ares_request* r, const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, - bool check_grpclb, grpc_combiner* combiner) { + bool check_grpclb, int query_timeout_ms, grpc_combiner* combiner) { grpc_error* error = GRPC_ERROR_NONE; grpc_ares_hostbyname_request* hr = nullptr; ares_channel* channel = nullptr; @@ -388,7 +388,7 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( port = gpr_strdup(default_port); } error = grpc_ares_ev_driver_create_locked(&r->ev_driver, interested_parties, - combiner, r); + query_timeout_ms, combiner, r); if (error != GRPC_ERROR_NONE) goto error_cleanup; channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver); // If dns_server is specified, use it. @@ -522,7 +522,7 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner) { + int query_timeout_ms, grpc_combiner* combiner) { grpc_ares_request* r = static_cast(gpr_zalloc(sizeof(grpc_ares_request))); r->ev_driver = nullptr; @@ -546,7 +546,7 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( // Look up name using c-ares lib. grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( r, dns_server, name, default_port, interested_parties, check_grpclb, - combiner); + query_timeout_ms, combiner); return r; } @@ -554,6 +554,7 @@ grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) { @@ -648,7 +649,8 @@ static void grpc_resolve_address_invoke_dns_lookup_ares_locked( r->ares_request = grpc_dns_lookup_ares_locked( nullptr /* dns_server */, r->name, r->default_port, r->interested_parties, &r->on_dns_lookup_done_locked, &r->lb_addrs, false /* check_grpclb */, - nullptr /* service_config_json */, r->combiner); + nullptr /* service_config_json */, GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, + r->combiner); } static void grpc_resolve_address_ares_impl(const char* name, diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h index a1231cc4e0d..9acef1d0ca9 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -26,6 +26,8 @@ #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/resolve_address.h" +#define GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS 10000 + extern grpc_core::TraceFlag grpc_trace_cares_address_sorting; extern grpc_core::TraceFlag grpc_trace_cares_resolver; @@ -60,7 +62,7 @@ extern grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addresses, bool check_grpclb, - char** service_config_json, grpc_combiner* combiner); + char** service_config_json, int query_timeout_ms, grpc_combiner* combiner); /* Cancel the pending grpc_ares_request \a request */ extern void (*grpc_cancel_ares_request_locked)(grpc_ares_request* request); diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc index 9f293c1ac07..fc78b183044 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc @@ -30,7 +30,7 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner) { + int query_timeout_ms, grpc_combiner* combiner) { return NULL; } @@ -38,6 +38,7 @@ grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {} diff --git a/src/core/lib/iomgr/resolve_address.h b/src/core/lib/iomgr/resolve_address.h index 6afe94a7a92..7016ffc31aa 100644 --- a/src/core/lib/iomgr/resolve_address.h +++ b/src/core/lib/iomgr/resolve_address.h @@ -65,7 +65,7 @@ void grpc_set_resolver_impl(grpc_address_resolver_vtable* vtable); /* Asynchronously resolve addr. Use default_port if a port isn't designated in addr, otherwise use the port in addr. */ -/* TODO(ctiller): add a timeout here */ +/* TODO(apolcyn): add a timeout here */ void grpc_resolve_address(const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, 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 eb5a9117484..cc041ac7f3d 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -64,7 +64,7 @@ static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner) { + int query_timeout_ms, grpc_combiner* combiner) { gpr_mu_lock(&g_mu); GPR_ASSERT(0 == strcmp("test", addr)); grpc_error* error = GRPC_ERROR_NONE; 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..51fcc0dec67 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -41,7 +41,7 @@ static grpc_ares_request* (*g_default_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner); + int query_timeout_ms, grpc_combiner* combiner); // Counter incremented by test_resolve_address_impl indicating the number of // times a system-level resolution has happened. @@ -91,10 +91,10 @@ static grpc_ares_request* test_dns_lookup_ares_locked( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner) { + int query_timeout_ms, grpc_combiner* combiner) { grpc_ares_request* result = g_default_dns_lookup_ares_locked( dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, addrs, - check_grpclb, service_config_json, combiner); + check_grpclb, service_config_json, query_timeout_ms, combiner); ++g_resolution_count; static grpc_millis last_resolution_time = 0; if (last_resolution_time == 0) { diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index e97a544e12c..9b6eddee6e1 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -378,7 +378,7 @@ grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner) { + int query_timeout, grpc_combiner* combiner) { addr_req* r = static_cast(gpr_malloc(sizeof(*r))); r->addr = gpr_strdup(addr); r->on_done = on_done; diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 3f1c5596ad9..6369caf0d1b 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -48,7 +48,7 @@ static grpc_ares_request* (*iomgr_dns_lookup_ares_locked)( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addresses, bool check_grpclb, - char** service_config_json, grpc_combiner* combiner); + char** service_config_json, int query_timeout_ms, grpc_combiner* combiner); static void (*iomgr_cancel_ares_request_locked)(grpc_ares_request* request); @@ -104,11 +104,11 @@ static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner) { + int query_timeout_ms, grpc_combiner* combiner) { if (0 != strcmp(addr, "test")) { return iomgr_dns_lookup_ares_locked( dns_server, addr, default_port, interested_parties, on_done, lb_addrs, - check_grpclb, service_config_json, combiner); + check_grpclb, service_config_json, query_timeout_ms, combiner); } grpc_error* error = GRPC_ERROR_NONE; diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index dec7c171dc0..4c7a7c37357 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -260,8 +260,15 @@ TEST(CancelDuringAresQuery, TestFdsAreDeletedFromPollsetSet) { grpc_pollset_set_destroy(fake_other_pollset_set); } -TEST(CancelDuringAresQuery, - TestHitDeadlineAndDestroyChannelDuringAresResolutionIsGraceful) { +// Settings for TestCancelDuringActiveQuery test +typedef enum { + NONE, + SHORT, + ZERO, +} cancellation_test_query_timeout_setting; + +void TestCancelDuringActiveQuery( + cancellation_test_query_timeout_setting query_timeout_setting) { // Start up fake non responsive DNS server int fake_dns_port = grpc_pick_unused_port_or_die(); FakeNonResponsiveDNSServer fake_dns_server(fake_dns_port); @@ -271,9 +278,33 @@ TEST(CancelDuringAresQuery, &client_target, "dns://[::1]:%d/dont-care-since-wont-be-resolved.test.com:1234", fake_dns_port)); + gpr_log(GPR_DEBUG, "TestCancelActiveDNSQuery. query timeout setting: %d", + query_timeout_setting); + grpc_channel_args* client_args = nullptr; + grpc_status_code expected_status_code = GRPC_STATUS_OK; + if (query_timeout_setting == NONE) { + expected_status_code = GRPC_STATUS_DEADLINE_EXCEEDED; + client_args = nullptr; + } else if (query_timeout_setting == SHORT) { + expected_status_code = GRPC_STATUS_UNAVAILABLE; + grpc_arg arg; + arg.type = GRPC_ARG_INTEGER; + arg.key = const_cast(GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS); + arg.value.integer = + 1; // Set this shorter than the call deadline so that it goes off. + client_args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + } else if (query_timeout_setting == ZERO) { + expected_status_code = GRPC_STATUS_DEADLINE_EXCEEDED; + grpc_arg arg; + arg.type = GRPC_ARG_INTEGER; + arg.key = const_cast(GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS); + arg.value.integer = 0; // Set this to zero to disable query timeouts. + client_args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + } else { + abort(); + } grpc_channel* client = - grpc_insecure_channel_create(client_target, - /* client_args */ nullptr, nullptr); + grpc_insecure_channel_create(client_target, client_args, nullptr); gpr_free(client_target); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); cq_verifier* cqv = cq_verifier_create(cq); @@ -325,8 +356,9 @@ TEST(CancelDuringAresQuery, EXPECT_EQ(GRPC_CALL_OK, error); CQ_EXPECT_COMPLETION(cqv, Tag(1), 1); cq_verify(cqv); - EXPECT_EQ(status, GRPC_STATUS_DEADLINE_EXCEEDED); + EXPECT_EQ(status, expected_status_code); // Teardown + grpc_channel_args_destroy(client_args); grpc_slice_unref(details); gpr_free((void*)error_string); grpc_metadata_array_destroy(&initial_metadata_recv); @@ -338,6 +370,23 @@ TEST(CancelDuringAresQuery, EndTest(client, cq); } +TEST(CancelDuringAresQuery, + TestHitDeadlineAndDestroyChannelDuringAresResolutionIsGraceful) { + TestCancelDuringActiveQuery(NONE /* don't set query timeouts */); +} + +TEST( + CancelDuringAresQuery, + TestHitDeadlineAndDestroyChannelDuringAresResolutionWithQueryTimeoutIsGraceful) { + TestCancelDuringActiveQuery(SHORT /* set short query timeout */); +} + +TEST( + CancelDuringAresQuery, + TestHitDeadlineAndDestroyChannelDuringAresResolutionWithZeroQueryTimeoutIsGraceful) { + TestCancelDuringActiveQuery(ZERO /* disable query timeouts */); +} + } // namespace int main(int argc, char** argv) { From 19b3ca5689b9477235fe93d913ca9f9a6d54de3d Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 30 Nov 2018 15:26:56 -0800 Subject: [PATCH 0398/2143] Clang-format --- test/core/util/test_config.cc | 6 +++--- test/core/util/test_config.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index 115d89b6b42..fe80bb2d4d0 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -401,11 +401,11 @@ void grpc_test_init(int argc, char** argv) { namespace grpc { namespace testing { -TestEnvironment::TestEnvironment(int argc, char **argv) { +TestEnvironment::TestEnvironment(int argc, char** argv) { grpc_test_init(argc, argv); } TestEnvironment::~TestEnvironment() {} -} // namespace testing -} // namespace grpc +} // namespace testing +} // namespace grpc diff --git a/test/core/util/test_config.h b/test/core/util/test_config.h index a8a2d32aaf0..112af3176f9 100644 --- a/test/core/util/test_config.h +++ b/test/core/util/test_config.h @@ -46,12 +46,12 @@ namespace testing { // A TestEnvironment object should be alive in the main function of a test. It // provides test init and shutdown inside. class TestEnvironment { -public: - TestEnvironment(int argc, char **argv); + public: + TestEnvironment(int argc, char** argv); ~TestEnvironment(); }; -} // namespace testing -} // namespace grpc +} // namespace testing +} // namespace grpc #endif /* GRPC_TEST_CORE_UTIL_TEST_CONFIG_H */ From 8ace4e16dfca8224d7ce4de60d046059127595aa Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 30 Nov 2018 11:57:01 -0800 Subject: [PATCH 0399/2143] disable some add some --- test/cpp/microbenchmarks/BUILD | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 671e7f1096a..84ea386870d 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -53,11 +53,12 @@ grpc_cc_test( uses_polling = False, ) -grpc_cc_test( +# TODO(https://github.com/grpc/grpc/pull/16882): make this a test target +# right now it OOMs +grpc_cc_binary( name = "bm_arena", srcs = ["bm_arena.cc"], deps = [":helpers"], - uses_polling = False, ) grpc_cc_test( @@ -67,7 +68,9 @@ grpc_cc_test( uses_polling = False, ) -grpc_cc_test( +# TODO(https://github.com/grpc/grpc/pull/16882): make this a test target +# right now it fails UBSAN +grpc_cc_binary( name = "bm_call_create", srcs = ["bm_call_create.cc"], deps = [":helpers"], @@ -162,6 +165,18 @@ grpc_cc_test( uses_polling = False, ) +grpc_cc_test( + name = "bm_chttp2_transport", + srcs = ["bm_chttp2_transport.cc"], + deps = [":helpers"], +) + +grpc_cc_test( + name = "bm_pollset", + srcs = ["bm_pollset.cc"], + deps = [":helpers"], +) + grpc_cc_binary( name = "bm_opencensus_plugin", testonly = 1, From 237cc52ffd58c6f46a68d5662fd69cac05b52ec2 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Sat, 1 Dec 2018 00:42:34 +0100 Subject: [PATCH 0400/2143] Fix sanity checker. --- tools/run_tests/sanity/check_bazel_workspace.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/run_tests/sanity/check_bazel_workspace.py b/tools/run_tests/sanity/check_bazel_workspace.py index 35da88d70e6..1486d0bd277 100755 --- a/tools/run_tests/sanity/check_bazel_workspace.py +++ b/tools/run_tests/sanity/check_bazel_workspace.py @@ -111,6 +111,8 @@ bazel_file += '\ngrpc_deps()\n' bazel_file += '\ngrpc_test_only_deps()\n' build_rules = { 'native': eval_state, + 'http_archive': lambda **args: eval_state.http_archive(**args), + 'load': lambda a, b: None, } exec bazel_file in build_rules for name in _GRPC_DEP_NAMES: @@ -150,6 +152,8 @@ for name in _GRPC_DEP_NAMES: names_and_urls_with_overridden_name, overridden_name=name) rules = { 'native': state, + 'http_archive': lambda **args: state.http_archive(**args), + 'load': lambda a, b: None, } exec bazel_file in rules assert name not in names_and_urls_with_overridden_name.keys() From 2a0c0d7ad6a1256ef6c0398e1900eca2be077a51 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 5 Nov 2018 14:39:44 -0800 Subject: [PATCH 0401/2143] Streaming API for callback servers --- include/grpcpp/impl/codegen/byte_buffer.h | 8 +- include/grpcpp/impl/codegen/callback_common.h | 19 +- include/grpcpp/impl/codegen/server_callback.h | 774 +++++++++++++++++- include/grpcpp/impl/codegen/server_context.h | 21 +- src/compiler/cpp_generator.cc | 69 +- src/cpp/server/server_cc.cc | 7 +- src/cpp/server/server_context.cc | 47 +- test/cpp/codegen/compiler_test_golden | 56 +- test/cpp/end2end/end2end_test.cc | 90 +- test/cpp/end2end/test_service_impl.cc | 314 ++++++- test/cpp/end2end/test_service_impl.h | 21 +- 11 files changed, 1261 insertions(+), 165 deletions(-) diff --git a/include/grpcpp/impl/codegen/byte_buffer.h b/include/grpcpp/impl/codegen/byte_buffer.h index abba5549b86..53ecb53371b 100644 --- a/include/grpcpp/impl/codegen/byte_buffer.h +++ b/include/grpcpp/impl/codegen/byte_buffer.h @@ -45,8 +45,10 @@ template class RpcMethodHandler; template class ServerStreamingHandler; -template +template class CallbackUnaryHandler; +template +class CallbackServerStreamingHandler; template class ErrorMethodHandler; template @@ -156,8 +158,10 @@ class ByteBuffer final { friend class internal::RpcMethodHandler; template friend class internal::ServerStreamingHandler; - template + template friend class internal::CallbackUnaryHandler; + template + friend class ::grpc::internal::CallbackServerStreamingHandler; template friend class internal::ErrorMethodHandler; template diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index f7a24204dc2..a3c8c41246c 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -32,6 +32,8 @@ namespace grpc { namespace internal { /// An exception-safe way of invoking a user-specified callback function +// TODO(vjpai): decide whether it is better for this to take a const lvalue +// parameter or an rvalue parameter, or if it even matters template void CatchingCallback(Func&& func, Args&&... args) { #if GRPC_ALLOW_EXCEPTIONS @@ -45,6 +47,20 @@ void CatchingCallback(Func&& func, Args&&... args) { #endif // GRPC_ALLOW_EXCEPTIONS } +template +ReturnType* CatchingReactorCreator(Func&& func, Args&&... args) { +#if GRPC_ALLOW_EXCEPTIONS + try { + return func(std::forward(args)...); + } catch (...) { + // fail the RPC, don't crash the library + return nullptr; + } +#else // GRPC_ALLOW_EXCEPTIONS + return func(std::forward(args)...); +#endif // GRPC_ALLOW_EXCEPTIONS +} + // The contract on these tags is that they are single-shot. They must be // constructed and then fired at exactly one point. There is no expectation // that they can be reused without reconstruction. @@ -185,8 +201,9 @@ class CallbackWithSuccessTag void* ignored = ops_; // Allow a "false" return value from FinalizeResult to silence the // callback, just as it silences a CQ tag in the async cases + auto* ops = ops_; bool do_callback = ops_->FinalizeResult(&ignored, &ok); - GPR_CODEGEN_ASSERT(ignored == ops_); + GPR_CODEGEN_ASSERT(ignored == ops); if (do_callback) { CatchingCallback(func_, ok); diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index b866fc16dcf..1854f6ef2f5 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -19,7 +19,9 @@ #ifndef GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_H #define GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_H +#include #include +#include #include #include @@ -32,19 +34,33 @@ namespace grpc { -// forward declarations +// Declare base class of all reactors as internal namespace internal { -template -class CallbackUnaryHandler; + +class ServerReactor { + public: + virtual ~ServerReactor() = default; + virtual void OnDone() {} + virtual void OnCancel() {} +}; + } // namespace internal namespace experimental { +// Forward declarations +template +class ServerReadReactor; +template +class ServerWriteReactor; +template +class ServerBidiReactor; + // For unary RPCs, the exposed controller class is only an interface // and the actual implementation is an internal class. class ServerCallbackRpcController { public: - virtual ~ServerCallbackRpcController() {} + virtual ~ServerCallbackRpcController() = default; // The method handler must call this function when it is done so that // the library knows to free its resources @@ -55,18 +71,193 @@ class ServerCallbackRpcController { virtual void SendInitialMetadata(std::function) = 0; }; +// NOTE: The actual streaming object classes are provided +// as API only to support mocking. There are no implementations of +// these class interfaces in the API. +template +class ServerCallbackReader { + public: + virtual ~ServerCallbackReader() {} + virtual void Finish(Status s) = 0; + virtual void SendInitialMetadata() = 0; + virtual void Read(Request* msg) = 0; + + protected: + template + void BindReactor(ServerReadReactor* reactor) { + reactor->BindReader(this); + } +}; + +template +class ServerCallbackWriter { + public: + virtual ~ServerCallbackWriter() {} + + virtual void Finish(Status s) = 0; + virtual void SendInitialMetadata() = 0; + virtual void Write(const Response* msg, WriteOptions options) = 0; + virtual void WriteAndFinish(const Response* msg, WriteOptions options, + Status s) { + // Default implementation that can/should be overridden + Write(msg, std::move(options)); + Finish(std::move(s)); + }; + + protected: + template + void BindReactor(ServerWriteReactor* reactor) { + reactor->BindWriter(this); + } +}; + +template +class ServerCallbackReaderWriter { + public: + virtual ~ServerCallbackReaderWriter() {} + + virtual void Finish(Status s) = 0; + virtual void SendInitialMetadata() = 0; + virtual void Read(Request* msg) = 0; + virtual void Write(const Response* msg, WriteOptions options) = 0; + virtual void WriteAndFinish(const Response* msg, WriteOptions options, + Status s) { + // Default implementation that can/should be overridden + Write(msg, std::move(options)); + Finish(std::move(s)); + }; + + protected: + void BindReactor(ServerBidiReactor* reactor) { + reactor->BindStream(this); + } +}; + +// 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 +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) {} + + 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)); + } + void StartWriteAndFinish(const Response* msg, WriteOptions options, + Status s) { + stream_->WriteAndFinish(msg, std::move(options), std::move(s)); + } + void StartWriteLast(const Response* msg, WriteOptions options) { + StartWrite(msg, std::move(options.set_last_message())); + } + void Finish(Status s) { stream_->Finish(std::move(s)); } + + private: + friend class ServerCallbackReaderWriter; + void BindStream(ServerCallbackReaderWriter* stream) { + stream_ = stream; + } + + ServerCallbackReaderWriter* stream_; +}; + +template +class ServerReadReactor : public internal::ServerReactor { + public: + ~ServerReadReactor() = default; + virtual void OnStarted(ServerContext*, Response* resp) {} + 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; } + + ServerCallbackReader* reader_; +}; + +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) {} + + 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 StartWriteAndFinish(const Response* msg, WriteOptions options, + Status s) { + writer_->WriteAndFinish(msg, std::move(options), std::move(s)); + } + void StartWriteLast(const Response* msg, WriteOptions options) { + StartWrite(msg, std::move(options.set_last_message())); + } + void Finish(Status s) { writer_->Finish(std::move(s)); } + + private: + friend class ServerCallbackWriter; + void BindWriter(ServerCallbackWriter* writer) { writer_ = writer; } + + ServerCallbackWriter* writer_; +}; + } // namespace experimental namespace internal { -template +template +class UnimplementedReadReactor + : public experimental::ServerReadReactor { + public: + void OnDone() override { delete this; } + void OnStarted(ServerContext*, Response*) override { + this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); + } +}; + +template +class UnimplementedWriteReactor + : public experimental::ServerWriteReactor { + public: + void OnDone() override { delete this; } + void OnStarted(ServerContext*, const Request*) override { + this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); + } +}; + +template +class UnimplementedBidiReactor + : public experimental::ServerBidiReactor { + public: + void OnDone() override { delete this; } + void OnStarted(ServerContext*) override { + this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); + } +}; + +template class CallbackUnaryHandler : public MethodHandler { public: CallbackUnaryHandler( std::function - func, - ServiceType* service) + func) : func_(func) {} void RunHandler(const HandlerParameter& param) final { // Arena allocate a controller structure (that includes request/response) @@ -81,9 +272,8 @@ class CallbackUnaryHandler : public MethodHandler { if (status.ok()) { // Call the actual function handler and expect the user to call finish - CatchingCallback(std::move(func_), param.server_context, - controller->request(), controller->response(), - controller); + CatchingCallback(func_, param.server_context, controller->request(), + controller->response(), controller); } else { // if deserialization failed, we need to fail the call controller->Finish(status); @@ -117,79 +307,579 @@ class CallbackUnaryHandler : public MethodHandler { : public experimental::ServerCallbackRpcController { public: void Finish(Status s) override { - finish_tag_.Set( - call_.call(), - [this](bool) { - grpc_call* call = call_.call(); - auto call_requester = std::move(call_requester_); - this->~ServerCallbackRpcControllerImpl(); // explicitly call - // destructor - g_core_codegen_interface->grpc_call_unref(call); - call_requester(); - }, - &finish_buf_); + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); if (!ctx_->sent_initial_metadata_) { - finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_, + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, ctx_->initial_metadata_flags()); if (ctx_->compression_level_set()) { - finish_buf_.set_compression_level(ctx_->compression_level()); + finish_ops_.set_compression_level(ctx_->compression_level()); } ctx_->sent_initial_metadata_ = true; } // The response is dropped if the status is not OK. if (s.ok()) { - finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_buf_.SendMessage(resp_)); + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, + finish_ops_.SendMessage(resp_)); } else { - finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, s); + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); } - finish_buf_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_buf_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); } void SendInitialMetadata(std::function f) override { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_tag_.Set(call_.call(), std::move(f), &meta_buf_); - meta_buf_.SendInitialMetadata(&ctx_->initial_metadata_, + callbacks_outstanding_++; + // TODO(vjpai): Consider taking f as a move-capture if we adopt C++14 + // and if performance of this operation matters + meta_tag_.Set(call_.call(), + [this, f](bool ok) { + f(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, ctx_->initial_metadata_flags()); if (ctx_->compression_level_set()) { - meta_buf_.set_compression_level(ctx_->compression_level()); + meta_ops_.set_compression_level(ctx_->compression_level()); } ctx_->sent_initial_metadata_ = true; - meta_buf_.set_core_cq_tag(&meta_tag_); - call_.PerformOps(&meta_buf_); + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); } private: - template - friend class CallbackUnaryHandler; + friend class CallbackUnaryHandler; ServerCallbackRpcControllerImpl(ServerContext* ctx, Call* call, - RequestType* req, + const RequestType* req, std::function call_requester) : ctx_(ctx), call_(*call), req_(req), - call_requester_(std::move(call_requester)) {} + call_requester_(std::move(call_requester)) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, nullptr); + } ~ServerCallbackRpcControllerImpl() { req_->~RequestType(); } - RequestType* request() { return req_; } + const RequestType* request() { return req_; } ResponseType* response() { return &resp_; } - CallOpSet meta_buf_; + void MaybeDone() { + if (--callbacks_outstanding_ == 0) { + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + this->~ServerCallbackRpcControllerImpl(); // explicitly call destructor + g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + CallOpSet meta_ops_; CallbackWithSuccessTag meta_tag_; CallOpSet - finish_buf_; + finish_ops_; CallbackWithSuccessTag finish_tag_; ServerContext* ctx_; Call call_; - RequestType* req_; + const RequestType* req_; ResponseType resp_; std::function call_requester_; + std::atomic_int callbacks_outstanding_{ + 2}; // reserve for Finish and CompletionOp + }; +}; + +template +class CallbackClientStreamingHandler : public MethodHandler { + public: + CallbackClientStreamingHandler( + std::function< + experimental::ServerReadReactor*()> + func) + : func_(std::move(func)) {} + void RunHandler(const HandlerParameter& param) final { + // Arena allocate a reader structure (that includes response) + g_core_codegen_interface->grpc_call_ref(param.call->call()); + + experimental::ServerReadReactor* reactor = + param.status.ok() + ? CatchingReactorCreator< + experimental::ServerReadReactor>( + func_) + : nullptr; + + if (reactor == nullptr) { + // if deserialization or reactor creator failed, we need to fail the call + reactor = new UnimplementedReadReactor; + } + + auto* reader = new (g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackReaderImpl))) + ServerCallbackReaderImpl(param.server_context, param.call, + std::move(param.call_requester), reactor); + + reader->BindReactor(reactor); + reactor->OnStarted(param.server_context, reader->response()); + reader->MaybeDone(); + } + + private: + std::function*()> + func_; + + class ServerCallbackReaderImpl + : public experimental::ServerCallbackReader { + public: + void Finish(Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // The response is dropped if the status is not OK. + if (s.ok()) { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, + finish_ops_.SendMessage(resp_)); + } else { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + } + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_++; + meta_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnSendInitialMetadataDone(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + void Read(RequestType* req) override { + callbacks_outstanding_++; + read_ops_.RecvMessage(req); + call_.PerformOps(&read_ops_); + } + + private: + friend class CallbackClientStreamingHandler; + + ServerCallbackReaderImpl( + ServerContext* ctx, Call* call, std::function call_requester, + experimental::ServerReadReactor* reactor) + : ctx_(ctx), + call_(*call), + call_requester_(std::move(call_requester)), + reactor_(reactor) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeDone(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + } + + ~ServerCallbackReaderImpl() {} + + ResponseType* response() { return &resp_; } + + void MaybeDone() { + if (--callbacks_outstanding_ == 0) { + reactor_->OnDone(); + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + this->~ServerCallbackReaderImpl(); // explicitly call destructor + g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + CallOpSet meta_ops_; + CallbackWithSuccessTag meta_tag_; + CallOpSet + finish_ops_; + CallbackWithSuccessTag finish_tag_; + CallOpSet> read_ops_; + CallbackWithSuccessTag read_tag_; + + ServerContext* ctx_; + Call call_; + ResponseType resp_; + std::function call_requester_; + experimental::ServerReadReactor* reactor_; + std::atomic_int callbacks_outstanding_{ + 3}; // reserve for OnStarted, Finish, and CompletionOp + }; +}; + +template +class CallbackServerStreamingHandler : public MethodHandler { + public: + CallbackServerStreamingHandler( + std::function< + experimental::ServerWriteReactor*()> + func) + : func_(std::move(func)) {} + void RunHandler(const HandlerParameter& param) final { + // Arena allocate a writer structure + g_core_codegen_interface->grpc_call_ref(param.call->call()); + + experimental::ServerWriteReactor* reactor = + param.status.ok() + ? CatchingReactorCreator< + experimental::ServerWriteReactor>( + func_) + : nullptr; + + if (reactor == nullptr) { + // if deserialization or reactor creator failed, we need to fail the call + reactor = new UnimplementedWriteReactor; + } + + auto* writer = new (g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackWriterImpl))) + ServerCallbackWriterImpl(param.server_context, param.call, + static_cast(param.request), + std::move(param.call_requester), reactor); + writer->BindReactor(reactor); + reactor->OnStarted(param.server_context, writer->request()); + writer->MaybeDone(); + } + + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, + Status* status) final { + ByteBuffer buf; + buf.set_buffer(req); + auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc( + call, sizeof(RequestType))) RequestType(); + *status = SerializationTraits::Deserialize(&buf, request); + buf.Release(); + if (status->ok()) { + return request; + } + request->~RequestType(); + return nullptr; + } + + private: + std::function*()> + func_; + + class ServerCallbackWriterImpl + : public experimental::ServerCallbackWriter { + public: + void Finish(Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + finish_ops_.set_core_cq_tag(&finish_tag_); + + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_++; + meta_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnSendInitialMetadataDone(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + void Write(const ResponseType* resp, WriteOptions options) override { + callbacks_outstanding_++; + if (options.is_last_message()) { + options.set_buffer_hint(); + } + if (!ctx_->sent_initial_metadata_) { + write_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + write_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*resp, options).ok()); + call_.PerformOps(&write_ops_); + } + + void WriteAndFinish(const ResponseType* resp, WriteOptions options, + Status s) override { + // This combines the write into the finish callback + // Don't send any message if the status is bad + if (s.ok()) { + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(*resp, options).ok()); + } + Finish(std::move(s)); + } + + private: + friend class CallbackServerStreamingHandler; + + ServerCallbackWriterImpl( + ServerContext* ctx, Call* call, const RequestType* req, + std::function call_requester, + experimental::ServerWriteReactor* reactor) + : ctx_(ctx), + call_(*call), + req_(req), + call_requester_(std::move(call_requester)), + reactor_(reactor) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeDone(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + } + ~ServerCallbackWriterImpl() { req_->~RequestType(); } + + const RequestType* request() { return req_; } + + void MaybeDone() { + if (--callbacks_outstanding_ == 0) { + reactor_->OnDone(); + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + this->~ServerCallbackWriterImpl(); // explicitly call destructor + g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + CallOpSet meta_ops_; + CallbackWithSuccessTag meta_tag_; + CallOpSet + finish_ops_; + CallbackWithSuccessTag finish_tag_; + CallOpSet write_ops_; + CallbackWithSuccessTag write_tag_; + + ServerContext* ctx_; + Call call_; + const RequestType* req_; + std::function call_requester_; + experimental::ServerWriteReactor* reactor_; + std::atomic_int callbacks_outstanding_{ + 3}; // reserve for OnStarted, Finish, and CompletionOp + }; +}; + +template +class CallbackBidiHandler : public MethodHandler { + public: + CallbackBidiHandler( + std::function< + experimental::ServerBidiReactor*()> + func) + : func_(std::move(func)) {} + void RunHandler(const HandlerParameter& param) final { + g_core_codegen_interface->grpc_call_ref(param.call->call()); + + experimental::ServerBidiReactor* reactor = + param.status.ok() + ? CatchingReactorCreator< + experimental::ServerBidiReactor>( + func_) + : nullptr; + + if (reactor == nullptr) { + // if deserialization or reactor creator failed, we need to fail the call + reactor = new UnimplementedBidiReactor; + } + + auto* stream = new (g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackReaderWriterImpl))) + ServerCallbackReaderWriterImpl(param.server_context, param.call, + std::move(param.call_requester), + reactor); + + stream->BindReactor(reactor); + reactor->OnStarted(param.server_context); + stream->MaybeDone(); + } + + private: + std::function*()> + func_; + + class ServerCallbackReaderWriterImpl + : public experimental::ServerCallbackReaderWriter { + public: + void Finish(Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + finish_ops_.set_core_cq_tag(&finish_tag_); + + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_++; + meta_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnSendInitialMetadataDone(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + void Write(const ResponseType* resp, WriteOptions options) override { + callbacks_outstanding_++; + if (options.is_last_message()) { + options.set_buffer_hint(); + } + if (!ctx_->sent_initial_metadata_) { + write_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + write_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*resp, options).ok()); + call_.PerformOps(&write_ops_); + } + + void WriteAndFinish(const ResponseType* resp, WriteOptions options, + Status s) override { + // Don't send any message if the status is bad + if (s.ok()) { + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(*resp, options).ok()); + } + Finish(std::move(s)); + } + + void Read(RequestType* req) override { + callbacks_outstanding_++; + read_ops_.RecvMessage(req); + call_.PerformOps(&read_ops_); + } + + private: + friend class CallbackBidiHandler; + + ServerCallbackReaderWriterImpl( + ServerContext* ctx, Call* call, std::function call_requester, + experimental::ServerBidiReactor* reactor) + : ctx_(ctx), + call_(*call), + call_requester_(std::move(call_requester)), + reactor_(reactor) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeDone(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeDone(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + } + ~ServerCallbackReaderWriterImpl() {} + + void MaybeDone() { + if (--callbacks_outstanding_ == 0) { + reactor_->OnDone(); + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + this->~ServerCallbackReaderWriterImpl(); // explicitly call destructor + g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + CallOpSet meta_ops_; + CallbackWithSuccessTag meta_tag_; + CallOpSet + finish_ops_; + CallbackWithSuccessTag finish_tag_; + CallOpSet write_ops_; + CallbackWithSuccessTag write_tag_; + CallOpSet> read_ops_; + CallbackWithSuccessTag read_tag_; + + ServerContext* ctx_; + Call call_; + std::function call_requester_; + experimental::ServerBidiReactor* reactor_; + std::atomic_int callbacks_outstanding_{ + 3}; // reserve for OnStarted, Finish, and CompletionOp }; }; diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index 82ee862f61b..4a5f9e2dd91 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -66,13 +66,20 @@ template class ServerStreamingHandler; template class BidiStreamingHandler; -template +template class CallbackUnaryHandler; +template +class CallbackClientStreamingHandler; +template +class CallbackServerStreamingHandler; +template +class CallbackBidiHandler; template class TemplatedBidiStreamingHandler; template class ErrorMethodHandler; class Call; +class ServerReactor; } // namespace internal class CompletionQueue; @@ -270,8 +277,14 @@ class ServerContext { friend class ::grpc::internal::ServerStreamingHandler; template friend class ::grpc::internal::TemplatedBidiStreamingHandler; - template + template friend class ::grpc::internal::CallbackUnaryHandler; + template + friend class ::grpc::internal::CallbackClientStreamingHandler; + template + friend class ::grpc::internal::CallbackServerStreamingHandler; + template + friend class ::grpc::internal::CallbackBidiHandler; template friend class internal::ErrorMethodHandler; friend class ::grpc::ClientContext; @@ -282,7 +295,9 @@ class ServerContext { class CompletionOp; - void BeginCompletionOp(internal::Call* call, bool callback); + void BeginCompletionOp(internal::Call* call, + std::function callback, + internal::ServerReactor* reactor); /// Return the tag queued by BeginCompletionOp() internal::CompletionQueueTag* GetCompletionOpTag(); diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index a368b47f016..b0046872502 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -889,6 +889,11 @@ void PrintHeaderServerCallbackMethodsHelper( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); + printer->Print(*vars, + "virtual ::grpc::experimental::ServerReadReactor< " + "$RealRequest$, $RealResponse$>* $Method$() {\n" + " return new ::grpc::internal::UnimplementedReadReactor<\n" + " $RealRequest$, $RealResponse$>;}\n"); } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, @@ -900,6 +905,11 @@ void PrintHeaderServerCallbackMethodsHelper( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); + printer->Print(*vars, + "virtual ::grpc::experimental::ServerWriteReactor< " + "$RealRequest$, $RealResponse$>* $Method$() {\n" + " return new ::grpc::internal::UnimplementedWriteReactor<\n" + " $RealRequest$, $RealResponse$>;}\n"); } else if (method->BidiStreaming()) { printer->Print( *vars, @@ -911,6 +921,11 @@ void PrintHeaderServerCallbackMethodsHelper( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); + printer->Print(*vars, + "virtual ::grpc::experimental::ServerBidiReactor< " + "$RealRequest$, $RealResponse$>* $Method$() {\n" + " return new ::grpc::internal::UnimplementedBidiReactor<\n" + " $RealRequest$, $RealResponse$>;}\n"); } } @@ -939,22 +954,36 @@ void PrintHeaderServerMethodCallback( *vars, " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" " new ::grpc::internal::CallbackUnaryHandler< " - "ExperimentalWithCallbackMethod_$Method$, $RealRequest$, " - "$RealResponse$>(\n" + "$RealRequest$, $RealResponse$>(\n" " [this](::grpc::ServerContext* context,\n" " const $RealRequest$* request,\n" " $RealResponse$* response,\n" " ::grpc::experimental::ServerCallbackRpcController* " "controller) {\n" - " this->$" + " return this->$" "Method$(context, request, response, controller);\n" - " }, this));\n"); + " }));\n"); } else if (ClientOnlyStreaming(method)) { - // TODO(vjpai): Add in code generation for all streaming methods + printer->Print( + *vars, + " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" + " new ::grpc::internal::CallbackClientStreamingHandler< " + "$RealRequest$, $RealResponse$>(\n" + " [this] { return this->$Method$(); }));\n"); } else if (ServerOnlyStreaming(method)) { - // TODO(vjpai): Add in code generation for all streaming methods + printer->Print( + *vars, + " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" + " new ::grpc::internal::CallbackServerStreamingHandler< " + "$RealRequest$, $RealResponse$>(\n" + " [this] { return this->$Method$(); }));\n"); } else if (method->BidiStreaming()) { - // TODO(vjpai): Add in code generation for all streaming methods + printer->Print( + *vars, + " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" + " new ::grpc::internal::CallbackBidiHandler< " + "$RealRequest$, $RealResponse$>(\n" + " [this] { return this->$Method$(); }));\n"); } printer->Print(*vars, "}\n"); printer->Print(*vars, @@ -991,8 +1020,7 @@ void PrintHeaderServerMethodRawCallback( *vars, " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" " new ::grpc::internal::CallbackUnaryHandler< " - "ExperimentalWithRawCallbackMethod_$Method$, $RealRequest$, " - "$RealResponse$>(\n" + "$RealRequest$, $RealResponse$>(\n" " [this](::grpc::ServerContext* context,\n" " const $RealRequest$* request,\n" " $RealResponse$* response,\n" @@ -1000,13 +1028,28 @@ void PrintHeaderServerMethodRawCallback( "controller) {\n" " this->$" "Method$(context, request, response, controller);\n" - " }, this));\n"); + " }));\n"); } else if (ClientOnlyStreaming(method)) { - // TODO(vjpai): Add in code generation for all streaming methods + printer->Print( + *vars, + " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" + " new ::grpc::internal::CallbackClientStreamingHandler< " + "$RealRequest$, $RealResponse$>(\n" + " [this] { return this->$Method$(); }));\n"); } else if (ServerOnlyStreaming(method)) { - // TODO(vjpai): Add in code generation for all streaming methods + printer->Print( + *vars, + " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" + " new ::grpc::internal::CallbackServerStreamingHandler< " + "$RealRequest$, $RealResponse$>(\n" + " [this] { return this->$Method$(); }));\n"); } else if (method->BidiStreaming()) { - // TODO(vjpai): Add in code generation for all streaming methods + printer->Print( + *vars, + " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" + " new ::grpc::internal::CallbackBidiHandler< " + "$RealRequest$, $RealResponse$>(\n" + " [this] { return this->$Method$(); }));\n"); } printer->Print(*vars, "}\n"); printer->Print(*vars, diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 0a51cf5626e..69af43a6562 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -291,7 +291,7 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { void ContinueRunAfterInterception() { { - ctx_.BeginCompletionOp(&call_, false); + ctx_.BeginCompletionOp(&call_, nullptr, nullptr); global_callbacks_->PreSynchronousRequest(&ctx_); auto* handler = resources_ ? method_->handler() : server_->resource_exhausted_handler_.get(); @@ -456,7 +456,6 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { } } void ContinueRunAfterInterception() { - req_->ctx_.BeginCompletionOp(call_, true); req_->method_->handler()->RunHandler( internal::MethodHandler::HandlerParameter( call_, &req_->ctx_, req_->request_, req_->request_status_, @@ -1018,7 +1017,7 @@ bool ServerInterface::BaseAsyncRequest::FinalizeResult(void** tag, } } if (*status && call_) { - context_->BeginCompletionOp(&call_wrapper_, false); + context_->BeginCompletionOp(&call_wrapper_, nullptr, nullptr); } *tag = tag_; if (delete_on_finalize_) { @@ -1029,7 +1028,7 @@ bool ServerInterface::BaseAsyncRequest::FinalizeResult(void** tag, void ServerInterface::BaseAsyncRequest:: ContinueFinalizeResultAfterInterception() { - context_->BeginCompletionOp(&call_wrapper_, false); + context_->BeginCompletionOp(&call_wrapper_, nullptr, nullptr); // Queue a tag which will be returned immediately grpc_core::ExecCtx exec_ctx; grpc_cq_begin_op(notification_cq_->cq(), this); diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index 9c01f896e6c..1b524bc3e83 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -41,8 +42,9 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { public: // initial refs: one in the server context, one in the cq // must ref the call before calling constructor and after deleting this - CompletionOp(internal::Call* call) + CompletionOp(internal::Call* call, internal::ServerReactor* reactor) : call_(*call), + reactor_(reactor), has_tag_(false), tag_(nullptr), core_cq_tag_(this), @@ -124,9 +126,9 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { return; } /* Start a dummy op so that we can return the tag */ - GPR_CODEGEN_ASSERT(GRPC_CALL_OK == - g_core_codegen_interface->grpc_call_start_batch( - call_.call(), nullptr, 0, this, nullptr)); + GPR_CODEGEN_ASSERT( + GRPC_CALL_OK == + grpc_call_start_batch(call_.call(), nullptr, 0, core_cq_tag_, nullptr)); } private: @@ -136,13 +138,14 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { } internal::Call call_; + internal::ServerReactor* reactor_; bool has_tag_; void* tag_; void* core_cq_tag_; std::mutex mu_; int refs_; bool finalized_; - int cancelled_; + int cancelled_; // This is an int (not bool) because it is passed to core bool done_intercepting_; internal::InterceptorBatchMethodsImpl interceptor_methods_; }; @@ -190,7 +193,16 @@ bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { } finalized_ = true; - if (!*status) cancelled_ = 1; + // If for some reason the incoming status is false, mark that as a + // cancellation. + // TODO(vjpai): does this ever happen? + if (!*status) { + cancelled_ = 1; + } + + if (cancelled_ && (reactor_ != nullptr)) { + reactor_->OnCancel(); + } /* Release the lock since we are going to be running through interceptors now */ lock.unlock(); @@ -251,21 +263,25 @@ void ServerContext::Clear() { initial_metadata_.clear(); trailing_metadata_.clear(); client_metadata_.Reset(); - if (call_) { - grpc_call_unref(call_); - } if (completion_op_) { completion_op_->Unref(); + completion_op_ = nullptr; completion_tag_.Clear(); } if (rpc_info_) { rpc_info_->Unref(); + rpc_info_ = nullptr; + } + if (call_) { + auto* call = call_; + call_ = nullptr; + grpc_call_unref(call); } - // Don't need to clear out call_, completion_op_, or rpc_info_ because this is - // either called from destructor or just before Setup } -void ServerContext::BeginCompletionOp(internal::Call* call, bool callback) { +void ServerContext::BeginCompletionOp(internal::Call* call, + std::function callback, + internal::ServerReactor* reactor) { GPR_ASSERT(!completion_op_); if (rpc_info_) { rpc_info_->Ref(); @@ -273,10 +289,11 @@ void ServerContext::BeginCompletionOp(internal::Call* call, bool callback) { grpc_call_ref(call->call()); completion_op_ = new (grpc_call_arena_alloc(call->call(), sizeof(CompletionOp))) - CompletionOp(call); - if (callback) { - completion_tag_.Set(call->call(), nullptr, completion_op_); + CompletionOp(call, reactor); + if (callback != nullptr) { + completion_tag_.Set(call->call(), std::move(callback), completion_op_); completion_op_->set_core_cq_tag(&completion_tag_); + completion_op_->set_tag(completion_op_); } else if (has_notify_when_done_tag_) { completion_op_->set_tag(async_notify_when_done_tag_); } diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 5f0eb6c35ce..1871e1375ed 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -322,13 +322,13 @@ class ServiceA final { public: ExperimentalWithCallbackMethod_MethodA1() { ::grpc::Service::experimental().MarkMethodCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithCallbackMethod_MethodA1, ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this](::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ServerCallbackRpcController* controller) { - this->MethodA1(context, request, response, controller); - }, this)); + return this->MethodA1(context, request, response, controller); + })); } ~ExperimentalWithCallbackMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); @@ -346,6 +346,9 @@ class ServiceA final { void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithCallbackMethod_MethodA2() { + ::grpc::Service::experimental().MarkMethodCallback(1, + new ::grpc::internal::CallbackClientStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + [this] { return this->MethodA2(); })); } ~ExperimentalWithCallbackMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); @@ -355,6 +358,9 @@ class ServiceA final { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } + virtual ::grpc::experimental::ServerReadReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA2() { + return new ::grpc::internal::UnimplementedReadReactor< + ::grpc::testing::Request, ::grpc::testing::Response>;} }; template class ExperimentalWithCallbackMethod_MethodA3 : public BaseClass { @@ -362,6 +368,9 @@ class ServiceA final { void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithCallbackMethod_MethodA3() { + ::grpc::Service::experimental().MarkMethodCallback(2, + new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + [this] { return this->MethodA3(); })); } ~ExperimentalWithCallbackMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); @@ -371,6 +380,9 @@ class ServiceA final { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } + virtual ::grpc::experimental::ServerWriteReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA3() { + return new ::grpc::internal::UnimplementedWriteReactor< + ::grpc::testing::Request, ::grpc::testing::Response>;} }; template class ExperimentalWithCallbackMethod_MethodA4 : public BaseClass { @@ -378,6 +390,9 @@ class ServiceA final { void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithCallbackMethod_MethodA4() { + ::grpc::Service::experimental().MarkMethodCallback(3, + new ::grpc::internal::CallbackBidiHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + [this] { return this->MethodA4(); })); } ~ExperimentalWithCallbackMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); @@ -387,6 +402,9 @@ class ServiceA final { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } + virtual ::grpc::experimental::ServerBidiReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4() { + return new ::grpc::internal::UnimplementedBidiReactor< + ::grpc::testing::Request, ::grpc::testing::Response>;} }; typedef ExperimentalWithCallbackMethod_MethodA1 > > > ExperimentalCallbackService; template @@ -544,13 +562,13 @@ class ServiceA final { public: ExperimentalWithRawCallbackMethod_MethodA1() { ::grpc::Service::experimental().MarkMethodRawCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithRawCallbackMethod_MethodA1, ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this](::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response, ::grpc::experimental::ServerCallbackRpcController* controller) { this->MethodA1(context, request, response, controller); - }, this)); + })); } ~ExperimentalWithRawCallbackMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); @@ -568,6 +586,9 @@ class ServiceA final { void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithRawCallbackMethod_MethodA2() { + ::grpc::Service::experimental().MarkMethodRawCallback(1, + new ::grpc::internal::CallbackClientStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this] { return this->MethodA2(); })); } ~ExperimentalWithRawCallbackMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); @@ -577,6 +598,9 @@ class ServiceA final { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } + virtual ::grpc::experimental::ServerReadReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA2() { + return new ::grpc::internal::UnimplementedReadReactor< + ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} }; template class ExperimentalWithRawCallbackMethod_MethodA3 : public BaseClass { @@ -584,6 +608,9 @@ class ServiceA final { void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithRawCallbackMethod_MethodA3() { + ::grpc::Service::experimental().MarkMethodRawCallback(2, + new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this] { return this->MethodA3(); })); } ~ExperimentalWithRawCallbackMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); @@ -593,6 +620,9 @@ class ServiceA final { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } + virtual ::grpc::experimental::ServerWriteReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA3() { + return new ::grpc::internal::UnimplementedWriteReactor< + ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} }; template class ExperimentalWithRawCallbackMethod_MethodA4 : public BaseClass { @@ -600,6 +630,9 @@ class ServiceA final { void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithRawCallbackMethod_MethodA4() { + ::grpc::Service::experimental().MarkMethodRawCallback(3, + new ::grpc::internal::CallbackBidiHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this] { return this->MethodA4(); })); } ~ExperimentalWithRawCallbackMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); @@ -609,6 +642,9 @@ class ServiceA final { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } + virtual ::grpc::experimental::ServerBidiReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA4() { + return new ::grpc::internal::UnimplementedBidiReactor< + ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} }; template class WithStreamedUnaryMethod_MethodA1 : public BaseClass { @@ -752,13 +788,13 @@ class ServiceB final { public: ExperimentalWithCallbackMethod_MethodB1() { ::grpc::Service::experimental().MarkMethodCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithCallbackMethod_MethodB1, ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this](::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ServerCallbackRpcController* controller) { - this->MethodB1(context, request, response, controller); - }, this)); + return this->MethodB1(context, request, response, controller); + })); } ~ExperimentalWithCallbackMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); @@ -815,13 +851,13 @@ class ServiceB final { public: ExperimentalWithRawCallbackMethod_MethodB1() { ::grpc::Service::experimental().MarkMethodRawCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithRawCallbackMethod_MethodB1, ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this](::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response, ::grpc::experimental::ServerCallbackRpcController* controller) { this->MethodB1(context, request, response, controller); - }, this)); + })); } ~ExperimentalWithRawCallbackMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 03291e1785c..4d37bae217e 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -196,16 +196,18 @@ class TestServiceImplDupPkg class TestScenario { public: TestScenario(bool interceptors, bool proxy, bool inproc_stub, - const grpc::string& creds_type) + const grpc::string& creds_type, bool use_callback_server) : use_interceptors(interceptors), use_proxy(proxy), inproc(inproc_stub), - credentials_type(creds_type) {} + credentials_type(creds_type), + callback_server(use_callback_server) {} void Log() const; bool use_interceptors; bool use_proxy; bool inproc; const grpc::string credentials_type; + bool callback_server; }; static std::ostream& operator<<(std::ostream& out, @@ -214,6 +216,8 @@ static std::ostream& operator<<(std::ostream& out, << (scenario.use_interceptors ? "true" : "false") << ", use_proxy=" << (scenario.use_proxy ? "true" : "false") << ", inproc=" << (scenario.inproc ? "true" : "false") + << ", server_type=" + << (scenario.callback_server ? "callback" : "sync") << ", credentials='" << scenario.credentials_type << "'}"; } @@ -280,7 +284,11 @@ class End2endTest : public ::testing::TestWithParam { builder.experimental().SetInterceptorCreators(std::move(creators)); } builder.AddListeningPort(server_address_.str(), server_creds); - builder.RegisterService(&service_); + if (!GetParam().callback_server) { + builder.RegisterService(&service_); + } else { + builder.RegisterService(&callback_service_); + } builder.RegisterService("foo.test.youtube.com", &special_service_); builder.RegisterService(&dup_pkg_service_); @@ -362,6 +370,7 @@ class End2endTest : public ::testing::TestWithParam { std::ostringstream server_address_; const int kMaxMessageSize_; TestServiceImpl service_; + CallbackTestServiceImpl callback_service_; TestServiceImpl special_service_; TestServiceImplDupPkg dup_pkg_service_; grpc::string user_agent_prefix_; @@ -1016,7 +1025,8 @@ TEST_P(End2endTest, DiffPackageServices) { EXPECT_TRUE(s.ok()); } -void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) { +template +void CancelRpc(ClientContext* context, int delay_us, ServiceType* service) { gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_micros(delay_us, GPR_TIMESPAN))); while (!service->signal_client()) { @@ -1446,7 +1456,24 @@ TEST_P(ProxyEnd2endTest, ClientCancelsRpc) { request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs); ClientContext context; - std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_); + std::thread cancel_thread; + if (!GetParam().callback_server) { + cancel_thread = std::thread( + [&context, this](int delay) { CancelRpc(&context, delay, &service_); }, + kCancelDelayUs); + // Note: the unusual pattern above (and below) is caused by a conflict + // between two sets of compiler expectations. clang allows const to be + // captured without mention, so there is no need to capture kCancelDelayUs + // (and indeed clang-tidy complains if you do so). OTOH, a Windows compiler + // in our tests requires an explicit capture even for const. We square this + // circle by passing the const value in as an argument to the lambda. + } else { + cancel_thread = std::thread( + [&context, this](int delay) { + CancelRpc(&context, delay, &callback_service_); + }, + kCancelDelayUs); + } Status s = stub_->Echo(&context, request, &response); cancel_thread.join(); EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); @@ -1838,10 +1865,12 @@ TEST_P(ResourceQuotaEnd2endTest, SimpleRequest) { EXPECT_TRUE(s.ok()); } +// TODO(vjpai): refactor arguments into a struct if it makes sense std::vector CreateTestScenarios(bool use_proxy, bool test_insecure, bool test_secure, - bool test_inproc) { + bool test_inproc, + bool test_callback_server) { std::vector scenarios; std::vector credentials_types; if (test_secure) { @@ -1857,41 +1886,48 @@ std::vector CreateTestScenarios(bool use_proxy, if (test_insecure && insec_ok()) { credentials_types.push_back(kInsecureCredentialsType); } + + // For now test callback server only with inproc GPR_ASSERT(!credentials_types.empty()); for (const auto& cred : credentials_types) { - scenarios.emplace_back(false, false, false, cred); - scenarios.emplace_back(true, false, false, cred); + scenarios.emplace_back(false, false, false, cred, false); + scenarios.emplace_back(true, false, false, cred, false); if (use_proxy) { - scenarios.emplace_back(false, true, false, cred); - scenarios.emplace_back(true, true, false, cred); + scenarios.emplace_back(false, true, false, cred, false); + scenarios.emplace_back(true, true, false, cred, false); } } if (test_inproc && insec_ok()) { - scenarios.emplace_back(false, false, true, kInsecureCredentialsType); - scenarios.emplace_back(true, false, true, kInsecureCredentialsType); + scenarios.emplace_back(false, false, true, kInsecureCredentialsType, false); + scenarios.emplace_back(true, false, true, kInsecureCredentialsType, false); + if (test_callback_server) { + scenarios.emplace_back(false, false, true, kInsecureCredentialsType, + true); + scenarios.emplace_back(true, false, true, kInsecureCredentialsType, true); + } } return scenarios; } -INSTANTIATE_TEST_CASE_P(End2end, End2endTest, - ::testing::ValuesIn(CreateTestScenarios(false, true, - true, true))); +INSTANTIATE_TEST_CASE_P( + End2end, End2endTest, + ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, true))); -INSTANTIATE_TEST_CASE_P(End2endServerTryCancel, End2endServerTryCancelTest, - ::testing::ValuesIn(CreateTestScenarios(false, true, - true, true))); +INSTANTIATE_TEST_CASE_P( + End2endServerTryCancel, End2endServerTryCancelTest, + ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, true))); -INSTANTIATE_TEST_CASE_P(ProxyEnd2end, ProxyEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(true, true, - true, true))); +INSTANTIATE_TEST_CASE_P( + ProxyEnd2end, ProxyEnd2endTest, + ::testing::ValuesIn(CreateTestScenarios(true, true, true, true, false))); -INSTANTIATE_TEST_CASE_P(SecureEnd2end, SecureEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(false, false, - true, false))); +INSTANTIATE_TEST_CASE_P( + SecureEnd2end, SecureEnd2endTest, + ::testing::ValuesIn(CreateTestScenarios(false, false, true, false, true))); -INSTANTIATE_TEST_CASE_P(ResourceQuotaEnd2end, ResourceQuotaEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(false, true, - true, true))); +INSTANTIATE_TEST_CASE_P( + ResourceQuotaEnd2end, ResourceQuotaEnd2endTest, + ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, false))); } // namespace } // namespace testing diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 1726e87ea66..9d9c01cade1 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -71,6 +71,46 @@ void CheckServerAuthContext( } } // namespace +namespace { +int GetIntValueFromMetadataHelper( + const char* key, + const std::multimap& metadata, + int default_value) { + if (metadata.find(key) != metadata.end()) { + std::istringstream iss(ToString(metadata.find(key)->second)); + iss >> default_value; + gpr_log(GPR_INFO, "%s : %d", key, default_value); + } + + return default_value; +} + +int GetIntValueFromMetadata( + const char* key, + const std::multimap& metadata, + int default_value) { + return GetIntValueFromMetadataHelper(key, metadata, default_value); +} + +void ServerTryCancel(ServerContext* context) { + EXPECT_FALSE(context->IsCancelled()); + context->TryCancel(); + gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request"); + // Now wait until it's really canceled + while (!context->IsCancelled()) { + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_micros(1000, GPR_TIMESPAN))); + } +} + +void ServerTryCancelNonblocking(ServerContext* context) { + EXPECT_FALSE(context->IsCancelled()); + context->TryCancel(); + gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request"); +} + +} // namespace + Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, EchoResponse* response) { // A bit of sleep to make sure that short deadline tests fail @@ -195,6 +235,7 @@ void CallbackTestServiceImpl::EchoNonDelayed( controller->Finish(Status(static_cast(error.code()), error.error_message(), error.binary_error_details())); + return; } int server_try_cancel = GetIntValueFromMetadata( kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL); @@ -254,7 +295,7 @@ void CallbackTestServiceImpl::EchoNonDelayed( alarm_.experimental().Set( gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_micros(request->param().client_cancel_after_us(), + gpr_time_from_micros(request->param().server_cancel_after_us(), GPR_TIMESPAN)), [controller](bool) { controller->Finish(Status::CANCELLED); }); return; @@ -279,6 +320,7 @@ void CallbackTestServiceImpl::EchoNonDelayed( request->param().debug_info().SerializeAsString(); context->AddTrailingMetadata(kDebugInfoTrailerKey, serialized_debug_info); controller->Finish(Status::CANCELLED); + return; } } if (request->has_param() && @@ -325,7 +367,7 @@ Status TestServiceImpl::RequestStream(ServerContext* context, std::thread* server_try_cancel_thd = nullptr; if (server_try_cancel == CANCEL_DURING_PROCESSING) { server_try_cancel_thd = - new std::thread(&TestServiceImpl::ServerTryCancel, this, context); + new std::thread([context] { ServerTryCancel(context); }); } int num_msgs_read = 0; @@ -380,7 +422,7 @@ Status TestServiceImpl::ResponseStream(ServerContext* context, std::thread* server_try_cancel_thd = nullptr; if (server_try_cancel == CANCEL_DURING_PROCESSING) { server_try_cancel_thd = - new std::thread(&TestServiceImpl::ServerTryCancel, this, context); + new std::thread([context] { ServerTryCancel(context); }); } for (int i = 0; i < server_responses_to_send; i++) { @@ -431,7 +473,7 @@ Status TestServiceImpl::BidiStream( std::thread* server_try_cancel_thd = nullptr; if (server_try_cancel == CANCEL_DURING_PROCESSING) { server_try_cancel_thd = - new std::thread(&TestServiceImpl::ServerTryCancel, this, context); + new std::thread([context] { ServerTryCancel(context); }); } // kServerFinishAfterNReads suggests after how many reads, the server should @@ -465,44 +507,244 @@ Status TestServiceImpl::BidiStream( return Status::OK; } -namespace { -int GetIntValueFromMetadataHelper( - const char* key, - const std::multimap& metadata, - int default_value) { - if (metadata.find(key) != metadata.end()) { - std::istringstream iss(ToString(metadata.find(key)->second)); - iss >> default_value; - gpr_log(GPR_INFO, "%s : %d", key, default_value); - } +experimental::ServerReadReactor* +CallbackTestServiceImpl::RequestStream() { + class Reactor : public ::grpc::experimental::ServerReadReactor { + public: + Reactor() {} + void OnStarted(ServerContext* context, EchoResponse* response) override { + ctx_ = context; + response_ = response; + // If 'server_try_cancel' is set in the metadata, the RPC is cancelled by + // the server by calling ServerContext::TryCancel() depending on the + // value: + // CANCEL_BEFORE_PROCESSING: The RPC is cancelled before the server + // reads any message from the client CANCEL_DURING_PROCESSING: The RPC + // is cancelled while the server is reading messages from the client + // CANCEL_AFTER_PROCESSING: The RPC is cancelled after the server reads + // all the messages from the client + server_try_cancel_ = GetIntValueFromMetadata( + kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL); - return default_value; -} -}; // namespace + response_->set_message(""); -int TestServiceImpl::GetIntValueFromMetadata( - const char* key, - const std::multimap& metadata, - int default_value) { - return GetIntValueFromMetadataHelper(key, metadata, default_value); + if (server_try_cancel_ == CANCEL_BEFORE_PROCESSING) { + ServerTryCancelNonblocking(ctx_); + return; + } + + if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { + ctx_->TryCancel(); + // Don't wait for it here + } + + StartRead(&request_); + } + void OnDone() override { delete this; } + void OnCancel() override { FinishOnce(Status::CANCELLED); } + void OnReadDone(bool ok) override { + if (ok) { + response_->mutable_message()->append(request_.message()); + num_msgs_read_++; + StartRead(&request_); + } else { + gpr_log(GPR_INFO, "Read: %d messages", num_msgs_read_); + + if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { + // Let OnCancel recover this + return; + } + if (server_try_cancel_ == CANCEL_AFTER_PROCESSING) { + ServerTryCancelNonblocking(ctx_); + return; + } + FinishOnce(Status::OK); + } + } + + private: + void FinishOnce(const Status& s) { + std::lock_guard l(finish_mu_); + if (!finished_) { + Finish(s); + finished_ = true; + } + } + + ServerContext* ctx_; + EchoResponse* response_; + EchoRequest request_; + int num_msgs_read_{0}; + int server_try_cancel_; + std::mutex finish_mu_; + bool finished_{false}; + }; + + return new Reactor; } -int CallbackTestServiceImpl::GetIntValueFromMetadata( - const char* key, - const std::multimap& metadata, - int default_value) { - return GetIntValueFromMetadataHelper(key, metadata, default_value); +// Return 'kNumResponseStreamMsgs' messages. +// TODO(yangg) make it generic by adding a parameter into EchoRequest +experimental::ServerWriteReactor* +CallbackTestServiceImpl::ResponseStream() { + class Reactor + : public ::grpc::experimental::ServerWriteReactor { + public: + Reactor() {} + void OnStarted(ServerContext* context, + const EchoRequest* request) override { + ctx_ = context; + request_ = request; + // If 'server_try_cancel' is set in the metadata, the RPC is cancelled by + // the server by calling ServerContext::TryCancel() depending on the + // value: + // CANCEL_BEFORE_PROCESSING: The RPC is cancelled before the server + // reads any message from the client CANCEL_DURING_PROCESSING: The RPC + // is cancelled while the server is reading messages from the client + // CANCEL_AFTER_PROCESSING: The RPC is cancelled after the server reads + // all the messages from the client + server_try_cancel_ = GetIntValueFromMetadata( + kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL); + server_coalescing_api_ = GetIntValueFromMetadata( + kServerUseCoalescingApi, context->client_metadata(), 0); + server_responses_to_send_ = GetIntValueFromMetadata( + kServerResponseStreamsToSend, context->client_metadata(), + kServerDefaultResponseStreamsToSend); + if (server_try_cancel_ == CANCEL_BEFORE_PROCESSING) { + ServerTryCancelNonblocking(ctx_); + return; + } + + if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { + ctx_->TryCancel(); + } + if (num_msgs_sent_ < server_responses_to_send_) { + NextWrite(); + } + } + void OnDone() override { delete this; } + void OnCancel() override { FinishOnce(Status::CANCELLED); } + void OnWriteDone(bool ok) override { + if (num_msgs_sent_ < server_responses_to_send_) { + NextWrite(); + } else if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { + // Let OnCancel recover this + } else if (server_try_cancel_ == CANCEL_AFTER_PROCESSING) { + ServerTryCancelNonblocking(ctx_); + } else { + FinishOnce(Status::OK); + } + } + + private: + void FinishOnce(const Status& s) { + std::lock_guard l(finish_mu_); + if (!finished_) { + Finish(s); + finished_ = true; + } + } + + void NextWrite() { + response_.set_message(request_->message() + + grpc::to_string(num_msgs_sent_)); + if (num_msgs_sent_ == server_responses_to_send_ - 1 && + server_coalescing_api_ != 0) { + num_msgs_sent_++; + StartWriteLast(&response_, WriteOptions()); + } else { + num_msgs_sent_++; + StartWrite(&response_); + } + } + ServerContext* ctx_; + const EchoRequest* request_; + EchoResponse response_; + int num_msgs_sent_{0}; + int server_try_cancel_; + int server_coalescing_api_; + int server_responses_to_send_; + std::mutex finish_mu_; + bool finished_{false}; + }; + return new Reactor; } -void TestServiceImpl::ServerTryCancel(ServerContext* context) { - EXPECT_FALSE(context->IsCancelled()); - context->TryCancel(); - gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request"); - // Now wait until it's really canceled - while (!context->IsCancelled()) { - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_micros(1000, GPR_TIMESPAN))); - } +experimental::ServerBidiReactor* +CallbackTestServiceImpl::BidiStream() { + class Reactor : public ::grpc::experimental::ServerBidiReactor { + public: + Reactor() {} + void OnStarted(ServerContext* context) override { + ctx_ = context; + // If 'server_try_cancel' is set in the metadata, the RPC is cancelled by + // the server by calling ServerContext::TryCancel() depending on the + // value: + // CANCEL_BEFORE_PROCESSING: The RPC is cancelled before the server + // reads any message from the client CANCEL_DURING_PROCESSING: The RPC + // is cancelled while the server is reading messages from the client + // CANCEL_AFTER_PROCESSING: The RPC is cancelled after the server reads + // all the messages from the client + server_try_cancel_ = GetIntValueFromMetadata( + kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL); + server_write_last_ = GetIntValueFromMetadata( + kServerFinishAfterNReads, context->client_metadata(), 0); + if (server_try_cancel_ == CANCEL_BEFORE_PROCESSING) { + ServerTryCancelNonblocking(ctx_); + return; + } + + if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { + ctx_->TryCancel(); + } + + StartRead(&request_); + } + void OnDone() override { delete this; } + void OnCancel() override { FinishOnce(Status::CANCELLED); } + void OnReadDone(bool ok) override { + if (ok) { + num_msgs_read_++; + gpr_log(GPR_INFO, "recv msg %s", request_.message().c_str()); + response_.set_message(request_.message()); + if (num_msgs_read_ == server_write_last_) { + StartWriteLast(&response_, WriteOptions()); + } else { + StartWrite(&response_); + } + } else if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { + // Let OnCancel handle this + } else if (server_try_cancel_ == CANCEL_AFTER_PROCESSING) { + ServerTryCancelNonblocking(ctx_); + } else { + FinishOnce(Status::OK); + } + } + void OnWriteDone(bool ok) override { StartRead(&request_); } + + private: + void FinishOnce(const Status& s) { + std::lock_guard l(finish_mu_); + if (!finished_) { + Finish(s); + finished_ = true; + } + } + + ServerContext* ctx_; + EchoRequest request_; + EchoResponse response_; + int num_msgs_read_{0}; + int server_try_cancel_; + int server_write_last_; + std::mutex finish_mu_; + bool finished_{false}; + }; + + return new Reactor; } } // namespace testing diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h index ddfe94487e8..fad7768b872 100644 --- a/test/cpp/end2end/test_service_impl.h +++ b/test/cpp/end2end/test_service_impl.h @@ -72,13 +72,6 @@ class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { } private: - int GetIntValueFromMetadata( - const char* key, - const std::multimap& metadata, - int default_value); - - void ServerTryCancel(ServerContext* context); - bool signal_client_; std::mutex mu_; std::unique_ptr host_; @@ -95,6 +88,15 @@ class CallbackTestServiceImpl EchoResponse* response, experimental::ServerCallbackRpcController* controller) override; + experimental::ServerReadReactor* RequestStream() + override; + + experimental::ServerWriteReactor* ResponseStream() + override; + + experimental::ServerBidiReactor* BidiStream() + override; + // Unimplemented is left unimplemented to test the returned error. bool signal_client() { std::unique_lock lock(mu_); @@ -106,11 +108,6 @@ class CallbackTestServiceImpl EchoResponse* response, experimental::ServerCallbackRpcController* controller); - int GetIntValueFromMetadata( - const char* key, - const std::multimap& metadata, - int default_value); - Alarm alarm_; bool signal_client_; std::mutex mu_; From 09ba4b40472e50a55bb56b069420d74ad5472d37 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 30 Nov 2018 16:17:16 -0800 Subject: [PATCH 0402/2143] Test client-side callback streaming with callback server --- test/cpp/end2end/client_callback_end2end_test.cc | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 6c18703f06b..861f7d55b07 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -322,11 +322,6 @@ TEST_P(ClientCallbackEnd2endTest, CancelRpcBeforeStart) { } TEST_P(ClientCallbackEnd2endTest, RequestStream) { - // TODO(vjpai): test with callback server once supported - if (GetParam().callback_server) { - return; - } - ResetStub(); class Client : public grpc::experimental::ClientWriteReactor { public: @@ -373,11 +368,6 @@ TEST_P(ClientCallbackEnd2endTest, RequestStream) { } TEST_P(ClientCallbackEnd2endTest, ResponseStream) { - // TODO(vjpai): test with callback server once supported - if (GetParam().callback_server) { - return; - } - ResetStub(); class Client : public grpc::experimental::ClientReadReactor { public: @@ -425,10 +415,6 @@ TEST_P(ClientCallbackEnd2endTest, ResponseStream) { } TEST_P(ClientCallbackEnd2endTest, BidiStream) { - // TODO(vjpai): test with callback server once supported - if (GetParam().callback_server) { - return; - } ResetStub(); class Client : public grpc::experimental::ClientBidiReactor { From 4345ef121a3422bd5de4d99bd758e4fd8567680d Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 30 Nov 2018 13:40:12 -0500 Subject: [PATCH 0403/2143] Add debug-only tracing to grpc_core::RefCount Also, this patch removes the *WithTracing variants in favor of the new API. --- .../health/health_check_client.cc | 6 +- .../health/health_check_client.h | 5 +- .../ext/filters/client_channel/lb_policy.cc | 2 +- .../ext/filters/client_channel/lb_policy.h | 3 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 5 +- .../lb_policy/subchannel_list.h | 8 +- .../client_channel/lb_policy/xds/xds.cc | 5 +- .../ext/filters/client_channel/resolver.cc | 2 +- .../ext/filters/client_channel/resolver.h | 2 +- .../ext/filters/client_channel/subchannel.cc | 2 +- .../ext/filters/client_channel/subchannel.h | 2 +- .../chttp2/transport/chttp2_transport.cc | 26 +-- .../ext/transport/chttp2/transport/internal.h | 16 +- src/core/lib/debug/trace.h | 5 +- src/core/lib/gprpp/orphanable.h | 91 ++--------- src/core/lib/gprpp/ref_counted.h | 152 ++++++++---------- src/core/lib/gprpp/ref_counted_ptr.h | 33 ++-- test/core/gprpp/orphanable_test.cc | 4 +- test/core/gprpp/ref_counted_ptr_test.cc | 4 +- test/core/gprpp/ref_counted_test.cc | 9 +- 20 files changed, 144 insertions(+), 238 deletions(-) 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 587919596ff..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 @@ -51,8 +51,7 @@ HealthCheckClient::HealthCheckClient( RefCountedPtr connected_subchannel, grpc_pollset_set* interested_parties, grpc_core::RefCountedPtr channelz_node) - : InternallyRefCountedWithTracing( - &grpc_health_check_client_trace), + : InternallyRefCounted(&grpc_health_check_client_trace), service_name_(service_name), connected_subchannel_(std::move(connected_subchannel)), interested_parties_(interested_parties), @@ -281,8 +280,7 @@ bool DecodeResponse(grpc_slice_buffer* slice_buffer, grpc_error** error) { HealthCheckClient::CallState::CallState( RefCountedPtr health_check_client, grpc_pollset_set* interested_parties) - : InternallyRefCountedWithTracing( - &grpc_health_check_client_trace), + : InternallyRefCounted(&grpc_health_check_client_trace), health_check_client_(std::move(health_check_client)), pollent_(grpc_polling_entity_create_from_pollset_set(interested_parties)), arena_(gpr_arena_create(health_check_client_->connected_subchannel_ 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 f6babef7d62..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 @@ -41,8 +41,7 @@ namespace grpc_core { -class HealthCheckClient - : public InternallyRefCountedWithTracing { +class HealthCheckClient : public InternallyRefCounted { public: HealthCheckClient(const char* service_name, RefCountedPtr connected_subchannel, @@ -61,7 +60,7 @@ class HealthCheckClient private: // Contains a call to the backend and all the data related to the call. - class CallState : public InternallyRefCountedWithTracing { + class CallState : public InternallyRefCounted { public: CallState(RefCountedPtr health_check_client, grpc_pollset_set* 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 e065f45639b..b4e803689e9 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -27,7 +27,7 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount( namespace grpc_core { LoadBalancingPolicy::LoadBalancingPolicy(const Args& args) - : InternallyRefCountedWithTracing(&grpc_trace_lb_policy_refcount), + : InternallyRefCounted(&grpc_trace_lb_policy_refcount), combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")), client_channel_factory_(args.client_channel_factory), interested_parties_(grpc_pollset_set_create()), diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 6733fdca814..7034da6249c 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -42,8 +42,7 @@ namespace grpc_core { /// /// Any I/O done by the LB policy should be done under the pollset_set /// returned by \a interested_parties(). -class LoadBalancingPolicy - : public InternallyRefCountedWithTracing { +class LoadBalancingPolicy : public InternallyRefCounted { public: struct Args { /// The combiner under which all LB policy calls will be run. 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 7e70f1c28bd..a46579c7f74 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 @@ -171,8 +171,7 @@ class GrpcLb : public LoadBalancingPolicy { }; /// Contains a call to the LB server and all the data related to the call. - class BalancerCallState - : public InternallyRefCountedWithTracing { + class BalancerCallState : public InternallyRefCounted { public: explicit BalancerCallState( RefCountedPtr parent_grpclb_policy); @@ -499,7 +498,7 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { GrpcLb::BalancerCallState::BalancerCallState( RefCountedPtr parent_grpclb_policy) - : InternallyRefCountedWithTracing(&grpc_lb_glb_trace), + : InternallyRefCounted(&grpc_lb_glb_trace), grpclb_policy_(std::move(parent_grpclb_policy)) { GPR_ASSERT(grpclb_policy_ != nullptr); GPR_ASSERT(!grpclb_policy()->shutting_down_); 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 4ec9e935ed1..f31401502c3 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 @@ -186,8 +186,7 @@ class SubchannelData { // A list of subchannels. template -class SubchannelList - : public InternallyRefCountedWithTracing { +class SubchannelList : public InternallyRefCounted { public: typedef InlinedVector SubchannelVector; @@ -226,8 +225,7 @@ class SubchannelList // Note: Caller must ensure that this is invoked inside of the combiner. void Orphan() override { ShutdownLocked(); - InternallyRefCountedWithTracing::Unref(DEBUG_LOCATION, - "shutdown"); + InternallyRefCounted::Unref(DEBUG_LOCATION, "shutdown"); } GRPC_ABSTRACT_BASE_CLASS @@ -493,7 +491,7 @@ SubchannelList::SubchannelList( const grpc_lb_addresses* addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) - : InternallyRefCountedWithTracing(tracer), + : InternallyRefCounted(tracer), policy_(policy), tracer_(tracer), combiner_(GRPC_COMBINER_REF(combiner, "subchannel_list")) { 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 89b86b38a63..563ff42b2ea 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 @@ -166,8 +166,7 @@ class XdsLb : public LoadBalancingPolicy { }; /// Contains a call to the LB server and all the data related to the call. - class BalancerCallState - : public InternallyRefCountedWithTracing { + class BalancerCallState : public InternallyRefCounted { public: explicit BalancerCallState( RefCountedPtr parent_xdslb_policy); @@ -488,7 +487,7 @@ grpc_lb_addresses* ProcessServerlist(const xds_grpclb_serverlist* serverlist) { XdsLb::BalancerCallState::BalancerCallState( RefCountedPtr parent_xdslb_policy) - : InternallyRefCountedWithTracing(&grpc_lb_xds_trace), + : InternallyRefCounted(&grpc_lb_xds_trace), xdslb_policy_(std::move(parent_xdslb_policy)) { GPR_ASSERT(xdslb_policy_ != nullptr); GPR_ASSERT(!xdslb_policy()->shutting_down_); diff --git a/src/core/ext/filters/client_channel/resolver.cc b/src/core/ext/filters/client_channel/resolver.cc index cd11eeb9e4d..601b08be246 100644 --- a/src/core/ext/filters/client_channel/resolver.cc +++ b/src/core/ext/filters/client_channel/resolver.cc @@ -27,7 +27,7 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_resolver_refcount(false, namespace grpc_core { Resolver::Resolver(grpc_combiner* combiner) - : InternallyRefCountedWithTracing(&grpc_trace_resolver_refcount), + : InternallyRefCounted(&grpc_trace_resolver_refcount), 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 e9acbb7c41c..9da849a1017 100644 --- a/src/core/ext/filters/client_channel/resolver.h +++ b/src/core/ext/filters/client_channel/resolver.h @@ -44,7 +44,7 @@ namespace grpc_core { /// /// Note: All methods with a "Locked" suffix must be called from the /// combiner passed to the constructor. -class Resolver : public InternallyRefCountedWithTracing { +class Resolver : public InternallyRefCounted { public: // Not copyable nor movable. Resolver(const Resolver&) = delete; diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index a56db0201b8..0817b1dd392 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -1072,7 +1072,7 @@ ConnectedSubchannel::ConnectedSubchannel( grpc_core::RefCountedPtr channelz_subchannel, intptr_t socket_uuid) - : RefCountedWithTracing(&grpc_trace_stream_refcount), + : RefCounted(&grpc_trace_stream_refcount), channel_stack_(channel_stack), channelz_subchannel_(std::move(channelz_subchannel)), socket_uuid_(socket_uuid) {} diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index ec3b4d86e41..69c2456ec20 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -72,7 +72,7 @@ typedef struct grpc_subchannel_key grpc_subchannel_key; namespace grpc_core { -class ConnectedSubchannel : public RefCountedWithTracing { +class ConnectedSubchannel : public RefCounted { public: struct CallArgs { grpc_polling_entity* pollent; diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 99c675f503a..7377287e8cb 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -207,29 +207,6 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { gpr_free(peer_string); } -#ifndef NDEBUG -void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, const char* reason, - const char* file, int line) { - if (grpc_trace_chttp2_refcount.enabled()) { - const grpc_core::RefCount::Value val = t->refs.get(); - gpr_log(GPR_DEBUG, "chttp2:unref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]", - t, val, val - 1, reason, file, line); - } - if (!t->refs.Unref()) return; - grpc_core::Delete(t); -} - -void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason, - const char* file, int line) { - if (grpc_trace_chttp2_refcount.enabled()) { - const grpc_core::RefCount::Value val = t->refs.get(); - gpr_log(GPR_DEBUG, "chttp2: ref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]", - t, val, val + 1, reason, file, line); - } - t->refs.Ref(); -} -#endif - static const grpc_transport_vtable* get_vtable(void); /* Returns whether bdp is enabled */ @@ -481,7 +458,8 @@ static void init_keepalive_pings_if_enabled(grpc_chttp2_transport* t) { grpc_chttp2_transport::grpc_chttp2_transport( const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client, grpc_resource_user* resource_user) - : ep(ep), + : refs(1, &grpc_trace_chttp2_refcount), + ep(ep), peer_string(grpc_endpoint_get_peer(ep)), resource_user(resource_user), combiner(grpc_combiner_create()), diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 6aa68f5d4a9..341f5b3977f 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -792,10 +792,18 @@ void grpc_chttp2_stream_unref(grpc_chttp2_stream* s); grpc_chttp2_ref_transport(t, r, __FILE__, __LINE__) #define GRPC_CHTTP2_UNREF_TRANSPORT(t, r) \ grpc_chttp2_unref_transport(t, r, __FILE__, __LINE__) -void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, const char* reason, - const char* file, int line); -void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason, - const char* file, int line); +inline void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, + const char* reason, const char* file, + int line) { + if (t->refs.Unref(grpc_core::DebugLocation(file, line), reason)) { + grpc_core::Delete(t); + } +} +inline void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, + const char* reason, const char* file, + int line) { + t->refs.Ref(grpc_core::DebugLocation(file, line), reason); +} #else #define GRPC_CHTTP2_REF_TRANSPORT(t, r) grpc_chttp2_ref_transport(t) #define GRPC_CHTTP2_UNREF_TRANSPORT(t, r) grpc_chttp2_unref_transport(t) diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h index fe6301a3fcd..5ed52454bd7 100644 --- a/src/core/lib/debug/trace.h +++ b/src/core/lib/debug/trace.h @@ -102,8 +102,9 @@ typedef TraceFlag DebugOnlyTraceFlag; #else class DebugOnlyTraceFlag { public: - DebugOnlyTraceFlag(bool default_enabled, const char* name) {} - bool enabled() { return false; } + constexpr DebugOnlyTraceFlag(bool default_enabled, const char* name) {} + constexpr bool enabled() const { return false; } + constexpr const char* name() const { return "DebugOnlyTraceFlag"; } private: void set_enabled(bool enabled) {} diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h index 3eb510165e2..9053c60111f 100644 --- a/src/core/lib/gprpp/orphanable.h +++ b/src/core/lib/gprpp/orphanable.h @@ -90,104 +90,41 @@ class InternallyRefCounted : public Orphanable { template friend class RefCountedPtr; - InternallyRefCounted() = default; + // TraceFlagT is defined to accept both DebugOnlyTraceFlag and TraceFlag. + // 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) {} virtual ~InternallyRefCounted() = default; RefCountedPtr Ref() GRPC_MUST_USE_RESULT { IncrementRefCount(); return RefCountedPtr(static_cast(this)); } - - void Unref() { - if (refs_.Unref()) { - Delete(static_cast(this)); - } - } - - private: - void IncrementRefCount() { refs_.Ref(); } - - grpc_core::RefCount refs_; -}; - -// An alternative version of the InternallyRefCounted base class that -// supports tracing. This is intended to be used in cases where the -// object will be handled both by idiomatic C++ code using smart -// pointers and legacy code that is manually calling Ref() and Unref(). -// Once all of our code is converted to idiomatic C++, we may be able to -// eliminate this class. -template -class InternallyRefCountedWithTracing : public Orphanable { - public: - // Not copyable nor movable. - InternallyRefCountedWithTracing(const InternallyRefCountedWithTracing&) = - delete; - InternallyRefCountedWithTracing& operator=( - const InternallyRefCountedWithTracing&) = delete; - - GRPC_ABSTRACT_BASE_CLASS - - protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - - // Allow RefCountedPtr<> to access Unref() and IncrementRefCount(). - template - friend class RefCountedPtr; - - InternallyRefCountedWithTracing() - : InternallyRefCountedWithTracing(static_cast(nullptr)) {} - - explicit InternallyRefCountedWithTracing(TraceFlag* trace_flag) - : trace_flag_(trace_flag) {} - -#ifdef NDEBUG - explicit InternallyRefCountedWithTracing(DebugOnlyTraceFlag* trace_flag) - : InternallyRefCountedWithTracing() {} -#endif - - virtual ~InternallyRefCountedWithTracing() = default; - - RefCountedPtr Ref() GRPC_MUST_USE_RESULT { - IncrementRefCount(); + RefCountedPtr Ref(const DebugLocation& location, + const char* reason) GRPC_MUST_USE_RESULT { + IncrementRefCount(location, reason); return RefCountedPtr(static_cast(this)); } - RefCountedPtr Ref(const DebugLocation& location, - const char* reason) GRPC_MUST_USE_RESULT { - if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { - const grpc_core::RefCount::Value old_refs = refs_.get(); - gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s", - trace_flag_->name(), this, location.file(), location.line(), - old_refs, old_refs + 1, reason); - } - return Ref(); - } - - // TODO(roth): Once all of our code is converted to C++ and can use - // RefCountedPtr<> instead of manual ref-counting, make the Unref() methods - // private, since they will only be used by RefCountedPtr<>, which is a - // friend of this class. - void Unref() { if (refs_.Unref()) { Delete(static_cast(this)); } } - void Unref(const DebugLocation& location, const char* reason) { - if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { - const grpc_core::RefCount::Value old_refs = refs_.get(); - gpr_log(GPR_INFO, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s", - trace_flag_->name(), this, location.file(), location.line(), - old_refs, old_refs - 1, reason); + if (refs_.Unref(location, reason)) { + Delete(static_cast(this)); } - Unref(); } private: void IncrementRefCount() { refs_.Ref(); } + void IncrementRefCount(const DebugLocation& location, const char* reason) { + refs_.Ref(location, reason); + } - TraceFlag* trace_flag_ = nullptr; grpc_core::RefCount refs_; }; diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index 98de1a3653f..fa97ffcfed2 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -74,12 +74,34 @@ class RefCount { using Value = intptr_t; // `init` is the initial refcount stored in this object. - constexpr explicit RefCount(Value init = 1) : value_(init) {} + // + // TraceFlagT is defined to accept both DebugOnlyTraceFlag and TraceFlag. + // Note: RefCount tracing is only enabled on debug builds, even when a + // TraceFlag is used. + template + constexpr explicit RefCount(Value init = 1, TraceFlagT* trace_flag = nullptr) + : +#ifndef NDEBUG + trace_flag_(trace_flag), +#endif + value_(init) { + } // Increases the ref-count by `n`. void Ref(Value n = 1) { GPR_ATM_INC_ADD_THEN(value_.fetch_add(n, std::memory_order_relaxed)); } + void Ref(const DebugLocation& location, const char* reason, Value n = 1) { +#ifndef NDEBUG + if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { + const RefCount::Value old_refs = get(); + gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s", + trace_flag_->name(), this, location.file(), location.line(), + old_refs, old_refs + n, reason); + } +#endif + Ref(n); + } // Similar to Ref() with an assert on the ref-count being non-zero. void RefNonZero() { @@ -91,6 +113,17 @@ class RefCount { Ref(); #endif } + void RefNonZero(const DebugLocation& location, const char* reason) { +#ifndef NDEBUG + if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { + const RefCount::Value old_refs = get(); + gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s", + trace_flag_->name(), this, location.file(), location.line(), + old_refs, old_refs + 1, reason); + } +#endif + RefNonZero(); + } // Decrements the ref-count and returns true if the ref-count reaches 0. bool Unref() { @@ -99,10 +132,24 @@ class RefCount { GPR_DEBUG_ASSERT(prior > 0); return prior == 1; } - - Value get() const { return value_.load(std::memory_order_relaxed); } + bool Unref(const DebugLocation& location, const char* reason) { +#ifndef NDEBUG + if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { + const RefCount::Value old_refs = get(); + gpr_log(GPR_INFO, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s", + trace_flag_->name(), this, location.file(), location.line(), + old_refs, old_refs - 1, reason); + } +#endif + return Unref(); + } private: + Value get() const { return value_.load(std::memory_order_relaxed); } + +#ifndef NDEBUG + TraceFlag* trace_flag_; +#endif std::atomic value_; }; @@ -140,6 +187,12 @@ class RefCounted : public Impl { return RefCountedPtr(static_cast(this)); } + RefCountedPtr Ref(const DebugLocation& location, + const char* reason) GRPC_MUST_USE_RESULT { + IncrementRefCount(location, reason); + return RefCountedPtr(static_cast(this)); + } + // TODO(roth): Once all of our code is converted to C++ and can use // RefCountedPtr<> instead of manual ref-counting, make this method // private, since it will only be used by RefCountedPtr<>, which is a @@ -149,6 +202,11 @@ class RefCounted : public Impl { Delete(static_cast(this)); } } + void Unref(const DebugLocation& location, const char* reason) { + if (refs_.Unref(location, reason)) { + Delete(static_cast(this)); + } + } // Not copyable nor movable. RefCounted(const RefCounted&) = delete; @@ -159,7 +217,12 @@ class RefCounted : public Impl { protected: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - RefCounted() = default; + // TraceFlagT is defined to accept both DebugOnlyTraceFlag and TraceFlag. + // 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) {} // Note: Depending on the Impl used, this dtor can be implicitly virtual. ~RefCounted() = default; @@ -170,87 +233,10 @@ class RefCounted : public Impl { friend class RefCountedPtr; void IncrementRefCount() { refs_.Ref(); } - - RefCount refs_; -}; - -// An alternative version of the RefCounted base class that -// supports tracing. This is intended to be used in cases where the -// object will be handled both by idiomatic C++ code using smart -// pointers and legacy code that is manually calling Ref() and Unref(). -// Once all of our code is converted to idiomatic C++, we may be able to -// eliminate this class. -template -class RefCountedWithTracing : public Impl { - public: - RefCountedPtr Ref() GRPC_MUST_USE_RESULT { - IncrementRefCount(); - return RefCountedPtr(static_cast(this)); + void IncrementRefCount(const DebugLocation& location, const char* reason) { + refs_.Ref(location, reason); } - RefCountedPtr Ref(const DebugLocation& location, - const char* reason) GRPC_MUST_USE_RESULT { - if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { - const RefCount::Value old_refs = refs_.get(); - gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s", - trace_flag_->name(), this, location.file(), location.line(), - old_refs, old_refs + 1, reason); - } - return Ref(); - } - - // TODO(roth): Once all of our code is converted to C++ and can use - // RefCountedPtr<> instead of manual ref-counting, make the Unref() methods - // private, since they will only be used by RefCountedPtr<>, which is a - // friend of this class. - - void Unref() { - if (refs_.Unref()) { - Delete(static_cast(this)); - } - } - - void Unref(const DebugLocation& location, const char* reason) { - if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { - const RefCount::Value old_refs = refs_.get(); - gpr_log(GPR_INFO, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s", - trace_flag_->name(), this, location.file(), location.line(), - old_refs, old_refs - 1, reason); - } - Unref(); - } - - // Not copyable nor movable. - RefCountedWithTracing(const RefCountedWithTracing&) = delete; - RefCountedWithTracing& operator=(const RefCountedWithTracing&) = delete; - - GRPC_ABSTRACT_BASE_CLASS - - protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - - RefCountedWithTracing() - : RefCountedWithTracing(static_cast(nullptr)) {} - - explicit RefCountedWithTracing(TraceFlag* trace_flag) - : trace_flag_(trace_flag) {} - -#ifdef NDEBUG - explicit RefCountedWithTracing(DebugOnlyTraceFlag* trace_flag) - : RefCountedWithTracing() {} -#endif - - // Note: Depending on the Impl used, this dtor can be implicitly virtual. - ~RefCountedWithTracing() = default; - - private: - // Allow RefCountedPtr<> to access IncrementRefCount(). - template - friend class RefCountedPtr; - - void IncrementRefCount() { refs_.Ref(); } - - TraceFlag* trace_flag_ = nullptr; RefCount refs_; }; diff --git a/src/core/lib/gprpp/ref_counted_ptr.h b/src/core/lib/gprpp/ref_counted_ptr.h index facd7c6dce6..1ed5d584c70 100644 --- a/src/core/lib/gprpp/ref_counted_ptr.h +++ b/src/core/lib/gprpp/ref_counted_ptr.h @@ -24,6 +24,7 @@ #include #include +#include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/memory.h" namespace grpc_core { @@ -55,15 +56,13 @@ class RefCountedPtr { // Move assignment. RefCountedPtr& operator=(RefCountedPtr&& other) { - if (value_ != nullptr) value_->Unref(); - value_ = other.value_; + reset(other.value_); other.value_ = nullptr; return *this; } template RefCountedPtr& operator=(RefCountedPtr&& other) { - if (value_ != nullptr) value_->Unref(); - value_ = other.value_; + reset(other.value_); other.value_ = nullptr; return *this; } @@ -86,8 +85,7 @@ class RefCountedPtr { // Note: Order of reffing and unreffing is important here in case value_ // and other.value_ are the same object. if (other.value_ != nullptr) other.value_->IncrementRefCount(); - if (value_ != nullptr) value_->Unref(); - value_ = other.value_; + reset(other.value_); return *this; } template @@ -97,8 +95,7 @@ class RefCountedPtr { // Note: Order of reffing and unreffing is important here in case value_ // and other.value_ are the same object. if (other.value_ != nullptr) other.value_->IncrementRefCount(); - if (value_ != nullptr) value_->Unref(); - value_ = other.value_; + reset(other.value_); return *this; } @@ -107,21 +104,29 @@ class RefCountedPtr { } // If value is non-null, we take ownership of a ref to it. - void reset(T* value) { + void reset(T* value = nullptr) { if (value_ != nullptr) value_->Unref(); value_ = value; } + void reset(const DebugLocation& location, const char* reason, + T* value = nullptr) { + if (value_ != nullptr) value_->Unref(location, reason); + value_ = value; + } template - void reset(Y* value) { + void reset(Y* value = nullptr) { static_assert(std::has_virtual_destructor::value, "T does not have a virtual dtor"); if (value_ != nullptr) value_->Unref(); value_ = value; } - - void reset() { - if (value_ != nullptr) value_->Unref(); - value_ = nullptr; + template + void reset(const DebugLocation& location, const char* reason, + Y* value = nullptr) { + static_assert(std::has_virtual_destructor::value, + "T does not have a virtual dtor"); + if (value_ != nullptr) value_->Unref(location, reason); + value_ = value; } // TODO(roth): This method exists solely as a transition mechanism to allow diff --git a/test/core/gprpp/orphanable_test.cc b/test/core/gprpp/orphanable_test.cc index 546f395cef6..fe13df0d0d0 100644 --- a/test/core/gprpp/orphanable_test.cc +++ b/test/core/gprpp/orphanable_test.cc @@ -83,11 +83,11 @@ TEST(OrphanablePtr, InternallyRefCounted) { // things build properly in both debug and non-debug cases. DebugOnlyTraceFlag baz_tracer(true, "baz"); -class Baz : public InternallyRefCountedWithTracing { +class Baz : public InternallyRefCounted { public: Baz() : Baz(0) {} explicit Baz(int value) - : InternallyRefCountedWithTracing(&baz_tracer), value_(value) {} + : InternallyRefCounted(&baz_tracer), value_(value) {} void Orphan() override { Unref(); } int value() const { return value_; } diff --git a/test/core/gprpp/ref_counted_ptr_test.cc b/test/core/gprpp/ref_counted_ptr_test.cc index 512687eb679..96dbdf884b0 100644 --- a/test/core/gprpp/ref_counted_ptr_test.cc +++ b/test/core/gprpp/ref_counted_ptr_test.cc @@ -163,9 +163,9 @@ TEST(MakeRefCounted, Args) { TraceFlag foo_tracer(true, "foo"); -class FooWithTracing : public RefCountedWithTracing { +class FooWithTracing : public RefCounted { public: - FooWithTracing() : RefCountedWithTracing(&foo_tracer) {} + FooWithTracing() : RefCounted(&foo_tracer) {} }; TEST(RefCountedPtr, RefCountedWithTracing) { diff --git a/test/core/gprpp/ref_counted_test.cc b/test/core/gprpp/ref_counted_test.cc index 5aba1634efb..1955be33115 100644 --- a/test/core/gprpp/ref_counted_test.cc +++ b/test/core/gprpp/ref_counted_test.cc @@ -74,9 +74,9 @@ TEST(RefCountedNonPolymorphic, ExtraRef) { // things build properly in both debug and non-debug cases. DebugOnlyTraceFlag foo_tracer(true, "foo"); -class FooWithTracing : public RefCountedWithTracing { +class FooWithTracing : public RefCounted { public: - FooWithTracing() : RefCountedWithTracing(&foo_tracer) {} + FooWithTracing() : RefCounted(&foo_tracer) {} }; TEST(RefCountedWithTracing, Basic) { @@ -92,10 +92,9 @@ TEST(RefCountedWithTracing, Basic) { } class FooNonPolymorphicWithTracing - : public RefCountedWithTracing { + : public RefCounted { public: - FooNonPolymorphicWithTracing() : RefCountedWithTracing(&foo_tracer) {} + FooNonPolymorphicWithTracing() : RefCounted(&foo_tracer) {} }; TEST(RefCountedNonPolymorphicWithTracing, Basic) { From 6311ddbe4b70d5a83dbf0970f8ce456bb46fe6d2 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 3 Dec 2018 12:11:15 +0100 Subject: [PATCH 0404/2143] BAZEL_INTERNAL_INVOCATION_ID is deprecated --- .../internal_ci/linux/grpc_bazel_on_foundry_base.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index 74778d9d291..d35bbbd2756 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -15,8 +15,8 @@ set -ex -# A temporary solution to give Kokoro credentials. -# The file name 4321_grpc-testing-service needs to match auth_credential in +# A temporary solution to give Kokoro credentials. +# The file name 4321_grpc-testing-service needs to match auth_credential in # the build config. mkdir -p ${KOKORO_KEYSTORE_DIR} cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service @@ -35,14 +35,15 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc # to get "bazel" link for kokoro build, we need to generate -# invocation UUID, set an env var for bazel to pick it up -# and upload "bazel_invocation_ids" file as artifact. -export BAZEL_INTERNAL_INVOCATION_ID="$(uuidgen)" -echo "${BAZEL_INTERNAL_INVOCATION_ID}" >"${KOKORO_ARTIFACTS_DIR}/bazel_invocation_ids" +# invocation UUID, set a flag for bazel to use it +# and upload "bazel_invocation_ids" file as artifact. +BAZEL_INVOCATION_ID="$(uuidgen)" +echo "${BAZEL_INVOCATION_ID}" >"${KOKORO_ARTIFACTS_DIR}/bazel_invocation_ids" bazel \ --bazelrc=tools/remote_build/kokoro.bazelrc \ test \ + --invocation_id="${BAZEL_INVOCATION_ID}" \ $@ \ -- //test/... || FAILED="true" From daa1ffb855bffe65be25ec2cebddf89c7ee883a0 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 3 Dec 2018 12:13:35 +0100 Subject: [PATCH 0405/2143] bazel bes_best_effort flag is deprecated --- tools/remote_build/kokoro.bazelrc | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/remote_build/kokoro.bazelrc b/tools/remote_build/kokoro.bazelrc index 11462bd301c..2fbdd3ce020 100644 --- a/tools/remote_build/kokoro.bazelrc +++ b/tools/remote_build/kokoro.bazelrc @@ -26,7 +26,6 @@ build --auth_credentials=/tmpfs/src/keystore/4321_grpc-testing-service build --auth_scope=https://www.googleapis.com/auth/cloud-source-tools build --bes_backend=buildeventservice.googleapis.com -build --bes_best_effort=false build --bes_timeout=600s build --project_id=grpc-testing From b021add5e489052d2b7823e72634e87e296f3b26 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 3 Dec 2018 15:17:52 +0100 Subject: [PATCH 0406/2143] C#: avoid unnecessary ifdefine in NUnitMain.cs --- src/csharp/Grpc.Core.Tests/NUnitMain.cs | 6 +----- src/csharp/Grpc.Examples.Tests/NUnitMain.cs | 6 +----- src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs | 6 +----- src/csharp/Grpc.IntegrationTesting/NUnitMain.cs | 6 +----- src/csharp/Grpc.Reflection.Tests/NUnitMain.cs | 6 +----- src/csharp/Grpc.Tools.Tests/NUnitMain.cs | 4 ---- 6 files changed, 5 insertions(+), 29 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/NUnitMain.cs b/src/csharp/Grpc.Core.Tests/NUnitMain.cs index 221a6b823a4..3b206603f14 100644 --- a/src/csharp/Grpc.Core.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Core.Tests/NUnitMain.cs @@ -34,11 +34,7 @@ namespace Grpc.Core.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_1 || NETCOREAPP2_1 - return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); -#else - return new AutoRun().Execute(args); -#endif + return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); } } } diff --git a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs index 0b9a5258ef4..107df648099 100644 --- a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs @@ -34,11 +34,7 @@ namespace Grpc.Examples.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_1 || NETCOREAPP2_1 - return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); -#else - return new AutoRun().Execute(args); -#endif + return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); } } } diff --git a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs index f5091863b84..db6d32a5b25 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs @@ -34,11 +34,7 @@ namespace Grpc.HealthCheck.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_1 || NETCOREAPP2_1 - return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); -#else - return new AutoRun().Execute(args); -#endif + return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); } } } diff --git a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs index 6265953622c..4135186275d 100644 --- a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs +++ b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs @@ -34,11 +34,7 @@ namespace Grpc.IntegrationTesting { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_1 || NETCOREAPP2_1 - return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); -#else - return new AutoRun().Execute(args); -#endif + return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); } } } diff --git a/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs b/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs index 1be7f6542b3..de4b4af6cfa 100644 --- a/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs @@ -34,11 +34,7 @@ namespace Grpc.Reflection.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_1 || NETCOREAPP2_1 - return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); -#else - return new AutoRun().Execute(args); -#endif + return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); } } } diff --git a/src/csharp/Grpc.Tools.Tests/NUnitMain.cs b/src/csharp/Grpc.Tools.Tests/NUnitMain.cs index 13ba8b51d09..d30d608aa33 100644 --- a/src/csharp/Grpc.Tools.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Tools.Tests/NUnitMain.cs @@ -24,10 +24,6 @@ namespace Grpc.Tools.Tests static class NUnitMain { public static int Main(string[] args) => -#if NETCOREAPP1_1 || NETCOREAPP2_1 new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); -#else - new AutoRun().Execute(args); -#endif }; } From 5861f082607344ed42215ac341e97e4b4bbf0abc Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 28 Nov 2018 15:39:05 +0100 Subject: [PATCH 0407/2143] basic tcp_trace support for windows --- src/core/lib/iomgr/tcp_windows.cc | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 64c4a56ae95..d7351c3661f 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -42,6 +42,7 @@ #include "src/core/lib/iomgr/tcp_windows.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" #if defined(__MSYS__) && defined(GPR_ARCH_64) /* Nasty workaround for nasty bug when using the 64 bits msys compiler @@ -182,6 +183,10 @@ static void on_read(void* tcpp, grpc_error* error) { grpc_slice sub; grpc_winsocket_callback_info* info = &socket->read_info; + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p on_read", tcp); + } + GRPC_ERROR_REF(error); if (error == GRPC_ERROR_NONE) { @@ -194,7 +199,21 @@ static void on_read(void* tcpp, grpc_error* error) { if (info->bytes_transfered != 0 && !tcp->shutting_down) { sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); grpc_slice_buffer_add(tcp->read_slices, sub); + + if (grpc_tcp_trace.enabled()) { + size_t i; + for (i = 0; i < tcp->read_slices->count; i++) { + char* dump = grpc_dump_slice(tcp->read_slices->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); + } + } } else { + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p unref read_slice", tcp); + } grpc_slice_unref_internal(tcp->read_slice); error = tcp->shutting_down ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -219,6 +238,10 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, DWORD flags = 0; WSABUF buffer; + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p win_read", tcp); + } + if (tcp->shutting_down) { GRPC_CLOSURE_SCHED( cb, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -275,6 +298,10 @@ static void on_write(void* tcpp, grpc_error* error) { grpc_winsocket_callback_info* info = &handle->write_info; grpc_closure* cb; + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p on_write", tcp); + } + GRPC_ERROR_REF(error); gpr_mu_lock(&tcp->mu); @@ -308,6 +335,16 @@ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, WSABUF* buffers = local_buffers; size_t len; + if (grpc_tcp_trace.enabled()) { + size_t i; + for (i = 0; i < slices->count; i++) { + char* data = + grpc_dump_slice(slices->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); + } + } + if (tcp->shutting_down) { GRPC_CLOSURE_SCHED( cb, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( From b0139e15425196be518b251dbdfa3b86648b4740 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 3 Dec 2018 16:58:05 +0100 Subject: [PATCH 0408/2143] better slice management for win_read --- src/core/lib/iomgr/tcp_windows.cc | 57 ++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index d7351c3661f..658da9c46bf 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -113,7 +113,10 @@ typedef struct grpc_tcp { grpc_closure* read_cb; grpc_closure* write_cb; - grpc_slice read_slice; + + /* garbage after the last read */ + grpc_slice_buffer last_read_buffer; + grpc_slice_buffer* write_slices; grpc_slice_buffer* read_slices; @@ -132,6 +135,7 @@ static void tcp_free(grpc_tcp* tcp) { grpc_winsocket_destroy(tcp->socket); gpr_mu_destroy(&tcp->mu); gpr_free(tcp->peer_string); + grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); if (tcp->shutting_down) GRPC_ERROR_UNREF(tcp->shutdown_error); gpr_free(tcp); @@ -180,7 +184,6 @@ static void on_read(void* tcpp, grpc_error* error) { grpc_tcp* tcp = (grpc_tcp*)tcpp; grpc_closure* cb = tcp->read_cb; grpc_winsocket* socket = tcp->socket; - grpc_slice sub; grpc_winsocket_callback_info* info = &socket->read_info; if (grpc_tcp_trace.enabled()) { @@ -194,11 +197,19 @@ static void on_read(void* tcpp, grpc_error* error) { char* utf8_message = gpr_format_message(info->wsa_error); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(utf8_message); gpr_free(utf8_message); - grpc_slice_unref_internal(tcp->read_slice); + grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); } else { if (info->bytes_transfered != 0 && !tcp->shutting_down) { - sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); - grpc_slice_buffer_add(tcp->read_slices, sub); + GPR_ASSERT((size_t)info->bytes_transfered <= tcp->read_slices->length); + if (static_cast(info->bytes_transfered) != + tcp->read_slices->length) { + grpc_slice_buffer_trim_end( + tcp->read_slices, + tcp->read_slices->length - + static_cast(info->bytes_transfered), + &tcp->last_read_buffer); + } + GPR_ASSERT((size_t)info->bytes_transfered == tcp->read_slices->length); if (grpc_tcp_trace.enabled()) { size_t i; @@ -214,7 +225,7 @@ static void on_read(void* tcpp, grpc_error* error) { if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p unref read_slice", tcp); } - grpc_slice_unref_internal(tcp->read_slice); + grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); error = tcp->shutting_down ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "TCP stream shutting down", &tcp->shutdown_error, 1) @@ -228,6 +239,8 @@ static void on_read(void* tcpp, grpc_error* error) { GRPC_CLOSURE_SCHED(cb, 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_tcp* tcp = (grpc_tcp*)ep; @@ -236,7 +249,8 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, int status; DWORD bytes_read = 0; DWORD flags = 0; - WSABUF buffer; + WSABUF buffers[MAX_WSABUF_COUNT]; + size_t i; if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p win_read", tcp); @@ -252,18 +266,27 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, tcp->read_cb = cb; tcp->read_slices = read_slices; grpc_slice_buffer_reset_and_unref_internal(read_slices); + grpc_slice_buffer_swap(read_slices, &tcp->last_read_buffer); - tcp->read_slice = GRPC_SLICE_MALLOC(8192); + if (tcp->read_slices->length < DEFAULT_TARGET_READ_SIZE / 2 && + tcp->read_slices->count < MAX_WSABUF_COUNT) { + // TODO(jtattermusch): slice should be allocated using resource quota + grpc_slice_buffer_add(tcp->read_slices, + GRPC_SLICE_MALLOC(DEFAULT_TARGET_READ_SIZE)); + } - buffer.len = (ULONG)GRPC_SLICE_LENGTH( - tcp->read_slice); // we know slice size fits in 32bit. - buffer.buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slice); + GPR_ASSERT(tcp->read_slices->count <= MAX_WSABUF_COUNT); + for (i = 0; i < tcp->read_slices->count; i++) { + buffers[i].len = (ULONG)GRPC_SLICE_LENGTH( + tcp->read_slices->slices[i]); // we know slice size fits in 32bit. + buffers[i].buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slices->slices[i]); + } TCP_REF(tcp, "read"); /* First let's try a synchronous, non-blocking read. */ - status = - WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, NULL, NULL); + status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count, + &bytes_read, &flags, NULL, NULL); info->wsa_error = status == 0 ? 0 : WSAGetLastError(); /* Did we get data immediately ? Yay. */ @@ -275,8 +298,8 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, /* Otherwise, let's retry, by queuing a read. */ memset(&tcp->socket->read_info.overlapped, 0, sizeof(OVERLAPPED)); - status = WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, - &info->overlapped, NULL); + status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count, + &bytes_read, &flags, &info->overlapped, NULL); if (status != 0) { int wsa_error = WSAGetLastError(); @@ -330,7 +353,7 @@ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, unsigned i; DWORD bytes_sent; int status; - WSABUF local_buffers[16]; + WSABUF local_buffers[MAX_WSABUF_COUNT]; WSABUF* allocated = NULL; WSABUF* buffers = local_buffers; size_t len; @@ -449,6 +472,7 @@ 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"); } @@ -497,6 +521,7 @@ grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket, GRPC_CLOSURE_INIT(&tcp->on_read, on_read, tcp, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&tcp->on_write, on_write, tcp, grpc_schedule_on_exec_ctx); 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); From 1b115db5dbe5f79c0a40227f21b183d98a014245 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Mon, 3 Dec 2018 09:03:15 -0800 Subject: [PATCH 0409/2143] re-order ALTS log messages. --- .../tsi/alts/handshaker/alts_handshaker_client.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc index 1de6264183a..43d0979f4b9 100644 --- a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +++ b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc @@ -116,12 +116,13 @@ void alts_handshaker_client_handle_response(alts_handshaker_client* c, "cb is nullptr in alts_tsi_handshaker_handle_response()"); return; } - if (handshaker == nullptr || recv_buffer == nullptr) { + if (handshaker == nullptr) { gpr_log(GPR_ERROR, - "Invalid arguments to alts_tsi_handshaker_handle_response()"); + "handshaker is nullptr in alts_tsi_handshaker_handle_response()"); cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr); return; } + /* TSI handshake has been shutdown. */ if (alts_tsi_handshaker_has_shutdown(handshaker)) { gpr_log(GPR_ERROR, "TSI handshake shutdown"); cb(TSI_HANDSHAKE_SHUTDOWN, user_data, nullptr, 0, nullptr); @@ -133,6 +134,12 @@ void alts_handshaker_client_handle_response(alts_handshaker_client* c, cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr); return; } + if (recv_buffer == nullptr) { + gpr_log(GPR_ERROR, + "recv_buffer is nullptr in alts_tsi_handshaker_handle_response()"); + cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr); + return; + } grpc_gcp_handshaker_resp* resp = alts_tsi_utils_deserialize_response(recv_buffer); grpc_byte_buffer_destroy(client->recv_buffer); From c12aabc6a7d67e9f786125480ed6b17e25278c98 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Mon, 3 Dec 2018 10:14:46 -0800 Subject: [PATCH 0410/2143] Clang format --- test/cpp/end2end/client_callback_end2end_test.cc | 2 +- test/cpp/end2end/test_service_impl.cc | 6 +++--- test/cpp/end2end/test_service_impl.h | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 3871c644be4..98bd99fac69 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -219,7 +219,7 @@ TEST_P(ClientCallbackEnd2endTest, SendClientInitialMetadata) { gpr_log(GPR_ERROR, s.error_message().c_str()); gpr_log(GPR_ERROR, s.error_details().c_str()); GPR_ASSERT(s.ok()); - + std::lock_guard l(mu); done = true; cv.notify_one(); diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 8f973182520..4eefe58fa7c 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -181,9 +181,9 @@ Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, return Status::OK; } -Status TestServiceImpl::CheckClientInitialMetadata( - ServerContext* context, const SimpleRequest* request, - SimpleResponse* response) { +Status TestServiceImpl::CheckClientInitialMetadata(ServerContext* context, + const SimpleRequest* request, + SimpleResponse* response) { EXPECT_EQ(MetadataMatchCount(context->client_metadata(), kCheckClientInitialMetadataKey, kCheckClientInitialMetadataVal), diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h index 2c63aa4dab3..ad0b230907a 100644 --- a/test/cpp/end2end/test_service_impl.h +++ b/test/cpp/end2end/test_service_impl.h @@ -55,9 +55,9 @@ class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { Status Echo(ServerContext* context, const EchoRequest* request, EchoResponse* response) override; - Status CheckClientInitialMetadata( - ServerContext* context, const SimpleRequest* request, - SimpleResponse* response) override; + Status CheckClientInitialMetadata(ServerContext* context, + const SimpleRequest* request, + SimpleResponse* response) override; // Unimplemented is left unimplemented to test the returned error. From 97ec5c1d681d74a53c55589db3b3c90aaf7b8fc9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 3 Dec 2018 11:53:33 -0800 Subject: [PATCH 0411/2143] Bump version to v1.17.0 --- BUILD | 4 ++-- CMakeLists.txt | 2 +- Makefile | 6 +++--- build.yaml | 4 ++-- .../helloworld/HelloWorld.xcodeproj/project.pbxproj | 8 ++++++++ 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_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/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 +- 34 files changed, 51 insertions(+), 43 deletions(-) diff --git a/BUILD b/BUILD index 989bc02a0b8..eeb1a2fa620 100644 --- a/BUILD +++ b/BUILD @@ -66,9 +66,9 @@ config_setting( # This should be updated along with build.yaml g_stands_for = "gizmo" -core_version = "7.0.0-pre3" +core_version = "7.0.0" -version = "1.17.0-pre3" +version = "1.17.0" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 87f0846fd1e..58525d6c6f1 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.17.0-pre3") +set(PACKAGE_VERSION "1.17.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 1e32de5e6b2..02273df21d1 100644 --- a/Makefile +++ b/Makefile @@ -437,9 +437,9 @@ E = @echo Q = @ endif -CORE_VERSION = 7.0.0-pre3 -CPP_VERSION = 1.17.0-pre3 -CSHARP_VERSION = 1.17.0-pre3 +CORE_VERSION = 7.0.0 +CPP_VERSION = 1.17.0 +CSHARP_VERSION = 1.17.0 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/build.yaml b/build.yaml index b8b002ac149..62e07f64e42 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-pre3 + core_version: 7.0.0 g_stands_for: gizmo - version: 1.17.0-pre3 + version: 1.17.0 filegroups: - name: alts_proto headers: diff --git a/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj b/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj index df5c40cda20..e067e82b3de 100644 --- a/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj +++ b/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj @@ -132,6 +132,8 @@ TargetAttributes = { 5E36905F1B2A23800040F884 = { CreatedOnToolsVersion = 6.2; + DevelopmentTeam = EQHXZ8M8AV; + ProvisioningStyle = Manual; }; }; }; @@ -321,9 +323,12 @@ baseConfigurationReference = DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = EQHXZ8M8AV; INFOPLIST_FILE = HelloWorld/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Google Development"; }; name = Debug; }; @@ -332,9 +337,12 @@ baseConfigurationReference = 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = HelloWorld/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 35c446ede37..73c87942430 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.17.0-pre3' - version = '0.0.6-pre3' + # version = '1.17.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.17.0-pre3' + grpc_version = '1.17.0' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 674ea75243e..ff4d79426fe 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.17.0-pre3' + version = '1.17.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 5f01dbaeef1..d7050906e43 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.17.0-pre3' + version = '1.17.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 6289a14205b..955f3682f67 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.17.0-pre3' + version = '1.17.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 42d6819e30c..fb46ab46704 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.17.0-pre3' + version = '1.17.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 aad44ab1398..bd2fffcc555 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.17.0RC3 - 1.17.0RC3 + 1.17.0 + 1.17.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 6fdd2a960a6..ed30130f33d 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-pre3"; } +const char* grpc_version_string(void) { return "7.0.0"; } const char* grpc_g_stands_for(void) { return "gizmo"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 97d7670396a..0a3fd804fe5 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.17.0-pre3"; } +grpc::string Version() { return "1.17.0"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 183651bfe00..4741e08cf53 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.17.0-pre3 + 1.17.0 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 5c28018e433..aa881867ec5 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.17.0-pre3"; + public const string CurrentVersion = "1.17.0"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 4ade233f767..1b860c95380 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.17.0-pre3 +set VERSION=1.17.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 e4b91a626ff..b9f9cf4dbb8 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.17.0-pre3 +set VERSION=1.17.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 db1dc596696..c72751d1c6f 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.17.0-pre3' + v = '1.17.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 32e3be3a8a5..fa5b04612ce 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.17.0-pre3" +#define GRPC_OBJC_VERSION_STRING @"1.17.0" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 278348c2093..1cfbf6f705d 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.17.0-pre3" -#define GRPC_C_VERSION_STRING @"7.0.0-pre3" +#define GRPC_OBJC_VERSION_STRING @"1.17.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 e1d36bfc3fc..e529c749dbd 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.17.0RC3" +#define PHP_GRPC_VERSION "1.17.0" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index a1e58cc3ed8..0677d1b9cf5 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.17.0rc3""" +__version__ = """1.17.0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 2182471388f..8cbd5b24f25 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.17.0rc3' +VERSION = '1.17.0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 147e8840a61..222d77aab18 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.17.0rc3' +VERSION = '1.17.0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index ac41352b34b..daa8a84edb3 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.17.0rc3' +VERSION = '1.17.0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 0083836a337..af9ab31aa13 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.17.0rc3' +VERSION = '1.17.0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index e4e5d85764d..887f8c105bc 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.17.0rc3' +VERSION = '1.17.0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 23906096225..6b09d61c0b4 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.17.0.pre3' + VERSION = '1.17.0' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index af6255d822a..9ae2162335d 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.17.0.pre3' + VERSION = '1.17.0' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index a65fcd36da5..4070200384b 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.17.0rc3' +VERSION = '1.17.0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 766c5aeb77d..88bfada6917 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.17.0-pre3 +PROJECT_NUMBER = 1.17.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 7968d182c8d..31f90cf1b66 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.17.0-pre3 +PROJECT_NUMBER = 1.17.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 85f6bfce56a..a72cf688a2d 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-pre3 +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 1ebb0ee8c4d..b54b441e3d8 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-pre3 +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 570599cfc60c26e347ca8c2d1a9ab46607051734 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 30 Nov 2018 01:59:15 -0800 Subject: [PATCH 0412/2143] Cancel still-active c-ares queries after 10 seconds to avoid chance of deadlock --- include/grpc/impl/codegen/grpc_types.h | 5 ++ .../resolver/dns/c_ares/dns_resolver_ares.cc | 10 +++- .../dns/c_ares/grpc_ares_ev_driver.cc | 36 +++++++++++ .../resolver/dns/c_ares/grpc_ares_ev_driver.h | 1 + .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 12 ++-- .../resolver/dns/c_ares/grpc_ares_wrapper.h | 4 +- .../dns/c_ares/grpc_ares_wrapper_fallback.cc | 3 +- src/core/lib/iomgr/resolve_address.h | 2 +- .../dns_resolver_connectivity_test.cc | 2 +- .../resolvers/dns_resolver_cooldown_test.cc | 6 +- test/core/end2end/fuzzers/api_fuzzer.cc | 2 +- test/core/end2end/goaway_server_test.cc | 6 +- test/cpp/naming/cancel_ares_query_test.cc | 59 +++++++++++++++++-- 13 files changed, 126 insertions(+), 22 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 17a43fab0f1..58f02dc7221 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, 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 + * entirely. */ +#define GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS "grpc.dns_ares_query_timeout" /** \} */ /** Result of a grpc call. If the caller satisfies the prerequisites of a 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 90bc88961d9..4ebc2c8161c 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 @@ -122,6 +122,8 @@ class AresDnsResolver : public Resolver { char* service_config_json_ = nullptr; // has shutdown been initiated bool shutdown_initiated_ = false; + // timeout in milliseconds for active DNS queries + int query_timeout_ms_; }; AresDnsResolver::AresDnsResolver(const ResolverArgs& args) @@ -159,6 +161,11 @@ AresDnsResolver::AresDnsResolver(const ResolverArgs& args) grpc_combiner_scheduler(combiner())); GRPC_CLOSURE_INIT(&on_resolved_, OnResolvedLocked, this, grpc_combiner_scheduler(combiner())); + const grpc_arg* query_timeout_ms_arg = + grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS); + query_timeout_ms_ = grpc_channel_arg_get_integer( + query_timeout_ms_arg, + {GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, 0, INT_MAX}); } AresDnsResolver::~AresDnsResolver() { @@ -410,7 +417,8 @@ void AresDnsResolver::StartResolvingLocked() { pending_request_ = grpc_dns_lookup_ares_locked( dns_server_, name_to_resolve_, kDefaultPort, interested_parties_, &on_resolved_, &lb_addresses_, true /* check_grpclb */, - request_service_config_ ? &service_config_json_ : nullptr, combiner()); + request_service_config_ ? &service_config_json_ : nullptr, + query_timeout_ms_, combiner()); last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc index fdbd07ebf51..f42b1e309df 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -33,6 +33,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/timer.h" typedef struct fd_node { /** the owner of this fd node */ @@ -76,6 +77,12 @@ struct grpc_ares_ev_driver { grpc_ares_request* request; /** Owned by the ev_driver. Creates new GrpcPolledFd's */ grpc_core::UniquePtr polled_fd_factory; + /** query timeout in milliseconds */ + int query_timeout_ms; + /** alarm to cancel active queries */ + grpc_timer query_timeout; + /** cancels queries on a timeout */ + grpc_closure on_timeout_locked; }; static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver); @@ -116,8 +123,11 @@ static void fd_node_shutdown_locked(fd_node* fdn, const char* reason) { } } +static void on_timeout_locked(void* arg, grpc_error* error); + grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set, + int query_timeout_ms, grpc_combiner* combiner, grpc_ares_request* request) { *ev_driver = grpc_core::New(); @@ -146,6 +156,9 @@ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, grpc_core::NewGrpcPolledFdFactory((*ev_driver)->combiner); (*ev_driver) ->polled_fd_factory->ConfigureAresChannelLocked((*ev_driver)->channel); + GRPC_CLOSURE_INIT(&(*ev_driver)->on_timeout_locked, on_timeout_locked, + *ev_driver, grpc_combiner_scheduler(combiner)); + (*ev_driver)->query_timeout_ms = query_timeout_ms; return GRPC_ERROR_NONE; } @@ -155,6 +168,7 @@ void grpc_ares_ev_driver_on_queries_complete_locked( // is working, grpc_ares_notify_on_event_locked will shut down the // fds; if it's not working, there are no fds to shut down. ev_driver->shutting_down = true; + grpc_timer_cancel(&ev_driver->query_timeout); grpc_ares_ev_driver_unref(ev_driver); } @@ -185,6 +199,17 @@ static fd_node* pop_fd_node_locked(fd_node** head, ares_socket_t as) { return nullptr; } +static void on_timeout_locked(void* arg, grpc_error* error) { + grpc_ares_ev_driver* driver = static_cast(arg); + GRPC_CARES_TRACE_LOG( + "ev_driver=%p on_timeout_locked. driver->shutting_down=%d. err=%s", + driver, driver->shutting_down, grpc_error_string(error)); + if (!driver->shutting_down && error == GRPC_ERROR_NONE) { + grpc_ares_ev_driver_shutdown_locked(driver); + } + grpc_ares_ev_driver_unref(driver); +} + static void on_readable_locked(void* arg, grpc_error* error) { fd_node* fdn = static_cast(arg); grpc_ares_ev_driver* ev_driver = fdn->ev_driver; @@ -314,6 +339,17 @@ void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) { if (!ev_driver->working) { ev_driver->working = true; grpc_ares_notify_on_event_locked(ev_driver); + grpc_millis timeout = + ev_driver->query_timeout_ms == 0 + ? GRPC_MILLIS_INF_FUTURE + : ev_driver->query_timeout_ms + grpc_core::ExecCtx::Get()->Now(); + GRPC_CARES_TRACE_LOG( + "ev_driver=%p grpc_ares_ev_driver_start_locked. timeout in %" PRId64 + " ms", + ev_driver, timeout); + grpc_ares_ev_driver_ref(ev_driver); + grpc_timer_init(&ev_driver->query_timeout, timeout, + &ev_driver->on_timeout_locked); } } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h index 671c537fe72..b8cefd9470e 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h @@ -43,6 +43,7 @@ ares_channel* grpc_ares_ev_driver_get_channel_locked( created successfully. */ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set, + int query_timeout_ms, grpc_combiner* combiner, grpc_ares_request* request); 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 582e2203fc7..55715869b63 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 @@ -359,7 +359,7 @@ done: void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( grpc_ares_request* r, const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, - bool check_grpclb, grpc_combiner* combiner) { + bool check_grpclb, int query_timeout_ms, grpc_combiner* combiner) { grpc_error* error = GRPC_ERROR_NONE; grpc_ares_hostbyname_request* hr = nullptr; ares_channel* channel = nullptr; @@ -388,7 +388,7 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( port = gpr_strdup(default_port); } error = grpc_ares_ev_driver_create_locked(&r->ev_driver, interested_parties, - combiner, r); + query_timeout_ms, combiner, r); if (error != GRPC_ERROR_NONE) goto error_cleanup; channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver); // If dns_server is specified, use it. @@ -522,7 +522,7 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner) { + int query_timeout_ms, grpc_combiner* combiner) { grpc_ares_request* r = static_cast(gpr_zalloc(sizeof(grpc_ares_request))); r->ev_driver = nullptr; @@ -546,7 +546,7 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( // Look up name using c-ares lib. grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( r, dns_server, name, default_port, interested_parties, check_grpclb, - combiner); + query_timeout_ms, combiner); return r; } @@ -554,6 +554,7 @@ grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) { @@ -648,7 +649,8 @@ static void grpc_resolve_address_invoke_dns_lookup_ares_locked( r->ares_request = grpc_dns_lookup_ares_locked( nullptr /* dns_server */, r->name, r->default_port, r->interested_parties, &r->on_dns_lookup_done_locked, &r->lb_addrs, false /* check_grpclb */, - nullptr /* service_config_json */, r->combiner); + nullptr /* service_config_json */, GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, + r->combiner); } static void grpc_resolve_address_ares_impl(const char* name, diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h index a1231cc4e0d..9acef1d0ca9 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -26,6 +26,8 @@ #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/resolve_address.h" +#define GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS 10000 + extern grpc_core::TraceFlag grpc_trace_cares_address_sorting; extern grpc_core::TraceFlag grpc_trace_cares_resolver; @@ -60,7 +62,7 @@ extern grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addresses, bool check_grpclb, - char** service_config_json, grpc_combiner* combiner); + char** service_config_json, int query_timeout_ms, grpc_combiner* combiner); /* Cancel the pending grpc_ares_request \a request */ extern void (*grpc_cancel_ares_request_locked)(grpc_ares_request* request); diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc index 9f293c1ac07..fc78b183044 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc @@ -30,7 +30,7 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner) { + int query_timeout_ms, grpc_combiner* combiner) { return NULL; } @@ -38,6 +38,7 @@ grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {} diff --git a/src/core/lib/iomgr/resolve_address.h b/src/core/lib/iomgr/resolve_address.h index 6afe94a7a92..7016ffc31aa 100644 --- a/src/core/lib/iomgr/resolve_address.h +++ b/src/core/lib/iomgr/resolve_address.h @@ -65,7 +65,7 @@ void grpc_set_resolver_impl(grpc_address_resolver_vtable* vtable); /* Asynchronously resolve addr. Use default_port if a port isn't designated in addr, otherwise use the port in addr. */ -/* TODO(ctiller): add a timeout here */ +/* TODO(apolcyn): add a timeout here */ void grpc_resolve_address(const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, 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 eb5a9117484..cc041ac7f3d 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -64,7 +64,7 @@ static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner) { + int query_timeout_ms, grpc_combiner* combiner) { gpr_mu_lock(&g_mu); GPR_ASSERT(0 == strcmp("test", addr)); grpc_error* error = GRPC_ERROR_NONE; 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..51fcc0dec67 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -41,7 +41,7 @@ static grpc_ares_request* (*g_default_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner); + int query_timeout_ms, grpc_combiner* combiner); // Counter incremented by test_resolve_address_impl indicating the number of // times a system-level resolution has happened. @@ -91,10 +91,10 @@ static grpc_ares_request* test_dns_lookup_ares_locked( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner) { + int query_timeout_ms, grpc_combiner* combiner) { grpc_ares_request* result = g_default_dns_lookup_ares_locked( dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, addrs, - check_grpclb, service_config_json, combiner); + check_grpclb, service_config_json, query_timeout_ms, combiner); ++g_resolution_count; static grpc_millis last_resolution_time = 0; if (last_resolution_time == 0) { diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index e97a544e12c..9b6eddee6e1 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -378,7 +378,7 @@ grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner) { + int query_timeout, grpc_combiner* combiner) { addr_req* r = static_cast(gpr_malloc(sizeof(*r))); r->addr = gpr_strdup(addr); r->on_done = on_done; diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 3f1c5596ad9..6369caf0d1b 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -48,7 +48,7 @@ static grpc_ares_request* (*iomgr_dns_lookup_ares_locked)( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addresses, bool check_grpclb, - char** service_config_json, grpc_combiner* combiner); + char** service_config_json, int query_timeout_ms, grpc_combiner* combiner); static void (*iomgr_cancel_ares_request_locked)(grpc_ares_request* request); @@ -104,11 +104,11 @@ static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner) { + int query_timeout_ms, grpc_combiner* combiner) { if (0 != strcmp(addr, "test")) { return iomgr_dns_lookup_ares_locked( dns_server, addr, default_port, interested_parties, on_done, lb_addrs, - check_grpclb, service_config_json, combiner); + check_grpclb, service_config_json, query_timeout_ms, combiner); } grpc_error* error = GRPC_ERROR_NONE; diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index dec7c171dc0..4c7a7c37357 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -260,8 +260,15 @@ TEST(CancelDuringAresQuery, TestFdsAreDeletedFromPollsetSet) { grpc_pollset_set_destroy(fake_other_pollset_set); } -TEST(CancelDuringAresQuery, - TestHitDeadlineAndDestroyChannelDuringAresResolutionIsGraceful) { +// Settings for TestCancelDuringActiveQuery test +typedef enum { + NONE, + SHORT, + ZERO, +} cancellation_test_query_timeout_setting; + +void TestCancelDuringActiveQuery( + cancellation_test_query_timeout_setting query_timeout_setting) { // Start up fake non responsive DNS server int fake_dns_port = grpc_pick_unused_port_or_die(); FakeNonResponsiveDNSServer fake_dns_server(fake_dns_port); @@ -271,9 +278,33 @@ TEST(CancelDuringAresQuery, &client_target, "dns://[::1]:%d/dont-care-since-wont-be-resolved.test.com:1234", fake_dns_port)); + gpr_log(GPR_DEBUG, "TestCancelActiveDNSQuery. query timeout setting: %d", + query_timeout_setting); + grpc_channel_args* client_args = nullptr; + grpc_status_code expected_status_code = GRPC_STATUS_OK; + if (query_timeout_setting == NONE) { + expected_status_code = GRPC_STATUS_DEADLINE_EXCEEDED; + client_args = nullptr; + } else if (query_timeout_setting == SHORT) { + expected_status_code = GRPC_STATUS_UNAVAILABLE; + grpc_arg arg; + arg.type = GRPC_ARG_INTEGER; + arg.key = const_cast(GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS); + arg.value.integer = + 1; // Set this shorter than the call deadline so that it goes off. + client_args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + } else if (query_timeout_setting == ZERO) { + expected_status_code = GRPC_STATUS_DEADLINE_EXCEEDED; + grpc_arg arg; + arg.type = GRPC_ARG_INTEGER; + arg.key = const_cast(GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS); + arg.value.integer = 0; // Set this to zero to disable query timeouts. + client_args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + } else { + abort(); + } grpc_channel* client = - grpc_insecure_channel_create(client_target, - /* client_args */ nullptr, nullptr); + grpc_insecure_channel_create(client_target, client_args, nullptr); gpr_free(client_target); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); cq_verifier* cqv = cq_verifier_create(cq); @@ -325,8 +356,9 @@ TEST(CancelDuringAresQuery, EXPECT_EQ(GRPC_CALL_OK, error); CQ_EXPECT_COMPLETION(cqv, Tag(1), 1); cq_verify(cqv); - EXPECT_EQ(status, GRPC_STATUS_DEADLINE_EXCEEDED); + EXPECT_EQ(status, expected_status_code); // Teardown + grpc_channel_args_destroy(client_args); grpc_slice_unref(details); gpr_free((void*)error_string); grpc_metadata_array_destroy(&initial_metadata_recv); @@ -338,6 +370,23 @@ TEST(CancelDuringAresQuery, EndTest(client, cq); } +TEST(CancelDuringAresQuery, + TestHitDeadlineAndDestroyChannelDuringAresResolutionIsGraceful) { + TestCancelDuringActiveQuery(NONE /* don't set query timeouts */); +} + +TEST( + CancelDuringAresQuery, + TestHitDeadlineAndDestroyChannelDuringAresResolutionWithQueryTimeoutIsGraceful) { + TestCancelDuringActiveQuery(SHORT /* set short query timeout */); +} + +TEST( + CancelDuringAresQuery, + TestHitDeadlineAndDestroyChannelDuringAresResolutionWithZeroQueryTimeoutIsGraceful) { + TestCancelDuringActiveQuery(ZERO /* disable query timeouts */); +} + } // namespace int main(int argc, char** argv) { From f0cb7e6bdc3bfd6a6d3d60ea03e57a92bc5d76c1 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Mon, 3 Dec 2018 13:55:06 -0800 Subject: [PATCH 0413/2143] Remove log lines --- test/cpp/end2end/client_callback_end2end_test.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 98bd99fac69..deec6980812 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -215,9 +215,6 @@ TEST_P(ClientCallbackEnd2endTest, SendClientInitialMetadata) { bool done = false; stub_->experimental_async()->CheckClientInitialMetadata( &cli_ctx, &request, &response, [&done, &mu, &cv](Status s) { - std::cout << s.error_code() << std::endl; - gpr_log(GPR_ERROR, s.error_message().c_str()); - gpr_log(GPR_ERROR, s.error_details().c_str()); GPR_ASSERT(s.ok()); std::lock_guard l(mu); From be76eb4429c0037027ea0782c7726c909165235c Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Mon, 3 Dec 2018 14:58:34 -0800 Subject: [PATCH 0414/2143] Address reviewer comments --- src/proto/grpc/testing/simple_messages.proto | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/proto/grpc/testing/simple_messages.proto b/src/proto/grpc/testing/simple_messages.proto index 8bb334ac278..4b65d18909d 100644 --- a/src/proto/grpc/testing/simple_messages.proto +++ b/src/proto/grpc/testing/simple_messages.proto @@ -18,9 +18,7 @@ syntax = "proto3"; package grpc.testing; message SimpleRequest { - string message = 1; } message SimpleResponse { - string message = 1; } From b7f283b06fff95ac950531561bddef594708959d Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Mon, 3 Dec 2018 16:04:30 -0800 Subject: [PATCH 0415/2143] Fix bazel rbe tests --- test/cpp/util/BUILD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD index 57eaf3baf2f..61e65029fff 100644 --- a/test/cpp/util/BUILD +++ b/test/cpp/util/BUILD @@ -181,6 +181,7 @@ grpc_cc_test( data = [ "//src/proto/grpc/testing:echo.proto", "//src/proto/grpc/testing:echo_messages.proto", + "//src/proto/grpc/testing:simple_messages.proto", ], external_deps = [ "gtest", @@ -192,6 +193,7 @@ grpc_cc_test( "//:grpc++_reflection", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", + "//src/proto/grpc/testing:simple_messages_proto", "//test/core/end2end:ssl_test_data", "//test/core/util:grpc_test_util", ], From dc930c7868a9be5427afeec76f90d06748c9ef7f Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Mon, 3 Dec 2018 19:16:21 -0800 Subject: [PATCH 0416/2143] Workarounding bazelbuild/bazel#6831 This will take care of the bazel crash until we have a proper fix upstream. --- WORKSPACE | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 8d0fd693c6c..5f159c867ce 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -8,11 +8,12 @@ grpc_deps() grpc_test_only_deps() register_execution_platforms( - "//third_party/toolchains:all", + "//third_party/toolchains:rbe_ubuntu1604", + "//third_party/toolchains:rbe_ubuntu1604_large", ) register_toolchains( - "//third_party/toolchains:all", + "//third_party/toolchains:cc-toolchain-clang-x86_64-default", ) new_http_archive( From 606177bbc8343c94b075021522f304e6ecf43aa8 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 3 Dec 2018 20:00:08 -0800 Subject: [PATCH 0417/2143] Document that ClientContext must remain alive for duration of RPC --- include/grpcpp/impl/codegen/client_context.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 6059c3c58a4..142cfa35dd0 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -168,6 +168,8 @@ class InteropClientContextInspector; /// (see \a grpc::CreateCustomChannel). /// /// \warning ClientContext instances should \em not be reused across rpcs. +/// \warning The ClientContext instance used for creating an rpc must remain +/// alive and valid for the lifetime of the rpc. class ClientContext { public: ClientContext(); From b30218b6e0ffb0c0e65af5e15872f3e644813dc3 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 4 Dec 2018 11:34:15 +0100 Subject: [PATCH 0418/2143] C#: use netcoreapp1.1 qps worker --- tools/run_tests/performance/run_worker_csharp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/performance/run_worker_csharp.sh b/tools/run_tests/performance/run_worker_csharp.sh index 6546d6010b1..bfa59b5d9e6 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.0 +cd src/csharp/Grpc.IntegrationTesting.QpsWorker/bin/Release/netcoreapp1.1 dotnet exec Grpc.IntegrationTesting.QpsWorker.dll "$@" From 140cda9af0c12b520107079e0b23d062bf8657cc Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 4 Dec 2018 11:39:29 +0100 Subject: [PATCH 0419/2143] updates for grpc-performance-kokoro-v3 image --- .../create_linux_kokoro_performance_worker_from_image.sh | 2 +- tools/gce/linux_kokoro_performance_worker_init.sh | 6 ++++++ 2 files changed, 7 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 0f7939be4c0..28c49a66f24 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-v2 # update if newer image exists +LATEST_PERF_WORKER_IMAGE=grpc-performance-kokoro-v3 # 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 b78695d8020..d67ff58506f 100755 --- a/tools/gce/linux_kokoro_performance_worker_init.sh +++ b/tools/gce/linux_kokoro_performance_worker_init.sh @@ -133,6 +133,12 @@ sudo cp -r dotnet105_download/shared/Microsoft.NETCore.App/1.0.5/ /usr/share/dot wget -q http://security.ubuntu.com/ubuntu/pool/main/i/icu/libicu55_55.1-7ubuntu0.4_amd64.deb sudo dpkg -i libicu55_55.1-7ubuntu0.4_amd64.deb +# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1) +wget -q -O dotnet_old.tar.gz https://download.visualstudio.microsoft.com/download/pr/b25b5650-0cb8-4699-a347-48d73650da0b/920966211e9bb1907232bbda1faa895a/dotnet-ubuntu.18.04-x64.1.1.10.tar.gz +mkdir -p dotnet_old +tar zxf dotnet_old.tar.gz -C dotnet_old +sudo cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ + # Ruby dependencies gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 curl -sSL https://get.rvm.io | bash -s stable --ruby From 9d2b3f35b9c214b23e0bb0b664de7bebb427cf4c Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 4 Dec 2018 09:25:04 -0800 Subject: [PATCH 0420/2143] Fix another problem in grpc_tool_test --- test/cpp/util/grpc_tool_test.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index 4ddc11c5a64..b96b00f2db2 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -48,6 +48,7 @@ using grpc::testing::EchoResponse; #define ECHO_TEST_SERVICE_SUMMARY \ "Echo\n" \ + "CheckClientInitialMetadata\n" \ "RequestStream\n" \ "ResponseStream\n" \ "BidiStream\n" \ @@ -59,6 +60,8 @@ using grpc::testing::EchoResponse; "service EchoTestService {\n" \ " rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \ "{}\n" \ + " rpc CheckClientInitialMetadata(grpc.testing.SimpleRequest) returns " \ + "(grpc.testing.SimpleResponse) {}\n" \ " rpc RequestStream(stream grpc.testing.EchoRequest) returns " \ "(grpc.testing.EchoResponse) {}\n" \ " rpc ResponseStream(grpc.testing.EchoRequest) returns (stream " \ From f27eb3aed15f26d9aa5206928436be389b832a95 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 4 Dec 2018 09:39:29 -0800 Subject: [PATCH 0421/2143] Change xds plugin name to xds_experimental until it's ready for use. --- src/core/ext/filters/client_channel/lb_policy/xds/xds.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 563ff42b2ea..faedc0a9194 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 @@ -1780,7 +1780,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { return OrphanablePtr(New(addresses, args)); } - const char* name() const override { return "xds"; } + const char* name() const override { return "xds_experimental"; } }; } // namespace From 2f55f4f85af9afe9d3f2e55b51ec949c87ed9b4d Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Sat, 1 Dec 2018 21:07:35 -0500 Subject: [PATCH 0422/2143] Add TSAN annotations to gRPC. --- BUILD | 7 +- build.yaml | 1 + gRPC-C++.podspec | 2 + gRPC-Core.podspec | 2 + grpc.gemspec | 1 + include/grpc/impl/codegen/port_platform.h | 9 +++ package.xml | 1 + src/core/lib/iomgr/dynamic_annotations.h | 67 +++++++++++++++++++ tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core.internal | 1 + .../generated/sources_and_headers.json | 2 + 11 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 src/core/lib/iomgr/dynamic_annotations.h diff --git a/BUILD b/BUILD index 9a2c16c6012..9e3e594038d 100644 --- a/BUILD +++ b/BUILD @@ -856,6 +856,7 @@ grpc_cc_library( "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", @@ -1088,11 +1089,11 @@ grpc_cc_library( "grpc_base", "grpc_client_authority_filter", "grpc_deadline_filter", + "health_proto", "inlined_vector", "orphanable", "ref_counted", "ref_counted_ptr", - "health_proto", ], ) @@ -1590,8 +1591,8 @@ grpc_cc_library( "src/core/lib/security/security_connector/load_system_roots_linux.cc", "src/core/lib/security/security_connector/local/local_security_connector.cc", "src/core/lib/security/security_connector/security_connector.cc", - "src/core/lib/security/security_connector/ssl_utils.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/transport/client_auth_filter.cc", "src/core/lib/security/transport/secure_endpoint.cc", "src/core/lib/security/transport/security_handshaker.cc", @@ -1624,8 +1625,8 @@ grpc_cc_library( "src/core/lib/security/security_connector/load_system_roots_linux.h", "src/core/lib/security/security_connector/local/local_security_connector.h", "src/core/lib/security/security_connector/security_connector.h", - "src/core/lib/security/security_connector/ssl_utils.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/transport/auth_filters.h", "src/core/lib/security/transport/secure_endpoint.h", "src/core/lib/security/transport/security_handshaker.h", diff --git a/build.yaml b/build.yaml index 381e649b392..ba9a1578425 100644 --- a/build.yaml +++ b/build.yaml @@ -440,6 +440,7 @@ filegroups: - 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 diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 6647201714c..5e79803497f 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -405,6 +405,7 @@ Pod::Spec.new do |s| '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', @@ -597,6 +598,7 @@ Pod::Spec.new do |s| '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', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 3ec0852ad31..1d4e1ae35c0 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -403,6 +403,7 @@ Pod::Spec.new do |s| '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', @@ -1022,6 +1023,7 @@ Pod::Spec.new do |s| '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', diff --git a/grpc.gemspec b/grpc.gemspec index b5a1ef43fd3..92b1e0be689 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -339,6 +339,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/call_combiner.h ) s.files += %w( src/core/lib/iomgr/closure.h ) s.files += %w( src/core/lib/iomgr/combiner.h ) + s.files += %w( src/core/lib/iomgr/dynamic_annotations.h ) s.files += %w( src/core/lib/iomgr/endpoint.h ) s.files += %w( src/core/lib/iomgr/endpoint_pair.h ) s.files += %w( src/core/lib/iomgr/error.h ) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index b2028a63053..031c0c36aef 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -526,6 +526,15 @@ typedef unsigned __int64 uint64_t; #endif /* GPR_ATTRIBUTE_NO_TSAN (2) */ #endif /* GPR_ATTRIBUTE_NO_TSAN (1) */ +/* 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) +#define GRPC_TSAN_ENABLED +#endif +#endif + /* GRPC_ALLOW_EXCEPTIONS should be 0 or 1 if exceptions are allowed or not */ #ifndef GRPC_ALLOW_EXCEPTIONS /* If not already set, set to 1 on Windows (style guide standard) but to diff --git a/package.xml b/package.xml index a354ad5fa7d..bdcb12bfc5e 100644 --- a/package.xml +++ b/package.xml @@ -344,6 +344,7 @@ + diff --git a/src/core/lib/iomgr/dynamic_annotations.h b/src/core/lib/iomgr/dynamic_annotations.h new file mode 100644 index 00000000000..713928023ae --- /dev/null +++ b/src/core/lib/iomgr/dynamic_annotations.h @@ -0,0 +1,67 @@ +/* + * + * 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_IOMGR_DYNAMIC_ANNOTATIONS_H +#define GRPC_CORE_LIB_IOMGR_DYNAMIC_ANNOTATIONS_H + +#include + +#ifdef GRPC_TSAN_ENABLED + +#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) \ + AnnotateHappensBefore(__FILE__, __LINE__, (void*)(addr)) +#define TSAN_ANNOTATE_HAPPENS_AFTER(addr) \ + AnnotateHappensAfter(__FILE__, __LINE__, (void*)(addr)) +#define TSAN_ANNOTATE_RWLOCK_CREATE(addr) \ + AnnotateRWLockCreate(__FILE__, __LINE__, (void*)(addr)) +#define TSAN_ANNOTATE_RWLOCK_DESTROY(addr) \ + AnnotateRWLockDestroy(__FILE__, __LINE__, (void*)(addr)) +#define TSAN_ANNOTATE_RWLOCK_ACQUIRED(addr, is_w) \ + AnnotateRWLockAcquired(__FILE__, __LINE__, (void*)(addr), (is_w)) +#define TSAN_ANNOTATE_RWLOCK_RELEASED(addr, is_w) \ + AnnotateRWLockReleased(__FILE__, __LINE__, (void*)(addr), (is_w)) + +#ifdef __cplusplus +extern "C" { +#endif +void AnnotateHappensBefore(const char* file, int line, const volatile void* cv); +void AnnotateHappensAfter(const char* file, int line, const volatile void* cv); +void AnnotateRWLockCreate(const char* file, int line, + const volatile void* lock); +void AnnotateRWLockDestroy(const char* file, int line, + const volatile void* lock); +void AnnotateRWLockAcquired(const char* file, int line, + const volatile void* lock, long is_w); +void AnnotateRWLockReleased(const char* file, int line, + const volatile void* lock, long is_w); +#ifdef __cplusplus +} +#endif + +#else /* GRPC_TSAN_ENABLED */ + +#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) +#define TSAN_ANNOTATE_HAPPENS_AFTER(addr) +#define TSAN_ANNOTATE_RWLOCK_CREATE(addr) +#define TSAN_ANNOTATE_RWLOCK_DESTROY(addr) +#define TSAN_ANNOTATE_RWLOCK_ACQUIRED(addr, is_w) +#define TSAN_ANNOTATE_RWLOCK_RELEASED(addr, is_w) + +#endif /* GRPC_TSAN_ENABLED */ + +#endif /* GRPC_CORE_LIB_IOMGR_DYNAMIC_ANNOTATIONS_H */ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 72b247c48da..0e65bf6daa0 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1084,6 +1084,7 @@ 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 \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 0f1943de25f..dd5bead58ca 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1182,6 +1182,7 @@ 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 \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 4d9bbb0f09e..afd63aadb4d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9732,6 +9732,7 @@ "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", @@ -9884,6 +9885,7 @@ "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", From 3cdf8377cfa6865d65cfb347da43d0950ce00975 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 4 Dec 2018 19:55:41 +0100 Subject: [PATCH 0423/2143] Fixing jq's installation. --- tools/internal_ci/linux/grpc_run_tests_matrix.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/internal_ci/linux/grpc_run_tests_matrix.sh b/tools/internal_ci/linux/grpc_run_tests_matrix.sh index 4e7515227bd..f9acd814ae8 100755 --- a/tools/internal_ci/linux/grpc_run_tests_matrix.sh +++ b/tools/internal_ci/linux/grpc_run_tests_matrix.sh @@ -22,6 +22,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 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" From 0a37159ff4d9bfd6a4b7b94c5d5bf915033cf706 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 4 Dec 2018 12:41:47 -0800 Subject: [PATCH 0424/2143] re add testonly --- test/cpp/microbenchmarks/BUILD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 84ea386870d..b9708cf3877 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -29,6 +29,7 @@ grpc_cc_test( grpc_cc_library( name = "helpers", + testonly=1, srcs = ["helpers.cc"], hdrs = [ "fullstack_context_mutators.h", @@ -57,6 +58,7 @@ grpc_cc_test( # right now it OOMs grpc_cc_binary( name = "bm_arena", + testonly=1, srcs = ["bm_arena.cc"], deps = [":helpers"], ) @@ -72,6 +74,7 @@ grpc_cc_test( # right now it fails UBSAN grpc_cc_binary( name = "bm_call_create", + testonly=1, srcs = ["bm_call_create.cc"], deps = [":helpers"], ) @@ -99,6 +102,7 @@ grpc_cc_test( grpc_cc_library( name = "fullstack_streaming_ping_pong_h", + testonly=1, hdrs = [ "fullstack_streaming_ping_pong.h", ], @@ -115,6 +119,7 @@ grpc_cc_test( grpc_cc_library( name = "fullstack_streaming_pump_h", + testonly=1, hdrs = [ "fullstack_streaming_pump.h", ], @@ -131,12 +136,14 @@ grpc_cc_test( grpc_cc_binary( name = "bm_fullstack_trickle", + testonly=1, srcs = ["bm_fullstack_trickle.cc"], deps = [":helpers"], ) grpc_cc_library( name = "fullstack_unary_ping_pong_h", + testonly=1, hdrs = [ "fullstack_unary_ping_pong.h", ], From 073467b584d5257e941a1734e360a122f9d7d77e Mon Sep 17 00:00:00 2001 From: Sheena Madan <43831800+sheenaqotj@users.noreply.github.com> Date: Tue, 4 Dec 2018 13:14:58 -0800 Subject: [PATCH 0425/2143] Update BUILD --- test/cpp/microbenchmarks/BUILD | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index b9708cf3877..afac414e09d 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -29,7 +29,7 @@ grpc_cc_test( grpc_cc_library( name = "helpers", - testonly=1, + testonly = 1, srcs = ["helpers.cc"], hdrs = [ "fullstack_context_mutators.h", @@ -58,7 +58,7 @@ grpc_cc_test( # right now it OOMs grpc_cc_binary( name = "bm_arena", - testonly=1, + testonly = 1, srcs = ["bm_arena.cc"], deps = [":helpers"], ) @@ -74,7 +74,7 @@ grpc_cc_test( # right now it fails UBSAN grpc_cc_binary( name = "bm_call_create", - testonly=1, + testonly = 1, srcs = ["bm_call_create.cc"], deps = [":helpers"], ) @@ -102,7 +102,7 @@ grpc_cc_test( grpc_cc_library( name = "fullstack_streaming_ping_pong_h", - testonly=1, + testonly = 1, hdrs = [ "fullstack_streaming_ping_pong.h", ], @@ -119,7 +119,7 @@ grpc_cc_test( grpc_cc_library( name = "fullstack_streaming_pump_h", - testonly=1, + testonly = 1, hdrs = [ "fullstack_streaming_pump.h", ], @@ -136,14 +136,14 @@ grpc_cc_test( grpc_cc_binary( name = "bm_fullstack_trickle", - testonly=1, + testonly = 1, srcs = ["bm_fullstack_trickle.cc"], deps = [":helpers"], ) grpc_cc_library( name = "fullstack_unary_ping_pong_h", - testonly=1, + testonly = 1, hdrs = [ "fullstack_unary_ping_pong.h", ], From d42c56788c31547f8ed99833e10f77d6af2c1732 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 4 Dec 2018 13:48:01 -0800 Subject: [PATCH 0426/2143] More debug timers to record root cause --- src/core/lib/gpr/sync_posix.cc | 92 ++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 5 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 69bd6094850..813a03c34bc 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -30,11 +30,16 @@ // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER +#include void (*g_grpc_debug_timer_manager_stats)( int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count, int64_t fork_count, int64_t timer_wait_err, int64_t timer_cv_value, int64_t timer_mu_value, int64_t abstime_sec_value, - int64_t abstime_nsec_value) = nullptr; + int64_t abstime_nsec_value, int64_t abs_deadline_sec_value, int64_t abs_deadline_nsec_value, int64_t now1_sec_value, + int64_t now1_nsec_value, int64_t now2_sec_value, + int64_t now2_nsec_value, int64_t add_result_sec_value, + int64_t add_result_nsec_value, int64_t sub_result_sec_value, + int64_t sub_result_nsec_value) = nullptr; int64_t g_timer_manager_init_count = 0; int64_t g_timer_manager_shutdown_count = 0; int64_t g_fork_count = 0; @@ -43,6 +48,16 @@ int64_t g_timer_cv_value = 0; int64_t g_timer_mu_value = 0; int64_t g_abstime_sec_value = -1; int64_t g_abstime_nsec_value = -1; +int64_t g_abs_deadline_sec_value = -1; +int64_t g_abs_deadline_nsec_value = -1; +int64_t g_now1_sec_value = -1; +int64_t g_now1_nsec_value = -1; +int64_t g_now2_sec_value = -1; +int64_t g_now2_nsec_value = -1; +int64_t g_add_result_sec_value = -1; +int64_t g_add_result_nsec_value = -1; +int64_t g_sub_result_sec_value = -1; +int64_t g_sub_result_nsec_value = -1; #endif // GRPC_DEBUG_TIMER_MANAGER #ifdef GPR_LOW_LEVEL_COUNTERS @@ -90,17 +105,70 @@ void gpr_cv_init(gpr_cv* cv) { void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); } +// For debug of the timer manager crash only. +// TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER +static gpr_timespec gpr_convert_clock_type_debug_timespec(gpr_timespec t, + gpr_clock_type clock_type, + gpr_timespec &now1, + gpr_timespec &now2, + gpr_timespec &add_result, + gpr_timespec &sub_result) { + if (t.clock_type == clock_type) { + return t; + } + + if (t.tv_sec == INT64_MAX || t.tv_sec == INT64_MIN) { + t.clock_type = clock_type; + return t; + } + + if (clock_type == GPR_TIMESPAN) { + return gpr_time_sub(t, gpr_now(t.clock_type)); + } + + if (t.clock_type == GPR_TIMESPAN) { + return gpr_time_add(gpr_now(clock_type), t); + } + + now1 = gpr_now(t.clock_type); + sub_result = gpr_time_sub(t, now1); + now2 = gpr_now(clock_type); + add_result = gpr_time_add(now2, sub_result); + return add_result; +} + +#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, sub_result) gpr_convert_clock_type_debug_timespec((t), (clock_type), (now1), (now2), (add_result), (sub_result)) +#else +#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, sub_result) gpr_convert_clock_type((t), (clock_type)) +#endif + int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { int err = 0; +#ifdef GRPC_DEBUG_TIMER_MANAGER + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. + gpr_timespec abs_deadline_copy; + abs_deadline_copy.tv_sec = abs_deadline.tv_sec; + abs_deadline_copy.tv_nsec = abs_deadline.tv_nsec; + gpr_timespec now1; + gpr_timespec now2; + gpr_timespec add_result; + gpr_timespec sub_result; + memset(&now1, 0, sizeof(now1)); + memset(&now2, 0, sizeof(now2)); + memset(&add_result, 0, sizeof(add_result)); + memset(&sub_result, 0, sizeof(sub_result)); +#endif if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) == 0) { err = pthread_cond_wait(cv, mu); } else { struct timespec abs_deadline_ts; #if GPR_LINUX - abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_MONOTONIC); + abs_deadline = gpr_convert_clock_type_debug(abs_deadline, GPR_CLOCK_MONOTONIC, now1, now2, add_result, sub_result); #else - abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME); + abs_deadline = gpr_convert_clock_type_debug(abs_deadline, GPR_CLOCK_REALTIME, now1, now2, add_result, sub_result); #endif // GPR_LINUX abs_deadline_ts.tv_sec = static_cast(abs_deadline.tv_sec); abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; @@ -123,11 +191,25 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { g_timer_wait_err = err; g_timer_cv_value = (int64_t)cv; g_timer_mu_value = (int64_t)mu; + g_abs_deadline_sec_value = abs_deadline_copy.tv_sec; + g_abs_deadline_nsec_value = abs_deadline_copy.tv_nsec; + g_now1_sec_value = now1.tv_sec; + g_now1_nsec_value = now1.tv_nsec; + g_now2_sec_value = now2.tv_sec; + g_now2_nsec_value = now2.tv_nsec; + g_add_result_sec_value = add_result.tv_sec; + g_add_result_nsec_value = add_result.tv_nsec; + g_sub_result_sec_value = sub_result.tv_sec; + g_sub_result_nsec_value = sub_result.tv_nsec; g_grpc_debug_timer_manager_stats( g_timer_manager_init_count, g_timer_manager_shutdown_count, g_fork_count, g_timer_wait_err, g_timer_cv_value, g_timer_mu_value, - g_abstime_sec_value, g_abstime_nsec_value); - } + g_abstime_sec_value, g_abstime_nsec_value, g_abs_deadline_sec_value, + g_abs_deadline_nsec_value, g_now1_sec_value, g_now1_nsec_value, + g_now2_sec_value, g_now2_nsec_value, g_add_result_sec_value, + g_add_result_nsec_value, g_sub_result_sec_value, + g_sub_result_nsec_value); + } } #endif GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); From 5ebbba543c5be26412eb5ba9493ee242eee2e0ac Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 4 Dec 2018 14:20:56 -0800 Subject: [PATCH 0427/2143] clang-format --- src/core/lib/gpr/sync_posix.cc | 36 +++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 813a03c34bc..4ded03055c8 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -35,11 +35,11 @@ void (*g_grpc_debug_timer_manager_stats)( int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count, int64_t fork_count, int64_t timer_wait_err, int64_t timer_cv_value, int64_t timer_mu_value, int64_t abstime_sec_value, - int64_t abstime_nsec_value, int64_t abs_deadline_sec_value, int64_t abs_deadline_nsec_value, int64_t now1_sec_value, - int64_t now1_nsec_value, int64_t now2_sec_value, - int64_t now2_nsec_value, int64_t add_result_sec_value, - int64_t add_result_nsec_value, int64_t sub_result_sec_value, - int64_t sub_result_nsec_value) = nullptr; + int64_t abstime_nsec_value, int64_t abs_deadline_sec_value, + int64_t abs_deadline_nsec_value, int64_t now1_sec_value, + int64_t now1_nsec_value, int64_t now2_sec_value, int64_t now2_nsec_value, + int64_t add_result_sec_value, int64_t add_result_nsec_value, + int64_t sub_result_sec_value, int64_t sub_result_nsec_value) = nullptr; int64_t g_timer_manager_init_count = 0; int64_t g_timer_manager_shutdown_count = 0; int64_t g_fork_count = 0; @@ -108,12 +108,9 @@ void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); } // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER -static gpr_timespec gpr_convert_clock_type_debug_timespec(gpr_timespec t, - gpr_clock_type clock_type, - gpr_timespec &now1, - gpr_timespec &now2, - gpr_timespec &add_result, - gpr_timespec &sub_result) { +static gpr_timespec gpr_convert_clock_type_debug_timespec( + gpr_timespec t, gpr_clock_type clock_type, gpr_timespec& now1, + gpr_timespec& now2, gpr_timespec& add_result, gpr_timespec& sub_result) { if (t.clock_type == clock_type) { return t; } @@ -138,9 +135,14 @@ static gpr_timespec gpr_convert_clock_type_debug_timespec(gpr_timespec t, return add_result; } -#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, sub_result) gpr_convert_clock_type_debug_timespec((t), (clock_type), (now1), (now2), (add_result), (sub_result)) +#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \ + sub_result) \ + gpr_convert_clock_type_debug_timespec((t), (clock_type), (now1), (now2), \ + (add_result), (sub_result)) #else -#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, sub_result) gpr_convert_clock_type((t), (clock_type)) +#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \ + sub_result) \ + gpr_convert_clock_type((t), (clock_type)) #endif int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { @@ -166,9 +168,11 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { } else { struct timespec abs_deadline_ts; #if GPR_LINUX - abs_deadline = gpr_convert_clock_type_debug(abs_deadline, GPR_CLOCK_MONOTONIC, now1, now2, add_result, sub_result); + abs_deadline = gpr_convert_clock_type_debug( + abs_deadline, GPR_CLOCK_MONOTONIC, now1, now2, add_result, sub_result); #else - abs_deadline = gpr_convert_clock_type_debug(abs_deadline, GPR_CLOCK_REALTIME, now1, now2, add_result, sub_result); + abs_deadline = gpr_convert_clock_type_debug( + abs_deadline, GPR_CLOCK_REALTIME, now1, now2, add_result, sub_result); #endif // GPR_LINUX abs_deadline_ts.tv_sec = static_cast(abs_deadline.tv_sec); abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; @@ -209,7 +213,7 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { g_now2_sec_value, g_now2_nsec_value, g_add_result_sec_value, g_add_result_nsec_value, g_sub_result_sec_value, g_sub_result_nsec_value); - } + } } #endif GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); From e699c47c1e39a7174ee603ec3f3e6ad3de197bf4 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 4 Dec 2018 14:28:58 -0800 Subject: [PATCH 0428/2143] credentials: call grpc_init/grpc_shutdown when created/destroyed This addresses https://github.com/grpc/grpc/issues/17001. Prior to https://github.com/grpc/grpc/pull/13603, our credentials cython objects used grpc_initi() and grpc_shutdown() on creation and destruction. These are now managed differently, but the grpc_init() and grpc_shutdown() calls are still required. See the MetadataCredentialsPluginWrapper in C++, which extends the GrpcLibraryCodegen class to ensure that grpc_init() and grpc_shutdown() are called appropriately. Without this, we can deadlock when a call to grpc.Channel#close() triggers grpc_shutdown() to block and wait for all timer threads to finish: one of these timer threads may end up unreffing the subchannel and triggering grpc_call_credentials_unref, which will jump back into Cython and hang when it tries to reacquire the GIL. --- src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index ff523fb256c..6555e89edae 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -61,6 +61,7 @@ cdef int _get_metadata( cdef void _destroy(void *state) with gil: cpython.Py_DECREF(state) + grpc_shutdown() cdef class MetadataPluginCallCredentials(CallCredentials): @@ -76,6 +77,7 @@ cdef class MetadataPluginCallCredentials(CallCredentials): c_metadata_plugin.state = self._metadata_plugin c_metadata_plugin.type = self._name cpython.Py_INCREF(self._metadata_plugin) + fork_handlers_and_grpc_init() return grpc_metadata_credentials_create_from_plugin(c_metadata_plugin, NULL) From 8bed44b2c47577fe255eb5b9fe754a2756cefed7 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 4 Dec 2018 19:43:04 -0800 Subject: [PATCH 0429/2143] Make WORKSPACE compatible with Bazel 0.20.0 for Python --- WORKSPACE | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WORKSPACE b/WORKSPACE index 5f159c867ce..81371bf4187 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,5 +1,6 @@ workspace(name = "com_github_grpc_grpc") +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("//bazel:grpc_deps.bzl", "grpc_deps", "grpc_test_only_deps") load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") @@ -16,7 +17,7 @@ register_toolchains( "//third_party/toolchains:cc-toolchain-clang-x86_64-default", ) -new_http_archive( +http_archive( name = "cython", build_file = "//third_party:cython.BUILD", sha256 = "d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27", From c012afb73159322e3748967a438a9dce4668da9d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Dec 2018 16:56:48 +0100 Subject: [PATCH 0430/2143] fix macos PR jobs on high-sierra workers --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index eba05449e83..bafe0d98c1a 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -35,7 +35,7 @@ export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db3 if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then set +x brew update - brew install jq + 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" From 0cf8c59a58777d49067a534dcb94f3c28ee4da99 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 4 Dec 2018 09:39:29 -0800 Subject: [PATCH 0431/2143] Change xds plugin name to xds_experimental until it's ready for use. --- src/core/ext/filters/client_channel/lb_policy/xds/xds.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 29cd9043755..81a51ac56a9 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 @@ -1811,7 +1811,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { return OrphanablePtr(New(addresses, args)); } - const char* name() const override { return "xds"; } + const char* name() const override { return "xds_experimental"; } }; } // namespace From d685afc4626a793f1e7f1d2f3b2b05e9d404aa79 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Dec 2018 16:56:48 +0100 Subject: [PATCH 0432/2143] fix macos PR jobs on high-sierra workers --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 24a3545dedc..0ef9735c1cd 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -36,7 +36,7 @@ export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db3 if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then set +x brew update - brew install jq + 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" From be8ef52ea8a0bb91a83c41a8028bab69f42daac7 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Sat, 1 Dec 2018 22:17:48 -0500 Subject: [PATCH 0433/2143] Add TSAN anntations for grpc_call_combiner. Since GRPC_CLOSUSE_SCHEDULE can schedule callback asynchronously we have to schedule our own wrapper instead. Also, we cannot use ACQUIRE and RELEASE directly on the call_combiner, because callbacks are free to even destroy the call_combiner. Thus, we use a ref-counted structure that acts as a fake lock for Tsan annotations. --- src/core/lib/iomgr/call_combiner.cc | 52 +++++++++++++++++++++++++++-- src/core/lib/iomgr/call_combiner.h | 31 +++++++++++++++-- 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/call_combiner.cc b/src/core/lib/iomgr/call_combiner.cc index 90dda45ba37..6b5759a036f 100644 --- a/src/core/lib/iomgr/call_combiner.cc +++ b/src/core/lib/iomgr/call_combiner.cc @@ -39,10 +39,57 @@ static gpr_atm encode_cancel_state_error(grpc_error* error) { return static_cast(1) | (gpr_atm)error; } +#ifdef GRPC_TSAN_ENABLED +static void tsan_closure(void* user_data, grpc_error* error) { + grpc_call_combiner* call_combiner = + static_cast(user_data); + // We ref-count the lock, and check if it's already taken. + // If it was taken, we should do nothing. Otherwise, we will mark it as + // locked. Note that if two different threads try to do this, only one of + // them will be able to mark the lock as acquired, while they both run their + // callbacks. In such cases (which should never happen for call_combiner), + // TSAN will correctly produce an error. + // + // TODO(soheil): This only covers the callbacks scheduled by + // grpc_call_combiner_(start|finish). If in the future, a + // callback gets scheduled using other mechanisms, we will need + // to add APIs to externally lock call combiners. + grpc_core::RefCountedPtr lock = + call_combiner->tsan_lock; + bool prev = false; + if (lock->taken.compare_exchange_strong(prev, true)) { + TSAN_ANNOTATE_RWLOCK_ACQUIRED(&lock->taken, true); + } else { + lock.reset(); + } + GRPC_CLOSURE_RUN(call_combiner->original_closure, GRPC_ERROR_REF(error)); + if (lock != nullptr) { + TSAN_ANNOTATE_RWLOCK_RELEASED(&lock->taken, true); + bool prev = true; + GPR_ASSERT(lock->taken.compare_exchange_strong(prev, false)); + } +} +#endif + +static void call_combiner_sched_closure(grpc_call_combiner* call_combiner, + grpc_closure* closure, + grpc_error* error) { +#ifdef GRPC_TSAN_ENABLED + call_combiner->original_closure = closure; + GRPC_CLOSURE_SCHED(&call_combiner->tsan_closure, error); +#else + GRPC_CLOSURE_SCHED(closure, error); +#endif +} + void grpc_call_combiner_init(grpc_call_combiner* call_combiner) { gpr_atm_no_barrier_store(&call_combiner->cancel_state, 0); gpr_atm_no_barrier_store(&call_combiner->size, 0); gpr_mpscq_init(&call_combiner->queue); +#ifdef GRPC_TSAN_ENABLED + GRPC_CLOSURE_INIT(&call_combiner->tsan_closure, tsan_closure, call_combiner, + grpc_schedule_on_exec_ctx); +#endif } void grpc_call_combiner_destroy(grpc_call_combiner* call_combiner) { @@ -87,7 +134,7 @@ void grpc_call_combiner_start(grpc_call_combiner* call_combiner, gpr_log(GPR_INFO, " EXECUTING IMMEDIATELY"); } // Queue was empty, so execute this closure immediately. - GRPC_CLOSURE_SCHED(closure, error); + call_combiner_sched_closure(call_combiner, closure, error); } else { if (grpc_call_combiner_trace.enabled()) { gpr_log(GPR_INFO, " QUEUING"); @@ -134,7 +181,8 @@ void grpc_call_combiner_stop(grpc_call_combiner* call_combiner DEBUG_ARGS, gpr_log(GPR_INFO, " EXECUTING FROM QUEUE: closure=%p error=%s", closure, grpc_error_string(closure->error_data.error)); } - GRPC_CLOSURE_SCHED(closure, closure->error_data.error); + call_combiner_sched_closure(call_combiner, closure, + closure->error_data.error); break; } } else if (grpc_call_combiner_trace.enabled()) { diff --git a/src/core/lib/iomgr/call_combiner.h b/src/core/lib/iomgr/call_combiner.h index c943fb15570..4ec0044f056 100644 --- a/src/core/lib/iomgr/call_combiner.h +++ b/src/core/lib/iomgr/call_combiner.h @@ -27,7 +27,10 @@ #include "src/core/lib/gpr/mpscq.h" #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/iomgr/closure.h" +#include "src/core/lib/iomgr/dynamic_annotations.h" // A simple, lock-free mechanism for serializing activity related to a // single call. This is similar to a combiner but is more lightweight. @@ -40,14 +43,38 @@ extern grpc_core::TraceFlag grpc_call_combiner_trace; -typedef struct { +struct grpc_call_combiner { gpr_atm size = 0; // size_t, num closures in queue or currently executing gpr_mpscq queue; // Either 0 (if not cancelled and no cancellation closure set), // a grpc_closure* (if the lowest bit is 0), // or a grpc_error* (if the lowest bit is 1). gpr_atm cancel_state = 0; -} grpc_call_combiner; +#ifdef GRPC_TSAN_ENABLED + // A fake ref-counted lock that is kept alive after the destruction of + // grpc_call_combiner, when we are running the original closure. + // + // Ideally we want to lock and unlock the call combiner as a pointer, when the + // callback is called. However, original_closure is free to trigger + // anything on the call combiner (including destruction of grpc_call). + // Thus, we need a ref-counted structure that can outlive the call combiner. + struct TsanLock + : public grpc_core::RefCounted { + TsanLock() { TSAN_ANNOTATE_RWLOCK_CREATE(&taken); } + ~TsanLock() { TSAN_ANNOTATE_RWLOCK_DESTROY(&taken); } + + // To avoid double-locking by the same thread, we should acquire/release + // the lock only when taken is false. On each acquire taken must be set to + // true. + std::atomic taken{false}; + }; + grpc_core::RefCountedPtr tsan_lock = + grpc_core::MakeRefCounted(); + grpc_closure tsan_closure; + grpc_closure* original_closure; +#endif +}; // Assumes memory was initialized to zero. void grpc_call_combiner_init(grpc_call_combiner* call_combiner); From 750e80ea1c12315ce987ed7b5c38595f698cf355 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Wed, 5 Dec 2018 10:27:01 -0800 Subject: [PATCH 0434/2143] bring back original network test for metadata server detection --- .../google_default_credentials.cc | 134 +++++++++++++++--- test/core/security/credentials_test.cc | 76 +++++++++- 2 files changed, 188 insertions(+), 22 deletions(-) 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 fcab2529592..7474380c051 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 @@ -49,9 +49,11 @@ /* -- Default credentials. -- */ -static int g_compute_engine_detection_done = 0; -static int g_need_compute_engine_creds = 0; +static int g_metadata_server_detection_done = 0; +static int g_metadata_server_available = 0; +static int g_is_on_gce = 0; static gpr_mu g_state_mu; +static gpr_mu* g_polling_mu; static gpr_once g_once = GPR_ONCE_INIT; static grpc_core::internal::grpc_gce_tenancy_checker g_gce_tenancy_checker = grpc_alts_is_running_on_gcp; @@ -89,15 +91,20 @@ static grpc_security_status google_default_create_security_connector( bool use_alts = is_grpclb_load_balancer || is_backend_from_grpclb_load_balancer; grpc_security_status status = GRPC_SECURITY_ERROR; + /* Return failure if ALTS is selected but not running on GCE. */ + if (use_alts && !g_is_on_gce) { + goto end; + } status = use_alts ? c->alts_creds->vtable->create_security_connector( c->alts_creds, call_creds, target, args, sc, new_args) : c->ssl_creds->vtable->create_security_connector( c->ssl_creds, call_creds, target, args, sc, new_args); - /* grpclb-specific channel args are removed from the channel args set - * to ensure backends and fallback adresses will have the same set of channel - * args. By doing that, it guarantees the connections to backends will not be - * torn down and re-connected when switching in and out of fallback mode. - */ +/* grpclb-specific channel args are removed from the channel args set + * to ensure backends and fallback adresses will have the same set of channel + * args. By doing that, it guarantees the connections to backends will not be + * torn down and re-connected when switching in and out of fallback mode. + */ +end: if (use_alts) { static const char* args_to_remove[] = { GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER, @@ -113,6 +120,93 @@ static grpc_channel_credentials_vtable google_default_credentials_vtable = { google_default_credentials_destruct, google_default_create_security_connector, nullptr}; +static void on_metadata_server_detection_http_response(void* user_data, + grpc_error* error) { + compute_engine_detector* detector = + static_cast(user_data); + if (error == GRPC_ERROR_NONE && detector->response.status == 200 && + detector->response.hdr_count > 0) { + /* Internet providers can return a generic response to all requests, so + it is necessary to check that metadata header is present also. */ + size_t i; + for (i = 0; i < detector->response.hdr_count; i++) { + grpc_http_header* header = &detector->response.hdrs[i]; + if (strcmp(header->key, "Metadata-Flavor") == 0 && + strcmp(header->value, "Google") == 0) { + detector->success = 1; + break; + } + } + } + gpr_mu_lock(g_polling_mu); + detector->is_done = 1; + GRPC_LOG_IF_ERROR( + "Pollset kick", + grpc_pollset_kick(grpc_polling_entity_pollset(&detector->pollent), + nullptr)); + gpr_mu_unlock(g_polling_mu); +} + +static void destroy_pollset(void* p, grpc_error* e) { + grpc_pollset_destroy(static_cast(p)); +} + +static int is_metadata_server_reachable() { + compute_engine_detector detector; + grpc_httpcli_request request; + grpc_httpcli_context context; + grpc_closure destroy_closure; + /* The http call is local. If it takes more than one sec, it is for sure not + on compute engine. */ + grpc_millis max_detection_delay = GPR_MS_PER_SEC; + grpc_pollset* pollset = + static_cast(gpr_zalloc(grpc_pollset_size())); + grpc_pollset_init(pollset, &g_polling_mu); + detector.pollent = grpc_polling_entity_create_from_pollset(pollset); + detector.is_done = 0; + detector.success = 0; + memset(&detector.response, 0, sizeof(detector.response)); + memset(&request, 0, sizeof(grpc_httpcli_request)); + request.host = (char*)GRPC_COMPUTE_ENGINE_DETECTION_HOST; + request.http.path = (char*)"/"; + grpc_httpcli_context_init(&context); + grpc_resource_quota* resource_quota = + grpc_resource_quota_create("google_default_credentials"); + grpc_httpcli_get( + &context, &detector.pollent, resource_quota, &request, + grpc_core::ExecCtx::Get()->Now() + max_detection_delay, + GRPC_CLOSURE_CREATE(on_metadata_server_detection_http_response, &detector, + grpc_schedule_on_exec_ctx), + &detector.response); + grpc_resource_quota_unref_internal(resource_quota); + grpc_core::ExecCtx::Get()->Flush(); + /* Block until we get the response. This is not ideal but this should only be + called once for the lifetime of the process by the default credentials. */ + gpr_mu_lock(g_polling_mu); + while (!detector.is_done) { + grpc_pollset_worker* worker = nullptr; + if (!GRPC_LOG_IF_ERROR( + "pollset_work", + grpc_pollset_work(grpc_polling_entity_pollset(&detector.pollent), + &worker, GRPC_MILLIS_INF_FUTURE))) { + detector.is_done = 1; + detector.success = 0; + } + } + gpr_mu_unlock(g_polling_mu); + grpc_httpcli_context_destroy(&context); + GRPC_CLOSURE_INIT(&destroy_closure, destroy_pollset, + grpc_polling_entity_pollset(&detector.pollent), + grpc_schedule_on_exec_ctx); + grpc_pollset_shutdown(grpc_polling_entity_pollset(&detector.pollent), + &destroy_closure); + g_polling_mu = nullptr; + grpc_core::ExecCtx::Get()->Flush(); + gpr_free(grpc_polling_entity_pollset(&detector.pollent)); + grpc_http_response_destroy(&detector.response); + return detector.success; +} + /* Takes ownership of creds_path if not NULL. */ static grpc_error* create_default_creds_from_path( char* creds_path, grpc_call_credentials** creds) { @@ -182,7 +276,6 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) { grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Failed to create Google credentials"); grpc_error* err; - int need_compute_engine_creds = 0; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ()); @@ -202,16 +295,25 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) { error = grpc_error_add_child(error, err); gpr_mu_lock(&g_state_mu); - /* At last try to see if we're on compute engine (do the detection only once - since it requires a network test). */ - if (!g_compute_engine_detection_done) { - g_need_compute_engine_creds = g_gce_tenancy_checker(); - g_compute_engine_detection_done = 1; + + /* Try a platform-provided hint for GCE. */ + if (!g_metadata_server_detection_done) { + g_is_on_gce = g_gce_tenancy_checker(); + g_metadata_server_detection_done = g_is_on_gce; + g_metadata_server_available = g_is_on_gce; + } + /* TODO: Add a platform-provided hint for GAE. */ + + /* Do a network test for metadata server. */ + if (!g_metadata_server_detection_done) { + bool detected = is_metadata_server_reachable(); + /* Do not cache detecion result if netowrk test returns false. */ + g_metadata_server_detection_done = detected; + g_metadata_server_available = detected; } - need_compute_engine_creds = g_need_compute_engine_creds; gpr_mu_unlock(&g_state_mu); - if (need_compute_engine_creds) { + if (g_metadata_server_available) { call_creds = grpc_google_compute_engine_credentials_create(nullptr); if (call_creds == nullptr) { error = grpc_error_add_child( @@ -259,7 +361,7 @@ void grpc_flush_cached_google_default_credentials(void) { grpc_core::ExecCtx exec_ctx; gpr_once_init(&g_once, init_default_credentials); gpr_mu_lock(&g_state_mu); - g_compute_engine_detection_done = 0; + g_metadata_server_detection_done = 0; gpr_mu_unlock(&g_state_mu); } diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index b3e3c3c7415..a7a6050ec0a 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -919,6 +919,22 @@ static void test_google_default_creds_refresh_token(void) { gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ } +static int default_creds_metadata_server_detection_httpcli_get_success_override( + const grpc_httpcli_request* request, grpc_millis deadline, + grpc_closure* on_done, grpc_httpcli_response* response) { + *response = http_response(200, ""); + grpc_http_header* headers = + static_cast(gpr_malloc(sizeof(*headers) * 1)); + headers[0].key = gpr_strdup("Metadata-Flavor"); + headers[0].value = gpr_strdup("Google"); + response->hdr_count = 1; + response->hdrs = headers; + GPR_ASSERT(strcmp(request->http.path, "/") == 0); + GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0); + GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + return 1; +} + static char* null_well_known_creds_path_getter(void) { return nullptr; } static bool test_gce_tenancy_checker(void) { @@ -963,26 +979,73 @@ static void test_google_default_creds_gce(void) { grpc_override_well_known_credentials_path_getter(nullptr); } +static void test_google_default_creds_non_gce(void) { + grpc_core::ExecCtx exec_ctx; + expected_md emd[] = { + {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}}; + request_metadata_state* state = + make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd)); + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, + nullptr, nullptr}; + grpc_flush_cached_google_default_credentials(); + gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ + grpc_override_well_known_credentials_path_getter( + null_well_known_creds_path_getter); + set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker); + g_test_gce_tenancy_checker_called = false; + g_test_is_on_gce = false; + /* Simulate a successful detection of metadata server. */ + grpc_httpcli_set_override( + default_creds_metadata_server_detection_httpcli_get_success_override, + httpcli_post_should_not_be_called); + grpc_composite_channel_credentials* creds = + reinterpret_cast( + grpc_google_default_credentials_create()); + /* Verify that the default creds actually embeds a GCE creds. */ + GPR_ASSERT(creds != nullptr); + GPR_ASSERT(creds->call_creds != nullptr); + grpc_httpcli_set_override(compute_engine_httpcli_get_success_override, + httpcli_post_should_not_be_called); + run_request_metadata_test(creds->call_creds, auth_md_ctx, state); + grpc_core::ExecCtx::Get()->Flush(); + GPR_ASSERT(g_test_gce_tenancy_checker_called == true); + /* Cleanup. */ + grpc_channel_credentials_unref(&creds->base); + grpc_httpcli_set_override(nullptr, nullptr); + grpc_override_well_known_credentials_path_getter(nullptr); +} + +static int default_creds_gce_detection_httpcli_get_failure_override( + const grpc_httpcli_request* request, grpc_millis deadline, + 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); + *response = http_response(200, ""); + GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + return 1; +} + static void test_no_google_default_creds(void) { grpc_flush_cached_google_default_credentials(); gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ grpc_override_well_known_credentials_path_getter( null_well_known_creds_path_getter); - set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker); g_test_gce_tenancy_checker_called = false; g_test_is_on_gce = false; - + grpc_httpcli_set_override( + default_creds_gce_detection_httpcli_get_failure_override, + httpcli_post_should_not_be_called); /* Simulate a successful detection of GCE. */ GPR_ASSERT(grpc_google_default_credentials_create() == nullptr); - - /* Try a second one. GCE detection should not occur anymore. */ + /* Try a second one. GCE detection should occur again. */ g_test_gce_tenancy_checker_called = false; GPR_ASSERT(grpc_google_default_credentials_create() == nullptr); - GPR_ASSERT(g_test_gce_tenancy_checker_called == false); - + GPR_ASSERT(g_test_gce_tenancy_checker_called == true); /* Cleanup. */ grpc_override_well_known_credentials_path_getter(nullptr); + grpc_httpcli_set_override(nullptr, nullptr); } typedef enum { @@ -1233,6 +1296,7 @@ int main(int argc, char** argv) { test_google_default_creds_auth_key(); test_google_default_creds_refresh_token(); test_google_default_creds_gce(); + test_google_default_creds_non_gce(); test_no_google_default_creds(); test_metadata_plugin_success(); test_metadata_plugin_failure(); From 9dce850250ff332fea7837a7d0a42638edd1aee8 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 5 Dec 2018 11:48:17 -0800 Subject: [PATCH 0435/2143] stop() server and enable skipped channelz test --- .../tests/channelz/_channelz_servicer_test.py | 46 +++++-------------- 1 file changed, 11 insertions(+), 35 deletions(-) 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 84f85946896..8ca51895224 100644 --- a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -69,32 +69,28 @@ class _ChannelServerPair(object): def __init__(self): # Server will enable channelz service - # Bind as attribute, so its `del` can be called explicitly, during - # the destruction process. Otherwise, if the removal of server - # rely on gc cycle, the test will become non-deterministic. - self._server = grpc.server( + self.server = grpc.server( futures.ThreadPoolExecutor(max_workers=3), options=_DISABLE_REUSE_PORT + _ENABLE_CHANNELZ) - port = self._server.add_insecure_port('[::]:0') - self._server.add_generic_rpc_handlers((_GenericHandler(),)) - self._server.start() + port = self.server.add_insecure_port('[::]:0') + self.server.add_generic_rpc_handlers((_GenericHandler(),)) + self.server.start() # Channel will enable channelz service... self.channel = grpc.insecure_channel('localhost:%d' % port, _ENABLE_CHANNELZ) - def __del__(self): - self._server.__del__() - self.channel.close() - def _generate_channel_server_pairs(n): return [_ChannelServerPair() for i in range(n)] -def _clean_channel_server_pairs(pairs): +def _close_channel_server_pairs(pairs): for pair in pairs: - pair.__del__() + pair.server.stop(None) + # TODO(ericgribkoff) This del should not be required + del pair.server + pair.channel.close() class ChannelzServicerTest(unittest.TestCase): @@ -147,9 +143,9 @@ class ChannelzServicerTest(unittest.TestCase): self._channelz_stub = channelz_pb2_grpc.ChannelzStub(self._channel) def tearDown(self): - self._server.__del__() + self._server.stop(None) self._channel.close() - _clean_channel_server_pairs(self._pairs) + _close_channel_server_pairs(self._pairs) def test_get_top_channels_basic(self): self._pairs = _generate_channel_server_pairs(1) @@ -278,20 +274,12 @@ class ChannelzServicerTest(unittest.TestCase): self.assertEqual(gtc_resp.channel[i].data.calls_failed, gsc_resp.subchannel.data.calls_failed) - @unittest.skip('Servers in core are not guaranteed to be destroyed ' \ - 'immediately when the reference goes out of scope, so ' \ - 'servers from multiple test cases are not hermetic. ' \ - 'TODO(https://github.com/grpc/grpc/issues/17258)') def test_server_basic(self): self._pairs = _generate_channel_server_pairs(1) resp = self._channelz_stub.GetServers( channelz_pb2.GetServersRequest(start_server_id=0)) self.assertEqual(len(resp.server), 1) - @unittest.skip('Servers in core are not guaranteed to be destroyed ' \ - 'immediately when the reference goes out of scope, so ' \ - 'servers from multiple test cases are not hermetic. ' \ - 'TODO(https://github.com/grpc/grpc/issues/17258)') def test_get_one_server(self): self._pairs = _generate_channel_server_pairs(1) gss_resp = self._channelz_stub.GetServers( @@ -303,10 +291,6 @@ class ChannelzServicerTest(unittest.TestCase): self.assertEqual(gss_resp.server[0].ref.server_id, gs_resp.server.ref.server_id) - @unittest.skip('Servers in core are not guaranteed to be destroyed ' \ - 'immediately when the reference goes out of scope, so ' \ - 'servers from multiple test cases are not hermetic. ' \ - 'TODO(https://github.com/grpc/grpc/issues/17258)') def test_server_call(self): self._pairs = _generate_channel_server_pairs(1) k_success = 23 @@ -401,10 +385,6 @@ class ChannelzServicerTest(unittest.TestCase): self.assertEqual(gs_resp.socket.data.messages_received, test_constants.STREAM_LENGTH) - @unittest.skip('Servers in core are not guaranteed to be destroyed ' \ - 'immediately when the reference goes out of scope, so ' \ - 'servers from multiple test cases are not hermetic. ' \ - 'TODO(https://github.com/grpc/grpc/issues/17258)') def test_server_sockets(self): self._pairs = _generate_channel_server_pairs(1) self._send_successful_unary_unary(0) @@ -423,10 +403,6 @@ class ChannelzServicerTest(unittest.TestCase): # If the RPC call failed, it will raise a grpc.RpcError # So, if there is no exception raised, considered pass - @unittest.skip('Servers in core are not guaranteed to be destroyed ' \ - 'immediately when the reference goes out of scope, so ' \ - 'servers from multiple test cases are not hermetic. ' \ - 'TODO(https://github.com/grpc/grpc/issues/17258)') def test_server_listen_sockets(self): self._pairs = _generate_channel_server_pairs(1) From 8d438057e42864e0a53217cd7b8d1636d5842422 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 5 Dec 2018 11:41:09 -0800 Subject: [PATCH 0436/2143] Add License to Python tarball --- PYTHON-MANIFEST.in | 1 + setup.cfg | 3 +++ 2 files changed, 4 insertions(+) diff --git a/PYTHON-MANIFEST.in b/PYTHON-MANIFEST.in index c0de5289ee2..544fefbc487 100644 --- a/PYTHON-MANIFEST.in +++ b/PYTHON-MANIFEST.in @@ -20,3 +20,4 @@ include src/python/grpcio/README.rst include requirements.txt include etc/roots.pem include Makefile +include LICENSE diff --git a/setup.cfg b/setup.cfg index 218792e674c..125ec93491d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -15,3 +15,6 @@ exclude=.*protoc_plugin/protoc_plugin_test\.proto$ # Style settings [yapf] based_on_style = google + +[metadata] +license_files = LICENSE From 4590fc5b7cddfac7647cfc493d9e4abb03c65bf9 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 5 Dec 2018 13:51:46 -0800 Subject: [PATCH 0437/2143] Revert "Strip manylinux1 binary wheels" This reverts commit be4b2db4ad68190288b5d1e8a9b54f094ebde157. Appears to leave the incorrect hash in the wheel RECORD file, as in https://github.com/grpc/grpc/issues/17409 --- tools/run_tests/artifacts/build_package_python.sh | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/tools/run_tests/artifacts/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh index d93e8979fcc..29801a5b867 100755 --- a/tools/run_tests/artifacts/build_package_python.sh +++ b/tools/run_tests/artifacts/build_package_python.sh @@ -19,20 +19,10 @@ cd "$(dirname "$0")/../../.." mkdir -p artifacts/ +# All the python packages have been built in the artifact phase already +# 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() { - TEMP_WHEEL_DIR=$(mktemp -d) - unzip "$1" -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 {} ";" - (cd "$TEMP_WHEEL_DIR" && zip -r - .) > "$1" -} - -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 b4565f1b19a60f7e89806454b27f83e188381d81 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 5 Dec 2018 15:01:37 -0800 Subject: [PATCH 0438/2143] 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 5710a3a25d57f63c8cf4e50d258d0aaa1cc54aee Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 5 Dec 2018 13:51:46 -0800 Subject: [PATCH 0439/2143] Revert "Strip manylinux1 binary wheels" This reverts commit be4b2db4ad68190288b5d1e8a9b54f094ebde157. Appears to leave the incorrect hash in the wheel RECORD file, as in https://github.com/grpc/grpc/issues/17409 --- tools/run_tests/artifacts/build_package_python.sh | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/tools/run_tests/artifacts/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh index d93e8979fcc..29801a5b867 100755 --- a/tools/run_tests/artifacts/build_package_python.sh +++ b/tools/run_tests/artifacts/build_package_python.sh @@ -19,20 +19,10 @@ cd "$(dirname "$0")/../../.." mkdir -p artifacts/ +# All the python packages have been built in the artifact phase already +# 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() { - TEMP_WHEEL_DIR=$(mktemp -d) - unzip "$1" -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 {} ";" - (cd "$TEMP_WHEEL_DIR" && zip -r - .) > "$1" -} - -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 5c1ff6cb4a9826b2aad773e3397ea608db543798 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 5 Dec 2018 15:09:12 -0800 Subject: [PATCH 0440/2143] 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 5584d58e6ce3dbc2f110f1096dfd739b1cb2ce18 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 5 Dec 2018 14:51:07 -0800 Subject: [PATCH 0441/2143] Add LICENSE to grpcio-* packages * Using the proprocess command to copy the LICENSE --- src/python/grpcio_channelz/MANIFEST.in | 1 + .../grpcio_channelz/channelz_commands.py | 8 +++- src/python/grpcio_channelz/setup.py | 2 +- src/python/grpcio_health_checking/MANIFEST.in | 1 + .../grpcio_health_checking/health_commands.py | 8 +++- src/python/grpcio_health_checking/setup.py | 2 +- src/python/grpcio_reflection/MANIFEST.in | 1 + .../grpcio_reflection/reflection_commands.py | 8 +++- src/python/grpcio_reflection/setup.py | 2 +- src/python/grpcio_testing/MANIFEST.in | 1 + src/python/grpcio_testing/setup.py | 33 +++++++++++++++- src/python/grpcio_testing/testing_commands.py | 39 +++++++++++++++++++ .../artifacts/build_artifact_python.sh | 3 +- 13 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 src/python/grpcio_testing/testing_commands.py diff --git a/src/python/grpcio_channelz/MANIFEST.in b/src/python/grpcio_channelz/MANIFEST.in index 5597f375ba6..ee93e21a69b 100644 --- a/src/python/grpcio_channelz/MANIFEST.in +++ b/src/python/grpcio_channelz/MANIFEST.in @@ -1,3 +1,4 @@ include grpc_version.py recursive-include grpc_channelz *.py global-exclude *.pyc +include LICENSE diff --git a/src/python/grpcio_channelz/channelz_commands.py b/src/python/grpcio_channelz/channelz_commands.py index e9ad3550340..7f158c2a4bf 100644 --- a/src/python/grpcio_channelz/channelz_commands.py +++ b/src/python/grpcio_channelz/channelz_commands.py @@ -21,10 +21,12 @@ 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 CopyProtoModules(setuptools.Command): - """Command to copy proto modules from grpc/src/proto.""" +class Preprocess(setuptools.Command): + """Command to copy proto modules from grpc/src/proto and LICENSE from + the root directory""" description = '' user_options = [] @@ -40,6 +42,8 @@ class CopyProtoModules(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_channelz/setup.py b/src/python/grpcio_channelz/setup.py index a495052376d..f8c0e93913d 100644 --- a/src/python/grpcio_channelz/setup.py +++ b/src/python/grpcio_channelz/setup.py @@ -69,7 +69,7 @@ try: 'grpcio-tools=={version}'.format(version=grpc_version.VERSION),) COMMAND_CLASS = { # Run preprocess from the repository *before* doing any packaging! - 'preprocess': _channelz_commands.CopyProtoModules, + 'preprocess': _channelz_commands.Preprocess, 'build_package_protos': _channelz_commands.BuildPackageProtos, } except ImportError: diff --git a/src/python/grpcio_health_checking/MANIFEST.in b/src/python/grpcio_health_checking/MANIFEST.in index 996c74a9d49..3a22311b8e7 100644 --- a/src/python/grpcio_health_checking/MANIFEST.in +++ b/src/python/grpcio_health_checking/MANIFEST.in @@ -1,3 +1,4 @@ include grpc_version.py recursive-include grpc_health *.py global-exclude *.pyc +include LICENSE diff --git a/src/python/grpcio_health_checking/health_commands.py b/src/python/grpcio_health_checking/health_commands.py index 933f965aa2d..3820ef0bbad 100644 --- a/src/python/grpcio_health_checking/health_commands.py +++ b/src/python/grpcio_health_checking/health_commands.py @@ -20,10 +20,12 @@ 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 CopyProtoModules(setuptools.Command): - """Command to copy proto modules from grpc/src/proto.""" +class Preprocess(setuptools.Command): + """Command to copy proto modules from grpc/src/proto and LICENSE from + the root directory""" description = '' user_options = [] @@ -39,6 +41,8 @@ class CopyProtoModules(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_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py index db2edae2cea..5a09a80f6ae 100644 --- a/src/python/grpcio_health_checking/setup.py +++ b/src/python/grpcio_health_checking/setup.py @@ -68,7 +68,7 @@ try: 'grpcio-tools=={version}'.format(version=grpc_version.VERSION),) COMMAND_CLASS = { # Run preprocess from the repository *before* doing any packaging! - 'preprocess': _health_commands.CopyProtoModules, + 'preprocess': _health_commands.Preprocess, 'build_package_protos': _health_commands.BuildPackageProtos, } except ImportError: diff --git a/src/python/grpcio_reflection/MANIFEST.in b/src/python/grpcio_reflection/MANIFEST.in index d6fb6ce73aa..10b01fa41de 100644 --- a/src/python/grpcio_reflection/MANIFEST.in +++ b/src/python/grpcio_reflection/MANIFEST.in @@ -1,3 +1,4 @@ include grpc_version.py recursive-include grpc_reflection *.py global-exclude *.pyc +include LICENSE diff --git a/src/python/grpcio_reflection/reflection_commands.py b/src/python/grpcio_reflection/reflection_commands.py index 6f91f6b8751..311ca4c4dba 100644 --- a/src/python/grpcio_reflection/reflection_commands.py +++ b/src/python/grpcio_reflection/reflection_commands.py @@ -21,10 +21,12 @@ 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 CopyProtoModules(setuptools.Command): - """Command to copy proto modules from grpc/src/proto.""" +class Preprocess(setuptools.Command): + """Command to copy proto modules from grpc/src/proto and LICENSE from + the root directory""" description = '' user_options = [] @@ -41,6 +43,8 @@ class CopyProtoModules(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_reflection/setup.py b/src/python/grpcio_reflection/setup.py index b4087d87b49..f205069acd5 100644 --- a/src/python/grpcio_reflection/setup.py +++ b/src/python/grpcio_reflection/setup.py @@ -69,7 +69,7 @@ try: 'grpcio-tools=={version}'.format(version=grpc_version.VERSION),) COMMAND_CLASS = { # Run preprocess from the repository *before* doing any packaging! - 'preprocess': _reflection_commands.CopyProtoModules, + 'preprocess': _reflection_commands.Preprocess, 'build_package_protos': _reflection_commands.BuildPackageProtos, } except ImportError: diff --git a/src/python/grpcio_testing/MANIFEST.in b/src/python/grpcio_testing/MANIFEST.in index 39b35652173..559dfaf786f 100644 --- a/src/python/grpcio_testing/MANIFEST.in +++ b/src/python/grpcio_testing/MANIFEST.in @@ -1,3 +1,4 @@ include grpc_version.py recursive-include grpc_testing *.py global-exclude *.pyc +include LICENSE diff --git a/src/python/grpcio_testing/setup.py b/src/python/grpcio_testing/setup.py index 6ceb1fc5c9d..18db71e0f09 100644 --- a/src/python/grpcio_testing/setup.py +++ b/src/python/grpcio_testing/setup.py @@ -24,6 +24,23 @@ os.chdir(os.path.dirname(os.path.abspath(__file__))) # Break import style to ensure that we can find same-directory modules. import grpc_version + +class _NoOpCommand(setuptools.Command): + """No-op command.""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + pass + + PACKAGE_DIRECTORIES = { '': '.', } @@ -33,6 +50,19 @@ 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, + } + setuptools.setup( name='grpcio-testing', version=grpc_version.VERSION, @@ -43,4 +73,5 @@ setuptools.setup( url='https://grpc.io', package_dir=PACKAGE_DIRECTORIES, packages=setuptools.find_packages('.'), - install_requires=INSTALL_REQUIRES) + install_requires=INSTALL_REQUIRES, + cmdclass=COMMAND_CLASS) 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/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index bc6e5582046..605470325ab 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -105,7 +105,8 @@ then "${PIP}" install grpcio-tools --no-index --find-links "file://$ARTIFACT_DIR/" # Build grpcio_testing source distribution - ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_testing/setup.py sdist + ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_testing/setup.py preprocess \ + sdist cp -r src/python/grpcio_testing/dist/* "$ARTIFACT_DIR" # Build grpcio_channelz source distribution From e1f573a58b9278c7f98011264613ef4e66a028f2 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 5 Dec 2018 15:43:23 -0800 Subject: [PATCH 0442/2143] 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 eb0b39df3d9304bf1b15a4c294abaad36a173ddc Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 5 Dec 2018 16:04:26 -0800 Subject: [PATCH 0443/2143] Do OnDone as the actual last thing so that the reactor can be reused. --- include/grpcpp/impl/codegen/client_callback.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 4d9579fd6ab..ede8ac54ca0 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -255,10 +255,12 @@ class ClientCallbackReaderWriterImpl void MaybeFinish() { if (--callbacks_outstanding_ == 0) { - reactor_->OnDone(finish_status_); + Status s = std::move(finish_status_); + auto* reactor = reactor_; auto* call = call_.call(); this->~ClientCallbackReaderWriterImpl(); g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); } } @@ -450,10 +452,12 @@ class ClientCallbackReaderImpl void MaybeFinish() { if (--callbacks_outstanding_ == 0) { - reactor_->OnDone(finish_status_); + Status s = std::move(finish_status_); + auto* reactor = reactor_; auto* call = call_.call(); this->~ClientCallbackReaderImpl(); g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); } } @@ -576,10 +580,12 @@ class ClientCallbackWriterImpl void MaybeFinish() { if (--callbacks_outstanding_ == 0) { - reactor_->OnDone(finish_status_); + Status s = std::move(finish_status_); + auto* reactor = reactor_; auto* call = call_.call(); this->~ClientCallbackWriterImpl(); g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); } } From de00c613a95269f1e3a2947c5f16f3cb3b7bbb02 Mon Sep 17 00:00:00 2001 From: Sheena Madan <43831800+sheenaqotj@users.noreply.github.com> Date: Wed, 5 Dec 2018 16:40:37 -0800 Subject: [PATCH 0444/2143] Revert "Add Testonly to Targets" --- test/cpp/microbenchmarks/BUILD | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index afac414e09d..84ea386870d 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -29,7 +29,6 @@ grpc_cc_test( grpc_cc_library( name = "helpers", - testonly = 1, srcs = ["helpers.cc"], hdrs = [ "fullstack_context_mutators.h", @@ -58,7 +57,6 @@ grpc_cc_test( # right now it OOMs grpc_cc_binary( name = "bm_arena", - testonly = 1, srcs = ["bm_arena.cc"], deps = [":helpers"], ) @@ -74,7 +72,6 @@ grpc_cc_test( # right now it fails UBSAN grpc_cc_binary( name = "bm_call_create", - testonly = 1, srcs = ["bm_call_create.cc"], deps = [":helpers"], ) @@ -102,7 +99,6 @@ grpc_cc_test( grpc_cc_library( name = "fullstack_streaming_ping_pong_h", - testonly = 1, hdrs = [ "fullstack_streaming_ping_pong.h", ], @@ -119,7 +115,6 @@ grpc_cc_test( grpc_cc_library( name = "fullstack_streaming_pump_h", - testonly = 1, hdrs = [ "fullstack_streaming_pump.h", ], @@ -136,14 +131,12 @@ grpc_cc_test( grpc_cc_binary( name = "bm_fullstack_trickle", - testonly = 1, srcs = ["bm_fullstack_trickle.cc"], deps = [":helpers"], ) grpc_cc_library( name = "fullstack_unary_ping_pong_h", - testonly = 1, hdrs = [ "fullstack_unary_ping_pong.h", ], From 8a461613d1ac867310558e03f5856fdb771c319a Mon Sep 17 00:00:00 2001 From: Sheena Madan <43831800+sheenaqotj@users.noreply.github.com> Date: Wed, 5 Dec 2018 16:45:15 -0800 Subject: [PATCH 0445/2143] Revert "Make Microbenchmarks Test Targets" --- test/cpp/microbenchmarks/BUILD | 53 ++++++++-------------- test/cpp/microbenchmarks/bm_call_create.cc | 2 +- 2 files changed, 21 insertions(+), 34 deletions(-) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index afac414e09d..097e92f5836 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -47,15 +47,13 @@ grpc_cc_library( ], ) -grpc_cc_test( +grpc_cc_binary( name = "bm_closure", + testonly = 1, srcs = ["bm_closure.cc"], deps = [":helpers"], - uses_polling = False, ) -# TODO(https://github.com/grpc/grpc/pull/16882): make this a test target -# right now it OOMs grpc_cc_binary( name = "bm_arena", testonly = 1, @@ -63,15 +61,13 @@ grpc_cc_binary( deps = [":helpers"], ) -grpc_cc_test( +grpc_cc_binary( name = "bm_channel", + testonly = 1, srcs = ["bm_channel.cc"], deps = [":helpers"], - uses_polling = False, ) -# TODO(https://github.com/grpc/grpc/pull/16882): make this a test target -# right now it fails UBSAN grpc_cc_binary( name = "bm_call_create", testonly = 1, @@ -79,25 +75,25 @@ grpc_cc_binary( deps = [":helpers"], ) -grpc_cc_test( +grpc_cc_binary( name = "bm_cq", + testonly = 1, srcs = ["bm_cq.cc"], deps = [":helpers"], - uses_polling = False, ) -grpc_cc_test( +grpc_cc_binary( name = "bm_cq_multiple_threads", + testonly = 1, srcs = ["bm_cq_multiple_threads.cc"], deps = [":helpers"], - uses_polling = False, ) -grpc_cc_test( +grpc_cc_binary( name = "bm_error", + testonly = 1, srcs = ["bm_error.cc"], deps = [":helpers"], - uses_polling = False, ) grpc_cc_library( @@ -109,8 +105,9 @@ grpc_cc_library( deps = [":helpers"], ) -grpc_cc_test( +grpc_cc_binary( name = "bm_fullstack_streaming_ping_pong", + testonly = 1, srcs = [ "bm_fullstack_streaming_ping_pong.cc", ], @@ -126,8 +123,9 @@ grpc_cc_library( deps = [":helpers"], ) -grpc_cc_test( +grpc_cc_binary( name = "bm_fullstack_streaming_pump", + testonly = 1, srcs = [ "bm_fullstack_streaming_pump.cc", ], @@ -150,38 +148,27 @@ grpc_cc_library( deps = [":helpers"], ) -grpc_cc_test( +grpc_cc_binary( name = "bm_fullstack_unary_ping_pong", + testonly = 1, srcs = [ "bm_fullstack_unary_ping_pong.cc", ], deps = [":fullstack_unary_ping_pong_h"], ) -grpc_cc_test( +grpc_cc_binary( name = "bm_metadata", + testonly = 1, srcs = ["bm_metadata.cc"], deps = [":helpers"], - uses_polling = False, ) -grpc_cc_test( +grpc_cc_binary( name = "bm_chttp2_hpack", + testonly = 1, srcs = ["bm_chttp2_hpack.cc"], deps = [":helpers"], - uses_polling = False, -) - -grpc_cc_test( - name = "bm_chttp2_transport", - srcs = ["bm_chttp2_transport.cc"], - deps = [":helpers"], -) - -grpc_cc_test( - name = "bm_pollset", - srcs = ["bm_pollset.cc"], - deps = [":helpers"], ) grpc_cc_binary( diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index a0157c66c25..8d12606434b 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -526,7 +526,7 @@ static void BM_IsolatedFilter(benchmark::State& state) { grpc_core::ExecCtx exec_ctx; size_t channel_size = grpc_channel_stack_size( - filters.size() == 0 ? nullptr : filters.data(), filters.size()); + filters.size() == 0 ? nullptr : &filters[0], filters.size()); grpc_channel_stack* channel_stack = static_cast(gpr_zalloc(channel_size)); GPR_ASSERT(GRPC_LOG_IF_ERROR( From 734be6c7890670ea3c651aecbba74420a6601db3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 5 Dec 2018 18:28:43 -0800 Subject: [PATCH 0446/2143] Update doc to clarify serial queue requirement --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index e0ef8b1391f..e687a65da7d 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -253,7 +253,7 @@ extern id const kGRPCTrailersKey; + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path; /** - * Set the dispatch queue to be used for callbacks. + * Set the dispatch queue to be used for callbacks. Current implementation requires \a queue to be a serial queue. * * This configuration is only effective before the call starts. */ From f95262b53fe19cecf760457763ac6938be459835 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 4 Dec 2018 23:09:03 -0500 Subject: [PATCH 0447/2143] Implement a lock-free fast path for queue_call_request() For tiny RPCs, every single requests in almost the first item in the list. Hence, it would try to lock the server to process pending requests. Instead of locking, simply set and check atomic values when there is a possiblity of having pending requests. This increases QPS by 10%, for the 62-channel/0B-RPC benchmark using the callback API. --- src/core/lib/surface/server.cc | 106 ++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 42 deletions(-) diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 5dc81b29bb7..1f66be240e3 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -192,10 +192,13 @@ struct call_data { }; struct request_matcher { + request_matcher(grpc_server* server); + ~request_matcher(); + grpc_server* server; - call_data* pending_head; - call_data* pending_tail; - gpr_locked_mpscq* requests_per_cq; + std::atomic pending_head{nullptr}; + call_data* pending_tail = nullptr; + gpr_locked_mpscq* requests_per_cq = nullptr; }; struct registered_method { @@ -344,22 +347,30 @@ static void channel_broadcaster_shutdown(channel_broadcaster* cb, * request_matcher */ -static void request_matcher_init(request_matcher* rm, grpc_server* server) { - memset(rm, 0, sizeof(*rm)); - rm->server = server; - rm->requests_per_cq = static_cast( - gpr_malloc(sizeof(*rm->requests_per_cq) * server->cq_count)); +namespace { +request_matcher::request_matcher(grpc_server* server) : server(server) { + requests_per_cq = static_cast( + gpr_malloc(sizeof(*requests_per_cq) * server->cq_count)); for (size_t i = 0; i < server->cq_count; i++) { - gpr_locked_mpscq_init(&rm->requests_per_cq[i]); + gpr_locked_mpscq_init(&requests_per_cq[i]); } } -static void request_matcher_destroy(request_matcher* rm) { - for (size_t i = 0; i < rm->server->cq_count; i++) { - GPR_ASSERT(gpr_locked_mpscq_pop(&rm->requests_per_cq[i]) == nullptr); - gpr_locked_mpscq_destroy(&rm->requests_per_cq[i]); +request_matcher::~request_matcher() { + for (size_t i = 0; i < server->cq_count; i++) { + GPR_ASSERT(gpr_locked_mpscq_pop(&requests_per_cq[i]) == nullptr); + gpr_locked_mpscq_destroy(&requests_per_cq[i]); } - gpr_free(rm->requests_per_cq); + gpr_free(requests_per_cq); +} +} // namespace + +static void request_matcher_init(request_matcher* rm, grpc_server* server) { + new (rm) request_matcher(server); +} + +static void request_matcher_destroy(request_matcher* rm) { + rm->~request_matcher(); } static void kill_zombie(void* elem, grpc_error* error) { @@ -368,9 +379,10 @@ static void kill_zombie(void* elem, grpc_error* error) { } static void request_matcher_zombify_all_pending_calls(request_matcher* rm) { - while (rm->pending_head) { - call_data* calld = rm->pending_head; - rm->pending_head = calld->pending_next; + call_data* calld; + while ((calld = rm->pending_head.load(std::memory_order_relaxed)) != + nullptr) { + rm->pending_head.store(calld->pending_next, std::memory_order_relaxed); gpr_atm_no_barrier_store(&calld->state, ZOMBIED); GRPC_CLOSURE_INIT( &calld->kill_zombie_closure, kill_zombie, @@ -568,8 +580,9 @@ static void publish_new_rpc(void* arg, grpc_error* error) { } gpr_atm_no_barrier_store(&calld->state, PENDING); - if (rm->pending_head == nullptr) { - rm->pending_tail = rm->pending_head = calld; + if (rm->pending_head.load(std::memory_order_relaxed) == nullptr) { + rm->pending_head.store(calld, std::memory_order_relaxed); + rm->pending_tail = calld; } else { rm->pending_tail->pending_next = calld; rm->pending_tail = calld; @@ -1433,30 +1446,39 @@ static grpc_call_error queue_call_request(grpc_server* server, size_t cq_idx, rm = &rc->data.registered.method->matcher; break; } - if (gpr_locked_mpscq_push(&rm->requests_per_cq[cq_idx], &rc->request_link)) { - /* this was the first queued request: we need to lock and start - matching calls */ - gpr_mu_lock(&server->mu_call); - while ((calld = rm->pending_head) != nullptr) { - rc = reinterpret_cast( - gpr_locked_mpscq_pop(&rm->requests_per_cq[cq_idx])); - if (rc == nullptr) break; - rm->pending_head = calld->pending_next; - gpr_mu_unlock(&server->mu_call); - if (!gpr_atm_full_cas(&calld->state, PENDING, ACTIVATED)) { - // Zombied Call - GRPC_CLOSURE_INIT( - &calld->kill_zombie_closure, kill_zombie, - grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0), - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_SCHED(&calld->kill_zombie_closure, GRPC_ERROR_NONE); - } else { - publish_call(server, calld, cq_idx, rc); - } - gpr_mu_lock(&server->mu_call); - } - gpr_mu_unlock(&server->mu_call); + + // Fast path: if there is no pending request to be processed, immediately + // return. + if (!gpr_locked_mpscq_push(&rm->requests_per_cq[cq_idx], &rc->request_link) || + // Note: We are reading the pending_head without holding the server's call + // mutex. Even if we read a non-null value here due to reordering, + // we will check it below again after grabbing the lock. + rm->pending_head.load(std::memory_order_relaxed) == nullptr) { + return GRPC_CALL_OK; } + // Slow path: This was the first queued request and there are pendings: + // We need to lock and start matching calls. + gpr_mu_lock(&server->mu_call); + while ((calld = rm->pending_head.load(std::memory_order_relaxed)) != + nullptr) { + rc = reinterpret_cast( + gpr_locked_mpscq_pop(&rm->requests_per_cq[cq_idx])); + if (rc == nullptr) break; + rm->pending_head.store(calld->pending_next, std::memory_order_relaxed); + gpr_mu_unlock(&server->mu_call); + if (!gpr_atm_full_cas(&calld->state, PENDING, ACTIVATED)) { + // Zombied Call + GRPC_CLOSURE_INIT( + &calld->kill_zombie_closure, kill_zombie, + grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0), + grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_SCHED(&calld->kill_zombie_closure, GRPC_ERROR_NONE); + } else { + publish_call(server, calld, cq_idx, rc); + } + gpr_mu_lock(&server->mu_call); + } + gpr_mu_unlock(&server->mu_call); return GRPC_CALL_OK; } From dfec57a9a9ebfbe92709498074eb184527ef599e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 5 Dec 2018 22:52:12 -0800 Subject: [PATCH 0448/2143] Channel pool polishments --- .../GRPCClient/private/GRPCChannelPool.h | 5 ++- .../GRPCClient/private/GRPCChannelPool.m | 41 ++++++++++--------- .../GRPCClient/private/GRPCWrappedCall.m | 10 ++--- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 338b6e440f3..7c6f2b3bbfa 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -67,8 +67,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)notifyWrappedCallDealloc:(GRPCWrappedCall *)wrappedCall; /** - * Force the channel to disconnect immediately. Subsequent calls to unmanagedCallWithPath: will - * attempt to reconnect to the remote channel. + * Force the channel to disconnect immediately. GRPCWrappedCall objects previously created with + * \a wrappedCallWithPath are failed if not already finished. Subsequent calls to + * unmanagedCallWithPath: will attempt to reconnect to the remote channel. */ - (void)disconnect; diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 488766c0edc..391022efd19 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -57,7 +57,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (void)dealloc { - if ([_wrappedCalls objectEnumerator].allObjects.count != 0) { + // Disconnect GRPCWrappedCall objects created but not yet removed + if (_wrappedCalls.allObjects.count != 0) { NSEnumerator *enumerator = [_wrappedCalls objectEnumerator]; GRPCWrappedCall *wrappedCall; while ((wrappedCall = [enumerator nextObject])) { @@ -111,13 +112,17 @@ callOptions:(GRPCCallOptions *)callOptions { return; } @synchronized(self) { - if ([_wrappedCalls objectEnumerator].allObjects.count == 0) { + // Detect if all objects weakly referenced in _wrappedCalls are (implicitly) removed. In such + // case the channel is no longer referenced by a grpc_call object and can be destroyed after + // a certain delay. + if (_wrappedCalls.allObjects.count == 0) { NSDate *now = [NSDate date]; + NSAssert(now != nil, @"Unable to create NSDate object 'now'."); _lastTimedDestroy = now; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)_destroyDelay * NSEC_PER_SEC), _timerQueue, ^{ @synchronized(self) { - if (self->_lastTimedDestroy == now) { + if (now != nil && self->_lastTimedDestroy == now) { self->_wrappedChannel = nil; self->_lastTimedDestroy = nil; } @@ -128,17 +133,15 @@ callOptions:(GRPCCallOptions *)callOptions { } - (void)disconnect { - NSHashTable *copiedWrappedCalls = nil; + NSArray *copiedWrappedCalls = nil; @synchronized(self) { if (_wrappedChannel != nil) { _wrappedChannel = nil; - copiedWrappedCalls = [_wrappedCalls copy]; + copiedWrappedCalls = _wrappedCalls.allObjects; [_wrappedCalls removeAllObjects]; } } - NSEnumerator *enumerator = [copiedWrappedCalls objectEnumerator]; - GRPCWrappedCall *wrappedCall; - while ((wrappedCall = [enumerator nextObject])) { + for (GRPCWrappedCall *wrappedCall in copiedWrappedCalls) { [wrappedCall channelDisconnected]; } } @@ -155,9 +158,9 @@ callOptions:(GRPCCallOptions *)callOptions { } if ((self = [super init])) { - _channelConfiguration = channelConfiguration; + _channelConfiguration = [channelConfiguration copy]; _destroyDelay = destroyDelay; - _wrappedCalls = [[NSHashTable alloc] initWithOptions:NSHashTableWeakMemory capacity:1]; + _wrappedCalls = [NSHashTable weakObjectsHashTable]; _wrappedChannel = nil; _lastTimedDestroy = nil; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 @@ -187,7 +190,7 @@ callOptions:(GRPCCallOptions *)callOptions { @interface GRPCChannelPool () -- (instancetype)initInstance NS_DESIGNATED_INITIALIZER; +- (instancetype)initPrivate NS_DESIGNATED_INITIALIZER; @end @@ -198,13 +201,13 @@ callOptions:(GRPCCallOptions *)callOptions { + (instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ gChannelPool = - [[GRPCChannelPool alloc] initInstance]; + [[GRPCChannelPool alloc] initPrivate]; NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); }); return gChannelPool; } -- (instancetype)initInstance { +- (instancetype)initPrivate { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; @@ -242,15 +245,15 @@ callOptions:(GRPCCallOptions *)callOptions { } - (void)disconnectAllChannels { - NSDictionary *copiedPooledChannels; + NSArray *copiedPooledChannels; @synchronized(self) { - copiedPooledChannels = [NSDictionary dictionaryWithDictionary:_channelPool]; + copiedPooledChannels = _channelPool.allValues; } // Disconnect pooled channels. - [copiedPooledChannels enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - [obj disconnect]; - }]; + for (GRPCPooledChannel *pooledChannel in copiedPooledChannels) { + [pooledChannel disconnect]; + } } - (void)connectivityChange:(NSNotification *)note { @@ -262,7 +265,7 @@ callOptions:(GRPCCallOptions *)callOptions { @implementation GRPCChannelPool (Test) - (instancetype)initTestPool { - return [self initInstance]; + return [self initPrivate]; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 7e2d9d3c6d3..727c9e0a88e 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -237,7 +237,7 @@ #pragma mark GRPCWrappedCall @implementation GRPCWrappedCall { - __weak GRPCPooledChannel *_channel; + GRPCPooledChannel *_pooledChannel; grpc_call *_call; } @@ -251,7 +251,7 @@ if ((self = [super init])) { _call = unmanagedCall; - _channel = pooledChannel; + _pooledChannel = pooledChannel; } return self; } @@ -324,10 +324,8 @@ _call = NULL; } } - __strong GRPCPooledChannel *channel = _channel; - if (channel != nil) { - [channel notifyWrappedCallDealloc:self]; - } + __strong GRPCPooledChannel *channel = _pooledChannel; + [channel notifyWrappedCallDealloc:self]; } @end From 7cb0290d9cec348eb0dde9c6661d78b77ac7b0f6 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 6 Dec 2018 07:41:58 -0800 Subject: [PATCH 0449/2143] Fix off by one error in channelz --- src/core/lib/channel/channelz.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 8d589f5983e..0802143fbeb 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -208,11 +208,7 @@ char* ServerNode::RenderServerSockets(intptr_t start_socket_id) { grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; ChildRefsList socket_refs; - // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is - // reserved). However, we want to support requests coming in with - // start_server_id=0, which signifies "give me everything." - size_t start_idx = start_socket_id == 0 ? 0 : start_socket_id - 1; - grpc_server_populate_server_sockets(server_, &socket_refs, start_idx); + grpc_server_populate_server_sockets(server_, &socket_refs, start_socket_id); if (!socket_refs.empty()) { // create list of socket refs grpc_json* array_parent = grpc_json_create_child( From f1f5d2fa8c8ceea386f0a69da2e3a4e78973db51 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 6 Dec 2018 08:34:08 -0800 Subject: [PATCH 0450/2143] Fix LB policy name case handling. --- .../filters/client_channel/client_channel.cc | 6 +- .../client_channel/resolver_result_parsing.cc | 65 +++++++------------ 2 files changed, 28 insertions(+), 43 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index be7962261bc..3347676a48f 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -489,9 +489,9 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) { // taking a lock on chand->info_mu, because this function is the // only thing that modifies its value, and it can only be invoked // once at any given time. - bool lb_policy_name_changed = chand->info_lb_policy_name == nullptr || - gpr_stricmp(chand->info_lb_policy_name.get(), - lb_policy_name.get()) != 0; + bool lb_policy_name_changed = + chand->info_lb_policy_name == nullptr || + strcmp(chand->info_lb_policy_name.get(), lb_policy_name.get()) != 0; if (chand->lb_policy != nullptr && !lb_policy_name_changed) { // Continue using the same LB policy. Update with new addresses. if (grpc_client_channel_trace.enabled()) { 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 82a26ace634..4f7fd6b4243 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -40,32 +40,11 @@ namespace grpc_core { namespace internal { -namespace { - -// Converts string format from JSON to proto. -grpc_core::UniquePtr ConvertCamelToSnake(const char* camel) { - const size_t size = strlen(camel); - char* snake = static_cast(gpr_malloc(size * 2)); - size_t j = 0; - for (size_t i = 0; i < size; ++i) { - if (isupper(camel[i])) { - snake[j++] = '_'; - snake[j++] = tolower(camel[i]); - } else { - snake[j++] = camel[i]; - } - } - snake[j] = '\0'; - return grpc_core::UniquePtr(snake); -} - -} // namespace - ProcessedResolverResult::ProcessedResolverResult( const grpc_channel_args* resolver_result, bool parse_retry) { ProcessServiceConfig(resolver_result, parse_retry); // If no LB config was found above, just find the LB policy name then. - if (lb_policy_config_ == nullptr) ProcessLbPolicyName(resolver_result); + if (lb_policy_name_ == nullptr) ProcessLbPolicyName(resolver_result); } void ProcessedResolverResult::ProcessServiceConfig( @@ -98,18 +77,25 @@ void ProcessedResolverResult::ProcessServiceConfig( void ProcessedResolverResult::ProcessLbPolicyName( const grpc_channel_args* resolver_result) { - const char* lb_policy_name = nullptr; // 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. if (service_config_ != nullptr) { - lb_policy_name = service_config_->GetLoadBalancingPolicyName(); + lb_policy_name_.reset( + gpr_strdup(service_config_->GetLoadBalancingPolicyName())); + // Convert to lower-case. + if (lb_policy_name_ != nullptr) { + char* lb_policy_name = lb_policy_name_.get(); + for (size_t i = 0; i < strlen(lb_policy_name); ++i) { + lb_policy_name[i] = tolower(lb_policy_name[i]); + } + } } // Otherwise, find the LB policy name set by the client API. - if (lb_policy_name == nullptr) { + if (lb_policy_name_ == nullptr) { const grpc_arg* channel_arg = grpc_channel_args_find(resolver_result, GRPC_ARG_LB_POLICY_NAME); - lb_policy_name = grpc_channel_arg_get_string(channel_arg); + 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. @@ -119,20 +105,21 @@ void ProcessedResolverResult::ProcessLbPolicyName( grpc_lb_addresses* addresses = static_cast(channel_arg->value.pointer.p); if (grpc_lb_addresses_contains_balancer_address(*addresses)) { - if (lb_policy_name != nullptr && - gpr_stricmp(lb_policy_name, "grpclb") != 0) { + 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); + lb_policy_name_.get()); } - lb_policy_name = "grpclb"; + lb_policy_name_.reset(gpr_strdup("grpclb")); } } // Use pick_first if nothing was specified and we didn't select grpclb // above. - if (lb_policy_name == nullptr) lb_policy_name = "pick_first"; - lb_policy_name_.reset(gpr_strdup(lb_policy_name)); + if (lb_policy_name_ == nullptr) { + lb_policy_name_.reset(gpr_strdup("pick_first")); + } } void ProcessedResolverResult::ParseServiceConfig( @@ -175,15 +162,13 @@ void ProcessedResolverResult::ParseLbConfigFromServiceConfig( if (policy_content != nullptr) return; // Violate "oneof" type. policy_content = field; } - grpc_core::UniquePtr lb_policy_name = - ConvertCamelToSnake(policy_content->key); - if (!grpc_core::LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( - lb_policy_name.get())) { - continue; + // 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; } - lb_policy_name_ = std::move(lb_policy_name); - lb_policy_config_ = policy_content->child; - return; } } From 13a4977c23f2339f82093840533eec7047866fc0 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 6 Dec 2018 09:02:03 -0800 Subject: [PATCH 0451/2143] Treat StartCall like a reserved callback since it is required --- include/grpcpp/impl/codegen/client_callback.h | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index ede8ac54ca0..66cf9b7754c 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -270,6 +270,7 @@ class ClientCallbackReaderWriterImpl // 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) started_ = true; start_tag_.Set(call_.call(), @@ -320,6 +321,7 @@ class ClientCallbackReaderWriterImpl if (writes_done_ops_at_start_) { call_.PerformOps(&writes_done_ops_); } + MaybeFinish(); } void Read(Response* msg) override { @@ -412,8 +414,8 @@ class ClientCallbackReaderWriterImpl CallbackWithSuccessTag read_tag_; bool read_ops_at_start_{false}; - // Minimum of 2 outstanding callbacks to pre-register for start and finish - std::atomic_int callbacks_outstanding_{2}; + // Minimum of 3 callbacks to pre-register for StartCall, start, and finish + std::atomic_int callbacks_outstanding_{3}; bool started_{false}; }; @@ -466,6 +468,7 @@ 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(), @@ -497,6 +500,8 @@ 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 { @@ -540,8 +545,8 @@ class ClientCallbackReaderImpl CallbackWithSuccessTag read_tag_; bool read_ops_at_start_{false}; - // Minimum of 2 outstanding callbacks to pre-register for start and finish - std::atomic_int callbacks_outstanding_{2}; + // Minimum of 3 callbacks to pre-register for StartCall, start, and finish + std::atomic_int callbacks_outstanding_{3}; bool started_{false}; }; @@ -594,6 +599,7 @@ class ClientCallbackWriterImpl // 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) started_ = true; start_tag_.Set(call_.call(), @@ -633,6 +639,8 @@ class ClientCallbackWriterImpl if (writes_done_ops_at_start_) { call_.PerformOps(&writes_done_ops_); } + + MaybeFinish(); } void Write(const Request* msg, WriteOptions options) override { @@ -714,8 +722,8 @@ class ClientCallbackWriterImpl CallbackWithSuccessTag writes_done_tag_; bool writes_done_ops_at_start_{false}; - // Minimum of 2 outstanding callbacks to pre-register for start and finish - std::atomic_int callbacks_outstanding_{2}; + // Minimum of 3 callbacks to pre-register for StartCall, start, and finish + std::atomic_int callbacks_outstanding_{3}; bool started_{false}; }; From 22c74fcff56f7a89c0404c24ea0efe424559ebab Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 6 Dec 2018 09:07:47 -0800 Subject: [PATCH 0452/2143] Make TraceFlag trivially destructible --- src/core/lib/debug/trace.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h index 5ed52454bd7..4623494520e 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); - ~TraceFlag() {} + // This needs to be trivially destructible as it is used as global variable. + ~TraceFlag() = default; const char* name() const { return name_; } From 611bb6b4950a845874660a156480cbd472fff01c Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 6 Dec 2018 09:13:52 -0800 Subject: [PATCH 0453/2143] Test reactor reuse --- .../end2end/client_callback_end2end_test.cc | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 65434bac6b2..a999321992f 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -182,7 +182,7 @@ class ClientCallbackEnd2endTest } } - void SendGenericEchoAsBidi(int num_rpcs) { + void SendGenericEchoAsBidi(int num_rpcs, int reuses) { const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo"); grpc::string test_string(""); for (int i = 0; i < num_rpcs; i++) { @@ -191,14 +191,26 @@ class ClientCallbackEnd2endTest ByteBuffer> { public: Client(ClientCallbackEnd2endTest* test, const grpc::string& method_name, - const grpc::string& test_str) { - test->generic_stub_->experimental().PrepareBidiStreamingCall( - &cli_ctx_, method_name, this); - request_.set_message(test_str); - send_buf_ = SerializeToByteBuffer(&request_); - StartWrite(send_buf_.get()); - StartRead(&recv_buf_); - StartCall(); + const grpc::string& test_str, int reuses) + : reuses_remaining_(reuses) { + activate_ = [this, test, method_name, test_str] { + if (reuses_remaining_ > 0) { + cli_ctx_.reset(new ClientContext); + reuses_remaining_--; + test->generic_stub_->experimental().PrepareBidiStreamingCall( + cli_ctx_.get(), method_name, this); + request_.set_message(test_str); + send_buf_ = SerializeToByteBuffer(&request_); + StartWrite(send_buf_.get()); + StartRead(&recv_buf_); + StartCall(); + } else { + std::unique_lock l(mu_); + done_ = true; + cv_.notify_one(); + } + }; + activate_(); } void OnWriteDone(bool ok) override { StartWritesDone(); } void OnReadDone(bool ok) override { @@ -208,9 +220,7 @@ class ClientCallbackEnd2endTest }; void OnDone(const Status& s) override { EXPECT_TRUE(s.ok()); - std::unique_lock l(mu_); - done_ = true; - cv_.notify_one(); + activate_(); } void Await() { std::unique_lock l(mu_); @@ -222,11 +232,13 @@ class ClientCallbackEnd2endTest EchoRequest request_; std::unique_ptr send_buf_; ByteBuffer recv_buf_; - ClientContext cli_ctx_; + std::unique_ptr cli_ctx_; + int reuses_remaining_; + std::function activate_; std::mutex mu_; std::condition_variable cv_; bool done_ = false; - } rpc{this, kMethodName, test_string}; + } rpc{this, kMethodName, test_string, reuses}; rpc.Await(); } @@ -293,7 +305,12 @@ TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcs) { TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidi) { ResetStub(); - SendGenericEchoAsBidi(10); + SendGenericEchoAsBidi(10, 1); +} + +TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidiWithReactorReuse) { + ResetStub(); + SendGenericEchoAsBidi(10, 10); } #if GRPC_ALLOW_EXCEPTIONS From 5f806d77dc9ddf0b3bec066bf71ff6dc76a6e504 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 4 Dec 2018 09:01:35 -0800 Subject: [PATCH 0454/2143] Fix bug in subchannel backoff reset code. --- .../ext/filters/client_channel/subchannel.cc | 2 +- test/cpp/end2end/client_lb_end2end_test.cc | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 0817b1dd392..4d98b63b49a 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -887,12 +887,12 @@ static void on_subchannel_connected(void* arg, grpc_error* error) { void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel) { gpr_mu_lock(&subchannel->mu); + subchannel->backoff->Reset(); if (subchannel->have_alarm) { subchannel->deferred_reset_backoff = true; grpc_timer_cancel(&subchannel->alarm); } else { subchannel->backoff_begun = false; - subchannel->backoff->Reset(); maybe_start_connecting_locked(subchannel); } gpr_mu_unlock(&subchannel->mu); diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index b667460cf08..1a7b36cdc05 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -507,6 +507,46 @@ TEST_F(ClientLbEnd2endTest, PickFirstResetConnectionBackoff) { EXPECT_LT(waited_ms, kInitialBackOffMs); } +TEST_F(ClientLbEnd2endTest, + PickFirstResetConnectionBackoffNextAttemptStartsImmediately) { + ChannelArguments args; + constexpr int kInitialBackOffMs = 1000; + args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs); + const std::vector ports = {grpc_pick_unused_port_or_die()}; + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + SetNextResolution(ports); + // Wait for connect, which should fail ~immediately, because the server + // is not up. + gpr_log(GPR_INFO, "=== INITIAL CONNECTION ATTEMPT"); + EXPECT_FALSE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10))); + // Reset connection backoff. + gpr_log(GPR_INFO, "=== RESETTING BACKOFF"); + experimental::ChannelResetConnectionBackoff(channel.get()); + // Trigger a second connection attempt. This should also fail + // ~immediately, but the retry should be scheduled for + // kInitialBackOffMs instead of applying the multiplier. + gpr_log(GPR_INFO, "=== TRIGGERING SECOND CONNECTION ATTEMPT"); + EXPECT_FALSE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10))); + // Bring up a server on the chosen port. + gpr_log(GPR_INFO, "=== STARTING BACKEND"); + StartServers(1, ports); + // Wait for connect. Should happen within kInitialBackOffMs. + gpr_log(GPR_INFO, "=== TRIGGERING THIRD CONNECTION ATTEMPT"); + const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); + EXPECT_TRUE(channel->WaitForConnected( + grpc_timeout_milliseconds_to_deadline(kInitialBackOffMs))); + const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); + const grpc_millis waited_ms = gpr_time_to_millis(gpr_time_sub(t1, t0)); + gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited_ms); + // Give an extra 100ms for timing slack. + // (This is still far less than the 1.6x increase we would see if the + // backoff state was not reset properly.) + EXPECT_LT(waited_ms, kInitialBackOffMs + 100); +} + TEST_F(ClientLbEnd2endTest, PickFirstUpdates) { // Start servers and send one RPC per server. const int kNumServers = 3; From 0a3a99d84e2a12a68568ee45cf4496a2d9ef5bf7 Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Thu, 6 Dec 2018 09:33:53 -0800 Subject: [PATCH 0455/2143] Bump version to v1.17.1-pre1 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index eeb1a2fa620..fb87e824bec 100644 --- a/BUILD +++ b/BUILD @@ -68,7 +68,7 @@ g_stands_for = "gizmo" core_version = "7.0.0" -version = "1.17.0" +version = "1.17.1-pre1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 62e07f64e42..df1fd85e050 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: gizmo - version: 1.17.0 + version: 1.17.1-pre1 filegroups: - name: alts_proto headers: From a267d4a48c59142f66a67459e63369be5a827886 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 6 Dec 2018 09:37:58 -0800 Subject: [PATCH 0456/2143] Add a static_assert --- src/core/lib/debug/trace.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/lib/debug/trace.cc b/src/core/lib/debug/trace.cc index 01c1e867d9d..cafdb15c699 100644 --- a/src/core/lib/debug/trace.cc +++ b/src/core/lib/debug/trace.cc @@ -21,6 +21,7 @@ #include "src/core/lib/debug/trace.h" #include +#include #include #include @@ -79,6 +80,8 @@ void TraceFlagList::LogAllTracers() { // Flags register themselves on the list during construction TraceFlag::TraceFlag(bool default_enabled, const char* name) : name_(name) { + static_assert(std::is_trivially_destructible::value, + "TraceFlag needs to be trivially destructible."); set_enabled(default_enabled); TraceFlagList::Add(this); } From 9eaebf116d0651b314e186c454b26565347e5ede Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Thu, 6 Dec 2018 09:38:39 -0800 Subject: [PATCH 0457/2143] 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 | 4 ++-- 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 | 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_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/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, 36 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 58525d6c6f1..8c199696a9b 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.17.0") +set(PACKAGE_VERSION "1.17.1-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 02273df21d1..18f49301d76 100644 --- a/Makefile +++ b/Makefile @@ -438,8 +438,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.17.0 -CSHARP_VERSION = 1.17.0 +CPP_VERSION = 1.17.1-pre1 +CSHARP_VERSION = 1.17.1-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 73c87942430..ba26e3979d6 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.17.0' - version = '0.0.6' + # version = '1.17.1-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.17.0' + grpc_version = '1.17.1-pre1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index ff4d79426fe..4b499208f5c 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.17.0' + version = '1.17.1-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 d7050906e43..5d5bd6c47f5 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.17.0' + version = '1.17.1-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 955f3682f67..9c453f0b192 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.17.0' + version = '1.17.1-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 fb46ab46704..83c7fceef1a 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.17.0' + version = '1.17.1-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 bd2fffcc555..3e3d0c354c3 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.17.0 - 1.17.0 + 1.17.1RC1 + 1.17.1RC1 - stable - stable + beta + beta Apache 2.0 diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 0a3fd804fe5..af717f9934f 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.17.0"; } +grpc::string Version() { return "1.17.1-pre1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 4741e08cf53..1935ab77e4f 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.17.0 + 1.17.1-pre1 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index aa881867ec5..1209c509d03 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.17.0.0"; + public const string CurrentAssemblyFileVersion = "1.17.1.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.17.0"; + public const string CurrentVersion = "1.17.1-pre1"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 1b860c95380..996700b3e1e 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.17.0 +set VERSION=1.17.1-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 b9f9cf4dbb8..2fec12ddf89 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.17.0 +set VERSION=1.17.1-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 c72751d1c6f..65524edad29 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.17.0' + v = '1.17.1-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 fa5b04612ce..02d2c58a7d0 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.17.0" +#define GRPC_OBJC_VERSION_STRING @"1.17.1-pre1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 1cfbf6f705d..8c3e0da603f 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.17.0" +#define GRPC_OBJC_VERSION_STRING @"1.17.1-pre1" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index d54db91b5fb..be72fc059e9 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.17.0", + "version": "1.17.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 e529c749dbd..9e79442157f 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.17.0" +#define PHP_GRPC_VERSION "1.17.1RC1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 0677d1b9cf5..63e56efa6b1 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.17.0""" +__version__ = """1.17.1rc1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 8cbd5b24f25..03f7db3b2fe 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.17.0' +VERSION = '1.17.1rc1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 222d77aab18..c0817d51dce 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.17.0' +VERSION = '1.17.1rc1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index daa8a84edb3..445513c6045 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.17.0' +VERSION = '1.17.1rc1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index af9ab31aa13..0c89e08dfbf 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.17.0' +VERSION = '1.17.1rc1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 887f8c105bc..5b861bc0c83 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.17.0' +VERSION = '1.17.1rc1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 6b09d61c0b4..3af5e94a7d0 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.17.0' + VERSION = '1.17.1.pre1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 9ae2162335d..e27237158e0 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.17.0' + VERSION = '1.17.1.pre1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 4070200384b..628315ad26e 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.17.0' +VERSION = '1.17.1rc1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 88bfada6917..c32e6b34519 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.17.0 +PROJECT_NUMBER = 1.17.1-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 31f90cf1b66..d62f540ce84 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.17.0 +PROJECT_NUMBER = 1.17.1-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 6638279564f64e14e033865fc2191c60679b389d Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Thu, 6 Dec 2018 10:01:48 -0800 Subject: [PATCH 0458/2143] revision 1 --- .../google_default_credentials.cc | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) 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 7474380c051..cf6eb83758c 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 @@ -49,11 +49,16 @@ /* -- Default credentials. -- */ -static int g_metadata_server_detection_done = 0; +/* A sticky bit that will be set only if the result of metadata server detection + * is positive. We do not set the bit if the result is negative. Because it + * means the detection is done via network test that is unreliable and the + * unreliable result should not be referred by successive calls. */ static int g_metadata_server_available = 0; static int g_is_on_gce = 0; static gpr_mu g_state_mu; -static gpr_mu* g_polling_mu; +/* Protect a metadata_server_detector instance that can be modified by more than + * one gRPC threads */ +.static gpr_mu* g_polling_mu; static gpr_once g_once = GPR_ONCE_INIT; static grpc_core::internal::grpc_gce_tenancy_checker g_gce_tenancy_checker = grpc_alts_is_running_on_gcp; @@ -65,7 +70,7 @@ typedef struct { int is_done; int success; grpc_http_response response; -} compute_engine_detector; +} metadata_server_detector; static void google_default_credentials_destruct( grpc_channel_credentials* creds) { @@ -93,7 +98,7 @@ static grpc_security_status google_default_create_security_connector( grpc_security_status status = GRPC_SECURITY_ERROR; /* Return failure if ALTS is selected but not running on GCE. */ if (use_alts && !g_is_on_gce) { - goto end; + gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE.") goto end; } status = use_alts ? c->alts_creds->vtable->create_security_connector( c->alts_creds, call_creds, target, args, sc, new_args) @@ -122,8 +127,8 @@ static grpc_channel_credentials_vtable google_default_credentials_vtable = { static void on_metadata_server_detection_http_response(void* user_data, grpc_error* error) { - compute_engine_detector* detector = - static_cast(user_data); + metadata_server_detector* detector = + static_cast(user_data); if (error == GRPC_ERROR_NONE && detector->response.status == 200 && detector->response.hdr_count > 0) { /* Internet providers can return a generic response to all requests, so @@ -152,7 +157,7 @@ static void destroy_pollset(void* p, grpc_error* e) { } static int is_metadata_server_reachable() { - compute_engine_detector detector; + metadata_server_detector detector; grpc_httpcli_request request; grpc_httpcli_context context; grpc_closure destroy_closure; @@ -297,19 +302,15 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) { gpr_mu_lock(&g_state_mu); /* Try a platform-provided hint for GCE. */ - if (!g_metadata_server_detection_done) { + if (!g_metadata_server_available) { g_is_on_gce = g_gce_tenancy_checker(); - g_metadata_server_detection_done = g_is_on_gce; g_metadata_server_available = g_is_on_gce; } /* TODO: Add a platform-provided hint for GAE. */ /* Do a network test for metadata server. */ - if (!g_metadata_server_detection_done) { - bool detected = is_metadata_server_reachable(); - /* Do not cache detecion result if netowrk test returns false. */ - g_metadata_server_detection_done = detected; - g_metadata_server_available = detected; + if (!g_metadata_server_available) { + g_metadata_server_available = is_metadata_server_reachable(); } gpr_mu_unlock(&g_state_mu); @@ -361,7 +362,7 @@ void grpc_flush_cached_google_default_credentials(void) { grpc_core::ExecCtx exec_ctx; gpr_once_init(&g_once, init_default_credentials); gpr_mu_lock(&g_state_mu); - g_metadata_server_detection_done = 0; + g_metadata_server_available = 0; gpr_mu_unlock(&g_state_mu); } From c449da58339d4618ca1af447607033fab81de101 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Thu, 6 Dec 2018 10:09:54 -0800 Subject: [PATCH 0459/2143] fix a compilation error --- .../credentials/google_default/google_default_credentials.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 cf6eb83758c..0674540d01c 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 @@ -58,7 +58,7 @@ static int g_is_on_gce = 0; static gpr_mu g_state_mu; /* Protect a metadata_server_detector instance that can be modified by more than * one gRPC threads */ -.static gpr_mu* g_polling_mu; +static gpr_mu* g_polling_mu; static gpr_once g_once = GPR_ONCE_INIT; static grpc_core::internal::grpc_gce_tenancy_checker g_gce_tenancy_checker = grpc_alts_is_running_on_gcp; @@ -98,7 +98,8 @@ static grpc_security_status google_default_create_security_connector( grpc_security_status status = GRPC_SECURITY_ERROR; /* Return failure if ALTS is selected but not running on GCE. */ if (use_alts && !g_is_on_gce) { - gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE.") goto end; + gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE."); + goto end; } status = use_alts ? c->alts_creds->vtable->create_security_connector( c->alts_creds, call_creds, target, args, sc, new_args) From bb5741f9c006957e72e6a91e3389c0c3bc34d6b8 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 6 Dec 2018 10:18:44 -0800 Subject: [PATCH 0460/2143] Change pick_first to immediately select the first subchannel in READY state. --- .../lb_policy/pick_first/pick_first.cc | 74 +++++++++---------- test/cpp/end2end/client_lb_end2end_test.cc | 48 +++++++++--- 2 files changed, 74 insertions(+), 48 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 d454401a669..d1a05f12554 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 @@ -380,6 +380,31 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, selected_ = nullptr; return; } + // If one of the subchannels in the new list is already in state + // 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. + for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { + PickFirstSubchannelData* sd = subchannel_list->subchannel(i); + grpc_error* error = GRPC_ERROR_NONE; + grpc_connectivity_state state = sd->CheckConnectivityStateLocked(&error); + GRPC_ERROR_UNREF(error); + if (state == GRPC_CHANNEL_READY) { + subchannel_list_ = std::move(subchannel_list); + sd->ProcessUnselectedReadyLocked(); + sd->StartConnectivityWatchLocked(); + // 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. + latest_pending_subchannel_list_.reset(); + // 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; + return; + } + } if (selected_ == nullptr) { // We don't yet have a selected subchannel, so replace the current // subchannel list immediately. @@ -387,46 +412,14 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, // If we've started picking, start trying to connect to the first // subchannel in the new list. if (started_picking_) { - subchannel_list_->subchannel(0) - ->CheckConnectivityStateAndStartWatchingLocked(); + // 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. - // Check if it's present in the new list. If so, we're done. - for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { - PickFirstSubchannelData* sd = subchannel_list->subchannel(i); - if (sd->subchannel() == selected_->subchannel()) { - // The currently selected subchannel is in the update: we are done. - if (grpc_lb_pick_first_trace.enabled()) { - gpr_log(GPR_INFO, - "Pick First %p found already selected subchannel %p " - "at update index %" PRIuPTR " of %" PRIuPTR "; update done", - this, selected_->subchannel(), i, - subchannel_list->num_subchannels()); - } - // Make sure it's in state READY. It might not be if we grabbed - // the combiner while a connectivity state notification - // informing us otherwise is pending. - // Note that CheckConnectivityStateLocked() also takes a ref to - // the connected subchannel. - grpc_error* error = GRPC_ERROR_NONE; - if (sd->CheckConnectivityStateLocked(&error) == GRPC_CHANNEL_READY) { - selected_ = sd; - subchannel_list_ = std::move(subchannel_list); - sd->StartConnectivityWatchLocked(); - // 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. - latest_pending_subchannel_list_.reset(); - return; - } - GRPC_ERROR_UNREF(error); - } - } - // Not keeping the previous selected subchannel, so set the latest - // pending subchannel list to the new subchannel list. We will wait - // for it to report READY before swapping it into the current - // subchannel list. + // We do have a selected subchannel, 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, @@ -440,8 +433,11 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, // If we've started picking, start trying to connect to the first // subchannel in the new list. if (started_picking_) { + // Note: No need to use CheckConnectivityStateAndStartWatchingLocked() + // here, since we've already checked the initial connectivity + // state of all subchannels above. latest_pending_subchannel_list_->subchannel(0) - ->CheckConnectivityStateAndStartWatchingLocked(); + ->StartConnectivityWatchLocked(); } } } diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index b667460cf08..759847be3e9 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -116,7 +116,10 @@ class MyTestServiceImpl : public TestServiceImpl { class ClientLbEnd2endTest : public ::testing::Test { protected: ClientLbEnd2endTest() - : server_host_("localhost"), kRequestMessage_("Live long and prosper.") { + : server_host_("localhost"), + kRequestMessage_("Live long and prosper."), + creds_(new SecureChannelCredentials( + grpc_fake_transport_security_credentials_create())) { // 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"); @@ -215,9 +218,7 @@ class ClientLbEnd2endTest : public ::testing::Test { } // else, default to pick first args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, response_generator_.get()); - std::shared_ptr creds(new SecureChannelCredentials( - grpc_fake_transport_security_credentials_create())); - return CreateCustomChannel("fake:///", std::move(creds), args); + return CreateCustomChannel("fake:///", creds_, args); } bool SendRpc( @@ -265,6 +266,7 @@ class ClientLbEnd2endTest : public ::testing::Test { MyTestServiceImpl service_; std::unique_ptr thread_; bool server_ready_ = false; + bool started_ = false; explicit ServerData(int port = 0) { port_ = port > 0 ? port : grpc_pick_unused_port_or_die(); @@ -272,6 +274,7 @@ class ClientLbEnd2endTest : public ::testing::Test { void Start(const grpc::string& server_host) { gpr_log(GPR_INFO, "starting server on port %d", port_); + started_ = true; std::mutex mu; std::unique_lock lock(mu); std::condition_variable cond; @@ -297,9 +300,11 @@ class ClientLbEnd2endTest : public ::testing::Test { cond->notify_one(); } - void Shutdown(bool join = true) { + void Shutdown() { + if (!started_) return; server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - if (join) thread_->join(); + thread_->join(); + started_ = false; } void SetServingStatus(const grpc::string& service, bool serving) { @@ -378,6 +383,7 @@ class ClientLbEnd2endTest : public ::testing::Test { grpc_core::RefCountedPtr response_generator_; const grpc::string kRequestMessage_; + std::shared_ptr creds_; }; TEST_F(ClientLbEnd2endTest, PickFirst) { @@ -422,6 +428,30 @@ TEST_F(ClientLbEnd2endTest, PickFirstProcessPending) { CheckRpcSendOk(second_stub, DEBUG_LOCATION); } +TEST_F(ClientLbEnd2endTest, PickFirstSelectsReadyAtStartup) { + ChannelArguments args; + constexpr int kInitialBackOffMs = 5000; + args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs); + // Create 2 servers, but start only the second one. + std::vector ports = {grpc_pick_unused_port_or_die(), + grpc_pick_unused_port_or_die()}; + CreateServers(2, ports); + StartServer(1); + auto channel1 = BuildChannel("pick_first", args); + auto stub1 = BuildStub(channel1); + SetNextResolution(ports); + // Wait for second server to be ready. + WaitForServer(stub1, 1, DEBUG_LOCATION); + // Create a second channel with the same addresses. Its PF instance + // should immediately pick the second subchannel, since it's already + // in READY state. + auto channel2 = BuildChannel("pick_first", args); + SetNextResolution(ports); + // Check that the channel reports READY without waiting for the + // initial backoff. + EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1 /* timeout_seconds */)); +} + TEST_F(ClientLbEnd2endTest, PickFirstBackOffInitialReconnect) { ChannelArguments args; constexpr int kInitialBackOffMs = 100; @@ -899,7 +929,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdateInError) { servers_[0]->service_.ResetCounters(); // Shutdown one of the servers to be sent in the update. - servers_[1]->Shutdown(false); + servers_[1]->Shutdown(); ports.emplace_back(servers_[1]->port_); ports.emplace_back(servers_[2]->port_); SetNextResolution(ports); @@ -958,7 +988,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinReresolve) { // Kill all servers gpr_log(GPR_INFO, "****** ABOUT TO KILL SERVERS *******"); for (size_t i = 0; i < servers_.size(); ++i) { - servers_[i]->Shutdown(true); + servers_[i]->Shutdown(); } gpr_log(GPR_INFO, "****** SERVERS KILLED *******"); gpr_log(GPR_INFO, "****** SENDING DOOMED REQUESTS *******"); @@ -1006,7 +1036,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { } const auto pre_death = servers_[0]->service_.request_count(); // Kill the first server. - servers_[0]->Shutdown(true); + servers_[0]->Shutdown(); // Client request still succeed. May need retrying if RR had returned a pick // before noticing the change in the server's connectivity. while (!SendRpc(stub)) { From bc447b5f232198bc840fd1449acc076389f6b2ee Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Thu, 6 Dec 2018 11:16:15 -0800 Subject: [PATCH 0461/2143] Revert "Revert "Add Testonly to Targets"" --- test/cpp/microbenchmarks/BUILD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 5ae9a9a7910..097e92f5836 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -29,6 +29,7 @@ grpc_cc_test( grpc_cc_library( name = "helpers", + testonly = 1, srcs = ["helpers.cc"], hdrs = [ "fullstack_context_mutators.h", @@ -55,6 +56,7 @@ grpc_cc_binary( grpc_cc_binary( name = "bm_arena", + testonly = 1, srcs = ["bm_arena.cc"], deps = [":helpers"], ) @@ -68,6 +70,7 @@ grpc_cc_binary( grpc_cc_binary( name = "bm_call_create", + testonly = 1, srcs = ["bm_call_create.cc"], deps = [":helpers"], ) @@ -95,6 +98,7 @@ grpc_cc_binary( grpc_cc_library( name = "fullstack_streaming_ping_pong_h", + testonly = 1, hdrs = [ "fullstack_streaming_ping_pong.h", ], @@ -112,6 +116,7 @@ grpc_cc_binary( grpc_cc_library( name = "fullstack_streaming_pump_h", + testonly = 1, hdrs = [ "fullstack_streaming_pump.h", ], @@ -129,12 +134,14 @@ grpc_cc_binary( grpc_cc_binary( name = "bm_fullstack_trickle", + testonly = 1, srcs = ["bm_fullstack_trickle.cc"], deps = [":helpers"], ) grpc_cc_library( name = "fullstack_unary_ping_pong_h", + testonly = 1, hdrs = [ "fullstack_unary_ping_pong.h", ], From 70f34521deaeaf0d783f30d121fd26787135ac04 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 12:08:43 -0800 Subject: [PATCH 0462/2143] isolate start: function from proto calls --- src/objective-c/ProtoRPC/ProtoRPC.h | 10 ++++++ src/objective-c/ProtoRPC/ProtoRPC.m | 19 ++++++---- src/objective-c/tests/InteropTests.m | 53 ++++++++++++++++++++++++---- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 2623aecb82f..949f52d1b53 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -76,6 +76,11 @@ NS_ASSUME_NONNULL_BEGIN callOptions:(nullable GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; +/** + * Start the call. This function must only be called once for each instance. + */ +- (void)start; + /** * Cancel the request of this call at best effort. It attempts to notify the server that the RPC * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code @@ -101,6 +106,11 @@ NS_ASSUME_NONNULL_BEGIN callOptions:(nullable GRPCCallOptions *)callOptions responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; +/** + * Start the call. This function must only be called once for each instance. + */ +- (void)start; + /** * Cancel the request of this call at best effort. It attempts to notify the server that the RPC * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 1db04894d5e..09f8d03af6f 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -47,6 +47,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @implementation GRPCUnaryProtoCall { GRPCStreamingProtoCall *_call; + GPBMessage *_message; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -54,17 +55,24 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { + NSAssert(message != nil, @"message cannot be empty."); + NSAssert(responseClass != nil, @"responseClass cannot be empty."); if ((self = [super init])) { _call = [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions responseHandler:handler callOptions:callOptions responseClass:responseClass]; - [_call writeMessage:message]; - [_call finish]; + _message = [message copy]; } return self; } +- (void)start { + [_call start]; + [_call writeMessage:_message]; + [_call finish]; +} + - (void)cancel { [_call cancel]; _call = nil; @@ -120,15 +128,14 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } dispatch_set_target_queue(_dispatchQueue, handler.dispatchQueue); - [self start]; + _call = [[GRPCCall2 alloc] initWithRequestOptions:_requestOptions + responseHandler:self + callOptions:_callOptions]; } return self; } - (void)start { - _call = [[GRPCCall2 alloc] initWithRequestOptions:_requestOptions - responseHandler:self - callOptions:_callOptions]; [_call start]; } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 2492718046f..e94fd1493a0 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -197,7 +197,7 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testEmptyUnaryRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnary"]; + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnaryWithV2API"]; GPBEmpty *request = [GPBEmpty message]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; @@ -205,7 +205,7 @@ BOOL isRemoteInteropTest(NSString *host) { options.PEMRootCertificates = [[self class] PEMRootCertificates]; options.hostNameOverride = [[self class] hostNameOverride]; - [_service + GRPCUnaryProtoCall *call = [_service emptyCallWithMessage:request responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(id message) { @@ -219,6 +219,7 @@ BOOL isRemoteInteropTest(NSString *host) { XCTAssertNil(error, @"Unexpected error: %@", error); }] callOptions:options]; + [call start]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } @@ -246,6 +247,44 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testLargeUnaryRPCWithV2API { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectRecvMessage = [self expectationWithDescription:@"LargeUnaryWithV2API received message"]; + __weak XCTestExpectation *expectRecvComplete = [self expectationWithDescription:@"LargeUnaryWithV2API received complete"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = 314159; + request.payload.body = [NSMutableData dataWithLength:271828]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + + GRPCUnaryProtoCall *call = [_service + unaryCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertNotNil(message); + if (message) { + RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message]; + expectedResponse.payload.type = RMTPayloadType_Compressable; + expectedResponse.payload.body = [NSMutableData dataWithLength:314159]; + XCTAssertEqualObjects(message, expectedResponse); + + [expectRecvMessage fulfill]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + [expectRecvComplete fulfill]; + }] + callOptions:options]; + [call start]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testPacketCoalescing { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; @@ -473,7 +512,7 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testPingPongRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"]; + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPongWithV2API"]; NSArray *requests = @[ @27182, @8, @1828, @45904 ]; NSArray *responses = @[ @31415, @9, @2653, @58979 ]; @@ -517,6 +556,7 @@ BOOL isRemoteInteropTest(NSString *host) { [expectation fulfill]; }] callOptions:options]; + [call start]; [call writeMessage:request]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; @@ -562,7 +602,7 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testCancelAfterBeginRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBegin"]; + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBeginWithV2API"]; // A buffered pipe to which we never write any value acts as a writer that just hangs. __block GRPCStreamingProtoCall *call = [_service @@ -577,6 +617,7 @@ BOOL isRemoteInteropTest(NSString *host) { [expectation fulfill]; }] callOptions:nil]; + [call start]; [call cancel]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; @@ -650,7 +691,7 @@ BOOL isRemoteInteropTest(NSString *host) { [completionExpectation fulfill]; }] callOptions:options]; - + [call start]; [call writeMessage:request]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } @@ -680,7 +721,7 @@ BOOL isRemoteInteropTest(NSString *host) { [completionExpectation fulfill]; }] callOptions:options]; - + [call start]; [call writeMessage:request]; [call cancel]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; From 3dd24ea9789fcc455842b9582102f8c261e0bb1c Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 6 Dec 2018 12:27:41 -0800 Subject: [PATCH 0463/2143] code review changes --- .../ext/filters/client_channel/subchannel.cc | 8 ++++---- test/cpp/end2end/client_lb_end2end_test.cc | 19 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 4d98b63b49a..af55f7710e2 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -153,7 +153,7 @@ struct grpc_subchannel { /** have we started the backoff loop */ bool backoff_begun; // reset_backoff() was called while alarm was pending - bool deferred_reset_backoff; + bool retry_immediately; /** our alarm */ grpc_timer alarm; @@ -709,8 +709,8 @@ static void on_alarm(void* arg, grpc_error* error) { if (c->disconnected) { error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected", &error, 1); - } else if (c->deferred_reset_backoff) { - c->deferred_reset_backoff = false; + } else if (c->retry_immediately) { + c->retry_immediately = false; error = GRPC_ERROR_NONE; } else { GRPC_ERROR_REF(error); @@ -889,7 +889,7 @@ void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel) { gpr_mu_lock(&subchannel->mu); subchannel->backoff->Reset(); if (subchannel->have_alarm) { - subchannel->deferred_reset_backoff = true; + subchannel->retry_immediately = true; grpc_timer_cancel(&subchannel->alarm); } else { subchannel->backoff_begun = false; diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 1a7b36cdc05..f60f110c5ff 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -527,24 +527,27 @@ TEST_F(ClientLbEnd2endTest, // Trigger a second connection attempt. This should also fail // ~immediately, but the retry should be scheduled for // kInitialBackOffMs instead of applying the multiplier. - gpr_log(GPR_INFO, "=== TRIGGERING SECOND CONNECTION ATTEMPT"); + gpr_log(GPR_INFO, "=== POLLING FOR SECOND CONNECTION ATTEMPT"); + const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); EXPECT_FALSE( channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10))); // Bring up a server on the chosen port. gpr_log(GPR_INFO, "=== STARTING BACKEND"); StartServers(1, ports); // Wait for connect. Should happen within kInitialBackOffMs. - gpr_log(GPR_INFO, "=== TRIGGERING THIRD CONNECTION ATTEMPT"); - const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); + // Give an extra 100ms to account for the time spent in the second and + // third connection attempts themselves (since what we really want to + // measure is the time between the two). As long as this is less than + // the 1.6x increase we would see if the backoff state was not reset + // properly, the test is still proving that the backoff was reset. + constexpr int kWaitMs = kInitialBackOffMs + 100; + gpr_log(GPR_INFO, "=== POLLING FOR THIRD CONNECTION ATTEMPT"); EXPECT_TRUE(channel->WaitForConnected( - grpc_timeout_milliseconds_to_deadline(kInitialBackOffMs))); + grpc_timeout_milliseconds_to_deadline(kWaitMs))); const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); const grpc_millis waited_ms = gpr_time_to_millis(gpr_time_sub(t1, t0)); gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited_ms); - // Give an extra 100ms for timing slack. - // (This is still far less than the 1.6x increase we would see if the - // backoff state was not reset properly.) - EXPECT_LT(waited_ms, kInitialBackOffMs + 100); + EXPECT_LT(waited_ms, kWaitMs); } TEST_F(ClientLbEnd2endTest, PickFirstUpdates) { From 76f1ec16e1880605215beb60a204b0cab7c36b2d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 12:42:27 -0800 Subject: [PATCH 0464/2143] sensible nullability annotation for old API --- src/objective-c/GRPCClient/GRPCCall.h | 22 ++++++++++--------- src/objective-c/GRPCClient/GRPCCall.m | 7 +++--- src/objective-c/ProtoRPC/ProtoRPC.h | 10 ++++----- .../examples/SwiftSample/ViewController.swift | 10 ++++----- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 214969af230..51a82263bff 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -282,6 +282,8 @@ NS_ASSUME_NONNULL_END */ @interface GRPCCall : GRXWriter +- (instancetype)init NS_UNAVAILABLE; + /** * The container of the request headers of an RPC conforms to this protocol, which is a subset of * NSMutableDictionary's interface. It will become a NSMutableDictionary later on. @@ -306,7 +308,7 @@ NS_ASSUME_NONNULL_END * * The property is initialized to an empty NSMutableDictionary. */ -@property(nullable, atomic, readonly) NSMutableDictionary *requestHeaders; +@property(nonnull, atomic, readonly) NSMutableDictionary *requestHeaders; /** * This dictionary is populated with the HTTP headers received from the server. This happens before @@ -339,9 +341,9 @@ NS_ASSUME_NONNULL_END * host parameter should not contain the scheme (http:// or https://), only the name or IP addr * and the port number, for example @"localhost:5050". */ -- (nullable instancetype)initWithHost:(nullable NSString *)host - path:(nullable NSString *)path - requestsWriter:(nullable GRXWriter *)requestWriter; +- (nullable instancetype)initWithHost:(nonnull NSString *)host + path:(nonnull NSString *)path + requestsWriter:(nonnull GRXWriter *)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -353,11 +355,11 @@ NS_ASSUME_NONNULL_END * The following methods are deprecated. */ + (void)setCallSafety:(GRPCCallSafety)callSafety - host:(nullable NSString *)host - path:(nullable NSString *)path; + host:(nonnull NSString *)host + path:(nonnull NSString *)path; @property(nullable, atomic, copy, readwrite) NSString *serverName; @property NSTimeInterval timeout; -- (void)setResponseDispatchQueue:(nullable dispatch_queue_t)queue; +- (void)setResponseDispatchQueue:(nonnull dispatch_queue_t)queue; @end @@ -368,11 +370,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (nullable id)objectForKeyedSubscript:(nullable id)key; -- (void)setObject:(nullable id)obj forKeyedSubscript:(nullable id)key; +- (nullable id)objectForKeyedSubscript:(nonnull id)key; +- (void)setObject:(nullable id)obj forKeyedSubscript:(nonnull id)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(nullable id)key; +- (void)removeObjectForKey:(nonnull id)key; @end #pragma clang diagnostic push diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index dad8594a264..9b3bcd385e7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -445,6 +445,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; } + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path { + if (host.length == 0 || path.length == 0) { + return; + } NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; switch (callSafety) { case GRPCCallSafetyDefault: @@ -466,10 +469,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; return [callFlags[hostAndPath] intValue]; } -- (instancetype)init { - return [self initWithHost:nil path:nil requestsWriter:nil]; -} - // Designated initializer - (instancetype)initWithHost:(NSString *)host path:(NSString *)path diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 949f52d1b53..1819fa93796 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -142,11 +142,11 @@ __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC * addr and the port number, for example @"localhost:5050". */ - - (nullable instancetype)initWithHost : (nullable NSString *)host method - : (nullable GRPCProtoMethod *)method requestsWriter - : (nullable GRXWriter *)requestsWriter responseClass - : (nullable Class)responseClass responsesWriteable - : (nullable id)responsesWriteable NS_DESIGNATED_INITIALIZER; + (nullable instancetype)initWithHost : (nonnull NSString *)host method + : (nonnull GRPCProtoMethod *)method requestsWriter + : (nonnull GRXWriter *)requestsWriter responseClass + : (nonnull Class)responseClass responsesWriteable + : (nonnull id)responsesWriteable NS_DESIGNATED_INITIALIZER; - (void)start; @end diff --git a/src/objective-c/examples/SwiftSample/ViewController.swift b/src/objective-c/examples/SwiftSample/ViewController.swift index 0ba6e21f02a..4ed10266a4d 100644 --- a/src/objective-c/examples/SwiftSample/ViewController.swift +++ b/src/objective-c/examples/SwiftSample/ViewController.swift @@ -54,8 +54,8 @@ class ViewController: UIViewController { } else { NSLog("2. Finished with error: \(error!)") } - NSLog("2. Response headers: \(RPC.responseHeaders)") - NSLog("2. Response trailers: \(RPC.responseTrailers)") + NSLog("2. Response headers: \(String(describing: RPC.responseHeaders))") + NSLog("2. Response trailers: \(String(describing: RPC.responseTrailers))") } // TODO(jcanizales): Revert to using subscript syntax once XCode 8 is released. @@ -68,7 +68,7 @@ class ViewController: UIViewController { let method = GRPCProtoMethod(package: "grpc.testing", service: "TestService", method: "UnaryCall")! - let requestsWriter = GRXWriter(value: request.data()) + let requestsWriter = GRXWriter(value: request.data())! let call = GRPCCall(host: RemoteHost, path: method.httpPath, requestsWriter: requestsWriter)! @@ -80,8 +80,8 @@ class ViewController: UIViewController { } else { NSLog("3. Finished with error: \(error!)") } - NSLog("3. Response headers: \(call.responseHeaders)") - NSLog("3. Response trailers: \(call.responseTrailers)") + NSLog("3. Response headers: \(String(describing: call.responseHeaders))") + NSLog("3. Response trailers: \(String(describing: call.responseTrailers))") }) } } From eeced98fc556c6a5bc3a5dedc171c98747217078 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 13:08:34 -0800 Subject: [PATCH 0465/2143] Rename handlers to didXxx --- src/objective-c/GRPCClient/GRPCCall.h | 8 +++---- src/objective-c/GRPCClient/GRPCCall.m | 16 ++++++------- src/objective-c/ProtoRPC/ProtoRPC.h | 12 +++++----- src/objective-c/ProtoRPC/ProtoRPC.m | 24 +++++++++---------- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 6 ++--- src/objective-c/tests/InteropTests.m | 6 ++--- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 51a82263bff..985743433cf 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -158,13 +158,13 @@ extern NSString *const kGRPCTrailersKey; /** * Issued when initial metadata is received from the server. */ -- (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; +- (void)didReceiveInitialMetadata:(nullable NSDictionary *)initialMetadata; /** * Issued when a message is received from the server. The message is the raw data received from the * server, with decompression and without proto deserialization. */ -- (void)receivedRawMessage:(nullable NSData *)message; +- (void)didReceiveRawMessage:(nullable NSData *)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -172,7 +172,7 @@ extern NSString *const kGRPCTrailersKey; * is non-nil and contains the corresponding error information, including gRPC error codes and * error descriptions. */ -- (void)closedWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata +- (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; @required @@ -247,7 +247,7 @@ extern NSString *const kGRPCTrailersKey; /** * Cancel the request of this call at best effort. It attempts to notify the server that the RPC - * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code + * should be cancelled, and issue didCloseWithTrailingMetadata:error: callback with error code * CANCELED if no other error code has already been issued. */ - (void)cancel; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9b3bcd385e7..48253677bd3 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -250,7 +250,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _call = nil; _pipe = nil; - if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ // Copy to local so that block is freed after cancellation completes. id copiedHandler = nil; @@ -259,7 +259,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; self->_handler = nil; } - [copiedHandler closedWithTrailingMetadata:nil + [copiedHandler didCloseWithTrailingMetadata:nil error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled userInfo:@{ @@ -321,13 +321,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)issueInitialMetadata:(NSDictionary *)initialMetadata { @synchronized(self) { if (initialMetadata != nil && - [_handler respondsToSelector:@selector(receivedInitialMetadata:)]) { + [_handler respondsToSelector:@selector(didReceiveInitialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; } - [copiedHandler receivedInitialMetadata:initialMetadata]; + [copiedHandler didReceiveInitialMetadata:initialMetadata]; }); } } @@ -335,13 +335,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)issueMessage:(id)message { @synchronized(self) { - if (message != nil && [_handler respondsToSelector:@selector(receivedRawMessage:)]) { + if (message != nil && [_handler respondsToSelector:@selector(didReceiveRawMessage:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; } - [copiedHandler receivedRawMessage:message]; + [copiedHandler didReceiveRawMessage:message]; }); } } @@ -349,7 +349,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { @synchronized(self) { - if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { @@ -357,7 +357,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Clean up _handler so that no more responses are reported to the handler. self->_handler = nil; } - [copiedHandler closedWithTrailingMetadata:trailingMetadata error:error]; + [copiedHandler didCloseWithTrailingMetadata:trailingMetadata error:error]; }); } else { _handler = nil; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 1819fa93796..287aa0369b1 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -33,12 +33,12 @@ NS_ASSUME_NONNULL_BEGIN /** * Issued when initial metadata is received from the server. */ -- (void)receivedInitialMetadata:(nullable NSDictionary *)initialMetadata; +- (void)didReceiveInitialMetadata:(nullable NSDictionary *)initialMetadata; /** * Issued when a message is received from the server. The message is the deserialized proto object. */ -- (void)receivedProtoMessage:(nullable GPBMessage *)message; +- (void)didReceiveProtoMessage:(nullable GPBMessage *)message; /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a @@ -46,8 +46,8 @@ NS_ASSUME_NONNULL_BEGIN * is non-nil and contains the corresponding error information, including gRPC error codes and * error descriptions. */ -- (void)closedWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata - error:(nullable NSError *)error; +- (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata + error:(nullable NSError *)error; @required @@ -83,7 +83,7 @@ NS_ASSUME_NONNULL_BEGIN /** * Cancel the request of this call at best effort. It attempts to notify the server that the RPC - * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code + * should be cancelled, and issue didCloseWithTrailingMetadata:error: callback with error code * CANCELED if no other error code has already been issued. */ - (void)cancel; @@ -113,7 +113,7 @@ NS_ASSUME_NONNULL_BEGIN /** * Cancel the request of this call at best effort. It attempts to notify the server that the RPC - * should be cancelled, and issue closedWithTrailingMetadata:error: callback with error code + * should be cancelled, and issue didCloseWithTrailingMetadata:error: callback with error code * CANCELED if no other error code has already been issued. */ - (void)cancel; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 09f8d03af6f..886e31ce58a 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -144,14 +144,14 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @synchronized(self) { copiedCall = _call; _call = nil; - if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { dispatch_async(_handler.dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; self->_handler = nil; } - [copiedHandler closedWithTrailingMetadata:nil + [copiedHandler didCloseWithTrailingMetadata:nil error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled userInfo:@{ @@ -187,7 +187,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing [call finish]; } -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { @synchronized(self) { if (initialMetadata != nil && [_handler respondsToSelector:@selector(initialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ @@ -195,35 +195,35 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @synchronized(self) { copiedHandler = self->_handler; } - [copiedHandler receivedInitialMetadata:initialMetadata]; + [copiedHandler didReceiveInitialMetadata:initialMetadata]; }); } } } -- (void)receivedRawMessage:(NSData *)message { +- (void)didReceiveRawMessage:(NSData *)message { if (message == nil) return; NSError *error = nil; GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; @synchronized(self) { - if (parsed && [_handler respondsToSelector:@selector(receivedProtoMessage:)]) { + if (parsed && [_handler respondsToSelector:@selector(didReceiveProtoMessage:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; } - [copiedHandler receivedProtoMessage:parsed]; + [copiedHandler didReceiveProtoMessage:parsed]; }); } else if (!parsed && - [_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + [_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; self->_handler = nil; } - [copiedHandler closedWithTrailingMetadata:nil + [copiedHandler didCloseWithTrailingMetadata:nil error:ErrorForBadProto(message, _responseClass, error)]; }); [_call cancel]; @@ -232,16 +232,16 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { @synchronized(self) { - if ([_handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) { + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; self->_handler = nil; } - [copiedHandler closedWithTrailingMetadata:trailingMetadata error:error]; + [copiedHandler didCloseWithTrailingMetadata:trailingMetadata error:error]; }); } _call = nil; diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index 32f2122f79b..ca7bf472830 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -81,19 +81,19 @@ static const NSTimeInterval kTestTimeout = 16; return self; } -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { if (self->_initialMetadataCallback) { self->_initialMetadataCallback(initialMetadata); } } -- (void)receivedRawMessage:(GPBMessage *)message { +- (void)didReceiveRawMessage:(GPBMessage *)message { if (self->_messageCallback) { self->_messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { if (self->_closeCallback) { self->_closeCallback(trailingMetadata, error); } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index e94fd1493a0..d17a07f929a 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -102,19 +102,19 @@ BOOL isRemoteInteropTest(NSString *host) { return self; } -- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); } } -- (void)receivedProtoMessage:(GPBMessage *)message { +- (void)didReceiveProtoMessage:(GPBMessage *)message { if (_messageCallback) { _messageCallback(message); } } -- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { if (_closeCallback) { _closeCallback(trailingMetadata, error); } From e00ca0371a332e8d35a7394556883e1693fa8a2f Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 6 Dec 2018 13:40:12 -0800 Subject: [PATCH 0466/2143] Promote gpr_test_util to part of grpc_test_util, add a sample to show it works, build.yaml change first --- CMakeLists.txt | 375 +--- Makefile | 1895 ++++++++--------- build.yaml | 288 +-- gRPC-Core.podspec | 6 +- grpc.gyp | 21 +- src/core/lib/surface/init.cc | 4 + src/core/lib/surface/init.h | 1 + test/core/bad_client/gen_build_yaml.py | 2 - test/core/bad_ssl/gen_build_yaml.py | 3 - test/core/end2end/gen_build_yaml.py | 2 - test/core/util/test_config.cc | 3 +- test/cpp/naming/gen_build_yaml.py | 4 - .../generated/sources_and_headers.json | 370 +--- 13 files changed, 1074 insertions(+), 1900 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1194d0072e3..c3058de14e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -930,49 +930,6 @@ if (gRPC_INSTALL) ) endif() -if (gRPC_BUILD_TESTS) - -add_library(gpr_test_util - test/core/util/test_config.cc -) - -if(WIN32 AND MSVC) - set_target_properties(gpr_test_util PROPERTIES COMPILE_PDB_NAME "gpr_test_util" - COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" - ) - if (gRPC_INSTALL) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gpr_test_util.pdb - DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL - ) - endif() -endif() - - -target_include_directories(gpr_test_util - 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(gpr_test_util PROPERTIES LINKER_LANGUAGE C) - # only use the flags for C++ source files - target_compile_options(gpr_test_util PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() -target_link_libraries(gpr_test_util - ${_gRPC_ALLTARGETS_LIBRARIES} - gpr -) - - -endif (gRPC_BUILD_TESTS) add_library(grpc src/core/lib/surface/init.cc @@ -1797,6 +1754,7 @@ add_library(grpc_test_util 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/tracer_util.cc test/core/util/trickle_endpoint.cc test/core/util/cmdline.cc @@ -2041,7 +1999,6 @@ target_include_directories(grpc_test_util endif() target_link_libraries(grpc_test_util ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr grpc ) @@ -2117,6 +2074,7 @@ add_library(grpc_test_util_unsecure 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/tracer_util.cc test/core/util/trickle_endpoint.cc test/core/util/cmdline.cc @@ -2362,7 +2320,6 @@ target_include_directories(grpc_test_util_unsecure target_link_libraries(grpc_test_util_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} gpr - gpr_test_util grpc_unsecure ) @@ -2802,7 +2759,6 @@ target_link_libraries(reconnect_server test_tcp_server grpc_test_util grpc - gpr_test_util gpr ) @@ -2848,7 +2804,6 @@ target_link_libraries(test_tcp_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5140,7 +5095,6 @@ target_link_libraries(interop_client_main grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ) @@ -5260,7 +5214,6 @@ target_link_libraries(interop_server_lib grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ) @@ -5514,7 +5467,6 @@ target_link_libraries(bad_client_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -5560,7 +5512,6 @@ target_link_libraries(bad_ssl_test_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5686,7 +5637,6 @@ target_link_libraries(end2end_tests ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5810,7 +5760,6 @@ target_link_libraries(end2end_nosec_tests ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -5841,7 +5790,6 @@ target_link_libraries(algorithm_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5874,8 +5822,9 @@ target_include_directories(alloc_test target_link_libraries(alloc_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -5909,7 +5858,6 @@ target_link_libraries(alpn_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5942,8 +5890,9 @@ target_include_directories(arena_test target_link_libraries(arena_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -5975,8 +5924,8 @@ target_include_directories(avl_test target_link_libraries(avl_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util grpc ) @@ -6012,7 +5961,6 @@ target_link_libraries(bad_server_response_test test_tcp_server grpc_test_util grpc - gpr_test_util gpr ) @@ -6114,7 +6062,6 @@ target_link_libraries(buffer_list_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6150,7 +6097,6 @@ target_link_libraries(channel_create_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6216,7 +6162,6 @@ target_link_libraries(chttp2_hpack_encoder_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6251,7 +6196,6 @@ target_link_libraries(chttp2_stream_map_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6286,7 +6230,6 @@ target_link_libraries(chttp2_varint_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6320,8 +6263,8 @@ target_include_directories(cmdline_test target_link_libraries(cmdline_test ${_gRPC_ALLTARGETS_LIBRARIES} gpr - gpr_test_util grpc_test_util + grpc ) # avoid dependency on libstdc++ @@ -6355,7 +6298,6 @@ target_link_libraries(combiner_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6390,7 +6332,6 @@ target_link_libraries(compression_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6425,7 +6366,6 @@ target_link_libraries(concurrent_connectivity_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6460,7 +6400,6 @@ target_link_libraries(connection_refused_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6495,7 +6434,6 @@ target_link_libraries(dns_resolver_connectivity_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6530,7 +6468,6 @@ target_link_libraries(dns_resolver_cooldown_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6565,7 +6502,6 @@ target_link_libraries(dns_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6601,7 +6537,6 @@ target_link_libraries(dualstack_socket_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6637,7 +6572,6 @@ target_link_libraries(endpoint_pair_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6672,7 +6606,6 @@ target_link_libraries(error_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6708,7 +6641,6 @@ target_link_libraries(ev_epollex_linux_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6744,7 +6676,6 @@ target_link_libraries(fake_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6779,8 +6710,8 @@ target_include_directories(fake_transport_security_test target_link_libraries(fake_transport_security_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util grpc ) @@ -6817,7 +6748,6 @@ target_link_libraries(fd_conservation_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6854,7 +6784,6 @@ target_link_libraries(fd_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6890,7 +6819,6 @@ target_link_libraries(fling_client ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6925,7 +6853,6 @@ target_link_libraries(fling_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6961,7 +6888,6 @@ target_link_libraries(fling_stream_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6998,7 +6924,6 @@ target_link_libraries(fling_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7033,8 +6958,9 @@ target_include_directories(fork_test target_link_libraries(fork_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7070,7 +6996,6 @@ target_link_libraries(goaway_server_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7104,8 +7029,9 @@ target_include_directories(gpr_cpu_test target_link_libraries(gpr_cpu_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7137,8 +7063,9 @@ target_include_directories(gpr_env_test target_link_libraries(gpr_env_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7170,8 +7097,9 @@ target_include_directories(gpr_host_port_test target_link_libraries(gpr_host_port_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7203,8 +7131,9 @@ target_include_directories(gpr_log_test target_link_libraries(gpr_log_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7236,8 +7165,9 @@ target_include_directories(gpr_manual_constructor_test target_link_libraries(gpr_manual_constructor_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7269,8 +7199,9 @@ target_include_directories(gpr_mpscq_test target_link_libraries(gpr_mpscq_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7302,8 +7233,9 @@ target_include_directories(gpr_spinlock_test target_link_libraries(gpr_spinlock_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7335,8 +7267,9 @@ target_include_directories(gpr_string_test target_link_libraries(gpr_string_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7368,8 +7301,9 @@ target_include_directories(gpr_sync_test target_link_libraries(gpr_sync_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7401,8 +7335,9 @@ target_include_directories(gpr_thd_test target_link_libraries(gpr_thd_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7434,8 +7369,9 @@ target_include_directories(gpr_time_test target_link_libraries(gpr_time_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7467,8 +7403,9 @@ target_include_directories(gpr_tls_test target_link_libraries(gpr_tls_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7500,8 +7437,9 @@ target_include_directories(gpr_useful_test target_link_libraries(gpr_useful_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7535,7 +7473,6 @@ target_link_libraries(grpc_auth_context_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7570,7 +7507,6 @@ target_link_libraries(grpc_b64_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7605,7 +7541,6 @@ target_link_libraries(grpc_byte_buffer_reader_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7640,7 +7575,6 @@ target_link_libraries(grpc_channel_args_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7675,7 +7609,6 @@ target_link_libraries(grpc_channel_stack_builder_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7710,7 +7643,6 @@ target_link_libraries(grpc_channel_stack_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7745,7 +7677,6 @@ target_link_libraries(grpc_completion_queue_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7780,7 +7711,6 @@ target_link_libraries(grpc_completion_queue_threading_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7848,7 +7778,6 @@ target_link_libraries(grpc_credentials_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7883,7 +7812,6 @@ target_link_libraries(grpc_fetch_oauth2 ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7918,7 +7846,6 @@ target_link_libraries(grpc_ipv6_loopback_available_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7954,7 +7881,6 @@ target_link_libraries(grpc_json_token_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7990,7 +7916,6 @@ target_link_libraries(grpc_jwt_verifier_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8057,7 +7982,6 @@ target_link_libraries(grpc_security_connector_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8092,7 +8016,6 @@ target_link_libraries(grpc_ssl_credentials_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8161,7 +8084,6 @@ target_link_libraries(handshake_client_ssl ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8200,7 +8122,6 @@ target_link_libraries(handshake_server_ssl ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8239,7 +8160,6 @@ target_link_libraries(handshake_server_with_readahead_handshaker ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8277,7 +8197,6 @@ target_link_libraries(handshake_verify_peer_options ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8346,7 +8265,6 @@ target_link_libraries(hpack_parser_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8381,7 +8299,6 @@ target_link_libraries(hpack_table_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8416,7 +8333,6 @@ target_link_libraries(http_parser_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8451,7 +8367,6 @@ target_link_libraries(httpcli_format_request_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8487,7 +8402,6 @@ target_link_libraries(httpcli_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8524,7 +8438,6 @@ target_link_libraries(httpscli_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8560,7 +8473,6 @@ target_link_libraries(init_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8595,7 +8507,6 @@ target_link_libraries(inproc_callback_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8630,7 +8541,6 @@ target_link_libraries(invalid_call_argument_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8665,7 +8575,6 @@ target_link_libraries(json_rewrite ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8700,7 +8609,6 @@ target_link_libraries(json_rewrite_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8735,7 +8643,6 @@ target_link_libraries(json_stream_error_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8770,7 +8677,6 @@ target_link_libraries(json_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8805,7 +8711,6 @@ target_link_libraries(lame_client_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8840,7 +8745,6 @@ target_link_libraries(load_file_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8875,7 +8779,6 @@ target_link_libraries(memory_usage_client ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8910,7 +8813,6 @@ target_link_libraries(memory_usage_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8946,7 +8848,6 @@ target_link_libraries(memory_usage_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8982,7 +8883,6 @@ target_link_libraries(message_compress_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9017,7 +8917,6 @@ target_link_libraries(minimal_stack_is_minimal_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9052,7 +8951,6 @@ target_link_libraries(multiple_server_queues_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9085,8 +8983,9 @@ target_include_directories(murmur_hash_test target_link_libraries(murmur_hash_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -9120,7 +9019,6 @@ target_link_libraries(no_server_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9155,7 +9053,6 @@ target_link_libraries(num_external_connectivity_watchers_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9190,7 +9087,6 @@ target_link_libraries(parse_address_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9225,7 +9121,6 @@ target_link_libraries(percent_encoding_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9261,7 +9156,6 @@ target_link_libraries(resolve_address_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9297,7 +9191,6 @@ target_link_libraries(resolve_address_using_ares_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9332,7 +9225,6 @@ target_link_libraries(resolve_address_using_native_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9367,7 +9259,6 @@ target_link_libraries(resource_quota_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9402,7 +9293,6 @@ target_link_libraries(secure_channel_create_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9437,7 +9327,6 @@ target_link_libraries(secure_endpoint_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9472,7 +9361,6 @@ target_link_libraries(sequential_connectivity_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9507,7 +9395,6 @@ target_link_libraries(server_chttp2_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9542,7 +9429,6 @@ target_link_libraries(server_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9577,7 +9463,6 @@ target_link_libraries(slice_buffer_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9612,7 +9497,6 @@ target_link_libraries(slice_string_helpers_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9647,7 +9531,6 @@ target_link_libraries(slice_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9682,7 +9565,6 @@ target_link_libraries(sockaddr_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9717,7 +9599,6 @@ target_link_libraries(sockaddr_utils_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9753,7 +9634,6 @@ target_link_libraries(socket_utils_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9789,8 +9669,8 @@ target_include_directories(ssl_transport_security_test target_link_libraries(ssl_transport_security_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util grpc ) @@ -9826,7 +9706,6 @@ target_link_libraries(status_conversion_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9861,7 +9740,6 @@ target_link_libraries(stream_compression_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9896,7 +9774,6 @@ target_link_libraries(stream_owned_slice_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9932,7 +9809,6 @@ target_link_libraries(tcp_client_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9968,7 +9844,6 @@ target_link_libraries(tcp_client_uv_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10004,7 +9879,6 @@ target_link_libraries(tcp_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10041,7 +9915,6 @@ target_link_libraries(tcp_server_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10077,7 +9950,6 @@ target_link_libraries(tcp_server_uv_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10112,7 +9984,6 @@ target_link_libraries(time_averaged_stats_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10147,7 +10018,6 @@ target_link_libraries(timeout_encoding_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10182,7 +10052,6 @@ target_link_libraries(timer_heap_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10217,7 +10086,6 @@ target_link_libraries(timer_list_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10252,7 +10120,6 @@ target_link_libraries(transport_connectivity_state_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10287,7 +10154,6 @@ target_link_libraries(transport_metadata_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10323,7 +10189,6 @@ target_link_libraries(transport_security_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10360,7 +10225,6 @@ target_link_libraries(udp_server_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10396,7 +10260,6 @@ target_link_libraries(uri_parser_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10432,7 +10295,6 @@ target_link_libraries(wakeup_fd_cv_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10478,7 +10340,6 @@ target_link_libraries(alarm_test grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -10554,8 +10415,8 @@ target_link_libraries(alts_crypt_test ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} alts_test_util - gpr_test_util gpr + grpc_test_util grpc ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11014,7 +10875,6 @@ target_link_libraries(async_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11055,7 +10915,6 @@ target_link_libraries(auth_property_iterator_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11094,7 +10953,6 @@ target_link_libraries(backoff_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11135,7 +10993,6 @@ target_link_libraries(bdp_estimator_test grpc++ grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11179,7 +11036,6 @@ target_link_libraries(bm_arena grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11225,7 +11081,6 @@ target_link_libraries(bm_call_create grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11271,7 +11126,6 @@ target_link_libraries(bm_channel grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11317,7 +11171,6 @@ target_link_libraries(bm_chttp2_hpack grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11363,7 +11216,6 @@ target_link_libraries(bm_chttp2_transport grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11409,7 +11261,6 @@ target_link_libraries(bm_closure grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11455,7 +11306,6 @@ target_link_libraries(bm_cq grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11501,7 +11351,6 @@ target_link_libraries(bm_cq_multiple_threads grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11547,7 +11396,6 @@ target_link_libraries(bm_error grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11593,7 +11441,6 @@ target_link_libraries(bm_fullstack_streaming_ping_pong grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11639,7 +11486,6 @@ target_link_libraries(bm_fullstack_streaming_pump grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11685,7 +11531,6 @@ target_link_libraries(bm_fullstack_trickle grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11731,7 +11576,6 @@ target_link_libraries(bm_fullstack_unary_ping_pong grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11777,7 +11621,6 @@ target_link_libraries(bm_metadata grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11823,7 +11666,6 @@ target_link_libraries(bm_pollset grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11864,7 +11706,6 @@ target_link_libraries(byte_stream_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11988,7 +11829,6 @@ target_link_libraries(channel_trace_test grpc++_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12029,7 +11869,6 @@ target_link_libraries(channelz_registry_test grpc++_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12078,7 +11917,6 @@ target_link_libraries(channelz_service_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12126,7 +11964,6 @@ target_link_libraries(channelz_test grpc++_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12239,7 +12076,6 @@ target_link_libraries(chttp2_settings_timeout_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12281,7 +12117,6 @@ target_link_libraries(cli_call_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12322,7 +12157,6 @@ target_link_libraries(client_callback_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12370,7 +12204,6 @@ target_link_libraries(client_channel_stress_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12412,7 +12245,6 @@ target_link_libraries(client_crash_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12454,7 +12286,6 @@ target_link_libraries(client_crash_test_server grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12496,7 +12327,6 @@ target_link_libraries(client_interceptors_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12537,7 +12367,6 @@ target_link_libraries(client_lb_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12752,7 +12581,6 @@ target_link_libraries(context_list_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12830,7 +12658,6 @@ target_link_libraries(cxx_byte_buffer_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12870,7 +12697,6 @@ target_link_libraries(cxx_slice_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12947,7 +12773,6 @@ target_link_libraries(cxx_time_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12989,7 +12814,6 @@ target_link_libraries(end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13074,7 +12898,6 @@ target_link_libraries(exception_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13115,7 +12938,6 @@ target_link_libraries(filter_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13156,7 +12978,6 @@ target_link_libraries(generic_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13396,7 +13217,6 @@ target_link_libraries(grpc_linux_system_roots_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13649,7 +13469,6 @@ target_link_libraries(grpc_tool_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13743,7 +13562,6 @@ target_link_libraries(grpclb_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13783,7 +13601,6 @@ target_link_libraries(h2_ssl_cert_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13823,7 +13640,6 @@ target_link_libraries(h2_ssl_session_reuse_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13864,7 +13680,6 @@ target_link_libraries(health_service_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13947,7 +13762,6 @@ target_link_libraries(hybrid_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13987,7 +13801,6 @@ target_link_libraries(inlined_vector_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14031,7 +13844,6 @@ target_link_libraries(inproc_sync_unary_ping_pong_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14076,7 +13888,6 @@ target_link_libraries(interop_client grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14122,7 +13933,6 @@ target_link_libraries(interop_server grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14164,7 +13974,6 @@ target_link_libraries(interop_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14208,7 +14017,6 @@ target_link_libraries(json_run_localhost grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14250,7 +14058,6 @@ target_link_libraries(memory_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14337,7 +14144,6 @@ target_link_libraries(mock_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14378,7 +14184,6 @@ target_link_libraries(nonblocking_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14454,7 +14259,6 @@ target_link_libraries(orphanable_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14497,7 +14301,6 @@ target_link_libraries(proto_server_reflection_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14577,7 +14380,6 @@ target_link_libraries(qps_interarrival_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14622,7 +14424,6 @@ target_link_libraries(qps_json_driver grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14667,7 +14468,6 @@ target_link_libraries(qps_openloop_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14712,7 +14512,6 @@ target_link_libraries(qps_worker grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14754,7 +14553,6 @@ target_link_libraries(raw_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14816,7 +14614,6 @@ target_link_libraries(reconnect_interop_client grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14881,7 +14678,6 @@ target_link_libraries(reconnect_interop_server grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14922,7 +14718,6 @@ target_link_libraries(ref_counted_ptr_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14962,7 +14757,6 @@ target_link_libraries(ref_counted_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15001,7 +14795,6 @@ target_link_libraries(retry_throttle_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15042,7 +14835,6 @@ target_link_libraries(secure_auth_context_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15086,7 +14878,6 @@ target_link_libraries(secure_sync_unary_ping_pong_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -15129,7 +14920,6 @@ target_link_libraries(server_builder_plugin_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15182,7 +14972,6 @@ target_link_libraries(server_builder_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -15238,7 +15027,6 @@ target_link_libraries(server_builder_with_socket_mutator_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -15281,7 +15069,6 @@ target_link_libraries(server_context_test_spouse_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15323,7 +15110,6 @@ target_link_libraries(server_crash_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15365,7 +15151,6 @@ target_link_libraries(server_crash_test_client grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15406,7 +15191,6 @@ target_link_libraries(server_early_return_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15448,7 +15232,6 @@ target_link_libraries(server_interceptors_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15501,7 +15284,6 @@ target_link_libraries(server_request_call_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -15544,7 +15326,6 @@ target_link_libraries(shutdown_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15583,7 +15364,6 @@ target_link_libraries(slice_hash_table_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15622,7 +15402,6 @@ target_link_libraries(slice_weak_hash_table_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15662,7 +15441,6 @@ target_link_libraries(stats_test grpc++_test_util grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15776,7 +15554,6 @@ target_link_libraries(streaming_throughput_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15849,7 +15626,6 @@ target_link_libraries(stress_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -15930,7 +15706,6 @@ target_link_libraries(thread_stress_test grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15971,7 +15746,6 @@ target_link_libraries(transport_pid_controller_test grpc++ grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -16051,7 +15825,6 @@ target_link_libraries(writes_per_rpc_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -16187,7 +15960,6 @@ target_link_libraries(badreq_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16224,7 +15996,6 @@ target_link_libraries(connection_prefix_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16261,7 +16032,6 @@ target_link_libraries(duplicate_header_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16298,7 +16068,6 @@ target_link_libraries(head_of_line_blocking_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16335,7 +16104,6 @@ target_link_libraries(headers_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16372,7 +16140,6 @@ target_link_libraries(initial_settings_frame_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16409,7 +16176,6 @@ target_link_libraries(large_metadata_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16446,7 +16212,6 @@ target_link_libraries(server_registered_method_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16483,7 +16248,6 @@ target_link_libraries(simple_request_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16520,7 +16284,6 @@ target_link_libraries(unknown_frame_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16557,7 +16320,6 @@ target_link_libraries(window_overflow_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16594,7 +16356,6 @@ target_link_libraries(bad_ssl_cert_server bad_ssl_test_server grpc_test_util grpc - gpr_test_util gpr ) @@ -16631,7 +16392,6 @@ target_link_libraries(bad_ssl_cert_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -16668,7 +16428,6 @@ target_link_libraries(h2_census_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16704,7 +16463,6 @@ target_link_libraries(h2_compress_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16740,7 +16498,6 @@ target_link_libraries(h2_fakesec_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16777,7 +16534,6 @@ target_link_libraries(h2_fd_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16814,7 +16570,6 @@ target_link_libraries(h2_full_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16851,7 +16606,6 @@ target_link_libraries(h2_full+pipe_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16888,7 +16642,6 @@ target_link_libraries(h2_full+trace_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16924,7 +16677,6 @@ target_link_libraries(h2_full+workarounds_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16960,7 +16712,6 @@ target_link_libraries(h2_http_proxy_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16997,7 +16748,6 @@ target_link_libraries(h2_local_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17034,7 +16784,6 @@ target_link_libraries(h2_oauth2_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17070,7 +16819,6 @@ target_link_libraries(h2_proxy_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17106,7 +16854,6 @@ target_link_libraries(h2_sockpair_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17142,7 +16889,6 @@ target_link_libraries(h2_sockpair+trace_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17178,7 +16924,6 @@ target_link_libraries(h2_sockpair_1byte_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17214,7 +16959,6 @@ target_link_libraries(h2_ssl_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17250,7 +16994,6 @@ target_link_libraries(h2_ssl_proxy_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17287,7 +17030,6 @@ target_link_libraries(h2_uds_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17324,7 +17066,6 @@ target_link_libraries(inproc_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17360,7 +17101,6 @@ target_link_libraries(h2_census_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17396,7 +17136,6 @@ target_link_libraries(h2_compress_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17433,7 +17172,6 @@ target_link_libraries(h2_fd_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17470,7 +17208,6 @@ target_link_libraries(h2_full_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17507,7 +17244,6 @@ target_link_libraries(h2_full+pipe_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17544,7 +17280,6 @@ target_link_libraries(h2_full+trace_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17580,7 +17315,6 @@ target_link_libraries(h2_full+workarounds_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17616,7 +17350,6 @@ target_link_libraries(h2_http_proxy_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17652,7 +17385,6 @@ target_link_libraries(h2_proxy_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17688,7 +17420,6 @@ target_link_libraries(h2_sockpair_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17724,7 +17455,6 @@ target_link_libraries(h2_sockpair+trace_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17760,7 +17490,6 @@ target_link_libraries(h2_sockpair_1byte_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17797,7 +17526,6 @@ target_link_libraries(h2_uds_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17841,7 +17569,6 @@ target_link_libraries(resolver_component_test_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -17883,7 +17610,6 @@ target_link_libraries(resolver_component_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -17926,7 +17652,6 @@ target_link_libraries(resolver_component_tests_runner_invoker_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -17970,7 +17695,6 @@ target_link_libraries(resolver_component_tests_runner_invoker ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -18013,7 +17737,6 @@ target_link_libraries(address_sorting_test_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -18055,7 +17778,6 @@ target_link_libraries(address_sorting_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -18097,7 +17819,6 @@ target_link_libraries(cancel_ares_query_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -18132,7 +17853,6 @@ target_link_libraries(alts_credentials_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18168,7 +17888,6 @@ target_link_libraries(api_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18204,7 +17923,6 @@ target_link_libraries(client_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18240,7 +17958,6 @@ target_link_libraries(hpack_parser_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18276,7 +17993,6 @@ target_link_libraries(http_request_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18312,7 +18028,6 @@ target_link_libraries(http_response_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18348,7 +18063,6 @@ target_link_libraries(json_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18384,7 +18098,6 @@ target_link_libraries(nanopb_fuzzer_response_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18420,7 +18133,6 @@ target_link_libraries(nanopb_fuzzer_serverlist_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18456,7 +18168,6 @@ target_link_libraries(percent_decode_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18492,7 +18203,6 @@ target_link_libraries(percent_encode_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18528,7 +18238,6 @@ target_link_libraries(server_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18564,7 +18273,6 @@ target_link_libraries(ssl_server_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18600,7 +18308,6 @@ target_link_libraries(uri_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) diff --git a/Makefile b/Makefile index 7dfce79c922..d0b09e79289 100644 --- a/Makefile +++ b/Makefile @@ -1411,7 +1411,7 @@ plugins: $(PROTOC_PLUGINS) privatelibs: privatelibs_c privatelibs_cxx -privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.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)/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 @@ -3444,31 +3444,6 @@ ifneq ($(NO_DEPS),true) endif -LIBGPR_TEST_UTIL_SRC = \ - test/core/util/test_config.cc \ - -PUBLIC_HEADERS_C += \ - -LIBGPR_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGPR_TEST_UTIL_SRC)))) - - -$(LIBDIR)/$(CONFIG)/libgpr_test_util.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(LIBGPR_TEST_UTIL_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr_test_util.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBGPR_TEST_UTIL_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgpr_test_util.a -endif - - - - -ifneq ($(NO_DEPS),true) --include $(LIBGPR_TEST_UTIL_OBJS:.o=.dep) -endif - - LIBGRPC_SRC = \ src/core/lib/surface/init.cc \ src/core/lib/avl/avl.cc \ @@ -4279,6 +4254,7 @@ LIBGRPC_TEST_UTIL_SRC = \ 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/tracer_util.cc \ test/core/util/trickle_endpoint.cc \ test/core/util/cmdline.cc \ @@ -4585,6 +4561,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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/tracer_util.cc \ test/core/util/trickle_endpoint.cc \ test/core/util/cmdline.cc \ @@ -10545,14 +10522,14 @@ else -$(BINDIR)/$(CONFIG)/algorithm_test: $(ALGORITHM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/algorithm_test: $(ALGORITHM_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) $(ALGORITHM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/algorithm_test + $(Q) $(LD) $(LDFLAGS) $(ALGORITHM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/algorithm_test endif -$(OBJDIR)/$(CONFIG)/test/core/compression/algorithm_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/compression/algorithm_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_algorithm_test: $(ALGORITHM_TEST_OBJS:.o=.dep) @@ -10577,14 +10554,14 @@ else -$(BINDIR)/$(CONFIG)/alloc_test: $(ALLOC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/alloc_test: $(ALLOC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ALLOC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alloc_test + $(Q) $(LD) $(LDFLAGS) $(ALLOC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alloc_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/alloc_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/alloc_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_alloc_test: $(ALLOC_TEST_OBJS:.o=.dep) @@ -10609,14 +10586,14 @@ else -$(BINDIR)/$(CONFIG)/alpn_test: $(ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/alpn_test: $(ALPN_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) $(ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alpn_test + $(Q) $(LD) $(LDFLAGS) $(ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alpn_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/alpn_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/alpn_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_alpn_test: $(ALPN_TEST_OBJS:.o=.dep) @@ -10641,14 +10618,14 @@ else -$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer: $(ALTS_CREDENTIALS_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer: $(ALTS_CREDENTIALS_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ALTS_CREDENTIALS_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(ALTS_CREDENTIALS_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/security/alts_credentials_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/alts_credentials_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_alts_credentials_fuzzer: $(ALTS_CREDENTIALS_FUZZER_OBJS:.o=.dep) @@ -10673,14 +10650,14 @@ else -$(BINDIR)/$(CONFIG)/api_fuzzer: $(API_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/api_fuzzer: $(API_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(API_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/api_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(API_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/api_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/api_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/api_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_api_fuzzer: $(API_FUZZER_OBJS:.o=.dep) @@ -10705,14 +10682,14 @@ else -$(BINDIR)/$(CONFIG)/arena_test: $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/arena_test: $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/arena_test + $(Q) $(LD) $(LDFLAGS) $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/arena_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/arena_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/arena_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_arena_test: $(ARENA_TEST_OBJS:.o=.dep) @@ -10737,14 +10714,14 @@ else -$(BINDIR)/$(CONFIG)/avl_test: $(AVL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(BINDIR)/$(CONFIG)/avl_test: $(AVL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(AVL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/avl_test + $(Q) $(LD) $(LDFLAGS) $(AVL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/avl_test endif -$(OBJDIR)/$(CONFIG)/test/core/avl/avl_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/avl/avl_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_avl_test: $(AVL_TEST_OBJS:.o=.dep) @@ -10769,14 +10746,14 @@ else -$(BINDIR)/$(CONFIG)/bad_server_response_test: $(BAD_SERVER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bad_server_response_test: $(BAD_SERVER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.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) $(BAD_SERVER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_server_response_test + $(Q) $(LD) $(LDFLAGS) $(BAD_SERVER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_server_response_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/bad_server_response_test.o: $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/bad_server_response_test.o: $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bad_server_response_test: $(BAD_SERVER_RESPONSE_TEST_OBJS:.o=.dep) @@ -10865,14 +10842,14 @@ else -$(BINDIR)/$(CONFIG)/buffer_list_test: $(BUFFER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/buffer_list_test: $(BUFFER_LIST_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) $(BUFFER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/buffer_list_test + $(Q) $(LD) $(LDFLAGS) $(BUFFER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/buffer_list_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/buffer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/buffer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_buffer_list_test: $(BUFFER_LIST_TEST_OBJS:.o=.dep) @@ -10897,14 +10874,14 @@ else -$(BINDIR)/$(CONFIG)/channel_create_test: $(CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channel_create_test: $(CHANNEL_CREATE_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) $(CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/channel_create_test + $(Q) $(LD) $(LDFLAGS) $(CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/channel_create_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/channel_create_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/channel_create_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_channel_create_test: $(CHANNEL_CREATE_TEST_OBJS:.o=.dep) @@ -10961,14 +10938,14 @@ else -$(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test: $(CHTTP2_HPACK_ENCODER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test: $(CHTTP2_HPACK_ENCODER_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) $(CHTTP2_HPACK_ENCODER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test + $(Q) $(LD) $(LDFLAGS) $(CHTTP2_HPACK_ENCODER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_encoder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_encoder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_chttp2_hpack_encoder_test: $(CHTTP2_HPACK_ENCODER_TEST_OBJS:.o=.dep) @@ -10993,14 +10970,14 @@ else -$(BINDIR)/$(CONFIG)/chttp2_stream_map_test: $(CHTTP2_STREAM_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/chttp2_stream_map_test: $(CHTTP2_STREAM_MAP_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) $(CHTTP2_STREAM_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_stream_map_test + $(Q) $(LD) $(LDFLAGS) $(CHTTP2_STREAM_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_stream_map_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/stream_map_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/stream_map_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_chttp2_stream_map_test: $(CHTTP2_STREAM_MAP_TEST_OBJS:.o=.dep) @@ -11025,14 +11002,14 @@ else -$(BINDIR)/$(CONFIG)/chttp2_varint_test: $(CHTTP2_VARINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/chttp2_varint_test: $(CHTTP2_VARINT_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) $(CHTTP2_VARINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_varint_test + $(Q) $(LD) $(LDFLAGS) $(CHTTP2_VARINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_varint_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/varint_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/varint_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_chttp2_varint_test: $(CHTTP2_VARINT_TEST_OBJS:.o=.dep) @@ -11057,14 +11034,14 @@ else -$(BINDIR)/$(CONFIG)/client_fuzzer: $(CLIENT_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_fuzzer: $(CLIENT_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/client_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/client_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/client_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/client_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_fuzzer: $(CLIENT_FUZZER_OBJS:.o=.dep) @@ -11089,14 +11066,14 @@ else -$(BINDIR)/$(CONFIG)/cmdline_test: $(CMDLINE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a +$(BINDIR)/$(CONFIG)/cmdline_test: $(CMDLINE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CMDLINE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/cmdline_test + $(Q) $(LD) $(LDFLAGS) $(CMDLINE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/cmdline_test endif -$(OBJDIR)/$(CONFIG)/test/core/util/cmdline_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a +$(OBJDIR)/$(CONFIG)/test/core/util/cmdline_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_cmdline_test: $(CMDLINE_TEST_OBJS:.o=.dep) @@ -11121,14 +11098,14 @@ else -$(BINDIR)/$(CONFIG)/combiner_test: $(COMBINER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/combiner_test: $(COMBINER_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) $(COMBINER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/combiner_test + $(Q) $(LD) $(LDFLAGS) $(COMBINER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/combiner_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/combiner_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/combiner_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_combiner_test: $(COMBINER_TEST_OBJS:.o=.dep) @@ -11153,14 +11130,14 @@ else -$(BINDIR)/$(CONFIG)/compression_test: $(COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/compression_test: $(COMPRESSION_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) $(COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/compression_test + $(Q) $(LD) $(LDFLAGS) $(COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/compression_test endif -$(OBJDIR)/$(CONFIG)/test/core/compression/compression_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/compression/compression_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_compression_test: $(COMPRESSION_TEST_OBJS:.o=.dep) @@ -11185,14 +11162,14 @@ else -$(BINDIR)/$(CONFIG)/concurrent_connectivity_test: $(CONCURRENT_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/concurrent_connectivity_test: $(CONCURRENT_CONNECTIVITY_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) $(CONCURRENT_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/concurrent_connectivity_test + $(Q) $(LD) $(LDFLAGS) $(CONCURRENT_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/concurrent_connectivity_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/concurrent_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/concurrent_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_concurrent_connectivity_test: $(CONCURRENT_CONNECTIVITY_TEST_OBJS:.o=.dep) @@ -11217,14 +11194,14 @@ else -$(BINDIR)/$(CONFIG)/connection_refused_test: $(CONNECTION_REFUSED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/connection_refused_test: $(CONNECTION_REFUSED_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) $(CONNECTION_REFUSED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/connection_refused_test + $(Q) $(LD) $(LDFLAGS) $(CONNECTION_REFUSED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/connection_refused_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/connection_refused_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/connection_refused_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_connection_refused_test: $(CONNECTION_REFUSED_TEST_OBJS:.o=.dep) @@ -11249,14 +11226,14 @@ else -$(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test: $(DNS_RESOLVER_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test: $(DNS_RESOLVER_CONNECTIVITY_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) $(DNS_RESOLVER_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test + $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_dns_resolver_connectivity_test: $(DNS_RESOLVER_CONNECTIVITY_TEST_OBJS:.o=.dep) @@ -11281,14 +11258,14 @@ else -$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_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) $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test + $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_cooldown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_cooldown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS:.o=.dep) @@ -11313,14 +11290,14 @@ else -$(BINDIR)/$(CONFIG)/dns_resolver_test: $(DNS_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/dns_resolver_test: $(DNS_RESOLVER_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) $(DNS_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_test + $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_dns_resolver_test: $(DNS_RESOLVER_TEST_OBJS:.o=.dep) @@ -11345,14 +11322,14 @@ else -$(BINDIR)/$(CONFIG)/dualstack_socket_test: $(DUALSTACK_SOCKET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/dualstack_socket_test: $(DUALSTACK_SOCKET_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) $(DUALSTACK_SOCKET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dualstack_socket_test + $(Q) $(LD) $(LDFLAGS) $(DUALSTACK_SOCKET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dualstack_socket_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/dualstack_socket_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/dualstack_socket_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_dualstack_socket_test: $(DUALSTACK_SOCKET_TEST_OBJS:.o=.dep) @@ -11377,14 +11354,14 @@ else -$(BINDIR)/$(CONFIG)/endpoint_pair_test: $(ENDPOINT_PAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/endpoint_pair_test: $(ENDPOINT_PAIR_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) $(ENDPOINT_PAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/endpoint_pair_test + $(Q) $(LD) $(LDFLAGS) $(ENDPOINT_PAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/endpoint_pair_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/endpoint_pair_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/endpoint_pair_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_endpoint_pair_test: $(ENDPOINT_PAIR_TEST_OBJS:.o=.dep) @@ -11409,14 +11386,14 @@ else -$(BINDIR)/$(CONFIG)/error_test: $(ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/error_test: $(ERROR_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) $(ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/error_test + $(Q) $(LD) $(LDFLAGS) $(ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/error_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/error_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/error_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_error_test: $(ERROR_TEST_OBJS:.o=.dep) @@ -11441,14 +11418,14 @@ else -$(BINDIR)/$(CONFIG)/ev_epollex_linux_test: $(EV_EPOLLEX_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ev_epollex_linux_test: $(EV_EPOLLEX_LINUX_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) $(EV_EPOLLEX_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ev_epollex_linux_test + $(Q) $(LD) $(LDFLAGS) $(EV_EPOLLEX_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ev_epollex_linux_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/ev_epollex_linux_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/ev_epollex_linux_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ev_epollex_linux_test: $(EV_EPOLLEX_LINUX_TEST_OBJS:.o=.dep) @@ -11473,14 +11450,14 @@ else -$(BINDIR)/$(CONFIG)/fake_resolver_test: $(FAKE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fake_resolver_test: $(FAKE_RESOLVER_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) $(FAKE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fake_resolver_test + $(Q) $(LD) $(LDFLAGS) $(FAKE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fake_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/fake_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/fake_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fake_resolver_test: $(FAKE_RESOLVER_TEST_OBJS:.o=.dep) @@ -11506,16 +11483,16 @@ else -$(BINDIR)/$(CONFIG)/fake_transport_security_test: $(FAKE_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(BINDIR)/$(CONFIG)/fake_transport_security_test: $(FAKE_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FAKE_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fake_transport_security_test + $(Q) $(LD) $(LDFLAGS) $(FAKE_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fake_transport_security_test endif -$(OBJDIR)/$(CONFIG)/test/core/tsi/fake_transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/fake_transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a -$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test_lib.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test_lib.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_fake_transport_security_test: $(FAKE_TRANSPORT_SECURITY_TEST_OBJS:.o=.dep) @@ -11540,14 +11517,14 @@ else -$(BINDIR)/$(CONFIG)/fd_conservation_posix_test: $(FD_CONSERVATION_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fd_conservation_posix_test: $(FD_CONSERVATION_POSIX_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) $(FD_CONSERVATION_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fd_conservation_posix_test + $(Q) $(LD) $(LDFLAGS) $(FD_CONSERVATION_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fd_conservation_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/fd_conservation_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/fd_conservation_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fd_conservation_posix_test: $(FD_CONSERVATION_POSIX_TEST_OBJS:.o=.dep) @@ -11572,14 +11549,14 @@ else -$(BINDIR)/$(CONFIG)/fd_posix_test: $(FD_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fd_posix_test: $(FD_POSIX_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) $(FD_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fd_posix_test + $(Q) $(LD) $(LDFLAGS) $(FD_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fd_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/fd_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/fd_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fd_posix_test: $(FD_POSIX_TEST_OBJS:.o=.dep) @@ -11604,14 +11581,14 @@ else -$(BINDIR)/$(CONFIG)/fling_client: $(FLING_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fling_client: $(FLING_CLIENT_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) $(FLING_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_client + $(Q) $(LD) $(LDFLAGS) $(FLING_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_client endif -$(OBJDIR)/$(CONFIG)/test/core/fling/client.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/fling/client.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fling_client: $(FLING_CLIENT_OBJS:.o=.dep) @@ -11636,14 +11613,14 @@ else -$(BINDIR)/$(CONFIG)/fling_server: $(FLING_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fling_server: $(FLING_SERVER_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) $(FLING_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_server + $(Q) $(LD) $(LDFLAGS) $(FLING_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_server endif -$(OBJDIR)/$(CONFIG)/test/core/fling/server.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/fling/server.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fling_server: $(FLING_SERVER_OBJS:.o=.dep) @@ -11668,14 +11645,14 @@ else -$(BINDIR)/$(CONFIG)/fling_stream_test: $(FLING_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fling_stream_test: $(FLING_STREAM_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) $(FLING_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_stream_test + $(Q) $(LD) $(LDFLAGS) $(FLING_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_stream_test endif -$(OBJDIR)/$(CONFIG)/test/core/fling/fling_stream_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/fling/fling_stream_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fling_stream_test: $(FLING_STREAM_TEST_OBJS:.o=.dep) @@ -11700,14 +11677,14 @@ else -$(BINDIR)/$(CONFIG)/fling_test: $(FLING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fling_test: $(FLING_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) $(FLING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_test + $(Q) $(LD) $(LDFLAGS) $(FLING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_test endif -$(OBJDIR)/$(CONFIG)/test/core/fling/fling_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/fling/fling_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fling_test: $(FLING_TEST_OBJS:.o=.dep) @@ -11732,14 +11709,14 @@ else -$(BINDIR)/$(CONFIG)/fork_test: $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fork_test: $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fork_test + $(Q) $(LD) $(LDFLAGS) $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fork_test endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/fork_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/fork_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_fork_test: $(FORK_TEST_OBJS:.o=.dep) @@ -11764,14 +11741,14 @@ else -$(BINDIR)/$(CONFIG)/goaway_server_test: $(GOAWAY_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/goaway_server_test: $(GOAWAY_SERVER_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) $(GOAWAY_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/goaway_server_test + $(Q) $(LD) $(LDFLAGS) $(GOAWAY_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/goaway_server_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/goaway_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/goaway_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_goaway_server_test: $(GOAWAY_SERVER_TEST_OBJS:.o=.dep) @@ -11796,14 +11773,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_cpu_test: $(GPR_CPU_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_cpu_test: $(GPR_CPU_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_CPU_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_cpu_test + $(Q) $(LD) $(LDFLAGS) $(GPR_CPU_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_cpu_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/cpu_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/cpu_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_cpu_test: $(GPR_CPU_TEST_OBJS:.o=.dep) @@ -11828,14 +11805,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_env_test: $(GPR_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_env_test: $(GPR_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_env_test + $(Q) $(LD) $(LDFLAGS) $(GPR_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_env_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/env_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/env_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_env_test: $(GPR_ENV_TEST_OBJS:.o=.dep) @@ -11860,14 +11837,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_host_port_test + $(Q) $(LD) $(LDFLAGS) $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_host_port_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS:.o=.dep) @@ -11892,14 +11869,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_log_test: $(GPR_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_log_test: $(GPR_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_log_test + $(Q) $(LD) $(LDFLAGS) $(GPR_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_log_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/log_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/log_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_log_test: $(GPR_LOG_TEST_OBJS:.o=.dep) @@ -11924,14 +11901,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test + $(Q) $(LD) $(LDFLAGS) $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/manual_constructor_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/manual_constructor_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS:.o=.dep) @@ -11956,14 +11933,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_mpscq_test: $(GPR_MPSCQ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_mpscq_test: $(GPR_MPSCQ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_MPSCQ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_mpscq_test + $(Q) $(LD) $(LDFLAGS) $(GPR_MPSCQ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_mpscq_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/mpscq_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/mpscq_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_mpscq_test: $(GPR_MPSCQ_TEST_OBJS:.o=.dep) @@ -11988,14 +11965,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_spinlock_test: $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_spinlock_test: $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_spinlock_test + $(Q) $(LD) $(LDFLAGS) $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_spinlock_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/spinlock_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/spinlock_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_spinlock_test: $(GPR_SPINLOCK_TEST_OBJS:.o=.dep) @@ -12020,14 +11997,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_string_test: $(GPR_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_string_test: $(GPR_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_string_test + $(Q) $(LD) $(LDFLAGS) $(GPR_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_string_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/string_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/string_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_string_test: $(GPR_STRING_TEST_OBJS:.o=.dep) @@ -12052,14 +12029,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_sync_test: $(GPR_SYNC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_sync_test: $(GPR_SYNC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_SYNC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_sync_test + $(Q) $(LD) $(LDFLAGS) $(GPR_SYNC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_sync_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/sync_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/sync_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_sync_test: $(GPR_SYNC_TEST_OBJS:.o=.dep) @@ -12084,14 +12061,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_thd_test: $(GPR_THD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_thd_test: $(GPR_THD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_THD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_thd_test + $(Q) $(LD) $(LDFLAGS) $(GPR_THD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_thd_test endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/thd_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/thd_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_thd_test: $(GPR_THD_TEST_OBJS:.o=.dep) @@ -12116,14 +12093,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_time_test: $(GPR_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_time_test: $(GPR_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_time_test + $(Q) $(LD) $(LDFLAGS) $(GPR_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_time_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/time_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/time_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_time_test: $(GPR_TIME_TEST_OBJS:.o=.dep) @@ -12148,14 +12125,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_tls_test: $(GPR_TLS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_tls_test: $(GPR_TLS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_TLS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_tls_test + $(Q) $(LD) $(LDFLAGS) $(GPR_TLS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_tls_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/tls_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/tls_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_tls_test: $(GPR_TLS_TEST_OBJS:.o=.dep) @@ -12180,14 +12157,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_useful_test: $(GPR_USEFUL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_useful_test: $(GPR_USEFUL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_USEFUL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_useful_test + $(Q) $(LD) $(LDFLAGS) $(GPR_USEFUL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_useful_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/useful_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/useful_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_useful_test: $(GPR_USEFUL_TEST_OBJS:.o=.dep) @@ -12212,14 +12189,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_auth_context_test: $(GRPC_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_auth_context_test: $(GRPC_AUTH_CONTEXT_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) $(GRPC_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_auth_context_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_auth_context_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/auth_context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/auth_context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_auth_context_test: $(GRPC_AUTH_CONTEXT_TEST_OBJS:.o=.dep) @@ -12244,14 +12221,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_b64_test: $(GRPC_B64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_b64_test: $(GRPC_B64_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) $(GRPC_B64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_b64_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_B64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_b64_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/b64_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/b64_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_b64_test: $(GRPC_B64_TEST_OBJS:.o=.dep) @@ -12276,14 +12253,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test: $(GRPC_BYTE_BUFFER_READER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test: $(GRPC_BYTE_BUFFER_READER_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) $(GRPC_BYTE_BUFFER_READER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_BYTE_BUFFER_READER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/byte_buffer_reader_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/byte_buffer_reader_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_byte_buffer_reader_test: $(GRPC_BYTE_BUFFER_READER_TEST_OBJS:.o=.dep) @@ -12308,14 +12285,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_channel_args_test: $(GRPC_CHANNEL_ARGS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_channel_args_test: $(GRPC_CHANNEL_ARGS_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) $(GRPC_CHANNEL_ARGS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_args_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_ARGS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_args_test endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channel_args_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channel_args_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_channel_args_test: $(GRPC_CHANNEL_ARGS_TEST_OBJS:.o=.dep) @@ -12340,14 +12317,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_channel_stack_builder_test: $(GRPC_CHANNEL_STACK_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_channel_stack_builder_test: $(GRPC_CHANNEL_STACK_BUILDER_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) $(GRPC_CHANNEL_STACK_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_stack_builder_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_STACK_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_stack_builder_test endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channel_stack_builder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channel_stack_builder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_channel_stack_builder_test: $(GRPC_CHANNEL_STACK_BUILDER_TEST_OBJS:.o=.dep) @@ -12372,14 +12349,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_channel_stack_test: $(GRPC_CHANNEL_STACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_channel_stack_test: $(GRPC_CHANNEL_STACK_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) $(GRPC_CHANNEL_STACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_stack_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_STACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_stack_test endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channel_stack_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channel_stack_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_channel_stack_test: $(GRPC_CHANNEL_STACK_TEST_OBJS:.o=.dep) @@ -12404,14 +12381,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_completion_queue_test: $(GRPC_COMPLETION_QUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_completion_queue_test: $(GRPC_COMPLETION_QUEUE_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) $(GRPC_COMPLETION_QUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_completion_queue_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_COMPLETION_QUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_completion_queue_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/completion_queue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/completion_queue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_completion_queue_test: $(GRPC_COMPLETION_QUEUE_TEST_OBJS:.o=.dep) @@ -12436,14 +12413,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test: $(GRPC_COMPLETION_QUEUE_THREADING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test: $(GRPC_COMPLETION_QUEUE_THREADING_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) $(GRPC_COMPLETION_QUEUE_THREADING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_COMPLETION_QUEUE_THREADING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/completion_queue_threading_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/completion_queue_threading_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_completion_queue_threading_test: $(GRPC_COMPLETION_QUEUE_THREADING_TEST_OBJS:.o=.dep) @@ -12503,14 +12480,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_credentials_test: $(GRPC_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_credentials_test: $(GRPC_CREDENTIALS_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) $(GRPC_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_credentials_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_credentials_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/credentials_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/credentials_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_credentials_test: $(GRPC_CREDENTIALS_TEST_OBJS:.o=.dep) @@ -12535,14 +12512,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_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) $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 + $(Q) $(LD) $(LDFLAGS) $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 endif -$(OBJDIR)/$(CONFIG)/test/core/security/fetch_oauth2.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/fetch_oauth2.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS:.o=.dep) @@ -12567,14 +12544,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test: $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test: $(GRPC_IPV6_LOOPBACK_AVAILABLE_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) $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/grpc_ipv6_loopback_available_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/grpc_ipv6_loopback_available_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_ipv6_loopback_available_test: $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS:.o=.dep) @@ -12599,14 +12576,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_json_token_test: $(GRPC_JSON_TOKEN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_json_token_test: $(GRPC_JSON_TOKEN_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) $(GRPC_JSON_TOKEN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_json_token_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_JSON_TOKEN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_json_token_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/json_token_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/json_token_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_json_token_test: $(GRPC_JSON_TOKEN_TEST_OBJS:.o=.dep) @@ -12631,14 +12608,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test: $(GRPC_JWT_VERIFIER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test: $(GRPC_JWT_VERIFIER_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) $(GRPC_JWT_VERIFIER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_JWT_VERIFIER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/jwt_verifier_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/jwt_verifier_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_jwt_verifier_test: $(GRPC_JWT_VERIFIER_TEST_OBJS:.o=.dep) @@ -12698,14 +12675,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_security_connector_test: $(GRPC_SECURITY_CONNECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_security_connector_test: $(GRPC_SECURITY_CONNECTOR_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) $(GRPC_SECURITY_CONNECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_security_connector_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_SECURITY_CONNECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_security_connector_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/security_connector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/security_connector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_security_connector_test: $(GRPC_SECURITY_CONNECTOR_TEST_OBJS:.o=.dep) @@ -12730,14 +12707,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test: $(GRPC_SSL_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test: $(GRPC_SSL_CREDENTIALS_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) $(GRPC_SSL_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_SSL_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/ssl_credentials_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/ssl_credentials_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_ssl_credentials_test: $(GRPC_SSL_CREDENTIALS_TEST_OBJS:.o=.dep) @@ -12797,14 +12774,14 @@ else -$(BINDIR)/$(CONFIG)/handshake_client_ssl: $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/handshake_client_ssl: $(HANDSHAKE_CLIENT_SSL_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) $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_client_ssl + $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_client_ssl endif -$(OBJDIR)/$(CONFIG)/test/core/handshake/client_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/handshake/client_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_handshake_client_ssl: $(HANDSHAKE_CLIENT_SSL_OBJS:.o=.dep) @@ -12830,16 +12807,16 @@ else -$(BINDIR)/$(CONFIG)/handshake_server_ssl: $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/handshake_server_ssl: $(HANDSHAKE_SERVER_SSL_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) $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_ssl + $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_ssl endif -$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_handshake_server_ssl: $(HANDSHAKE_SERVER_SSL_OBJS:.o=.dep) @@ -12865,16 +12842,16 @@ else -$(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker: $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker: $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_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) $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker + $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker endif -$(OBJDIR)/$(CONFIG)/test/core/handshake/readahead_handshaker_server_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/handshake/readahead_handshaker_server_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_handshake_server_with_readahead_handshaker: $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS:.o=.dep) @@ -12899,14 +12876,14 @@ else -$(BINDIR)/$(CONFIG)/handshake_verify_peer_options: $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/handshake_verify_peer_options: $(HANDSHAKE_VERIFY_PEER_OPTIONS_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) $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_verify_peer_options + $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_verify_peer_options endif -$(OBJDIR)/$(CONFIG)/test/core/handshake/verify_peer_options.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/handshake/verify_peer_options.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_handshake_verify_peer_options: $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS:.o=.dep) @@ -12963,14 +12940,14 @@ else -$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test: $(HPACK_PARSER_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test: $(HPACK_PARSER_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HPACK_PARSER_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(HPACK_PARSER_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hpack_parser_fuzzer_test: $(HPACK_PARSER_FUZZER_TEST_OBJS:.o=.dep) @@ -12995,14 +12972,14 @@ else -$(BINDIR)/$(CONFIG)/hpack_parser_test: $(HPACK_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hpack_parser_test: $(HPACK_PARSER_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) $(HPACK_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_parser_test + $(Q) $(LD) $(LDFLAGS) $(HPACK_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_parser_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hpack_parser_test: $(HPACK_PARSER_TEST_OBJS:.o=.dep) @@ -13027,14 +13004,14 @@ else -$(BINDIR)/$(CONFIG)/hpack_table_test: $(HPACK_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hpack_table_test: $(HPACK_TABLE_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) $(HPACK_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_table_test + $(Q) $(LD) $(LDFLAGS) $(HPACK_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_table_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hpack_table_test: $(HPACK_TABLE_TEST_OBJS:.o=.dep) @@ -13059,14 +13036,14 @@ else -$(BINDIR)/$(CONFIG)/http_parser_test: $(HTTP_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_parser_test: $(HTTP_PARSER_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) $(HTTP_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_parser_test + $(Q) $(LD) $(LDFLAGS) $(HTTP_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_parser_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_parser_test: $(HTTP_PARSER_TEST_OBJS:.o=.dep) @@ -13091,14 +13068,14 @@ else -$(BINDIR)/$(CONFIG)/http_request_fuzzer_test: $(HTTP_REQUEST_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_request_fuzzer_test: $(HTTP_REQUEST_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HTTP_REQUEST_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/http_request_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(HTTP_REQUEST_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/http_request_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/request_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/request_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_request_fuzzer_test: $(HTTP_REQUEST_FUZZER_TEST_OBJS:.o=.dep) @@ -13123,14 +13100,14 @@ else -$(BINDIR)/$(CONFIG)/http_response_fuzzer_test: $(HTTP_RESPONSE_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_response_fuzzer_test: $(HTTP_RESPONSE_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HTTP_RESPONSE_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/http_response_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(HTTP_RESPONSE_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/http_response_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/response_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/response_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_response_fuzzer_test: $(HTTP_RESPONSE_FUZZER_TEST_OBJS:.o=.dep) @@ -13155,14 +13132,14 @@ else -$(BINDIR)/$(CONFIG)/httpcli_format_request_test: $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/httpcli_format_request_test: $(HTTPCLI_FORMAT_REQUEST_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) $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpcli_format_request_test + $(Q) $(LD) $(LDFLAGS) $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpcli_format_request_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/format_request_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/format_request_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_httpcli_format_request_test: $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS:.o=.dep) @@ -13187,14 +13164,14 @@ else -$(BINDIR)/$(CONFIG)/httpcli_test: $(HTTPCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/httpcli_test: $(HTTPCLI_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) $(HTTPCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpcli_test + $(Q) $(LD) $(LDFLAGS) $(HTTPCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpcli_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/httpcli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/httpcli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_httpcli_test: $(HTTPCLI_TEST_OBJS:.o=.dep) @@ -13219,14 +13196,14 @@ else -$(BINDIR)/$(CONFIG)/httpscli_test: $(HTTPSCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/httpscli_test: $(HTTPSCLI_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) $(HTTPSCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpscli_test + $(Q) $(LD) $(LDFLAGS) $(HTTPSCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpscli_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/httpscli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/httpscli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_httpscli_test: $(HTTPSCLI_TEST_OBJS:.o=.dep) @@ -13251,14 +13228,14 @@ else -$(BINDIR)/$(CONFIG)/init_test: $(INIT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/init_test: $(INIT_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) $(INIT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/init_test + $(Q) $(LD) $(LDFLAGS) $(INIT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/init_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/init_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/init_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_init_test: $(INIT_TEST_OBJS:.o=.dep) @@ -13283,14 +13260,14 @@ else -$(BINDIR)/$(CONFIG)/inproc_callback_test: $(INPROC_CALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/inproc_callback_test: $(INPROC_CALLBACK_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) $(INPROC_CALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/inproc_callback_test + $(Q) $(LD) $(LDFLAGS) $(INPROC_CALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/inproc_callback_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/inproc_callback_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/inproc_callback_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_inproc_callback_test: $(INPROC_CALLBACK_TEST_OBJS:.o=.dep) @@ -13315,14 +13292,14 @@ else -$(BINDIR)/$(CONFIG)/invalid_call_argument_test: $(INVALID_CALL_ARGUMENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/invalid_call_argument_test: $(INVALID_CALL_ARGUMENT_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) $(INVALID_CALL_ARGUMENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/invalid_call_argument_test + $(Q) $(LD) $(LDFLAGS) $(INVALID_CALL_ARGUMENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/invalid_call_argument_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/invalid_call_argument_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/invalid_call_argument_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_invalid_call_argument_test: $(INVALID_CALL_ARGUMENT_TEST_OBJS:.o=.dep) @@ -13347,14 +13324,14 @@ else -$(BINDIR)/$(CONFIG)/json_fuzzer_test: $(JSON_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_fuzzer_test: $(JSON_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(JSON_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/json_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(JSON_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/json_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/json/fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/json/fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_fuzzer_test: $(JSON_FUZZER_TEST_OBJS:.o=.dep) @@ -13379,14 +13356,14 @@ else -$(BINDIR)/$(CONFIG)/json_rewrite: $(JSON_REWRITE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_rewrite: $(JSON_REWRITE_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) $(JSON_REWRITE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_rewrite + $(Q) $(LD) $(LDFLAGS) $(JSON_REWRITE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_rewrite endif -$(OBJDIR)/$(CONFIG)/test/core/json/json_rewrite.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/json/json_rewrite.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_rewrite: $(JSON_REWRITE_OBJS:.o=.dep) @@ -13411,14 +13388,14 @@ else -$(BINDIR)/$(CONFIG)/json_rewrite_test: $(JSON_REWRITE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_rewrite_test: $(JSON_REWRITE_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) $(JSON_REWRITE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_rewrite_test + $(Q) $(LD) $(LDFLAGS) $(JSON_REWRITE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_rewrite_test endif -$(OBJDIR)/$(CONFIG)/test/core/json/json_rewrite_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/json/json_rewrite_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_rewrite_test: $(JSON_REWRITE_TEST_OBJS:.o=.dep) @@ -13443,14 +13420,14 @@ else -$(BINDIR)/$(CONFIG)/json_stream_error_test: $(JSON_STREAM_ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_stream_error_test: $(JSON_STREAM_ERROR_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) $(JSON_STREAM_ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_stream_error_test + $(Q) $(LD) $(LDFLAGS) $(JSON_STREAM_ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_stream_error_test endif -$(OBJDIR)/$(CONFIG)/test/core/json/json_stream_error_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/json/json_stream_error_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_stream_error_test: $(JSON_STREAM_ERROR_TEST_OBJS:.o=.dep) @@ -13475,14 +13452,14 @@ else -$(BINDIR)/$(CONFIG)/json_test: $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_test: $(JSON_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) $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_test + $(Q) $(LD) $(LDFLAGS) $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_test endif -$(OBJDIR)/$(CONFIG)/test/core/json/json_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/json/json_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_test: $(JSON_TEST_OBJS:.o=.dep) @@ -13507,14 +13484,14 @@ else -$(BINDIR)/$(CONFIG)/lame_client_test: $(LAME_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/lame_client_test: $(LAME_CLIENT_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) $(LAME_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/lame_client_test + $(Q) $(LD) $(LDFLAGS) $(LAME_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/lame_client_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/lame_client_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/lame_client_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_lame_client_test: $(LAME_CLIENT_TEST_OBJS:.o=.dep) @@ -13539,14 +13516,14 @@ else -$(BINDIR)/$(CONFIG)/load_file_test: $(LOAD_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/load_file_test: $(LOAD_FILE_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) $(LOAD_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/load_file_test + $(Q) $(LD) $(LDFLAGS) $(LOAD_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/load_file_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/load_file_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/load_file_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_load_file_test: $(LOAD_FILE_TEST_OBJS:.o=.dep) @@ -13571,14 +13548,14 @@ else -$(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark: $(LOW_LEVEL_PING_PONG_BENCHMARK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark: $(LOW_LEVEL_PING_PONG_BENCHMARK_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) $(LOW_LEVEL_PING_PONG_BENCHMARK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark + $(Q) $(LD) $(LDFLAGS) $(LOW_LEVEL_PING_PONG_BENCHMARK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark endif -$(OBJDIR)/$(CONFIG)/test/core/network_benchmarks/low_level_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/network_benchmarks/low_level_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_low_level_ping_pong_benchmark: $(LOW_LEVEL_PING_PONG_BENCHMARK_OBJS:.o=.dep) @@ -13603,14 +13580,14 @@ else -$(BINDIR)/$(CONFIG)/memory_usage_client: $(MEMORY_USAGE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/memory_usage_client: $(MEMORY_USAGE_CLIENT_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) $(MEMORY_USAGE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_client + $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_client endif -$(OBJDIR)/$(CONFIG)/test/core/memory_usage/client.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/memory_usage/client.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_memory_usage_client: $(MEMORY_USAGE_CLIENT_OBJS:.o=.dep) @@ -13635,14 +13612,14 @@ else -$(BINDIR)/$(CONFIG)/memory_usage_server: $(MEMORY_USAGE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/memory_usage_server: $(MEMORY_USAGE_SERVER_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) $(MEMORY_USAGE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_server + $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_server endif -$(OBJDIR)/$(CONFIG)/test/core/memory_usage/server.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/memory_usage/server.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_memory_usage_server: $(MEMORY_USAGE_SERVER_OBJS:.o=.dep) @@ -13667,14 +13644,14 @@ else -$(BINDIR)/$(CONFIG)/memory_usage_test: $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/memory_usage_test: $(MEMORY_USAGE_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) $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_test + $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_test endif -$(OBJDIR)/$(CONFIG)/test/core/memory_usage/memory_usage_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/memory_usage/memory_usage_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_memory_usage_test: $(MEMORY_USAGE_TEST_OBJS:.o=.dep) @@ -13699,14 +13676,14 @@ else -$(BINDIR)/$(CONFIG)/message_compress_test: $(MESSAGE_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/message_compress_test: $(MESSAGE_COMPRESS_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) $(MESSAGE_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/message_compress_test + $(Q) $(LD) $(LDFLAGS) $(MESSAGE_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/message_compress_test endif -$(OBJDIR)/$(CONFIG)/test/core/compression/message_compress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/compression/message_compress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_message_compress_test: $(MESSAGE_COMPRESS_TEST_OBJS:.o=.dep) @@ -13731,14 +13708,14 @@ else -$(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test: $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test: $(MINIMAL_STACK_IS_MINIMAL_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) $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test + $(Q) $(LD) $(LDFLAGS) $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test endif -$(OBJDIR)/$(CONFIG)/test/core/channel/minimal_stack_is_minimal_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/minimal_stack_is_minimal_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_minimal_stack_is_minimal_test: $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS:.o=.dep) @@ -13763,14 +13740,14 @@ else -$(BINDIR)/$(CONFIG)/multiple_server_queues_test: $(MULTIPLE_SERVER_QUEUES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/multiple_server_queues_test: $(MULTIPLE_SERVER_QUEUES_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) $(MULTIPLE_SERVER_QUEUES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/multiple_server_queues_test + $(Q) $(LD) $(LDFLAGS) $(MULTIPLE_SERVER_QUEUES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/multiple_server_queues_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/multiple_server_queues_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/multiple_server_queues_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_multiple_server_queues_test: $(MULTIPLE_SERVER_QUEUES_TEST_OBJS:.o=.dep) @@ -13795,14 +13772,14 @@ else -$(BINDIR)/$(CONFIG)/murmur_hash_test: $(MURMUR_HASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/murmur_hash_test: $(MURMUR_HASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MURMUR_HASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/murmur_hash_test + $(Q) $(LD) $(LDFLAGS) $(MURMUR_HASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/murmur_hash_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/murmur_hash_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/murmur_hash_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_murmur_hash_test: $(MURMUR_HASH_TEST_OBJS:.o=.dep) @@ -13827,14 +13804,14 @@ else -$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test: $(NANOPB_FUZZER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test: $(NANOPB_FUZZER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test + $(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test endif -$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_response.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_response.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nanopb_fuzzer_response_test: $(NANOPB_FUZZER_RESPONSE_TEST_OBJS:.o=.dep) @@ -13859,14 +13836,14 @@ else -$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test: $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test: $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test + $(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test endif -$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_serverlist.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_serverlist.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nanopb_fuzzer_serverlist_test: $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS:.o=.dep) @@ -13891,14 +13868,14 @@ else -$(BINDIR)/$(CONFIG)/no_server_test: $(NO_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/no_server_test: $(NO_SERVER_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) $(NO_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/no_server_test + $(Q) $(LD) $(LDFLAGS) $(NO_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/no_server_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/no_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/no_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_no_server_test: $(NO_SERVER_TEST_OBJS:.o=.dep) @@ -13923,14 +13900,14 @@ else -$(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test: $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test: $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_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) $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test + $(Q) $(LD) $(LDFLAGS) $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/num_external_connectivity_watchers_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/num_external_connectivity_watchers_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_num_external_connectivity_watchers_test: $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_TEST_OBJS:.o=.dep) @@ -13955,14 +13932,14 @@ else -$(BINDIR)/$(CONFIG)/parse_address_test: $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/parse_address_test: $(PARSE_ADDRESS_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) $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/parse_address_test + $(Q) $(LD) $(LDFLAGS) $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/parse_address_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/parse_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/parse_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_parse_address_test: $(PARSE_ADDRESS_TEST_OBJS:.o=.dep) @@ -13987,14 +13964,14 @@ else -$(BINDIR)/$(CONFIG)/percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS:.o=.dep) @@ -14019,14 +13996,14 @@ else -$(BINDIR)/$(CONFIG)/percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS:.o=.dep) @@ -14051,14 +14028,14 @@ else -$(BINDIR)/$(CONFIG)/percent_encoding_test: $(PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_encoding_test: $(PERCENT_ENCODING_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) $(PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_encoding_test + $(Q) $(LD) $(LDFLAGS) $(PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_encoding_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_encoding_test: $(PERCENT_ENCODING_TEST_OBJS:.o=.dep) @@ -14083,14 +14060,14 @@ else -$(BINDIR)/$(CONFIG)/resolve_address_posix_test: $(RESOLVE_ADDRESS_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resolve_address_posix_test: $(RESOLVE_ADDRESS_POSIX_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) $(RESOLVE_ADDRESS_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_posix_test + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_resolve_address_posix_test: $(RESOLVE_ADDRESS_POSIX_TEST_OBJS:.o=.dep) @@ -14115,14 +14092,14 @@ else -$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_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) $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_resolve_address_using_ares_resolver_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS:.o=.dep) @@ -14147,14 +14124,14 @@ else -$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_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) $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_resolve_address_using_native_resolver_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS:.o=.dep) @@ -14179,14 +14156,14 @@ else -$(BINDIR)/$(CONFIG)/resource_quota_test: $(RESOURCE_QUOTA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resource_quota_test: $(RESOURCE_QUOTA_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) $(RESOURCE_QUOTA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resource_quota_test + $(Q) $(LD) $(LDFLAGS) $(RESOURCE_QUOTA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resource_quota_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/resource_quota_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/resource_quota_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_resource_quota_test: $(RESOURCE_QUOTA_TEST_OBJS:.o=.dep) @@ -14211,14 +14188,14 @@ else -$(BINDIR)/$(CONFIG)/secure_channel_create_test: $(SECURE_CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/secure_channel_create_test: $(SECURE_CHANNEL_CREATE_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) $(SECURE_CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/secure_channel_create_test + $(Q) $(LD) $(LDFLAGS) $(SECURE_CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/secure_channel_create_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/secure_channel_create_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/secure_channel_create_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_secure_channel_create_test: $(SECURE_CHANNEL_CREATE_TEST_OBJS:.o=.dep) @@ -14243,14 +14220,14 @@ else -$(BINDIR)/$(CONFIG)/secure_endpoint_test: $(SECURE_ENDPOINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/secure_endpoint_test: $(SECURE_ENDPOINT_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) $(SECURE_ENDPOINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/secure_endpoint_test + $(Q) $(LD) $(LDFLAGS) $(SECURE_ENDPOINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/secure_endpoint_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/secure_endpoint_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/secure_endpoint_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_secure_endpoint_test: $(SECURE_ENDPOINT_TEST_OBJS:.o=.dep) @@ -14275,14 +14252,14 @@ else -$(BINDIR)/$(CONFIG)/sequential_connectivity_test: $(SEQUENTIAL_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/sequential_connectivity_test: $(SEQUENTIAL_CONNECTIVITY_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) $(SEQUENTIAL_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sequential_connectivity_test + $(Q) $(LD) $(LDFLAGS) $(SEQUENTIAL_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sequential_connectivity_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/sequential_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/sequential_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_sequential_connectivity_test: $(SEQUENTIAL_CONNECTIVITY_TEST_OBJS:.o=.dep) @@ -14307,14 +14284,14 @@ else -$(BINDIR)/$(CONFIG)/server_chttp2_test: $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_chttp2_test: $(SERVER_CHTTP2_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) $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_chttp2_test + $(Q) $(LD) $(LDFLAGS) $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_chttp2_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/server_chttp2_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/server_chttp2_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_chttp2_test: $(SERVER_CHTTP2_TEST_OBJS:.o=.dep) @@ -14339,14 +14316,14 @@ else -$(BINDIR)/$(CONFIG)/server_fuzzer: $(SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_fuzzer: $(SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/server_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/server_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_fuzzer: $(SERVER_FUZZER_OBJS:.o=.dep) @@ -14371,14 +14348,14 @@ else -$(BINDIR)/$(CONFIG)/server_test: $(SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_test: $(SERVER_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) $(SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_test + $(Q) $(LD) $(LDFLAGS) $(SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/surface/server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_test: $(SERVER_TEST_OBJS:.o=.dep) @@ -14403,14 +14380,14 @@ else -$(BINDIR)/$(CONFIG)/slice_buffer_test: $(SLICE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_buffer_test: $(SLICE_BUFFER_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) $(SLICE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_buffer_test + $(Q) $(LD) $(LDFLAGS) $(SLICE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_buffer_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_buffer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/slice_buffer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_buffer_test: $(SLICE_BUFFER_TEST_OBJS:.o=.dep) @@ -14435,14 +14412,14 @@ else -$(BINDIR)/$(CONFIG)/slice_string_helpers_test: $(SLICE_STRING_HELPERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_string_helpers_test: $(SLICE_STRING_HELPERS_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) $(SLICE_STRING_HELPERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_string_helpers_test + $(Q) $(LD) $(LDFLAGS) $(SLICE_STRING_HELPERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_string_helpers_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_string_helpers_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/slice_string_helpers_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_string_helpers_test: $(SLICE_STRING_HELPERS_TEST_OBJS:.o=.dep) @@ -14467,14 +14444,14 @@ else -$(BINDIR)/$(CONFIG)/slice_test: $(SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_test: $(SLICE_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) $(SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_test + $(Q) $(LD) $(LDFLAGS) $(SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_test: $(SLICE_TEST_OBJS:.o=.dep) @@ -14499,14 +14476,14 @@ else -$(BINDIR)/$(CONFIG)/sockaddr_resolver_test: $(SOCKADDR_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/sockaddr_resolver_test: $(SOCKADDR_RESOLVER_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) $(SOCKADDR_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sockaddr_resolver_test + $(Q) $(LD) $(LDFLAGS) $(SOCKADDR_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sockaddr_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/sockaddr_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/sockaddr_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_sockaddr_resolver_test: $(SOCKADDR_RESOLVER_TEST_OBJS:.o=.dep) @@ -14531,14 +14508,14 @@ else -$(BINDIR)/$(CONFIG)/sockaddr_utils_test: $(SOCKADDR_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/sockaddr_utils_test: $(SOCKADDR_UTILS_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) $(SOCKADDR_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sockaddr_utils_test + $(Q) $(LD) $(LDFLAGS) $(SOCKADDR_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sockaddr_utils_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/sockaddr_utils_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/sockaddr_utils_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_sockaddr_utils_test: $(SOCKADDR_UTILS_TEST_OBJS:.o=.dep) @@ -14563,14 +14540,14 @@ else -$(BINDIR)/$(CONFIG)/socket_utils_test: $(SOCKET_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/socket_utils_test: $(SOCKET_UTILS_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) $(SOCKET_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/socket_utils_test + $(Q) $(LD) $(LDFLAGS) $(SOCKET_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/socket_utils_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/socket_utils_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/socket_utils_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_socket_utils_test: $(SOCKET_UTILS_TEST_OBJS:.o=.dep) @@ -14595,14 +14572,14 @@ else -$(BINDIR)/$(CONFIG)/ssl_server_fuzzer: $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ssl_server_fuzzer: $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/ssl_server_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/ssl_server_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ssl_server_fuzzer: $(SSL_SERVER_FUZZER_OBJS:.o=.dep) @@ -14628,16 +14605,16 @@ else -$(BINDIR)/$(CONFIG)/ssl_transport_security_test: $(SSL_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(BINDIR)/$(CONFIG)/ssl_transport_security_test: $(SSL_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SSL_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ssl_transport_security_test + $(Q) $(LD) $(LDFLAGS) $(SSL_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ssl_transport_security_test endif -$(OBJDIR)/$(CONFIG)/test/core/tsi/ssl_transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/ssl_transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a -$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test_lib.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test_lib.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_ssl_transport_security_test: $(SSL_TRANSPORT_SECURITY_TEST_OBJS:.o=.dep) @@ -14662,14 +14639,14 @@ else -$(BINDIR)/$(CONFIG)/status_conversion_test: $(STATUS_CONVERSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/status_conversion_test: $(STATUS_CONVERSION_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) $(STATUS_CONVERSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/status_conversion_test + $(Q) $(LD) $(LDFLAGS) $(STATUS_CONVERSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/status_conversion_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/status_conversion_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/status_conversion_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_status_conversion_test: $(STATUS_CONVERSION_TEST_OBJS:.o=.dep) @@ -14694,14 +14671,14 @@ else -$(BINDIR)/$(CONFIG)/stream_compression_test: $(STREAM_COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/stream_compression_test: $(STREAM_COMPRESSION_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) $(STREAM_COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/stream_compression_test + $(Q) $(LD) $(LDFLAGS) $(STREAM_COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/stream_compression_test endif -$(OBJDIR)/$(CONFIG)/test/core/compression/stream_compression_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/compression/stream_compression_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_stream_compression_test: $(STREAM_COMPRESSION_TEST_OBJS:.o=.dep) @@ -14726,14 +14703,14 @@ else -$(BINDIR)/$(CONFIG)/stream_owned_slice_test: $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/stream_owned_slice_test: $(STREAM_OWNED_SLICE_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) $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/stream_owned_slice_test + $(Q) $(LD) $(LDFLAGS) $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/stream_owned_slice_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/stream_owned_slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/stream_owned_slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_stream_owned_slice_test: $(STREAM_OWNED_SLICE_TEST_OBJS:.o=.dep) @@ -14758,14 +14735,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_client_posix_test: $(TCP_CLIENT_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_client_posix_test: $(TCP_CLIENT_POSIX_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) $(TCP_CLIENT_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_client_posix_test + $(Q) $(LD) $(LDFLAGS) $(TCP_CLIENT_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_client_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_client_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_client_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_client_posix_test: $(TCP_CLIENT_POSIX_TEST_OBJS:.o=.dep) @@ -14790,14 +14767,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_client_uv_test: $(TCP_CLIENT_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_client_uv_test: $(TCP_CLIENT_UV_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) $(TCP_CLIENT_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_client_uv_test + $(Q) $(LD) $(LDFLAGS) $(TCP_CLIENT_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_client_uv_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_client_uv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_client_uv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_client_uv_test: $(TCP_CLIENT_UV_TEST_OBJS:.o=.dep) @@ -14822,14 +14799,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_posix_test: $(TCP_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_posix_test: $(TCP_POSIX_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) $(TCP_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_posix_test + $(Q) $(LD) $(LDFLAGS) $(TCP_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_posix_test: $(TCP_POSIX_TEST_OBJS:.o=.dep) @@ -14854,14 +14831,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_server_posix_test: $(TCP_SERVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_server_posix_test: $(TCP_SERVER_POSIX_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) $(TCP_SERVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_server_posix_test + $(Q) $(LD) $(LDFLAGS) $(TCP_SERVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_server_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_server_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_server_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_server_posix_test: $(TCP_SERVER_POSIX_TEST_OBJS:.o=.dep) @@ -14886,14 +14863,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_server_uv_test: $(TCP_SERVER_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_server_uv_test: $(TCP_SERVER_UV_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) $(TCP_SERVER_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_server_uv_test + $(Q) $(LD) $(LDFLAGS) $(TCP_SERVER_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_server_uv_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_server_uv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_server_uv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_server_uv_test: $(TCP_SERVER_UV_TEST_OBJS:.o=.dep) @@ -14918,14 +14895,14 @@ else -$(BINDIR)/$(CONFIG)/time_averaged_stats_test: $(TIME_AVERAGED_STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/time_averaged_stats_test: $(TIME_AVERAGED_STATS_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) $(TIME_AVERAGED_STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/time_averaged_stats_test + $(Q) $(LD) $(LDFLAGS) $(TIME_AVERAGED_STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/time_averaged_stats_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/time_averaged_stats_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/time_averaged_stats_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_time_averaged_stats_test: $(TIME_AVERAGED_STATS_TEST_OBJS:.o=.dep) @@ -14950,14 +14927,14 @@ else -$(BINDIR)/$(CONFIG)/timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/timeout_encoding_test: $(TIMEOUT_ENCODING_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) $(TIMEOUT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timeout_encoding_test + $(Q) $(LD) $(LDFLAGS) $(TIMEOUT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timeout_encoding_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/timeout_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/timeout_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS:.o=.dep) @@ -14982,14 +14959,14 @@ else -$(BINDIR)/$(CONFIG)/timer_heap_test: $(TIMER_HEAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/timer_heap_test: $(TIMER_HEAP_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) $(TIMER_HEAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timer_heap_test + $(Q) $(LD) $(LDFLAGS) $(TIMER_HEAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timer_heap_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_heap_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_heap_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_timer_heap_test: $(TIMER_HEAP_TEST_OBJS:.o=.dep) @@ -15014,14 +14991,14 @@ else -$(BINDIR)/$(CONFIG)/timer_list_test: $(TIMER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/timer_list_test: $(TIMER_LIST_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) $(TIMER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timer_list_test + $(Q) $(LD) $(LDFLAGS) $(TIMER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timer_list_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_timer_list_test: $(TIMER_LIST_TEST_OBJS:.o=.dep) @@ -15046,14 +15023,14 @@ else -$(BINDIR)/$(CONFIG)/transport_connectivity_state_test: $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/transport_connectivity_state_test: $(TRANSPORT_CONNECTIVITY_STATE_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) $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_connectivity_state_test + $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_connectivity_state_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/connectivity_state_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/connectivity_state_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_transport_connectivity_state_test: $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS:.o=.dep) @@ -15078,14 +15055,14 @@ else -$(BINDIR)/$(CONFIG)/transport_metadata_test: $(TRANSPORT_METADATA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/transport_metadata_test: $(TRANSPORT_METADATA_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) $(TRANSPORT_METADATA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_metadata_test + $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_METADATA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_metadata_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/metadata_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/metadata_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_transport_metadata_test: $(TRANSPORT_METADATA_TEST_OBJS:.o=.dep) @@ -15110,14 +15087,14 @@ else -$(BINDIR)/$(CONFIG)/transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/transport_security_test: $(TRANSPORT_SECURITY_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) $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_security_test + $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_security_test endif -$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS:.o=.dep) @@ -15142,14 +15119,14 @@ else -$(BINDIR)/$(CONFIG)/udp_server_test: $(UDP_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/udp_server_test: $(UDP_SERVER_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) $(UDP_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/udp_server_test + $(Q) $(LD) $(LDFLAGS) $(UDP_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/udp_server_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/udp_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/iomgr/udp_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_udp_server_test: $(UDP_SERVER_TEST_OBJS:.o=.dep) @@ -15174,14 +15151,14 @@ else -$(BINDIR)/$(CONFIG)/uri_fuzzer_test: $(URI_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/uri_fuzzer_test: $(URI_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(URI_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/uri_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(URI_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/uri_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_uri_fuzzer_test: $(URI_FUZZER_TEST_OBJS:.o=.dep) @@ -15206,14 +15183,14 @@ else -$(BINDIR)/$(CONFIG)/uri_parser_test: $(URI_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/uri_parser_test: $(URI_PARSER_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) $(URI_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/uri_parser_test + $(Q) $(LD) $(LDFLAGS) $(URI_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/uri_parser_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_uri_parser_test: $(URI_PARSER_TEST_OBJS:.o=.dep) @@ -15238,14 +15215,14 @@ 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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test + $(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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(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) @@ -15279,16 +15256,16 @@ $(BINDIR)/$(CONFIG)/alarm_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/alarm_test: $(PROTOBUF_DEP) $(ALARM_TEST_OBJS) $(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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/alarm_test: $(PROTOBUF_DEP) $(ALARM_TEST_OBJS) $(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 $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ALARM_TEST_OBJS) $(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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alarm_test + $(Q) $(LDXX) $(LDFLAGS) $(ALARM_TEST_OBJS) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alarm_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/common/alarm_test.o: $(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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/common/alarm_test.o: $(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 deps_alarm_test: $(ALARM_TEST_OBJS:.o=.dep) @@ -15365,16 +15342,16 @@ $(BINDIR)/$(CONFIG)/alts_crypt_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/alts_crypt_test: $(PROTOBUF_DEP) $(ALTS_CRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(BINDIR)/$(CONFIG)/alts_crypt_test: $(PROTOBUF_DEP) $(ALTS_CRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ALTS_CRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alts_crypt_test + $(Q) $(LDXX) $(LDFLAGS) $(ALTS_CRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alts_crypt_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/tsi/alts/crypt/aes_gcm_test.o: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/alts/crypt/aes_gcm_test.o: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_alts_crypt_test: $(ALTS_CRYPT_TEST_OBJS:.o=.dep) @@ -15884,16 +15861,16 @@ $(BINDIR)/$(CONFIG)/async_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/async_end2end_test: $(PROTOBUF_DEP) $(ASYNC_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/async_end2end_test: $(PROTOBUF_DEP) $(ASYNC_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) $(ASYNC_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/async_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(ASYNC_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)/async_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/async_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/async_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_async_end2end_test: $(ASYNC_END2END_TEST_OBJS:.o=.dep) @@ -15927,16 +15904,16 @@ $(BINDIR)/$(CONFIG)/auth_property_iterator_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/auth_property_iterator_test: $(PROTOBUF_DEP) $(AUTH_PROPERTY_ITERATOR_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/auth_property_iterator_test: $(PROTOBUF_DEP) $(AUTH_PROPERTY_ITERATOR_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) $(AUTH_PROPERTY_ITERATOR_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/auth_property_iterator_test + $(Q) $(LDXX) $(LDFLAGS) $(AUTH_PROPERTY_ITERATOR_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)/auth_property_iterator_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/common/auth_property_iterator_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/common/auth_property_iterator_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_auth_property_iterator_test: $(AUTH_PROPERTY_ITERATOR_TEST_OBJS:.o=.dep) @@ -15970,16 +15947,16 @@ $(BINDIR)/$(CONFIG)/backoff_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/backoff_test: $(PROTOBUF_DEP) $(BACKOFF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/backoff_test: $(PROTOBUF_DEP) $(BACKOFF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BACKOFF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/backoff_test + $(Q) $(LDXX) $(LDFLAGS) $(BACKOFF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/backoff_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/backoff/backoff_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/backoff/backoff_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_backoff_test: $(BACKOFF_TEST_OBJS:.o=.dep) @@ -16013,16 +15990,16 @@ $(BINDIR)/$(CONFIG)/bdp_estimator_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bdp_estimator_test: $(PROTOBUF_DEP) $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bdp_estimator_test: $(PROTOBUF_DEP) $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bdp_estimator_test + $(Q) $(LDXX) $(LDFLAGS) $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bdp_estimator_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/bdp_estimator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/bdp_estimator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bdp_estimator_test: $(BDP_ESTIMATOR_TEST_OBJS:.o=.dep) @@ -16056,17 +16033,17 @@ $(BINDIR)/$(CONFIG)/bm_arena: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_arena: $(PROTOBUF_DEP) $(BM_ARENA_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_arena: $(PROTOBUF_DEP) $(BM_ARENA_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_ARENA_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_arena + $(Q) $(LDXX) $(LDFLAGS) $(BM_ARENA_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_arena endif endif $(BM_ARENA_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_arena.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_arena.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_arena: $(BM_ARENA_OBJS:.o=.dep) @@ -16100,17 +16077,17 @@ $(BINDIR)/$(CONFIG)/bm_call_create: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_call_create: $(PROTOBUF_DEP) $(BM_CALL_CREATE_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_call_create: $(PROTOBUF_DEP) $(BM_CALL_CREATE_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_CALL_CREATE_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_call_create + $(Q) $(LDXX) $(LDFLAGS) $(BM_CALL_CREATE_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_call_create endif endif $(BM_CALL_CREATE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_call_create.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_call_create.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_call_create: $(BM_CALL_CREATE_OBJS:.o=.dep) @@ -16144,17 +16121,17 @@ $(BINDIR)/$(CONFIG)/bm_channel: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_channel: $(PROTOBUF_DEP) $(BM_CHANNEL_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_channel: $(PROTOBUF_DEP) $(BM_CHANNEL_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_CHANNEL_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_channel + $(Q) $(LDXX) $(LDFLAGS) $(BM_CHANNEL_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_channel endif endif $(BM_CHANNEL_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_channel.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_channel.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_channel: $(BM_CHANNEL_OBJS:.o=.dep) @@ -16188,17 +16165,17 @@ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: $(PROTOBUF_DEP) $(BM_CHTTP2_HPACK_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_chttp2_hpack: $(PROTOBUF_DEP) $(BM_CHTTP2_HPACK_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_CHTTP2_HPACK_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_hpack + $(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_HPACK_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_chttp2_hpack endif endif $(BM_CHTTP2_HPACK_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_hpack.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_hpack.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_chttp2_hpack: $(BM_CHTTP2_HPACK_OBJS:.o=.dep) @@ -16232,17 +16209,17 @@ $(BINDIR)/$(CONFIG)/bm_chttp2_transport: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_chttp2_transport: $(PROTOBUF_DEP) $(BM_CHTTP2_TRANSPORT_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_chttp2_transport: $(PROTOBUF_DEP) $(BM_CHTTP2_TRANSPORT_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_CHTTP2_TRANSPORT_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_chttp2_transport + $(Q) $(LDXX) $(LDFLAGS) $(BM_CHTTP2_TRANSPORT_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_chttp2_transport endif endif $(BM_CHTTP2_TRANSPORT_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_transport.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_chttp2_transport.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_chttp2_transport: $(BM_CHTTP2_TRANSPORT_OBJS:.o=.dep) @@ -16276,17 +16253,17 @@ $(BINDIR)/$(CONFIG)/bm_closure: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_closure: $(PROTOBUF_DEP) $(BM_CLOSURE_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_closure: $(PROTOBUF_DEP) $(BM_CLOSURE_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_CLOSURE_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_closure + $(Q) $(LDXX) $(LDFLAGS) $(BM_CLOSURE_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_closure endif endif $(BM_CLOSURE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_closure.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_closure.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_closure: $(BM_CLOSURE_OBJS:.o=.dep) @@ -16320,17 +16297,17 @@ $(BINDIR)/$(CONFIG)/bm_cq: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_cq: $(PROTOBUF_DEP) $(BM_CQ_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_cq: $(PROTOBUF_DEP) $(BM_CQ_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_CQ_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq + $(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_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_cq endif endif $(BM_CQ_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq.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_cq: $(BM_CQ_OBJS:.o=.dep) @@ -16364,17 +16341,17 @@ $(BINDIR)/$(CONFIG)/bm_cq_multiple_threads: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_cq_multiple_threads: $(PROTOBUF_DEP) $(BM_CQ_MULTIPLE_THREADS_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_cq_multiple_threads: $(PROTOBUF_DEP) $(BM_CQ_MULTIPLE_THREADS_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_CQ_MULTIPLE_THREADS_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_cq_multiple_threads + $(Q) $(LDXX) $(LDFLAGS) $(BM_CQ_MULTIPLE_THREADS_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_cq_multiple_threads endif endif $(BM_CQ_MULTIPLE_THREADS_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq_multiple_threads.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_cq_multiple_threads.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_cq_multiple_threads: $(BM_CQ_MULTIPLE_THREADS_OBJS:.o=.dep) @@ -16408,17 +16385,17 @@ $(BINDIR)/$(CONFIG)/bm_error: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_error: $(PROTOBUF_DEP) $(BM_ERROR_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_error: $(PROTOBUF_DEP) $(BM_ERROR_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_ERROR_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_error + $(Q) $(LDXX) $(LDFLAGS) $(BM_ERROR_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_error endif endif $(BM_ERROR_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_error.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_error.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_error: $(BM_ERROR_OBJS:.o=.dep) @@ -16452,17 +16429,17 @@ $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PING_PONG_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PING_PONG_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_FULLSTACK_STREAMING_PING_PONG_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong + $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PING_PONG_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_fullstack_streaming_ping_pong endif endif $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.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_fullstack_streaming_ping_pong: $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS:.o=.dep) @@ -16496,17 +16473,17 @@ $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PUMP_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump: $(PROTOBUF_DEP) $(BM_FULLSTACK_STREAMING_PUMP_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_FULLSTACK_STREAMING_PUMP_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_pump + $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_STREAMING_PUMP_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_fullstack_streaming_pump endif endif $(BM_FULLSTACK_STREAMING_PUMP_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.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_fullstack_streaming_pump: $(BM_FULLSTACK_STREAMING_PUMP_OBJS:.o=.dep) @@ -16540,17 +16517,17 @@ $(BINDIR)/$(CONFIG)/bm_fullstack_trickle: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: $(PROTOBUF_DEP) $(BM_FULLSTACK_TRICKLE_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: $(PROTOBUF_DEP) $(BM_FULLSTACK_TRICKLE_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_FULLSTACK_TRICKLE_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_trickle + $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_TRICKLE_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_fullstack_trickle endif endif $(BM_FULLSTACK_TRICKLE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_trickle.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_trickle.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_fullstack_trickle: $(BM_FULLSTACK_TRICKLE_OBJS:.o=.dep) @@ -16584,17 +16561,17 @@ $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_UNARY_PING_PONG_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong: $(PROTOBUF_DEP) $(BM_FULLSTACK_UNARY_PING_PONG_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_FULLSTACK_UNARY_PING_PONG_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong + $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_UNARY_PING_PONG_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_fullstack_unary_ping_pong endif endif $(BM_FULLSTACK_UNARY_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.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_fullstack_unary_ping_pong: $(BM_FULLSTACK_UNARY_PING_PONG_OBJS:.o=.dep) @@ -16628,17 +16605,17 @@ $(BINDIR)/$(CONFIG)/bm_metadata: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_metadata: $(PROTOBUF_DEP) $(BM_METADATA_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_METADATA_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_metadata + $(Q) $(LDXX) $(LDFLAGS) $(BM_METADATA_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_metadata endif endif $(BM_METADATA_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_metadata.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_metadata: $(BM_METADATA_OBJS:.o=.dep) @@ -16672,17 +16649,17 @@ $(BINDIR)/$(CONFIG)/bm_pollset: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_pollset: $(PROTOBUF_DEP) $(BM_POLLSET_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_pollset: $(PROTOBUF_DEP) $(BM_POLLSET_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_POLLSET_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_pollset + $(Q) $(LDXX) $(LDFLAGS) $(BM_POLLSET_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_pollset endif endif $(BM_POLLSET_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_pollset.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_pollset.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_pollset: $(BM_POLLSET_OBJS:.o=.dep) @@ -16716,16 +16693,16 @@ $(BINDIR)/$(CONFIG)/byte_stream_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/byte_stream_test: $(PROTOBUF_DEP) $(BYTE_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/byte_stream_test: $(PROTOBUF_DEP) $(BYTE_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BYTE_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/byte_stream_test + $(Q) $(LDXX) $(LDFLAGS) $(BYTE_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/byte_stream_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/byte_stream_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/byte_stream_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_byte_stream_test: $(BYTE_STREAM_TEST_OBJS:.o=.dep) @@ -16846,18 +16823,18 @@ $(BINDIR)/$(CONFIG)/channel_trace_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/channel_trace_test: $(PROTOBUF_DEP) $(CHANNEL_TRACE_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channel_trace_test: $(PROTOBUF_DEP) $(CHANNEL_TRACE_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) $(CHANNEL_TRACE_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channel_trace_test + $(Q) $(LDXX) $(LDFLAGS) $(CHANNEL_TRACE_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)/channel_trace_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channel_trace_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channel_trace_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)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.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_channel_trace_test: $(CHANNEL_TRACE_TEST_OBJS:.o=.dep) @@ -16892,16 +16869,16 @@ $(BINDIR)/$(CONFIG)/channelz_registry_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/channelz_registry_test: $(PROTOBUF_DEP) $(CHANNELZ_REGISTRY_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channelz_registry_test: $(PROTOBUF_DEP) $(CHANNELZ_REGISTRY_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) $(CHANNELZ_REGISTRY_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_registry_test + $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_REGISTRY_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)/channelz_registry_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channelz_registry_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channelz_registry_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_channelz_registry_test: $(CHANNELZ_REGISTRY_TEST_OBJS:.o=.dep) @@ -16936,18 +16913,18 @@ $(BINDIR)/$(CONFIG)/channelz_service_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/channelz_service_test: $(PROTOBUF_DEP) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channelz_service_test: $(PROTOBUF_DEP) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(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) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_service_test + $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(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)/channelz_service_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/channelz_service_test.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/channelz_service_test.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(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)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(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_channelz_service_test: $(CHANNELZ_SERVICE_TEST_OBJS:.o=.dep) @@ -16983,18 +16960,18 @@ $(BINDIR)/$(CONFIG)/channelz_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/channelz_test: $(PROTOBUF_DEP) $(CHANNELZ_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channelz_test: $(PROTOBUF_DEP) $(CHANNELZ_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) $(CHANNELZ_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_test + $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_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)/channelz_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channelz_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channelz_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)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.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_channelz_test: $(CHANNELZ_TEST_OBJS:.o=.dep) @@ -17115,16 +17092,16 @@ $(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test: $(PROTOBUF_DEP) $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test: $(PROTOBUF_DEP) $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test + $(Q) $(LDXX) $(LDFLAGS) $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/settings_timeout_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/settings_timeout_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_chttp2_settings_timeout_test: $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS:.o=.dep) @@ -17158,16 +17135,16 @@ $(BINDIR)/$(CONFIG)/cli_call_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cli_call_test: $(PROTOBUF_DEP) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/cli_call_test: $(PROTOBUF_DEP) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(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) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cli_call_test + $(Q) $(LDXX) $(LDFLAGS) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(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)/cli_call_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(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_cli_call_test: $(CLI_CALL_TEST_OBJS:.o=.dep) @@ -17201,16 +17178,16 @@ $(BINDIR)/$(CONFIG)/client_callback_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_callback_end2end_test: $(PROTOBUF_DEP) $(CLIENT_CALLBACK_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_callback_end2end_test: $(PROTOBUF_DEP) $(CLIENT_CALLBACK_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_CALLBACK_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_callback_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CALLBACK_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_callback_end2end_test endif 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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(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 deps_client_callback_end2end_test: $(CLIENT_CALLBACK_END2END_TEST_OBJS:.o=.dep) @@ -17245,18 +17222,18 @@ $(BINDIR)/$(CONFIG)/client_channel_stress_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_channel_stress_test: $(PROTOBUF_DEP) $(CLIENT_CHANNEL_STRESS_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_channel_stress_test: $(PROTOBUF_DEP) $(CLIENT_CHANNEL_STRESS_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_CHANNEL_STRESS_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_channel_stress_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CHANNEL_STRESS_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_channel_stress_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(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/client/client_channel_stress_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/client/client_channel_stress_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_channel_stress_test: $(CLIENT_CHANNEL_STRESS_TEST_OBJS:.o=.dep) @@ -17291,16 +17268,16 @@ $(BINDIR)/$(CONFIG)/client_crash_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_crash_test: $(PROTOBUF_DEP) $(CLIENT_CRASH_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_crash_test: $(PROTOBUF_DEP) $(CLIENT_CRASH_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_CRASH_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_crash_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CRASH_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_crash_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_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_crash_test: $(CLIENT_CRASH_TEST_OBJS:.o=.dep) @@ -17334,16 +17311,16 @@ $(BINDIR)/$(CONFIG)/client_crash_test_server: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_crash_test_server: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_crash_test_server: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_SERVER_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_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_crash_test_server + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CRASH_TEST_SERVER_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_crash_test_server endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test_server.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test_server.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_crash_test_server: $(CLIENT_CRASH_TEST_SERVER_OBJS:.o=.dep) @@ -17378,18 +17355,18 @@ $(BINDIR)/$(CONFIG)/client_interceptors_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_interceptors_end2end_test: $(PROTOBUF_DEP) $(CLIENT_INTERCEPTORS_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_interceptors_end2end_test: $(PROTOBUF_DEP) $(CLIENT_INTERCEPTORS_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_INTERCEPTORS_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_interceptors_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_INTERCEPTORS_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_interceptors_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_interceptors_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_interceptors_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_test_util.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_interceptors_end2end_test: $(CLIENT_INTERCEPTORS_END2END_TEST_OBJS:.o=.dep) @@ -17423,16 +17400,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_test_util.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 $(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_test_util.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 $(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_test_util.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 deps_client_lb_end2end_test: $(CLIENT_LB_END2END_TEST_OBJS:.o=.dep) @@ -17600,16 +17577,16 @@ $(BINDIR)/$(CONFIG)/context_list_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/context_list_test: $(PROTOBUF_DEP) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/context_list_test: $(PROTOBUF_DEP) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/context_list_test + $(Q) $(LDXX) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/context_list_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_context_list_test: $(CONTEXT_LIST_TEST_OBJS:.o=.dep) @@ -17686,16 +17663,16 @@ $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cxx_byte_buffer_test: $(PROTOBUF_DEP) $(CXX_BYTE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/cxx_byte_buffer_test: $(PROTOBUF_DEP) $(CXX_BYTE_BUFFER_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) $(CXX_BYTE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test + $(Q) $(LDXX) $(LDFLAGS) $(CXX_BYTE_BUFFER_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)/cxx_byte_buffer_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_cxx_byte_buffer_test: $(CXX_BYTE_BUFFER_TEST_OBJS:.o=.dep) @@ -17729,16 +17706,16 @@ $(BINDIR)/$(CONFIG)/cxx_slice_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cxx_slice_test: $(PROTOBUF_DEP) $(CXX_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/cxx_slice_test: $(PROTOBUF_DEP) $(CXX_SLICE_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) $(CXX_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cxx_slice_test + $(Q) $(LDXX) $(LDFLAGS) $(CXX_SLICE_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)/cxx_slice_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_cxx_slice_test: $(CXX_SLICE_TEST_OBJS:.o=.dep) @@ -17815,16 +17792,16 @@ $(BINDIR)/$(CONFIG)/cxx_time_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cxx_time_test: $(PROTOBUF_DEP) $(CXX_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/cxx_time_test: $(PROTOBUF_DEP) $(CXX_TIME_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) $(CXX_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cxx_time_test + $(Q) $(LDXX) $(LDFLAGS) $(CXX_TIME_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)/cxx_time_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/time_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/time_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_cxx_time_test: $(CXX_TIME_TEST_OBJS:.o=.dep) @@ -17859,18 +17836,18 @@ $(BINDIR)/$(CONFIG)/end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/end2end_test: $(PROTOBUF_DEP) $(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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/end2end_test: $(PROTOBUF_DEP) $(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) $(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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(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)/end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/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_test_util.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_end2end_test: $(END2END_TEST_OBJS:.o=.dep) @@ -17951,16 +17928,16 @@ $(BINDIR)/$(CONFIG)/exception_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/exception_test: $(PROTOBUF_DEP) $(EXCEPTION_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/exception_test: $(PROTOBUF_DEP) $(EXCEPTION_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) $(EXCEPTION_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/exception_test + $(Q) $(LDXX) $(LDFLAGS) $(EXCEPTION_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)/exception_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/exception_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/exception_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_exception_test: $(EXCEPTION_TEST_OBJS:.o=.dep) @@ -17994,16 +17971,16 @@ $(BINDIR)/$(CONFIG)/filter_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/filter_end2end_test: $(PROTOBUF_DEP) $(FILTER_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/filter_end2end_test: $(PROTOBUF_DEP) $(FILTER_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) $(FILTER_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/filter_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(FILTER_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)/filter_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/filter_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/filter_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_filter_end2end_test: $(FILTER_END2END_TEST_OBJS:.o=.dep) @@ -18037,16 +18014,16 @@ $(BINDIR)/$(CONFIG)/generic_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/generic_end2end_test: $(PROTOBUF_DEP) $(GENERIC_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/generic_end2end_test: $(PROTOBUF_DEP) $(GENERIC_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) $(GENERIC_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/generic_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(GENERIC_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)/generic_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/generic_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/generic_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_generic_end2end_test: $(GENERIC_END2END_TEST_OBJS:.o=.dep) @@ -18275,16 +18252,16 @@ $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test: $(PROTOBUF_DEP) $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test: $(PROTOBUF_DEP) $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/security/linux_system_roots_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/linux_system_roots_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_linux_system_roots_test: $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS:.o=.dep) @@ -18475,20 +18452,20 @@ $(BINDIR)/$(CONFIG)/grpc_tool_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpc_tool_test: $(PROTOBUF_DEP) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_tool_test: $(PROTOBUF_DEP) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(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) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_tool_test + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(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)/grpc_tool_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(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)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(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/util/grpc_tool_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_tool_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(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_grpc_tool_test: $(GRPC_TOOL_TEST_OBJS:.o=.dep) @@ -18571,18 +18548,18 @@ $(BINDIR)/$(CONFIG)/grpclb_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpclb_end2end_test: $(PROTOBUF_DEP) $(GRPCLB_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpclb_end2end_test: $(PROTOBUF_DEP) $(GRPCLB_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) $(GRPCLB_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpclb_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(GRPCLB_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)/grpclb_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(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/grpclb_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/grpclb_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_grpclb_end2end_test: $(GRPCLB_END2END_TEST_OBJS:.o=.dep) @@ -18617,16 +18594,16 @@ $(BINDIR)/$(CONFIG)/h2_ssl_cert_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: $(PROTOBUF_DEP) $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: $(PROTOBUF_DEP) $(H2_SSL_CERT_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) $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/h2_ssl_cert_test + $(Q) $(LDXX) $(LDFLAGS) $(H2_SSL_CERT_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)/h2_ssl_cert_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/h2_ssl_cert_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/h2_ssl_cert_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_ssl_cert_test: $(H2_SSL_CERT_TEST_OBJS:.o=.dep) @@ -18660,16 +18637,16 @@ $(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test: $(PROTOBUF_DEP) $(H2_SSL_SESSION_REUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test: $(PROTOBUF_DEP) $(H2_SSL_SESSION_REUSE_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) $(H2_SSL_SESSION_REUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test + $(Q) $(LDXX) $(LDFLAGS) $(H2_SSL_SESSION_REUSE_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)/h2_ssl_session_reuse_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/h2_ssl_session_reuse_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/h2_ssl_session_reuse_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_ssl_session_reuse_test: $(H2_SSL_SESSION_REUSE_TEST_OBJS:.o=.dep) @@ -18703,16 +18680,16 @@ $(BINDIR)/$(CONFIG)/health_service_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/health_service_end2end_test: $(PROTOBUF_DEP) $(HEALTH_SERVICE_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/health_service_end2end_test: $(PROTOBUF_DEP) $(HEALTH_SERVICE_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) $(HEALTH_SERVICE_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/health_service_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(HEALTH_SERVICE_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)/health_service_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/health_service_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/health_service_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_health_service_end2end_test: $(HEALTH_SERVICE_END2END_TEST_OBJS:.o=.dep) @@ -18777,16 +18754,16 @@ $(BINDIR)/$(CONFIG)/hybrid_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/hybrid_end2end_test: $(PROTOBUF_DEP) $(HYBRID_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hybrid_end2end_test: $(PROTOBUF_DEP) $(HYBRID_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) $(HYBRID_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/hybrid_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(HYBRID_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)/hybrid_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/hybrid_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/hybrid_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_hybrid_end2end_test: $(HYBRID_END2END_TEST_OBJS:.o=.dep) @@ -18820,16 +18797,16 @@ $(BINDIR)/$(CONFIG)/inlined_vector_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/inlined_vector_test: $(PROTOBUF_DEP) $(INLINED_VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/inlined_vector_test: $(PROTOBUF_DEP) $(INLINED_VECTOR_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) $(INLINED_VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/inlined_vector_test + $(Q) $(LDXX) $(LDFLAGS) $(INLINED_VECTOR_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)/inlined_vector_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/inlined_vector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/inlined_vector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_inlined_vector_test: $(INLINED_VECTOR_TEST_OBJS:.o=.dep) @@ -18863,16 +18840,16 @@ $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test + $(Q) $(LDXX) $(LDFLAGS) $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/inproc_sync_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/inproc_sync_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a deps_inproc_sync_unary_ping_pong_test: $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS:.o=.dep) @@ -18902,10 +18879,10 @@ $(BINDIR)/$(CONFIG)/interop_client: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/interop_client: $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/interop_client: $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_client + $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_client endif @@ -18933,10 +18910,10 @@ $(BINDIR)/$(CONFIG)/interop_server: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/interop_server: $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/interop_server: $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_server + $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_server endif @@ -18968,16 +18945,16 @@ $(BINDIR)/$(CONFIG)/interop_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/interop_test: $(PROTOBUF_DEP) $(INTEROP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/interop_test: $(PROTOBUF_DEP) $(INTEROP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(INTEROP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_test + $(Q) $(LDXX) $(LDFLAGS) $(INTEROP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_interop_test: $(INTEROP_TEST_OBJS:.o=.dep) @@ -19011,16 +18988,16 @@ $(BINDIR)/$(CONFIG)/json_run_localhost: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/json_run_localhost: $(PROTOBUF_DEP) $(JSON_RUN_LOCALHOST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/json_run_localhost: $(PROTOBUF_DEP) $(JSON_RUN_LOCALHOST_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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(JSON_RUN_LOCALHOST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/json_run_localhost + $(Q) $(LDXX) $(LDFLAGS) $(JSON_RUN_LOCALHOST_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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/json_run_localhost endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/json_run_localhost.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/json_run_localhost.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)/libgrpc++_test_config.a deps_json_run_localhost: $(JSON_RUN_LOCALHOST_OBJS:.o=.dep) @@ -19054,16 +19031,16 @@ $(BINDIR)/$(CONFIG)/memory_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/memory_test: $(PROTOBUF_DEP) $(MEMORY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/memory_test: $(PROTOBUF_DEP) $(MEMORY_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) $(MEMORY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/memory_test + $(Q) $(LDXX) $(LDFLAGS) $(MEMORY_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)/memory_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/memory_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/memory_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_memory_test: $(MEMORY_TEST_OBJS:.o=.dep) @@ -19144,16 +19121,16 @@ $(BINDIR)/$(CONFIG)/mock_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/mock_test: $(PROTOBUF_DEP) $(MOCK_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/mock_test: $(PROTOBUF_DEP) $(MOCK_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) $(MOCK_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/mock_test + $(Q) $(LDXX) $(LDFLAGS) $(MOCK_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)/mock_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/mock_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/mock_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_mock_test: $(MOCK_TEST_OBJS:.o=.dep) @@ -19187,16 +19164,16 @@ $(BINDIR)/$(CONFIG)/nonblocking_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/nonblocking_test: $(PROTOBUF_DEP) $(NONBLOCKING_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nonblocking_test: $(PROTOBUF_DEP) $(NONBLOCKING_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) $(NONBLOCKING_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/nonblocking_test + $(Q) $(LDXX) $(LDFLAGS) $(NONBLOCKING_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)/nonblocking_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/nonblocking_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/nonblocking_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_nonblocking_test: $(NONBLOCKING_TEST_OBJS:.o=.dep) @@ -19274,16 +19251,16 @@ $(BINDIR)/$(CONFIG)/orphanable_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/orphanable_test: $(PROTOBUF_DEP) $(ORPHANABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/orphanable_test: $(PROTOBUF_DEP) $(ORPHANABLE_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) $(ORPHANABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/orphanable_test + $(Q) $(LDXX) $(LDFLAGS) $(ORPHANABLE_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)/orphanable_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/orphanable_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/orphanable_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_orphanable_test: $(ORPHANABLE_TEST_OBJS:.o=.dep) @@ -19317,16 +19294,16 @@ $(BINDIR)/$(CONFIG)/proto_server_reflection_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/proto_server_reflection_test: $(PROTOBUF_DEP) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/proto_server_reflection_test: $(PROTOBUF_DEP) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(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) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/proto_server_reflection_test + $(Q) $(LDXX) $(LDFLAGS) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(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)/proto_server_reflection_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/proto_server_reflection_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/proto_server_reflection_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(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_proto_server_reflection_test: $(PROTO_SERVER_REFLECTION_TEST_OBJS:.o=.dep) @@ -19403,16 +19380,16 @@ $(BINDIR)/$(CONFIG)/qps_interarrival_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/qps_interarrival_test: $(PROTOBUF_DEP) $(QPS_INTERARRIVAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/qps_interarrival_test: $(PROTOBUF_DEP) $(QPS_INTERARRIVAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(QPS_INTERARRIVAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_interarrival_test + $(Q) $(LDXX) $(LDFLAGS) $(QPS_INTERARRIVAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_interarrival_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_interarrival_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_interarrival_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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)/libgrpc++_test_config.a deps_qps_interarrival_test: $(QPS_INTERARRIVAL_TEST_OBJS:.o=.dep) @@ -19446,16 +19423,16 @@ $(BINDIR)/$(CONFIG)/qps_json_driver: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/qps_json_driver: $(PROTOBUF_DEP) $(QPS_JSON_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/qps_json_driver: $(PROTOBUF_DEP) $(QPS_JSON_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(QPS_JSON_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_json_driver + $(Q) $(LDXX) $(LDFLAGS) $(QPS_JSON_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_json_driver endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_json_driver.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_json_driver.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a deps_qps_json_driver: $(QPS_JSON_DRIVER_OBJS:.o=.dep) @@ -19489,16 +19466,16 @@ $(BINDIR)/$(CONFIG)/qps_openloop_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/qps_openloop_test: $(PROTOBUF_DEP) $(QPS_OPENLOOP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/qps_openloop_test: $(PROTOBUF_DEP) $(QPS_OPENLOOP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(QPS_OPENLOOP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_openloop_test + $(Q) $(LDXX) $(LDFLAGS) $(QPS_OPENLOOP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_openloop_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_openloop_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_openloop_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a deps_qps_openloop_test: $(QPS_OPENLOOP_TEST_OBJS:.o=.dep) @@ -19532,16 +19509,16 @@ $(BINDIR)/$(CONFIG)/qps_worker: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/qps_worker: $(PROTOBUF_DEP) $(QPS_WORKER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/qps_worker: $(PROTOBUF_DEP) $(QPS_WORKER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(QPS_WORKER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_worker + $(Q) $(LDXX) $(LDFLAGS) $(QPS_WORKER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_worker endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/worker.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/worker.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a deps_qps_worker: $(QPS_WORKER_OBJS:.o=.dep) @@ -19575,16 +19552,16 @@ $(BINDIR)/$(CONFIG)/raw_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/raw_end2end_test: $(PROTOBUF_DEP) $(RAW_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/raw_end2end_test: $(PROTOBUF_DEP) $(RAW_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) $(RAW_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/raw_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(RAW_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)/raw_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/raw_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/raw_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_raw_end2end_test: $(RAW_END2END_TEST_OBJS:.o=.dep) @@ -19621,22 +19598,22 @@ $(BINDIR)/$(CONFIG)/reconnect_interop_client: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/reconnect_interop_client: $(PROTOBUF_DEP) $(RECONNECT_INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/reconnect_interop_client: $(PROTOBUF_DEP) $(RECONNECT_INTEROP_CLIENT_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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RECONNECT_INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/reconnect_interop_client + $(Q) $(LDXX) $(LDFLAGS) $(RECONNECT_INTEROP_CLIENT_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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/reconnect_interop_client endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.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)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.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)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/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)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_client.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)/libgrpc++_test_config.a deps_reconnect_interop_client: $(RECONNECT_INTEROP_CLIENT_OBJS:.o=.dep) @@ -19674,22 +19651,22 @@ $(BINDIR)/$(CONFIG)/reconnect_interop_server: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/reconnect_interop_server: $(PROTOBUF_DEP) $(RECONNECT_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/reconnect_interop_server: $(PROTOBUF_DEP) $(RECONNECT_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RECONNECT_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/reconnect_interop_server + $(Q) $(LDXX) $(LDFLAGS) $(RECONNECT_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/reconnect_interop_server endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(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)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(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)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(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)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_server.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_server.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(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)/libgrpc++_test_config.a deps_reconnect_interop_server: $(RECONNECT_INTEROP_SERVER_OBJS:.o=.dep) @@ -19724,16 +19701,16 @@ $(BINDIR)/$(CONFIG)/ref_counted_ptr_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/ref_counted_ptr_test: $(PROTOBUF_DEP) $(REF_COUNTED_PTR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ref_counted_ptr_test: $(PROTOBUF_DEP) $(REF_COUNTED_PTR_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) $(REF_COUNTED_PTR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/ref_counted_ptr_test + $(Q) $(LDXX) $(LDFLAGS) $(REF_COUNTED_PTR_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)/ref_counted_ptr_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_ptr_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_ptr_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ref_counted_ptr_test: $(REF_COUNTED_PTR_TEST_OBJS:.o=.dep) @@ -19767,16 +19744,16 @@ $(BINDIR)/$(CONFIG)/ref_counted_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/ref_counted_test: $(PROTOBUF_DEP) $(REF_COUNTED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ref_counted_test: $(PROTOBUF_DEP) $(REF_COUNTED_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) $(REF_COUNTED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/ref_counted_test + $(Q) $(LDXX) $(LDFLAGS) $(REF_COUNTED_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)/ref_counted_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ref_counted_test: $(REF_COUNTED_TEST_OBJS:.o=.dep) @@ -19810,16 +19787,16 @@ $(BINDIR)/$(CONFIG)/retry_throttle_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/retry_throttle_test: $(PROTOBUF_DEP) $(RETRY_THROTTLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/retry_throttle_test: $(PROTOBUF_DEP) $(RETRY_THROTTLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RETRY_THROTTLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/retry_throttle_test + $(Q) $(LDXX) $(LDFLAGS) $(RETRY_THROTTLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/retry_throttle_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/retry_throttle_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/retry_throttle_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_retry_throttle_test: $(RETRY_THROTTLE_TEST_OBJS:.o=.dep) @@ -19853,16 +19830,16 @@ $(BINDIR)/$(CONFIG)/secure_auth_context_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/secure_auth_context_test: $(PROTOBUF_DEP) $(SECURE_AUTH_CONTEXT_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/secure_auth_context_test: $(PROTOBUF_DEP) $(SECURE_AUTH_CONTEXT_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) $(SECURE_AUTH_CONTEXT_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/secure_auth_context_test + $(Q) $(LDXX) $(LDFLAGS) $(SECURE_AUTH_CONTEXT_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)/secure_auth_context_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/common/secure_auth_context_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/common/secure_auth_context_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_secure_auth_context_test: $(SECURE_AUTH_CONTEXT_TEST_OBJS:.o=.dep) @@ -19896,16 +19873,16 @@ $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test + $(Q) $(LDXX) $(LDFLAGS) $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/secure_sync_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/secure_sync_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(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)/libgrpc++_test_config.a deps_secure_sync_unary_ping_pong_test: $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS:.o=.dep) @@ -19939,16 +19916,16 @@ $(BINDIR)/$(CONFIG)/server_builder_plugin_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_builder_plugin_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_PLUGIN_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_builder_plugin_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_PLUGIN_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) $(SERVER_BUILDER_PLUGIN_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_plugin_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_PLUGIN_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)/server_builder_plugin_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_builder_plugin_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_builder_plugin_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_server_builder_plugin_test: $(SERVER_BUILDER_PLUGIN_TEST_OBJS:.o=.dep) @@ -19984,20 +19961,20 @@ $(BINDIR)/$(CONFIG)/server_builder_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_builder_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_builder_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_TEST_OBJS) $(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 $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_TEST_OBJS) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(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 -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(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 -$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o: $(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 deps_server_builder_test: $(SERVER_BUILDER_TEST_OBJS:.o=.dep) @@ -20034,20 +20011,20 @@ $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS) $(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 $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_with_socket_mutator_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(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 -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(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 -$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_with_socket_mutator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_with_socket_mutator_test.o: $(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 deps_server_builder_with_socket_mutator_test: $(SERVER_BUILDER_WITH_SOCKET_MUTATOR_TEST_OBJS:.o=.dep) @@ -20082,16 +20059,16 @@ $(BINDIR)/$(CONFIG)/server_context_test_spouse_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_context_test_spouse_test: $(PROTOBUF_DEP) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_context_test_spouse_test: $(PROTOBUF_DEP) $(SERVER_CONTEXT_TEST_SPOUSE_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) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_context_test_spouse_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CONTEXT_TEST_SPOUSE_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)/server_context_test_spouse_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/test/server_context_test_spouse_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/test/server_context_test_spouse_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_context_test_spouse_test: $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS:.o=.dep) @@ -20125,16 +20102,16 @@ $(BINDIR)/$(CONFIG)/server_crash_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_crash_test: $(PROTOBUF_DEP) $(SERVER_CRASH_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_crash_test: $(PROTOBUF_DEP) $(SERVER_CRASH_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) $(SERVER_CRASH_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_crash_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CRASH_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)/server_crash_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_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_server_crash_test: $(SERVER_CRASH_TEST_OBJS:.o=.dep) @@ -20168,16 +20145,16 @@ $(BINDIR)/$(CONFIG)/server_crash_test_client: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_crash_test_client: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_crash_test_client: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_CLIENT_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) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_crash_test_client + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CRASH_TEST_CLIENT_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)/server_crash_test_client endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test_client.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_server_crash_test_client: $(SERVER_CRASH_TEST_CLIENT_OBJS:.o=.dep) @@ -20211,16 +20188,16 @@ $(BINDIR)/$(CONFIG)/server_early_return_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_early_return_test: $(PROTOBUF_DEP) $(SERVER_EARLY_RETURN_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_early_return_test: $(PROTOBUF_DEP) $(SERVER_EARLY_RETURN_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) $(SERVER_EARLY_RETURN_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_early_return_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_EARLY_RETURN_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)/server_early_return_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_early_return_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_early_return_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_server_early_return_test: $(SERVER_EARLY_RETURN_TEST_OBJS:.o=.dep) @@ -20255,18 +20232,18 @@ $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_interceptors_end2end_test: $(PROTOBUF_DEP) $(SERVER_INTERCEPTORS_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_interceptors_end2end_test: $(PROTOBUF_DEP) $(SERVER_INTERCEPTORS_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) $(SERVER_INTERCEPTORS_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_INTERCEPTORS_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)/server_interceptors_end2end_test endif endif -$(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_test_util.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 -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_interceptors_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_interceptors_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_server_interceptors_end2end_test: $(SERVER_INTERCEPTORS_END2END_TEST_OBJS:.o=.dep) @@ -20302,20 +20279,20 @@ $(BINDIR)/$(CONFIG)/server_request_call_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_request_call_test: $(PROTOBUF_DEP) $(SERVER_REQUEST_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_request_call_test: $(PROTOBUF_DEP) $(SERVER_REQUEST_CALL_TEST_OBJS) $(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 $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_REQUEST_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_request_call_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_REQUEST_CALL_TEST_OBJS) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_request_call_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(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 -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(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 -$(OBJDIR)/$(CONFIG)/test/cpp/server/server_request_call_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/server/server_request_call_test.o: $(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 deps_server_request_call_test: $(SERVER_REQUEST_CALL_TEST_OBJS:.o=.dep) @@ -20350,16 +20327,16 @@ $(BINDIR)/$(CONFIG)/shutdown_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/shutdown_test: $(PROTOBUF_DEP) $(SHUTDOWN_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/shutdown_test: $(PROTOBUF_DEP) $(SHUTDOWN_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) $(SHUTDOWN_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/shutdown_test + $(Q) $(LDXX) $(LDFLAGS) $(SHUTDOWN_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)/shutdown_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/shutdown_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/shutdown_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_shutdown_test: $(SHUTDOWN_TEST_OBJS:.o=.dep) @@ -20393,16 +20370,16 @@ $(BINDIR)/$(CONFIG)/slice_hash_table_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/slice_hash_table_test: $(PROTOBUF_DEP) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_hash_table_test: $(PROTOBUF_DEP) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_hash_table_test + $(Q) $(LDXX) $(LDFLAGS) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_hash_table_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/slice_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_hash_table_test: $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep) @@ -20436,16 +20413,16 @@ $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: $(PROTOBUF_DEP) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: $(PROTOBUF_DEP) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test + $(Q) $(LDXX) $(LDFLAGS) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_weak_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/slice_weak_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_weak_hash_table_test: $(SLICE_WEAK_HASH_TABLE_TEST_OBJS:.o=.dep) @@ -20479,16 +20456,16 @@ $(BINDIR)/$(CONFIG)/stats_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/stats_test: $(PROTOBUF_DEP) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/stats_test: $(PROTOBUF_DEP) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/stats_test + $(Q) $(LDXX) $(LDFLAGS) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/stats_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/debug/stats_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/debug/stats_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_stats_test: $(STATS_TEST_OBJS:.o=.dep) @@ -20608,16 +20585,16 @@ $(BINDIR)/$(CONFIG)/streaming_throughput_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/streaming_throughput_test: $(PROTOBUF_DEP) $(STREAMING_THROUGHPUT_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/streaming_throughput_test: $(PROTOBUF_DEP) $(STREAMING_THROUGHPUT_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) $(STREAMING_THROUGHPUT_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/streaming_throughput_test + $(Q) $(LDXX) $(LDFLAGS) $(STREAMING_THROUGHPUT_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)/streaming_throughput_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/streaming_throughput_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/streaming_throughput_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_streaming_throughput_test: $(STREAMING_THROUGHPUT_TEST_OBJS:.o=.dep) @@ -20658,30 +20635,30 @@ $(BINDIR)/$(CONFIG)/stress_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/stress_test: $(PROTOBUF_DEP) $(STRESS_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/stress_test: $(PROTOBUF_DEP) $(STRESS_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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(STRESS_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/stress_test + $(Q) $(LDXX) $(LDFLAGS) $(STRESS_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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/stress_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.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)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.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)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/metrics.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/metrics.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)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/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)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_client.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)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_interop_client.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)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_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)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.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)/libgrpc++_test_config.a deps_stress_test: $(STRESS_TEST_OBJS:.o=.dep) @@ -20762,16 +20739,16 @@ $(BINDIR)/$(CONFIG)/thread_stress_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/thread_stress_test: $(PROTOBUF_DEP) $(THREAD_STRESS_TEST_OBJS) $(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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/thread_stress_test: $(PROTOBUF_DEP) $(THREAD_STRESS_TEST_OBJS) $(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 $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(THREAD_STRESS_TEST_OBJS) $(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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/thread_stress_test + $(Q) $(LDXX) $(LDFLAGS) $(THREAD_STRESS_TEST_OBJS) $(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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/thread_stress_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/thread_stress_test.o: $(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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/thread_stress_test.o: $(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 deps_thread_stress_test: $(THREAD_STRESS_TEST_OBJS:.o=.dep) @@ -20805,16 +20782,16 @@ $(BINDIR)/$(CONFIG)/transport_pid_controller_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/transport_pid_controller_test: $(PROTOBUF_DEP) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/transport_pid_controller_test: $(PROTOBUF_DEP) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/transport_pid_controller_test + $(Q) $(LDXX) $(LDFLAGS) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/transport_pid_controller_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/pid_controller_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/pid_controller_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_transport_pid_controller_test: $(TRANSPORT_PID_CONTROLLER_TEST_OBJS:.o=.dep) @@ -20891,16 +20868,16 @@ $(BINDIR)/$(CONFIG)/writes_per_rpc_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/writes_per_rpc_test: $(PROTOBUF_DEP) $(WRITES_PER_RPC_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/writes_per_rpc_test: $(PROTOBUF_DEP) $(WRITES_PER_RPC_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) $(WRITES_PER_RPC_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/writes_per_rpc_test + $(Q) $(LDXX) $(LDFLAGS) $(WRITES_PER_RPC_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)/writes_per_rpc_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/performance/writes_per_rpc_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/performance/writes_per_rpc_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_writes_per_rpc_test: $(WRITES_PER_RPC_TEST_OBJS:.o=.dep) @@ -23089,12 +23066,12 @@ BADREQ_BAD_CLIENT_TEST_SRC = \ BADREQ_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BADREQ_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/badreq_bad_client_test: $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/badreq_bad_client_test: $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/badreq_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/badreq_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/badreq.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/badreq.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_badreq_bad_client_test: $(BADREQ_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23109,12 +23086,12 @@ CONNECTION_PREFIX_BAD_CLIENT_TEST_SRC = \ CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CONNECTION_PREFIX_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test: $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test: $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/connection_prefix.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/connection_prefix.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_connection_prefix_bad_client_test: $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23129,12 +23106,12 @@ DUPLICATE_HEADER_BAD_CLIENT_TEST_SRC = \ DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DUPLICATE_HEADER_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/duplicate_header.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/duplicate_header.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23149,12 +23126,12 @@ HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC = \ HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/head_of_line_blocking.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/head_of_line_blocking.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23169,12 +23146,12 @@ HEADERS_BAD_CLIENT_TEST_SRC = \ HEADERS_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HEADERS_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/headers_bad_client_test: $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/headers_bad_client_test: $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/headers_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/headers_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/headers.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/headers.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_headers_bad_client_test: $(HEADERS_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23189,12 +23166,12 @@ INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_SRC = \ INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test: $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test: $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/initial_settings_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/initial_settings_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_initial_settings_frame_bad_client_test: $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23209,12 +23186,12 @@ LARGE_METADATA_BAD_CLIENT_TEST_SRC = \ LARGE_METADATA_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LARGE_METADATA_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test: $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test: $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/large_metadata.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/large_metadata.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_large_metadata_bad_client_test: $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23229,12 +23206,12 @@ SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_SRC = \ SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test: $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test: $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/server_registered_method.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/server_registered_method.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_registered_method_bad_client_test: $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23249,12 +23226,12 @@ SIMPLE_REQUEST_BAD_CLIENT_TEST_SRC = \ SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SIMPLE_REQUEST_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/simple_request_bad_client_test: $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/simple_request_bad_client_test: $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/simple_request_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/simple_request_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/simple_request.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/simple_request.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_simple_request_bad_client_test: $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23269,12 +23246,12 @@ UNKNOWN_FRAME_BAD_CLIENT_TEST_SRC = \ UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(UNKNOWN_FRAME_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test: $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test: $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/unknown_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/unknown_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_unknown_frame_bad_client_test: $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23289,12 +23266,12 @@ WINDOW_OVERFLOW_BAD_CLIENT_TEST_SRC = \ WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test: $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test: $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/window_overflow.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/window_overflow.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_window_overflow_bad_client_test: $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23317,14 +23294,14 @@ else -$(BINDIR)/$(CONFIG)/bad_ssl_cert_server: $(BAD_SSL_CERT_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bad_ssl_cert_server: $(BAD_SSL_CERT_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.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) $(BAD_SSL_CERT_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_ssl_cert_server + $(Q) $(LD) $(LDFLAGS) $(BAD_SSL_CERT_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_ssl_cert_server endif -$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/servers/cert.o: $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/servers/cert.o: $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bad_ssl_cert_server: $(BAD_SSL_CERT_SERVER_OBJS:.o=.dep) @@ -23349,14 +23326,14 @@ else -$(BINDIR)/$(CONFIG)/bad_ssl_cert_test: $(BAD_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bad_ssl_cert_test: $(BAD_SSL_CERT_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) $(BAD_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_ssl_cert_test + $(Q) $(LD) $(LDFLAGS) $(BAD_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_ssl_cert_test endif -$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/bad_ssl_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/bad_ssl_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bad_ssl_cert_test: $(BAD_SSL_CERT_TEST_OBJS:.o=.dep) @@ -23381,14 +23358,14 @@ else -$(BINDIR)/$(CONFIG)/h2_census_test: $(H2_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_census_test: $(H2_CENSUS_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_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_census_test + $(Q) $(LD) $(LDFLAGS) $(H2_CENSUS_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_census_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_census_test: $(H2_CENSUS_TEST_OBJS:.o=.dep) @@ -23413,14 +23390,14 @@ else -$(BINDIR)/$(CONFIG)/h2_compress_test: $(H2_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_compress_test: $(H2_COMPRESS_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_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_compress_test + $(Q) $(LD) $(LDFLAGS) $(H2_COMPRESS_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_compress_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_compress_test: $(H2_COMPRESS_TEST_OBJS:.o=.dep) @@ -23445,14 +23422,14 @@ else -$(BINDIR)/$(CONFIG)/h2_fakesec_test: $(H2_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_fakesec_test: $(H2_FAKESEC_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_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_fakesec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FAKESEC_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_fakesec_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fakesec.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fakesec.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_fakesec_test: $(H2_FAKESEC_TEST_OBJS:.o=.dep) @@ -23477,14 +23454,14 @@ else -$(BINDIR)/$(CONFIG)/h2_fd_test: $(H2_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_fd_test: $(H2_FD_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_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_fd_test + $(Q) $(LD) $(LDFLAGS) $(H2_FD_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_fd_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_fd_test: $(H2_FD_TEST_OBJS:.o=.dep) @@ -23509,14 +23486,14 @@ else -$(BINDIR)/$(CONFIG)/h2_full_test: $(H2_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full_test: $(H2_FULL_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_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL_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_full_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full_test: $(H2_FULL_TEST_OBJS:.o=.dep) @@ -23541,14 +23518,14 @@ else -$(BINDIR)/$(CONFIG)/h2_full+pipe_test: $(H2_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+pipe_test: $(H2_FULL+PIPE_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_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+pipe_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+PIPE_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_full+pipe_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+pipe_test: $(H2_FULL+PIPE_TEST_OBJS:.o=.dep) @@ -23573,14 +23550,14 @@ else -$(BINDIR)/$(CONFIG)/h2_full+trace_test: $(H2_FULL+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+trace_test: $(H2_FULL+TRACE_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_FULL+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+trace_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+TRACE_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_full+trace_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+trace_test: $(H2_FULL+TRACE_TEST_OBJS:.o=.dep) @@ -23605,14 +23582,14 @@ else -$(BINDIR)/$(CONFIG)/h2_full+workarounds_test: $(H2_FULL+WORKAROUNDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+workarounds_test: $(H2_FULL+WORKAROUNDS_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_FULL+WORKAROUNDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+workarounds_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+WORKAROUNDS_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_full+workarounds_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+workarounds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+workarounds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+workarounds_test: $(H2_FULL+WORKAROUNDS_TEST_OBJS:.o=.dep) @@ -23637,14 +23614,14 @@ else -$(BINDIR)/$(CONFIG)/h2_http_proxy_test: $(H2_HTTP_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_http_proxy_test: $(H2_HTTP_PROXY_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_HTTP_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_http_proxy_test + $(Q) $(LD) $(LDFLAGS) $(H2_HTTP_PROXY_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_http_proxy_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_http_proxy_test: $(H2_HTTP_PROXY_TEST_OBJS:.o=.dep) @@ -23669,14 +23646,14 @@ else -$(BINDIR)/$(CONFIG)/h2_local_test: $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_local_test: $(H2_LOCAL_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_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_test + $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_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_local_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_local_test: $(H2_LOCAL_TEST_OBJS:.o=.dep) @@ -23701,14 +23678,14 @@ else -$(BINDIR)/$(CONFIG)/h2_oauth2_test: $(H2_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_oauth2_test: $(H2_OAUTH2_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_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_oauth2_test + $(Q) $(LD) $(LDFLAGS) $(H2_OAUTH2_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_oauth2_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_oauth2.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_oauth2.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_oauth2_test: $(H2_OAUTH2_TEST_OBJS:.o=.dep) @@ -23733,14 +23710,14 @@ else -$(BINDIR)/$(CONFIG)/h2_proxy_test: $(H2_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_proxy_test: $(H2_PROXY_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_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_proxy_test + $(Q) $(LD) $(LDFLAGS) $(H2_PROXY_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_proxy_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_proxy_test: $(H2_PROXY_TEST_OBJS:.o=.dep) @@ -23765,14 +23742,14 @@ else -$(BINDIR)/$(CONFIG)/h2_sockpair_test: $(H2_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair_test: $(H2_SOCKPAIR_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_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_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_sockpair_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair_test: $(H2_SOCKPAIR_TEST_OBJS:.o=.dep) @@ -23797,14 +23774,14 @@ else -$(BINDIR)/$(CONFIG)/h2_sockpair+trace_test: $(H2_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair+trace_test: $(H2_SOCKPAIR+TRACE_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_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR+TRACE_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_sockpair+trace_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair+trace_test: $(H2_SOCKPAIR+TRACE_TEST_OBJS:.o=.dep) @@ -23829,14 +23806,14 @@ else -$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test: $(H2_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test: $(H2_SOCKPAIR_1BYTE_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_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_1BYTE_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_sockpair_1byte_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair_1byte_test: $(H2_SOCKPAIR_1BYTE_TEST_OBJS:.o=.dep) @@ -23861,14 +23838,14 @@ else -$(BINDIR)/$(CONFIG)/h2_ssl_test: $(H2_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_ssl_test: $(H2_SSL_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_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_test + $(Q) $(LD) $(LDFLAGS) $(H2_SSL_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_ssl_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_ssl_test: $(H2_SSL_TEST_OBJS:.o=.dep) @@ -23893,14 +23870,14 @@ else -$(BINDIR)/$(CONFIG)/h2_ssl_proxy_test: $(H2_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_ssl_proxy_test: $(H2_SSL_PROXY_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_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test + $(Q) $(LD) $(LDFLAGS) $(H2_SSL_PROXY_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_ssl_proxy_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_ssl_proxy_test: $(H2_SSL_PROXY_TEST_OBJS:.o=.dep) @@ -23925,14 +23902,14 @@ else -$(BINDIR)/$(CONFIG)/h2_uds_test: $(H2_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_uds_test: $(H2_UDS_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_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uds_test + $(Q) $(LD) $(LDFLAGS) $(H2_UDS_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_uds_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_uds_test: $(H2_UDS_TEST_OBJS:.o=.dep) @@ -23957,14 +23934,14 @@ else -$(BINDIR)/$(CONFIG)/inproc_test: $(INPROC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/inproc_test: $(INPROC_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) $(INPROC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/inproc_test + $(Q) $(LD) $(LDFLAGS) $(INPROC_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)/inproc_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/inproc.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/inproc.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_inproc_test: $(INPROC_TEST_OBJS:.o=.dep) @@ -23981,12 +23958,12 @@ H2_CENSUS_NOSEC_TEST_SRC = \ H2_CENSUS_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_CENSUS_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_census_nosec_test: $(H2_CENSUS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_census_nosec_test: $(H2_CENSUS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_CENSUS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_census_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_CENSUS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_census_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_census_nosec_test: $(H2_CENSUS_NOSEC_TEST_OBJS:.o=.dep) @@ -24001,12 +23978,12 @@ H2_COMPRESS_NOSEC_TEST_SRC = \ H2_COMPRESS_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_COMPRESS_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_compress_nosec_test: $(H2_COMPRESS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_compress_nosec_test: $(H2_COMPRESS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_COMPRESS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_compress_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_COMPRESS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_compress_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_compress_nosec_test: $(H2_COMPRESS_NOSEC_TEST_OBJS:.o=.dep) @@ -24021,12 +23998,12 @@ H2_FD_NOSEC_TEST_SRC = \ H2_FD_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FD_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_fd_nosec_test: $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_fd_nosec_test: $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_fd_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_fd_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_fd_nosec_test: $(H2_FD_NOSEC_TEST_OBJS:.o=.dep) @@ -24041,12 +24018,12 @@ H2_FULL_NOSEC_TEST_SRC = \ H2_FULL_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_full_nosec_test: $(H2_FULL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full_nosec_test: $(H2_FULL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full_nosec_test: $(H2_FULL_NOSEC_TEST_OBJS:.o=.dep) @@ -24061,12 +24038,12 @@ H2_FULL+PIPE_NOSEC_TEST_SRC = \ H2_FULL+PIPE_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL+PIPE_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test: $(H2_FULL+PIPE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test: $(H2_FULL+PIPE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+PIPE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+PIPE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+pipe_nosec_test: $(H2_FULL+PIPE_NOSEC_TEST_OBJS:.o=.dep) @@ -24081,12 +24058,12 @@ H2_FULL+TRACE_NOSEC_TEST_SRC = \ H2_FULL+TRACE_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL+TRACE_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test: $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test: $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+trace_nosec_test: $(H2_FULL+TRACE_NOSEC_TEST_OBJS:.o=.dep) @@ -24101,12 +24078,12 @@ H2_FULL+WORKAROUNDS_NOSEC_TEST_SRC = \ H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL+WORKAROUNDS_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test: $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test: $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+workarounds.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+workarounds.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+workarounds_nosec_test: $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS:.o=.dep) @@ -24121,12 +24098,12 @@ H2_HTTP_PROXY_NOSEC_TEST_SRC = \ H2_HTTP_PROXY_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_HTTP_PROXY_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test: $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test: $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_http_proxy_nosec_test: $(H2_HTTP_PROXY_NOSEC_TEST_OBJS:.o=.dep) @@ -24141,12 +24118,12 @@ H2_PROXY_NOSEC_TEST_SRC = \ H2_PROXY_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_PROXY_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_proxy_nosec_test: $(H2_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_proxy_nosec_test: $(H2_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_proxy_nosec_test: $(H2_PROXY_NOSEC_TEST_OBJS:.o=.dep) @@ -24161,12 +24138,12 @@ H2_SOCKPAIR_NOSEC_TEST_SRC = \ H2_SOCKPAIR_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SOCKPAIR_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test: $(H2_SOCKPAIR_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test: $(H2_SOCKPAIR_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair_nosec_test: $(H2_SOCKPAIR_NOSEC_TEST_OBJS:.o=.dep) @@ -24181,12 +24158,12 @@ H2_SOCKPAIR+TRACE_NOSEC_TEST_SRC = \ H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SOCKPAIR+TRACE_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test: $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test: $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair+trace_nosec_test: $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS:.o=.dep) @@ -24201,12 +24178,12 @@ H2_SOCKPAIR_1BYTE_NOSEC_TEST_SRC = \ H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test: $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test: $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair_1byte_nosec_test: $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS:.o=.dep) @@ -24221,12 +24198,12 @@ H2_UDS_NOSEC_TEST_SRC = \ H2_UDS_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_UDS_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_uds_nosec_test: $(H2_UDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_uds_nosec_test: $(H2_UDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_UDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_uds_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_UDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_uds_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_uds_nosec_test: $(H2_UDS_NOSEC_TEST_OBJS:.o=.dep) @@ -24258,16 +24235,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/resolver_component_test_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/resolver_component_test_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(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) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.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)/resolver_component_test_unsecure + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(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)/resolver_component_test_unsecure endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_test.o: $(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_resolver_component_test_unsecure: $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS:.o=.dep) @@ -24301,16 +24278,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/resolver_component_test: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/resolver_component_test: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_test + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_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)/libgrpc++_test_config.a deps_resolver_component_test: $(RESOLVER_COMPONENT_TEST_OBJS:.o=.dep) @@ -24344,16 +24321,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure: protobuf_d else -$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_tests_runner_invoker.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_tests_runner_invoker.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)/libgrpc++_test_config.a deps_resolver_component_tests_runner_invoker_unsecure: $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_OBJS:.o=.dep) @@ -24387,16 +24364,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_tests_runner_invoker.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_tests_runner_invoker.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)/libgrpc++_test_config.a deps_resolver_component_tests_runner_invoker: $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_OBJS:.o=.dep) @@ -24430,16 +24407,16 @@ $(BINDIR)/$(CONFIG)/address_sorting_test_unsecure: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/address_sorting_test_unsecure: $(PROTOBUF_DEP) $(ADDRESS_SORTING_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/address_sorting_test_unsecure: $(PROTOBUF_DEP) $(ADDRESS_SORTING_TEST_UNSECURE_OBJS) $(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) $(ADDRESS_SORTING_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.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)/address_sorting_test_unsecure + $(Q) $(LDXX) $(LDFLAGS) $(ADDRESS_SORTING_TEST_UNSECURE_OBJS) $(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)/address_sorting_test_unsecure endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/address_sorting_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/address_sorting_test.o: $(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_address_sorting_test_unsecure: $(ADDRESS_SORTING_TEST_UNSECURE_OBJS:.o=.dep) @@ -24473,16 +24450,16 @@ $(BINDIR)/$(CONFIG)/address_sorting_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/address_sorting_test: $(PROTOBUF_DEP) $(ADDRESS_SORTING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/address_sorting_test: $(PROTOBUF_DEP) $(ADDRESS_SORTING_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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ADDRESS_SORTING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/address_sorting_test + $(Q) $(LDXX) $(LDFLAGS) $(ADDRESS_SORTING_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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/address_sorting_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/address_sorting_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/address_sorting_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)/libgrpc++_test_config.a deps_address_sorting_test: $(ADDRESS_SORTING_TEST_OBJS:.o=.dep) @@ -24516,16 +24493,16 @@ $(BINDIR)/$(CONFIG)/cancel_ares_query_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cancel_ares_query_test: $(PROTOBUF_DEP) $(CANCEL_ARES_QUERY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/cancel_ares_query_test: $(PROTOBUF_DEP) $(CANCEL_ARES_QUERY_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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CANCEL_ARES_QUERY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cancel_ares_query_test + $(Q) $(LDXX) $(LDFLAGS) $(CANCEL_ARES_QUERY_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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cancel_ares_query_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/cancel_ares_query_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/cancel_ares_query_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)/libgrpc++_test_config.a deps_cancel_ares_query_test: $(CANCEL_ARES_QUERY_TEST_OBJS:.o=.dep) @@ -24551,16 +24528,16 @@ else -$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry: $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry: $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_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) $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/security/alts_credentials_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/alts_credentials_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_alts_credentials_fuzzer_one_entry: $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24586,16 +24563,16 @@ else -$(BINDIR)/$(CONFIG)/api_fuzzer_one_entry: $(API_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/api_fuzzer_one_entry: $(API_FUZZER_ONE_ENTRY_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) $(API_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/api_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(API_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/api_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/api_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/api_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_api_fuzzer_one_entry: $(API_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24621,16 +24598,16 @@ else -$(BINDIR)/$(CONFIG)/client_fuzzer_one_entry: $(CLIENT_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_fuzzer_one_entry: $(CLIENT_FUZZER_ONE_ENTRY_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) $(CLIENT_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/client_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(CLIENT_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/client_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/client_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/client_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_fuzzer_one_entry: $(CLIENT_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24656,16 +24633,16 @@ else -$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry: $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry: $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_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) $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hpack_parser_fuzzer_test_one_entry: $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24691,16 +24668,16 @@ else -$(BINDIR)/$(CONFIG)/http_request_fuzzer_test_one_entry: $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_request_fuzzer_test_one_entry: $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_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) $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_request_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_request_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/http/request_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/request_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_request_fuzzer_test_one_entry: $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24726,16 +24703,16 @@ else -$(BINDIR)/$(CONFIG)/http_response_fuzzer_test_one_entry: $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_response_fuzzer_test_one_entry: $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_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) $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_response_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_response_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/http/response_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/http/response_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_response_fuzzer_test_one_entry: $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24761,16 +24738,16 @@ else -$(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry: $(JSON_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry: $(JSON_FUZZER_TEST_ONE_ENTRY_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) $(JSON_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(JSON_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/json/fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/json/fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_fuzzer_test_one_entry: $(JSON_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24796,16 +24773,16 @@ else -$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry: $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry: $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_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) $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_response.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_response.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nanopb_fuzzer_response_test_one_entry: $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24831,16 +24808,16 @@ else -$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry: $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry: $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_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) $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_serverlist.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_serverlist.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nanopb_fuzzer_serverlist_test_one_entry: $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24866,16 +24843,16 @@ else -$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_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) $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24901,16 +24878,16 @@ else -$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_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) $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24936,16 +24913,16 @@ else -$(BINDIR)/$(CONFIG)/server_fuzzer_one_entry: $(SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_fuzzer_one_entry: $(SERVER_FUZZER_ONE_ENTRY_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) $(SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_fuzzer_one_entry: $(SERVER_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24971,16 +24948,16 @@ else -$(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry: $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry: $(SSL_SERVER_FUZZER_ONE_ENTRY_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) $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ssl_server_fuzzer_one_entry: $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -25006,16 +24983,16 @@ else -$(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry: $(URI_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry: $(URI_FUZZER_TEST_ONE_ENTRY_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) $(URI_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(URI_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_uri_fuzzer_test_one_entry: $(URI_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) diff --git a/build.yaml b/build.yaml index 1e63933f555..74506219d6c 100644 --- a/build.yaml +++ b/build.yaml @@ -913,6 +913,7 @@ filegroups: - test/core/util/port_server_client.h - test/core/util/slice_splitter.h - test/core/util/subprocess.h + - test/core/util/test_config.h - test/core/util/tracer_util.h - test/core/util/trickle_endpoint.h src: @@ -935,10 +936,10 @@ filegroups: - 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/tracer_util.cc - test/core/util/trickle_endpoint.cc deps: - - gpr_test_util - gpr uses: - cmdline @@ -1499,16 +1500,6 @@ libs: filegroups: - gpr_base secure: false -- name: gpr_test_util - build: private - language: c - headers: - - test/core/util/test_config.h - src: - - test/core/util/test_config.cc - deps: - - gpr - secure: false - name: grpc build: all language: c @@ -1571,7 +1562,6 @@ libs: - test/core/end2end/data/test_root_cert.cc - test/core/security/oauth2_utils.cc deps: - - gpr_test_util - gpr - grpc filegroups: @@ -1581,7 +1571,6 @@ libs: language: c deps: - gpr - - gpr_test_util - grpc_unsecure filegroups: - grpc_test_util_base @@ -1628,7 +1617,6 @@ libs: - test_tcp_server - grpc_test_util - grpc - - gpr_test_util - gpr - name: test_tcp_server build: private @@ -1640,7 +1628,6 @@ libs: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc++ build: all @@ -1965,7 +1952,6 @@ libs: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: interop_server_helper @@ -1995,7 +1981,6 @@ libs: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: interop_server_main @@ -2068,7 +2053,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: alloc_test @@ -2077,8 +2061,9 @@ targets: src: - test/core/gpr/alloc_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: alpn_test build: test @@ -2088,7 +2073,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: alts_credentials_fuzzer build: fuzzer @@ -2098,7 +2082,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/security/corpus/alts_credentials_corpus @@ -2111,7 +2094,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/end2end/fuzzers/api_fuzzer_corpus @@ -2124,8 +2106,9 @@ targets: src: - test/core/gpr/arena_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: avl_test build: test @@ -2133,8 +2116,8 @@ targets: src: - test/core/avl/avl_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util - grpc uses_polling: false - name: bad_server_response_test @@ -2146,7 +2129,6 @@ targets: - test_tcp_server - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2176,7 +2158,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2190,7 +2171,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: check_epollexclusive build: tool @@ -2208,7 +2188,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: chttp2_stream_map_test @@ -2219,7 +2198,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: chttp2_varint_test @@ -2230,7 +2208,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: client_fuzzer @@ -2241,7 +2218,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/end2end/fuzzers/client_fuzzer_corpus @@ -2254,8 +2230,8 @@ targets: - test/core/util/cmdline_test.cc deps: - gpr - - gpr_test_util - grpc_test_util + - grpc uses_polling: false - name: combiner_test cpu_cost: 10 @@ -2266,7 +2242,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: compression_test build: test @@ -2276,7 +2251,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: concurrent_connectivity_test @@ -2288,7 +2262,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2301,7 +2274,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: dns_resolver_connectivity_test cpu_cost: 0.1 @@ -2312,7 +2284,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2324,7 +2295,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: dns_resolver_test build: test @@ -2334,7 +2304,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: dualstack_socket_test cpu_cost: 0.1 @@ -2345,7 +2314,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2361,7 +2329,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2374,7 +2341,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: ev_epollex_linux_test @@ -2386,7 +2352,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2400,7 +2365,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: fake_transport_security_test build: test @@ -2408,8 +2372,8 @@ targets: src: - test/core/tsi/fake_transport_security_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util - grpc filegroups: - transport_security_test_lib @@ -2425,7 +2389,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2441,7 +2404,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2458,7 +2420,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: fling_server build: test @@ -2469,7 +2430,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: fling_stream_test cpu_cost: 1.5 @@ -2480,7 +2440,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -2495,7 +2454,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -2507,8 +2465,9 @@ targets: src: - test/core/gprpp/fork_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure platforms: - mac - linux @@ -2522,7 +2481,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2537,8 +2495,9 @@ targets: src: - test/core/gpr/cpu_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_env_test build: test @@ -2546,8 +2505,9 @@ targets: src: - test/core/gpr/env_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_host_port_test build: test @@ -2555,8 +2515,9 @@ targets: src: - test/core/gpr/host_port_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_log_test build: test @@ -2564,8 +2525,9 @@ targets: src: - test/core/gpr/log_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_manual_constructor_test cpu_cost: 3 @@ -2574,8 +2536,9 @@ targets: src: - test/core/gprpp/manual_constructor_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_mpscq_test cpu_cost: 30 @@ -2584,8 +2547,9 @@ targets: src: - test/core/gpr/mpscq_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_spinlock_test cpu_cost: 3 @@ -2594,8 +2558,9 @@ targets: src: - test/core/gpr/spinlock_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_string_test build: test @@ -2603,8 +2568,9 @@ targets: src: - test/core/gpr/string_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_sync_test cpu_cost: 10 @@ -2613,8 +2579,9 @@ targets: src: - test/core/gpr/sync_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_thd_test cpu_cost: 10 @@ -2623,8 +2590,9 @@ targets: src: - test/core/gprpp/thd_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_time_test build: test @@ -2632,8 +2600,9 @@ targets: src: - test/core/gpr/time_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_tls_test build: test @@ -2641,8 +2610,9 @@ targets: src: - test/core/gpr/tls_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_useful_test build: test @@ -2650,8 +2620,9 @@ targets: src: - test/core/gpr/useful_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: grpc_auth_context_test build: test @@ -2661,7 +2632,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_b64_test @@ -2672,7 +2642,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_byte_buffer_reader_test @@ -2683,7 +2652,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_channel_args_test @@ -2694,7 +2662,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_channel_stack_builder_test @@ -2705,7 +2672,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_channel_stack_test build: test @@ -2715,7 +2681,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_completion_queue_test @@ -2726,7 +2691,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_completion_queue_threading_test build: test @@ -2736,7 +2700,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2760,7 +2723,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_fetch_oauth2 build: test @@ -2771,7 +2733,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_ipv6_loopback_available_test build: test @@ -2781,7 +2742,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2793,7 +2753,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - linux @@ -2808,7 +2767,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_print_google_default_creds_token @@ -2830,7 +2788,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_ssl_credentials_test build: test @@ -2840,7 +2797,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_verify_jwt build: tool @@ -2861,7 +2817,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2879,7 +2834,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2897,7 +2851,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2912,7 +2865,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2936,7 +2888,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/transport/chttp2/hpack_parser_corpus @@ -2950,7 +2901,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: hpack_table_test @@ -2961,7 +2911,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: http_parser_test @@ -2972,7 +2921,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: http_request_fuzzer_test @@ -2983,7 +2931,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/http/request_corpus @@ -2996,7 +2943,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/http/response_corpus @@ -3009,7 +2955,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: httpcli_test cpu_cost: 0.5 @@ -3020,7 +2965,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -3035,7 +2979,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - linux @@ -3047,7 +2990,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: inproc_callback_test @@ -3060,7 +3002,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: invalid_call_argument_test @@ -3072,7 +3013,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: json_fuzzer_test build: fuzzer @@ -3082,7 +3022,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/json/corpus @@ -3096,7 +3035,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: json_rewrite_test @@ -3107,7 +3045,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: json_stream_error_test @@ -3118,7 +3055,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: json_test @@ -3129,7 +3065,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: lame_client_test @@ -3140,7 +3075,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: load_file_test build: test @@ -3150,7 +3084,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: low_level_ping_pong_benchmark @@ -3161,7 +3094,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -3176,7 +3108,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: memory_usage_server @@ -3188,7 +3119,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: memory_usage_test cpu_cost: 1.5 @@ -3199,7 +3129,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -3213,7 +3142,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: minimal_stack_is_minimal_test @@ -3224,7 +3152,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: multiple_server_queues_test @@ -3235,7 +3162,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: murmur_hash_test build: test @@ -3243,8 +3169,9 @@ targets: src: - test/core/gpr/murmur_hash_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: nanopb_fuzzer_response_test build: fuzzer @@ -3254,7 +3181,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/nanopb/corpus_response @@ -3267,7 +3193,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/nanopb/corpus_serverlist @@ -3281,7 +3206,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: num_external_connectivity_watchers_test build: test @@ -3291,7 +3215,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3303,7 +3226,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: percent_decode_fuzzer @@ -3314,7 +3236,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/slice/percent_decode_corpus @@ -3327,7 +3248,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/slice/percent_encode_corpus @@ -3340,7 +3260,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: resolve_address_posix_test @@ -3351,7 +3270,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3367,7 +3285,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr args: - --resolver=ares @@ -3379,7 +3296,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr args: - --resolver=native @@ -3392,7 +3308,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: secure_channel_create_test build: test @@ -3402,7 +3317,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: secure_endpoint_test build: test @@ -3412,7 +3326,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3424,7 +3337,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3436,7 +3348,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: server_fuzzer build: fuzzer @@ -3446,7 +3357,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/end2end/fuzzers/server_fuzzer_corpus @@ -3460,7 +3370,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: slice_buffer_test build: test @@ -3470,7 +3379,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: slice_string_helpers_test @@ -3481,7 +3389,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: slice_test @@ -3492,7 +3399,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: sockaddr_resolver_test @@ -3503,7 +3409,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: sockaddr_utils_test build: test @@ -3513,7 +3418,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: socket_utils_test build: test @@ -3523,7 +3427,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3539,7 +3442,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/security/corpus/ssl_server_corpus @@ -3550,8 +3452,8 @@ targets: src: - test/core/tsi/ssl_transport_security_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util - grpc filegroups: - transport_security_test_lib @@ -3567,7 +3469,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: stream_compression_test @@ -3578,7 +3479,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: stream_owned_slice_test @@ -3589,7 +3489,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: tcp_client_posix_test @@ -3601,7 +3500,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3618,7 +3516,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - native @@ -3631,7 +3528,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3647,7 +3543,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3663,7 +3558,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - native @@ -3675,7 +3569,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: timeout_encoding_test @@ -3686,7 +3579,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: timer_heap_test @@ -3697,7 +3589,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3710,7 +3601,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3723,7 +3613,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: transport_metadata_test build: test @@ -3733,7 +3622,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: transport_security_test build: test @@ -3743,7 +3631,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - linux @@ -3757,7 +3644,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3773,7 +3659,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/client_channel/uri_corpus @@ -3786,7 +3671,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: wakeup_fd_cv_test build: test @@ -3796,7 +3680,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3815,7 +3698,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - name: alts_counter_test build: test @@ -3833,8 +3715,8 @@ targets: - test/core/tsi/alts/crypt/aes_gcm_test.cc deps: - alts_test_util - - gpr_test_util - gpr + - grpc_test_util - grpc - name: alts_crypter_test build: test @@ -3947,7 +3829,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: auth_property_iterator_test gtest: true @@ -3960,7 +3841,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses_polling: false - name: backoff_test @@ -3971,7 +3851,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: bdp_estimator_test @@ -3984,7 +3863,6 @@ targets: - grpc++ - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: bm_arena @@ -3999,7 +3877,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4021,7 +3898,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4043,7 +3919,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4065,7 +3940,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4087,7 +3961,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4108,7 +3981,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4129,7 +4001,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4150,7 +4021,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4172,7 +4042,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4196,7 +4065,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4223,7 +4091,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4248,7 +4115,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4277,7 +4143,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4302,7 +4167,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4324,7 +4188,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4342,7 +4205,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: channel_arguments_test @@ -4378,7 +4240,6 @@ targets: - grpc++_test_util - grpc++ - grpc - - gpr_test_util - gpr filegroups: - grpcpp_channelz_proto @@ -4395,7 +4256,6 @@ targets: - grpc++_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -4412,7 +4272,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr filegroups: - grpcpp_channelz_proto @@ -4427,7 +4286,6 @@ targets: - grpc++_test_util - grpc++ - grpc - - gpr_test_util - gpr filegroups: - grpcpp_channelz_proto @@ -4458,7 +4316,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: true - name: cli_call_test @@ -4473,7 +4330,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_callback_end2end_test gtest: true @@ -4487,7 +4343,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_channel_stress_test gtest: false @@ -4502,7 +4357,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_crash_test gtest: true @@ -4516,7 +4370,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr platforms: - mac @@ -4533,7 +4386,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_interceptors_end2end_test gtest: true @@ -4550,7 +4402,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_lb_end2end_test gtest: true @@ -4563,7 +4414,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: codegen_test_full gtest: true @@ -4616,7 +4466,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: credentials_test @@ -4639,7 +4488,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses_polling: false - name: cxx_slice_test @@ -4652,7 +4500,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses_polling: false - name: cxx_string_ref_test @@ -4675,7 +4522,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses_polling: false - name: end2end_test @@ -4693,7 +4539,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: error_details_test gtest: true @@ -4716,7 +4561,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: filter_end2end_test gtest: true @@ -4729,7 +4573,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: generic_end2end_test gtest: true @@ -4742,7 +4585,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: golden_file_test gtest: true @@ -4804,7 +4646,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_node_plugin build: protoc @@ -4862,7 +4703,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr filegroups: - grpc++_codegen_proto @@ -4890,7 +4730,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: h2_ssl_cert_test gtest: true @@ -4904,7 +4743,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -4920,7 +4758,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -4935,7 +4772,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: http2_client build: test @@ -4964,7 +4800,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: inlined_vector_test gtest: true @@ -4976,7 +4811,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -4992,7 +4826,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5011,7 +4844,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5031,7 +4863,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5047,7 +4878,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5065,7 +4895,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5082,7 +4911,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5115,7 +4943,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: nonblocking_test gtest: true @@ -5128,7 +4955,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: noop-benchmark build: test @@ -5148,7 +4974,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5165,7 +4990,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: proto_utils_test gtest: true @@ -5192,7 +5016,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5213,7 +5036,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: qps_openloop_test @@ -5229,7 +5051,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5252,7 +5073,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: raw_end2end_test @@ -5266,7 +5086,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: reconnect_interop_client build: test @@ -5282,7 +5101,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: reconnect_interop_server @@ -5301,7 +5119,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: ref_counted_ptr_test @@ -5314,7 +5131,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5328,7 +5144,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5341,7 +5156,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: secure_auth_context_test @@ -5355,7 +5169,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: secure_sync_unary_ping_pong_test build: test @@ -5369,7 +5182,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5387,7 +5199,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: server_builder_test gtest: true @@ -5400,7 +5211,6 @@ targets: deps: - grpc++_test_util_unsecure - grpc_test_util_unsecure - - gpr_test_util - grpc++_unsecure - grpc_unsecure - gpr @@ -5415,7 +5225,6 @@ targets: deps: - grpc++_test_util_unsecure - grpc_test_util_unsecure - - gpr_test_util - grpc++_unsecure - grpc_unsecure - gpr @@ -5431,7 +5240,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5447,7 +5255,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr platforms: - mac @@ -5464,7 +5271,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: server_early_return_test gtest: true @@ -5477,7 +5283,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: server_interceptors_end2end_test gtest: true @@ -5494,7 +5299,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: server_request_call_test gtest: true @@ -5507,7 +5311,6 @@ targets: deps: - grpc++_test_util_unsecure - grpc_test_util_unsecure - - gpr_test_util - grpc++_unsecure - grpc_unsecure - gpr @@ -5522,7 +5325,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: slice_hash_table_test gtest: true @@ -5533,7 +5335,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: slice_weak_hash_table_test @@ -5545,7 +5346,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: stats_test @@ -5558,7 +5358,6 @@ targets: - grpc++_test_util - grpc_test_util - grpc - - gpr_test_util - gpr exclude_configs: - tsan @@ -5594,7 +5393,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr platforms: - mac @@ -5624,7 +5422,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: thread_manager_test @@ -5649,7 +5446,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - name: transport_pid_controller_test build: test @@ -5661,7 +5457,6 @@ targets: - grpc++ - grpc_test_util - grpc - - gpr_test_util - gpr - name: transport_security_common_api_test build: test @@ -5684,7 +5479,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr platforms: - mac diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 1d4e1ae35c0..c875fcb4306 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1196,9 +1196,7 @@ Pod::Spec.new do |s| ss.dependency "#{s.name}/Interface", version ss.dependency "#{s.name}/Implementation", version - ss.source_files = 'test/core/util/test_config.cc', - 'test/core/util/test_config.h', - 'test/core/end2end/data/client_certs.cc', + ss.source_files = 'test/core/end2end/data/client_certs.cc', 'test/core/end2end/data/server1_cert.cc', 'test/core/end2end/data/server1_key.cc', 'test/core/end2end/data/test_root_cert.cc', @@ -1221,6 +1219,7 @@ Pod::Spec.new do |s| '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/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', @@ -1245,6 +1244,7 @@ Pod::Spec.new do |s| 'test/core/util/port_server_client.h', 'test/core/util/slice_splitter.h', 'test/core/util/subprocess.h', + 'test/core/util/test_config.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 2b841354baf..d619f395bb4 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -258,16 +258,6 @@ 'src/core/lib/profiling/stap_timers.cc', ], }, - { - 'target_name': 'gpr_test_util', - 'type': 'static_library', - 'dependencies': [ - 'gpr', - ], - 'sources': [ - 'test/core/util/test_config.cc', - ], - }, { 'target_name': 'grpc', 'type': 'static_library', @@ -604,7 +594,6 @@ 'target_name': 'grpc_test_util', 'type': 'static_library', 'dependencies': [ - 'gpr_test_util', 'gpr', 'grpc', ], @@ -633,6 +622,7 @@ '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/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', @@ -850,7 +840,6 @@ 'type': 'static_library', 'dependencies': [ 'gpr', - 'gpr_test_util', 'grpc_unsecure', ], 'sources': [ @@ -873,6 +862,7 @@ '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/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', @@ -1351,7 +1341,6 @@ 'test_tcp_server', 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr', ], 'sources': [ @@ -1364,7 +1353,6 @@ 'dependencies': [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr', ], 'sources': [ @@ -1679,7 +1667,6 @@ 'grpc_test_util', 'grpc++', 'grpc', - 'gpr_test_util', 'gpr', 'grpc++_test_config', ], @@ -1714,7 +1701,6 @@ 'grpc_test_util', 'grpc++', 'grpc', - 'gpr_test_util', 'gpr', 'grpc++_test_config', ], @@ -2667,7 +2653,6 @@ 'dependencies': [ 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr', ], 'sources': [ @@ -2680,7 +2665,6 @@ 'dependencies': [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr', ], 'sources': [ @@ -2772,7 +2756,6 @@ 'dependencies': [ 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr', ], 'sources': [ diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 67cf5d89bff..aaa6939c90c 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -195,3 +195,7 @@ int grpc_is_initialized(void) { gpr_mu_unlock(&g_init_mu); return r; } + +void grpc_test_x(void) { + gpr_log(GPR_ERROR, "X"); +} diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h index 193f51447d9..2b3e6a64e78 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_test_x(void); #endif /* GRPC_CORE_LIB_SURFACE_INIT_H */ diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py index 32afba5b1f5..6a40b4e5e9d 100755 --- a/test/core/bad_client/gen_build_yaml.py +++ b/test/core/bad_client/gen_build_yaml.py @@ -56,7 +56,6 @@ def main(): 'deps': [ 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr' ] }], @@ -74,7 +73,6 @@ def main(): 'bad_client_test', 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr' ] } diff --git a/test/core/bad_ssl/gen_build_yaml.py b/test/core/bad_ssl/gen_build_yaml.py index 6b78e9c7aa4..52f49bea2ad 100755 --- a/test/core/bad_ssl/gen_build_yaml.py +++ b/test/core/bad_ssl/gen_build_yaml.py @@ -45,7 +45,6 @@ def main(): 'deps': [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr' ] } @@ -63,7 +62,6 @@ def main(): 'bad_ssl_test_server', 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr' ] } @@ -79,7 +77,6 @@ def main(): 'deps': [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr' ] } diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 601d3bac387..99063e13e64 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -281,13 +281,11 @@ def main(): sec_deps = [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr' ] unsec_deps = [ 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr' ] json = { diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index fe80bb2d4d0..5db409343b8 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_test_x(); } } // namespace testing } // namespace grpc diff --git a/test/cpp/naming/gen_build_yaml.py b/test/cpp/naming/gen_build_yaml.py index 1c9d0676b89..da0effed935 100755 --- a/test/cpp/naming/gen_build_yaml.py +++ b/test/cpp/naming/gen_build_yaml.py @@ -72,7 +72,6 @@ def main(): 'deps': [ 'grpc++_test_util' + unsecure_build_config_suffix, 'grpc_test_util' + unsecure_build_config_suffix, - 'gpr_test_util', 'grpc++' + unsecure_build_config_suffix, 'grpc' + unsecure_build_config_suffix, 'gpr', @@ -91,7 +90,6 @@ def main(): 'deps': [ 'grpc++_test_util', 'grpc_test_util', - 'gpr_test_util', 'grpc++', 'grpc', 'gpr', @@ -114,7 +112,6 @@ def main(): 'deps': [ 'grpc++_test_util' + unsecure_build_config_suffix, 'grpc_test_util' + unsecure_build_config_suffix, - 'gpr_test_util', 'grpc++' + unsecure_build_config_suffix, 'grpc' + unsecure_build_config_suffix, 'gpr', @@ -133,7 +130,6 @@ def main(): 'deps': [ 'grpc++_test_util', 'grpc_test_util', - 'gpr_test_util', 'grpc++', 'grpc', 'gpr', diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a7231554e3d..191b3872146 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -4,7 +4,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -21,7 +20,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -36,7 +36,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -53,7 +52,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -70,7 +68,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -87,7 +84,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -102,8 +100,8 @@ { "deps": [ "gpr", - "gpr_test_util", - "grpc" + "grpc", + "grpc_test_util" ], "headers": [], "is_filegroup": false, @@ -118,7 +116,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util", "test_tcp_server" @@ -166,7 +163,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -183,7 +179,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -215,7 +210,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -232,7 +226,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -249,7 +242,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -266,7 +258,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -283,7 +274,7 @@ { "deps": [ "gpr", - "gpr_test_util", + "grpc", "grpc_test_util" ], "headers": [], @@ -299,7 +290,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -316,7 +306,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -333,7 +322,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -350,7 +338,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -367,7 +354,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -384,7 +370,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -401,7 +386,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -418,7 +402,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -435,7 +418,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -452,7 +434,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -469,7 +450,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -486,7 +466,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -503,8 +482,8 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", + "grpc_test_util", "transport_security_test_lib" ], "headers": [], @@ -520,7 +499,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -537,7 +515,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -554,7 +531,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -571,7 +547,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -588,7 +563,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -605,7 +579,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -622,7 +595,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -637,7 +611,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -654,7 +627,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -669,7 +643,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -684,7 +659,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -699,7 +675,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -714,7 +691,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -729,7 +707,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -744,7 +723,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -759,7 +739,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -774,7 +755,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -789,7 +771,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -804,7 +787,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -819,7 +803,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -834,7 +819,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -849,7 +835,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -866,7 +851,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -883,7 +867,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -900,7 +883,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -917,7 +899,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -934,7 +915,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -951,7 +931,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -968,7 +947,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1001,7 +979,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1018,7 +995,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1035,7 +1011,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1052,7 +1027,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1069,7 +1043,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1102,7 +1075,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1119,7 +1091,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1152,7 +1123,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1169,7 +1139,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1190,7 +1159,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1211,7 +1179,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1243,7 +1210,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1260,7 +1226,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1277,7 +1242,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1294,7 +1258,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1311,7 +1274,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1328,7 +1290,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1345,7 +1306,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1362,7 +1322,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1379,7 +1338,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1396,7 +1354,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1413,7 +1370,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1433,7 +1389,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1450,7 +1405,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1467,7 +1421,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1484,7 +1437,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1501,7 +1453,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1518,7 +1469,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1535,7 +1485,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1552,7 +1501,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1569,7 +1517,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1586,7 +1533,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1603,7 +1549,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1620,7 +1565,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1637,7 +1581,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1654,7 +1597,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1671,7 +1613,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1688,7 +1629,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -1703,7 +1645,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1720,7 +1661,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1737,7 +1677,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1754,7 +1693,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1771,7 +1709,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1788,7 +1725,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1805,7 +1741,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1822,7 +1757,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1839,7 +1773,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1856,7 +1789,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1873,7 +1805,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1890,7 +1821,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1907,7 +1837,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1924,7 +1853,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1941,7 +1869,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1958,7 +1885,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1975,7 +1901,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1992,7 +1917,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2009,7 +1933,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2026,7 +1949,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2043,7 +1965,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2060,7 +1981,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2077,7 +1997,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2094,7 +2013,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2111,7 +2029,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2128,8 +2045,8 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", + "grpc_test_util", "transport_security_test_lib" ], "headers": [], @@ -2145,7 +2062,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2162,7 +2078,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2179,7 +2094,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2196,7 +2110,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2213,7 +2126,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2230,7 +2142,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2247,7 +2158,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2264,7 +2174,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2281,7 +2190,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2298,7 +2206,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2315,7 +2222,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2332,7 +2238,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2349,7 +2254,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2366,7 +2270,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2383,7 +2286,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2400,7 +2302,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2417,7 +2318,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2434,7 +2334,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2451,7 +2350,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2468,7 +2366,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -2504,8 +2401,8 @@ "deps": [ "alts_test_util", "gpr", - "gpr_test_util", - "grpc" + "grpc", + "grpc_test_util" ], "headers": [], "is_filegroup": false, @@ -2696,7 +2593,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -2715,7 +2611,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -2734,7 +2629,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2751,7 +2645,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -2771,7 +2664,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2793,7 +2685,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2815,7 +2706,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2837,7 +2727,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2859,7 +2748,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2881,7 +2769,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2903,7 +2790,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2925,7 +2811,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2947,7 +2832,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2969,7 +2853,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2994,7 +2877,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3019,7 +2901,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3041,7 +2922,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3066,7 +2946,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3088,7 +2967,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3109,7 +2987,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -3158,7 +3035,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3179,7 +3055,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3199,7 +3074,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3220,7 +3094,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3271,7 +3144,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -3288,7 +3160,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3308,7 +3179,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3327,7 +3197,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3350,7 +3219,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3369,7 +3237,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3388,7 +3255,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3411,7 +3277,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3510,7 +3375,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -3543,7 +3407,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc_test_util" @@ -3561,7 +3424,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc_test_util" @@ -3594,7 +3456,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc_test_util" @@ -3612,7 +3473,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3654,7 +3514,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3673,7 +3532,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3692,7 +3550,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3793,7 +3650,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -3880,7 +3736,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_codegen_proto", @@ -3931,7 +3786,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3954,7 +3808,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3976,7 +3829,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3998,7 +3850,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4034,7 +3885,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4053,7 +3903,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4072,7 +3921,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4094,7 +3942,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4114,7 +3961,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4135,7 +3981,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++_test_config", "grpc_test_util" @@ -4153,7 +3998,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4173,7 +4017,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4215,7 +4058,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4239,7 +4081,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4272,7 +4113,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4291,7 +4131,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_proto_reflection_desc_db", @@ -4329,7 +4168,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4350,7 +4188,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4372,7 +4209,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4394,7 +4230,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4421,7 +4256,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4440,7 +4274,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4470,7 +4303,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4502,7 +4334,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4521,7 +4352,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4540,7 +4370,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -4557,7 +4386,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4576,7 +4404,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4598,7 +4425,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4617,7 +4443,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -4643,7 +4468,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -4669,7 +4493,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4688,7 +4511,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4707,7 +4529,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4726,7 +4547,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4745,7 +4565,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4768,7 +4587,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -4794,7 +4612,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4813,7 +4630,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -4830,7 +4646,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -4847,7 +4662,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++_test_util", "grpc_test_util" @@ -4893,7 +4707,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4912,7 +4725,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4975,7 +4787,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -4994,7 +4805,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -5029,7 +4839,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -5817,7 +5626,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5835,7 +5643,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5853,7 +5660,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5871,7 +5677,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5889,7 +5694,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5907,7 +5711,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5925,7 +5728,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5943,7 +5745,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5961,7 +5762,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5979,7 +5779,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5997,7 +5796,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6015,7 +5813,6 @@ "deps": [ "bad_ssl_test_server", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6032,7 +5829,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6050,7 +5846,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6068,7 +5863,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6086,7 +5880,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6104,7 +5897,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6122,7 +5914,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6140,7 +5931,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6158,7 +5948,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6176,7 +5965,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6194,7 +5982,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6212,7 +5999,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6230,7 +6016,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6248,7 +6033,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6266,7 +6050,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6284,7 +6067,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6302,7 +6084,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6320,7 +6101,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6338,7 +6118,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6356,7 +6135,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6374,7 +6152,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6392,7 +6169,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6410,7 +6186,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6428,7 +6203,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6446,7 +6220,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6464,7 +6237,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6482,7 +6254,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6500,7 +6271,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6518,7 +6288,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6536,7 +6305,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6554,7 +6322,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6572,7 +6339,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6590,7 +6356,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6608,7 +6373,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6625,7 +6389,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -6645,7 +6408,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6665,7 +6427,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6685,7 +6446,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6705,7 +6465,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -6725,7 +6484,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6745,7 +6503,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6765,7 +6522,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6783,7 +6539,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6801,7 +6556,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6819,7 +6573,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6837,7 +6590,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6855,7 +6607,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6873,7 +6624,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6891,7 +6641,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6909,7 +6658,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6927,7 +6675,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6945,7 +6692,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6963,7 +6709,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6981,7 +6726,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6999,7 +6743,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -7069,23 +6812,6 @@ "third_party": false, "type": "lib" }, - { - "deps": [ - "gpr" - ], - "headers": [ - "test/core/util/test_config.h" - ], - "is_filegroup": false, - "language": "c", - "name": "gpr_test_util", - "src": [ - "test/core/util/test_config.cc", - "test/core/util/test_config.h" - ], - "third_party": false, - "type": "lib" - }, { "deps": [ "census", @@ -7142,7 +6868,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util_base" ], @@ -7168,7 +6893,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc_test_util_base", "grpc_unsecure" ], @@ -7217,7 +6941,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util", "test_tcp_server" @@ -7238,7 +6961,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -7745,7 +7467,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -7800,7 +7521,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -8887,7 +8607,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -8907,7 +8626,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -8927,7 +8645,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -9028,7 +8745,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -10644,7 +10360,6 @@ "deps": [ "cmdline", "gpr", - "gpr_test_util", "grpc_base", "grpc_client_channel", "grpc_transport_chttp2" @@ -10667,6 +10382,7 @@ "test/core/util/port_server_client.h", "test/core/util/slice_splitter.h", "test/core/util/subprocess.h", + "test/core/util/test_config.h", "test/core/util/tracer_util.h", "test/core/util/trickle_endpoint.h" ], @@ -10710,6 +10426,8 @@ "test/core/util/subprocess.h", "test/core/util/subprocess_posix.cc", "test/core/util/subprocess_windows.cc", + "test/core/util/test_config.cc", + "test/core/util/test_config.h", "test/core/util/tracer_util.cc", "test/core/util/tracer_util.h", "test/core/util/trickle_endpoint.cc", From 88045f8440610676daa9cf429ba0cf55b4041bc5 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 6 Dec 2018 13:43:46 -0800 Subject: [PATCH 0467/2143] podsec fix --- templates/gRPC-C++.podspec.template | 4 ++-- templates/gRPC-Core.podspec.template | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template index ab330415af2..a3336f50e64 100644 --- a/templates/gRPC-C++.podspec.template +++ b/templates/gRPC-C++.podspec.template @@ -96,11 +96,11 @@ return out def grpc_test_util_files(libs): - out = grpc_lib_files(libs, ("grpc_test_util", "gpr_test_util"), ("src", "headers")) + out = grpc_lib_files(libs, ("grpc_test_util",), ("src", "headers")) return out def grpc_test_util_headers(libs): - out = grpc_lib_files(libs, ("grpc_test_util", "gpr_test_util"), ("headers",)) + out = grpc_lib_files(libs, ("grpc_test_util",), ("headers",)) return out # Tests subspec is currently disabled since the tests currently use `grpc++` include style instead of `grpcpp`. diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 98b6344a4bf..461e8b767ff 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -59,7 +59,7 @@ return [file for file in out if not file in excl] def grpc_test_util_files(libs): - out = grpc_lib_files(libs, ("grpc_test_util", "gpr_test_util"), ("src", "headers")) + out = grpc_lib_files(libs, ("grpc_test_util",), ("src", "headers")) excl = grpc_private_files(libs) return [file for file in out if not file in excl] From 67742ef63fd13630461abb1287298e8f262276bb Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 6 Dec 2018 14:05:38 -0800 Subject: [PATCH 0468/2143] Fix BUILD files. Manually edit bzl files --- test/core/avl/BUILD | 2 +- test/core/backoff/BUILD | 1 - test/core/channel/BUILD | 35 ++++++--------- test/core/client_channel/BUILD | 1 - test/core/client_channel/resolvers/BUILD | 5 --- test/core/compression/BUILD | 4 -- test/core/debug/BUILD | 1 - test/core/end2end/BUILD | 9 ---- test/core/end2end/generate_tests.bzl | 2 - test/core/fling/BUILD | 4 -- test/core/gpr/BUILD | 28 ++++++------ test/core/gprpp/BUILD | 16 +++---- test/core/handshake/BUILD | 16 +++---- test/core/http/BUILD | 16 +++---- test/core/iomgr/BUILD | 24 ---------- test/core/json/BUILD | 8 +--- test/core/memory_usage/BUILD | 11 ++--- test/core/network_benchmarks/BUILD | 9 ++-- test/core/security/BUILD | 27 ++++-------- test/core/slice/BUILD | 7 --- test/core/surface/BUILD | 13 ------ test/core/transport/BUILD | 36 ++++++--------- test/core/transport/chttp2/BUILD | 17 ++----- test/core/tsi/BUILD | 22 +++++----- test/core/tsi/alts/crypt/BUILD | 10 +++-- test/core/tsi/alts/fake_handshaker/BUILD | 7 ++- test/core/tsi/alts/frame_protector/BUILD | 12 ++--- test/core/tsi/alts/handshaker/BUILD | 23 +++++----- .../tsi/alts/zero_copy_frame_protector/BUILD | 8 ++-- test/core/util/BUILD | 34 +++++--------- test/cpp/client/BUILD | 3 +- test/cpp/codegen/BUILD | 42 +++++++++--------- test/cpp/common/BUILD | 44 +++++++++---------- test/cpp/end2end/BUILD | 28 +----------- test/cpp/ext/filters/census/BUILD | 5 +-- test/cpp/grpclb/BUILD | 1 - test/cpp/interop/BUILD | 1 - test/cpp/microbenchmarks/BUILD | 2 +- test/cpp/naming/BUILD | 14 +++--- .../generate_resolver_component_tests.bzl | 3 -- test/cpp/qps/BUILD | 3 -- test/cpp/qps/qps_benchmark_script.bzl | 1 - test/cpp/server/BUILD | 18 ++++---- test/cpp/server/load_reporter/BUILD | 2 - test/cpp/test/BUILD | 1 - test/cpp/thread_manager/BUILD | 1 - test/cpp/util/BUILD | 14 +++--- 47 files changed, 212 insertions(+), 379 deletions(-) diff --git a/test/core/avl/BUILD b/test/core/avl/BUILD index 48f5baeb1a5..c31abebcbe5 100644 --- a/test/core/avl/BUILD +++ b/test/core/avl/BUILD @@ -25,6 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/backoff/BUILD b/test/core/backoff/BUILD index 6fbd6542d49..e4fc2871054 100644 --- a/test/core/backoff/BUILD +++ b/test/core/backoff/BUILD @@ -33,7 +33,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/channel/BUILD b/test/core/channel/BUILD index da419f00cf9..3249a16edda 100644 --- a/test/core/channel/BUILD +++ b/test/core/channel/BUILD @@ -25,7 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,7 +36,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +47,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +58,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -69,62 +65,59 @@ grpc_cc_test( grpc_cc_test( name = "channel_trace_test", srcs = ["channel_trace_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:channel_trace_proto_helper", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "channelz_test", srcs = ["channelz_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:channel_trace_proto_helper", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "channelz_registry_test", srcs = ["channelz_registry_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "status_util_test", srcs = ["status_util_test.cc"], - language = "C++", - deps = [ - "//:grpc", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + language = "C++", + deps = [ + "//:grpc", + "//test/core/util:grpc_test_util", + ], ) diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD index db98ffab77b..04485f5240f 100644 --- a/test/core/client_channel/BUILD +++ b/test/core/client_channel/BUILD @@ -64,7 +64,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/client_channel/resolvers/BUILD b/test/core/client_channel/resolvers/BUILD index d8b03958461..3dbee5c9e6d 100644 --- a/test/core/client_channel/resolvers/BUILD +++ b/test/core/client_channel/resolvers/BUILD @@ -25,7 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,7 +36,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +47,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +58,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -74,7 +70,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:grpc_resolver_fake", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/compression/BUILD b/test/core/compression/BUILD index 532972c784e..03c82689a85 100644 --- a/test/core/compression/BUILD +++ b/test/core/compression/BUILD @@ -25,7 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,7 +36,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +47,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +58,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/debug/BUILD b/test/core/debug/BUILD index 1592472532b..c4209296702 100644 --- a/test/core/debug/BUILD +++ b/test/core/debug/BUILD @@ -28,7 +28,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index 398e8a2d9ad..1b4ad284994 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -78,7 +78,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -91,7 +90,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -104,7 +102,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -117,7 +114,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -130,7 +126,6 @@ grpc_cc_test( ":end2end_tests", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -143,7 +138,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -156,7 +150,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -169,7 +162,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -190,7 +182,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 81956db841f..dd9abedebdf 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -388,7 +388,6 @@ def grpc_end2end_tests(): ":end2end_tests", "//test/core/util:grpc_test_util", "//:grpc", - "//test/core/util:gpr_test_util", "//:gpr", ], ) @@ -440,7 +439,6 @@ def grpc_end2end_nosec_tests(): ":end2end_nosec_tests", "//test/core/util:grpc_test_util_unsecure", "//:grpc_unsecure", - "//test/core/util:gpr_test_util", "//:gpr", ], ) diff --git a/test/core/fling/BUILD b/test/core/fling/BUILD index 268e94aacc1..5c6930cc85b 100644 --- a/test/core/fling/BUILD +++ b/test/core/fling/BUILD @@ -29,7 +29,6 @@ grpc_cc_binary( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -43,7 +42,6 @@ grpc_cc_binary( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -59,7 +57,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -75,7 +72,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/gpr/BUILD b/test/core/gpr/BUILD index 67657ee1ce9..434d55e0451 100644 --- a/test/core/gpr/BUILD +++ b/test/core/gpr/BUILD @@ -24,7 +24,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -34,7 +34,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -44,7 +44,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -54,7 +54,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -64,7 +64,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -74,7 +74,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -85,7 +85,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -95,7 +95,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -105,7 +105,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -115,7 +115,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -125,7 +125,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -135,7 +135,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -145,7 +145,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -155,6 +155,6 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD index e7232d9df81..fe3fea1df88 100644 --- a/test/core/gprpp/BUILD +++ b/test/core/gprpp/BUILD @@ -24,7 +24,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -34,7 +34,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -47,7 +47,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr_base", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -60,7 +60,7 @@ grpc_cc_test( language = "C++", deps = [ "//:inlined_vector", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -73,7 +73,7 @@ grpc_cc_test( language = "C++", deps = [ "//:orphanable", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -86,7 +86,7 @@ grpc_cc_test( language = "C++", deps = [ "//:ref_counted", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -100,7 +100,7 @@ grpc_cc_test( deps = [ "//:ref_counted", "//:ref_counted_ptr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -110,6 +110,6 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/handshake/BUILD b/test/core/handshake/BUILD index 712cd591977..b9d2f31515a 100644 --- a/test/core/handshake/BUILD +++ b/test/core/handshake/BUILD @@ -21,28 +21,26 @@ licenses(["notice"]) # Apache v2 grpc_cc_test( name = "client_ssl", srcs = ["client_ssl.cc"], - language = "C++", data = [ "//src/core/tsi/test_creds:ca.pem", "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) grpc_cc_library( name = "server_ssl_common", - hdrs = ["server_ssl_common.h"], srcs = ["server_ssl_common.cc"], + hdrs = ["server_ssl_common.h"], deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -50,17 +48,16 @@ grpc_cc_library( grpc_cc_test( name = "server_ssl", srcs = ["server_ssl.cc"], - language = "C++", data = [ "//src/core/tsi/test_creds:ca.pem", "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", ], + language = "C++", deps = [ ":server_ssl_common", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -68,17 +65,16 @@ grpc_cc_test( grpc_cc_test( name = "handshake_server_with_readahead_handshaker", srcs = ["readahead_handshaker_server_ssl.cc"], - language = "C++", data = [ "//src/core/tsi/test_creds:ca.pem", "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", ], + language = "C++", deps = [ ":server_ssl_common", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -86,17 +82,15 @@ grpc_cc_test( grpc_cc_test( name = "handshake_verify_peer_options", srcs = ["verify_peer_options.cc"], - language = "C++", data = [ "//src/core/tsi/test_creds:ca.pem", "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) - diff --git a/test/core/http/BUILD b/test/core/http/BUILD index be51ea07371..3e679262555 100644 --- a/test/core/http/BUILD +++ b/test/core/http/BUILD @@ -23,8 +23,8 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_fuzzer( name = "response_fuzzer", srcs = ["response_fuzzer.cc"], - language = "C++", corpus = "response_corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -35,8 +35,8 @@ grpc_fuzzer( grpc_fuzzer( name = "request_fuzzer", srcs = ["request_fuzzer.cc"], - language = "C++", corpus = "request_corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -65,18 +65,17 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_cc_test( name = "httpcli_test", srcs = ["httpcli_test.cc"], - language = "C++", data = [ "python_wrapper.sh", "test_server.py", + "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", - "//src/core/tsi/test_creds:server1.key" ], + language = "C++", deps = [ "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -84,19 +83,18 @@ grpc_cc_test( grpc_cc_test( name = "httpscli_test", srcs = ["httpscli_test.cc"], - language = "C++", data = [ "python_wrapper.sh", "test_server.py", "//src/core/tsi/test_creds:ca.pem", + "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", - "//src/core/tsi/test_creds:server1.key" ], + language = "C++", deps = [ "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -109,7 +107,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -122,7 +119,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index e278632e502..e920ceacf00 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -32,7 +32,6 @@ grpc_cc_library( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -45,7 +44,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -58,7 +56,6 @@ grpc_cc_test( ":endpoint_tests", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -71,7 +68,6 @@ grpc_cc_test( ":endpoint_tests", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -83,7 +79,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -95,7 +90,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -107,7 +101,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -119,7 +112,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -131,7 +123,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -143,7 +134,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -158,7 +148,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -173,7 +162,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -185,7 +173,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -197,7 +184,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -209,7 +195,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -221,7 +206,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -234,7 +218,6 @@ grpc_cc_test( ":endpoint_tests", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -246,7 +229,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -259,7 +241,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -271,7 +252,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -283,7 +263,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -295,7 +274,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -307,7 +285,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -319,7 +296,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/json/BUILD b/test/core/json/BUILD index b8b36c06528..5684505cbc9 100644 --- a/test/core/json/BUILD +++ b/test/core/json/BUILD @@ -23,8 +23,8 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_fuzzer( name = "json_fuzzer", srcs = ["fuzzer.cc"], - language = "C++", corpus = "corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -40,7 +40,6 @@ grpc_cc_binary( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -48,17 +47,16 @@ grpc_cc_binary( grpc_cc_test( name = "json_rewrite_test", srcs = ["json_rewrite_test.cc"], - language = "C++", data = [ "rewrite_test_input.json", "rewrite_test_output_condensed.json", "rewrite_test_output_indented.json", ":json_stream_error_test", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -70,7 +68,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -82,7 +79,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/memory_usage/BUILD b/test/core/memory_usage/BUILD index f39c309e369..2fe94dfa120 100644 --- a/test/core/memory_usage/BUILD +++ b/test/core/memory_usage/BUILD @@ -25,7 +25,6 @@ grpc_cc_library( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,24 +36,22 @@ grpc_cc_library( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/end2end:ssl_test_data", "//test/core/util:grpc_test_util", - "//test/core/end2end:ssl_test_data" ], ) grpc_cc_test( name = "memory_usage_test", srcs = ["memory_usage_test.cc"], - language = "C++", data = [ - ":client", - ":server", + ":client", + ":server", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/network_benchmarks/BUILD b/test/core/network_benchmarks/BUILD index e1b49536084..fbc611d5fe3 100644 --- a/test/core/network_benchmarks/BUILD +++ b/test/core/network_benchmarks/BUILD @@ -14,8 +14,12 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_cc_binary", "grpc_package") -grpc_package(name = "test/core/network_benchmarks", - features = ["-layering_check", "-parse_headers" ] +grpc_package( + name = "test/core/network_benchmarks", + features = [ + "-layering_check", + "-parse_headers", + ], ) licenses(["notice"]) # Apache v2 @@ -27,7 +31,6 @@ grpc_cc_binary( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/security/BUILD b/test/core/security/BUILD index b7de955cdbe..d8dcdc25231 100644 --- a/test/core/security/BUILD +++ b/test/core/security/BUILD @@ -23,8 +23,8 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_fuzzer( name = "alts_credentials_fuzzer", srcs = ["alts_credentials_fuzzer.cc"], - language = "C++", corpus = "corpus/alts_credentials_corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -35,8 +35,8 @@ grpc_fuzzer( grpc_fuzzer( name = "ssl_server_fuzzer", srcs = ["ssl_server_fuzzer.cc"], - language = "C++", corpus = "corpus/ssl_server_corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -50,8 +50,8 @@ grpc_cc_library( srcs = ["oauth2_utils.cc"], hdrs = ["oauth2_utils.h"], language = "C++", - deps = ["//:grpc"], visibility = ["//test/cpp:__subpackages__"], + deps = ["//:grpc"], ) grpc_cc_test( @@ -61,7 +61,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -73,7 +72,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -85,7 +83,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -97,12 +94,10 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) - grpc_cc_test( name = "secure_endpoint_test", srcs = ["secure_endpoint_test.cc"], @@ -111,7 +106,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/iomgr:endpoint_tests", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -123,7 +117,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -137,14 +130,13 @@ grpc_cc_test( "//test/core/security/etc:test_roots/cert2.pem", "//test/core/security/etc:test_roots/cert3.pem", ], - language = "C++", external_deps = [ "gtest", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -156,9 +148,8 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", - ] + ], ) grpc_cc_binary( @@ -204,7 +195,7 @@ grpc_cc_test( "//:gpr", "//:gpr_base", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -217,7 +208,7 @@ grpc_cc_test( "//:gpr", "//:gpr_base", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -229,7 +220,7 @@ grpc_cc_test( "//:alts_util", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -244,6 +235,6 @@ grpc_cc_test( "//:grpc_secure", "//:tsi", "//:tsi_interface", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/slice/BUILD b/test/core/slice/BUILD index 9a1a506a43c..12ee42ba9c3 100644 --- a/test/core/slice/BUILD +++ b/test/core/slice/BUILD @@ -51,7 +51,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -63,7 +62,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -75,7 +73,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -87,7 +84,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -102,7 +98,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -117,7 +112,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -129,7 +123,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/surface/BUILD b/test/core/surface/BUILD index 77df1cc989c..34777806cf2 100644 --- a/test/core/surface/BUILD +++ b/test/core/surface/BUILD @@ -25,7 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,7 +36,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +47,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +58,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -73,7 +69,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -85,7 +80,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -98,7 +92,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:cq_verifier", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -111,7 +104,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -123,7 +115,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -135,7 +126,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -148,7 +138,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -160,7 +149,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -172,7 +160,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/transport/BUILD b/test/core/transport/BUILD index 7ca1c1d9435..f38ecf2f66b 100644 --- a/test/core/transport/BUILD +++ b/test/core/transport/BUILD @@ -21,31 +21,29 @@ grpc_package(name = "test/core/transport") grpc_cc_test( name = "bdp_estimator_test", srcs = ["bdp_estimator_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "byte_stream_test", srcs = ["byte_stream_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( @@ -55,7 +53,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -67,7 +64,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -75,16 +71,15 @@ grpc_cc_test( grpc_cc_test( name = "pid_controller_test", srcs = ["pid_controller_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( @@ -94,7 +89,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -106,7 +100,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -118,7 +111,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -126,12 +118,12 @@ grpc_cc_test( grpc_cc_test( name = "status_metadata_test", srcs = ["status_metadata_test.cc"], - language = "C++", - deps = [ - "//:grpc", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + language = "C++", + deps = [ + "//:grpc", + "//test/core/util:grpc_test_util", + ], ) diff --git a/test/core/transport/chttp2/BUILD b/test/core/transport/chttp2/BUILD index 33437373e4e..e5c1a7cff70 100644 --- a/test/core/transport/chttp2/BUILD +++ b/test/core/transport/chttp2/BUILD @@ -37,7 +37,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +48,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +59,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -76,12 +73,10 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) - grpc_cc_test( name = "hpack_encoder_test", srcs = ["hpack_encoder_test.cc"], @@ -89,7 +84,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -101,7 +95,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -113,7 +106,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -125,7 +117,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -133,16 +124,15 @@ grpc_cc_test( grpc_cc_test( name = "settings_timeout_test", srcs = ["settings_timeout_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( @@ -152,7 +142,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/tsi/BUILD b/test/core/tsi/BUILD index ae6e8fdc325..14578c0e48b 100644 --- a/test/core/tsi/BUILD +++ b/test/core/tsi/BUILD @@ -16,7 +16,10 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_c licenses(["notice"]) # Apache v2 -grpc_package(name = "test/core/tsi", visibility = "public") +grpc_package( + name = "test/core/tsi", + visibility = "public", +) grpc_cc_library( name = "transport_security_test_lib", @@ -34,25 +37,25 @@ grpc_cc_test( language = "C++", deps = [ ":transport_security_test_lib", - "//:grpc", "//:gpr", + "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) grpc_cc_test( name = "ssl_session_cache_test", srcs = ["ssl_session_cache_test.cc"], - language = "C++", external_deps = [ "gtest", ], + language = "C++", deps = [ - "//:grpc", "//:gpr", + "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -75,10 +78,10 @@ grpc_cc_test( language = "C++", deps = [ ":transport_security_test_lib", - "//:grpc", "//:gpr", + "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -87,9 +90,8 @@ grpc_cc_test( srcs = ["transport_security_test.cc"], language = "C++", deps = [ - "//:grpc", "//:gpr", - "//test/core/util:gpr_test_util", + "//:grpc", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/tsi/alts/crypt/BUILD b/test/core/tsi/alts/crypt/BUILD index abe1e83656f..767368a2f80 100644 --- a/test/core/tsi/alts/crypt/BUILD +++ b/test/core/tsi/alts/crypt/BUILD @@ -1,5 +1,5 @@ # 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 @@ -16,7 +16,10 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_p licenses(["notice"]) # Apache v2 -grpc_package(name = "test/core/tsi/alts/crypt", visibility = "public") +grpc_package( + name = "test/core/tsi/alts/crypt", + visibility = "public", +) grpc_cc_test( name = "alts_crypt_test", @@ -27,7 +30,7 @@ grpc_cc_test( "//:alts_frame_protector", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -40,4 +43,3 @@ grpc_cc_library( "//:grpc", ], ) - diff --git a/test/core/tsi/alts/fake_handshaker/BUILD b/test/core/tsi/alts/fake_handshaker/BUILD index 98cd628a7d2..8bf9c654d42 100644 --- a/test/core/tsi/alts/fake_handshaker/BUILD +++ b/test/core/tsi/alts/fake_handshaker/BUILD @@ -16,7 +16,10 @@ licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_cc_library", "grpc_cc_binary", "grpc_package") -grpc_package(name = "test/core/tsi/alts/fake_handshaker", visibility = "public") +grpc_package( + name = "test/core/tsi/alts/fake_handshaker", + visibility = "public", +) grpc_proto_library( name = "transport_security_common_proto", @@ -52,7 +55,7 @@ grpc_cc_binary( srcs = ["fake_handshaker_server_main.cc"], language = "C++", deps = [ - "//test/cpp/util:test_config", "fake_handshaker_lib", + "//test/cpp/util:test_config", ], ) diff --git a/test/core/tsi/alts/frame_protector/BUILD b/test/core/tsi/alts/frame_protector/BUILD index 6ff3015f4dd..1e3d16df02c 100644 --- a/test/core/tsi/alts/frame_protector/BUILD +++ b/test/core/tsi/alts/frame_protector/BUILD @@ -1,5 +1,5 @@ # 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 @@ -27,7 +27,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -40,7 +40,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -54,9 +54,9 @@ grpc_cc_test( "//:grpc", "//:tsi", "//:tsi_interface", - "//test/core/tsi/alts/crypt:alts_crypt_test_util", "//test/core/tsi:transport_security_test_lib", - "//test/core/util:gpr_test_util", + "//test/core/tsi/alts/crypt:alts_crypt_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -70,6 +70,6 @@ grpc_cc_test( "//:gpr_base", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/tsi/alts/handshaker/BUILD b/test/core/tsi/alts/handshaker/BUILD index 3f1a681c1ad..61ba16ad6db 100644 --- a/test/core/tsi/alts/handshaker/BUILD +++ b/test/core/tsi/alts/handshaker/BUILD @@ -1,5 +1,5 @@ # 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 @@ -14,10 +14,10 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") -licenses(["notice"]) # Apache v2 - +licenses(["notice"]) # Apache v2 + grpc_package(name = "test/core/tsi/alts/handshaker") - + grpc_cc_library( name = "alts_handshaker_service_api_test_lib", srcs = ["alts_handshaker_service_api_test_lib.cc"], @@ -25,7 +25,7 @@ grpc_cc_library( deps = [ "//:alts_util", "//:grpc", - ], + ], ) grpc_cc_test( @@ -34,10 +34,10 @@ grpc_cc_test( language = "C++", deps = [ ":alts_handshaker_service_api_test_lib", + "//:grpc", "//:tsi", "//:tsi_interface", - "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -48,7 +48,7 @@ grpc_cc_test( deps = [ ":alts_handshaker_service_api_test_lib", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -62,7 +62,7 @@ grpc_cc_test( "//:gpr_base", "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -74,7 +74,7 @@ grpc_cc_test( ":alts_handshaker_service_api_test_lib", "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -85,7 +85,6 @@ grpc_cc_test( deps = [ "//:alts_util", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) - diff --git a/test/core/tsi/alts/zero_copy_frame_protector/BUILD b/test/core/tsi/alts/zero_copy_frame_protector/BUILD index a3b797327e4..696fc8dc065 100644 --- a/test/core/tsi/alts/zero_copy_frame_protector/BUILD +++ b/test/core/tsi/alts/zero_copy_frame_protector/BUILD @@ -1,5 +1,5 @@ # 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 @@ -28,7 +28,7 @@ grpc_cc_test( "//:grpc", "//:grpc_base_c", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -41,7 +41,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -55,6 +55,6 @@ grpc_cc_test( "//:grpc", "//:grpc_base_c", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 5492dcfa795..226e41aea7c 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -21,24 +21,6 @@ grpc_package( visibility = "public", ) -grpc_cc_library( - name = "gpr_test_util", - srcs = [ - "memory_counters.cc", - "test_config.cc", - ], - hdrs = [ - "memory_counters.h", - "test_config.h", - ], - deps = ["//:gpr"], - data = [ - "lsan_suppressions.txt", - "tsan_suppressions.txt", - "ubsan_suppressions.txt", - ], -) - grpc_cc_library( name = "grpc_debugger_macros", srcs = [ @@ -48,7 +30,6 @@ grpc_cc_library( "debugger_macros.h", ], deps = [ - ":gpr_test_util", "//:grpc_common", ], ) @@ -60,6 +41,7 @@ grpc_cc_library( "fuzzer_util.cc", "grpc_profiler.cc", "histogram.cc", + "memory_counters.cc", "mock_endpoint.cc", "parse_hexstring.cc", "passthru_endpoint.cc", @@ -70,6 +52,7 @@ grpc_cc_library( "slice_splitter.cc", "subprocess_posix.cc", "subprocess_windows.cc", + "test_config.cc", "test_tcp_server.cc", "tracer_util.cc", "trickle_endpoint.cc", @@ -79,24 +62,31 @@ grpc_cc_library( "fuzzer_util.h", "grpc_profiler.h", "histogram.h", + "memory_counters.h", "mock_endpoint.h", "parse_hexstring.h", "passthru_endpoint.h", "port.h", "port_server_client.h", "reconnect_server.h", - "subprocess.h", "slice_splitter.h", + "subprocess.h", + "test_config.h", "test_tcp_server.h", "tracer_util.h", "trickle_endpoint.h", ], language = "C++", deps = [ - ":gpr_test_util", ":grpc_debugger_macros", + "//:gpr", "//:grpc_common", ], + data = [ + "lsan_suppressions.txt", + "tsan_suppressions.txt", + "ubsan_suppressions.txt", + ], ) grpc_cc_library( @@ -140,7 +130,7 @@ grpc_cc_library( "gflags", ], deps = [ - ":gpr_test_util", + ":grpc_test_util", "//:grpc", ], ) diff --git a/test/cpp/client/BUILD b/test/cpp/client/BUILD index c03ea92d34a..1d90e361913 100644 --- a/test/cpp/client/BUILD +++ b/test/cpp/client/BUILD @@ -28,7 +28,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -44,7 +44,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/end2end:test_service_impl", "//test/cpp/util:test_util", diff --git a/test/cpp/codegen/BUILD b/test/cpp/codegen/BUILD index 12712a3e6c8..558e5e7818c 100644 --- a/test/cpp/codegen/BUILD +++ b/test/cpp/codegen/BUILD @@ -21,76 +21,76 @@ grpc_package(name = "test/cpp/codegen") grpc_cc_test( name = "codegen_test_full", srcs = ["codegen_test_full.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "codegen_test_minimal", srcs = ["codegen_test_minimal.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "proto_utils_test", srcs = ["proto_utils_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", "protobuf", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_binary( name = "golden_file_test", testonly = True, srcs = ["golden_file_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", "gflags", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) genrule( name = "copy_compiler_test_grpc_pb_h", srcs = ["//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen"], - cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.h > $@", outs = ["compiler_test.grpc.pb.h"], + cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.h > $@", ) genrule( name = "copy_compiler_test_mock_grpc_pb_h", srcs = ["//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen"], - cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test_mock.grpc.pb.h > $@", outs = ["compiler_test_mock.grpc.pb.h"], + cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test_mock.grpc.pb.h > $@", ) grpc_sh_test( name = "run_golden_file_test", srcs = ["run_golden_file_test.sh"], data = [ - ":golden_file_test", - ":compiler_test_golden", - ":compiler_test_mock_golden", ":compiler_test.grpc.pb.h", + ":compiler_test_golden", ":compiler_test_mock.grpc.pb.h", + ":compiler_test_mock_golden", + ":golden_file_test", ], ) diff --git a/test/cpp/common/BUILD b/test/cpp/common/BUILD index 2cf3ad669fa..73fcea94d9f 100644 --- a/test/cpp/common/BUILD +++ b/test/cpp/common/BUILD @@ -21,61 +21,61 @@ grpc_package(name = "test/cpp/common") grpc_cc_test( name = "alarm_test", srcs = ["alarm_test.cc"], - deps = [ - "//:grpc++_unsecure", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++_unsecure", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "auth_property_iterator_test", srcs = ["auth_property_iterator_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - "//test/cpp/util:test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], ) grpc_cc_test( name = "channel_arguments_test", srcs = ["channel_arguments_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "channel_filter_test", srcs = ["channel_filter_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "secure_auth_context_test", srcs = ["secure_auth_context_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - "//test/cpp/util:test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], ) diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 446804401a7..a648f4f0630 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -63,7 +63,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -85,7 +84,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -106,7 +104,6 @@ grpc_cc_binary( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -124,9 +121,8 @@ grpc_cc_test( "//:grpc", "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", - "//src/proto/grpc/testing:simple_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", + "//src/proto/grpc/testing:simple_messages_proto", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -146,7 +142,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -168,7 +163,6 @@ grpc_cc_library( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -189,7 +183,6 @@ grpc_cc_test( "//src/proto/grpc/channelz:channelz_proto", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -207,7 +200,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -232,7 +224,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -251,7 +242,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -270,7 +260,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -291,7 +280,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -311,7 +299,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -331,7 +318,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -352,7 +338,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -370,7 +355,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -390,7 +374,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -413,7 +396,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -435,7 +417,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:grpc++_proto_reflection_desc_db", "//test/cpp/util:test_util", @@ -456,7 +437,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -478,7 +458,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -499,7 +478,6 @@ grpc_cc_binary( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -519,7 +497,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -552,7 +529,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -571,7 +547,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -590,7 +565,6 @@ 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:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], diff --git a/test/cpp/ext/filters/census/BUILD b/test/cpp/ext/filters/census/BUILD index 6567dc667aa..78b27e2063c 100644 --- a/test/cpp/ext/filters/census/BUILD +++ b/test/cpp/ext/filters/census/BUILD @@ -24,19 +24,18 @@ grpc_cc_test( srcs = [ "stats_plugin_end2end_test.cc", ], - language = "C++", external_deps = [ "gtest", "gmock", "opencensus-stats-test", ], + language = "C++", deps = [ "//:grpc++", "//:grpc_opencensus_plugin", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", - "//test/cpp/util:test_util", "//test/cpp/util:test_config", + "//test/cpp/util:test_util", ], ) diff --git a/test/cpp/grpclb/BUILD b/test/cpp/grpclb/BUILD index 8319eb5142a..2f74a9bab0e 100644 --- a/test/cpp/grpclb/BUILD +++ b/test/cpp/grpclb/BUILD @@ -32,7 +32,6 @@ grpc_cc_test( "//:grpc", "//:grpc++", "//src/proto/grpc/lb/v1:load_balancer_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index 0f813054053..f36494d98db 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -157,7 +157,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 5ae9a9a7910..f8b5c54e207 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -24,7 +24,7 @@ grpc_cc_test( external_deps = [ "benchmark", ], - deps = ["//test/core/util:gpr_test_util"], + deps = ["//test/core/util:grpc_test_util"], ) grpc_cc_library( diff --git a/test/cpp/naming/BUILD b/test/cpp/naming/BUILD index 2925e8fbcfb..58e70480acf 100644 --- a/test/cpp/naming/BUILD +++ b/test/cpp/naming/BUILD @@ -23,16 +23,15 @@ package( licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_py_binary", "grpc_cc_test") - load(":generate_resolver_component_tests.bzl", "generate_resolver_component_tests") # Meant to be invoked only through the top-level shell script driver. grpc_py_binary( name = "resolver_component_tests_runner", + testonly = True, srcs = [ "resolver_component_tests_runner.py", ], - testonly = True, ) grpc_cc_test( @@ -40,14 +39,13 @@ grpc_cc_test( srcs = ["cancel_ares_query_test.cc"], external_deps = ["gmock"], deps = [ - "//test/cpp/util:test_util", - "//test/core/util:grpc_test_util", - "//test/core/util:gpr_test_util", - "//:grpc++", - "//:grpc", "//:gpr", - "//test/cpp/util:test_config", + "//:grpc", + "//:grpc++", "//test/core/end2end:cq_verifier", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_config", + "//test/cpp/util:test_util", ], ) diff --git a/test/cpp/naming/generate_resolver_component_tests.bzl b/test/cpp/naming/generate_resolver_component_tests.bzl index 5e9aa63abe0..f36021560c1 100755 --- a/test/cpp/naming/generate_resolver_component_tests.bzl +++ b/test/cpp/naming/generate_resolver_component_tests.bzl @@ -28,7 +28,6 @@ def generate_resolver_component_tests(): deps = [ "//test/cpp/util:test_util%s" % unsecure_build_config_suffix, "//test/core/util:grpc_test_util%s" % unsecure_build_config_suffix, - "//test/core/util:gpr_test_util", "//:grpc++%s" % unsecure_build_config_suffix, "//:grpc%s" % unsecure_build_config_suffix, "//:gpr", @@ -48,7 +47,6 @@ def generate_resolver_component_tests(): deps = [ "//test/cpp/util:test_util%s" % unsecure_build_config_suffix, "//test/core/util:grpc_test_util%s" % unsecure_build_config_suffix, - "//test/core/util:gpr_test_util", "//:grpc++%s" % unsecure_build_config_suffix, "//:grpc%s" % unsecure_build_config_suffix, "//:gpr", @@ -63,7 +61,6 @@ def generate_resolver_component_tests(): deps = [ "//test/cpp/util:test_util", "//test/core/util:grpc_test_util", - "//test/core/util:gpr_test_util", "//:grpc++", "//:grpc", "//:gpr", diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index 626ac5f3f2e..8855a1c155d 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -60,7 +60,6 @@ grpc_cc_library( "//src/proto/grpc/testing:payloads_proto", "//src/proto/grpc/testing:worker_service_proto", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", @@ -86,7 +85,6 @@ grpc_cc_library( "//src/proto/grpc/testing:messages_proto", "//src/proto/grpc/testing:report_qps_scenario_service_proto", "//src/proto/grpc/testing:worker_service_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -205,7 +203,6 @@ grpc_cc_binary( deps = [ ":qps_worker_impl", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", diff --git a/test/cpp/qps/qps_benchmark_script.bzl b/test/cpp/qps/qps_benchmark_script.bzl index b2b67d988ce..855caa0d37c 100644 --- a/test/cpp/qps/qps_benchmark_script.bzl +++ b/test/cpp/qps/qps_benchmark_script.bzl @@ -69,7 +69,6 @@ def json_run_localhost_batch(): ], deps = [ "//:gpr", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD index 3f89d6e26e3..050b83f5c4f 100644 --- a/test/cpp/server/BUILD +++ b/test/cpp/server/BUILD @@ -21,38 +21,38 @@ grpc_package(name = "test/cpp/server") grpc_cc_test( name = "server_builder_test", srcs = ["server_builder_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "server_builder_with_socket_mutator_test", srcs = ["server_builder_with_socket_mutator_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "server_request_call_test", srcs = ["server_request_call_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - external_deps = [ - "gtest", - ], ) diff --git a/test/cpp/server/load_reporter/BUILD b/test/cpp/server/load_reporter/BUILD index b7c4d29d719..8d876c56d29 100644 --- a/test/cpp/server/load_reporter/BUILD +++ b/test/cpp/server/load_reporter/BUILD @@ -43,7 +43,6 @@ grpc_cc_test( "//:grpc", "//:lb_load_reporter", "//:lb_server_load_reporting_filter", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -58,7 +57,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:lb_get_cpu_stats", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/cpp/test/BUILD b/test/cpp/test/BUILD index c5494789190..cd980dee84d 100644 --- a/test/cpp/test/BUILD +++ b/test/cpp/test/BUILD @@ -32,7 +32,6 @@ grpc_cc_test( "//:grpc", "//:grpc++", "//:grpc++_test", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], diff --git a/test/cpp/thread_manager/BUILD b/test/cpp/thread_manager/BUILD index 093e51e3faa..30488774e4e 100644 --- a/test/cpp/thread_manager/BUILD +++ b/test/cpp/thread_manager/BUILD @@ -32,7 +32,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD index 61e65029fff..bb1ca868ffb 100644 --- a/test/cpp/util/BUILD +++ b/test/cpp/util/BUILD @@ -93,14 +93,14 @@ grpc_cc_library( hdrs = [ "channel_trace_proto_helper.h", ], - deps = [ - "//:grpc++", - "//src/proto/grpc/channelz:channelz_proto", - ], external_deps = [ "gtest", "protobuf", ], + deps = [ + "//:grpc++", + "//src/proto/grpc/channelz:channelz_proto", + ], ) grpc_cc_library( @@ -235,7 +235,7 @@ grpc_cc_test( ], deps = [ "//:grpc++", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -279,7 +279,7 @@ grpc_cc_test( deps = [ "//:grpc++_error_details", "//src/proto/grpc/testing:echo_messages_proto", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -292,8 +292,8 @@ grpc_cc_binary( "gflags", ], deps = [ - ":grpc_cli_libs", ":grpc++_proto_reflection_desc_db", + ":grpc_cli_libs", ":test_config", "//:grpc++", "//src/proto/grpc/reflection/v1alpha:reflection_proto", From a324bcaad02117657f9027b14f9708f396ab9170 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 6 Dec 2018 13:53:16 -0800 Subject: [PATCH 0469/2143] Pre-fix python3 pylint failures --- src/python/grpcio/grpc/_channel.py | 1 + src/python/grpcio/grpc/_interceptor.py | 5 ++++- src/python/grpcio_tests/tests/qps/worker_server.py | 4 ++-- src/python/grpcio_tests/tests/unit/_exit_scenarios.py | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index ab154d85121..35fa82d56bd 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -175,6 +175,7 @@ def _event_handler(state, response_deserializer): return handle_event +#pylint: disable=too-many-statements def _consume_request_iterator(request_iterator, state, call, request_serializer, event_handler): if cygrpc.is_fork_support_enabled(): diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py index 2a8ddd8ce42..fc0ad77eb9e 100644 --- a/src/python/grpcio/grpc/_interceptor.py +++ b/src/python/grpcio/grpc/_interceptor.py @@ -135,9 +135,12 @@ class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): def __iter__(self): return self - def next(self): + def __next__(self): raise self._exception + def next(self): + return self.__next__() + class _UnaryOutcome(grpc.Call, grpc.Future): diff --git a/src/python/grpcio_tests/tests/qps/worker_server.py b/src/python/grpcio_tests/tests/qps/worker_server.py index 740bdcf1eb3..337a94b546c 100644 --- a/src/python/grpcio_tests/tests/qps/worker_server.py +++ b/src/python/grpcio_tests/tests/qps/worker_server.py @@ -39,7 +39,7 @@ class WorkerServer(worker_service_pb2_grpc.WorkerServiceServicer): self._quit_event = threading.Event() def RunServer(self, request_iterator, context): - config = next(request_iterator).setup + config = next(request_iterator).setup #pylint: disable=stop-iteration-return server, port = self._create_server(config) cores = multiprocessing.cpu_count() server.start() @@ -102,7 +102,7 @@ class WorkerServer(worker_service_pb2_grpc.WorkerServiceServicer): return (server, port) def RunClient(self, request_iterator, context): - config = next(request_iterator).setup + config = next(request_iterator).setup #pylint: disable=stop-iteration-return client_runners = [] qps_data = histogram.Histogram(config.histogram_params.resolution, config.histogram_params.max_possible) diff --git a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py index f489db12cb3..d1263c2c56c 100644 --- a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py +++ b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py @@ -87,7 +87,7 @@ def hang_stream_stream(request_iterator, servicer_context): def hang_partial_stream_stream(request_iterator, servicer_context): for _ in range(test_constants.STREAM_LENGTH // 2): - yield next(request_iterator) + yield next(request_iterator) #pylint: disable=stop-iteration-return time.sleep(WAIT_TIME) From 97de30d7b3f3fdbddf140cc988ccfaf29bd8edab Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 6 Dec 2018 15:51:31 -0800 Subject: [PATCH 0470/2143] Allow the interceptor to know the method type --- .../grpcpp/impl/codegen/channel_interface.h | 1 - include/grpcpp/impl/codegen/client_context.h | 6 ++- .../grpcpp/impl/codegen/client_interceptor.h | 48 ++++++++++++++++--- include/grpcpp/impl/codegen/server_context.h | 4 +- .../grpcpp/impl/codegen/server_interceptor.h | 25 ++++++++-- .../grpcpp/impl/codegen/server_interface.h | 18 +++---- src/cpp/client/channel_cc.cc | 5 +- src/cpp/server/server_cc.cc | 17 ++++--- .../client_interceptors_end2end_test.cc | 1 + .../server_interceptors_end2end_test.cc | 27 ++++++++++- 10 files changed, 121 insertions(+), 31 deletions(-) diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h index 728a7b90496..5353f5feaa6 100644 --- a/include/grpcpp/impl/codegen/channel_interface.h +++ b/include/grpcpp/impl/codegen/channel_interface.h @@ -21,7 +21,6 @@ #include #include -#include #include #include diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 142cfa35dd0..0a71f3d9b6a 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -418,12 +419,13 @@ class ClientContext { void set_call(grpc_call* call, const std::shared_ptr& channel); experimental::ClientRpcInfo* set_client_rpc_info( - const char* method, grpc::ChannelInterface* channel, + const char* method, internal::RpcMethod::RpcType type, + grpc::ChannelInterface* channel, const std::vector< std::unique_ptr>& creators, size_t interceptor_pos) { - rpc_info_ = experimental::ClientRpcInfo(this, method, channel); + rpc_info_ = experimental::ClientRpcInfo(this, type, method, channel); rpc_info_.RegisterInterceptors(creators, interceptor_pos); return &rpc_info_; } diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index f69c99ab229..2bae11a2516 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -23,6 +23,7 @@ #include #include +#include #include namespace grpc { @@ -52,23 +53,56 @@ extern experimental::ClientInterceptorFactoryInterface* namespace experimental { class ClientRpcInfo { public: - ClientRpcInfo() {} + // TODO(yashykt): Stop default-constructing ClientRpcInfo and remove UNKNOWN + // from the list of possible Types. + enum class Type { + UNARY, + CLIENT_STREAMING, + SERVER_STREAMING, + BIDI_STREAMING, + UNKNOWN // UNKNOWN is not API and will be removed later + }; ~ClientRpcInfo(){}; ClientRpcInfo(const ClientRpcInfo&) = delete; ClientRpcInfo(ClientRpcInfo&&) = default; - ClientRpcInfo& operator=(ClientRpcInfo&&) = default; // Getter methods - const char* method() { return method_; } + const char* method() const { return method_; } ChannelInterface* channel() { return channel_; } grpc::ClientContext* client_context() { return ctx_; } + Type type() const { return type_; } private: - ClientRpcInfo(grpc::ClientContext* ctx, const char* method, - grpc::ChannelInterface* channel) - : ctx_(ctx), method_(method), channel_(channel) {} + static_assert(Type::UNARY == + static_cast(internal::RpcMethod::NORMAL_RPC), + "violated expectation about Type enum"); + static_assert(Type::CLIENT_STREAMING == + static_cast(internal::RpcMethod::CLIENT_STREAMING), + "violated expectation about Type enum"); + static_assert(Type::SERVER_STREAMING == + static_cast(internal::RpcMethod::SERVER_STREAMING), + "violated expectation about Type enum"); + static_assert(Type::BIDI_STREAMING == + static_cast(internal::RpcMethod::BIDI_STREAMING), + "violated expectation about Type enum"); + + // Default constructor should only be used by ClientContext + ClientRpcInfo() = default; + + // Constructor will only be called from ClientContext + ClientRpcInfo(grpc::ClientContext* ctx, internal::RpcMethod::RpcType type, + const char* method, grpc::ChannelInterface* channel) + : ctx_(ctx), + type_(static_cast(type)), + method_(method), + channel_(channel) {} + + // Move assignment should only be used by ClientContext + // TODO(yashykt): Delete move assignment + ClientRpcInfo& operator=(ClientRpcInfo&&) = default; + // Runs interceptor at pos \a pos. void RunInterceptor( experimental::InterceptorBatchMethods* interceptor_methods, size_t pos) { @@ -97,6 +131,8 @@ class ClientRpcInfo { } grpc::ClientContext* ctx_ = nullptr; + // TODO(yashykt): make type_ const once move-assignment is deleted + Type type_{Type::UNKNOWN}; const char* method_ = nullptr; grpc::ChannelInterface* channel_ = nullptr; std::vector> interceptors_; diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index 4a5f9e2dd91..ccb5925e7d8 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -314,12 +314,12 @@ class ServerContext { uint32_t initial_metadata_flags() const { return 0; } experimental::ServerRpcInfo* set_server_rpc_info( - const char* method, + const char* method, internal::RpcMethod::RpcType type, const std::vector< std::unique_ptr>& creators) { if (creators.size() != 0) { - rpc_info_ = new experimental::ServerRpcInfo(this, method); + rpc_info_ = new experimental::ServerRpcInfo(this, method, type); rpc_info_->RegisterInterceptors(creators); } return rpc_info_; diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h index 5fb5df28b70..cd7c0600b60 100644 --- a/include/grpcpp/impl/codegen/server_interceptor.h +++ b/include/grpcpp/impl/codegen/server_interceptor.h @@ -23,6 +23,7 @@ #include #include +#include #include namespace grpc { @@ -44,6 +45,8 @@ class ServerInterceptorFactoryInterface { class ServerRpcInfo { public: + enum class Type { UNARY, CLIENT_STREAMING, SERVER_STREAMING, BIDI_STREAMING }; + ~ServerRpcInfo(){}; ServerRpcInfo(const ServerRpcInfo&) = delete; @@ -51,12 +54,27 @@ class ServerRpcInfo { ServerRpcInfo& operator=(ServerRpcInfo&&) = default; // Getter methods - const char* method() { return method_; } + const char* method() const { return method_; } + Type type() const { return type_; } grpc::ServerContext* server_context() { return ctx_; } private: - ServerRpcInfo(grpc::ServerContext* ctx, const char* method) - : ctx_(ctx), method_(method) { + static_assert(Type::UNARY == + static_cast(internal::RpcMethod::NORMAL_RPC), + "violated expectation about Type enum"); + static_assert(Type::CLIENT_STREAMING == + static_cast(internal::RpcMethod::CLIENT_STREAMING), + "violated expectation about Type enum"); + static_assert(Type::SERVER_STREAMING == + static_cast(internal::RpcMethod::SERVER_STREAMING), + "violated expectation about Type enum"); + static_assert(Type::BIDI_STREAMING == + static_cast(internal::RpcMethod::BIDI_STREAMING), + "violated expectation about Type enum"); + + ServerRpcInfo(grpc::ServerContext* ctx, const char* method, + internal::RpcMethod::RpcType type) + : ctx_(ctx), method_(method), type_(static_cast(type)) { ref_.store(1); } @@ -86,6 +104,7 @@ class ServerRpcInfo { grpc::ServerContext* ctx_ = nullptr; const char* method_ = nullptr; + const Type type_; std::atomic_int ref_; std::vector> interceptors_; diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index 55c94f4d2fa..e0e26298270 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -174,13 +174,14 @@ class ServerInterface : public internal::CallHook { bool done_intercepting_; }; + /// RegisteredAsyncRequest is not part of the C++ API class RegisteredAsyncRequest : public BaseAsyncRequest { public: RegisteredAsyncRequest(ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag, - const char* name); + const char* name, internal::RpcMethod::RpcType type); virtual bool FinalizeResult(void** tag, bool* status) override { /* If we are done intercepting, then there is nothing more for us to do */ @@ -189,7 +190,7 @@ class ServerInterface : public internal::CallHook { } call_wrapper_ = internal::Call( call_, server_, call_cq_, server_->max_receive_message_size(), - context_->set_server_rpc_info(name_, + context_->set_server_rpc_info(name_, type_, *server_->interceptor_creators())); return BaseAsyncRequest::FinalizeResult(tag, status); } @@ -198,6 +199,7 @@ class ServerInterface : public internal::CallHook { void IssueRequest(void* registered_method, grpc_byte_buffer** payload, ServerCompletionQueue* notification_cq); const char* name_; + const internal::RpcMethod::RpcType type_; }; class NoPayloadAsyncRequest final : public RegisteredAsyncRequest { @@ -207,9 +209,9 @@ class ServerInterface : public internal::CallHook { internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag) - : RegisteredAsyncRequest(server, context, stream, call_cq, - notification_cq, tag, - registered_method->name()) { + : RegisteredAsyncRequest( + server, context, stream, call_cq, notification_cq, tag, + registered_method->name(), registered_method->method_type()) { IssueRequest(registered_method->server_tag(), nullptr, notification_cq); } @@ -225,9 +227,9 @@ class ServerInterface : public internal::CallHook { CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag, Message* request) - : RegisteredAsyncRequest(server, context, stream, call_cq, - notification_cq, tag, - registered_method->name()), + : RegisteredAsyncRequest( + server, context, stream, call_cq, notification_cq, tag, + registered_method->name(), registered_method->method_type()), registered_method_(registered_method), server_(server), context_(context), diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index d1c55319f7c..a31d0b30b15 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -149,8 +149,9 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, // ClientRpcInfo should be set before call because set_call also checks // whether the call has been cancelled, and if the call was cancelled, we // should notify the interceptors too/ - auto* info = context->set_client_rpc_info( - method.name(), this, interceptor_creators_, interceptor_pos); + auto* info = + context->set_client_rpc_info(method.name(), method.method_type(), this, + interceptor_creators_, interceptor_pos); context->set_call(c_call, shared_from_this()); return internal::Call(c_call, this, cq, info); diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 69af43a6562..1e3c57446f4 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -236,9 +236,10 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { : nullptr), request_(nullptr), method_(mrd->method_), - call_(mrd->call_, server, &cq_, server->max_receive_message_size(), - ctx_.set_server_rpc_info(method_->name(), - server->interceptor_creators_)), + call_( + mrd->call_, server, &cq_, server->max_receive_message_size(), + ctx_.set_server_rpc_info(method_->name(), method_->method_type(), + server->interceptor_creators_)), server_(server), global_callbacks_(nullptr), resources_(false) { @@ -427,7 +428,8 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { req_->call_, req_->server_, req_->cq_, req_->server_->max_receive_message_size(), req_->ctx_.set_server_rpc_info( - req_->method_->name(), req_->server_->interceptor_creators_)); + req_->method_->name(), req_->method_->method_type(), + req_->server_->interceptor_creators_)); req_->interceptor_methods_.SetCall(call_); req_->interceptor_methods_.SetReverse(); @@ -1041,10 +1043,12 @@ void ServerInterface::BaseAsyncRequest:: ServerInterface::RegisteredAsyncRequest::RegisteredAsyncRequest( ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, const char* name) + ServerCompletionQueue* notification_cq, void* tag, const char* name, + internal::RpcMethod::RpcType type) : BaseAsyncRequest(server, context, stream, call_cq, notification_cq, tag, true), - name_(name) {} + name_(name), + type_(type) {} void ServerInterface::RegisteredAsyncRequest::IssueRequest( void* registered_method, grpc_byte_buffer** payload, @@ -1091,6 +1095,7 @@ bool ServerInterface::GenericAsyncRequest::FinalizeResult(void** tag, call_, server_, call_cq_, server_->max_receive_message_size(), context_->set_server_rpc_info( static_cast(context_)->method_.c_str(), + internal::RpcMethod::BIDI_STREAMING, *server_->interceptor_creators())); return BaseAsyncRequest::FinalizeResult(tag, status); } diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 3a191d1e038..f55ece1c2bf 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -50,6 +50,7 @@ class HijackingInterceptor : public experimental::Interceptor { info_ = info; // Make sure it is the right method EXPECT_EQ(strcmp("/grpc.testing.EchoTestService/Echo", info->method()), 0); + EXPECT_EQ(info->type(), experimental::ClientRpcInfo::Type::UNARY); } virtual void Intercept(experimental::InterceptorBatchMethods* methods) { diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index c98b6143c66..1e0e3668707 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -44,7 +44,32 @@ namespace { class LoggingInterceptor : public experimental::Interceptor { public: - LoggingInterceptor(experimental::ServerRpcInfo* info) { info_ = info; } + LoggingInterceptor(experimental::ServerRpcInfo* info) { + info_ = info; + + // Check the method name and compare to the type + const char* method = info->method(); + experimental::ServerRpcInfo::Type type = info->type(); + + // Check that we use one of our standard methods with expected type. + // We accept BIDI_STREAMING for Echo in case it's an AsyncGenericService + // being tested (the GenericRpc test). + // The empty method is for the Unimplemented requests that arise + // when draining the CQ. + EXPECT_TRUE( + (strcmp(method, "/grpc.testing.EchoTestService/Echo") == 0 && + (type == experimental::ServerRpcInfo::Type::UNARY || + type == experimental::ServerRpcInfo::Type::BIDI_STREAMING)) || + (strcmp(method, "/grpc.testing.EchoTestService/RequestStream") == 0 && + type == experimental::ServerRpcInfo::Type::CLIENT_STREAMING) || + (strcmp(method, "/grpc.testing.EchoTestService/ResponseStream") == 0 && + type == experimental::ServerRpcInfo::Type::SERVER_STREAMING) || + (strcmp(method, "/grpc.testing.EchoTestService/BidiStream") == 0 && + type == experimental::ServerRpcInfo::Type::BIDI_STREAMING) || + strcmp(method, "/grpc.testing.EchoTestService/Unimplemented") == 0 || + (strcmp(method, "") == 0 && + type == experimental::ServerRpcInfo::Type::BIDI_STREAMING)); + } virtual void Intercept(experimental::InterceptorBatchMethods* methods) { if (methods->QueryInterceptionHookPoint( From f9e50322bf1d6be736b415831eea44130b9dedfe Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 15:58:53 -0800 Subject: [PATCH 0471/2143] batch fix --- src/objective-c/GRPCClient/GRPCCall.h | 16 +++--- src/objective-c/GRPCClient/GRPCCall.m | 4 +- .../GRPCClient/private/GRPCChannelPool+Test.h | 49 +++++++++++++++++++ .../GRPCClient/private/GRPCChannelPool.h | 28 ----------- .../GRPCClient/private/GRPCChannelPool.m | 7 ++- src/objective-c/ProtoRPC/ProtoRPC.h | 16 +++--- src/objective-c/ProtoRPC/ProtoRPC.m | 5 +- .../tests/ChannelTests/ChannelPoolTest.m | 2 +- .../tests/ChannelTests/ChannelTests.m | 1 + 9 files changed, 73 insertions(+), 55 deletions(-) create mode 100644 src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 985743433cf..6d8b9c1b127 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -153,6 +153,14 @@ extern NSString *const kGRPCTrailersKey; /** An object can implement this protocol to receive responses from server from a call. */ @protocol GRPCResponseHandler +@required + +/** + * All the responses must be issued to a user-provided dispatch queue. This property specifies the + * dispatch queue to be used for issuing the notifications. + */ +@property(atomic, readonly) dispatch_queue_t dispatchQueue; + @optional /** @@ -175,14 +183,6 @@ extern NSString *const kGRPCTrailersKey; - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; -@required - -/** - * All the responses must be issued to a user-provided dispatch queue. This property specifies the - * dispatch queue to be used for issuing the notifications. - */ -@property(atomic, readonly) dispatch_queue_t dispatchQueue; - @end /** diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 48253677bd3..e75ca7193a7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -856,9 +856,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _retainSelf = self; if (_callOptions == nil) { - GRPCMutableCallOptions *callOptions; - - callOptions = [[GRPCHost callOptionsForHost:_host] mutableCopy]; + GRPCMutableCallOptions *callOptions = [[GRPCHost callOptionsForHost:_host] mutableCopy]; if (_serverName.length != 0) { callOptions.serverAuthority = _serverName; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h new file mode 100644 index 00000000000..4e7c988585d --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h @@ -0,0 +1,49 @@ +/* + * + * 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. + * + */ + +#import "GRPCChannelPool.h" + +/** Test-only interface for \a GRPCPooledChannel. */ +@interface GRPCPooledChannel (Test) + +/** + * Initialize a pooled channel with non-default destroy delay for testing purpose. + */ +- (nullable instancetype)initWithChannelConfiguration: +(GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay; + +/** + * Return the pointer to the raw channel wrapped. + */ +@property(atomic, readonly) GRPCChannel *wrappedChannel; + +@end + +/** Test-only interface for \a GRPCChannelPool. */ +@interface GRPCChannelPool (Test) + +/** + * Get an instance of pool isolated from the global shared pool with channels' destroy delay being + * \a destroyDelay. + */ +- (nullable instancetype)initTestPool; + +@end + + diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 7c6f2b3bbfa..d1f28ec9bfa 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -75,23 +75,6 @@ NS_ASSUME_NONNULL_BEGIN @end -/** Test-only interface for \a GRPCPooledChannel. */ -@interface GRPCPooledChannel (Test) - -/** - * Initialize a pooled channel with non-default destroy delay for testing purpose. - */ -- (nullable instancetype)initWithChannelConfiguration: -(GRPCChannelConfiguration *)channelConfiguration - destroyDelay:(NSTimeInterval)destroyDelay; - -/** - * Return the pointer to the raw channel wrapped. - */ -@property(atomic, readonly) GRPCChannel *wrappedChannel; - -@end - /** * Manage the pool of connected channels. When a channel is no longer referenced by any call, * destroy the channel after a certain period of time elapsed. @@ -119,15 +102,4 @@ NS_ASSUME_NONNULL_BEGIN @end -/** Test-only interface for \a GRPCChannelPool. */ -@interface GRPCChannelPool (Test) - -/** - * Get an instance of pool isolated from the global shared pool with channels' destroy delay being - * \a destroyDelay. - */ -- (nullable instancetype)initTestPool; - -@end - NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 391022efd19..349bdd44a65 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -22,6 +22,7 @@ #import "GRPCChannel.h" #import "GRPCChannelFactory.h" #import "GRPCChannelPool.h" +#import "GRPCChannelPool+Test.h" #import "GRPCConnectivityMonitor.h" #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" @@ -59,9 +60,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (void)dealloc { // Disconnect GRPCWrappedCall objects created but not yet removed if (_wrappedCalls.allObjects.count != 0) { - NSEnumerator *enumerator = [_wrappedCalls objectEnumerator]; - GRPCWrappedCall *wrappedCall; - while ((wrappedCall = [enumerator nextObject])) { + for (GRPCWrappedCall *wrappedCall in _wrappedCalls.allObjects) { [wrappedCall channelDisconnected]; }; } @@ -73,7 +72,7 @@ callOptions:(GRPCCallOptions *)callOptions { NSAssert(path.length > 0, @"path must not be empty."); NSAssert(queue != nil, @"completionQueue must not be empty."); NSAssert(callOptions, @"callOptions must not be empty."); - if (path.length == 0 || queue == nil || callOptions == nil) return NULL; + if (path.length == 0 || queue == nil || callOptions == nil) return nil; GRPCWrappedCall *call = nil; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 287aa0369b1..2e0400a323f 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -28,6 +28,14 @@ NS_ASSUME_NONNULL_BEGIN /** An object can implement this protocol to receive responses from server from a call. */ @protocol GRPCProtoResponseHandler +@required + +/** + * All the responses must be issued to a user-provided dispatch queue. This property specifies the + * dispatch queue to be used for issuing the notifications. + */ +@property(atomic, readonly) dispatch_queue_t dispatchQueue; + @optional /** @@ -49,14 +57,6 @@ NS_ASSUME_NONNULL_BEGIN - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; -@required - -/** - * All the responses must be issued to a user-provided dispatch queue. This property specifies the - * dispatch queue to be used for issuing the notifications. - */ -@property(atomic, readonly) dispatch_queue_t dispatchQueue; - @end /** A unary-request RPC call with Protobuf. */ diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 886e31ce58a..0f63f72f536 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -75,7 +75,6 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)cancel { [_call cancel]; - _call = nil; } @end @@ -124,7 +123,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing #else { #endif - _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); } dispatch_set_target_queue(_dispatchQueue, handler.dispatchQueue); @@ -145,7 +144,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing copiedCall = _call; _call = nil; if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { - dispatch_async(_handler.dispatchQueue, ^{ + dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { copiedHandler = self->_handler; diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m index dc42d7c341d..eab8c5193fb 100644 --- a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -19,7 +19,7 @@ #import #import "../../GRPCClient/private/GRPCChannel.h" -#import "../../GRPCClient/private/GRPCChannelPool.h" +#import "../../GRPCClient/private/GRPCChannelPool+Test.h" #import "../../GRPCClient/private/GRPCCompletionQueue.h" #define TEST_TIMEOUT 32 diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index ee7f8b6fddb..7c80868c2c9 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -21,6 +21,7 @@ #import "../../GRPCClient/GRPCCallOptions.h" #import "../../GRPCClient/private/GRPCChannel.h" #import "../../GRPCClient/private/GRPCChannelPool.h" +#import "../../GRPCClient/private/GRPCChannelPool+Test.h" #import "../../GRPCClient/private/GRPCCompletionQueue.h" #import "../../GRPCClient/private/GRPCWrappedCall.h" From f1f557bc43992ade0f09c9240c2d5c71c3478f0a Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 6 Dec 2018 16:16:58 -0800 Subject: [PATCH 0472/2143] Add a Shutdown call to HealthCheckServiceInterface --- .../grpcpp/health_check_service_interface.h | 4 + .../health/default_health_check_service.cc | 18 +++ .../health/default_health_check_service.h | 3 + .../end2end/health_service_end2end_test.cc | 107 ++++++++++++++++++ 4 files changed, 132 insertions(+) diff --git a/include/grpcpp/health_check_service_interface.h b/include/grpcpp/health_check_service_interface.h index b45a699bda9..dfd4c3983af 100644 --- a/include/grpcpp/health_check_service_interface.h +++ b/include/grpcpp/health_check_service_interface.h @@ -37,6 +37,10 @@ class HealthCheckServiceInterface { bool serving) = 0; /// Apply to all registered service names. virtual void SetServingStatus(bool serving) = 0; + + /// Set all registered service names to not serving and prevent future + /// state changes. + virtual void Shutdown() {} }; /// Enable/disable the default health checking service. This applies to all C++ diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index c951c69d513..db6286d240e 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -42,18 +42,36 @@ DefaultHealthCheckService::DefaultHealthCheckService() { void DefaultHealthCheckService::SetServingStatus( const grpc::string& service_name, bool serving) { std::unique_lock lock(mu_); + if (shutdown_) { + return; + } services_map_[service_name].SetServingStatus(serving ? SERVING : NOT_SERVING); } void DefaultHealthCheckService::SetServingStatus(bool serving) { const ServingStatus status = serving ? SERVING : NOT_SERVING; std::unique_lock lock(mu_); + if (shutdown_) { + return; + } for (auto& p : services_map_) { ServiceData& service_data = p.second; service_data.SetServingStatus(status); } } +void DefaultHealthCheckService::Shutdown() { + std::unique_lock lock(mu_); + if (shutdown_) { + return; + } + shutdown_ = true; + for (auto& p : services_map_) { + ServiceData& service_data = p.second; + service_data.SetServingStatus(NOT_SERVING); + } +} + DefaultHealthCheckService::ServingStatus DefaultHealthCheckService::GetServingStatus( const grpc::string& service_name) const { diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h index 450bd543f55..9551cd2e2cf 100644 --- a/src/cpp/server/health/default_health_check_service.h +++ b/src/cpp/server/health/default_health_check_service.h @@ -237,6 +237,8 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface { bool serving) override; void SetServingStatus(bool serving) override; + void Shutdown() override; + ServingStatus GetServingStatus(const grpc::string& service_name) const; HealthCheckServiceImpl* GetHealthCheckService( @@ -272,6 +274,7 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface { const std::shared_ptr& handler); mutable std::mutex mu_; + bool shutdown_ = false; // Guarded by mu_. std::map services_map_; // Guarded by mu_. std::unique_ptr impl_; }; diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index 89c4bef09cf..a439d42b031 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -90,18 +90,36 @@ class HealthCheckServiceImpl : public ::grpc::health::v1::Health::Service { void SetStatus(const grpc::string& service_name, HealthCheckResponse::ServingStatus status) { std::lock_guard lock(mu_); + if (shutdown_) { + return; + } status_map_[service_name] = status; } void SetAll(HealthCheckResponse::ServingStatus status) { std::lock_guard lock(mu_); + if (shutdown_) { + return; + } for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) { iter->second = status; } } + void Shutdown() { + std::lock_guard lock(mu_); + if (shutdown_) { + return; + } + shutdown_ = true; + for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) { + iter->second = HealthCheckResponse::NOT_SERVING; + } + } + private: std::mutex mu_; + bool shutdown_ = false; std::map status_map_; }; @@ -125,6 +143,8 @@ class CustomHealthCheckService : public HealthCheckServiceInterface { : HealthCheckResponse::NOT_SERVING); } + void Shutdown() override { impl_->Shutdown(); } + private: HealthCheckServiceImpl* impl_; // not owned }; @@ -260,6 +280,71 @@ class HealthServiceEnd2endTest : public ::testing::Test { context.TryCancel(); } + // Verify that after HealthCheckServiceInterface::Shutdown is called + // 1. unary client will see NOT_SERVING. + // 2. unary client still sees NOT_SERVING after a SetServing(true) is called. + // 3. streaming (Watch) client will see an update. + // This has to be called last. + void VerifyHealthCheckServiceShutdown() { + const grpc::string kServiceName("service_name"); + HealthCheckServiceInterface* service = server_->GetHealthCheckService(); + EXPECT_TRUE(service != nullptr); + const grpc::string kHealthyService("healthy_service"); + const grpc::string kUnhealthyService("unhealthy_service"); + const grpc::string kNotRegisteredService("not_registered"); + service->SetServingStatus(kHealthyService, true); + service->SetServingStatus(kUnhealthyService, false); + + ResetStubs(); + + // Start Watch for service. + ClientContext context; + HealthCheckRequest request; + request.set_service(kServiceName); + std::unique_ptr<::grpc::ClientReaderInterface> reader = + hc_stub_->Watch(&context, request); + + // Initial response will be SERVICE_UNKNOWN. + HealthCheckResponse response; + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.SERVICE_UNKNOWN, response.status()); + + // Set service to SERVING and make sure we get an update. + service->SetServingStatus(kServiceName, true); + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.SERVING, response.status()); + + SendHealthCheckRpc("", Status::OK, HealthCheckResponse::SERVING); + SendHealthCheckRpc(kHealthyService, Status::OK, + HealthCheckResponse::SERVING); + SendHealthCheckRpc(kUnhealthyService, Status::OK, + HealthCheckResponse::NOT_SERVING); + SendHealthCheckRpc(kNotRegisteredService, + Status(StatusCode::NOT_FOUND, "")); + + // Shutdown health check service. + service->Shutdown(); + + // Watch client gets another update. + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.NOT_SERVING, response.status()); + // Finish Watch call. + context.TryCancel(); + + SendHealthCheckRpc("", Status::OK, HealthCheckResponse::NOT_SERVING); + SendHealthCheckRpc(kHealthyService, Status::OK, + HealthCheckResponse::NOT_SERVING); + SendHealthCheckRpc(kUnhealthyService, Status::OK, + HealthCheckResponse::NOT_SERVING); + SendHealthCheckRpc(kNotRegisteredService, + Status(StatusCode::NOT_FOUND, "")); + + // Setting status after Shutdown has no effect. + service->SetServingStatus(kHealthyService, true); + SendHealthCheckRpc(kHealthyService, Status::OK, + HealthCheckResponse::NOT_SERVING); + } + TestServiceImpl echo_test_service_; HealthCheckServiceImpl health_check_service_impl_; std::unique_ptr hc_stub_; @@ -295,6 +380,13 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { Status(StatusCode::INVALID_ARGUMENT, "")); } +TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceShutdown) { + EnableDefaultHealthCheckService(true); + EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); + SetUpServer(true, false, false, nullptr); + VerifyHealthCheckServiceShutdown(); +} + // Provide an empty service to disable the default service. TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) { EnableDefaultHealthCheckService(true); @@ -326,6 +418,21 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) { VerifyHealthCheckServiceStreaming(); } +TEST_F(HealthServiceEnd2endTest, ExplicitlyHealthServiceShutdown) { + EnableDefaultHealthCheckService(true); + EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); + std::unique_ptr override_service( + new CustomHealthCheckService(&health_check_service_impl_)); + HealthCheckServiceInterface* underlying_service = override_service.get(); + SetUpServer(false, false, true, std::move(override_service)); + HealthCheckServiceInterface* service = server_->GetHealthCheckService(); + EXPECT_TRUE(service == underlying_service); + + ResetStubs(); + + VerifyHealthCheckServiceShutdown(); +} + } // namespace } // namespace testing } // namespace grpc From d7c252c9473a2a97eb441369603d8cc9ad64403c Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 6 Dec 2018 16:53:24 -0800 Subject: [PATCH 0473/2143] Surface socket name --- src/core/ext/filters/client_channel/connector.h | 5 +++-- src/core/ext/filters/client_channel/subchannel.cc | 4 +++- .../transport/chttp2/client/chttp2_connector.cc | 4 ++-- .../ext/transport/chttp2/server/chttp2_server.cc | 2 +- .../transport/chttp2/transport/chttp2_transport.cc | 9 +++------ .../transport/chttp2/transport/chttp2_transport.h | 4 +++- src/core/lib/channel/channelz.cc | 10 ++++++---- src/core/lib/channel/channelz.h | 5 +++++ src/core/lib/surface/server.cc | 14 +++++++------- src/core/lib/surface/server.h | 4 ++-- 10 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/core/ext/filters/client_channel/connector.h b/src/core/ext/filters/client_channel/connector.h index ea34dcdab57..484cc1b3c39 100644 --- a/src/core/ext/filters/client_channel/connector.h +++ b/src/core/ext/filters/client_channel/connector.h @@ -22,6 +22,7 @@ #include #include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/channel/channelz.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/transport/transport.h" @@ -48,8 +49,8 @@ typedef struct { /** channel arguments (to be passed to the filters) */ grpc_channel_args* channel_args; - /** socket uuid of the connected transport. 0 if not available */ - intptr_t socket_uuid; + /** socket node of the connected transport */ + grpc_core::channelz::SocketNode* socket_node; } grpc_connect_out_args; struct grpc_connector_vtable { diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 0817b1dd392..e66b0711cf9 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -826,7 +826,9 @@ static bool publish_transport_locked(grpc_subchannel* c) { GRPC_ERROR_UNREF(error); return false; } - intptr_t socket_uuid = c->connecting_result.socket_uuid; + intptr_t socket_uuid = c->connecting_result.socket_node == nullptr + ? 0 + : c->connecting_result.socket_node->uuid(); memset(&c->connecting_result, 0, sizeof(c->connecting_result)); if (c->disconnected) { diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index 60a32022f57..62a07d2ba61 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -117,8 +117,8 @@ static void on_handshake_done(void* arg, grpc_error* error) { c->args.interested_parties); c->result->transport = grpc_create_chttp2_transport(args->args, args->endpoint, true); - c->result->socket_uuid = - grpc_chttp2_transport_get_socket_uuid(c->result->transport); + c->result->socket_node = + grpc_chttp2_transport_get_socket_node(c->result->transport); GPR_ASSERT(c->result->transport); // TODO(roth): We ideally want to wait until we receive HTTP/2 // settings from the server before we consider the connection diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 33d2b22aa58..3d09187b9ba 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -149,7 +149,7 @@ static void on_handshake_done(void* arg, grpc_error* error) { grpc_server_setup_transport( connection_state->svr_state->server, transport, connection_state->accepting_pollset, args->args, - grpc_chttp2_transport_get_socket_uuid(transport), resource_user); + grpc_chttp2_transport_get_socket_node(transport), resource_user); // Use notify_on_receive_settings callback to enforce the // handshake deadline. connection_state->transport = diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 7377287e8cb..73e43131a0a 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -3145,14 +3145,11 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), static const grpc_transport_vtable* get_vtable(void) { return &vtable; } -intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport) { +grpc_core::channelz::SocketNode* grpc_chttp2_transport_get_socket_node( + grpc_transport* transport) { grpc_chttp2_transport* t = reinterpret_cast(transport); - if (t->channelz_socket != nullptr) { - return t->channelz_socket->uuid(); - } else { - return 0; - } + return t->channelz_socket.get(); } grpc_transport* grpc_create_chttp2_transport( diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/src/core/ext/transport/chttp2/transport/chttp2_transport.h index b3fe1c082ec..b9929b1662e 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.h +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.h @@ -21,6 +21,7 @@ #include +#include "src/core/lib/channel/channelz.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/transport/transport.h" @@ -35,7 +36,8 @@ grpc_transport* grpc_create_chttp2_transport( const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client, grpc_resource_user* resource_user = nullptr); -intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport); +grpc_core::channelz::SocketNode* grpc_chttp2_transport_get_socket_node( + grpc_transport* transport); /// Takes ownership of \a read_buffer, which (if non-NULL) contains /// leftover bytes previously read from the endpoint (e.g., by handshakers). diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 0802143fbeb..0cb28905181 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -207,18 +207,20 @@ char* ServerNode::RenderServerSockets(intptr_t start_socket_id) { grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; - ChildRefsList socket_refs; + ChildSocketsList socket_refs; grpc_server_populate_server_sockets(server_, &socket_refs, start_socket_id); if (!socket_refs.empty()) { // create list of socket refs grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); for (size_t i = 0; i < socket_refs.size(); ++i) { - json_iterator = + grpc_json* socket_ref_json = grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false); - grpc_json_add_number_string_child(json_iterator, nullptr, "socketId", - socket_refs[i]); + json_iterator = grpc_json_add_number_string_child( + socket_ref_json, nullptr, "socketId", socket_refs[i]->uuid()); + grpc_json_create_child(json_iterator, socket_ref_json, "name", + socket_refs[i]->remote(), GRPC_JSON_STRING, false); } } // For now we do not have any pagination rules. In the future we could diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 64ab5cb3a65..96a4333083a 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -59,6 +59,9 @@ namespace channelz { // add human readable names as in the channelz.proto typedef InlinedVector ChildRefsList; +class SocketNode; +typedef InlinedVector ChildSocketsList; + namespace testing { class CallCountingHelperPeer; class ChannelNodePeer; @@ -251,6 +254,8 @@ class SocketNode : public BaseNode { gpr_atm_no_barrier_fetch_add(&keepalives_sent_, static_cast(1)); } + const char* remote() { return remote_.get(); } + private: gpr_atm streams_started_ = 0; gpr_atm streams_succeeded_ = 0; diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 1f66be240e3..4c63b6bc394 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -109,7 +109,7 @@ struct channel_data { uint32_t registered_method_max_probes; grpc_closure finish_destroy_channel_closure; grpc_closure channel_connectivity_changed; - intptr_t socket_uuid; + grpc_core::channelz::SocketNode* socket_node; }; typedef struct shutdown_tag { @@ -1158,7 +1158,7 @@ void grpc_server_get_pollsets(grpc_server* server, grpc_pollset*** pollsets, void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, grpc_pollset* accepting_pollset, const grpc_channel_args* args, - intptr_t socket_uuid, + grpc_core::channelz::SocketNode* socket_node, grpc_resource_user* resource_user) { size_t num_registered_methods; size_t alloc; @@ -1180,7 +1180,7 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, chand->server = s; server_ref(s); chand->channel = channel; - chand->socket_uuid = socket_uuid; + chand->socket_node = socket_node; size_t cq_idx; for (cq_idx = 0; cq_idx < s->cq_count; cq_idx++) { @@ -1256,14 +1256,14 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, } void grpc_server_populate_server_sockets( - grpc_server* s, grpc_core::channelz::ChildRefsList* server_sockets, + grpc_server* s, grpc_core::channelz::ChildSocketsList* server_sockets, intptr_t start_idx) { gpr_mu_lock(&s->mu_global); channel_data* c = nullptr; for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { - intptr_t socket_uuid = c->socket_uuid; - if (socket_uuid >= start_idx) { - server_sockets->push_back(socket_uuid); + grpc_core::channelz::SocketNode* socket_node = c->socket_node; + if (socket_node && socket_node->uuid() >= start_idx) { + server_sockets->push_back(socket_node); } } gpr_mu_unlock(&s->mu_global); diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index 27038fdb7a6..8e8903d76b3 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -47,12 +47,12 @@ void grpc_server_add_listener(grpc_server* server, void* listener, void grpc_server_setup_transport(grpc_server* server, grpc_transport* transport, grpc_pollset* accepting_pollset, const grpc_channel_args* args, - intptr_t socket_uuid, + grpc_core::channelz::SocketNode* socket_node, grpc_resource_user* resource_user = nullptr); /* fills in the uuids of all sockets used for connections on this server */ void grpc_server_populate_server_sockets( - grpc_server* server, grpc_core::channelz::ChildRefsList* server_sockets, + grpc_server* server, grpc_core::channelz::ChildSocketsList* server_sockets, intptr_t start_idx); /* fills in the uuids of all listen sockets on this server */ From e7be6223d86172f2881935f83fb25b4bc7898942 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 6 Dec 2018 17:10:03 -0800 Subject: [PATCH 0474/2143] Delete unwanted constructor/assignment --- include/grpcpp/impl/codegen/server_interceptor.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h index 5fb5df28b70..030c26a9b05 100644 --- a/include/grpcpp/impl/codegen/server_interceptor.h +++ b/include/grpcpp/impl/codegen/server_interceptor.h @@ -47,8 +47,8 @@ class ServerRpcInfo { ~ServerRpcInfo(){}; ServerRpcInfo(const ServerRpcInfo&) = delete; - ServerRpcInfo(ServerRpcInfo&&) = default; - ServerRpcInfo& operator=(ServerRpcInfo&&) = default; + ServerRpcInfo(ServerRpcInfo&&) = delete; + ServerRpcInfo& operator=(ServerRpcInfo&&) = delete; // Getter methods const char* method() { return method_; } From 47233225cafb2e9366e23fb4dd4bafee1005b0ef Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 6 Dec 2018 17:12:43 -0800 Subject: [PATCH 0475/2143] Split out the test service to separate library so that it can be reused --- CMakeLists.txt | 2 + Makefile | 5 + build.yaml | 4 + grpc.gyp | 2 + test/cpp/end2end/BUILD | 13 +++ .../end2end/health_service_end2end_test.cc | 75 +-------------- .../end2end/test_health_check_service_impl.cc | 96 +++++++++++++++++++ .../end2end/test_health_check_service_impl.h | 58 +++++++++++ .../generated/sources_and_headers.json | 6 ++ 9 files changed, 187 insertions(+), 74 deletions(-) create mode 100644 test/cpp/end2end/test_health_check_service_impl.cc create mode 100644 test/cpp/end2end/test_health_check_service_impl.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1194d0072e3..6b02d778d1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4024,6 +4024,7 @@ add_library(grpc++_test_util ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/test_health_check_service_impl.cc test/cpp/end2end/test_service_impl.cc test/cpp/util/byte_buffer_proto_helper.cc test/cpp/util/channel_trace_proto_helper.cc @@ -4224,6 +4225,7 @@ add_library(grpc++_test_util_unsecure ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/test_health_check_service_impl.cc test/cpp/end2end/test_service_impl.cc test/cpp/util/byte_buffer_proto_helper.cc test/cpp/util/string_ref_helper.cc diff --git a/Makefile b/Makefile index 7dfce79c922..ed4e219f8b7 100644 --- a/Makefile +++ b/Makefile @@ -6439,6 +6439,7 @@ LIBGRPC++_TEST_UTIL_SRC = \ $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc \ + test/cpp/end2end/test_health_check_service_impl.cc \ test/cpp/end2end/test_service_impl.cc \ test/cpp/util/byte_buffer_proto_helper.cc \ test/cpp/util/channel_trace_proto_helper.cc \ @@ -6591,6 +6592,7 @@ ifneq ($(NO_DEPS),true) -include $(LIBGRPC++_TEST_UTIL_OBJS:.o=.dep) endif endif +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_health_check_service_impl.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/util/channel_trace_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc @@ -6607,6 +6609,7 @@ LIBGRPC++_TEST_UTIL_UNSECURE_SRC = \ $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc \ + test/cpp/end2end/test_health_check_service_impl.cc \ test/cpp/end2end/test_service_impl.cc \ test/cpp/util/byte_buffer_proto_helper.cc \ test/cpp/util/string_ref_helper.cc \ @@ -6756,6 +6759,7 @@ ifneq ($(NO_DEPS),true) -include $(LIBGRPC++_TEST_UTIL_UNSECURE_OBJS:.o=.dep) endif endif +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_health_check_service_impl.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc @@ -25142,6 +25146,7 @@ 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/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) test/cpp/end2end/test_service_impl.cc: $(OPENSSL_DEP) test/cpp/interop/client.cc: $(OPENSSL_DEP) test/cpp/interop/client_helper.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 1e63933f555..af70be8459a 100644 --- a/build.yaml +++ b/build.yaml @@ -1755,6 +1755,7 @@ libs: build: private language: c++ headers: + - test/cpp/end2end/test_health_check_service_impl.h - test/cpp/end2end/test_service_impl.h - test/cpp/util/byte_buffer_proto_helper.h - test/cpp/util/channel_trace_proto_helper.h @@ -1769,6 +1770,7 @@ libs: - src/proto/grpc/testing/echo.proto - src/proto/grpc/testing/duplicate/echo_duplicate.proto - src/proto/grpc/testing/simple_messages.proto + - test/cpp/end2end/test_health_check_service_impl.cc - test/cpp/end2end/test_service_impl.cc - test/cpp/util/byte_buffer_proto_helper.cc - test/cpp/util/channel_trace_proto_helper.cc @@ -1789,6 +1791,7 @@ libs: build: private language: c++ headers: + - test/cpp/end2end/test_health_check_service_impl.h - test/cpp/end2end/test_service_impl.h - test/cpp/util/byte_buffer_proto_helper.h - test/cpp/util/string_ref_helper.h @@ -1799,6 +1802,7 @@ libs: - src/proto/grpc/testing/echo.proto - src/proto/grpc/testing/duplicate/echo_duplicate.proto - src/proto/grpc/testing/simple_messages.proto + - test/cpp/end2end/test_health_check_service_impl.cc - test/cpp/end2end/test_service_impl.cc - test/cpp/util/byte_buffer_proto_helper.cc - test/cpp/util/string_ref_helper.cc diff --git a/grpc.gyp b/grpc.gyp index 2b841354baf..564922ff727 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1498,6 +1498,7 @@ 'src/proto/grpc/testing/echo.proto', 'src/proto/grpc/testing/duplicate/echo_duplicate.proto', 'src/proto/grpc/testing/simple_messages.proto', + 'test/cpp/end2end/test_health_check_service_impl.cc', 'test/cpp/end2end/test_service_impl.cc', 'test/cpp/util/byte_buffer_proto_helper.cc', 'test/cpp/util/channel_trace_proto_helper.cc', @@ -1522,6 +1523,7 @@ 'src/proto/grpc/testing/echo.proto', 'src/proto/grpc/testing/duplicate/echo_duplicate.proto', 'src/proto/grpc/testing/simple_messages.proto', + 'test/cpp/end2end/test_health_check_service_impl.cc', 'test/cpp/end2end/test_service_impl.cc', 'test/cpp/util/byte_buffer_proto_helper.cc', 'test/cpp/util/string_ref_helper.cc', diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 446804401a7..eb600ffb172 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -35,6 +35,18 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "test_health_check_service_impl", + testonly = True, + srcs = ["test_health_check_service_impl.cc"], + hdrs = ["test_health_check_service_impl.h"], + deps = [ + "//:grpc", + "//:grpc++", + "//src/proto/grpc/health/v1:health_proto", + ], +) + grpc_cc_library( name = "interceptors_util", testonly = True, @@ -283,6 +295,7 @@ grpc_cc_test( "gtest", ], deps = [ + ":test_health_check_service_impl", ":test_service_impl", "//:gpr", "//:grpc", diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index a439d42b031..94c92327c87 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -37,6 +37,7 @@ #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_health_check_service_impl.h" #include "test/cpp/end2end/test_service_impl.h" #include @@ -49,80 +50,6 @@ namespace grpc { namespace testing { namespace { -// A sample sync implementation of the health checking service. This does the -// same thing as the default one. -class HealthCheckServiceImpl : public ::grpc::health::v1::Health::Service { - public: - Status Check(ServerContext* context, const HealthCheckRequest* request, - HealthCheckResponse* response) override { - std::lock_guard lock(mu_); - auto iter = status_map_.find(request->service()); - if (iter == status_map_.end()) { - return Status(StatusCode::NOT_FOUND, ""); - } - response->set_status(iter->second); - return Status::OK; - } - - Status Watch(ServerContext* context, const HealthCheckRequest* request, - ::grpc::ServerWriter* writer) override { - auto last_state = HealthCheckResponse::UNKNOWN; - while (!context->IsCancelled()) { - { - std::lock_guard lock(mu_); - HealthCheckResponse response; - auto iter = status_map_.find(request->service()); - if (iter == status_map_.end()) { - response.set_status(response.SERVICE_UNKNOWN); - } else { - response.set_status(iter->second); - } - if (response.status() != last_state) { - writer->Write(response, ::grpc::WriteOptions()); - } - } - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis(1000, GPR_TIMESPAN))); - } - return Status::OK; - } - - void SetStatus(const grpc::string& service_name, - HealthCheckResponse::ServingStatus status) { - std::lock_guard lock(mu_); - if (shutdown_) { - return; - } - status_map_[service_name] = status; - } - - void SetAll(HealthCheckResponse::ServingStatus status) { - std::lock_guard lock(mu_); - if (shutdown_) { - return; - } - for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) { - iter->second = status; - } - } - - void Shutdown() { - std::lock_guard lock(mu_); - if (shutdown_) { - return; - } - shutdown_ = true; - for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) { - iter->second = HealthCheckResponse::NOT_SERVING; - } - } - - private: - std::mutex mu_; - bool shutdown_ = false; - std::map status_map_; -}; - // A custom implementation of the health checking service interface. This is // used to test that it prevents the server from creating a default service and // also serves as an example of how to override the default service. diff --git a/test/cpp/end2end/test_health_check_service_impl.cc b/test/cpp/end2end/test_health_check_service_impl.cc new file mode 100644 index 00000000000..fa70a44d24f --- /dev/null +++ b/test/cpp/end2end/test_health_check_service_impl.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 "test/cpp/end2end/test_health_check_service_impl.h" + +#include + +using grpc::health::v1::HealthCheckRequest; +using grpc::health::v1::HealthCheckResponse; + +namespace grpc { +namespace testing { + +Status HealthCheckServiceImpl::Check(ServerContext* context, + const HealthCheckRequest* request, + HealthCheckResponse* response) { + std::lock_guard lock(mu_); + auto iter = status_map_.find(request->service()); + if (iter == status_map_.end()) { + return Status(StatusCode::NOT_FOUND, ""); + } + response->set_status(iter->second); + return Status::OK; +} +Status HealthCheckServiceImpl::Watch( + ServerContext* context, const HealthCheckRequest* request, + ::grpc::ServerWriter* writer) { + auto last_state = HealthCheckResponse::UNKNOWN; + while (!context->IsCancelled()) { + { + std::lock_guard lock(mu_); + HealthCheckResponse response; + auto iter = status_map_.find(request->service()); + if (iter == status_map_.end()) { + response.set_status(response.SERVICE_UNKNOWN); + } else { + response.set_status(iter->second); + } + if (response.status() != last_state) { + writer->Write(response, ::grpc::WriteOptions()); + } + } + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis(1000, GPR_TIMESPAN))); + } + return Status::OK; +} + +void HealthCheckServiceImpl::SetStatus( + const grpc::string& service_name, + HealthCheckResponse::ServingStatus status) { + std::lock_guard lock(mu_); + if (shutdown_) { + return; + } + status_map_[service_name] = status; +} + +void HealthCheckServiceImpl::SetAll(HealthCheckResponse::ServingStatus status) { + std::lock_guard lock(mu_); + if (shutdown_) { + return; + } + for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) { + iter->second = status; + } +} + +void HealthCheckServiceImpl::Shutdown() { + std::lock_guard lock(mu_); + if (shutdown_) { + return; + } + shutdown_ = true; + for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) { + iter->second = HealthCheckResponse::NOT_SERVING; + } +} + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/end2end/test_health_check_service_impl.h b/test/cpp/end2end/test_health_check_service_impl.h new file mode 100644 index 00000000000..5d36ce5320a --- /dev/null +++ b/test/cpp/end2end/test_health_check_service_impl.h @@ -0,0 +1,58 @@ +/* + * + * 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_CPP_END2END_TEST_HEALTH_CHECK_SERVICE_IMPL_H +#define GRPC_TEST_CPP_END2END_TEST_HEALTH_CHECK_SERVICE_IMPL_H + +#include +#include + +#include +#include + +#include "src/proto/grpc/health/v1/health.grpc.pb.h" + +namespace grpc { +namespace testing { + +// A sample sync implementation of the health checking service. This does the +// same thing as the default one. +class HealthCheckServiceImpl : public health::v1::Health::Service { + public: + Status Check(ServerContext* context, + const health::v1::HealthCheckRequest* request, + health::v1::HealthCheckResponse* response) override; + Status Watch(ServerContext* context, + const health::v1::HealthCheckRequest* request, + ServerWriter* writer) override; + void SetStatus(const grpc::string& service_name, + health::v1::HealthCheckResponse::ServingStatus status); + void SetAll(health::v1::HealthCheckResponse::ServingStatus status); + + void Shutdown(); + + private: + std::mutex mu_; + bool shutdown_ = false; + std::map + status_map_; +}; + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_END2END_TEST_HEALTH_CHECK_SERVICE_IMPL_H diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a7231554e3d..0a7a4daf7de 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -7447,6 +7447,7 @@ "src/proto/grpc/testing/simple_messages.grpc.pb.h", "src/proto/grpc/testing/simple_messages.pb.h", "src/proto/grpc/testing/simple_messages_mock.grpc.pb.h", + "test/cpp/end2end/test_health_check_service_impl.h", "test/cpp/end2end/test_service_impl.h", "test/cpp/util/byte_buffer_proto_helper.h", "test/cpp/util/channel_trace_proto_helper.h", @@ -7459,6 +7460,8 @@ "language": "c++", "name": "grpc++_test_util", "src": [ + "test/cpp/end2end/test_health_check_service_impl.cc", + "test/cpp/end2end/test_health_check_service_impl.h", "test/cpp/end2end/test_service_impl.cc", "test/cpp/end2end/test_service_impl.h", "test/cpp/util/byte_buffer_proto_helper.cc", @@ -7503,6 +7506,7 @@ "src/proto/grpc/testing/simple_messages.grpc.pb.h", "src/proto/grpc/testing/simple_messages.pb.h", "src/proto/grpc/testing/simple_messages_mock.grpc.pb.h", + "test/cpp/end2end/test_health_check_service_impl.h", "test/cpp/end2end/test_service_impl.h", "test/cpp/util/byte_buffer_proto_helper.h", "test/cpp/util/string_ref_helper.h", @@ -7512,6 +7516,8 @@ "language": "c++", "name": "grpc++_test_util_unsecure", "src": [ + "test/cpp/end2end/test_health_check_service_impl.cc", + "test/cpp/end2end/test_health_check_service_impl.h", "test/cpp/end2end/test_service_impl.cc", "test/cpp/end2end/test_service_impl.h", "test/cpp/util/byte_buffer_proto_helper.cc", From da759f1fc63ceb0c893bb6027bacfadfda5ab111 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 18:26:51 -0800 Subject: [PATCH 0476/2143] batch fixes --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 5 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 4 +- src/objective-c/GRPCClient/GRPCCallOptions.m | 32 +-- .../GRPCClient/private/GRPCChannel.h | 5 +- .../GRPCClient/private/GRPCChannel.m | 8 +- .../GRPCClient/private/GRPCChannelPool.h | 13 +- .../GRPCClient/private/GRPCChannelPool.m | 190 +++++++++--------- .../private/GRPCCronetChannelFactory.m | 8 +- src/objective-c/GRPCClient/private/GRPCHost.m | 7 +- .../private/GRPCSecureChannelFactory.m | 5 +- .../GRPCClient/private/GRPCWrappedCall.m | 11 +- .../GRPCClient/private/utilities.h | 22 -- 13 files changed, 143 insertions(+), 169 deletions(-) delete mode 100644 src/objective-c/GRPCClient/private/utilities.h diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 6d8b9c1b127..be63de1af9b 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -206,7 +206,7 @@ extern NSString *const kGRPCTrailersKey; @property(copy, readonly) NSString *path; /** * Specify whether the call is idempotent or cachable. gRPC may select different HTTP verbs for the - * call based on this information. + * call based on this information. The default verb used by gRPC is POST. */ @property(readonly) GRPCCallSafety safety; diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index e75ca7193a7..e56cc72149c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -35,7 +35,6 @@ #import "private/NSData+GRPC.h" #import "private/NSDictionary+GRPC.h" #import "private/NSError+GRPC.h" -#import "private/utilities.h" #import "private/GRPCChannelPool.h" #import "private/GRPCCompletionQueue.h" @@ -277,7 +276,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeData:(NSData *)data { GRXBufferedPipe *copiedPipe = nil; @synchronized(self) { - NSAssert(!_canceled, @"Call arleady canceled."); + NSAssert(!_canceled, @"Call already canceled."); NSAssert(!_finished, @"Call is half-closed before sending data."); if (_canceled) { return; @@ -297,7 +296,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; GRXBufferedPipe *copiedPipe = nil; @synchronized(self) { NSAssert(_started, @"Call not started."); - NSAssert(!_canceled, @"Call arleady canceled."); + NSAssert(!_canceled, @"Call already canceled."); NSAssert(!_finished, @"Call already half-closed."); if (!_started) { return; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 158a4745d23..85786c74174 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -170,7 +170,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * PEM format certificate chain for client authentication, if required by the server. */ -@property(copy, readonly, nullable) NSString *PEMCertChain; +@property(copy, readonly, nullable) NSString *PEMCertificateChain; /** * Select the transport type to be used for this call. @@ -314,7 +314,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * PEM format certificate chain for client authentication, if required by the server. */ -@property(copy, readwrite, nullable) NSString *PEMCertChain; +@property(copy, readwrite, nullable) NSString *PEMCertificateChain; /** * Select the transport type to be used for this call. diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 9a36ee547cd..1962ad8956d 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -35,7 +35,7 @@ static const NSTimeInterval kDefaultConnectMaxBackoff = 0; static NSDictionary *const kDefaultAdditionalChannelArgs = nil; static NSString *const kDefaultPEMRootCertificates = nil; static NSString *const kDefaultPEMPrivateKey = nil; -static NSString *const kDefaultPEMCertChain = nil; +static NSString *const kDefaultPEMCertificateChain = nil; static NSString *const kDefaultOauth2AccessToken = nil; static const id kDefaultAuthTokenProvider = nil; static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2BoringSSL; @@ -74,7 +74,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { NSDictionary *_additionalChannelArgs; NSString *_PEMRootCertificates; NSString *_PEMPrivateKey; - NSString *_PEMCertChain; + NSString *_PEMCertificateChain; GRPCTransportType _transportType; NSString *_hostNameOverride; id _logContext; @@ -99,7 +99,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { @synthesize additionalChannelArgs = _additionalChannelArgs; @synthesize PEMRootCertificates = _PEMRootCertificates; @synthesize PEMPrivateKey = _PEMPrivateKey; -@synthesize PEMCertChain = _PEMCertChain; +@synthesize PEMCertificateChain = _PEMCertificateChain; @synthesize transportType = _transportType; @synthesize hostNameOverride = _hostNameOverride; @synthesize logContext = _logContext; @@ -124,7 +124,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:kDefaultAdditionalChannelArgs PEMRootCertificates:kDefaultPEMRootCertificates PEMPrivateKey:kDefaultPEMPrivateKey - PEMCertChain:kDefaultPEMCertChain + PEMCertificateChain:kDefaultPEMCertificateChain transportType:kDefaultTransportType hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext @@ -149,7 +149,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:(NSDictionary *)additionalChannelArgs PEMRootCertificates:(NSString *)PEMRootCertificates PEMPrivateKey:(NSString *)PEMPrivateKey - PEMCertChain:(NSString *)PEMCertChain + PEMCertificateChain:(NSString *)PEMCertificateChain transportType:(GRPCTransportType)transportType hostNameOverride:(NSString *)hostNameOverride logContext:(id)logContext @@ -174,7 +174,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; _PEMRootCertificates = [PEMRootCertificates copy]; _PEMPrivateKey = [PEMPrivateKey copy]; - _PEMCertChain = [PEMCertChain copy]; + _PEMCertificateChain = [PEMCertificateChain copy]; _transportType = transportType; _hostNameOverride = [hostNameOverride copy]; _logContext = logContext; @@ -203,7 +203,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:_additionalChannelArgs PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey - PEMCertChain:_PEMCertChain + PEMCertificateChain:_PEMCertificateChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -233,7 +233,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { copyItems:YES] PEMRootCertificates:[_PEMRootCertificates copy] PEMPrivateKey:[_PEMPrivateKey copy] - PEMCertChain:[_PEMCertChain copy] + PEMCertificateChain:[_PEMCertificateChain copy] transportType:_transportType hostNameOverride:[_hostNameOverride copy] logContext:_logContext @@ -256,7 +256,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { if (!areObjectsEqual(callOptions.additionalChannelArgs, _additionalChannelArgs)) return NO; if (!areObjectsEqual(callOptions.PEMRootCertificates, _PEMRootCertificates)) return NO; if (!areObjectsEqual(callOptions.PEMPrivateKey, _PEMPrivateKey)) return NO; - if (!areObjectsEqual(callOptions.PEMCertChain, _PEMCertChain)) return NO; + if (!areObjectsEqual(callOptions.PEMCertificateChain, _PEMCertificateChain)) return NO; if (!areObjectsEqual(callOptions.hostNameOverride, _hostNameOverride)) return NO; if (!(callOptions.transportType == _transportType)) return NO; if (!areObjectsEqual(callOptions.logContext, _logContext)) return NO; @@ -280,7 +280,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { result ^= _additionalChannelArgs.hash; result ^= _PEMRootCertificates.hash; result ^= _PEMPrivateKey.hash; - result ^= _PEMCertChain.hash; + result ^= _PEMCertificateChain.hash; result ^= _hostNameOverride.hash; result ^= _transportType; result ^= _logContext.hash; @@ -311,7 +311,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { @dynamic additionalChannelArgs; @dynamic PEMRootCertificates; @dynamic PEMPrivateKey; -@dynamic PEMCertChain; +@dynamic PEMCertificateChain; @dynamic transportType; @dynamic hostNameOverride; @dynamic logContext; @@ -336,7 +336,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:kDefaultAdditionalChannelArgs PEMRootCertificates:kDefaultPEMRootCertificates PEMPrivateKey:kDefaultPEMPrivateKey - PEMCertChain:kDefaultPEMCertChain + PEMCertificateChain:kDefaultPEMCertificateChain transportType:kDefaultTransportType hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext @@ -363,7 +363,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:_additionalChannelArgs PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey - PEMCertChain:_PEMCertChain + PEMCertificateChain:_PEMCertificateChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -391,7 +391,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:[_additionalChannelArgs copy] PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey - PEMCertChain:_PEMCertChain + PEMCertificateChain:_PEMCertificateChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -493,8 +493,8 @@ static BOOL areObjectsEqual(id obj1, id obj2) { _PEMPrivateKey = [PEMPrivateKey copy]; } -- (void)setPEMCertChain:(NSString *)PEMCertChain { - _PEMCertChain = [PEMCertChain copy]; +- (void)setPEMCertificateChain:(NSString *)PEMCertificateChain { + _PEMCertificateChain = [PEMCertificateChain copy]; } - (void)setTransportType:(GRPCTransportType)transportType { diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index c01aeccf81f..bbada0d8cb3 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -29,7 +29,10 @@ struct grpc_channel_credentials; NS_ASSUME_NONNULL_BEGIN -/** Caching signature of a channel. */ +/** + * Signature for the channel. If two channel's signatures are the same and connect to the same + * remote, they share the same underlying \a GRPCChannel object. + */ @interface GRPCChannelConfiguration : NSObject - (instancetype)init NS_UNAVAILABLE; diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 9432e7ab397..edcedf6e24f 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -28,7 +28,6 @@ #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" -#import "utilities.h" #import "version.h" #import @@ -63,8 +62,9 @@ factory = [GRPCSecureChannelFactory factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates privateKey:_callOptions.PEMPrivateKey - certChain:_callOptions.PEMCertChain + certChain:_callOptions.PEMCertificateChain error:&error]; + NSAssert(factory != nil, @"Failed to create secure channel factory"); if (factory == nil) { NSLog(@"Error creating secure channel factory: %@", error); } @@ -114,8 +114,8 @@ [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; } - if (_callOptions.retryEnabled == NO) { - args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.retryEnabled]; + if (!_callOptions.retryEnabled) { + args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.retryEnabled ? 1 : 0]; } if (_callOptions.connectMinTimeout > 0) { diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index d1f28ec9bfa..19ef4c93ac6 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -16,11 +16,6 @@ * */ -/** - * Signature for the channel. If two channel's signatures are the same, they share the same - * underlying \a GRPCChannel object. - */ - #import #import "GRPCChannelFactory.h" @@ -35,10 +30,10 @@ NS_ASSUME_NONNULL_BEGIN @class GRPCWrappedCall; /** - * A proxied channel object that can be retained and creates GRPCWrappedCall object from. If a - * raw channel is not present (i.e. no tcp connection to the server) when a GRPCWrappedCall object - * is requested, it issues a connection/reconnection. The behavior of this object is to mimic that - * of gRPC core's channel object. + * A proxied channel object that can be retained and used to create GRPCWrappedCall object + * regardless of the current connection status. If a connection is not established when a + * GRPCWrappedCall object is requested, it issues a connection/reconnection. This behavior is to + * follow that of gRPC core's channel object. */ @interface GRPCPooledChannel : NSObject diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 349bdd44a65..17c74e558b4 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -27,7 +27,6 @@ #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" -#import "utilities.h" #import "version.h" #import "GRPCWrappedCall.h" #import "GRPCCompletionQueue.h" @@ -57,98 +56,6 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; return [self initWithChannelConfiguration:channelConfiguration destroyDelay:kDefaultChannelDestroyDelay]; } -- (void)dealloc { - // Disconnect GRPCWrappedCall objects created but not yet removed - if (_wrappedCalls.allObjects.count != 0) { - for (GRPCWrappedCall *wrappedCall in _wrappedCalls.allObjects) { - [wrappedCall channelDisconnected]; - }; - } -} - -- (GRPCWrappedCall *)wrappedCallWithPath:(NSString *)path -completionQueue:(GRPCCompletionQueue *)queue -callOptions:(GRPCCallOptions *)callOptions { - NSAssert(path.length > 0, @"path must not be empty."); - NSAssert(queue != nil, @"completionQueue must not be empty."); - NSAssert(callOptions, @"callOptions must not be empty."); - if (path.length == 0 || queue == nil || callOptions == nil) return nil; - - GRPCWrappedCall *call = nil; - - @synchronized(self) { - if (_wrappedChannel == nil) { - _wrappedChannel = [[GRPCChannel alloc] initWithChannelConfiguration:_channelConfiguration]; - if (_wrappedChannel == nil) { - NSAssert(_wrappedChannel != nil, @"Unable to get a raw channel for proxy."); - return nil; - } - } - _lastTimedDestroy = nil; - - grpc_call *unmanagedCall = [_wrappedChannel unmanagedCallWithPath:path - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:callOptions]; - if (unmanagedCall == NULL) { - NSAssert(unmanagedCall != NULL, @"Unable to create grpc_call object"); - return nil; - } - - call = [[GRPCWrappedCall alloc] initWithUnmanagedCall:unmanagedCall pooledChannel:self]; - if (call == nil) { - NSAssert(call != nil, @"Unable to create GRPCWrappedCall object"); - return nil; - } - - [_wrappedCalls addObject:call]; - } - return call; -} - -- (void)notifyWrappedCallDealloc:(GRPCWrappedCall *)wrappedCall { - NSAssert(wrappedCall != nil, @"wrappedCall cannot be empty."); - if (wrappedCall == nil) { - return; - } - @synchronized(self) { - // Detect if all objects weakly referenced in _wrappedCalls are (implicitly) removed. In such - // case the channel is no longer referenced by a grpc_call object and can be destroyed after - // a certain delay. - if (_wrappedCalls.allObjects.count == 0) { - NSDate *now = [NSDate date]; - NSAssert(now != nil, @"Unable to create NSDate object 'now'."); - _lastTimedDestroy = now; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)_destroyDelay * NSEC_PER_SEC), - _timerQueue, ^{ - @synchronized(self) { - if (now != nil && self->_lastTimedDestroy == now) { - self->_wrappedChannel = nil; - self->_lastTimedDestroy = nil; - } - } - }); - } - } -} - -- (void)disconnect { - NSArray *copiedWrappedCalls = nil; - @synchronized(self) { - if (_wrappedChannel != nil) { - _wrappedChannel = nil; - copiedWrappedCalls = _wrappedCalls.allObjects; - [_wrappedCalls removeAllObjects]; - } - } - for (GRPCWrappedCall *wrappedCall in copiedWrappedCalls) { - [wrappedCall channelDisconnected]; - } -} - -@end - -@implementation GRPCPooledChannel (Test) - - (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration destroyDelay:(NSTimeInterval)destroyDelay { NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); @@ -177,6 +84,103 @@ callOptions:(GRPCCallOptions *)callOptions { return self; } +- (void)dealloc { + // Disconnect GRPCWrappedCall objects created but not yet removed + if (_wrappedCalls.allObjects.count != 0) { + for (GRPCWrappedCall *wrappedCall in _wrappedCalls.allObjects) { + [wrappedCall channelDisconnected]; + }; + } +} + +- (GRPCWrappedCall *)wrappedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions { + NSAssert(path.length > 0, @"path must not be empty."); + NSAssert(queue != nil, @"completionQueue must not be empty."); + NSAssert(callOptions, @"callOptions must not be empty."); + if (path.length == 0 || queue == nil || callOptions == nil) { + return nil; + } + + GRPCWrappedCall *call = nil; + + @synchronized(self) { + if (_wrappedChannel == nil) { + _wrappedChannel = [[GRPCChannel alloc] initWithChannelConfiguration:_channelConfiguration]; + if (_wrappedChannel == nil) { + NSAssert(_wrappedChannel != nil, @"Unable to get a raw channel for proxy."); + return nil; + } + } + _lastTimedDestroy = nil; + + grpc_call *unmanagedCall = [_wrappedChannel unmanagedCallWithPath:path + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:callOptions]; + if (unmanagedCall == NULL) { + NSAssert(unmanagedCall != NULL, @"Unable to create grpc_call object"); + return nil; + } + + call = [[GRPCWrappedCall alloc] initWithUnmanagedCall:unmanagedCall pooledChannel:self]; + if (call == nil) { + NSAssert(call != nil, @"Unable to create GRPCWrappedCall object"); + grpc_call_unref(unmanagedCall); + return nil; + } + + [_wrappedCalls addObject:call]; + } + return call; +} + +- (void)notifyWrappedCallDealloc:(GRPCWrappedCall *)wrappedCall { + NSAssert(wrappedCall != nil, @"wrappedCall cannot be empty."); + if (wrappedCall == nil) { + return; + } + @synchronized(self) { + // Detect if all objects weakly referenced in _wrappedCalls are (implicitly) removed. + // _wrappedCalls.count does not work here since the hash table may include deallocated weak + // references. _wrappedCalls.allObjects forces removal of those objects. + if (_wrappedCalls.allObjects.count == 0) { + // No more call has reference to this channel. We may start the timer for destroying the + // channel now. + NSDate *now = [NSDate date]; + NSAssert(now != nil, @"Unable to create NSDate object 'now'."); + _lastTimedDestroy = now; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)_destroyDelay * NSEC_PER_SEC), + _timerQueue, ^{ + @synchronized(self) { + // Check _lastTimedDestroy against now in case more calls are created (and + // maybe destroyed) after this dispatch_async. In that case the current + // dispatch_after block should be discarded; the channel should be + // destroyed in a later dispatch_after block. + if (now != nil && self->_lastTimedDestroy == now) { + self->_wrappedChannel = nil; + self->_lastTimedDestroy = nil; + } + } + }); + } + } +} + +- (void)disconnect { + NSArray *copiedWrappedCalls = nil; + @synchronized(self) { + if (_wrappedChannel != nil) { + _wrappedChannel = nil; + copiedWrappedCalls = _wrappedCalls.allObjects; + [_wrappedCalls removeAllObjects]; + } + } + for (GRPCWrappedCall *wrappedCall in copiedWrappedCalls) { + [wrappedCall channelDisconnected]; + } +} + - (GRPCChannel *)wrappedChannel { GRPCChannel *channel = nil; @synchronized(self) { diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m index 0aeb67b1426..5bcb021dc4b 100644 --- a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -40,8 +40,8 @@ } - (instancetype)initWithEngine:(stream_engine *)engine { + NSAssert(engine != NULL, @"Cronet engine cannot be empty."); if (!engine) { - [NSException raise:NSInvalidArgumentException format:@"Cronet engine is NULL. Set it first."]; return nil; } if ((self = [super init])) { @@ -65,14 +65,12 @@ @implementation GRPCCronetChannelFactory + (instancetype)sharedInstance { - [NSException raise:NSInvalidArgumentException - format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; + NSAssert(NO, @"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."); return nil; } - (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { - [NSException raise:NSInvalidArgumentException - format:@"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."]; + NSAssert(NO, @"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."); return NULL; } diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 0f2281ede85..e7a7460221f 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -32,7 +32,6 @@ #import "GRPCCronetChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" -#import "utilities.h" #import "version.h" NS_ASSUME_NONNULL_BEGIN @@ -42,7 +41,7 @@ static NSMutableDictionary *gHostCache; @implementation GRPCHost { NSString *_PEMRootCertificates; NSString *_PEMPrivateKey; - NSString *_pemCertChain; + NSString *_PEMCertificateChain; } + (nullable instancetype)hostWithAddress:(NSString *)address { @@ -96,7 +95,7 @@ static NSMutableDictionary *gHostCache; error:(NSError **)errorPtr { _PEMRootCertificates = [pemRootCerts copy]; _PEMPrivateKey = [pemPrivateKey copy]; - _pemCertChain = [pemCertChain copy]; + _PEMCertificateChain = [pemCertChain copy]; return YES; } @@ -113,7 +112,7 @@ static NSMutableDictionary *gHostCache; options.connectMaxBackoff = (NSTimeInterval)_maxConnectBackoff / 1000; options.PEMRootCertificates = _PEMRootCertificates; options.PEMPrivateKey = _PEMPrivateKey; - options.PEMCertChain = _pemCertChain; + options.PEMCertificateChain = _PEMCertificateChain; options.hostNameOverride = _hostNameOverride; #ifdef GRPC_COMPILE_WITH_CRONET // By old API logic, insecure channel precedes Cronet channel; Cronet channel preceeds default diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 69f70de17d1..3ccc70a7448 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -22,7 +22,6 @@ #import "ChannelArgsUtil.h" #import "GRPCChannel.h" -#import "utilities.h" @implementation GRPCSecureChannelFactory { grpc_channel_credentials *_channelCreds; @@ -116,6 +115,10 @@ } - (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { + NSAssert(host.length != 0, @"host cannot be empty"); + if (host.length == 0) { + return NULL; + } grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 727c9e0a88e..82149e3dba5 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -30,7 +30,6 @@ #import "NSData+GRPC.h" #import "NSDictionary+GRPC.h" #import "NSError+GRPC.h" -#import "utilities.h" #import "GRPCOpBatchLog.h" @@ -237,6 +236,7 @@ #pragma mark GRPCWrappedCall @implementation GRPCWrappedCall { + // pooledChannel holds weak reference to this object so this is ok GRPCPooledChannel *_pooledChannel; grpc_call *_call; } @@ -275,8 +275,7 @@ for (GRPCOperation *operation in operations) { ops_array[i++] = operation.op; } - grpc_call_error error; - error = grpc_call_start_batch(_call, ops_array, nops, (__bridge_retained void *)(^(bool success) { + grpc_call_error error = grpc_call_start_batch(_call, ops_array, nops, (__bridge_retained void *)(^(bool success) { if (!success) { if (errorHandler) { errorHandler(); @@ -291,11 +290,7 @@ NULL); gpr_free(ops_array); - if (error != GRPC_CALL_OK) { - [NSException - raise:NSInternalInconsistencyException - format:@"A precondition for calling grpc_call_start_batch wasn't met. Error %i", error]; - } + NSAssert(error == GRPC_CALL_OK, @"Error starting a batch of operations: %i", error); } } } diff --git a/src/objective-c/GRPCClient/private/utilities.h b/src/objective-c/GRPCClient/private/utilities.h deleted file mode 100644 index 8e3dd793586..00000000000 --- a/src/objective-c/GRPCClient/private/utilities.h +++ /dev/null @@ -1,22 +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. - * - */ - -#import - -/** Raise exception when condition not met. */ -#define GRPCAssert(condition, errorString) NSAssert(condition, errorString) From 1a9404876ce0315fc05fe82465dc389600db0965 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 19:07:25 -0800 Subject: [PATCH 0477/2143] batch fixes --- src/objective-c/GRPCClient/private/GRPCChannel.m | 16 ++++++---------- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.m | 15 ++++++++------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index edcedf6e24f..12acfa14295 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -50,16 +50,17 @@ } - (id)channelFactory { - NSError *error; - id factory; GRPCTransportType type = _callOptions.transportType; switch (type) { case GRPCTransportTypeChttp2BoringSSL: // TODO (mxyan): Remove when the API is deprecated #ifdef GRPC_COMPILE_WITH_CRONET if (![GRPCCall isUsingCronet]) { +#else + { #endif - factory = [GRPCSecureChannelFactory + NSError *error; + id factory = [GRPCSecureChannelFactory factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates privateKey:_callOptions.PEMPrivateKey certChain:_callOptions.PEMCertificateChain @@ -69,9 +70,7 @@ NSLog(@"Error creating secure channel factory: %@", error); } return factory; -#ifdef GRPC_COMPILE_WITH_CRONET } -#endif // fallthrough case GRPCTransportTypeCronet: return [GRPCCronetChannelFactory sharedInstance]; @@ -164,7 +163,7 @@ } - (NSUInteger)hash { - NSUInteger result = 0; + NSUInteger result = 31; result ^= _host.hash; result ^= _callOptions.channelOptionsHash; @@ -230,10 +229,7 @@ NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); if (timeout < 0) return NULL; - grpc_slice host_slice = grpc_empty_slice(); - if (serverAuthority) { - host_slice = grpc_slice_from_copied_string(serverAuthority.UTF8String); - } + grpc_slice host_slice = serverAuthority ? grpc_slice_from_copied_string(serverAuthority.UTF8String) : grpc_empty_slice(); grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); gpr_timespec deadline_ms = timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index e7a7460221f..24348c3aed7 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -75,7 +75,7 @@ static NSMutableDictionary *gHostCache; } if ((self = [super init])) { - _address = address; + _address = [address copy]; _retryEnabled = YES; gHostCache[address] = self; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 0f63f72f536..89f0b3f3473 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -97,14 +97,13 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { - if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { - [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; - } - if (requestOptions.safety > GRPCCallSafetyCacheableRequest) { - [NSException raise:NSInvalidArgumentException format:@"Invalid call safety value."]; + NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0 && requestOptions.safety <= GRPCCallSafetyCacheableRequest, @"Invalid callOptions."); + NSAssert(handler != nil, @"handler cannot be empty."); + if (requestOptions.host.length == 0 || requestOptions.path.length == 0 || requestOptions.safety > GRPCCallSafetyCacheableRequest) { + return nil; } if (handler == nil) { - [NSException raise:NSInvalidArgumentException format:@"Response handler required."]; + return nil; } if ((self = [super init])) { @@ -166,8 +165,10 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)writeMessage:(GPBMessage *)message { + NSAssert([message isKindOfClass:[GPBMessage class]]); if (![message isKindOfClass:[GPBMessage class]]) { - [NSException raise:NSInvalidArgumentException format:@"Data must be a valid protobuf type."]; + NSLog(@"Failed to send a message that is non-proto."); + return; } GRPCCall2 *call; From f0f6e03212837c67d7e078e6f33074e80aa4bcc0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 6 Dec 2018 22:41:03 -0800 Subject: [PATCH 0478/2143] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 19 ++--- src/objective-c/GRPCClient/GRPCCallOptions.m | 8 +-- .../GRPCClient/private/GRPCChannel.m | 6 +- .../GRPCClient/private/GRPCChannelPool+Test.h | 4 +- .../GRPCClient/private/GRPCChannelPool.h | 2 +- .../GRPCClient/private/GRPCChannelPool.m | 26 +++---- .../GRPCClient/private/GRPCWrappedCall.h | 2 +- .../GRPCClient/private/GRPCWrappedCall.m | 35 ++++----- src/objective-c/ProtoRPC/ProtoRPC.m | 24 ++++--- .../tests/ChannelTests/ChannelTests.m | 49 ++++++------- src/objective-c/tests/InteropTests.m | 71 ++++++++++--------- 12 files changed, 126 insertions(+), 122 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index be63de1af9b..b549f5d2bf3 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -181,7 +181,7 @@ extern NSString *const kGRPCTrailersKey; * error descriptions. */ - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata - error:(nullable NSError *)error; + error:(nullable NSError *)error; @end diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index e56cc72149c..589b52031a7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -28,6 +28,8 @@ #include #import "GRPCCallOptions.h" +#import "private/GRPCChannelPool.h" +#import "private/GRPCCompletionQueue.h" #import "private/GRPCConnectivityMonitor.h" #import "private/GRPCHost.h" #import "private/GRPCRequestHeaders.h" @@ -35,8 +37,6 @@ #import "private/NSData+GRPC.h" #import "private/NSDictionary+GRPC.h" #import "private/NSError+GRPC.h" -#import "private/GRPCChannelPool.h" -#import "private/GRPCCompletionQueue.h" // At most 6 ops can be in an op batch for a client: SEND_INITIAL_METADATA, // SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT, RECV_INITIAL_METADATA, RECV_MESSAGE, @@ -259,12 +259,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; } [copiedHandler didCloseWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; }); } else { _handler = nil; @@ -819,7 +819,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; - GRPCPooledChannel *channel = [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; + GRPCPooledChannel *channel = + [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:_path completionQueue:[GRPCCompletionQueue completionQueue] callOptions:_callOptions]; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 1962ad8956d..d3440ee6c07 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -233,7 +233,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { copyItems:YES] PEMRootCertificates:[_PEMRootCertificates copy] PEMPrivateKey:[_PEMPrivateKey copy] - PEMCertificateChain:[_PEMCertificateChain copy] + PEMCertificateChain:[_PEMCertificateChain copy] transportType:_transportType hostNameOverride:[_hostNameOverride copy] logContext:_logContext @@ -336,7 +336,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:kDefaultAdditionalChannelArgs PEMRootCertificates:kDefaultPEMRootCertificates PEMPrivateKey:kDefaultPEMPrivateKey - PEMCertificateChain:kDefaultPEMCertificateChain + PEMCertificateChain:kDefaultPEMCertificateChain transportType:kDefaultTransportType hostNameOverride:kDefaultHostNameOverride logContext:kDefaultLogContext @@ -363,7 +363,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:_additionalChannelArgs PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey - PEMCertificateChain:_PEMCertificateChain + PEMCertificateChain:_PEMCertificateChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext @@ -391,7 +391,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { additionalChannelArgs:[_additionalChannelArgs copy] PEMRootCertificates:_PEMRootCertificates PEMPrivateKey:_PEMPrivateKey - PEMCertificateChain:_PEMCertificateChain + PEMCertificateChain:_PEMCertificateChain transportType:_transportType hostNameOverride:_hostNameOverride logContext:_logContext diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 12acfa14295..1a79fb04a0d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -57,7 +57,7 @@ #ifdef GRPC_COMPILE_WITH_CRONET if (![GRPCCall isUsingCronet]) { #else - { + { #endif NSError *error; id factory = [GRPCSecureChannelFactory @@ -229,7 +229,9 @@ NSTimeInterval timeout = callOptions.timeout; NSAssert(timeout >= 0, @"Invalid timeout"); if (timeout < 0) return NULL; - grpc_slice host_slice = serverAuthority ? grpc_slice_from_copied_string(serverAuthority.UTF8String) : grpc_empty_slice(); + grpc_slice host_slice = serverAuthority + ? grpc_slice_from_copied_string(serverAuthority.UTF8String) + : grpc_empty_slice(); grpc_slice path_slice = grpc_slice_from_copied_string(path.UTF8String); gpr_timespec deadline_ms = timeout == 0 ? gpr_inf_future(GPR_CLOCK_REALTIME) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h index 4e7c988585d..ca0cc51a52c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h @@ -25,7 +25,7 @@ * Initialize a pooled channel with non-default destroy delay for testing purpose. */ - (nullable instancetype)initWithChannelConfiguration: -(GRPCChannelConfiguration *)channelConfiguration + (GRPCChannelConfiguration *)channelConfiguration destroyDelay:(NSTimeInterval)destroyDelay; /** @@ -45,5 +45,3 @@ - (nullable instancetype)initTestPool; @end - - diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index 19ef4c93ac6..d3a99ca8263 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN * Initialize with an actual channel object \a channel and a reference to the channel pool. */ - (nullable instancetype)initWithChannelConfiguration: - (GRPCChannelConfiguration *)channelConfiguration; + (GRPCChannelConfiguration *)channelConfiguration; /** * Create a GRPCWrappedCall object (grpc_call) from this channel. If channel is disconnected, get a diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 17c74e558b4..a323f0490c8 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -21,15 +21,15 @@ #import "../internal/GRPCCallOptions+Internal.h" #import "GRPCChannel.h" #import "GRPCChannelFactory.h" -#import "GRPCChannelPool.h" #import "GRPCChannelPool+Test.h" +#import "GRPCChannelPool.h" +#import "GRPCCompletionQueue.h" #import "GRPCConnectivityMonitor.h" #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" -#import "version.h" #import "GRPCWrappedCall.h" -#import "GRPCCompletionQueue.h" +#import "version.h" #import #include @@ -53,10 +53,12 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { - return [self initWithChannelConfiguration:channelConfiguration destroyDelay:kDefaultChannelDestroyDelay]; + return [self initWithChannelConfiguration:channelConfiguration + destroyDelay:kDefaultChannelDestroyDelay]; } -- (nullable instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration destroyDelay:(NSTimeInterval)destroyDelay { NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); if (channelConfiguration == nil) { @@ -71,8 +73,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; _lastTimedDestroy = nil; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 if (@available(iOS 8.0, macOS 10.10, *)) { - _timerQueue = dispatch_queue_create(NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + _timerQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class( + DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { #else { @@ -115,9 +117,10 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } _lastTimedDestroy = nil; - grpc_call *unmanagedCall = [_wrappedChannel unmanagedCallWithPath:path - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:callOptions]; + grpc_call *unmanagedCall = + [_wrappedChannel unmanagedCallWithPath:path + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:callOptions]; if (unmanagedCall == NULL) { NSAssert(unmanagedCall != NULL, @"Unable to create grpc_call object"); return nil; @@ -203,8 +206,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; + (instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ - gChannelPool = - [[GRPCChannelPool alloc] initPrivate]; + gChannelPool = [[GRPCChannelPool alloc] initPrivate]; NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); }); return gChannelPool; diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h index 0432190528f..92bd1be2570 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h @@ -77,7 +77,7 @@ - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; - (instancetype)initWithUnmanagedCall:(grpc_call *)unmanagedCall pooledChannel:(GRPCPooledChannel *)pooledChannel NS_DESIGNATED_INITIALIZER; diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 82149e3dba5..9066cb950f4 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -267,7 +267,7 @@ [GRPCOpBatchLog addOpBatchToLog:operations]; #endif - @synchronized (self) { + @synchronized(self) { if (_call != NULL) { size_t nops = operations.count; grpc_op *ops_array = gpr_malloc(nops * sizeof(grpc_op)); @@ -275,19 +275,20 @@ for (GRPCOperation *operation in operations) { ops_array[i++] = operation.op; } - grpc_call_error error = grpc_call_start_batch(_call, ops_array, nops, (__bridge_retained void *)(^(bool success) { - if (!success) { - if (errorHandler) { - errorHandler(); - } else { - return; - } - } - for (GRPCOperation *operation in operations) { - [operation finish]; - } - }), - NULL); + grpc_call_error error = + grpc_call_start_batch(_call, ops_array, nops, (__bridge_retained void *)(^(bool success) { + if (!success) { + if (errorHandler) { + errorHandler(); + } else { + return; + } + } + for (GRPCOperation *operation in operations) { + [operation finish]; + } + }), + NULL); gpr_free(ops_array); NSAssert(error == GRPC_CALL_OK, @"Error starting a batch of operations: %i", error); @@ -296,7 +297,7 @@ } - (void)cancel { - @synchronized (self) { + @synchronized(self) { if (_call != NULL) { grpc_call_cancel(_call, NULL); } @@ -304,7 +305,7 @@ } - (void)channelDisconnected { - @synchronized (self) { + @synchronized(self) { if (_call != NULL) { grpc_call_unref(_call); _call = NULL; @@ -313,7 +314,7 @@ } - (void)dealloc { - @synchronized (self) { + @synchronized(self) { if (_call != NULL) { grpc_call_unref(_call); _call = NULL; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 89f0b3f3473..da534351780 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -97,9 +97,12 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { - NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0 && requestOptions.safety <= GRPCCallSafetyCacheableRequest, @"Invalid callOptions."); + NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0 && + requestOptions.safety <= GRPCCallSafetyCacheableRequest, + @"Invalid callOptions."); NSAssert(handler != nil, @"handler cannot be empty."); - if (requestOptions.host.length == 0 || requestOptions.path.length == 0 || requestOptions.safety > GRPCCallSafetyCacheableRequest) { + if (requestOptions.host.length == 0 || requestOptions.path.length == 0 || + requestOptions.safety > GRPCCallSafetyCacheableRequest) { return nil; } if (handler == nil) { @@ -150,12 +153,12 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing self->_handler = nil; } [copiedHandler didCloseWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; }); } else { _handler = nil; @@ -223,8 +226,9 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing copiedHandler = self->_handler; self->_handler = nil; } - [copiedHandler didCloseWithTrailingMetadata:nil - error:ErrorForBadProto(message, _responseClass, error)]; + [copiedHandler + didCloseWithTrailingMetadata:nil + error:ErrorForBadProto(message, _responseClass, error)]; }); [_call cancel]; _call = nil; diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m index 7c80868c2c9..df78e8b1162 100644 --- a/src/objective-c/tests/ChannelTests/ChannelTests.m +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -20,8 +20,8 @@ #import "../../GRPCClient/GRPCCallOptions.h" #import "../../GRPCClient/private/GRPCChannel.h" -#import "../../GRPCClient/private/GRPCChannelPool.h" #import "../../GRPCClient/private/GRPCChannelPool+Test.h" +#import "../../GRPCClient/private/GRPCChannelPool.h" #import "../../GRPCClient/private/GRPCCompletionQueue.h" #import "../../GRPCClient/private/GRPCWrappedCall.h" @@ -40,13 +40,12 @@ static NSString *kDummyPath = @"/dummy/path"; - (void)testPooledChannelCreatingChannel { GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost - callOptions:options]; + GRPCChannelConfiguration *config = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options]; GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config]; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + GRPCWrappedCall *wrappedCall = + [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); (void)wrappedCall; } @@ -54,26 +53,22 @@ static NSString *kDummyPath = @"/dummy/path"; - (void)testTimedDestroyChannel { const NSTimeInterval kDestroyDelay = 1.0; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost - callOptions:options]; - GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config - destroyDelay:kDestroyDelay]; + GRPCChannelConfiguration *config = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options]; + GRPCPooledChannel *channel = + [[GRPCPooledChannel alloc] initWithChannelConfiguration:config destroyDelay:kDestroyDelay]; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; GRPCWrappedCall *wrappedCall; GRPCChannel *wrappedChannel; @autoreleasepool { - wrappedCall = [channel wrappedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + wrappedCall = [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); // Unref and ref channel immediately; expect using the same raw channel. wrappedChannel = channel.wrappedChannel; wrappedCall = nil; - wrappedCall = [channel wrappedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + wrappedCall = [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertEqual(channel.wrappedChannel, wrappedChannel); // Unref and ref channel after destroy delay; expect a new raw channel. @@ -81,23 +76,20 @@ static NSString *kDummyPath = @"/dummy/path"; } sleep(kDestroyDelay + 1); XCTAssertNil(channel.wrappedChannel); - wrappedCall = [channel wrappedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + wrappedCall = [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); } - (void)testDisconnect { const NSTimeInterval kDestroyDelay = 1.0; GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - GRPCChannelConfiguration *config = [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost - callOptions:options]; - GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config - destroyDelay:kDestroyDelay]; + GRPCChannelConfiguration *config = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options]; + GRPCPooledChannel *channel = + [[GRPCPooledChannel alloc] initWithChannelConfiguration:config destroyDelay:kDestroyDelay]; GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; - GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + GRPCWrappedCall *wrappedCall = + [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); // Disconnect; expect wrapped channel to be dropped @@ -106,9 +98,8 @@ static NSString *kDummyPath = @"/dummy/path"; // Create a new call and unref the old call; confirm that destroy of the old call does not make // the channel disconnect, even after the destroy delay. - GRPCWrappedCall *wrappedCall2 = [channel wrappedCallWithPath:kDummyPath - completionQueue:cq - callOptions:options]; + GRPCWrappedCall *wrappedCall2 = + [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; XCTAssertNotNil(channel.wrappedChannel); GRPCChannel *wrappedChannel = channel.wrappedChannel; wrappedCall = nil; diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index d17a07f929a..3665e9705d8 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -249,8 +249,10 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testLargeUnaryRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectRecvMessage = [self expectationWithDescription:@"LargeUnaryWithV2API received message"]; - __weak XCTestExpectation *expectRecvComplete = [self expectationWithDescription:@"LargeUnaryWithV2API received complete"]; + __weak XCTestExpectation *expectRecvMessage = + [self expectationWithDescription:@"LargeUnaryWithV2API received message"]; + __weak XCTestExpectation *expectRecvComplete = + [self expectationWithDescription:@"LargeUnaryWithV2API received complete"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; request.responseType = RMTPayloadType_Compressable; @@ -263,24 +265,26 @@ BOOL isRemoteInteropTest(NSString *host) { options.hostNameOverride = [[self class] hostNameOverride]; GRPCUnaryProtoCall *call = [_service - unaryCallWithMessage:request - responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - XCTAssertNotNil(message); - if (message) { - RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message]; - expectedResponse.payload.type = RMTPayloadType_Compressable; - expectedResponse.payload.body = [NSMutableData dataWithLength:314159]; - XCTAssertEqualObjects(message, expectedResponse); + unaryCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertNotNil(message); + if (message) { + RMTSimpleResponse *expectedResponse = + [RMTSimpleResponse message]; + expectedResponse.payload.type = RMTPayloadType_Compressable; + expectedResponse.payload.body = + [NSMutableData dataWithLength:314159]; + XCTAssertEqualObjects(message, expectedResponse); - [expectRecvMessage fulfill]; - } - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error, @"Unexpected error: %@", error); - [expectRecvComplete fulfill]; - }] - callOptions:options]; + [expectRecvMessage fulfill]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + [expectRecvComplete fulfill]; + }] + callOptions:options]; [call start]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } @@ -602,7 +606,8 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testCancelAfterBeginRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBeginWithV2API"]; + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"CancelAfterBeginWithV2API"]; // A buffered pipe to which we never write any value acts as a writer that just hangs. __block GRPCStreamingProtoCall *call = [_service @@ -699,7 +704,7 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testCancelAfterFirstRequestWithV2API { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *completionExpectation = - [self expectationWithDescription:@"Call completed."]; + [self expectationWithDescription:@"Call completed."]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = self.class.transportType; @@ -707,20 +712,20 @@ BOOL isRemoteInteropTest(NSString *host) { options.hostNameOverride = [[self class] hostNameOverride]; id request = - [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; + [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; __block GRPCStreamingProtoCall *call = [_service - fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - XCTFail(@"Received unexpected response."); - } - closeCallback:^(NSDictionary *trailingMetadata, - NSError *error) { - XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); - [completionExpectation fulfill]; - }] - callOptions:options]; + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTFail(@"Received unexpected response."); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + [completionExpectation fulfill]; + }] + callOptions:options]; [call start]; [call writeMessage:request]; [call cancel]; From a6a21d1c64b610805c42ca2218d6d95313cb5329 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 7 Dec 2018 08:38:29 -0800 Subject: [PATCH 0479/2143] more code review changes --- test/cpp/end2end/client_lb_end2end_test.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index f60f110c5ff..40b657f1053 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -522,13 +522,15 @@ TEST_F(ClientLbEnd2endTest, EXPECT_FALSE( channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10))); // Reset connection backoff. + // Note that the time at which the third attempt will be started is + // actually computed at this point, so we record the start time here. gpr_log(GPR_INFO, "=== RESETTING BACKOFF"); + const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); experimental::ChannelResetConnectionBackoff(channel.get()); // Trigger a second connection attempt. This should also fail // ~immediately, but the retry should be scheduled for // kInitialBackOffMs instead of applying the multiplier. gpr_log(GPR_INFO, "=== POLLING FOR SECOND CONNECTION ATTEMPT"); - const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); EXPECT_FALSE( channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10))); // Bring up a server on the chosen port. From 2246607dedfbad98c3aa4f39997907a203985863 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 7 Dec 2018 08:54:47 -0800 Subject: [PATCH 0480/2143] Review comments --- .../health/default_health_check_service.cc | 3 ++- .../end2end/health_service_end2end_test.cc | 19 +++++++++++-------- .../end2end/test_health_check_service_impl.cc | 3 ++- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index db6286d240e..44aebd2f9d9 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -43,7 +43,8 @@ void DefaultHealthCheckService::SetServingStatus( const grpc::string& service_name, bool serving) { std::unique_lock lock(mu_); if (shutdown_) { - return; + // Set to NOT_SERVING in case service_name is not in the map. + serving = false; } services_map_[service_name].SetServingStatus(serving ? SERVING : NOT_SERVING); } diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index 94c92327c87..b96ff53a3ea 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -211,14 +211,16 @@ class HealthServiceEnd2endTest : public ::testing::Test { // 1. unary client will see NOT_SERVING. // 2. unary client still sees NOT_SERVING after a SetServing(true) is called. // 3. streaming (Watch) client will see an update. + // 4. setting a new service to serving after shutdown will add the service + // name but return NOT_SERVING to client. // This has to be called last. void VerifyHealthCheckServiceShutdown() { - const grpc::string kServiceName("service_name"); HealthCheckServiceInterface* service = server_->GetHealthCheckService(); EXPECT_TRUE(service != nullptr); const grpc::string kHealthyService("healthy_service"); const grpc::string kUnhealthyService("unhealthy_service"); const grpc::string kNotRegisteredService("not_registered"); + const grpc::string kNewService("add_after_shutdown"); service->SetServingStatus(kHealthyService, true); service->SetServingStatus(kUnhealthyService, false); @@ -227,18 +229,12 @@ class HealthServiceEnd2endTest : public ::testing::Test { // Start Watch for service. ClientContext context; HealthCheckRequest request; - request.set_service(kServiceName); + request.set_service(kHealthyService); std::unique_ptr<::grpc::ClientReaderInterface> reader = hc_stub_->Watch(&context, request); - // Initial response will be SERVICE_UNKNOWN. HealthCheckResponse response; EXPECT_TRUE(reader->Read(&response)); - EXPECT_EQ(response.SERVICE_UNKNOWN, response.status()); - - // Set service to SERVING and make sure we get an update. - service->SetServingStatus(kServiceName, true); - EXPECT_TRUE(reader->Read(&response)); EXPECT_EQ(response.SERVING, response.status()); SendHealthCheckRpc("", Status::OK, HealthCheckResponse::SERVING); @@ -248,6 +244,7 @@ class HealthServiceEnd2endTest : public ::testing::Test { HealthCheckResponse::NOT_SERVING); SendHealthCheckRpc(kNotRegisteredService, Status(StatusCode::NOT_FOUND, "")); + SendHealthCheckRpc(kNewService, Status(StatusCode::NOT_FOUND, "")); // Shutdown health check service. service->Shutdown(); @@ -270,6 +267,12 @@ class HealthServiceEnd2endTest : public ::testing::Test { service->SetServingStatus(kHealthyService, true); SendHealthCheckRpc(kHealthyService, Status::OK, HealthCheckResponse::NOT_SERVING); + + // Adding serving status for a new service after shutdown will return + // NOT_SERVING. + service->SetServingStatus(kNewService, true); + SendHealthCheckRpc(kNewService, Status::OK, + HealthCheckResponse::NOT_SERVING); } TestServiceImpl echo_test_service_; diff --git a/test/cpp/end2end/test_health_check_service_impl.cc b/test/cpp/end2end/test_health_check_service_impl.cc index fa70a44d24f..0801e301996 100644 --- a/test/cpp/end2end/test_health_check_service_impl.cc +++ b/test/cpp/end2end/test_health_check_service_impl.cc @@ -37,6 +37,7 @@ Status HealthCheckServiceImpl::Check(ServerContext* context, response->set_status(iter->second); return Status::OK; } + Status HealthCheckServiceImpl::Watch( ServerContext* context, const HealthCheckRequest* request, ::grpc::ServerWriter* writer) { @@ -66,7 +67,7 @@ void HealthCheckServiceImpl::SetStatus( HealthCheckResponse::ServingStatus status) { std::lock_guard lock(mu_); if (shutdown_) { - return; + status = HealthCheckResponse::NOT_SERVING; } status_map_[service_name] = status; } From c5528b821b80f14f49d3a2857b12aecad0c6f009 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 7 Dec 2018 09:24:51 -0800 Subject: [PATCH 0481/2143] Remove unnecessary initialization of fields in PickState. --- src/core/ext/filters/client_channel/client_channel.cc | 6 ------ 1 file changed, 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 3347676a48f..ebc412b468d 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -570,12 +570,6 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { } else { grpc_error* error = GRPC_ERROR_NONE; grpc_core::LoadBalancingPolicy::PickState pick_state; - pick_state.initial_metadata = nullptr; - pick_state.initial_metadata_flags = 0; - pick_state.on_complete = nullptr; - memset(&pick_state.subchannel_call_context, 0, - sizeof(pick_state.subchannel_call_context)); - pick_state.user_data = nullptr; // Pick must return synchronously, because pick_state.on_complete is null. GPR_ASSERT(chand->lb_policy->PickLocked(&pick_state, &error)); if (pick_state.connected_subchannel != nullptr) { From d758ca9196eb157349e6b531218e18849abe65af Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 7 Dec 2018 09:25:54 -0800 Subject: [PATCH 0482/2143] clang-format --- src/core/lib/surface/init.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index aaa6939c90c..53e3db055dc 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -196,6 +196,4 @@ int grpc_is_initialized(void) { return r; } -void grpc_test_x(void) { - gpr_log(GPR_ERROR, "X"); -} +void grpc_test_x(void) { gpr_log(GPR_ERROR, "X"); } From 7fc52366a093aa23bba5a0daaa6cec0eb43a067f Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 7 Dec 2018 10:01:54 -0800 Subject: [PATCH 0483/2143] Fix alarm_test --- test/cpp/common/BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/common/BUILD b/test/cpp/common/BUILD index 73fcea94d9f..01699b26add 100644 --- a/test/cpp/common/BUILD +++ b/test/cpp/common/BUILD @@ -26,7 +26,7 @@ grpc_cc_test( ], deps = [ "//:grpc++_unsecure", - "//test/core/util:grpc_test_util", + "//test/core/util:grpc_test_util_unsecure", ], ) From 87b1c3ce56363a557f2874ab94b8af516e8ae532 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 7 Dec 2018 10:11:30 -0800 Subject: [PATCH 0484/2143] reviewer feedback --- .../ext/filters/client_channel/connector.h | 4 ++-- .../ext/filters/client_channel/subchannel.cc | 4 +--- .../chttp2/client/chttp2_connector.cc | 3 ++- .../chttp2/transport/chttp2_transport.cc | 6 +++--- .../chttp2/transport/chttp2_transport.h | 4 ++-- src/core/lib/surface/server.cc | 20 ++++++++++--------- src/core/lib/surface/server.h | 10 +++++----- test/core/end2end/tests/channelz.cc | 2 +- 8 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/core/ext/filters/client_channel/connector.h b/src/core/ext/filters/client_channel/connector.h index 484cc1b3c39..a5ef9bc2555 100644 --- a/src/core/ext/filters/client_channel/connector.h +++ b/src/core/ext/filters/client_channel/connector.h @@ -49,8 +49,8 @@ typedef struct { /** channel arguments (to be passed to the filters) */ grpc_channel_args* channel_args; - /** socket node of the connected transport */ - grpc_core::channelz::SocketNode* socket_node; + /** socket node of the connected transport. 0 if not availible */ + intptr_t socket_uuid; } grpc_connect_out_args; struct grpc_connector_vtable { diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index e66b0711cf9..0817b1dd392 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -826,9 +826,7 @@ static bool publish_transport_locked(grpc_subchannel* c) { GRPC_ERROR_UNREF(error); return false; } - intptr_t socket_uuid = c->connecting_result.socket_node == nullptr - ? 0 - : c->connecting_result.socket_node->uuid(); + intptr_t socket_uuid = c->connecting_result.socket_uuid; memset(&c->connecting_result, 0, sizeof(c->connecting_result)); if (c->disconnected) { diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index 62a07d2ba61..42a2e2e896c 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -117,8 +117,9 @@ static void on_handshake_done(void* arg, grpc_error* error) { c->args.interested_parties); c->result->transport = grpc_create_chttp2_transport(args->args, args->endpoint, true); - c->result->socket_node = + grpc_core::RefCountedPtr socket_node = grpc_chttp2_transport_get_socket_node(c->result->transport); + c->result->socket_uuid = socket_node == nullptr ? 0 : socket_node->uuid(); GPR_ASSERT(c->result->transport); // TODO(roth): We ideally want to wait until we receive HTTP/2 // settings from the server before we consider the connection diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 73e43131a0a..9b6574b612d 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -3145,11 +3145,11 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), static const grpc_transport_vtable* get_vtable(void) { return &vtable; } -grpc_core::channelz::SocketNode* grpc_chttp2_transport_get_socket_node( - grpc_transport* transport) { +grpc_core::RefCountedPtr +grpc_chttp2_transport_get_socket_node(grpc_transport* transport) { grpc_chttp2_transport* t = reinterpret_cast(transport); - return t->channelz_socket.get(); + return t->channelz_socket; } grpc_transport* grpc_create_chttp2_transport( diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/src/core/ext/transport/chttp2/transport/chttp2_transport.h index b9929b1662e..c22cfb0ad7d 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.h +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.h @@ -36,8 +36,8 @@ grpc_transport* grpc_create_chttp2_transport( const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client, grpc_resource_user* resource_user = nullptr); -grpc_core::channelz::SocketNode* grpc_chttp2_transport_get_socket_node( - grpc_transport* transport); +grpc_core::RefCountedPtr +grpc_chttp2_transport_get_socket_node(grpc_transport* transport); /// Takes ownership of \a read_buffer, which (if non-NULL) contains /// leftover bytes previously read from the endpoint (e.g., by handshakers). diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 4c63b6bc394..e257caa8f91 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -109,7 +109,7 @@ struct channel_data { uint32_t registered_method_max_probes; grpc_closure finish_destroy_channel_closure; grpc_closure channel_connectivity_changed; - grpc_core::channelz::SocketNode* socket_node; + grpc_core::RefCountedPtr socket_node; }; typedef struct shutdown_tag { @@ -462,6 +462,9 @@ static void finish_destroy_channel(void* cd, grpc_error* error) { channel_data* chand = static_cast(cd); grpc_server* server = chand->server; GRPC_CHANNEL_INTERNAL_UNREF(chand->channel, "server"); + if (chand->socket_node != nullptr) { + chand->socket_node->Unref(); + } server_unref(server); } @@ -1155,11 +1158,11 @@ void grpc_server_get_pollsets(grpc_server* server, grpc_pollset*** pollsets, *pollsets = server->pollsets; } -void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, - grpc_pollset* accepting_pollset, - const grpc_channel_args* args, - grpc_core::channelz::SocketNode* socket_node, - grpc_resource_user* resource_user) { +void grpc_server_setup_transport( + grpc_server* s, grpc_transport* transport, grpc_pollset* accepting_pollset, + const grpc_channel_args* args, + grpc_core::RefCountedPtr socket_node, + grpc_resource_user* resource_user) { size_t num_registered_methods; size_t alloc; registered_method* rm; @@ -1261,9 +1264,8 @@ void grpc_server_populate_server_sockets( gpr_mu_lock(&s->mu_global); channel_data* c = nullptr; for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { - grpc_core::channelz::SocketNode* socket_node = c->socket_node; - if (socket_node && socket_node->uuid() >= start_idx) { - server_sockets->push_back(socket_node); + if (c->socket_node != nullptr && c->socket_node->uuid() >= start_idx) { + server_sockets->push_back(c->socket_node.get()); } } gpr_mu_unlock(&s->mu_global); diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index 8e8903d76b3..393bb242148 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -44,11 +44,11 @@ void grpc_server_add_listener(grpc_server* server, void* listener, /* Setup a transport - creates a channel stack, binds the transport to the server */ -void grpc_server_setup_transport(grpc_server* server, grpc_transport* transport, - grpc_pollset* accepting_pollset, - const grpc_channel_args* args, - grpc_core::channelz::SocketNode* socket_node, - grpc_resource_user* resource_user = nullptr); +void grpc_server_setup_transport( + grpc_server* server, grpc_transport* transport, + grpc_pollset* accepting_pollset, const grpc_channel_args* args, + grpc_core::RefCountedPtr socket_node, + grpc_resource_user* resource_user = nullptr); /* fills in the uuids of all sockets used for connections on this server */ void grpc_server_populate_server_sockets( diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 922783aa0d0..49a0bc80112 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -260,7 +260,7 @@ static void test_channelz(grpc_end2end_test_config config) { gpr_free(json); json = channelz_server->RenderServerSockets(0); - GPR_ASSERT(nullptr != strstr(json, "\"socketRef\":")); + GPR_ASSERT(nullptr != strstr(json, "\"end\":true")); gpr_free(json); end_test(&f); From 92db5fc72488f9d62b81ee311a79832df787f3ef Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Dec 2018 10:29:24 -0800 Subject: [PATCH 0485/2143] Rename getTokenWithHandler --- src/objective-c/GRPCClient/GRPCCall.m | 14 ++++++++++++-- src/objective-c/GRPCClient/GRPCCallOptions.h | 13 ++++++++++++- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 2 +- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 589b52031a7..18f79311a69 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -885,7 +885,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(self) { self.isWaitingForToken = YES; } - [_callOptions.authTokenProvider getTokenWithHandler:^(NSString *token) { + void (^tokenHandler)(NSString *token) = ^(NSString *token) { @synchronized(self) { if (self.isWaitingForToken) { if (token) { @@ -895,7 +895,17 @@ const char *kCFStreamVarName = "grpc_cfstream"; self.isWaitingForToken = NO; } } - }]; + }; + id authTokenProvider = _callOptions.authTokenProvider; + if ([authTokenProvider respondsToSelector:@selector(provideTokenToHandler:)]) { + [_callOptions.authTokenProvider provideTokenToHandler:tokenHandler]; + } else { + NSAssert([authTokenProvider respondsToSelector:@selector(getTokenWithHandler:)], + @"authTokenProvider has no usable method"); + if ([authTokenProvider respondsToSelector:@selector(getTokenWithHandler:)]) { + [_callOptions.authTokenProvider getTokenWithHandler:tokenHandler]; + } + } } else { [self startCallWithWriteable:writeable]; } diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 85786c74174..b7f08480dc0 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -58,13 +58,24 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * Implement this protocol to provide a token to gRPC when a call is initiated. */ -@protocol GRPCAuthorizationProtocol +@protocol GRPCAuthorizationProtocol + +@optional /** * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ +- (void)provideTokenToHandler:(void (^_Nullable)(NSString *_Nullable token))handler; + +/** + * This method is deprecated. Please use \a provideTokenToHandler. + * + * This method is called when gRPC is about to start the call. When OAuth token is acquired, + * \a handler is expected to be called with \a token being the new token to be used for this call. + */ - (void)getTokenWithHandler:(void (^_Nullable)(NSString *_Nullable token))handler; + @end @interface GRPCCallOptions : NSObject diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index da534351780..92d7fce33cc 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -168,7 +168,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)writeMessage:(GPBMessage *)message { - NSAssert([message isKindOfClass:[GPBMessage class]]); + NSAssert([message isKindOfClass:[GPBMessage class]], @"Parameter message must be a GPBMessage"); if (![message isKindOfClass:[GPBMessage class]]) { NSLog(@"Failed to send a message that is non-proto."); return; diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index ca7bf472830..fd472aafebd 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -241,7 +241,7 @@ static const NSTimeInterval kTestTimeout = 16; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } -- (void)getTokenWithHandler:(void (^)(NSString *token))handler { +- (void)provideTokenToHandler:(void (^)(NSString *token))handler { dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); dispatch_sync(queue, ^{ handler(@"test-access-token"); From e95d1185e9c594d9df172a9e5be37dc9720c0e10 Mon Sep 17 00:00:00 2001 From: Jihun Cho Date: Tue, 4 Dec 2018 15:40:34 -0800 Subject: [PATCH 0486/2143] Add grpc-java 1.17.1 to interop matrix --- tools/interop_matrix/client_matrix.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index ff3344cd95d..931beddb9cf 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -207,6 +207,9 @@ LANG_RELEASE_MATRIX = { { 'v1.16.1': None }, + { + 'v1.17.1': None + }, ], 'python': [ { From 83c6640e926b3e623e4a290fd779bc7f70a90129 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 7 Dec 2018 11:03:28 -0800 Subject: [PATCH 0487/2143] Allow the health checking service --- test/cpp/end2end/server_interceptors_end2end_test.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 1e0e3668707..9460a7d6c64 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -52,11 +52,13 @@ class LoggingInterceptor : public experimental::Interceptor { experimental::ServerRpcInfo::Type type = info->type(); // Check that we use one of our standard methods with expected type. + // Also allow the health checking service. // We accept BIDI_STREAMING for Echo in case it's an AsyncGenericService // being tested (the GenericRpc test). // The empty method is for the Unimplemented requests that arise // when draining the CQ. EXPECT_TRUE( + strstr(method, "/grpc.health") == method || (strcmp(method, "/grpc.testing.EchoTestService/Echo") == 0 && (type == experimental::ServerRpcInfo::Type::UNARY || type == experimental::ServerRpcInfo::Type::BIDI_STREAMING)) || From 2e139e35fcaaabff7a21f85fc8e424ae39d0c586 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 30 Nov 2018 23:24:59 +0100 Subject: [PATCH 0488/2143] Bazel 0.20.0 workspace fixes. --- WORKSPACE | 2 ++ bazel/grpc_deps.bzl | 35 +++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index a547c24cbe2..c1e63d86e50 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,6 +1,8 @@ workspace(name="com_github_grpc_grpc") load("//bazel:grpc_deps.bzl", "grpc_deps", "grpc_test_only_deps") +load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") + grpc_deps() grpc_test_only_deps() diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 86268178554..82aada24629 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -1,5 +1,8 @@ """Load dependencies needed to compile and test the grpc library as a 3rd-party consumer.""" +load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + def grpc_deps(): """Loads dependencies need to compile and test the grpc library.""" @@ -99,14 +102,14 @@ def grpc_deps(): ) if "boringssl" not in native.existing_rules(): - native.http_archive( + http_archive( name = "boringssl", # on the chromium-stable-with-bazel branch url = "https://boringssl.googlesource.com/boringssl/+archive/afc30d43eef92979b05776ec0963c9cede5fb80f.tar.gz", ) if "com_github_madler_zlib" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_madler_zlib", build_file = "@com_github_grpc_grpc//third_party:zlib.BUILD", strip_prefix = "zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f", @@ -114,14 +117,14 @@ def grpc_deps(): ) if "com_google_protobuf" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_google_protobuf", strip_prefix = "protobuf-48cb18e5c419ddd23d9badcfe4e9df7bde1979b2", url = "https://github.com/google/protobuf/archive/48cb18e5c419ddd23d9badcfe4e9df7bde1979b2.tar.gz", ) if "com_github_nanopb_nanopb" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_nanopb_nanopb", build_file = "@com_github_grpc_grpc//third_party:nanopb.BUILD", strip_prefix = "nanopb-f8ac463766281625ad710900479130c7fcb4d63b", @@ -129,7 +132,7 @@ def grpc_deps(): ) if "com_github_google_googletest" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_google_googletest", build_file = "@com_github_grpc_grpc//third_party:gtest.BUILD", strip_prefix = "googletest-ec44c6c1675c25b9827aacd08c02433cccde7780", @@ -137,14 +140,14 @@ def grpc_deps(): ) if "com_github_gflags_gflags" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_github_gflags_gflags", strip_prefix = "gflags-30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e", url = "https://github.com/gflags/gflags/archive/30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e.tar.gz", ) if "com_github_google_benchmark" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_google_benchmark", build_file = "@com_github_grpc_grpc//third_party:benchmark.BUILD", strip_prefix = "benchmark-9913418d323e64a0111ca0da81388260c2bbe1e9", @@ -152,7 +155,7 @@ def grpc_deps(): ) if "com_github_cares_cares" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_cares_cares", build_file = "@com_github_grpc_grpc//third_party:cares/cares.BUILD", strip_prefix = "c-ares-3be1924221e1326df520f8498d704a5c4c8d0cce", @@ -160,14 +163,14 @@ def grpc_deps(): ) if "com_google_absl" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_google_absl", strip_prefix = "abseil-cpp-cd95e71df6eaf8f2a282b1da556c2cf1c9b09207", url = "https://github.com/abseil/abseil-cpp/archive/cd95e71df6eaf8f2a282b1da556c2cf1c9b09207.tar.gz", ) if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_github_bazelbuild_bazeltoolchains", strip_prefix = "bazel-toolchains-280edaa6f93623074513d2b426068de42e62ea4d", urls = [ @@ -178,7 +181,7 @@ def grpc_deps(): ) if "io_opencensus_cpp" not in native.existing_rules(): - native.http_archive( + http_archive( name = "io_opencensus_cpp", strip_prefix = "opencensus-cpp-fdf0f308b1631bb4a942e32ba5d22536a6170274", url = "https://github.com/census-instrumentation/opencensus-cpp/archive/fdf0f308b1631bb4a942e32ba5d22536a6170274.tar.gz", @@ -200,7 +203,7 @@ def grpc_test_only_deps(): ) if "com_github_twisted_twisted" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_twisted_twisted", strip_prefix = "twisted-twisted-17.5.0", url = "https://github.com/twisted/twisted/archive/twisted-17.5.0.zip", @@ -208,7 +211,7 @@ def grpc_test_only_deps(): ) if "com_github_yaml_pyyaml" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_yaml_pyyaml", strip_prefix = "pyyaml-3.12", url = "https://github.com/yaml/pyyaml/archive/3.12.zip", @@ -216,7 +219,7 @@ def grpc_test_only_deps(): ) if "com_github_twisted_incremental" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_twisted_incremental", strip_prefix = "incremental-incremental-17.5.0", url = "https://github.com/twisted/incremental/archive/incremental-17.5.0.zip", @@ -224,7 +227,7 @@ def grpc_test_only_deps(): ) if "com_github_zopefoundation_zope_interface" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_zopefoundation_zope_interface", strip_prefix = "zope.interface-4.4.3", url = "https://github.com/zopefoundation/zope.interface/archive/4.4.3.zip", @@ -232,7 +235,7 @@ def grpc_test_only_deps(): ) if "com_github_twisted_constantly" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_twisted_constantly", strip_prefix = "constantly-15.1.0", url = "https://github.com/twisted/constantly/archive/15.1.0.zip", From d3d8a37a6bdfab94690b75af21c4a4c580c25716 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Sat, 1 Dec 2018 00:42:34 +0100 Subject: [PATCH 0489/2143] Fix sanity checker. --- tools/run_tests/sanity/check_bazel_workspace.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/run_tests/sanity/check_bazel_workspace.py b/tools/run_tests/sanity/check_bazel_workspace.py index d562fffc8a9..a34f61208e6 100755 --- a/tools/run_tests/sanity/check_bazel_workspace.py +++ b/tools/run_tests/sanity/check_bazel_workspace.py @@ -110,6 +110,8 @@ bazel_file += '\ngrpc_deps()\n' bazel_file += '\ngrpc_test_only_deps()\n' build_rules = { 'native': eval_state, + 'http_archive': lambda **args: eval_state.http_archive(**args), + 'load': lambda a, b: None, } exec bazel_file in build_rules for name in _GRPC_DEP_NAMES: @@ -149,6 +151,8 @@ for name in _GRPC_DEP_NAMES: names_and_urls_with_overridden_name, overridden_name=name) rules = { 'native': state, + 'http_archive': lambda **args: state.http_archive(**args), + 'load': lambda a, b: None, } exec bazel_file in rules assert name not in names_and_urls_with_overridden_name.keys() From 12192bed323cacc5e59a5fca89da2a1ec66816a5 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 7 Dec 2018 12:01:16 -0800 Subject: [PATCH 0490/2143] reviewer feedback --- src/core/ext/filters/client_channel/connector.h | 3 +-- src/core/lib/surface/server.cc | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/core/ext/filters/client_channel/connector.h b/src/core/ext/filters/client_channel/connector.h index a5ef9bc2555..ea34dcdab57 100644 --- a/src/core/ext/filters/client_channel/connector.h +++ b/src/core/ext/filters/client_channel/connector.h @@ -22,7 +22,6 @@ #include #include "src/core/lib/channel/channel_stack.h" -#include "src/core/lib/channel/channelz.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/transport/transport.h" @@ -49,7 +48,7 @@ typedef struct { /** channel arguments (to be passed to the filters) */ grpc_channel_args* channel_args; - /** socket node of the connected transport. 0 if not availible */ + /** socket uuid of the connected transport. 0 if not available */ intptr_t socket_uuid; } grpc_connect_out_args; diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index e257caa8f91..44e938ad775 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -462,9 +462,7 @@ static void finish_destroy_channel(void* cd, grpc_error* error) { channel_data* chand = static_cast(cd); grpc_server* server = chand->server; GRPC_CHANNEL_INTERNAL_UNREF(chand->channel, "server"); - if (chand->socket_node != nullptr) { - chand->socket_node->Unref(); - } + chand->socket_node.reset(); server_unref(server); } From b5f4b4f1303578415bb7d87c6c6c26918fcf3a59 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 7 Dec 2018 12:09:32 -0800 Subject: [PATCH 0491/2143] Move the unref --- src/core/lib/surface/server.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 44e938ad775..5f7f630d16d 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -462,7 +462,6 @@ static void finish_destroy_channel(void* cd, grpc_error* error) { channel_data* chand = static_cast(cd); grpc_server* server = chand->server; GRPC_CHANNEL_INTERNAL_UNREF(chand->channel, "server"); - chand->socket_node.reset(); server_unref(server); } @@ -951,6 +950,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, static void destroy_channel_elem(grpc_channel_element* elem) { size_t i; channel_data* chand = static_cast(elem->channel_data); + chand->socket_node.reset(); if (chand->registered_methods) { for (i = 0; i < chand->registered_method_slots; i++) { grpc_slice_unref_internal(chand->registered_methods[i].method); From dedff37b4f569e888836b0cf92a9d6de2ddec326 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 7 Dec 2018 12:41:51 -0800 Subject: [PATCH 0492/2143] Allow encoding arbitrary channel args on a per-address basis. --- BUILD | 3 +- CMakeLists.txt | 12 +- Makefile | 12 +- build.yaml | 3 +- config.m4 | 2 +- config.w32 | 2 +- gRPC-C++.podspec | 1 + gRPC-Core.podspec | 4 +- grpc.gemspec | 3 +- grpc.gyp | 8 +- package.xml | 3 +- .../filters/client_channel/client_channel.cc | 16 +- .../ext/filters/client_channel/lb_policy.h | 9 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 240 +++++++---------- .../lb_policy/grpclb/grpclb_channel.h | 2 +- .../lb_policy/grpclb/grpclb_channel_secure.cc | 33 +-- .../lb_policy/grpclb/load_balancer_api.h | 2 +- .../lb_policy/pick_first/pick_first.cc | 19 +- .../lb_policy/round_robin/round_robin.cc | 40 +-- .../lb_policy/subchannel_list.h | 53 ++-- .../client_channel/lb_policy/xds/xds.cc | 247 +++++------------- .../lb_policy/xds/xds_channel.h | 2 +- .../lb_policy/xds/xds_channel_secure.cc | 33 +-- .../lb_policy/xds/xds_load_balancer_api.h | 2 +- .../client_channel/lb_policy_factory.cc | 163 ------------ .../client_channel/lb_policy_factory.h | 86 +----- .../resolver/dns/c_ares/dns_resolver_ares.cc | 12 +- .../dns/c_ares/grpc_ares_ev_driver.cc | 1 + .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 149 +++++------ .../resolver/dns/c_ares/grpc_ares_wrapper.h | 13 +- .../dns/c_ares/grpc_ares_wrapper_fallback.cc | 9 +- .../dns/c_ares/grpc_ares_wrapper_posix.cc | 3 +- .../dns/c_ares/grpc_ares_wrapper_windows.cc | 26 +- .../resolver/dns/native/dns_resolver.cc | 14 +- .../resolver/fake/fake_resolver.cc | 3 +- .../resolver/fake/fake_resolver.h | 3 +- .../resolver/sockaddr/sockaddr_resolver.cc | 34 +-- .../client_channel/resolver_result_parsing.cc | 20 +- .../filters/client_channel/server_address.cc | 103 ++++++++ .../filters/client_channel/server_address.h | 108 ++++++++ .../ext/filters/client_channel/subchannel.cc | 6 +- .../ext/filters/client_channel/subchannel.h | 13 +- src/core/lib/iomgr/sockaddr_utils.cc | 1 + src/python/grpcio/grpc_core_dependencies.py | 2 +- .../dns_resolver_connectivity_test.cc | 12 +- .../resolvers/dns_resolver_cooldown_test.cc | 15 +- .../resolvers/fake_resolver_test.cc | 42 +-- test/core/end2end/fuzzers/api_fuzzer.cc | 28 +- test/core/end2end/goaway_server_test.cc | 29 +- test/core/end2end/no_server_test.cc | 1 + test/core/util/ubsan_suppressions.txt | 3 +- test/cpp/client/client_channel_stress_test.cc | 28 +- test/cpp/end2end/client_lb_end2end_test.cc | 18 +- test/cpp/end2end/grpclb_end2end_test.cc | 37 ++- test/cpp/naming/address_sorting_test.cc | 127 +++++---- test/cpp/naming/resolver_component_test.cc | 21 +- tools/doxygen/Doxyfile.core.internal | 3 +- .../generated/sources_and_headers.json | 4 +- 58 files changed, 845 insertions(+), 1043 deletions(-) delete mode 100644 src/core/ext/filters/client_channel/lb_policy_factory.cc create mode 100644 src/core/ext/filters/client_channel/server_address.cc create mode 100644 src/core/ext/filters/client_channel/server_address.h diff --git a/BUILD b/BUILD index 9e3e594038d..5550e583a87 100644 --- a/BUILD +++ b/BUILD @@ -1048,7 +1048,6 @@ grpc_cc_library( "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_factory.cc", "src/core/ext/filters/client_channel/lb_policy_registry.cc", "src/core/ext/filters/client_channel/parse_address.cc", "src/core/ext/filters/client_channel/proxy_mapper.cc", @@ -1057,6 +1056,7 @@ grpc_cc_library( "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/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", ], @@ -1080,6 +1080,7 @@ grpc_cc_library( "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/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", ], diff --git a/CMakeLists.txt b/CMakeLists.txt index 1194d0072e3..084ddfde0e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1240,7 +1240,6 @@ add_library(grpc 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -1249,6 +1248,7 @@ add_library(grpc 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/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/deadline/deadline_filter.cc @@ -1592,7 +1592,6 @@ add_library(grpc_cronet 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -1601,6 +1600,7 @@ add_library(grpc_cronet 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/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/deadline/deadline_filter.cc @@ -1963,7 +1963,6 @@ add_library(grpc_test_util 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -1972,6 +1971,7 @@ add_library(grpc_test_util 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/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/deadline/deadline_filter.cc @@ -2283,7 +2283,6 @@ add_library(grpc_test_util_unsecure 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -2292,6 +2291,7 @@ add_library(grpc_test_util_unsecure 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/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/deadline/deadline_filter.cc @@ -2617,7 +2617,6 @@ add_library(grpc_unsecure 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -2626,6 +2625,7 @@ add_library(grpc_unsecure 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/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/deadline/deadline_filter.cc @@ -3469,7 +3469,6 @@ add_library(grpc++_cronet 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -3478,6 +3477,7 @@ add_library(grpc++_cronet 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/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/deadline/deadline_filter.cc diff --git a/Makefile b/Makefile index 7dfce79c922..cdddf49d1ee 100644 --- a/Makefile +++ b/Makefile @@ -3735,7 +3735,6 @@ LIBGRPC_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -3744,6 +3743,7 @@ LIBGRPC_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -4081,7 +4081,6 @@ LIBGRPC_CRONET_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -4090,6 +4089,7 @@ LIBGRPC_CRONET_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -4445,7 +4445,6 @@ LIBGRPC_TEST_UTIL_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -4454,6 +4453,7 @@ LIBGRPC_TEST_UTIL_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -4751,7 +4751,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -4760,6 +4759,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -5058,7 +5058,6 @@ LIBGRPC_UNSECURE_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -5067,6 +5066,7 @@ LIBGRPC_UNSECURE_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -5885,7 +5885,6 @@ LIBGRPC++_CRONET_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -5894,6 +5893,7 @@ LIBGRPC++_CRONET_SRC = \ 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/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/deadline/deadline_filter.cc \ diff --git a/build.yaml b/build.yaml index 1e63933f555..4dd08e0425f 100644 --- a/build.yaml +++ b/build.yaml @@ -589,6 +589,7 @@ filegroups: - 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/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: @@ -603,7 +604,6 @@ filegroups: - 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_factory.cc - src/core/ext/filters/client_channel/lb_policy_registry.cc - src/core/ext/filters/client_channel/parse_address.cc - src/core/ext/filters/client_channel/proxy_mapper.cc @@ -612,6 +612,7 @@ filegroups: - 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/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 plugin: grpc_client_channel diff --git a/config.m4 b/config.m4 index 3db660aceea..16de5204bb2 100644 --- a/config.m4 +++ b/config.m4 @@ -348,7 +348,6 @@ if test "$PHP_GRPC" != "no"; then 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -357,6 +356,7 @@ if test "$PHP_GRPC" != "no"; then 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/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/deadline/deadline_filter.cc \ diff --git a/config.w32 b/config.w32 index 7f8b6eee5fa..be10faab9cd 100644 --- a/config.w32 +++ b/config.w32 @@ -323,7 +323,6 @@ if (PHP_GRPC != "no") { "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_factory.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy_registry.cc " + "src\\core\\ext\\filters\\client_channel\\parse_address.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " + @@ -332,6 +331,7 @@ if (PHP_GRPC != "no") { "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\\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\\deadline\\deadline_filter.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index e939bead1b7..30fcb51ee19 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -356,6 +356,7 @@ Pod::Spec.new do |s| '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/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/deadline/deadline_filter.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 1d4e1ae35c0..5ab7a49cd27 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -354,6 +354,7 @@ Pod::Spec.new do |s| '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/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/deadline/deadline_filter.h', @@ -786,7 +787,6 @@ Pod::Spec.new do |s| '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -795,6 +795,7 @@ Pod::Spec.new do |s| '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/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/deadline/deadline_filter.cc', @@ -974,6 +975,7 @@ Pod::Spec.new do |s| '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/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/deadline/deadline_filter.h', diff --git a/grpc.gemspec b/grpc.gemspec index 92b1e0be689..1ee7bec8e7d 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -290,6 +290,7 @@ Gem::Specification.new do |s| 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/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/deadline/deadline_filter.h ) @@ -725,7 +726,6 @@ Gem::Specification.new do |s| 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_factory.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.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 ) @@ -734,6 +734,7 @@ Gem::Specification.new do |s| 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/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/deadline/deadline_filter.cc ) diff --git a/grpc.gyp b/grpc.gyp index 2b841354baf..d435eeadc78 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -540,7 +540,6 @@ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -549,6 +548,7 @@ '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/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/deadline/deadline_filter.cc', @@ -799,7 +799,6 @@ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -808,6 +807,7 @@ '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/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/deadline/deadline_filter.cc', @@ -1039,7 +1039,6 @@ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -1048,6 +1047,7 @@ '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/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/deadline/deadline_filter.cc', @@ -1292,7 +1292,6 @@ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -1301,6 +1300,7 @@ '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/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/deadline/deadline_filter.cc', diff --git a/package.xml b/package.xml index bdcb12bfc5e..68fc7433cb4 100644 --- a/package.xml +++ b/package.xml @@ -295,6 +295,7 @@ + @@ -730,7 +731,6 @@ - @@ -739,6 +739,7 @@ + diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index ebc412b468d..70aac472314 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -38,6 +38,7 @@ #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/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" @@ -62,6 +63,7 @@ #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_metadata.h" +using grpc_core::ServerAddressList; using grpc_core::internal::ClientChannelMethodParams; using grpc_core::internal::ClientChannelMethodParamsTable; using grpc_core::internal::ProcessedResolverResult; @@ -383,16 +385,10 @@ static void create_new_lb_policy_locked( static void maybe_add_trace_message_for_address_changes_locked( channel_data* chand, TraceStringVector* trace_strings) { - int resolution_contains_addresses = false; - const grpc_arg* channel_arg = - grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES); - if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) { - grpc_lb_addresses* addresses = - static_cast(channel_arg->value.pointer.p); - if (addresses->num_addresses > 0) { - resolution_contains_addresses = true; - } - } + const ServerAddressList* addresses = + grpc_core::FindServerAddressListChannelArg(chand->resolver_result); + const bool resolution_contains_addresses = + addresses != nullptr && addresses->size() > 0; if (!resolution_contains_addresses && chand->previous_resolution_contained_addresses) { trace_strings->push_back(gpr_strdup("Address list became empty")); diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 7034da6249c..6b76fe5d5d7 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 { grpc_client_channel_factory* client_channel_factory = nullptr; /// Channel args from the resolver. /// Note that the LB policy gets the set of addresses from the - /// GRPC_ARG_LB_ADDRESSES channel arg. + /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. grpc_channel_args* args = nullptr; /// Load balancing config from the resolver. grpc_json* lb_config = nullptr; @@ -80,11 +80,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Will be populated with context to pass to the subchannel call, if /// needed. grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {}; - /// Upon success, \a *user_data will be set to whatever opaque information - /// may need to be propagated from the LB policy, or nullptr if not needed. - // TODO(roth): As part of revamping our metadata APIs, try to find a - // way to clean this up and C++-ify it. - void** user_data = nullptr; /// Next pointer. For internal use by LB policy. PickState* next = nullptr; }; @@ -95,7 +90,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// 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 - /// GRPC_ARG_LB_ADDRESSES channel arg. + /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. virtual void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) GRPC_ABSTRACT; 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 a46579c7f74..a9a5965ed1c 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 @@ -84,6 +84,7 @@ #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" @@ -113,6 +114,8 @@ #define GRPC_GRPCLB_RECONNECT_JITTER 0.2 #define GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS 10000 +#define GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN "grpc.grpclb_address_lb_token" + namespace grpc_core { TraceFlag grpc_lb_glb_trace(false, "glb"); @@ -121,7 +124,7 @@ namespace { class GrpcLb : public LoadBalancingPolicy { public: - GrpcLb(const grpc_lb_addresses* addresses, const Args& args); + explicit GrpcLb(const Args& args); void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; @@ -161,9 +164,6 @@ class GrpcLb : public LoadBalancingPolicy { // Our on_complete closure and the original one. grpc_closure on_complete; grpc_closure* original_on_complete; - // The LB token associated with the pick. This is set via user_data in - // the pick. - grpc_mdelem lb_token; // Stats for client-side load reporting. RefCountedPtr client_stats; // Next pending pick. @@ -329,7 +329,7 @@ class GrpcLb : public LoadBalancingPolicy { // 0 means not using fallback. int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. - grpc_lb_addresses* fallback_backend_addresses_ = nullptr; + UniquePtr fallback_backend_addresses_; // Fallback timer. bool fallback_timer_callback_pending_ = false; grpc_timer lb_fallback_timer_; @@ -349,7 +349,7 @@ class GrpcLb : public LoadBalancingPolicy { // serverlist parsing code // -// vtable for LB tokens in grpc_lb_addresses +// vtable for LB token channel arg. void* lb_token_copy(void* token) { return token == nullptr ? nullptr @@ -361,38 +361,11 @@ void lb_token_destroy(void* token) { } } int lb_token_cmp(void* token1, void* token2) { - if (token1 > token2) return 1; - if (token1 < token2) return -1; - return 0; + return GPR_ICMP(token1, token2); } -const grpc_lb_user_data_vtable lb_token_vtable = { +const grpc_arg_pointer_vtable lb_token_arg_vtable = { lb_token_copy, lb_token_destroy, lb_token_cmp}; -// Returns the backend addresses extracted from the given addresses. -grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) { - // First pass: count the number of backend addresses. - size_t num_backends = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) { - ++num_backends; - } - } - // Second pass: actually populate the addresses and (empty) LB tokens. - grpc_lb_addresses* backend_addresses = - grpc_lb_addresses_create(num_backends, &lb_token_vtable); - size_t num_copied = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) continue; - const grpc_resolved_address* addr = &addresses->addresses[i].address; - grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr, - addr->len, false /* is_balancer */, - nullptr /* balancer_name */, - (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload); - ++num_copied; - } - return backend_addresses; -} - bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) { if (server->drop) return false; const grpc_grpclb_ip_address* ip = &server->ip_address; @@ -440,30 +413,16 @@ void ParseServer(const grpc_grpclb_server* server, } // Returns addresses extracted from \a serverlist. -grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { - size_t num_valid = 0; - /* first pass: count how many are valid in order to allocate the necessary - * memory in a single block */ +ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { + ServerAddressList addresses; for (size_t i = 0; i < serverlist->num_servers; ++i) { - if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid; - } - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_valid, &lb_token_vtable); - /* second pass: actually populate the addresses and LB tokens (aka user data - * to the outside world) to be read by the RR policy during its creation. - * Given that the validity tests are very cheap, they are performed again - * instead of marking the valid ones during the first pass, as this would - * incurr in an allocation due to the arbitrary number of server */ - size_t addr_idx = 0; - for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) { - const grpc_grpclb_server* server = serverlist->servers[sl_idx]; - if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue; - GPR_ASSERT(addr_idx < num_valid); - /* address processing */ + 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); - /* lb token processing */ - void* user_data; + // LB token processing. + void* lb_token; if (server->has_load_balance_token) { const size_t lb_token_max_length = GPR_ARRAY_SIZE(server->load_balance_token); @@ -471,7 +430,7 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { strnlen(server->load_balance_token, lb_token_max_length); grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer( server->load_balance_token, lb_token_length); - user_data = + lb_token = (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr) .payload; } else { @@ -481,15 +440,16 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { "be used instead", uri); gpr_free(uri); - user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; + lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; } - grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len, - false /* is_balancer */, - nullptr /* balancer_name */, user_data); - ++addr_idx; + // Add address. + grpc_arg arg = grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token, + &lb_token_arg_vtable); + grpc_channel_args* args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + addresses.emplace_back(addr, args); } - GPR_ASSERT(addr_idx == num_valid); - return lb_addresses; + return addresses; } // @@ -829,8 +789,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_); } else { // Dispose of the fallback. - grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_); - grpclb_policy->fallback_backend_addresses_ = nullptr; + grpclb_policy->fallback_backend_addresses_.reset(); if (grpclb_policy->fallback_timer_callback_pending_) { grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_); } @@ -910,31 +869,25 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( // helper code for creating balancer channel // -grpc_lb_addresses* ExtractBalancerAddresses( - const grpc_lb_addresses* addresses) { - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - // There must be at least one balancer address, or else the - // client_channel would not have chosen this LB policy. - GPR_ASSERT(num_grpclb_addrs > 0); - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_grpclb_addrs, nullptr); - size_t lb_addresses_idx = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) continue; - if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) { - gpr_log(GPR_ERROR, - "This LB policy doesn't support user data. It will be ignored"); +ServerAddressList ExtractBalancerAddresses(const ServerAddressList& addresses) { + ServerAddressList balancer_addresses; + for (size_t i = 0; i < addresses.size(); ++i) { + if (addresses[i].IsBalancer()) { + // Strip out the is_balancer channel arg, since we don't want to + // recursively use the grpclb policy in the channel used to talk to + // the balancers. Note that we do NOT strip out the balancer_name + // channel arg, since we need that to set the authority correctly + // to talk to the balancers. + static const char* args_to_remove[] = { + GRPC_ARG_ADDRESS_IS_BALANCER, + }; + balancer_addresses.emplace_back( + addresses[i].address(), + grpc_channel_args_copy_and_remove(addresses[i].args(), args_to_remove, + GPR_ARRAY_SIZE(args_to_remove))); } - grpc_lb_addresses_set_address( - lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr, - addresses->addresses[i].address.len, false /* is balancer */, - addresses->addresses[i].balancer_name, nullptr /* user data */); } - GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx); - return lb_addresses; + return balancer_addresses; } /* Returns the channel args for the LB channel, used to create a bidirectional @@ -946,10 +899,10 @@ grpc_lb_addresses* ExtractBalancerAddresses( * above the grpclb policy. * - \a args: other args inherited from the grpclb policy. */ grpc_channel_args* BuildBalancerChannelArgs( - const grpc_lb_addresses* addresses, + const ServerAddressList& addresses, FakeResolverResponseGenerator* response_generator, const grpc_channel_args* args) { - grpc_lb_addresses* lb_addresses = ExtractBalancerAddresses(addresses); + 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 @@ -967,7 +920,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // 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. - GRPC_ARG_LB_ADDRESSES, + 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. @@ -983,10 +936,10 @@ grpc_channel_args* BuildBalancerChannelArgs( }; // Channel args to add. const grpc_arg args_to_add[] = { - // New LB addresses. + // 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. - grpc_lb_addresses_create_channel_arg(lb_addresses), + CreateServerAddressListChannelArg(&balancer_addresses), // The fake resolver response generator, which we use to inject // address updates into the LB channel. grpc_core::FakeResolverResponseGenerator::MakeChannelArg( @@ -1004,18 +957,14 @@ 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. - new_args = grpc_lb_policy_grpclb_modify_lb_channel_args(new_args); - // Clean up. - grpc_lb_addresses_destroy(lb_addresses); - return new_args; + return grpc_lb_policy_grpclb_modify_lb_channel_args(new_args); } // // ctor and dtor // -GrpcLb::GrpcLb(const grpc_lb_addresses* addresses, - const LoadBalancingPolicy::Args& args) +GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args) : LoadBalancingPolicy(args), response_generator_(MakeRefCounted()), lb_call_backoff_( @@ -1072,9 +1021,6 @@ GrpcLb::~GrpcLb() { if (serverlist_ != nullptr) { grpc_grpclb_destroy_serverlist(serverlist_); } - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } grpc_subchannel_index_unref(); } @@ -1122,7 +1068,6 @@ void GrpcLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { while ((pp = pending_picks_) != nullptr) { pending_picks_ = pp->next; pp->pick->on_complete = pp->original_on_complete; - pp->pick->user_data = nullptr; grpc_error* error = GRPC_ERROR_NONE; if (new_policy->PickLocked(pp->pick, &error)) { // Synchronous return; schedule closure. @@ -1276,9 +1221,27 @@ void GrpcLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, notify); } +// Returns the backend addresses extracted from the given addresses. +UniquePtr 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(); + for (size_t i = 0; i < addresses.size(); ++i) { + if (!addresses[i].IsBalancer()) { + backend_addresses->emplace_back( + addresses[i].address(), + grpc_channel_args_copy_and_add(addresses[i].args(), &arg, 1)); + } + } + return backend_addresses; +} + void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { + const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); + if (addresses == nullptr) { // Ignore this update. gpr_log( GPR_ERROR, @@ -1286,13 +1249,8 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { this); return; } - const grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); // Update fallback address list. - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } - 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}; @@ -1303,7 +1261,7 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { &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); + BuildBalancerChannelArgs(*addresses, response_generator_.get(), &args); // Create balancer channel if needed. if (lb_channel_ == nullptr) { char* uri_str; @@ -1509,12 +1467,17 @@ void DestroyClientStats(void* arg) { } 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 - * user_data/token available */ + // 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) { - if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) { - AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token), + 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 { @@ -1598,12 +1561,10 @@ bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, return true; } } - // Set client_stats and user_data. + // Set client_stats. if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { pp->client_stats = lb_calld_->client_stats()->Ref(); } - GPR_ASSERT(pp->pick->user_data == nullptr); - pp->pick->user_data = (void**)&pp->lb_token; // Pick via the RR policy. bool pick_done = rr_policy_->PickLocked(pp->pick, error); if (pick_done) { @@ -1668,10 +1629,11 @@ void GrpcLb::CreateRoundRobinPolicyLocked(const Args& args) { } grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { - grpc_lb_addresses* addresses; + ServerAddressList tmp_addresses; + ServerAddressList* addresses = &tmp_addresses; bool is_backend_from_grpclb_load_balancer = false; if (serverlist_ != nullptr) { - addresses = ProcessServerlist(serverlist_); + tmp_addresses = ProcessServerlist(serverlist_); is_backend_from_grpclb_load_balancer = true; } else { // If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't @@ -1680,14 +1642,14 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { // empty, in which case the new round_robin policy will keep the requested // picks pending. GPR_ASSERT(fallback_backend_addresses_ != nullptr); - addresses = grpc_lb_addresses_copy(fallback_backend_addresses_); + addresses = fallback_backend_addresses_.get(); } GPR_ASSERT(addresses != nullptr); - // Replace the LB addresses in the channel args that we pass down to + // Replace the server address list in the channel args that we pass down to // the subchannel. - static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES}; + static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST}; grpc_arg args_to_add[3] = { - grpc_lb_addresses_create_channel_arg(addresses), + CreateServerAddressListChannelArg(addresses), // A channel arg indicating if the target is a backend inferred from a // grpclb load balancer. grpc_channel_arg_integer_create( @@ -1704,7 +1666,6 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { 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); - grpc_lb_addresses_destroy(addresses); return args; } @@ -1837,19 +1798,18 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { OrphanablePtr CreateLoadBalancingPolicy( const LoadBalancingPolicy::Args& args) const override { /* Count the number of gRPC-LB addresses. There must be at least one. */ - const grpc_arg* arg = - grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES); - if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { - return nullptr; + 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; + } } - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - if (num_grpclb_addrs == 0) return nullptr; - return OrphanablePtr(New(addresses, args)); + if (!found_balancer) return nullptr; + return OrphanablePtr(New(args)); } const char* name() const override { return "grpclb"; } 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 825065a9c32..3b2dc370eb3 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 @@ -21,7 +21,7 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include /// Makes any necessary modifications to \a args for use in the grpclb /// balancer channel. 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 441efd5e23b..6e8fbdcab77 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 @@ -26,6 +26,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -42,22 +43,23 @@ int BalancerNameCmp(const grpc_core::UniquePtr& a, } RefCountedPtr CreateTargetAuthorityTable( - grpc_lb_addresses* addresses) { + const ServerAddressList& addresses) { TargetAuthorityTable::Entry* target_authority_entries = - static_cast(gpr_zalloc( - sizeof(*target_authority_entries) * addresses->num_addresses)); - for (size_t i = 0; i < addresses->num_addresses; ++i) { + 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->addresses[i].address, true) > 0); + 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); - target_authority_entries[i].value.reset( - gpr_strdup(addresses->addresses[i].balancer_name)); 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->num_addresses, - target_authority_entries, BalancerNameCmp); + TargetAuthorityTable::Create(addresses.size(), target_authority_entries, + BalancerNameCmp); gpr_free(target_authority_entries); return target_authority_table; } @@ -72,13 +74,12 @@ grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args( grpc_arg args_to_add[2]; size_t num_args_to_add = 0; // Add arg for targets info table. - const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES); - GPR_ASSERT(arg != nullptr); - GPR_ASSERT(arg->type == GRPC_ARG_POINTER); - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); + 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/grpclb/load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h index 9ca7b28d8e6..71d371c880a 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 @@ -25,7 +25,7 @@ #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/lib/iomgr/exec_ctx.h" #define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128 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 d1a05f12554..74c17612a28 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 @@ -24,6 +24,7 @@ #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/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" @@ -75,11 +76,9 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner) - : SubchannelData(subchannel_list, user_data_vtable, address, subchannel, - combiner) {} + : SubchannelData(subchannel_list, address, subchannel, combiner) {} void ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state, grpc_error* error) override; @@ -95,7 +94,7 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData> { public: PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, + const ServerAddressList& addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) @@ -337,8 +336,8 @@ void PickFirst::UpdateChildRefsLocked() { void PickFirst::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { AutoChildRefsUpdater guard(this); - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { + 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_connectivity_state_set( @@ -354,19 +353,17 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, } return; } - const grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p received update with %" PRIuPTR " addresses", this, - addresses->num_addresses); + 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); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, addresses, combiner(), + 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) { 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 2a169751317..63089afbd78 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 @@ -82,8 +82,6 @@ class RoundRobin : public LoadBalancingPolicy { // Data for a particular subchannel in a subchannel list. // This subclass adds the following functionality: - // - Tracks user_data associated with each address, which will be - // returned along with picks that select the subchannel. // - Tracks the previous connectivity state of the subchannel, so that // we know how many subchannels are in each state. class RoundRobinSubchannelData @@ -93,26 +91,9 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner) - : SubchannelData(subchannel_list, user_data_vtable, address, subchannel, - combiner), - user_data_vtable_(user_data_vtable), - user_data_(user_data_vtable_ != nullptr - ? user_data_vtable_->copy(address.user_data) - : nullptr) {} - - void UnrefSubchannelLocked(const char* reason) override { - SubchannelData::UnrefSubchannelLocked(reason); - if (user_data_ != nullptr) { - GPR_ASSERT(user_data_vtable_ != nullptr); - user_data_vtable_->destroy(user_data_); - user_data_ = nullptr; - } - } - - void* user_data() const { return user_data_; } + : SubchannelData(subchannel_list, address, subchannel, combiner) {} grpc_connectivity_state connectivity_state() const { return last_connectivity_state_; @@ -125,8 +106,6 @@ class RoundRobin : public LoadBalancingPolicy { void ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state, grpc_error* error) override; - const grpc_lb_user_data_vtable* user_data_vtable_; - void* user_data_ = nullptr; grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE; }; @@ -137,7 +116,7 @@ class RoundRobin : public LoadBalancingPolicy { public: RoundRobinSubchannelList( RoundRobin* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, grpc_combiner* combiner, + const ServerAddressList& addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, @@ -354,9 +333,6 @@ bool RoundRobin::DoPickLocked(PickState* pick) { subchannel_list_->subchannel(next_ready_index); GPR_ASSERT(sd->connected_subchannel() != nullptr); pick->connected_subchannel = sd->connected_subchannel()->Ref(); - if (pick->user_data != nullptr) { - *pick->user_data = sd->user_data(); - } if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, " @@ -667,9 +643,9 @@ void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current, void RoundRobin::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); AutoChildRefsUpdater guard(this); - if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { + 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). @@ -681,11 +657,9 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, } return; } - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses", - this, addresses->num_addresses); + this, addresses->size()); } // Replace latest_pending_subchannel_list_. if (latest_pending_subchannel_list_ != nullptr) { @@ -696,7 +670,7 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, addresses, combiner(), + 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. 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 f31401502c3..6f31a643c1d 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 @@ -26,6 +26,7 @@ #include #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/lib/channel/channel_args.h" #include "src/core/lib/debug/trace.h" @@ -141,8 +142,7 @@ class SubchannelData { protected: SubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner); virtual ~SubchannelData(); @@ -156,9 +156,8 @@ class SubchannelData { grpc_connectivity_state connectivity_state, grpc_error* error) GRPC_ABSTRACT; - // Unrefs the subchannel. May be overridden by subclasses that need - // to perform extra cleanup when unreffing the subchannel. - virtual void UnrefSubchannelLocked(const char* reason); + // Unrefs the subchannel. + void UnrefSubchannelLocked(const char* reason); private: // Updates connected_subchannel_ based on pending_connectivity_state_unsafe_. @@ -232,7 +231,7 @@ class SubchannelList : public InternallyRefCounted { protected: SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, grpc_combiner* combiner, + const ServerAddressList& addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args); @@ -277,8 +276,7 @@ class SubchannelList : public InternallyRefCounted { template SubchannelData::SubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner) : subchannel_list_(subchannel_list), subchannel_(subchannel), @@ -488,7 +486,7 @@ void SubchannelData::ShutdownLocked() { template SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, grpc_combiner* combiner, + const ServerAddressList& addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) : InternallyRefCounted(tracer), @@ -498,9 +496,9 @@ SubchannelList::SubchannelList( if (tracer_->enabled()) { gpr_log(GPR_INFO, "[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels", - tracer_->name(), policy, this, addresses->num_addresses); + tracer_->name(), policy, this, addresses.size()); } - subchannels_.reserve(addresses->num_addresses); + subchannels_.reserve(addresses.size()); // We need to remove the LB addresses in order to be able to compare the // subchannel keys of subchannels from a different batch of addresses. // We also remove the inhibit-health-checking arg, since we are @@ -508,19 +506,27 @@ 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_LB_ADDRESSES, + GRPC_ARG_SERVER_ADDRESS_LIST, GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. grpc_subchannel_args sc_args; - for (size_t i = 0; i < addresses->num_addresses; i++) { - // If there were any balancer, we would have chosen grpclb policy instead. - GPR_ASSERT(!addresses->addresses[i].is_balancer); + 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()); memset(&sc_args, 0, sizeof(grpc_subchannel_args)); - grpc_arg addr_arg = - grpc_create_subchannel_address_arg(&addresses->addresses[i].address); + InlinedVector args_to_add; + args_to_add.emplace_back( + 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]); + } + } 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); + &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); sc_args.args = new_args; grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel( client_channel_factory, &sc_args); @@ -528,8 +534,7 @@ SubchannelList::SubchannelList( if (subchannel == nullptr) { // Subchannel could not be created. if (tracer_->enabled()) { - char* address_uri = - grpc_sockaddr_to_uri(&addresses->addresses[i].address); + char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address()); gpr_log(GPR_INFO, "[%s %p] could not create subchannel for address uri %s, " "ignoring", @@ -539,8 +544,7 @@ SubchannelList::SubchannelList( continue; } if (tracer_->enabled()) { - char* address_uri = - grpc_sockaddr_to_uri(&addresses->addresses[i].address); + char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address()); gpr_log(GPR_INFO, "[%s %p] subchannel list %p index %" PRIuPTR ": Created subchannel %p for address uri %s", @@ -548,8 +552,7 @@ SubchannelList::SubchannelList( address_uri); gpr_free(address_uri); } - subchannels_.emplace_back(this, addresses->user_data_vtable, - addresses->addresses[i], subchannel, combiner); + subchannels_.emplace_back(this, addresses[i], subchannel, 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 faedc0a9194..3c25de2386c 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 @@ -79,6 +79,7 @@ #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" @@ -116,7 +117,7 @@ namespace { class XdsLb : public LoadBalancingPolicy { public: - XdsLb(const grpc_lb_addresses* addresses, const Args& args); + explicit XdsLb(const Args& args); void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; @@ -156,9 +157,6 @@ class XdsLb : public LoadBalancingPolicy { // Our on_complete closure and the original one. grpc_closure on_complete; grpc_closure* original_on_complete; - // The LB token associated with the pick. This is set via user_data in - // the pick. - grpc_mdelem lb_token; // Stats for client-side load reporting. RefCountedPtr client_stats; // Next pending pick. @@ -256,7 +254,7 @@ class XdsLb : public LoadBalancingPolicy { grpc_error* error); // Pending pick methods. - static void PendingPickSetMetadataAndContext(PendingPick* pp); + static void PendingPickCleanup(PendingPick* pp); PendingPick* PendingPickCreate(PickState* pick); void AddPendingPick(PendingPick* pp); static void OnPendingPickComplete(void* arg, grpc_error* error); @@ -319,7 +317,7 @@ class XdsLb : public LoadBalancingPolicy { // 0 means not using fallback. int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. - grpc_lb_addresses* fallback_backend_addresses_ = nullptr; + UniquePtr fallback_backend_addresses_; // Fallback timer. bool fallback_timer_callback_pending_ = false; grpc_timer lb_fallback_timer_; @@ -339,47 +337,15 @@ class XdsLb : public LoadBalancingPolicy { // serverlist parsing code // -// vtable for LB tokens in grpc_lb_addresses -void* lb_token_copy(void* token) { - return token == nullptr - ? nullptr - : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload; -} -void lb_token_destroy(void* token) { - if (token != nullptr) { - GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token}); - } -} -int lb_token_cmp(void* token1, void* token2) { - if (token1 > token2) return 1; - if (token1 < token2) return -1; - return 0; -} -const grpc_lb_user_data_vtable lb_token_vtable = { - lb_token_copy, lb_token_destroy, lb_token_cmp}; - // Returns the backend addresses extracted from the given addresses. -grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) { - // First pass: count the number of backend addresses. - size_t num_backends = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) { - ++num_backends; +UniquePtr ExtractBackendAddresses( + const ServerAddressList& addresses) { + auto backend_addresses = MakeUnique(); + for (size_t i = 0; i < addresses.size(); ++i) { + if (!addresses[i].IsBalancer()) { + backend_addresses->emplace_back(addresses[i]); } } - // Second pass: actually populate the addresses and (empty) LB tokens. - grpc_lb_addresses* backend_addresses = - grpc_lb_addresses_create(num_backends, &lb_token_vtable); - size_t num_copied = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) continue; - const grpc_resolved_address* addr = &addresses->addresses[i].address; - grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr, - addr->len, false /* is_balancer */, - nullptr /* balancer_name */, - (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload); - ++num_copied; - } return backend_addresses; } @@ -429,56 +395,17 @@ void ParseServer(const xds_grpclb_server* server, grpc_resolved_address* addr) { } // Returns addresses extracted from \a serverlist. -grpc_lb_addresses* ProcessServerlist(const xds_grpclb_serverlist* serverlist) { - size_t num_valid = 0; - /* first pass: count how many are valid in order to allocate the necessary - * memory in a single block */ +UniquePtr ProcessServerlist( + const xds_grpclb_serverlist* serverlist) { + auto addresses = MakeUnique(); for (size_t i = 0; i < serverlist->num_servers; ++i) { - if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid; - } - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_valid, &lb_token_vtable); - /* second pass: actually populate the addresses and LB tokens (aka user data - * to the outside world) to be read by the child policy during its creation. - * Given that the validity tests are very cheap, they are performed again - * instead of marking the valid ones during the first pass, as this would - * incurr in an allocation due to the arbitrary number of server */ - size_t addr_idx = 0; - for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) { - const xds_grpclb_server* server = serverlist->servers[sl_idx]; - if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue; - GPR_ASSERT(addr_idx < num_valid); - /* address processing */ + const xds_grpclb_server* server = serverlist->servers[i]; + if (!IsServerValid(serverlist->servers[i], i, false)) continue; grpc_resolved_address addr; ParseServer(server, &addr); - /* lb token processing */ - void* user_data; - if (server->has_load_balance_token) { - const size_t lb_token_max_length = - GPR_ARRAY_SIZE(server->load_balance_token); - const size_t lb_token_length = - strnlen(server->load_balance_token, lb_token_max_length); - grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer( - server->load_balance_token, lb_token_length); - user_data = - (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr) - .payload; - } else { - char* uri = grpc_sockaddr_to_uri(&addr); - gpr_log(GPR_INFO, - "Missing LB token for backend address '%s'. The empty token will " - "be used instead", - uri); - gpr_free(uri); - user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; - } - grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len, - false /* is_balancer */, - nullptr /* balancer_name */, user_data); - ++addr_idx; + addresses->emplace_back(addr, nullptr); } - GPR_ASSERT(addr_idx == num_valid); - return lb_addresses; + return addresses; } // @@ -789,8 +716,7 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( xds_grpclb_destroy_serverlist(xdslb_policy->serverlist_); } else { /* or dispose of the fallback */ - grpc_lb_addresses_destroy(xdslb_policy->fallback_backend_addresses_); - xdslb_policy->fallback_backend_addresses_ = nullptr; + xdslb_policy->fallback_backend_addresses_.reset(); if (xdslb_policy->fallback_timer_callback_pending_) { grpc_timer_cancel(&xdslb_policy->lb_fallback_timer_); } @@ -876,31 +802,15 @@ void XdsLb::BalancerCallState::OnBalancerStatusReceivedLocked( // helper code for creating balancer channel // -grpc_lb_addresses* ExtractBalancerAddresses( - const grpc_lb_addresses* addresses) { - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - // There must be at least one balancer address, or else the - // client_channel would not have chosen this LB policy. - GPR_ASSERT(num_grpclb_addrs > 0); - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_grpclb_addrs, nullptr); - size_t lb_addresses_idx = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) continue; - if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) { - gpr_log(GPR_ERROR, - "This LB policy doesn't support user data. It will be ignored"); +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]); } - grpc_lb_addresses_set_address( - lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr, - addresses->addresses[i].address.len, false /* is balancer */, - addresses->addresses[i].balancer_name, nullptr /* user data */); } - GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx); - return lb_addresses; + return balancer_addresses; } /* Returns the channel args for the LB channel, used to create a bidirectional @@ -912,10 +822,11 @@ grpc_lb_addresses* ExtractBalancerAddresses( * above the grpclb policy. * - \a args: other args inherited from the xds policy. */ grpc_channel_args* BuildBalancerChannelArgs( - const grpc_lb_addresses* addresses, + const ServerAddressList& addresses, FakeResolverResponseGenerator* response_generator, const grpc_channel_args* args) { - grpc_lb_addresses* lb_addresses = ExtractBalancerAddresses(addresses); + UniquePtr 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 @@ -933,7 +844,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // 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. - GRPC_ARG_LB_ADDRESSES, + 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. @@ -949,10 +860,10 @@ grpc_channel_args* BuildBalancerChannelArgs( }; // Channel args to add. const grpc_arg args_to_add[] = { - // New LB addresses. + // 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. - grpc_lb_addresses_create_channel_arg(lb_addresses), + CreateServerAddressListChannelArg(balancer_addresses.get()), // The fake resolver response generator, which we use to inject // address updates into the LB channel. grpc_core::FakeResolverResponseGenerator::MakeChannelArg( @@ -970,10 +881,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. - new_args = grpc_lb_policy_xds_modify_lb_channel_args(new_args); - // Clean up. - grpc_lb_addresses_destroy(lb_addresses); - return new_args; + return grpc_lb_policy_xds_modify_lb_channel_args(new_args); } // @@ -981,8 +889,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // // TODO(vishalpowar): Use lb_config in args to configure LB policy. -XdsLb::XdsLb(const grpc_lb_addresses* addresses, - const LoadBalancingPolicy::Args& args) +XdsLb::XdsLb(const LoadBalancingPolicy::Args& args) : LoadBalancingPolicy(args), response_generator_(MakeRefCounted()), lb_call_backoff_( @@ -1038,9 +945,6 @@ XdsLb::~XdsLb() { if (serverlist_ != nullptr) { xds_grpclb_destroy_serverlist(serverlist_); } - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } grpc_subchannel_index_unref(); } @@ -1088,7 +992,6 @@ void XdsLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { while ((pp = pending_picks_) != nullptr) { pending_picks_ = pp->next; pp->pick->on_complete = pp->original_on_complete; - pp->pick->user_data = nullptr; grpc_error* error = GRPC_ERROR_NONE; if (new_policy->PickLocked(pp->pick, &error)) { // Synchronous return; schedule closure. @@ -1241,21 +1144,16 @@ void XdsLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, } void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { + 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; } - const grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); // Update fallback address list. - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } - 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}; @@ -1266,7 +1164,7 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { &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); + BuildBalancerChannelArgs(*addresses, response_generator_.get(), &args); // Create balancer channel if needed. if (lb_channel_ == nullptr) { char* uri_str; @@ -1457,37 +1355,15 @@ void XdsLb::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 XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) { - /* if connected_subchannel is nullptr, no pick has been made by the - * child policy (e.g., all addresses failed to connect). There won't be any - * user_data/token available */ +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) { - if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) { - AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token), - &pp->pick->lb_token_mdelem_storage, - pp->pick->initial_metadata); - } else { - gpr_log(GPR_ERROR, - "[xdslb %p] No LB token for connected subchannel pick %p", - pp->xdslb_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 = @@ -1505,7 +1381,7 @@ void XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) { * order to unref the child policy instance upon its invocation */ void XdsLb::OnPendingPickComplete(void* arg, grpc_error* error) { PendingPick* pp = static_cast(arg); - PendingPickSetMetadataAndContext(pp); + PendingPickCleanup(pp); GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error)); Delete(pp); } @@ -1537,16 +1413,14 @@ void XdsLb::AddPendingPick(PendingPick* pp) { // completion callback even if the pick is available immediately. bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp, grpc_error** error) { - // Set client_stats and user_data. + // Set client_stats. if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { pp->client_stats = lb_calld_->client_stats()->Ref(); } - GPR_ASSERT(pp->pick->user_data == nullptr); - pp->pick->user_data = (void**)&pp->lb_token; // Pick via the child policy. bool pick_done = child_policy_->PickLocked(pp->pick, error); if (pick_done) { - PendingPickSetMetadataAndContext(pp); + PendingPickCleanup(pp); if (force_async) { GRPC_CLOSURE_SCHED(pp->original_on_complete, *error); *error = GRPC_ERROR_NONE; @@ -1608,20 +1482,19 @@ void XdsLb::CreateChildPolicyLocked(const Args& args) { } grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { - grpc_lb_addresses* addresses; 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); - addresses = ProcessServerlist(serverlist_); - is_backend_from_grpclb_load_balancer = true; + UniquePtr addresses = ProcessServerlist(serverlist_); GPR_ASSERT(addresses != nullptr); - // Replace the LB addresses in the channel args that we pass down to + 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_LB_ADDRESSES}; + static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST}; const grpc_arg args_to_add[] = { - grpc_lb_addresses_create_channel_arg(addresses), + CreateServerAddressListChannelArg(addresses.get()), // A channel arg indicating if the target is a backend inferred from a // grpclb load balancer. grpc_channel_arg_integer_create( @@ -1631,7 +1504,6 @@ grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { 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)); - grpc_lb_addresses_destroy(addresses); return args; } @@ -1765,19 +1637,18 @@ class XdsFactory : public LoadBalancingPolicyFactory { OrphanablePtr CreateLoadBalancingPolicy( const LoadBalancingPolicy::Args& args) const override { /* Count the number of gRPC-LB addresses. There must be at least one. */ - const grpc_arg* arg = - grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES); - if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { - return nullptr; + 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; + } } - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - if (num_grpclb_addrs == 0) return nullptr; - return OrphanablePtr(New(addresses, args)); + if (!found_balancer_address) return nullptr; + return OrphanablePtr(New(args)); } const char* name() const override { return "xds_experimental"; } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h index 32c4acc8a3e..f713b7f563d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h @@ -21,7 +21,7 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include /// Makes any necessary modifications to \a args for use in the xds /// balancer channel. 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 5ab72efce46..9a11f8e39fd 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 @@ -25,6 +25,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -41,22 +42,23 @@ int BalancerNameCmp(const grpc_core::UniquePtr& a, } RefCountedPtr CreateTargetAuthorityTable( - grpc_lb_addresses* addresses) { + const ServerAddressList& addresses) { TargetAuthorityTable::Entry* target_authority_entries = - static_cast(gpr_zalloc( - sizeof(*target_authority_entries) * addresses->num_addresses)); - for (size_t i = 0; i < addresses->num_addresses; ++i) { + 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->addresses[i].address, true) > 0); + 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); - target_authority_entries[i].value.reset( - gpr_strdup(addresses->addresses[i].balancer_name)); 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->num_addresses, - target_authority_entries, BalancerNameCmp); + TargetAuthorityTable::Create(addresses.size(), target_authority_entries, + BalancerNameCmp); gpr_free(target_authority_entries); return target_authority_table; } @@ -71,13 +73,12 @@ grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args( grpc_arg args_to_add[2]; size_t num_args_to_add = 0; // Add arg for targets info table. - const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES); - GPR_ASSERT(arg != nullptr); - GPR_ASSERT(arg->type == GRPC_ARG_POINTER); - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); + 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/xds/xds_load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h index 9d08defa7ef..67049956417 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 @@ -25,7 +25,7 @@ #include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/lib/iomgr/exec_ctx.h" #define XDS_SERVICE_NAME_MAX_LENGTH 128 diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.cc b/src/core/ext/filters/client_channel/lb_policy_factory.cc deleted file mode 100644 index 5c6363d2952..00000000000 --- a/src/core/ext/filters/client_channel/lb_policy_factory.cc +++ /dev/null @@ -1,163 +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 - -#include -#include - -#include "src/core/lib/channel/channel_args.h" - -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" -#include "src/core/ext/filters/client_channel/parse_address.h" - -grpc_lb_addresses* grpc_lb_addresses_create( - size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable) { - grpc_lb_addresses* addresses = - static_cast(gpr_zalloc(sizeof(grpc_lb_addresses))); - addresses->num_addresses = num_addresses; - addresses->user_data_vtable = user_data_vtable; - const size_t addresses_size = sizeof(grpc_lb_address) * num_addresses; - addresses->addresses = - static_cast(gpr_zalloc(addresses_size)); - return addresses; -} - -grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses) { - grpc_lb_addresses* new_addresses = grpc_lb_addresses_create( - addresses->num_addresses, addresses->user_data_vtable); - memcpy(new_addresses->addresses, addresses->addresses, - sizeof(grpc_lb_address) * addresses->num_addresses); - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (new_addresses->addresses[i].balancer_name != nullptr) { - new_addresses->addresses[i].balancer_name = - gpr_strdup(new_addresses->addresses[i].balancer_name); - } - if (new_addresses->addresses[i].user_data != nullptr) { - new_addresses->addresses[i].user_data = addresses->user_data_vtable->copy( - new_addresses->addresses[i].user_data); - } - } - return new_addresses; -} - -void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index, - const void* address, size_t address_len, - bool is_balancer, const char* balancer_name, - void* user_data) { - GPR_ASSERT(index < addresses->num_addresses); - if (user_data != nullptr) GPR_ASSERT(addresses->user_data_vtable != nullptr); - grpc_lb_address* target = &addresses->addresses[index]; - memcpy(target->address.addr, address, address_len); - target->address.len = static_cast(address_len); - target->is_balancer = is_balancer; - target->balancer_name = gpr_strdup(balancer_name); - target->user_data = user_data; -} - -bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses, - size_t index, const grpc_uri* uri, - bool is_balancer, - const char* balancer_name, - void* user_data) { - grpc_resolved_address address; - if (!grpc_parse_uri(uri, &address)) return false; - grpc_lb_addresses_set_address(addresses, index, address.addr, address.len, - is_balancer, balancer_name, user_data); - return true; -} - -int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1, - const grpc_lb_addresses* addresses2) { - if (addresses1->num_addresses > addresses2->num_addresses) return 1; - if (addresses1->num_addresses < addresses2->num_addresses) return -1; - if (addresses1->user_data_vtable > addresses2->user_data_vtable) return 1; - if (addresses1->user_data_vtable < addresses2->user_data_vtable) return -1; - for (size_t i = 0; i < addresses1->num_addresses; ++i) { - const grpc_lb_address* target1 = &addresses1->addresses[i]; - const grpc_lb_address* target2 = &addresses2->addresses[i]; - if (target1->address.len > target2->address.len) return 1; - if (target1->address.len < target2->address.len) return -1; - int retval = memcmp(target1->address.addr, target2->address.addr, - target1->address.len); - if (retval != 0) return retval; - if (target1->is_balancer > target2->is_balancer) return 1; - if (target1->is_balancer < target2->is_balancer) return -1; - const char* balancer_name1 = - target1->balancer_name != nullptr ? target1->balancer_name : ""; - const char* balancer_name2 = - target2->balancer_name != nullptr ? target2->balancer_name : ""; - retval = strcmp(balancer_name1, balancer_name2); - if (retval != 0) return retval; - if (addresses1->user_data_vtable != nullptr) { - retval = addresses1->user_data_vtable->cmp(target1->user_data, - target2->user_data); - if (retval != 0) return retval; - } - } - return 0; -} - -void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses) { - for (size_t i = 0; i < addresses->num_addresses; ++i) { - gpr_free(addresses->addresses[i].balancer_name); - if (addresses->addresses[i].user_data != nullptr) { - addresses->user_data_vtable->destroy(addresses->addresses[i].user_data); - } - } - gpr_free(addresses->addresses); - gpr_free(addresses); -} - -static void* lb_addresses_copy(void* addresses) { - return grpc_lb_addresses_copy(static_cast(addresses)); -} -static void lb_addresses_destroy(void* addresses) { - grpc_lb_addresses_destroy(static_cast(addresses)); -} -static int lb_addresses_cmp(void* addresses1, void* addresses2) { - return grpc_lb_addresses_cmp(static_cast(addresses1), - static_cast(addresses2)); -} -static const grpc_arg_pointer_vtable lb_addresses_arg_vtable = { - lb_addresses_copy, lb_addresses_destroy, lb_addresses_cmp}; - -grpc_arg grpc_lb_addresses_create_channel_arg( - const grpc_lb_addresses* addresses) { - return grpc_channel_arg_pointer_create( - (char*)GRPC_ARG_LB_ADDRESSES, (void*)addresses, &lb_addresses_arg_vtable); -} - -grpc_lb_addresses* grpc_lb_addresses_find_channel_arg( - const grpc_channel_args* channel_args) { - const grpc_arg* lb_addresses_arg = - grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES); - if (lb_addresses_arg == nullptr || lb_addresses_arg->type != GRPC_ARG_POINTER) - return nullptr; - return static_cast(lb_addresses_arg->value.pointer.p); -} - -bool grpc_lb_addresses_contains_balancer_address( - const grpc_lb_addresses& addresses) { - for (size_t i = 0; i < addresses.num_addresses; ++i) { - if (addresses.addresses[i].is_balancer) return true; - } - return false; -} 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 a59deadb265..a165ebafaba 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -21,91 +21,9 @@ #include -#include "src/core/lib/iomgr/resolve_address.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/lib/uri/uri_parser.h" - -// -// representation of an LB address -// - -// Channel arg key for grpc_lb_addresses. -#define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses" - -/** A resolved address alongside any LB related information associated with it. - * \a user_data, if not NULL, contains opaque data meant to be consumed by the - * gRPC LB policy. Note that no all LB policies support \a user_data as input. - * Those who don't will simply ignore it and will correspondingly return NULL in - * their namesake pick() output argument. */ -// TODO(roth): Once we figure out a better way of handling user_data in -// LB policies, convert these structs to C++ classes. -typedef struct grpc_lb_address { - grpc_resolved_address address; - bool is_balancer; - char* balancer_name; /* For secure naming. */ - void* user_data; -} grpc_lb_address; - -typedef struct grpc_lb_user_data_vtable { - void* (*copy)(void*); - void (*destroy)(void*); - int (*cmp)(void*, void*); -} grpc_lb_user_data_vtable; - -typedef struct grpc_lb_addresses { - size_t num_addresses; - grpc_lb_address* addresses; - const grpc_lb_user_data_vtable* user_data_vtable; -} grpc_lb_addresses; - -/** Returns a grpc_addresses struct with enough space for - \a num_addresses addresses. The \a user_data_vtable argument may be - NULL if no user data will be added. */ -grpc_lb_addresses* grpc_lb_addresses_create( - size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable); - -/** Creates a copy of \a addresses. */ -grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses); - -/** Sets the value of the address at index \a index of \a addresses. - * \a address is a socket address of length \a address_len. */ -void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index, - const void* address, size_t address_len, - bool is_balancer, const char* balancer_name, - void* user_data); - -/** Sets the value of the address at index \a index of \a addresses from \a uri. - * Returns true upon success, false otherwise. */ -bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses, - size_t index, const grpc_uri* uri, - bool is_balancer, - const char* balancer_name, - void* user_data); - -/** Compares \a addresses1 and \a addresses2. */ -int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1, - const grpc_lb_addresses* addresses2); - -/** Destroys \a addresses. */ -void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses); - -/** Returns a channel arg containing \a addresses. */ -grpc_arg grpc_lb_addresses_create_channel_arg( - const grpc_lb_addresses* addresses); - -/** Returns the \a grpc_lb_addresses instance in \a channel_args or NULL */ -grpc_lb_addresses* grpc_lb_addresses_find_channel_arg( - const grpc_channel_args* channel_args); - -// Returns true if addresses contains at least one balancer address. -bool grpc_lb_addresses_contains_balancer_address( - const grpc_lb_addresses& addresses); - -// -// LB policy factory -// +#include "src/core/lib/gprpp/abstract.h" +#include "src/core/lib/gprpp/orphanable.h" namespace grpc_core { 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 4ebc2c8161c..c8425ae3365 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 @@ -33,6 +33,7 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #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/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -117,7 +118,7 @@ class AresDnsResolver : public Resolver { /// retry backoff state BackOff backoff_; /// currently resolving addresses - grpc_lb_addresses* lb_addresses_ = nullptr; + UniquePtr addresses_; /// currently resolving service config char* service_config_json_ = nullptr; // has shutdown been initiated @@ -314,13 +315,13 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { r->resolving_ = false; gpr_free(r->pending_request_); r->pending_request_ = nullptr; - if (r->lb_addresses_ != nullptr) { + 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++] = - grpc_lb_addresses_create_channel_arg(r->lb_addresses_); + CreateServerAddressListChannelArg(r->addresses_.get()); char* service_config_string = nullptr; if (r->service_config_json_ != nullptr) { service_config_string = ChooseServiceConfig(r->service_config_json_); @@ -337,7 +338,7 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { r->channel_args_, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add); gpr_free(service_config_string); - grpc_lb_addresses_destroy(r->lb_addresses_); + r->addresses_.reset(); // Reset backoff state so that we start from the beginning when the // next request gets triggered. r->backoff_.Reset(); @@ -412,11 +413,10 @@ void AresDnsResolver::StartResolvingLocked() { self.release(); GPR_ASSERT(!resolving_); resolving_ = true; - lb_addresses_ = nullptr; service_config_json_ = nullptr; pending_request_ = grpc_dns_lookup_ares_locked( dns_server_, name_to_resolve_, kDefaultPort, interested_parties_, - &on_resolved_, &lb_addresses_, true /* check_grpclb */, + &on_resolved_, &addresses_, true /* check_grpclb */, request_service_config_ ? &service_config_json_ : nullptr, query_timeout_ms_, combiner()); last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc index f42b1e309df..8abc34c6edb 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -31,6 +31,7 @@ #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/iomgr/timer.h" 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 55715869b63..1b1c2303da3 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 @@ -37,12 +37,16 @@ #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/nameser.h" #include "src/core/lib/iomgr/sockaddr_utils.h" +using grpc_core::ServerAddress; +using grpc_core::ServerAddressList; + static gpr_once g_basic_init = GPR_ONCE_INIT; static gpr_mu g_init_mu; @@ -58,7 +62,7 @@ struct grpc_ares_request { /** closure to call when the request completes */ grpc_closure* on_done; /** the pointer to receive the resolved addresses */ - grpc_lb_addresses** lb_addrs_out; + grpc_core::UniquePtr* addresses_out; /** the pointer to receive the service config in JSON */ char** service_config_json_out; /** the evernt driver used by this request */ @@ -87,12 +91,11 @@ typedef struct grpc_ares_hostbyname_request { static void do_basic_init(void) { gpr_mu_init(&g_init_mu); } -static void log_address_sorting_list(grpc_lb_addresses* lb_addrs, +static void log_address_sorting_list(const ServerAddressList& addresses, const char* input_output_str) { - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { + for (size_t i = 0; i < addresses.size(); i++) { char* addr_str; - if (grpc_sockaddr_to_string(&addr_str, &lb_addrs->addresses[i].address, - true)) { + if (grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true)) { gpr_log(GPR_DEBUG, "c-ares address sorting: %s[%" PRIuPTR "]=%s", input_output_str, i, addr_str); gpr_free(addr_str); @@ -104,29 +107,28 @@ static void log_address_sorting_list(grpc_lb_addresses* lb_addrs, } } -void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs) { +void grpc_cares_wrapper_address_sorting_sort(ServerAddressList* addresses) { if (grpc_trace_cares_address_sorting.enabled()) { - log_address_sorting_list(lb_addrs, "input"); + log_address_sorting_list(*addresses, "input"); } address_sorting_sortable* sortables = (address_sorting_sortable*)gpr_zalloc( - sizeof(address_sorting_sortable) * lb_addrs->num_addresses); - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { - sortables[i].user_data = &lb_addrs->addresses[i]; - memcpy(&sortables[i].dest_addr.addr, &lb_addrs->addresses[i].address.addr, - lb_addrs->addresses[i].address.len); - sortables[i].dest_addr.len = lb_addrs->addresses[i].address.len; + sizeof(address_sorting_sortable) * addresses->size()); + for (size_t i = 0; i < addresses->size(); ++i) { + sortables[i].user_data = &(*addresses)[i]; + memcpy(&sortables[i].dest_addr.addr, &(*addresses)[i].address().addr, + (*addresses)[i].address().len); + sortables[i].dest_addr.len = (*addresses)[i].address().len; } - address_sorting_rfc_6724_sort(sortables, lb_addrs->num_addresses); - grpc_lb_address* sorted_lb_addrs = (grpc_lb_address*)gpr_zalloc( - sizeof(grpc_lb_address) * lb_addrs->num_addresses); - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { - sorted_lb_addrs[i] = *(grpc_lb_address*)sortables[i].user_data; + address_sorting_rfc_6724_sort(sortables, addresses->size()); + ServerAddressList sorted; + sorted.reserve(addresses->size()); + for (size_t i = 0; i < addresses->size(); ++i) { + sorted.emplace_back(*static_cast(sortables[i].user_data)); } gpr_free(sortables); - gpr_free(lb_addrs->addresses); - lb_addrs->addresses = sorted_lb_addrs; + *addresses = std::move(sorted); if (grpc_trace_cares_address_sorting.enabled()) { - log_address_sorting_list(lb_addrs, "output"); + log_address_sorting_list(*addresses, "output"); } } @@ -145,9 +147,9 @@ void grpc_ares_complete_request_locked(grpc_ares_request* r) { /* Invoke on_done callback and destroy the request */ r->ev_driver = nullptr; - grpc_lb_addresses* lb_addrs = *(r->lb_addrs_out); - if (lb_addrs != nullptr) { - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + ServerAddressList* addresses = r->addresses_out->get(); + if (addresses != nullptr) { + grpc_cares_wrapper_address_sorting_sort(addresses); } GRPC_CLOSURE_SCHED(r->on_done, r->error); } @@ -181,33 +183,30 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, GRPC_ERROR_UNREF(r->error); r->error = GRPC_ERROR_NONE; r->success = true; - grpc_lb_addresses** lb_addresses = r->lb_addrs_out; - if (*lb_addresses == nullptr) { - *lb_addresses = grpc_lb_addresses_create(0, nullptr); + if (*r->addresses_out == nullptr) { + *r->addresses_out = grpc_core::MakeUnique(); } - size_t prev_naddr = (*lb_addresses)->num_addresses; - size_t i; - for (i = 0; hostent->h_addr_list[i] != nullptr; i++) { - } - (*lb_addresses)->num_addresses += i; - (*lb_addresses)->addresses = static_cast( - gpr_realloc((*lb_addresses)->addresses, - sizeof(grpc_lb_address) * (*lb_addresses)->num_addresses)); - for (i = prev_naddr; i < (*lb_addresses)->num_addresses; i++) { + ServerAddressList& addresses = **r->addresses_out; + for (size_t i = 0; hostent->h_addr_list[i] != nullptr; ++i) { + grpc_core::InlinedVector args_to_add; + if (hr->is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), hr->host)); + } + grpc_channel_args* args = grpc_channel_args_copy_and_add( + nullptr, args_to_add.data(), args_to_add.size()); switch (hostent->h_addrtype) { case AF_INET6: { size_t addr_len = sizeof(struct sockaddr_in6); struct sockaddr_in6 addr; memset(&addr, 0, addr_len); - memcpy(&addr.sin6_addr, hostent->h_addr_list[i - prev_naddr], + memcpy(&addr.sin6_addr, hostent->h_addr_list[i], sizeof(struct in6_addr)); addr.sin6_family = static_cast(hostent->h_addrtype); addr.sin6_port = hr->port; - grpc_lb_addresses_set_address( - *lb_addresses, i, &addr, addr_len, - hr->is_balancer /* is_balancer */, - hr->is_balancer ? hr->host : nullptr /* balancer_name */, - nullptr /* user_data */); + addresses.emplace_back(&addr, addr_len, args); char output[INET6_ADDRSTRLEN]; ares_inet_ntop(AF_INET6, &addr.sin6_addr, output, INET6_ADDRSTRLEN); gpr_log(GPR_DEBUG, @@ -220,15 +219,11 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, size_t addr_len = sizeof(struct sockaddr_in); struct sockaddr_in addr; memset(&addr, 0, addr_len); - memcpy(&addr.sin_addr, hostent->h_addr_list[i - prev_naddr], + memcpy(&addr.sin_addr, hostent->h_addr_list[i], sizeof(struct in_addr)); addr.sin_family = static_cast(hostent->h_addrtype); addr.sin_port = hr->port; - grpc_lb_addresses_set_address( - *lb_addresses, i, &addr, addr_len, - hr->is_balancer /* is_balancer */, - hr->is_balancer ? hr->host : nullptr /* balancer_name */, - nullptr /* user_data */); + addresses.emplace_back(&addr, addr_len, args); char output[INET_ADDRSTRLEN]; ares_inet_ntop(AF_INET, &addr.sin_addr, output, INET_ADDRSTRLEN); gpr_log(GPR_DEBUG, @@ -467,11 +462,10 @@ error_cleanup: gpr_free(port); } -static bool inner_resolve_as_ip_literal_locked(const char* name, - const char* default_port, - grpc_lb_addresses** addrs, - char** host, char** port, - char** hostport) { +static bool inner_resolve_as_ip_literal_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port, char** hostport) { gpr_split_host_port(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, @@ -495,18 +489,16 @@ static bool inner_resolve_as_ip_literal_locked(const char* name, if (grpc_parse_ipv4_hostport(*hostport, &addr, false /* log errors */) || grpc_parse_ipv6_hostport(*hostport, &addr, false /* log errors */)) { GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_lb_addresses_create(1, nullptr); - grpc_lb_addresses_set_address( - *addrs, 0, addr.addr, addr.len, false /* is_balancer */, - nullptr /* balancer_name */, nullptr /* user_data */); + *addrs = grpc_core::MakeUnique(); + (*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */); return true; } return false; } -static bool resolve_as_ip_literal_locked(const char* name, - const char* default_port, - grpc_lb_addresses** addrs) { +static bool resolve_as_ip_literal_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { char* host = nullptr; char* port = nullptr; char* hostport = nullptr; @@ -521,13 +513,14 @@ static bool resolve_as_ip_literal_locked(const char* name, static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { grpc_ares_request* r = static_cast(gpr_zalloc(sizeof(grpc_ares_request))); r->ev_driver = nullptr; r->on_done = on_done; - r->lb_addrs_out = addrs; + r->addresses_out = addrs; r->service_config_json_out = service_config_json; r->success = false; r->error = GRPC_ERROR_NONE; @@ -553,8 +546,8 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) { @@ -599,8 +592,8 @@ typedef struct grpc_resolve_address_ares_request { grpc_combiner* combiner; /** the pointer to receive the resolved addresses */ grpc_resolved_addresses** addrs_out; - /** currently resolving lb addresses */ - grpc_lb_addresses* lb_addrs; + /** currently resolving addresses */ + grpc_core::UniquePtr addresses; /** closure to call when the resolve_address_ares request completes */ grpc_closure* on_resolve_address_done; /** a closure wrapping on_resolve_address_done, which should be invoked when @@ -613,7 +606,7 @@ typedef struct grpc_resolve_address_ares_request { /* pollset_set to be driven by */ grpc_pollset_set* interested_parties; /* underlying ares_request that the query is performed on */ - grpc_ares_request* ares_request; + grpc_ares_request* ares_request = nullptr; } grpc_resolve_address_ares_request; static void on_dns_lookup_done_locked(void* arg, grpc_error* error) { @@ -621,25 +614,24 @@ static void on_dns_lookup_done_locked(void* arg, grpc_error* error) { static_cast(arg); gpr_free(r->ares_request); grpc_resolved_addresses** resolved_addresses = r->addrs_out; - if (r->lb_addrs == nullptr || r->lb_addrs->num_addresses == 0) { + if (r->addresses == nullptr || r->addresses->empty()) { *resolved_addresses = nullptr; } else { *resolved_addresses = static_cast( gpr_zalloc(sizeof(grpc_resolved_addresses))); - (*resolved_addresses)->naddrs = r->lb_addrs->num_addresses; + (*resolved_addresses)->naddrs = r->addresses->size(); (*resolved_addresses)->addrs = static_cast(gpr_zalloc( sizeof(grpc_resolved_address) * (*resolved_addresses)->naddrs)); - for (size_t i = 0; i < (*resolved_addresses)->naddrs; i++) { - GPR_ASSERT(!r->lb_addrs->addresses[i].is_balancer); - memcpy(&(*resolved_addresses)->addrs[i], - &r->lb_addrs->addresses[i].address, sizeof(grpc_resolved_address)); + for (size_t i = 0; i < (*resolved_addresses)->naddrs; ++i) { + GPR_ASSERT(!(*r->addresses)[i].IsBalancer()); + memcpy(&(*resolved_addresses)->addrs[i], &(*r->addresses)[i].address(), + sizeof(grpc_resolved_address)); } } GRPC_CLOSURE_SCHED(r->on_resolve_address_done, GRPC_ERROR_REF(error)); - if (r->lb_addrs != nullptr) grpc_lb_addresses_destroy(r->lb_addrs); GRPC_COMBINER_UNREF(r->combiner, "on_dns_lookup_done_cb"); - gpr_free(r); + grpc_core::Delete(r); } static void grpc_resolve_address_invoke_dns_lookup_ares_locked( @@ -648,7 +640,7 @@ static void grpc_resolve_address_invoke_dns_lookup_ares_locked( static_cast(arg); r->ares_request = grpc_dns_lookup_ares_locked( nullptr /* dns_server */, r->name, r->default_port, r->interested_parties, - &r->on_dns_lookup_done_locked, &r->lb_addrs, false /* check_grpclb */, + &r->on_dns_lookup_done_locked, &r->addresses, false /* check_grpclb */, nullptr /* service_config_json */, GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, r->combiner); } @@ -659,8 +651,7 @@ static void grpc_resolve_address_ares_impl(const char* name, grpc_closure* on_done, grpc_resolved_addresses** addrs) { grpc_resolve_address_ares_request* r = - static_cast( - gpr_zalloc(sizeof(grpc_resolve_address_ares_request))); + grpc_core::New(); r->combiner = grpc_combiner_create(); r->addrs_out = addrs; r->on_resolve_address_done = on_done; diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h index 9acef1d0ca9..28082504565 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -21,7 +21,7 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -61,8 +61,9 @@ extern void (*grpc_resolve_address_ares)(const char* name, extern grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addresses, bool check_grpclb, - char** service_config_json, int query_timeout_ms, grpc_combiner* combiner); + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner); /* Cancel the pending grpc_ares_request \a request */ extern void (*grpc_cancel_ares_request_locked)(grpc_ares_request* request); @@ -89,10 +90,12 @@ bool grpc_ares_query_ipv6(); * Returns a bool indicating whether or not such an action was performed. * See https://github.com/grpc/grpc/issues/15158. */ bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs); + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs); /* Sorts destinations in lb_addrs according to RFC 6724. */ -void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs); +void grpc_cares_wrapper_address_sorting_sort( + grpc_core::ServerAddressList* addresses); #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H \ */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc index fc78b183044..1f4701c9994 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc @@ -29,16 +29,17 @@ struct grpc_ares_request { static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { return NULL; } grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {} diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc index 639eec2323f..028d8442169 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc @@ -27,7 +27,8 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs) { + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { return false; } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index 7e34784691f..202452f1b2b 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -23,9 +23,9 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_windows.h" @@ -33,8 +33,9 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } static bool inner_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs, - char** host, char** port) { + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port) { gpr_split_host_port(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, @@ -55,7 +56,7 @@ static bool inner_maybe_resolve_localhost_manually_locked( } if (gpr_stricmp(*host, "localhost") == 0) { GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_lb_addresses_create(2, nullptr); + *addrs = grpc_core::MakeUnique(); uint16_t numeric_port = grpc_strhtons(*port); // Append the ipv6 loopback address. struct sockaddr_in6 ipv6_loopback_addr; @@ -63,10 +64,8 @@ static bool inner_maybe_resolve_localhost_manually_locked( ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; ipv6_loopback_addr.sin6_family = AF_INET6; ipv6_loopback_addr.sin6_port = numeric_port; - grpc_lb_addresses_set_address( - *addrs, 0, &ipv6_loopback_addr, sizeof(ipv6_loopback_addr), - false /* is_balancer */, nullptr /* balancer_name */, - nullptr /* user_data */); + (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), + nullptr /* args */); // Append the ipv4 loopback address. struct sockaddr_in ipv4_loopback_addr; memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); @@ -74,19 +73,18 @@ static bool inner_maybe_resolve_localhost_manually_locked( ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; ipv4_loopback_addr.sin_family = AF_INET; ipv4_loopback_addr.sin_port = numeric_port; - grpc_lb_addresses_set_address( - *addrs, 1, &ipv4_loopback_addr, sizeof(ipv4_loopback_addr), - false /* is_balancer */, nullptr /* balancer_name */, - nullptr /* user_data */); + (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), + nullptr /* args */); // Let the address sorter figure out which one should be tried first. - grpc_cares_wrapper_address_sorting_sort(*addrs); + grpc_cares_wrapper_address_sorting_sort(addrs->get()); return true; } return false; } bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs) { + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { char* host = nullptr; char* port = nullptr; bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, 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 65ff1ec1a5b..c365f1abfd8 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 @@ -26,8 +26,8 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -198,18 +198,14 @@ void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(r->name_to_resolve_)); if (r->addresses_ != nullptr) { - grpc_lb_addresses* addresses = grpc_lb_addresses_create( - r->addresses_->naddrs, nullptr /* user_data_vtable */); + ServerAddressList addresses; for (size_t i = 0; i < r->addresses_->naddrs; ++i) { - grpc_lb_addresses_set_address( - addresses, i, &r->addresses_->addrs[i].addr, - r->addresses_->addrs[i].len, false /* is_balancer */, - nullptr /* balancer_name */, nullptr /* user_data */); + addresses.emplace_back(&r->addresses_->addrs[i].addr, + r->addresses_->addrs[i].len, nullptr /* args */); } - grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses); + 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_lb_addresses_destroy(addresses); // 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 3aa690bea41..258339491c1 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 @@ -28,12 +28,13 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/resolve_address.h" 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 7f690593510..d86111c3829 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,10 +19,9 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/ref_counted.h" -#include "src/core/lib/uri/uri_parser.h" +#include "src/core/lib/iomgr/error.h" #define GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR \ "grpc.fake_resolver.response_generator" 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 801734764b4..1654747a79f 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 @@ -26,9 +26,9 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" @@ -45,7 +45,8 @@ namespace { class SockaddrResolver : public Resolver { public: /// Takes ownership of \a addresses. - SockaddrResolver(const ResolverArgs& args, grpc_lb_addresses* addresses); + SockaddrResolver(const ResolverArgs& args, + UniquePtr addresses); void NextLocked(grpc_channel_args** result, grpc_closure* on_complete) override; @@ -58,7 +59,7 @@ class SockaddrResolver : public Resolver { void MaybeFinishNextLocked(); /// the addresses that we've "resolved" - grpc_lb_addresses* addresses_ = nullptr; + UniquePtr addresses_; /// channel args grpc_channel_args* channel_args_ = nullptr; /// have we published? @@ -70,13 +71,12 @@ class SockaddrResolver : public Resolver { }; SockaddrResolver::SockaddrResolver(const ResolverArgs& args, - grpc_lb_addresses* addresses) + UniquePtr addresses) : Resolver(args.combiner), - addresses_(addresses), + addresses_(std::move(addresses)), channel_args_(grpc_channel_args_copy(args.args)) {} SockaddrResolver::~SockaddrResolver() { - grpc_lb_addresses_destroy(addresses_); grpc_channel_args_destroy(channel_args_); } @@ -100,7 +100,7 @@ void SockaddrResolver::ShutdownLocked() { void SockaddrResolver::MaybeFinishNextLocked() { if (next_completion_ != nullptr && !published_) { published_ = true; - grpc_arg arg = grpc_lb_addresses_create_channel_arg(addresses_); + 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; @@ -127,27 +127,27 @@ OrphanablePtr CreateSockaddrResolver( grpc_slice_buffer path_parts; grpc_slice_buffer_init(&path_parts); grpc_slice_split(path_slice, ",", &path_parts); - grpc_lb_addresses* addresses = grpc_lb_addresses_create( - path_parts.count, nullptr /* user_data_vtable */); + auto addresses = MakeUnique(); bool errors_found = false; - for (size_t i = 0; i < addresses->num_addresses; i++) { + for (size_t i = 0; i < path_parts.count; i++) { grpc_uri ith_uri = *args.uri; - char* part_str = grpc_slice_to_c_string(path_parts.slices[i]); - ith_uri.path = part_str; - if (!parse(&ith_uri, &addresses->addresses[i].address)) { + UniquePtr part_str(grpc_slice_to_c_string(path_parts.slices[i])); + ith_uri.path = part_str.get(); + grpc_resolved_address addr; + if (!parse(&ith_uri, &addr)) { errors_found = true; /* GPR_TRUE */ + break; } - gpr_free(part_str); - if (errors_found) break; + addresses->emplace_back(addr, nullptr /* args */); } grpc_slice_buffer_destroy_internal(&path_parts); grpc_slice_unref_internal(path_slice); if (errors_found) { - grpc_lb_addresses_destroy(addresses); return OrphanablePtr(nullptr); } // Instantiate resolver. - return OrphanablePtr(New(args, addresses)); + return OrphanablePtr( + New(args, std::move(addresses))); } class IPv4ResolverFactory : public ResolverFactory { 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 4f7fd6b4243..22b06db45c4 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -30,9 +30,11 @@ #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/status_util.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/uri/uri_parser.h" // As per the retry design, we do not allow more than 5 retry attempts. #define MAX_MAX_RETRY_ATTEMPTS 5 @@ -99,12 +101,18 @@ void ProcessedResolverResult::ProcessLbPolicyName( } // Special case: If at least one balancer address is present, we use // the grpclb policy, regardless of what the resolver has returned. - const grpc_arg* channel_arg = - grpc_channel_args_find(resolver_result, GRPC_ARG_LB_ADDRESSES); - if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) { - grpc_lb_addresses* addresses = - static_cast(channel_arg->value.pointer.p); - if (grpc_lb_addresses_contains_balancer_address(*addresses)) { + 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; + } + } + if (found_balancer_address) { if (lb_policy_name_ != nullptr && strcmp(lb_policy_name_.get(), "grpclb") != 0) { gpr_log(GPR_INFO, diff --git a/src/core/ext/filters/client_channel/server_address.cc b/src/core/ext/filters/client_channel/server_address.cc new file mode 100644 index 00000000000..ec33cbbd956 --- /dev/null +++ b/src/core/ext/filters/client_channel/server_address.cc @@ -0,0 +1,103 @@ +/* + * + * 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/server_address.h" + +#include + +namespace grpc_core { + +// +// ServerAddress +// + +ServerAddress::ServerAddress(const grpc_resolved_address& address, + grpc_channel_args* args) + : address_(address), args_(args) {} + +ServerAddress::ServerAddress(const void* address, size_t address_len, + grpc_channel_args* args) + : args_(args) { + memcpy(address_.addr, address, address_len); + address_.len = static_cast(address_len); +} + +int ServerAddress::Cmp(const ServerAddress& other) const { + if (address_.len > other.address_.len) return 1; + if (address_.len < other.address_.len) return -1; + int retval = memcmp(address_.addr, other.address_.addr, address_.len); + if (retval != 0) return retval; + return grpc_channel_args_compare(args_, other.args_); +} + +bool ServerAddress::IsBalancer() const { + return grpc_channel_arg_get_bool( + 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 new file mode 100644 index 00000000000..3a1bf1df67d --- /dev/null +++ b/src/core/ext/filters/client_channel/server_address.h @@ -0,0 +1,108 @@ +/* + * + * 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_SERVER_ADDRESS_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H + +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#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" + +// Channel arg key for a string indicating an address's balancer name. +#define GRPC_ARG_ADDRESS_BALANCER_NAME "grpc.address_balancer_name" + +namespace grpc_core { + +// +// ServerAddress +// + +// A server address is a grpc_resolved_address with an associated set of +// channel args. Any args present here will be merged into the channel +// args when a subchannel is created for this address. +class ServerAddress { + public: + // Takes ownership of args. + ServerAddress(const grpc_resolved_address& address, grpc_channel_args* args); + ServerAddress(const void* address, size_t address_len, + grpc_channel_args* args); + + ~ServerAddress() { grpc_channel_args_destroy(args_); } + + // Copyable. + ServerAddress(const ServerAddress& other) + : address_(other.address_), args_(grpc_channel_args_copy(other.args_)) {} + ServerAddress& operator=(const ServerAddress& other) { + address_ = other.address_; + grpc_channel_args_destroy(args_); + args_ = grpc_channel_args_copy(other.args_); + return *this; + } + + // Movable. + ServerAddress(ServerAddress&& other) + : address_(other.address_), args_(other.args_) { + other.args_ = nullptr; + } + ServerAddress& operator=(ServerAddress&& other) { + address_ = other.address_; + args_ = other.args_; + other.args_ = nullptr; + return *this; + } + + bool operator==(const ServerAddress& other) const { return Cmp(other) == 0; } + + int Cmp(const ServerAddress& other) const; + + const grpc_resolved_address& address() const { return address_; } + const grpc_channel_args* args() const { return args_; } + + bool IsBalancer() const; + + private: + grpc_resolved_address address_; + grpc_channel_args* args_; +}; + +// +// ServerAddressList +// + +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/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 0817b1dd392..3100889e3fd 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -837,7 +837,7 @@ static bool publish_transport_locked(grpc_subchannel* c) { /* publish */ c->connected_subchannel.reset(grpc_core::New( - stk, c->channelz_subchannel, socket_uuid)); + 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); @@ -1068,16 +1068,18 @@ grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) { namespace grpc_core { ConnectedSubchannel::ConnectedSubchannel( - grpc_channel_stack* channel_stack, + 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"); } diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 69c2456ec20..14f87f2c68e 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -85,28 +85,31 @@ class ConnectedSubchannel : public RefCounted { size_t parent_data_size; }; - explicit ConnectedSubchannel( - grpc_channel_stack* channel_stack, + ConnectedSubchannel( + grpc_channel_stack* channel_stack, const grpc_channel_args* args, grpc_core::RefCountedPtr channelz_subchannel, intptr_t socket_uuid); ~ConnectedSubchannel(); - grpc_channel_stack* channel_stack() { return channel_stack_; } void NotifyOnStateChange(grpc_pollset_set* interested_parties, 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); - channelz::SubchannelNode* channelz_subchannel() { + + grpc_channel_stack* channel_stack() const { return channel_stack_; } + const grpc_channel_args* args() const { return args_; } + channelz::SubchannelNode* channelz_subchannel() const { return channelz_subchannel_.get(); } - intptr_t socket_uuid() { return socket_uuid_; } + intptr_t socket_uuid() const { return socket_uuid_; } size_t GetInitialCallSizeEstimate(size_t parent_data_size) const; private: grpc_channel_stack* channel_stack_; + grpc_channel_args* args_; // ref counted pointer to the channelz node in this connected subchannel's // owning subchannel. grpc_core::RefCountedPtr diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc index 1b66dceb130..0839bdfef2d 100644 --- a/src/core/lib/iomgr/sockaddr_utils.cc +++ b/src/core/lib/iomgr/sockaddr_utils.cc @@ -217,6 +217,7 @@ void grpc_string_to_sockaddr(grpc_resolved_address* out, char* addr, int port) { } char* grpc_sockaddr_to_uri(const grpc_resolved_address* resolved_addr) { + if (resolved_addr->len == 0) return nullptr; grpc_resolved_address addr_normalized; if (grpc_sockaddr_is_v4mapped(resolved_addr, &addr_normalized)) { resolved_addr = &addr_normalized; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index ce65c594fe2..c6ca970beee 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -322,7 +322,6 @@ CORE_SOURCE_FILES = [ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -331,6 +330,7 @@ CORE_SOURCE_FILES = [ '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/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/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 76769b2b64a..1a7a7c9ccc9 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -21,10 +21,10 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver.h" #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/lib/channel/channel_args.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -63,8 +63,9 @@ static grpc_address_resolver_vtable test_resolver = {my_resolve_address, static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { gpr_mu_lock(&g_mu); GPR_ASSERT(0 == strcmp("test", addr)); grpc_error* error = GRPC_ERROR_NONE; @@ -74,9 +75,8 @@ static grpc_ares_request* my_dns_lookup_ares_locked( error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { gpr_mu_unlock(&g_mu); - *lb_addrs = grpc_lb_addresses_create(1, nullptr); - grpc_lb_addresses_set_address(*lb_addrs, 0, nullptr, 0, false, nullptr, - nullptr); + *addresses = grpc_core::MakeUnique(); + (*addresses)->emplace_back(nullptr, 0, nullptr); } GRPC_CLOSURE_SCHED(on_done, error); return nullptr; 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 cdbe33dbe79..16210b8164b 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -22,6 +22,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/lib/channel/channel_args.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/combiner.h" @@ -40,8 +41,9 @@ static grpc_combiner* g_combiner; static grpc_ares_request* (*g_default_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner); + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner); // Counter incremented by test_resolve_address_impl indicating the number of // times a system-level resolution has happened. @@ -90,11 +92,12 @@ static grpc_address_resolver_vtable test_resolver = { static grpc_ares_request* test_dns_lookup_ares_locked( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { grpc_ares_request* result = g_default_dns_lookup_ares_locked( - dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, addrs, - check_grpclb, service_config_json, query_timeout_ms, combiner); + dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, + addresses, check_grpclb, service_config_json, query_timeout_ms, combiner); ++g_resolution_count; static grpc_millis last_resolution_time = 0; if (last_resolution_time == 0) { diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc index 6362b95e50e..3b06fe063ae 100644 --- a/test/core/client_channel/resolvers/fake_resolver_test.cc +++ b/test/core/client_channel/resolvers/fake_resolver_test.cc @@ -22,10 +22,10 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.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/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/combiner.h" @@ -63,12 +63,14 @@ void on_resolution_cb(void* arg, grpc_error* error) { // We only check the addresses channel arg because that's the only one // explicitly set by the test via // FakeResolverResponseGenerator::SetResponse(). - const grpc_lb_addresses* actual_lb_addresses = - grpc_lb_addresses_find_channel_arg(res->resolver_result); - const grpc_lb_addresses* expected_lb_addresses = - grpc_lb_addresses_find_channel_arg(res->expected_resolver_result); - GPR_ASSERT( - grpc_lb_addresses_cmp(actual_lb_addresses, expected_lb_addresses) == 0); + 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); @@ -80,27 +82,35 @@ static grpc_channel_args* create_new_resolver_result() { const size_t num_addresses = 2; char* uri_string; char* balancer_name; - // Create grpc_lb_addresses. - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(num_addresses, nullptr); + // Create address list. + grpc_core::ServerAddressList addresses; 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); grpc_uri* uri = grpc_uri_parse(uri_string, true); gpr_asprintf(&balancer_name, "balancer%" PRIuPTR, test_counter * num_addresses + i); - grpc_lb_addresses_set_address_from_uri( - addresses, i, uri, bool(num_addresses % 2), balancer_name, nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(uri, &address)); + grpc_core::InlinedVector args_to_add; + const bool is_balancer = num_addresses % 2; + if (is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), balancer_name)); + } + 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); gpr_free(balancer_name); grpc_uri_destroy(uri); gpr_free(uri_string); } - // Convert grpc_lb_addresses to grpc_channel_args. - const grpc_arg addresses_arg = - grpc_lb_addresses_create_channel_arg(addresses); + // 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); - grpc_lb_addresses_destroy(addresses); ++test_counter; return results; } diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index 9b6eddee6e1..fbf6379a698 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -24,8 +24,8 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -325,7 +325,7 @@ typedef struct addr_req { char* addr; grpc_closure* on_done; grpc_resolved_addresses** addrs; - grpc_lb_addresses** lb_addrs; + grpc_core::UniquePtr* addresses; } addr_req; static void finish_resolve(void* arg, grpc_error* error) { @@ -340,11 +340,9 @@ static void finish_resolve(void* arg, grpc_error* error) { gpr_malloc(sizeof(*addrs->addrs))); addrs->addrs[0].len = 0; *r->addrs = addrs; - } else if (r->lb_addrs != nullptr) { - grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(1, nullptr); - grpc_lb_addresses_set_address(lb_addrs, 0, nullptr, 0, false, nullptr, - nullptr); - *r->lb_addrs = lb_addrs; + } else if (r->addresses != nullptr) { + *r->addresses = grpc_core::MakeUnique(); + (*r->addresses)->emplace_back(nullptr, 0, nullptr); } GRPC_CLOSURE_SCHED(r->on_done, GRPC_ERROR_NONE); } else { @@ -354,18 +352,17 @@ static void finish_resolve(void* arg, grpc_error* error) { } gpr_free(r->addr); - gpr_free(r); + grpc_core::Delete(r); } void my_resolve_address(const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_resolved_addresses** addresses) { - addr_req* r = static_cast(gpr_malloc(sizeof(*r))); + grpc_resolved_addresses** addrs) { + addr_req* r = grpc_core::New(); r->addr = gpr_strdup(addr); r->on_done = on_done; - r->addrs = addresses; - r->lb_addrs = nullptr; + r->addrs = addrs; grpc_timer_init( &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); @@ -377,13 +374,14 @@ static grpc_address_resolver_vtable fuzzer_resolver = {my_resolve_address, grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - int query_timeout, grpc_combiner* combiner) { + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout, + grpc_combiner* combiner) { addr_req* r = static_cast(gpr_malloc(sizeof(*r))); r->addr = gpr_strdup(addr); r->on_done = on_done; r->addrs = nullptr; - r->lb_addrs = lb_addrs; + r->addresses = addresses; grpc_timer_init( &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 66e8ca51614..7e3b418cd94 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -28,8 +28,8 @@ #include #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr.h" #include "test/core/end2end/cq_verifier.h" @@ -47,8 +47,9 @@ static int g_resolve_port = -1; static grpc_ares_request* (*iomgr_dns_lookup_ares_locked)( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addresses, bool check_grpclb, - char** service_config_json, int query_timeout_ms, grpc_combiner* combiner); + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner); static void (*iomgr_cancel_ares_request_locked)(grpc_ares_request* request); @@ -103,11 +104,12 @@ static grpc_address_resolver_vtable test_resolver = { static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { if (0 != strcmp(addr, "test")) { return iomgr_dns_lookup_ares_locked( - dns_server, addr, default_port, interested_parties, on_done, lb_addrs, + dns_server, addr, default_port, interested_parties, on_done, addresses, check_grpclb, service_config_json, query_timeout_ms, combiner); } @@ -117,15 +119,12 @@ static grpc_ares_request* my_dns_lookup_ares_locked( gpr_mu_unlock(&g_mu); error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { - *lb_addrs = grpc_lb_addresses_create(1, nullptr); - grpc_sockaddr_in* sa = - static_cast(gpr_zalloc(sizeof(grpc_sockaddr_in))); - sa->sin_family = GRPC_AF_INET; - sa->sin_addr.s_addr = 0x100007f; - sa->sin_port = grpc_htons(static_cast(g_resolve_port)); - grpc_lb_addresses_set_address(*lb_addrs, 0, sa, sizeof(*sa), false, nullptr, - nullptr); - gpr_free(sa); + *addresses = grpc_core::MakeUnique(); + grpc_sockaddr_in sa; + sa.sin_family = GRPC_AF_INET; + sa.sin_addr.s_addr = 0x100007f; + sa.sin_port = grpc_htons(static_cast(g_resolve_port)); + (*addresses)->emplace_back(&sa, sizeof(sa), nullptr); gpr_mu_unlock(&g_mu); } GRPC_CLOSURE_SCHED(on_done, error); diff --git a/test/core/end2end/no_server_test.cc b/test/core/end2end/no_server_test.cc index 5dda748f5a5..c289e719eea 100644 --- a/test/core/end2end/no_server_test.cc +++ b/test/core/end2end/no_server_test.cc @@ -23,6 +23,7 @@ #include #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/test_config.h" diff --git a/test/core/util/ubsan_suppressions.txt b/test/core/util/ubsan_suppressions.txt index 63898ea3b1c..8ed7d4d7fb6 100644 --- a/test/core/util/ubsan_suppressions.txt +++ b/test/core/util/ubsan_suppressions.txt @@ -25,7 +25,6 @@ alignment:absl::little_endian::Store64 alignment:absl::little_endian::Load64 float-divide-by-zero:grpc::testing::postprocess_scenario_result enum:grpc_op_string -nonnull-attribute:grpc_lb_addresses_copy signed-integer-overflow:chrono enum:grpc_http2_error_to_grpc_status -enum:grpc_chttp2_cancel_stream \ No newline at end of file +enum:grpc_chttp2_cancel_stream diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index bf321d8a89e..124557eb567 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -34,7 +34,9 @@ #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/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -216,23 +218,31 @@ class ClientChannelStressTest { void SetNextResolution(const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(address_data.size(), nullptr); - for (size_t i = 0; i < address_data.size(); ++i) { + grpc_core::ServerAddressList addresses; + for (const auto& addr : address_data) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port); + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port); grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); GPR_ASSERT(lb_uri != nullptr); - grpc_lb_addresses_set_address_from_uri( - addresses, i, lb_uri, address_data[i].is_balancer, - address_data[i].balancer_name.c_str(), nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + std::vector args_to_add; + if (addr.is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), + const_cast(addr.balancer_name.c_str()))); + } + 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); } - grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); + grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); grpc_channel_args fake_result = {1, &fake_addresses}; response_generator_->SetResponse(&fake_result); - grpc_lb_addresses_destroy(addresses); } void KeepSendingRequests() { diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 759847be3e9..aed02edf044 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -35,7 +35,9 @@ #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/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/gpr/env.h" @@ -159,24 +161,22 @@ class ClientLbEnd2endTest : public ::testing::Test { } grpc_channel_args* BuildFakeResults(const std::vector& ports) { - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(ports.size(), nullptr); - for (size_t i = 0; i < ports.size(); ++i) { + grpc_core::ServerAddressList addresses; + for (const int& port : ports) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", ports[i]); + 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_lb_addresses_set_address_from_uri(addresses, i, lb_uri, - false /* is balancer */, - "" /* balancer name */, nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + addresses.emplace_back(address.addr, address.len, nullptr /* args */); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } const grpc_arg fake_addresses = - grpc_lb_addresses_create_channel_arg(addresses); + CreateServerAddressListChannelArg(&addresses); grpc_channel_args* fake_results = grpc_channel_args_copy_and_add(nullptr, &fake_addresses, 1); - grpc_lb_addresses_destroy(addresses); return fake_results; } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 9c4cd050619..bf990a07b5a 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -32,7 +32,9 @@ #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" @@ -486,18 +488,27 @@ class GrpclbEnd2endTest : public ::testing::Test { grpc::string balancer_name; }; - grpc_lb_addresses* CreateLbAddressesFromAddressDataList( + grpc_core::ServerAddressList CreateLbAddressesFromAddressDataList( const std::vector& address_data) { - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(address_data.size(), nullptr); - for (size_t i = 0; i < address_data.size(); ++i) { + grpc_core::ServerAddressList addresses; + for (const auto& addr : address_data) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port); + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port); grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); GPR_ASSERT(lb_uri != nullptr); - grpc_lb_addresses_set_address_from_uri( - addresses, i, lb_uri, address_data[i].is_balancer, - address_data[i].balancer_name.c_str(), nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + std::vector args_to_add; + if (addr.is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), + const_cast(addr.balancer_name.c_str()))); + } + 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); } @@ -506,23 +517,21 @@ class GrpclbEnd2endTest : public ::testing::Test { void SetNextResolution(const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses* addresses = + grpc_core::ServerAddressList addresses = CreateLbAddressesFromAddressDataList(address_data); - grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); + grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); grpc_channel_args fake_result = {1, &fake_addresses}; response_generator_->SetResponse(&fake_result); - grpc_lb_addresses_destroy(addresses); } void SetNextReresolutionResponse( const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses* addresses = + grpc_core::ServerAddressList addresses = CreateLbAddressesFromAddressDataList(address_data); - grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); + grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); grpc_channel_args fake_result = {1, &fake_addresses}; response_generator_->SetReresolutionResponse(&fake_result); - grpc_lb_addresses_destroy(addresses); } const std::vector GetBackendPorts(const size_t start_index = 0) const { diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index 3eb0e7d7254..09e705df789 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -37,6 +37,7 @@ #include "src/core/ext/filters/client_channel/resolver.h" #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/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" @@ -167,30 +168,26 @@ void OverrideAddressSortingSourceAddrFactory( address_sorting_override_source_addr_factory_for_testing(factory); } -grpc_lb_addresses* BuildLbAddrInputs(std::vector test_addrs) { - grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(0, nullptr); - lb_addrs->addresses = - (grpc_lb_address*)gpr_zalloc(sizeof(grpc_lb_address) * test_addrs.size()); - lb_addrs->num_addresses = test_addrs.size(); - for (size_t i = 0; i < test_addrs.size(); i++) { - lb_addrs->addresses[i].address = - TestAddressToGrpcResolvedAddress(test_addrs[i]); +grpc_core::ServerAddressList BuildLbAddrInputs( + const std::vector& test_addrs) { + grpc_core::ServerAddressList addresses; + for (const auto& addr : test_addrs) { + addresses.emplace_back(TestAddressToGrpcResolvedAddress(addr), nullptr); } - return lb_addrs; + return addresses; } -void VerifyLbAddrOutputs(grpc_lb_addresses* lb_addrs, +void VerifyLbAddrOutputs(const grpc_core::ServerAddressList addresses, std::vector expected_addrs) { - EXPECT_EQ(lb_addrs->num_addresses, expected_addrs.size()); - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { + EXPECT_EQ(addresses.size(), expected_addrs.size()); + for (size_t i = 0; i < addresses.size(); ++i) { char* ip_addr_str; - grpc_sockaddr_to_string(&ip_addr_str, &lb_addrs->addresses[i].address, + grpc_sockaddr_to_string(&ip_addr_str, &addresses[i].address(), false /* normalize */); EXPECT_EQ(expected_addrs[i], ip_addr_str); gpr_free(ip_addr_str); } grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses_destroy(lb_addrs); } /* We need to run each test case inside of its own @@ -212,11 +209,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) { { {"1.2.3.4:443", {"4.3.2.1:443", AF_INET}}, }); - auto* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"1.2.3.4:443", AF_INET}, {"5.6.7.8:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "1.2.3.4:443", "5.6.7.8:443", @@ -235,7 +232,7 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) { {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "1.2.3.4:443", "[2607:f8b0:400a:801::1002]:443", @@ -251,11 +248,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) { {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}}, {"[2607:f8b0:400a:801::1002]:443", {"[fec0::1234]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2607:f8b0:400a:801::1002]:443", "1.2.3.4:443", @@ -275,11 +272,11 @@ TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) { {"[fec0::5000]:443", {"[fec0::5001]:0", AF_INET6}}, // site-local and site-local scope }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2000:f8b0:400a:801::1002]:443", AF_INET6}, {"[fec0::5000]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fec0::5000]:443", "[2000:f8b0:400a:801::1002]:443", @@ -298,11 +295,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) { {"[2001::5001]:443", {"[2001::5002]:0", AF_INET6}}, // matching labels }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2002::5001]:443", AF_INET6}, {"[2001::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2001::5001]:443", "[2002::5001]:443", @@ -321,11 +318,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) { {"[2001::5001]:443", {"[2001::5002]:0", AF_INET6}}, // matching labels }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2001::5001]:443", AF_INET6}, {"[2002::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2001::5001]:443", "[2002::5001]:443", @@ -344,11 +341,11 @@ TEST_F(AddressSortingTest, {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}}, {"1.2.3.4:443", {"5.6.7.8:0", AF_INET}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs( lb_addrs, { // The AF_INET address should be IPv4-mapped by the sort, @@ -377,11 +374,11 @@ TEST_F(AddressSortingTest, {"[::1]:443", {"[::1]:0", AF_INET6}}, {v4_compat_dest, {v4_compat_src, AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {v4_compat_dest, AF_INET6}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", v4_compat_dest, @@ -400,11 +397,11 @@ TEST_F(AddressSortingTest, {"[1234::2]:443", {"[1234::2]:0", AF_INET6}}, {"[::1]:443", {"[::1]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[1234::2]:443", AF_INET6}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs( lb_addrs, { @@ -424,11 +421,11 @@ TEST_F(AddressSortingTest, {"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}}, {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2001::1234]:443", AF_INET6}, {"[2000::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs( lb_addrs, { // The 2000::/16 address should match the ::/0 prefix rule @@ -448,11 +445,11 @@ TEST_F( {"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}}, {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2001::1231]:443", AF_INET6}, {"[2000::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2000::5001]:443", "[2001::1231]:443", @@ -469,11 +466,11 @@ TEST_F(AddressSortingTest, {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}}, {"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[fec0::1234]:443", AF_INET6}, {"[fc00::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fc00::5001]:443", "[fec0::1234]:443", @@ -494,11 +491,11 @@ TEST_F( {"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}}, {"[1234::2]:443", {"[1234::3]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[::ffff:1.1.1.2]:443", AF_INET6}, {"[1234::2]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { // ::ffff:0:2 should match the v4-mapped // precedence entry and be deprioritized. @@ -521,11 +518,11 @@ TEST_F(AddressSortingTest, TestPrefersSmallerScope) { {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}}, {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"[fec0::1234]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fec0::1234]:443", "[3ffe::5001]:443", @@ -546,11 +543,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) { {"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}}, {"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:5001::]:443", AF_INET6}, {"[3ffe:1234::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:1234::]:443", "[3ffe:5001::]:443", @@ -567,11 +564,11 @@ TEST_F(AddressSortingTest, {"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}}, {"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1234]:443", "[3ffe::5001]:443", @@ -587,11 +584,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) { {"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}}, {"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:8000::]:443", AF_INET6}, {"[3ffe:2000::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:2000::]:443", "[3ffe:8000::]:443", @@ -607,11 +604,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) { {"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}}, {"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:6::]:443", AF_INET6}, {"[3ffe:c::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:c::]:443", "[3ffe:6::]:443", @@ -629,11 +626,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) { {"[3ffe:1111:1111:1110::]:443", {"[3ffe:1111:1111:1111::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:1111:1111:1110::]:443", AF_INET6}, {"[3ffe:1111:1111:1111::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:1111:1111:1111::]:443", "[3ffe:1111:1111:1110::]:443", @@ -651,11 +648,11 @@ TEST_F(AddressSortingTest, TestStableSort) { {"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}}, {"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1234]:443", "[3ffe::1235]:443", @@ -674,14 +671,14 @@ TEST_F(AddressSortingTest, TestStableSortFiveElements) { {"[3ffe::1234]:443", {"[3ffe::1204]:0", AF_INET6}}, {"[3ffe::1235]:443", {"[3ffe::1205]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::1231]:443", AF_INET6}, {"[3ffe::1232]:443", AF_INET6}, {"[3ffe::1233]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1231]:443", "[3ffe::1232]:443", @@ -695,14 +692,14 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) { bool ipv4_supported = true; bool ipv6_supported = true; OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {}); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::1231]:443", AF_INET6}, {"[3ffe::1232]:443", AF_INET6}, {"[3ffe::1233]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1231]:443", "[3ffe::1232]:443", @@ -716,11 +713,11 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) { bool ipv4_supported = true; bool ipv6_supported = true; OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {}); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[::ffff:5.6.7.8]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::ffff:5.6.7.8]:443", "1.2.3.4:443", @@ -744,11 +741,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) { {"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}}, {v4_compat_dest, {v4_compat_src, AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[fec0::2000]:443", AF_INET6}, {v4_compat_dest, AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { // The sort should be stable since @@ -765,11 +762,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) { * (whether ipv4 loopback is available or not, an available ipv6 * loopback should be preferred). */ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) { - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[::1]:443", AF_INET6}, {"127.0.0.1:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", "127.0.0.1:443", @@ -779,11 +776,11 @@ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) { /* Flip the order of the inputs above and expect the same output order * (try to rule out influence of arbitrary qsort ordering) */ TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) { - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"127.0.0.1:443", AF_INET}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", "127.0.0.1:443", diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index fe6fcb8d9cb..2ac2c237cea 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -41,6 +41,7 @@ #include "src/core/ext/filters/client_channel/resolver.h" #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/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" @@ -382,23 +383,19 @@ 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; - const grpc_arg* channel_arg = - grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES); - GPR_ASSERT(channel_arg != nullptr); - GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER); - grpc_lb_addresses* addresses = - (grpc_lb_addresses*)channel_arg->value.pointer.p; + grpc_core::ServerAddressList* addresses = + grpc_core::FindServerAddressListChannelArg(channel_args); gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR, - addresses->num_addresses, args->expected_addrs.size()); - GPR_ASSERT(addresses->num_addresses == args->expected_addrs.size()); + 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->num_addresses; i++) { - grpc_lb_address addr = addresses->addresses[i]; + 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 */); + 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.is_balancer)); + GrpcLBAddress(std::string(str), addr.IsBalancer())); gpr_free(str); } if (args->expected_addrs.size() != found_lb_addrs.size()) { diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index dd5bead58ca..5011e19b03a 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -923,7 +923,6 @@ 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.cc \ 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 \ @@ -959,6 +958,8 @@ 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/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_index.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a7231554e3d..c8a70f17c8d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10068,6 +10068,7 @@ "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/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" ], @@ -10095,7 +10096,6 @@ "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_factory.cc", "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", @@ -10114,6 +10114,8 @@ "src/core/ext/filters/client_channel/resolver_result_parsing.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_index.cc", From bd5d86935f6fdefd22e12eab5c64e7cb1ba7d7bc Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 7 Dec 2018 14:05:48 -0800 Subject: [PATCH 0493/2143] revert the sample --- src/core/lib/surface/init.cc | 2 -- src/core/lib/surface/init.h | 1 - test/core/util/test_config.cc | 3 +-- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 53e3db055dc..67cf5d89bff 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -195,5 +195,3 @@ int grpc_is_initialized(void) { gpr_mu_unlock(&g_init_mu); return r; } - -void grpc_test_x(void) { gpr_log(GPR_ERROR, "X"); } diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h index 2b3e6a64e78..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_test_x(void); #endif /* GRPC_CORE_LIB_SURFACE_INIT_H */ diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index 5db409343b8..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_test_x(); } +TestEnvironment::~TestEnvironment() {} } // namespace testing } // namespace grpc From 7b81ae14a7c347f4971c319a93ba0690fe119ce9 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 7 Dec 2018 14:59:04 -0800 Subject: [PATCH 0494/2143] clang tidy and clang format --- .../transport/chttp2/server/insecure/server_chttp2_posix.cc | 2 +- src/core/ext/transport/inproc/inproc_transport.cc | 2 +- src/core/lib/surface/server.cc | 4 +++- test/core/bad_client/bad_client.cc | 2 +- test/core/end2end/fixtures/h2_sockpair+trace.cc | 2 +- test/core/end2end/fixtures/h2_sockpair.cc | 2 +- test/core/end2end/fixtures/h2_sockpair_1byte.cc | 2 +- test/core/end2end/fuzzers/api_fuzzer.cc | 2 +- test/core/end2end/fuzzers/server_fuzzer.cc | 2 +- test/cpp/end2end/client_interceptors_end2end_test.cc | 5 +++++ test/cpp/end2end/interceptors_util.cc | 1 + test/cpp/microbenchmarks/fullstack_fixtures.h | 2 +- test/cpp/performance/writes_per_rpc_test.cc | 2 +- 13 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc index b9024a87e24..c29c1e58cd9 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc @@ -61,7 +61,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server, grpc_endpoint_add_to_pollset(server_endpoint, pollsets[i]); } - grpc_server_setup_transport(server, transport, nullptr, server_args, 0); + grpc_server_setup_transport(server, transport, nullptr, server_args, nullptr); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); } diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index 61968de4d58..0b9bf5dd11b 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -1236,7 +1236,7 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server, // TODO(ncteisen): design and support channelz GetSocket for inproc. grpc_server_setup_transport(server, server_transport, nullptr, server_args, - 0); + nullptr); grpc_channel* channel = grpc_channel_create( "inproc", client_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 5f7f630d16d..67b38e6f0c0 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -28,6 +28,8 @@ #include #include +#include + #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/debug/stats.h" @@ -1181,7 +1183,7 @@ void grpc_server_setup_transport( chand->server = s; server_ref(s); chand->channel = channel; - chand->socket_node = socket_node; + chand->socket_node = std::move(socket_node); size_t cq_idx; for (cq_idx = 0; cq_idx < s->cq_count; cq_idx++) { diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc index 4f5d2a2862b..ae1e42a4e0d 100644 --- a/test/core/bad_client/bad_client.cc +++ b/test/core/bad_client/bad_client.cc @@ -66,7 +66,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) { thd_args* a = static_cast(ts); grpc_core::ExecCtx exec_ctx; grpc_server_setup_transport(a->server, transport, nullptr, - grpc_server_get_channel_args(a->server), 0); + grpc_server_get_channel_args(a->server), nullptr); } /* Sets the read_done event */ diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc index 4f393b22d05..45f78b59642 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.cc +++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc @@ -53,7 +53,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) { grpc_endpoint_pair* sfd = static_cast(f->fixture_data); grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq)); grpc_server_setup_transport(f->server, transport, nullptr, - grpc_server_get_channel_args(f->server), 0); + grpc_server_get_channel_args(f->server), nullptr); } typedef struct { diff --git a/test/core/end2end/fixtures/h2_sockpair.cc b/test/core/end2end/fixtures/h2_sockpair.cc index 1627fe0eb49..77bce7ebb30 100644 --- a/test/core/end2end/fixtures/h2_sockpair.cc +++ b/test/core/end2end/fixtures/h2_sockpair.cc @@ -47,7 +47,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) { grpc_endpoint_pair* sfd = static_cast(f->fixture_data); grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq)); grpc_server_setup_transport(f->server, transport, nullptr, - grpc_server_get_channel_args(f->server), 0); + grpc_server_get_channel_args(f->server), nullptr); } typedef struct { diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.cc b/test/core/end2end/fixtures/h2_sockpair_1byte.cc index 8f1024b774d..ac37841dc48 100644 --- a/test/core/end2end/fixtures/h2_sockpair_1byte.cc +++ b/test/core/end2end/fixtures/h2_sockpair_1byte.cc @@ -47,7 +47,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) { grpc_endpoint_pair* sfd = static_cast(f->fixture_data); grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq)); grpc_server_setup_transport(f->server, transport, nullptr, - grpc_server_get_channel_args(f->server), 0); + grpc_server_get_channel_args(f->server), nullptr); } typedef struct { diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index 9b6eddee6e1..a3de56d4f9f 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -420,7 +420,7 @@ static void do_connect(void* arg, grpc_error* error) { grpc_transport* transport = grpc_create_chttp2_transport(nullptr, server, false); - grpc_server_setup_transport(g_server, transport, nullptr, nullptr, 0); + grpc_server_setup_transport(g_server, transport, nullptr, nullptr, nullptr); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); GRPC_CLOSURE_SCHED(fc->closure, GRPC_ERROR_NONE); diff --git a/test/core/end2end/fuzzers/server_fuzzer.cc b/test/core/end2end/fuzzers/server_fuzzer.cc index bd686215ddb..d370dc7de85 100644 --- a/test/core/end2end/fuzzers/server_fuzzer.cc +++ b/test/core/end2end/fuzzers/server_fuzzer.cc @@ -62,7 +62,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_server_start(server); grpc_transport* transport = grpc_create_chttp2_transport(nullptr, mock_endpoint, false); - grpc_server_setup_transport(server, transport, nullptr, nullptr, 0); + grpc_server_setup_transport(server, transport, nullptr, nullptr, nullptr); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); grpc_call* call1 = nullptr; diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 3a191d1e038..e11b2aa67f6 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -383,6 +383,7 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingTest) { std::vector> creators; // Add 20 dummy interceptors before hijacking interceptor + creators.reserve(20); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); @@ -423,6 +424,7 @@ TEST_F(ClientInterceptorsEnd2endTest, std::vector> creators; // Add 5 dummy interceptors before hijacking interceptor + creators.reserve(5); for (auto i = 0; i < 5; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); @@ -570,6 +572,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, DummyGlobalInterceptor) { std::vector> creators; // Add 20 dummy interceptors + creators.reserve(20); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); @@ -595,6 +598,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) { std::vector> creators; // Add 20 dummy interceptors + creators.reserve(20); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); @@ -620,6 +624,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) { std::vector> creators; // Add 20 dummy interceptors + creators.reserve(20); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); diff --git a/test/cpp/end2end/interceptors_util.cc b/test/cpp/end2end/interceptors_util.cc index 5d59c1a4b72..e0ad7d1526c 100644 --- a/test/cpp/end2end/interceptors_util.cc +++ b/test/cpp/end2end/interceptors_util.cc @@ -137,6 +137,7 @@ CreateDummyClientInterceptors() { std::vector> creators; // Add 20 dummy interceptors before hijacking interceptor + creators.reserve(20); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index 71e8d9972bf..6bbf553bbd8 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -200,7 +200,7 @@ class EndpointPairFixture : public BaseFixture { } grpc_server_setup_transport(server_->c_server(), server_transport_, - nullptr, server_args, 0); + nullptr, server_args, nullptr); grpc_chttp2_transport_start_reading(server_transport_, nullptr, nullptr); } diff --git a/test/cpp/performance/writes_per_rpc_test.cc b/test/cpp/performance/writes_per_rpc_test.cc index 3c5b3468848..7b22f23cf00 100644 --- a/test/cpp/performance/writes_per_rpc_test.cc +++ b/test/cpp/performance/writes_per_rpc_test.cc @@ -100,7 +100,7 @@ class EndpointPairFixture { } grpc_server_setup_transport(server_->c_server(), transport, nullptr, - server_args, 0); + server_args, nullptr); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); } From df21aab3a6af360cff29a5164f9728ba646d35ab Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Dec 2018 16:01:23 -0800 Subject: [PATCH 0495/2143] nullability annotation --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/ProtoRPC/ProtoRPC.h | 18 ++++++------- src/objective-c/ProtoRPC/ProtoRPC.m | 3 +++ src/objective-c/ProtoRPC/ProtoService.h | 34 ++++++++++++++----------- src/objective-c/ProtoRPC/ProtoService.m | 7 ++--- src/objective-c/tests/GRPCClientTests.m | 3 ++- 6 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 18f79311a69..cfd0de1a8a2 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -485,7 +485,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. - NSAssert(host != nil && path != nil, @"Neither host nor path can be nil."); + NSAssert(host.length != 0 && path.length != 0, @"Neither host nor path can be nil."); NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); NSAssert(requestWriter.state == GRXWriterStateNotStarted, @"The requests writer can't be already started."); diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 2e0400a323f..e6ba1f66ca5 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -70,11 +70,11 @@ NS_ASSUME_NONNULL_BEGIN * Users should not use this initializer directly. Call objects will be created, initialized, and * returned to users by methods of the generated service. */ -- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - message:(GPBMessage *)message - responseHandler:(id)handler - callOptions:(nullable GRPCCallOptions *)callOptions - responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + message:(GPBMessage *)message + responseHandler:(id)handler + callOptions:(nullable GRPCCallOptions *)callOptions + responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** * Start the call. This function must only be called once for each instance. @@ -101,10 +101,10 @@ NS_ASSUME_NONNULL_BEGIN * Users should not use this initializer directly. Call objects will be created, initialized, and * returned to users by methods of the generated service. */ -- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - responseHandler:(id)handler - callOptions:(nullable GRPCCallOptions *)callOptions - responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + responseHandler:(id)handler + callOptions:(nullable GRPCCallOptions *)callOptions + responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; /** * Start the call. This function must only be called once for each instance. diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 92d7fce33cc..15b0f681ce3 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -57,6 +57,9 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing responseClass:(Class)responseClass { NSAssert(message != nil, @"message cannot be empty."); NSAssert(responseClass != nil, @"responseClass cannot be empty."); + if (message == nil || responseClass == nil) { + return nil; + } if ((self = [super init])) { _call = [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions responseHandler:handler diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index 2105de78a38..70423ee9def 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -27,33 +27,35 @@ @class GRPCStreamingProtoCall; @protocol GRPCProtoResponseCallbacks; +NS_ASSUME_NONNULL_BEGIN + __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoService : NSObject - - (instancetype)initWithHost : (NSString *)host packageName + (nullable instancetype)initWithHost : (NSString *)host packageName : (NSString *)packageName serviceName : (NSString *)serviceName callOptions - : (GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; + : (nullable GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName serviceName:(NSString *)serviceName; -- (GRPCProtoCall *)RPCToMethod:(NSString *)method - requestsWriter:(GRXWriter *)requestsWriter - responseClass:(Class)responseClass - responsesWriteable:(id)responsesWriteable; +- (nullable GRPCProtoCall *)RPCToMethod:(NSString *)method + requestsWriter:(GRXWriter *)requestsWriter + responseClass:(Class)responseClass + responsesWriteable:(id)responsesWriteable; -- (GRPCUnaryProtoCall *)RPCToMethod:(NSString *)method - message:(id)message - responseHandler:(id)handler - callOptions:(GRPCCallOptions *)callOptions - responseClass:(Class)responseClass; +- (nullable GRPCUnaryProtoCall *)RPCToMethod:(NSString *)method + message:(id)message + responseHandler:(id)handler + callOptions:(nullable GRPCCallOptions *)callOptions + responseClass:(Class)responseClass; -- (GRPCStreamingProtoCall *)RPCToMethod:(NSString *)method - responseHandler:(id)handler - callOptions:(GRPCCallOptions *)callOptions - responseClass:(Class)responseClass; +- (nullable GRPCStreamingProtoCall *)RPCToMethod:(NSString *)method + responseHandler:(id)handler + callOptions:(nullable GRPCCallOptions *)callOptions + responseClass:(Class)responseClass; @end @@ -67,3 +69,5 @@ __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoServ #pragma clang diagnostic pop @end + + NS_ASSUME_NONNULL_END diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m index 6df502fb0c0..3d998bfaeb8 100644 --- a/src/objective-c/ProtoRPC/ProtoService.m +++ b/src/objective-c/ProtoRPC/ProtoService.m @@ -44,9 +44,10 @@ packageName:(NSString *)packageName serviceName:(NSString *)serviceName callOptions:(GRPCCallOptions *)callOptions { - if (!host || !serviceName) { - [NSException raise:NSInvalidArgumentException - format:@"Neither host nor serviceName can be nil."]; + NSAssert(host.length != 0 && packageName.length != 0 && serviceName.length != 0, + @"Invalid parameter."); + if (host.length == 0 || packageName.length == 0 || serviceName.length == 0) { + return nil; } if ((self = [super init])) { _host = [host copy]; diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 2cfdd1a003b..b16720557f7 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -362,9 +362,10 @@ static GRPCProtoMethod *kFullDuplexCallMethod; // TODO(makarandd): Move to a different file that contains only unit tests - (void)testExceptions { + GRXWriter *writer = [GRXWriter writerWithValue:[NSData data]]; // Try to set parameters to nil for GRPCCall. This should cause an exception @try { - (void)[[GRPCCall alloc] initWithHost:nil path:nil requestsWriter:nil]; + (void)[[GRPCCall alloc] initWithHost:@"" path:@"" requestsWriter:writer]; XCTFail(@"Did not receive an exception when parameters are nil"); } @catch (NSException *theException) { NSLog(@"Received exception as expected: %@", theException.name); From 3f00d61b04874cc5f0159c16f2c598a8f2fb93a7 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Dec 2018 16:12:00 -0800 Subject: [PATCH 0496/2143] batch fix --- .../GRPCClient/private/GRPCWrappedCall.m | 1 + src/objective-c/ProtoRPC/ProtoRPC.m | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 9066cb950f4..4edd9d3e378 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -320,6 +320,7 @@ _call = NULL; } } + // Explicitly converting weak reference _pooledChannel to strong. __strong GRPCPooledChannel *channel = _pooledChannel; [channel notifyWrappedCallDealloc:self]; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 15b0f681ce3..abf224c3cfd 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -140,7 +140,11 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)start { - [_call start]; + GRPCCall2 *copiedCall; + @synchronized(self) { + copiedCall = _call; + } + [copiedCall start]; } - (void)cancel { @@ -177,20 +181,20 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing return; } - GRPCCall2 *call; + GRPCCall2 *copiedCall; @synchronized(self) { - call = _call; + copiedCall = _call; } - [call writeData:[message data]]; + [copiedCall writeData:[message data]]; } - (void)finish { - GRPCCall2 *call; + GRPCCall2 *copiedCall; @synchronized(self) { - call = _call; + copiedCall = _call; _call = nil; } - [call finish]; + [copiedCall finish]; } - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { From 27e2ba31bffa1c27fe12ad7d55e70b450eb777a8 Mon Sep 17 00:00:00 2001 From: hcaseyal Date: Fri, 7 Dec 2018 16:13:37 -0800 Subject: [PATCH 0497/2143] Revert "Allow encoding arbitrary channel args on a per-address basis." --- BUILD | 3 +- CMakeLists.txt | 12 +- Makefile | 12 +- build.yaml | 3 +- config.m4 | 2 +- config.w32 | 2 +- gRPC-C++.podspec | 1 - gRPC-Core.podspec | 4 +- grpc.gemspec | 3 +- grpc.gyp | 8 +- package.xml | 3 +- .../filters/client_channel/client_channel.cc | 16 +- .../ext/filters/client_channel/lb_policy.h | 9 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 242 ++++++++++------- .../lb_policy/grpclb/grpclb_channel.h | 2 +- .../lb_policy/grpclb/grpclb_channel_secure.cc | 33 ++- .../lb_policy/grpclb/load_balancer_api.h | 2 +- .../lb_policy/pick_first/pick_first.cc | 19 +- .../lb_policy/round_robin/round_robin.cc | 40 ++- .../lb_policy/subchannel_list.h | 53 ++-- .../client_channel/lb_policy/xds/xds.cc | 249 +++++++++++++----- .../lb_policy/xds/xds_channel.h | 2 +- .../lb_policy/xds/xds_channel_secure.cc | 33 ++- .../lb_policy/xds/xds_load_balancer_api.h | 2 +- .../client_channel/lb_policy_factory.cc | 163 ++++++++++++ .../client_channel/lb_policy_factory.h | 86 +++++- .../resolver/dns/c_ares/dns_resolver_ares.cc | 12 +- .../dns/c_ares/grpc_ares_ev_driver.cc | 1 - .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 149 ++++++----- .../resolver/dns/c_ares/grpc_ares_wrapper.h | 13 +- .../dns/c_ares/grpc_ares_wrapper_fallback.cc | 9 +- .../dns/c_ares/grpc_ares_wrapper_posix.cc | 3 +- .../dns/c_ares/grpc_ares_wrapper_windows.cc | 26 +- .../resolver/dns/native/dns_resolver.cc | 14 +- .../resolver/fake/fake_resolver.cc | 3 +- .../resolver/fake/fake_resolver.h | 3 +- .../resolver/sockaddr/sockaddr_resolver.cc | 34 +-- .../client_channel/resolver_result_parsing.cc | 20 +- .../filters/client_channel/server_address.cc | 103 -------- .../filters/client_channel/server_address.h | 108 -------- .../ext/filters/client_channel/subchannel.cc | 6 +- .../ext/filters/client_channel/subchannel.h | 13 +- src/core/lib/iomgr/sockaddr_utils.cc | 1 - src/python/grpcio/grpc_core_dependencies.py | 2 +- .../dns_resolver_connectivity_test.cc | 12 +- .../resolvers/dns_resolver_cooldown_test.cc | 15 +- .../resolvers/fake_resolver_test.cc | 42 ++- test/core/end2end/fuzzers/api_fuzzer.cc | 28 +- test/core/end2end/goaway_server_test.cc | 29 +- test/core/end2end/no_server_test.cc | 1 - test/core/util/ubsan_suppressions.txt | 3 +- test/cpp/client/client_channel_stress_test.cc | 28 +- test/cpp/end2end/client_lb_end2end_test.cc | 18 +- test/cpp/end2end/grpclb_end2end_test.cc | 37 +-- test/cpp/naming/address_sorting_test.cc | 127 ++++----- test/cpp/naming/resolver_component_test.cc | 21 +- tools/doxygen/Doxyfile.core.internal | 3 +- .../generated/sources_and_headers.json | 4 +- 58 files changed, 1045 insertions(+), 847 deletions(-) create mode 100644 src/core/ext/filters/client_channel/lb_policy_factory.cc delete mode 100644 src/core/ext/filters/client_channel/server_address.cc delete mode 100644 src/core/ext/filters/client_channel/server_address.h diff --git a/BUILD b/BUILD index 5550e583a87..9e3e594038d 100644 --- a/BUILD +++ b/BUILD @@ -1048,6 +1048,7 @@ grpc_cc_library( "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_factory.cc", "src/core/ext/filters/client_channel/lb_policy_registry.cc", "src/core/ext/filters/client_channel/parse_address.cc", "src/core/ext/filters/client_channel/proxy_mapper.cc", @@ -1056,7 +1057,6 @@ grpc_cc_library( "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/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", ], @@ -1080,7 +1080,6 @@ grpc_cc_library( "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/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", ], diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c660c77012..6b02d778d1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1240,6 +1240,7 @@ add_library(grpc 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -1248,7 +1249,6 @@ add_library(grpc 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/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/deadline/deadline_filter.cc @@ -1592,6 +1592,7 @@ add_library(grpc_cronet 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -1600,7 +1601,6 @@ add_library(grpc_cronet 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/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/deadline/deadline_filter.cc @@ -1963,6 +1963,7 @@ add_library(grpc_test_util 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -1971,7 +1972,6 @@ add_library(grpc_test_util 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/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/deadline/deadline_filter.cc @@ -2283,6 +2283,7 @@ add_library(grpc_test_util_unsecure 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -2291,7 +2292,6 @@ add_library(grpc_test_util_unsecure 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/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/deadline/deadline_filter.cc @@ -2617,6 +2617,7 @@ add_library(grpc_unsecure 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -2625,7 +2626,6 @@ add_library(grpc_unsecure 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/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/deadline/deadline_filter.cc @@ -3469,6 +3469,7 @@ add_library(grpc++_cronet 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -3477,7 +3478,6 @@ add_library(grpc++_cronet 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/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/deadline/deadline_filter.cc diff --git a/Makefile b/Makefile index 0163dc414a5..ed4e219f8b7 100644 --- a/Makefile +++ b/Makefile @@ -3735,6 +3735,7 @@ LIBGRPC_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -3743,7 +3744,6 @@ LIBGRPC_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -4081,6 +4081,7 @@ LIBGRPC_CRONET_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -4089,7 +4090,6 @@ LIBGRPC_CRONET_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -4445,6 +4445,7 @@ LIBGRPC_TEST_UTIL_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -4453,7 +4454,6 @@ LIBGRPC_TEST_UTIL_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -4751,6 +4751,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -4759,7 +4760,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -5058,6 +5058,7 @@ LIBGRPC_UNSECURE_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -5066,7 +5067,6 @@ LIBGRPC_UNSECURE_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -5885,6 +5885,7 @@ LIBGRPC++_CRONET_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -5893,7 +5894,6 @@ LIBGRPC++_CRONET_SRC = \ 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/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/deadline/deadline_filter.cc \ diff --git a/build.yaml b/build.yaml index 4521169e6c1..af70be8459a 100644 --- a/build.yaml +++ b/build.yaml @@ -589,7 +589,6 @@ filegroups: - 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/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: @@ -604,6 +603,7 @@ filegroups: - 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_factory.cc - src/core/ext/filters/client_channel/lb_policy_registry.cc - src/core/ext/filters/client_channel/parse_address.cc - src/core/ext/filters/client_channel/proxy_mapper.cc @@ -612,7 +612,6 @@ filegroups: - 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/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 plugin: grpc_client_channel diff --git a/config.m4 b/config.m4 index 16de5204bb2..3db660aceea 100644 --- a/config.m4 +++ b/config.m4 @@ -348,6 +348,7 @@ if test "$PHP_GRPC" != "no"; then 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -356,7 +357,6 @@ if test "$PHP_GRPC" != "no"; then 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/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/deadline/deadline_filter.cc \ diff --git a/config.w32 b/config.w32 index be10faab9cd..7f8b6eee5fa 100644 --- a/config.w32 +++ b/config.w32 @@ -323,6 +323,7 @@ if (PHP_GRPC != "no") { "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_factory.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy_registry.cc " + "src\\core\\ext\\filters\\client_channel\\parse_address.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " + @@ -331,7 +332,6 @@ if (PHP_GRPC != "no") { "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\\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\\deadline\\deadline_filter.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 30fcb51ee19..e939bead1b7 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -356,7 +356,6 @@ Pod::Spec.new do |s| '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/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/deadline/deadline_filter.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 5ab7a49cd27..1d4e1ae35c0 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -354,7 +354,6 @@ Pod::Spec.new do |s| '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/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/deadline/deadline_filter.h', @@ -787,6 +786,7 @@ Pod::Spec.new do |s| '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -795,7 +795,6 @@ Pod::Spec.new do |s| '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/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/deadline/deadline_filter.cc', @@ -975,7 +974,6 @@ Pod::Spec.new do |s| '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/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/deadline/deadline_filter.h', diff --git a/grpc.gemspec b/grpc.gemspec index 1ee7bec8e7d..92b1e0be689 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -290,7 +290,6 @@ Gem::Specification.new do |s| 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/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/deadline/deadline_filter.h ) @@ -726,6 +725,7 @@ Gem::Specification.new do |s| 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_factory.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.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 ) @@ -734,7 +734,6 @@ Gem::Specification.new do |s| 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/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/deadline/deadline_filter.cc ) diff --git a/grpc.gyp b/grpc.gyp index 00f06a1e54e..564922ff727 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -540,6 +540,7 @@ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -548,7 +549,6 @@ '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/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/deadline/deadline_filter.cc', @@ -799,6 +799,7 @@ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -807,7 +808,6 @@ '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/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/deadline/deadline_filter.cc', @@ -1039,6 +1039,7 @@ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -1047,7 +1048,6 @@ '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/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/deadline/deadline_filter.cc', @@ -1292,6 +1292,7 @@ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -1300,7 +1301,6 @@ '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/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/deadline/deadline_filter.cc', diff --git a/package.xml b/package.xml index 68fc7433cb4..bdcb12bfc5e 100644 --- a/package.xml +++ b/package.xml @@ -295,7 +295,6 @@ - @@ -731,6 +730,7 @@ + @@ -739,7 +739,6 @@ - diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 70aac472314..ebc412b468d 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -38,7 +38,6 @@ #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/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" @@ -63,7 +62,6 @@ #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_metadata.h" -using grpc_core::ServerAddressList; using grpc_core::internal::ClientChannelMethodParams; using grpc_core::internal::ClientChannelMethodParamsTable; using grpc_core::internal::ProcessedResolverResult; @@ -385,10 +383,16 @@ static void create_new_lb_policy_locked( static void maybe_add_trace_message_for_address_changes_locked( channel_data* chand, TraceStringVector* trace_strings) { - const ServerAddressList* addresses = - grpc_core::FindServerAddressListChannelArg(chand->resolver_result); - const bool resolution_contains_addresses = - addresses != nullptr && addresses->size() > 0; + int resolution_contains_addresses = false; + const grpc_arg* channel_arg = + grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES); + if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) { + grpc_lb_addresses* addresses = + static_cast(channel_arg->value.pointer.p); + if (addresses->num_addresses > 0) { + resolution_contains_addresses = true; + } + } if (!resolution_contains_addresses && chand->previous_resolution_contained_addresses) { trace_strings->push_back(gpr_strdup("Address list became empty")); diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 6b76fe5d5d7..7034da6249c 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 { grpc_client_channel_factory* client_channel_factory = nullptr; /// 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_ARG_LB_ADDRESSES channel arg. grpc_channel_args* args = nullptr; /// Load balancing config from the resolver. grpc_json* lb_config = nullptr; @@ -80,6 +80,11 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Will be populated with context to pass to the subchannel call, if /// needed. grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {}; + /// Upon success, \a *user_data will be set to whatever opaque information + /// may need to be propagated from the LB policy, or nullptr if not needed. + // TODO(roth): As part of revamping our metadata APIs, try to find a + // way to clean this up and C++-ify it. + void** user_data = nullptr; /// Next pointer. For internal use by LB policy. PickState* next = nullptr; }; @@ -90,7 +95,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// 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 - /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. + /// GRPC_ARG_LB_ADDRESSES channel arg. virtual void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) GRPC_ABSTRACT; 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 a9a5965ed1c..a46579c7f74 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 @@ -84,7 +84,6 @@ #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" @@ -114,8 +113,6 @@ #define GRPC_GRPCLB_RECONNECT_JITTER 0.2 #define GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS 10000 -#define GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN "grpc.grpclb_address_lb_token" - namespace grpc_core { TraceFlag grpc_lb_glb_trace(false, "glb"); @@ -124,7 +121,7 @@ namespace { class GrpcLb : public LoadBalancingPolicy { public: - explicit GrpcLb(const Args& args); + GrpcLb(const grpc_lb_addresses* addresses, const Args& args); void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; @@ -164,6 +161,9 @@ class GrpcLb : public LoadBalancingPolicy { // Our on_complete closure and the original one. grpc_closure on_complete; grpc_closure* original_on_complete; + // The LB token associated with the pick. This is set via user_data in + // the pick. + grpc_mdelem lb_token; // Stats for client-side load reporting. RefCountedPtr client_stats; // Next pending pick. @@ -329,7 +329,7 @@ class GrpcLb : public LoadBalancingPolicy { // 0 means not using fallback. int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. - UniquePtr fallback_backend_addresses_; + grpc_lb_addresses* fallback_backend_addresses_ = nullptr; // Fallback timer. bool fallback_timer_callback_pending_ = false; grpc_timer lb_fallback_timer_; @@ -349,7 +349,7 @@ class GrpcLb : public LoadBalancingPolicy { // serverlist parsing code // -// vtable for LB token channel arg. +// vtable for LB tokens in grpc_lb_addresses void* lb_token_copy(void* token) { return token == nullptr ? nullptr @@ -361,11 +361,38 @@ void lb_token_destroy(void* token) { } } int lb_token_cmp(void* token1, void* token2) { - return GPR_ICMP(token1, token2); + if (token1 > token2) return 1; + if (token1 < token2) return -1; + return 0; } -const grpc_arg_pointer_vtable lb_token_arg_vtable = { +const grpc_lb_user_data_vtable lb_token_vtable = { lb_token_copy, lb_token_destroy, lb_token_cmp}; +// Returns the backend addresses extracted from the given addresses. +grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) { + // First pass: count the number of backend addresses. + size_t num_backends = 0; + for (size_t i = 0; i < addresses->num_addresses; ++i) { + if (!addresses->addresses[i].is_balancer) { + ++num_backends; + } + } + // Second pass: actually populate the addresses and (empty) LB tokens. + grpc_lb_addresses* backend_addresses = + grpc_lb_addresses_create(num_backends, &lb_token_vtable); + size_t num_copied = 0; + for (size_t i = 0; i < addresses->num_addresses; ++i) { + if (addresses->addresses[i].is_balancer) continue; + const grpc_resolved_address* addr = &addresses->addresses[i].address; + grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr, + addr->len, false /* is_balancer */, + nullptr /* balancer_name */, + (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload); + ++num_copied; + } + return backend_addresses; +} + bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) { if (server->drop) return false; const grpc_grpclb_ip_address* ip = &server->ip_address; @@ -413,16 +440,30 @@ void ParseServer(const grpc_grpclb_server* server, } // Returns addresses extracted from \a serverlist. -ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { - ServerAddressList addresses; +grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { + size_t num_valid = 0; + /* first pass: count how many are valid in order to allocate the necessary + * memory in a single block */ 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. + if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid; + } + grpc_lb_addresses* lb_addresses = + grpc_lb_addresses_create(num_valid, &lb_token_vtable); + /* second pass: actually populate the addresses and LB tokens (aka user data + * to the outside world) to be read by the RR policy during its creation. + * Given that the validity tests are very cheap, they are performed again + * instead of marking the valid ones during the first pass, as this would + * incurr in an allocation due to the arbitrary number of server */ + size_t addr_idx = 0; + for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) { + const grpc_grpclb_server* server = serverlist->servers[sl_idx]; + if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue; + GPR_ASSERT(addr_idx < num_valid); + /* address processing */ grpc_resolved_address addr; ParseServer(server, &addr); - // LB token processing. - void* lb_token; + /* lb token processing */ + void* user_data; if (server->has_load_balance_token) { const size_t lb_token_max_length = GPR_ARRAY_SIZE(server->load_balance_token); @@ -430,7 +471,7 @@ ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { strnlen(server->load_balance_token, lb_token_max_length); grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer( server->load_balance_token, lb_token_length); - lb_token = + user_data = (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr) .payload; } else { @@ -440,16 +481,15 @@ ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { "be used instead", uri); gpr_free(uri); - lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; + user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; } - // Add address. - grpc_arg arg = grpc_channel_arg_pointer_create( - const_cast(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token, - &lb_token_arg_vtable); - grpc_channel_args* args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); - addresses.emplace_back(addr, args); + grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len, + false /* is_balancer */, + nullptr /* balancer_name */, user_data); + ++addr_idx; } - return addresses; + GPR_ASSERT(addr_idx == num_valid); + return lb_addresses; } // @@ -789,7 +829,8 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_); } else { // Dispose of the fallback. - grpclb_policy->fallback_backend_addresses_.reset(); + grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_); + grpclb_policy->fallback_backend_addresses_ = nullptr; if (grpclb_policy->fallback_timer_callback_pending_) { grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_); } @@ -869,25 +910,31 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( // helper code for creating balancer channel // -ServerAddressList ExtractBalancerAddresses(const ServerAddressList& addresses) { - ServerAddressList balancer_addresses; - for (size_t i = 0; i < addresses.size(); ++i) { - if (addresses[i].IsBalancer()) { - // Strip out the is_balancer channel arg, since we don't want to - // recursively use the grpclb policy in the channel used to talk to - // the balancers. Note that we do NOT strip out the balancer_name - // channel arg, since we need that to set the authority correctly - // to talk to the balancers. - static const char* args_to_remove[] = { - GRPC_ARG_ADDRESS_IS_BALANCER, - }; - balancer_addresses.emplace_back( - addresses[i].address(), - grpc_channel_args_copy_and_remove(addresses[i].args(), args_to_remove, - GPR_ARRAY_SIZE(args_to_remove))); - } +grpc_lb_addresses* ExtractBalancerAddresses( + const grpc_lb_addresses* addresses) { + size_t num_grpclb_addrs = 0; + for (size_t i = 0; i < addresses->num_addresses; ++i) { + if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; } - return balancer_addresses; + // There must be at least one balancer address, or else the + // client_channel would not have chosen this LB policy. + GPR_ASSERT(num_grpclb_addrs > 0); + grpc_lb_addresses* lb_addresses = + grpc_lb_addresses_create(num_grpclb_addrs, nullptr); + size_t lb_addresses_idx = 0; + for (size_t i = 0; i < addresses->num_addresses; ++i) { + if (!addresses->addresses[i].is_balancer) continue; + if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) { + gpr_log(GPR_ERROR, + "This LB policy doesn't support user data. It will be ignored"); + } + grpc_lb_addresses_set_address( + lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr, + addresses->addresses[i].address.len, false /* is balancer */, + addresses->addresses[i].balancer_name, nullptr /* user data */); + } + GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx); + return lb_addresses; } /* Returns the channel args for the LB channel, used to create a bidirectional @@ -899,10 +946,10 @@ ServerAddressList ExtractBalancerAddresses(const ServerAddressList& addresses) { * above the grpclb policy. * - \a args: other args inherited from the grpclb policy. */ grpc_channel_args* BuildBalancerChannelArgs( - const ServerAddressList& addresses, + const grpc_lb_addresses* addresses, FakeResolverResponseGenerator* response_generator, const grpc_channel_args* args) { - ServerAddressList balancer_addresses = ExtractBalancerAddresses(addresses); + grpc_lb_addresses* lb_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 @@ -920,7 +967,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // 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. - GRPC_ARG_SERVER_ADDRESS_LIST, + GRPC_ARG_LB_ADDRESSES, // 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. @@ -936,10 +983,10 @@ grpc_channel_args* BuildBalancerChannelArgs( }; // Channel args to add. const grpc_arg args_to_add[] = { - // New address list. + // New LB addresses. // 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), + grpc_lb_addresses_create_channel_arg(lb_addresses), // The fake resolver response generator, which we use to inject // address updates into the LB channel. grpc_core::FakeResolverResponseGenerator::MakeChannelArg( @@ -957,14 +1004,18 @@ 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); + new_args = grpc_lb_policy_grpclb_modify_lb_channel_args(new_args); + // Clean up. + grpc_lb_addresses_destroy(lb_addresses); + return new_args; } // // ctor and dtor // -GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args) +GrpcLb::GrpcLb(const grpc_lb_addresses* addresses, + const LoadBalancingPolicy::Args& args) : LoadBalancingPolicy(args), response_generator_(MakeRefCounted()), lb_call_backoff_( @@ -1021,6 +1072,9 @@ GrpcLb::~GrpcLb() { if (serverlist_ != nullptr) { grpc_grpclb_destroy_serverlist(serverlist_); } + if (fallback_backend_addresses_ != nullptr) { + grpc_lb_addresses_destroy(fallback_backend_addresses_); + } grpc_subchannel_index_unref(); } @@ -1068,6 +1122,7 @@ void GrpcLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { while ((pp = pending_picks_) != nullptr) { pending_picks_ = pp->next; pp->pick->on_complete = pp->original_on_complete; + pp->pick->user_data = nullptr; grpc_error* error = GRPC_ERROR_NONE; if (new_policy->PickLocked(pp->pick, &error)) { // Synchronous return; schedule closure. @@ -1221,27 +1276,9 @@ void GrpcLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, notify); } -// Returns the backend addresses extracted from the given addresses. -UniquePtr 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(); - for (size_t i = 0; i < addresses.size(); ++i) { - if (!addresses[i].IsBalancer()) { - backend_addresses->emplace_back( - addresses[i].address(), - grpc_channel_args_copy_and_add(addresses[i].args(), &arg, 1)); - } - } - return backend_addresses; -} - void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { - const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); - if (addresses == nullptr) { + const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); + if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { // Ignore this update. gpr_log( GPR_ERROR, @@ -1249,8 +1286,13 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { this); return; } + const grpc_lb_addresses* addresses = + static_cast(arg->value.pointer.p); // Update fallback address list. - fallback_backend_addresses_ = ExtractBackendAddresses(*addresses); + if (fallback_backend_addresses_ != nullptr) { + grpc_lb_addresses_destroy(fallback_backend_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}; @@ -1261,7 +1303,7 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { &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); + BuildBalancerChannelArgs(addresses, response_generator_.get(), &args); // Create balancer channel if needed. if (lb_channel_ == nullptr) { char* uri_str; @@ -1467,17 +1509,12 @@ void DestroyClientStats(void* arg) { } 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 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 + * user_data/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), + if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) { + AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token), &pp->pick->lb_token_mdelem_storage, pp->pick->initial_metadata); } else { @@ -1561,10 +1598,12 @@ bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, return true; } } - // Set client_stats. + // Set client_stats and user_data. if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { pp->client_stats = lb_calld_->client_stats()->Ref(); } + GPR_ASSERT(pp->pick->user_data == nullptr); + pp->pick->user_data = (void**)&pp->lb_token; // Pick via the RR policy. bool pick_done = rr_policy_->PickLocked(pp->pick, error); if (pick_done) { @@ -1629,11 +1668,10 @@ void GrpcLb::CreateRoundRobinPolicyLocked(const Args& args) { } grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { - ServerAddressList tmp_addresses; - ServerAddressList* addresses = &tmp_addresses; + grpc_lb_addresses* addresses; bool is_backend_from_grpclb_load_balancer = false; if (serverlist_ != nullptr) { - tmp_addresses = ProcessServerlist(serverlist_); + addresses = ProcessServerlist(serverlist_); is_backend_from_grpclb_load_balancer = true; } else { // If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't @@ -1642,14 +1680,14 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { // 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(); + addresses = grpc_lb_addresses_copy(fallback_backend_addresses_); } GPR_ASSERT(addresses != nullptr); - // Replace the server address list in the channel args that we pass down to + // Replace the LB addresses in the channel args that we pass down to // the subchannel. - static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST}; + static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES}; grpc_arg args_to_add[3] = { - CreateServerAddressListChannelArg(addresses), + grpc_lb_addresses_create_channel_arg(addresses), // A channel arg indicating if the target is a backend inferred from a // grpclb load balancer. grpc_channel_arg_integer_create( @@ -1666,6 +1704,7 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { 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); + grpc_lb_addresses_destroy(addresses); return args; } @@ -1798,18 +1837,19 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { OrphanablePtr CreateLoadBalancingPolicy( const 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; - } + const grpc_arg* arg = + grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES); + if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { + return nullptr; } - if (!found_balancer) return nullptr; - return OrphanablePtr(New(args)); + grpc_lb_addresses* addresses = + static_cast(arg->value.pointer.p); + size_t num_grpclb_addrs = 0; + for (size_t i = 0; i < addresses->num_addresses; ++i) { + if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; + } + if (num_grpclb_addrs == 0) return nullptr; + return OrphanablePtr(New(addresses, args)); } const char* name() const override { return "grpclb"; } 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..825065a9c32 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 @@ -21,7 +21,7 @@ #include -#include +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" /// Makes any necessary modifications to \a args for use in the grpclb /// balancer channel. 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 6e8fbdcab77..441efd5e23b 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 @@ -26,7 +26,6 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -43,23 +42,22 @@ int BalancerNameCmp(const grpc_core::UniquePtr& a, } RefCountedPtr CreateTargetAuthorityTable( - const ServerAddressList& addresses) { + grpc_lb_addresses* 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) { + static_cast(gpr_zalloc( + sizeof(*target_authority_entries) * addresses->num_addresses)); + for (size_t i = 0; i < addresses->num_addresses; ++i) { char* addr_str; - GPR_ASSERT( - grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true) > 0); + GPR_ASSERT(grpc_sockaddr_to_string( + &addr_str, &addresses->addresses[i].address, true) > 0); target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str); + target_authority_entries[i].value.reset( + gpr_strdup(addresses->addresses[i].balancer_name)); 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); + TargetAuthorityTable::Create(addresses->num_addresses, + target_authority_entries, BalancerNameCmp); gpr_free(target_authority_entries); return target_authority_table; } @@ -74,12 +72,13 @@ grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args( 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); + const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES); + GPR_ASSERT(arg != nullptr); + GPR_ASSERT(arg->type == GRPC_ARG_POINTER); + grpc_lb_addresses* addresses = + static_cast(arg->value.pointer.p); 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/grpclb/load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h index 71d371c880a..9ca7b28d8e6 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 @@ -25,7 +25,7 @@ #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" -#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128 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 74c17612a28..d1a05f12554 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 @@ -24,7 +24,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/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" @@ -76,9 +75,11 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, grpc_subchannel* subchannel, + const grpc_lb_user_data_vtable* user_data_vtable, + const grpc_lb_address& address, grpc_subchannel* subchannel, grpc_combiner* combiner) - : SubchannelData(subchannel_list, address, subchannel, combiner) {} + : SubchannelData(subchannel_list, user_data_vtable, address, subchannel, + combiner) {} void ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state, grpc_error* error) override; @@ -94,7 +95,7 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData> { public: PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, - const ServerAddressList& addresses, + const grpc_lb_addresses* addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) @@ -336,8 +337,8 @@ void PickFirst::UpdateChildRefsLocked() { void PickFirst::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { AutoChildRefsUpdater guard(this); - const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); - if (addresses == nullptr) { + const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); + if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { if (subchannel_list_ == nullptr) { // If we don't have a current subchannel list, go into TRANSIENT FAILURE. grpc_connectivity_state_set( @@ -353,17 +354,19 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, } return; } + const grpc_lb_addresses* addresses = + static_cast(arg->value.pointer.p); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p received update with %" PRIuPTR " addresses", this, - addresses->size()); + addresses->num_addresses); } 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); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, *addresses, combiner(), + 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) { 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 63089afbd78..2a169751317 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 @@ -82,6 +82,8 @@ class RoundRobin : public LoadBalancingPolicy { // Data for a particular subchannel in a subchannel list. // This subclass adds the following functionality: + // - Tracks user_data associated with each address, which will be + // returned along with picks that select the subchannel. // - Tracks the previous connectivity state of the subchannel, so that // we know how many subchannels are in each state. class RoundRobinSubchannelData @@ -91,9 +93,26 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, grpc_subchannel* subchannel, + const grpc_lb_user_data_vtable* user_data_vtable, + const grpc_lb_address& address, grpc_subchannel* subchannel, grpc_combiner* combiner) - : SubchannelData(subchannel_list, address, subchannel, combiner) {} + : SubchannelData(subchannel_list, user_data_vtable, address, subchannel, + combiner), + user_data_vtable_(user_data_vtable), + user_data_(user_data_vtable_ != nullptr + ? user_data_vtable_->copy(address.user_data) + : nullptr) {} + + void UnrefSubchannelLocked(const char* reason) override { + SubchannelData::UnrefSubchannelLocked(reason); + if (user_data_ != nullptr) { + GPR_ASSERT(user_data_vtable_ != nullptr); + user_data_vtable_->destroy(user_data_); + user_data_ = nullptr; + } + } + + void* user_data() const { return user_data_; } grpc_connectivity_state connectivity_state() const { return last_connectivity_state_; @@ -106,6 +125,8 @@ class RoundRobin : public LoadBalancingPolicy { void ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state, grpc_error* error) override; + const grpc_lb_user_data_vtable* user_data_vtable_; + void* user_data_ = nullptr; grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE; }; @@ -116,7 +137,7 @@ class RoundRobin : public LoadBalancingPolicy { public: RoundRobinSubchannelList( RoundRobin* policy, TraceFlag* tracer, - const ServerAddressList& addresses, grpc_combiner* combiner, + const grpc_lb_addresses* addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, @@ -333,6 +354,9 @@ bool RoundRobin::DoPickLocked(PickState* pick) { subchannel_list_->subchannel(next_ready_index); GPR_ASSERT(sd->connected_subchannel() != nullptr); pick->connected_subchannel = sd->connected_subchannel()->Ref(); + if (pick->user_data != nullptr) { + *pick->user_data = sd->user_data(); + } if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, " @@ -643,9 +667,9 @@ void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current, void RoundRobin::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { + const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); AutoChildRefsUpdater guard(this); - const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); - if (addresses == nullptr) { + if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { 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). @@ -657,9 +681,11 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, } return; } + grpc_lb_addresses* addresses = + static_cast(arg->value.pointer.p); if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses", - this, addresses->size()); + this, addresses->num_addresses); } // Replace latest_pending_subchannel_list_. if (latest_pending_subchannel_list_ != nullptr) { @@ -670,7 +696,7 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, *addresses, combiner(), + 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. 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 6f31a643c1d..f31401502c3 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 @@ -26,7 +26,6 @@ #include #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/lib/channel/channel_args.h" #include "src/core/lib/debug/trace.h" @@ -142,7 +141,8 @@ class SubchannelData { protected: SubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, grpc_subchannel* subchannel, + const grpc_lb_user_data_vtable* user_data_vtable, + const grpc_lb_address& address, grpc_subchannel* subchannel, grpc_combiner* combiner); virtual ~SubchannelData(); @@ -156,8 +156,9 @@ class SubchannelData { grpc_connectivity_state connectivity_state, grpc_error* error) GRPC_ABSTRACT; - // Unrefs the subchannel. - void UnrefSubchannelLocked(const char* reason); + // Unrefs the subchannel. May be overridden by subclasses that need + // to perform extra cleanup when unreffing the subchannel. + virtual void UnrefSubchannelLocked(const char* reason); private: // Updates connected_subchannel_ based on pending_connectivity_state_unsafe_. @@ -231,7 +232,7 @@ class SubchannelList : public InternallyRefCounted { protected: SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, - const ServerAddressList& addresses, grpc_combiner* combiner, + const grpc_lb_addresses* addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args); @@ -276,7 +277,8 @@ class SubchannelList : public InternallyRefCounted { template SubchannelData::SubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, grpc_subchannel* subchannel, + const grpc_lb_user_data_vtable* user_data_vtable, + const grpc_lb_address& address, grpc_subchannel* subchannel, grpc_combiner* combiner) : subchannel_list_(subchannel_list), subchannel_(subchannel), @@ -486,7 +488,7 @@ void SubchannelData::ShutdownLocked() { template SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, - const ServerAddressList& addresses, grpc_combiner* combiner, + const grpc_lb_addresses* addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) : InternallyRefCounted(tracer), @@ -496,9 +498,9 @@ SubchannelList::SubchannelList( if (tracer_->enabled()) { gpr_log(GPR_INFO, "[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels", - tracer_->name(), policy, this, addresses.size()); + tracer_->name(), policy, this, addresses->num_addresses); } - subchannels_.reserve(addresses.size()); + subchannels_.reserve(addresses->num_addresses); // We need to remove the LB addresses in order to be able to compare the // subchannel keys of subchannels from a different batch of addresses. // We also remove the inhibit-health-checking arg, since we are @@ -506,27 +508,19 @@ 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_LB_ADDRESSES, GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. grpc_subchannel_args sc_args; - 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()); + for (size_t i = 0; i < addresses->num_addresses; i++) { + // If there were any balancer, we would have chosen grpclb policy instead. + GPR_ASSERT(!addresses->addresses[i].is_balancer); memset(&sc_args, 0, sizeof(grpc_subchannel_args)); - InlinedVector args_to_add; - args_to_add.emplace_back( - 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]); - } - } + grpc_arg addr_arg = + grpc_create_subchannel_address_arg(&addresses->addresses[i].address); 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); + &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg, 1); + gpr_free(addr_arg.value.string); sc_args.args = new_args; grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel( client_channel_factory, &sc_args); @@ -534,7 +528,8 @@ SubchannelList::SubchannelList( if (subchannel == nullptr) { // Subchannel could not be created. if (tracer_->enabled()) { - char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address()); + char* address_uri = + grpc_sockaddr_to_uri(&addresses->addresses[i].address); gpr_log(GPR_INFO, "[%s %p] could not create subchannel for address uri %s, " "ignoring", @@ -544,7 +539,8 @@ SubchannelList::SubchannelList( continue; } if (tracer_->enabled()) { - char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address()); + char* address_uri = + grpc_sockaddr_to_uri(&addresses->addresses[i].address); gpr_log(GPR_INFO, "[%s %p] subchannel list %p index %" PRIuPTR ": Created subchannel %p for address uri %s", @@ -552,7 +548,8 @@ SubchannelList::SubchannelList( address_uri); gpr_free(address_uri); } - subchannels_.emplace_back(this, addresses[i], subchannel, combiner); + subchannels_.emplace_back(this, addresses->user_data_vtable, + addresses->addresses[i], subchannel, 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 3c25de2386c..faedc0a9194 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 @@ -79,7 +79,6 @@ #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" @@ -117,7 +116,7 @@ namespace { class XdsLb : public LoadBalancingPolicy { public: - explicit XdsLb(const Args& args); + XdsLb(const grpc_lb_addresses* addresses, const Args& args); void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; @@ -157,6 +156,9 @@ class XdsLb : public LoadBalancingPolicy { // Our on_complete closure and the original one. grpc_closure on_complete; grpc_closure* original_on_complete; + // The LB token associated with the pick. This is set via user_data in + // the pick. + grpc_mdelem lb_token; // Stats for client-side load reporting. RefCountedPtr client_stats; // Next pending pick. @@ -254,7 +256,7 @@ class XdsLb : public LoadBalancingPolicy { grpc_error* error); // Pending pick methods. - static void PendingPickCleanup(PendingPick* pp); + static void PendingPickSetMetadataAndContext(PendingPick* pp); PendingPick* PendingPickCreate(PickState* pick); void AddPendingPick(PendingPick* pp); static void OnPendingPickComplete(void* arg, grpc_error* error); @@ -317,7 +319,7 @@ class XdsLb : public LoadBalancingPolicy { // 0 means not using fallback. int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. - UniquePtr fallback_backend_addresses_; + grpc_lb_addresses* fallback_backend_addresses_ = nullptr; // Fallback timer. bool fallback_timer_callback_pending_ = false; grpc_timer lb_fallback_timer_; @@ -337,15 +339,47 @@ class XdsLb : public LoadBalancingPolicy { // serverlist parsing code // +// vtable for LB tokens in grpc_lb_addresses +void* lb_token_copy(void* token) { + return token == nullptr + ? nullptr + : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload; +} +void lb_token_destroy(void* token) { + if (token != nullptr) { + GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token}); + } +} +int lb_token_cmp(void* token1, void* token2) { + if (token1 > token2) return 1; + if (token1 < token2) return -1; + return 0; +} +const grpc_lb_user_data_vtable lb_token_vtable = { + lb_token_copy, lb_token_destroy, lb_token_cmp}; + // Returns the backend addresses extracted from the given addresses. -UniquePtr ExtractBackendAddresses( - const ServerAddressList& addresses) { - auto backend_addresses = MakeUnique(); - for (size_t i = 0; i < addresses.size(); ++i) { - if (!addresses[i].IsBalancer()) { - backend_addresses->emplace_back(addresses[i]); +grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) { + // First pass: count the number of backend addresses. + size_t num_backends = 0; + for (size_t i = 0; i < addresses->num_addresses; ++i) { + if (!addresses->addresses[i].is_balancer) { + ++num_backends; } } + // Second pass: actually populate the addresses and (empty) LB tokens. + grpc_lb_addresses* backend_addresses = + grpc_lb_addresses_create(num_backends, &lb_token_vtable); + size_t num_copied = 0; + for (size_t i = 0; i < addresses->num_addresses; ++i) { + if (addresses->addresses[i].is_balancer) continue; + const grpc_resolved_address* addr = &addresses->addresses[i].address; + grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr, + addr->len, false /* is_balancer */, + nullptr /* balancer_name */, + (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload); + ++num_copied; + } return backend_addresses; } @@ -395,17 +429,56 @@ 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(); +grpc_lb_addresses* ProcessServerlist(const xds_grpclb_serverlist* serverlist) { + size_t num_valid = 0; + /* first pass: count how many are valid in order to allocate the necessary + * memory in a single block */ 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; + if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid; + } + grpc_lb_addresses* lb_addresses = + grpc_lb_addresses_create(num_valid, &lb_token_vtable); + /* second pass: actually populate the addresses and LB tokens (aka user data + * to the outside world) to be read by the child policy during its creation. + * Given that the validity tests are very cheap, they are performed again + * instead of marking the valid ones during the first pass, as this would + * incurr in an allocation due to the arbitrary number of server */ + size_t addr_idx = 0; + for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) { + const xds_grpclb_server* server = serverlist->servers[sl_idx]; + if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue; + GPR_ASSERT(addr_idx < num_valid); + /* address processing */ grpc_resolved_address addr; ParseServer(server, &addr); - addresses->emplace_back(addr, nullptr); + /* lb token processing */ + void* user_data; + if (server->has_load_balance_token) { + const size_t lb_token_max_length = + GPR_ARRAY_SIZE(server->load_balance_token); + const size_t lb_token_length = + strnlen(server->load_balance_token, lb_token_max_length); + grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer( + server->load_balance_token, lb_token_length); + user_data = + (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr) + .payload; + } else { + char* uri = grpc_sockaddr_to_uri(&addr); + gpr_log(GPR_INFO, + "Missing LB token for backend address '%s'. The empty token will " + "be used instead", + uri); + gpr_free(uri); + user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; + } + grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len, + false /* is_balancer */, + nullptr /* balancer_name */, user_data); + ++addr_idx; } - return addresses; + GPR_ASSERT(addr_idx == num_valid); + return lb_addresses; } // @@ -716,7 +789,8 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( xds_grpclb_destroy_serverlist(xdslb_policy->serverlist_); } else { /* or dispose of the fallback */ - xdslb_policy->fallback_backend_addresses_.reset(); + grpc_lb_addresses_destroy(xdslb_policy->fallback_backend_addresses_); + xdslb_policy->fallback_backend_addresses_ = nullptr; if (xdslb_policy->fallback_timer_callback_pending_) { grpc_timer_cancel(&xdslb_policy->lb_fallback_timer_); } @@ -802,15 +876,31 @@ 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]); - } +grpc_lb_addresses* ExtractBalancerAddresses( + const grpc_lb_addresses* addresses) { + size_t num_grpclb_addrs = 0; + for (size_t i = 0; i < addresses->num_addresses; ++i) { + if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; } - return balancer_addresses; + // There must be at least one balancer address, or else the + // client_channel would not have chosen this LB policy. + GPR_ASSERT(num_grpclb_addrs > 0); + grpc_lb_addresses* lb_addresses = + grpc_lb_addresses_create(num_grpclb_addrs, nullptr); + size_t lb_addresses_idx = 0; + for (size_t i = 0; i < addresses->num_addresses; ++i) { + if (!addresses->addresses[i].is_balancer) continue; + if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) { + gpr_log(GPR_ERROR, + "This LB policy doesn't support user data. It will be ignored"); + } + grpc_lb_addresses_set_address( + lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr, + addresses->addresses[i].address.len, false /* is balancer */, + addresses->addresses[i].balancer_name, nullptr /* user data */); + } + GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx); + return lb_addresses; } /* Returns the channel args for the LB channel, used to create a bidirectional @@ -822,11 +912,10 @@ UniquePtr ExtractBalancerAddresses( * above the grpclb policy. * - \a args: other args inherited from the xds policy. */ grpc_channel_args* BuildBalancerChannelArgs( - const ServerAddressList& addresses, + const grpc_lb_addresses* addresses, FakeResolverResponseGenerator* response_generator, const grpc_channel_args* args) { - UniquePtr balancer_addresses = - ExtractBalancerAddresses(addresses); + grpc_lb_addresses* lb_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 @@ -844,7 +933,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // 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. - GRPC_ARG_SERVER_ADDRESS_LIST, + GRPC_ARG_LB_ADDRESSES, // 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. @@ -860,10 +949,10 @@ grpc_channel_args* BuildBalancerChannelArgs( }; // Channel args to add. const grpc_arg args_to_add[] = { - // New server address list. + // New LB addresses. // 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()), + grpc_lb_addresses_create_channel_arg(lb_addresses), // The fake resolver response generator, which we use to inject // address updates into the LB channel. grpc_core::FakeResolverResponseGenerator::MakeChannelArg( @@ -881,7 +970,10 @@ 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_xds_modify_lb_channel_args(new_args); + new_args = grpc_lb_policy_xds_modify_lb_channel_args(new_args); + // Clean up. + grpc_lb_addresses_destroy(lb_addresses); + return new_args; } // @@ -889,7 +981,8 @@ grpc_channel_args* BuildBalancerChannelArgs( // // TODO(vishalpowar): Use lb_config in args to configure LB policy. -XdsLb::XdsLb(const LoadBalancingPolicy::Args& args) +XdsLb::XdsLb(const grpc_lb_addresses* addresses, + const LoadBalancingPolicy::Args& args) : LoadBalancingPolicy(args), response_generator_(MakeRefCounted()), lb_call_backoff_( @@ -945,6 +1038,9 @@ XdsLb::~XdsLb() { if (serverlist_ != nullptr) { xds_grpclb_destroy_serverlist(serverlist_); } + if (fallback_backend_addresses_ != nullptr) { + grpc_lb_addresses_destroy(fallback_backend_addresses_); + } grpc_subchannel_index_unref(); } @@ -992,6 +1088,7 @@ void XdsLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { while ((pp = pending_picks_) != nullptr) { pending_picks_ = pp->next; pp->pick->on_complete = pp->original_on_complete; + pp->pick->user_data = nullptr; grpc_error* error = GRPC_ERROR_NONE; if (new_policy->PickLocked(pp->pick, &error)) { // Synchronous return; schedule closure. @@ -1144,16 +1241,21 @@ void XdsLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, } void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { - const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); - if (addresses == nullptr) { + const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); + if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { // Ignore this update. gpr_log(GPR_ERROR, "[xdslb %p] No valid LB addresses channel arg in update, ignoring.", this); return; } + const grpc_lb_addresses* addresses = + static_cast(arg->value.pointer.p); // Update fallback address list. - fallback_backend_addresses_ = ExtractBackendAddresses(*addresses); + if (fallback_backend_addresses_ != nullptr) { + grpc_lb_addresses_destroy(fallback_backend_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}; @@ -1164,7 +1266,7 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { &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); + BuildBalancerChannelArgs(addresses, response_generator_.get(), &args); // Create balancer channel if needed. if (lb_channel_ == nullptr) { char* uri_str; @@ -1355,15 +1457,37 @@ void XdsLb::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 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). +void XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) { + /* if connected_subchannel is nullptr, no pick has been made by the + * child policy (e.g., all addresses failed to connect). There won't be any + * user_data/token available */ if (pp->pick->connected_subchannel != nullptr) { + if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) { + AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token), + &pp->pick->lb_token_mdelem_storage, + pp->pick->initial_metadata); + } else { + gpr_log(GPR_ERROR, + "[xdslb %p] No LB token for connected subchannel pick %p", + pp->xdslb_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 = @@ -1381,7 +1505,7 @@ void XdsLb::PendingPickCleanup(PendingPick* pp) { * 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); + PendingPickSetMetadataAndContext(pp); GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error)); Delete(pp); } @@ -1413,14 +1537,16 @@ void XdsLb::AddPendingPick(PendingPick* pp) { // completion callback even if the pick is available immediately. bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp, grpc_error** error) { - // Set client_stats. + // Set client_stats and user_data. if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { pp->client_stats = lb_calld_->client_stats()->Ref(); } + GPR_ASSERT(pp->pick->user_data == nullptr); + pp->pick->user_data = (void**)&pp->lb_token; // Pick via the child policy. bool pick_done = child_policy_->PickLocked(pp->pick, error); if (pick_done) { - PendingPickCleanup(pp); + PendingPickSetMetadataAndContext(pp); if (force_async) { GRPC_CLOSURE_SCHED(pp->original_on_complete, *error); *error = GRPC_ERROR_NONE; @@ -1482,19 +1608,20 @@ void XdsLb::CreateChildPolicyLocked(const Args& args) { } grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { + grpc_lb_addresses* addresses; 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); + addresses = ProcessServerlist(serverlist_); is_backend_from_grpclb_load_balancer = true; - // Replace the server address list in the channel args that we pass down to + GPR_ASSERT(addresses != nullptr); + // Replace the LB addresses in the channel args that we pass down to // the subchannel. - static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST}; + static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES}; const grpc_arg args_to_add[] = { - CreateServerAddressListChannelArg(addresses.get()), + grpc_lb_addresses_create_channel_arg(addresses), // A channel arg indicating if the target is a backend inferred from a // grpclb load balancer. grpc_channel_arg_integer_create( @@ -1504,6 +1631,7 @@ grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { 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)); + grpc_lb_addresses_destroy(addresses); return args; } @@ -1637,18 +1765,19 @@ class XdsFactory : public LoadBalancingPolicyFactory { OrphanablePtr CreateLoadBalancingPolicy( const 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; - } + const grpc_arg* arg = + grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES); + if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { + return nullptr; } - if (!found_balancer_address) return nullptr; - return OrphanablePtr(New(args)); + grpc_lb_addresses* addresses = + static_cast(arg->value.pointer.p); + size_t num_grpclb_addrs = 0; + for (size_t i = 0; i < addresses->num_addresses; ++i) { + if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; + } + if (num_grpclb_addrs == 0) return nullptr; + return OrphanablePtr(New(addresses, args)); } const char* name() const override { return "xds_experimental"; } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h index f713b7f563d..32c4acc8a3e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h @@ -21,7 +21,7 @@ #include -#include +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" /// Makes any necessary modifications to \a args for use in the xds /// balancer channel. 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 9a11f8e39fd..5ab72efce46 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 @@ -25,7 +25,6 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -42,23 +41,22 @@ int BalancerNameCmp(const grpc_core::UniquePtr& a, } RefCountedPtr CreateTargetAuthorityTable( - const ServerAddressList& addresses) { + grpc_lb_addresses* 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) { + static_cast(gpr_zalloc( + sizeof(*target_authority_entries) * addresses->num_addresses)); + for (size_t i = 0; i < addresses->num_addresses; ++i) { char* addr_str; - GPR_ASSERT( - grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true) > 0); + GPR_ASSERT(grpc_sockaddr_to_string( + &addr_str, &addresses->addresses[i].address, true) > 0); target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str); + target_authority_entries[i].value.reset( + gpr_strdup(addresses->addresses[i].balancer_name)); 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); + TargetAuthorityTable::Create(addresses->num_addresses, + target_authority_entries, BalancerNameCmp); gpr_free(target_authority_entries); return target_authority_table; } @@ -73,12 +71,13 @@ grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args( 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); + const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES); + GPR_ASSERT(arg != nullptr); + GPR_ASSERT(arg->type == GRPC_ARG_POINTER); + grpc_lb_addresses* addresses = + static_cast(arg->value.pointer.p); 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/xds/xds_load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h index 67049956417..9d08defa7ef 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 @@ -25,7 +25,7 @@ #include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" -#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #define XDS_SERVICE_NAME_MAX_LENGTH 128 diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.cc b/src/core/ext/filters/client_channel/lb_policy_factory.cc new file mode 100644 index 00000000000..5c6363d2952 --- /dev/null +++ b/src/core/ext/filters/client_channel/lb_policy_factory.cc @@ -0,0 +1,163 @@ +/* + * + * 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 + +#include +#include + +#include "src/core/lib/channel/channel_args.h" + +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/ext/filters/client_channel/parse_address.h" + +grpc_lb_addresses* grpc_lb_addresses_create( + size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable) { + grpc_lb_addresses* addresses = + static_cast(gpr_zalloc(sizeof(grpc_lb_addresses))); + addresses->num_addresses = num_addresses; + addresses->user_data_vtable = user_data_vtable; + const size_t addresses_size = sizeof(grpc_lb_address) * num_addresses; + addresses->addresses = + static_cast(gpr_zalloc(addresses_size)); + return addresses; +} + +grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses) { + grpc_lb_addresses* new_addresses = grpc_lb_addresses_create( + addresses->num_addresses, addresses->user_data_vtable); + memcpy(new_addresses->addresses, addresses->addresses, + sizeof(grpc_lb_address) * addresses->num_addresses); + for (size_t i = 0; i < addresses->num_addresses; ++i) { + if (new_addresses->addresses[i].balancer_name != nullptr) { + new_addresses->addresses[i].balancer_name = + gpr_strdup(new_addresses->addresses[i].balancer_name); + } + if (new_addresses->addresses[i].user_data != nullptr) { + new_addresses->addresses[i].user_data = addresses->user_data_vtable->copy( + new_addresses->addresses[i].user_data); + } + } + return new_addresses; +} + +void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index, + const void* address, size_t address_len, + bool is_balancer, const char* balancer_name, + void* user_data) { + GPR_ASSERT(index < addresses->num_addresses); + if (user_data != nullptr) GPR_ASSERT(addresses->user_data_vtable != nullptr); + grpc_lb_address* target = &addresses->addresses[index]; + memcpy(target->address.addr, address, address_len); + target->address.len = static_cast(address_len); + target->is_balancer = is_balancer; + target->balancer_name = gpr_strdup(balancer_name); + target->user_data = user_data; +} + +bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses, + size_t index, const grpc_uri* uri, + bool is_balancer, + const char* balancer_name, + void* user_data) { + grpc_resolved_address address; + if (!grpc_parse_uri(uri, &address)) return false; + grpc_lb_addresses_set_address(addresses, index, address.addr, address.len, + is_balancer, balancer_name, user_data); + return true; +} + +int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1, + const grpc_lb_addresses* addresses2) { + if (addresses1->num_addresses > addresses2->num_addresses) return 1; + if (addresses1->num_addresses < addresses2->num_addresses) return -1; + if (addresses1->user_data_vtable > addresses2->user_data_vtable) return 1; + if (addresses1->user_data_vtable < addresses2->user_data_vtable) return -1; + for (size_t i = 0; i < addresses1->num_addresses; ++i) { + const grpc_lb_address* target1 = &addresses1->addresses[i]; + const grpc_lb_address* target2 = &addresses2->addresses[i]; + if (target1->address.len > target2->address.len) return 1; + if (target1->address.len < target2->address.len) return -1; + int retval = memcmp(target1->address.addr, target2->address.addr, + target1->address.len); + if (retval != 0) return retval; + if (target1->is_balancer > target2->is_balancer) return 1; + if (target1->is_balancer < target2->is_balancer) return -1; + const char* balancer_name1 = + target1->balancer_name != nullptr ? target1->balancer_name : ""; + const char* balancer_name2 = + target2->balancer_name != nullptr ? target2->balancer_name : ""; + retval = strcmp(balancer_name1, balancer_name2); + if (retval != 0) return retval; + if (addresses1->user_data_vtable != nullptr) { + retval = addresses1->user_data_vtable->cmp(target1->user_data, + target2->user_data); + if (retval != 0) return retval; + } + } + return 0; +} + +void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses) { + for (size_t i = 0; i < addresses->num_addresses; ++i) { + gpr_free(addresses->addresses[i].balancer_name); + if (addresses->addresses[i].user_data != nullptr) { + addresses->user_data_vtable->destroy(addresses->addresses[i].user_data); + } + } + gpr_free(addresses->addresses); + gpr_free(addresses); +} + +static void* lb_addresses_copy(void* addresses) { + return grpc_lb_addresses_copy(static_cast(addresses)); +} +static void lb_addresses_destroy(void* addresses) { + grpc_lb_addresses_destroy(static_cast(addresses)); +} +static int lb_addresses_cmp(void* addresses1, void* addresses2) { + return grpc_lb_addresses_cmp(static_cast(addresses1), + static_cast(addresses2)); +} +static const grpc_arg_pointer_vtable lb_addresses_arg_vtable = { + lb_addresses_copy, lb_addresses_destroy, lb_addresses_cmp}; + +grpc_arg grpc_lb_addresses_create_channel_arg( + const grpc_lb_addresses* addresses) { + return grpc_channel_arg_pointer_create( + (char*)GRPC_ARG_LB_ADDRESSES, (void*)addresses, &lb_addresses_arg_vtable); +} + +grpc_lb_addresses* grpc_lb_addresses_find_channel_arg( + const grpc_channel_args* channel_args) { + const grpc_arg* lb_addresses_arg = + grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES); + if (lb_addresses_arg == nullptr || lb_addresses_arg->type != GRPC_ARG_POINTER) + return nullptr; + return static_cast(lb_addresses_arg->value.pointer.p); +} + +bool grpc_lb_addresses_contains_balancer_address( + const grpc_lb_addresses& addresses) { + for (size_t i = 0; i < addresses.num_addresses; ++i) { + if (addresses.addresses[i].is_balancer) return true; + } + return false; +} 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..a59deadb265 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -21,9 +21,91 @@ #include +#include "src/core/lib/iomgr/resolve_address.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/lib/gprpp/abstract.h" -#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/uri/uri_parser.h" + +// +// representation of an LB address +// + +// Channel arg key for grpc_lb_addresses. +#define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses" + +/** A resolved address alongside any LB related information associated with it. + * \a user_data, if not NULL, contains opaque data meant to be consumed by the + * gRPC LB policy. Note that no all LB policies support \a user_data as input. + * Those who don't will simply ignore it and will correspondingly return NULL in + * their namesake pick() output argument. */ +// TODO(roth): Once we figure out a better way of handling user_data in +// LB policies, convert these structs to C++ classes. +typedef struct grpc_lb_address { + grpc_resolved_address address; + bool is_balancer; + char* balancer_name; /* For secure naming. */ + void* user_data; +} grpc_lb_address; + +typedef struct grpc_lb_user_data_vtable { + void* (*copy)(void*); + void (*destroy)(void*); + int (*cmp)(void*, void*); +} grpc_lb_user_data_vtable; + +typedef struct grpc_lb_addresses { + size_t num_addresses; + grpc_lb_address* addresses; + const grpc_lb_user_data_vtable* user_data_vtable; +} grpc_lb_addresses; + +/** Returns a grpc_addresses struct with enough space for + \a num_addresses addresses. The \a user_data_vtable argument may be + NULL if no user data will be added. */ +grpc_lb_addresses* grpc_lb_addresses_create( + size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable); + +/** Creates a copy of \a addresses. */ +grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses); + +/** Sets the value of the address at index \a index of \a addresses. + * \a address is a socket address of length \a address_len. */ +void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index, + const void* address, size_t address_len, + bool is_balancer, const char* balancer_name, + void* user_data); + +/** Sets the value of the address at index \a index of \a addresses from \a uri. + * Returns true upon success, false otherwise. */ +bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses, + size_t index, const grpc_uri* uri, + bool is_balancer, + const char* balancer_name, + void* user_data); + +/** Compares \a addresses1 and \a addresses2. */ +int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1, + const grpc_lb_addresses* addresses2); + +/** Destroys \a addresses. */ +void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses); + +/** Returns a channel arg containing \a addresses. */ +grpc_arg grpc_lb_addresses_create_channel_arg( + const grpc_lb_addresses* addresses); + +/** Returns the \a grpc_lb_addresses instance in \a channel_args or NULL */ +grpc_lb_addresses* grpc_lb_addresses_find_channel_arg( + const grpc_channel_args* channel_args); + +// Returns true if addresses contains at least one balancer address. +bool grpc_lb_addresses_contains_balancer_address( + const grpc_lb_addresses& addresses); + +// +// LB policy factory +// namespace grpc_core { 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 c8425ae3365..4ebc2c8161c 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 @@ -33,7 +33,6 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #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/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -118,7 +117,7 @@ class AresDnsResolver : public Resolver { /// retry backoff state BackOff backoff_; /// currently resolving addresses - UniquePtr addresses_; + grpc_lb_addresses* lb_addresses_ = nullptr; /// currently resolving service config char* service_config_json_ = nullptr; // has shutdown been initiated @@ -315,13 +314,13 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { r->resolving_ = false; gpr_free(r->pending_request_); r->pending_request_ = nullptr; - if (r->addresses_ != nullptr) { + if (r->lb_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()); + grpc_lb_addresses_create_channel_arg(r->lb_addresses_); char* service_config_string = nullptr; if (r->service_config_json_ != nullptr) { service_config_string = ChooseServiceConfig(r->service_config_json_); @@ -338,7 +337,7 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { r->channel_args_, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add); gpr_free(service_config_string); - r->addresses_.reset(); + grpc_lb_addresses_destroy(r->lb_addresses_); // Reset backoff state so that we start from the beginning when the // next request gets triggered. r->backoff_.Reset(); @@ -413,10 +412,11 @@ void AresDnsResolver::StartResolvingLocked() { self.release(); GPR_ASSERT(!resolving_); resolving_ = true; + lb_addresses_ = nullptr; 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_, &lb_addresses_, true /* check_grpclb */, request_service_config_ ? &service_config_json_ : nullptr, query_timeout_ms_, combiner()); last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc index 8abc34c6edb..f42b1e309df 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -31,7 +31,6 @@ #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/iomgr/timer.h" 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 1b1c2303da3..55715869b63 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 @@ -37,16 +37,12 @@ #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/nameser.h" #include "src/core/lib/iomgr/sockaddr_utils.h" -using grpc_core::ServerAddress; -using grpc_core::ServerAddressList; - static gpr_once g_basic_init = GPR_ONCE_INIT; static gpr_mu g_init_mu; @@ -62,7 +58,7 @@ struct grpc_ares_request { /** closure to call when the request completes */ grpc_closure* on_done; /** the pointer to receive the resolved addresses */ - grpc_core::UniquePtr* addresses_out; + grpc_lb_addresses** lb_addrs_out; /** the pointer to receive the service config in JSON */ char** service_config_json_out; /** the evernt driver used by this request */ @@ -91,11 +87,12 @@ typedef struct 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, +static void log_address_sorting_list(grpc_lb_addresses* lb_addrs, const char* input_output_str) { - for (size_t i = 0; i < addresses.size(); i++) { + for (size_t i = 0; i < lb_addrs->num_addresses; i++) { char* addr_str; - if (grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true)) { + if (grpc_sockaddr_to_string(&addr_str, &lb_addrs->addresses[i].address, + true)) { gpr_log(GPR_DEBUG, "c-ares address sorting: %s[%" PRIuPTR "]=%s", input_output_str, i, addr_str); gpr_free(addr_str); @@ -107,28 +104,29 @@ static void log_address_sorting_list(const ServerAddressList& addresses, } } -void grpc_cares_wrapper_address_sorting_sort(ServerAddressList* addresses) { +void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs) { if (grpc_trace_cares_address_sorting.enabled()) { - log_address_sorting_list(*addresses, "input"); + log_address_sorting_list(lb_addrs, "input"); } address_sorting_sortable* sortables = (address_sorting_sortable*)gpr_zalloc( - sizeof(address_sorting_sortable) * addresses->size()); - for (size_t i = 0; i < addresses->size(); ++i) { - sortables[i].user_data = &(*addresses)[i]; - memcpy(&sortables[i].dest_addr.addr, &(*addresses)[i].address().addr, - (*addresses)[i].address().len); - sortables[i].dest_addr.len = (*addresses)[i].address().len; + sizeof(address_sorting_sortable) * lb_addrs->num_addresses); + for (size_t i = 0; i < lb_addrs->num_addresses; i++) { + sortables[i].user_data = &lb_addrs->addresses[i]; + memcpy(&sortables[i].dest_addr.addr, &lb_addrs->addresses[i].address.addr, + lb_addrs->addresses[i].address.len); + sortables[i].dest_addr.len = lb_addrs->addresses[i].address.len; } - address_sorting_rfc_6724_sort(sortables, addresses->size()); - ServerAddressList sorted; - sorted.reserve(addresses->size()); - for (size_t i = 0; i < addresses->size(); ++i) { - sorted.emplace_back(*static_cast(sortables[i].user_data)); + address_sorting_rfc_6724_sort(sortables, lb_addrs->num_addresses); + grpc_lb_address* sorted_lb_addrs = (grpc_lb_address*)gpr_zalloc( + sizeof(grpc_lb_address) * lb_addrs->num_addresses); + for (size_t i = 0; i < lb_addrs->num_addresses; i++) { + sorted_lb_addrs[i] = *(grpc_lb_address*)sortables[i].user_data; } gpr_free(sortables); - *addresses = std::move(sorted); + gpr_free(lb_addrs->addresses); + lb_addrs->addresses = sorted_lb_addrs; if (grpc_trace_cares_address_sorting.enabled()) { - log_address_sorting_list(*addresses, "output"); + log_address_sorting_list(lb_addrs, "output"); } } @@ -147,9 +145,9 @@ void grpc_ares_complete_request_locked(grpc_ares_request* r) { /* Invoke on_done callback and destroy the request */ r->ev_driver = nullptr; - ServerAddressList* addresses = r->addresses_out->get(); - if (addresses != nullptr) { - grpc_cares_wrapper_address_sorting_sort(addresses); + grpc_lb_addresses* lb_addrs = *(r->lb_addrs_out); + if (lb_addrs != nullptr) { + grpc_cares_wrapper_address_sorting_sort(lb_addrs); } GRPC_CLOSURE_SCHED(r->on_done, r->error); } @@ -183,30 +181,33 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, GRPC_ERROR_UNREF(r->error); r->error = GRPC_ERROR_NONE; r->success = true; - if (*r->addresses_out == nullptr) { - *r->addresses_out = grpc_core::MakeUnique(); + grpc_lb_addresses** lb_addresses = r->lb_addrs_out; + if (*lb_addresses == nullptr) { + *lb_addresses = grpc_lb_addresses_create(0, nullptr); } - ServerAddressList& addresses = **r->addresses_out; - for (size_t i = 0; hostent->h_addr_list[i] != nullptr; ++i) { - grpc_core::InlinedVector args_to_add; - if (hr->is_balancer) { - args_to_add.emplace_back(grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); - args_to_add.emplace_back(grpc_channel_arg_string_create( - const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), hr->host)); - } - grpc_channel_args* args = grpc_channel_args_copy_and_add( - nullptr, args_to_add.data(), args_to_add.size()); + size_t prev_naddr = (*lb_addresses)->num_addresses; + size_t i; + for (i = 0; hostent->h_addr_list[i] != nullptr; i++) { + } + (*lb_addresses)->num_addresses += i; + (*lb_addresses)->addresses = static_cast( + gpr_realloc((*lb_addresses)->addresses, + sizeof(grpc_lb_address) * (*lb_addresses)->num_addresses)); + for (i = prev_naddr; i < (*lb_addresses)->num_addresses; i++) { switch (hostent->h_addrtype) { case AF_INET6: { size_t addr_len = sizeof(struct sockaddr_in6); struct sockaddr_in6 addr; memset(&addr, 0, addr_len); - memcpy(&addr.sin6_addr, hostent->h_addr_list[i], + memcpy(&addr.sin6_addr, hostent->h_addr_list[i - prev_naddr], sizeof(struct in6_addr)); addr.sin6_family = static_cast(hostent->h_addrtype); addr.sin6_port = hr->port; - addresses.emplace_back(&addr, addr_len, args); + grpc_lb_addresses_set_address( + *lb_addresses, i, &addr, addr_len, + hr->is_balancer /* is_balancer */, + hr->is_balancer ? hr->host : nullptr /* balancer_name */, + nullptr /* user_data */); char output[INET6_ADDRSTRLEN]; ares_inet_ntop(AF_INET6, &addr.sin6_addr, output, INET6_ADDRSTRLEN); gpr_log(GPR_DEBUG, @@ -219,11 +220,15 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, size_t addr_len = sizeof(struct sockaddr_in); struct sockaddr_in addr; memset(&addr, 0, addr_len); - memcpy(&addr.sin_addr, hostent->h_addr_list[i], + memcpy(&addr.sin_addr, hostent->h_addr_list[i - prev_naddr], sizeof(struct in_addr)); addr.sin_family = static_cast(hostent->h_addrtype); addr.sin_port = hr->port; - addresses.emplace_back(&addr, addr_len, args); + grpc_lb_addresses_set_address( + *lb_addresses, i, &addr, addr_len, + hr->is_balancer /* is_balancer */, + hr->is_balancer ? hr->host : nullptr /* balancer_name */, + nullptr /* user_data */); char output[INET_ADDRSTRLEN]; ares_inet_ntop(AF_INET, &addr.sin_addr, output, INET_ADDRSTRLEN); gpr_log(GPR_DEBUG, @@ -462,10 +467,11 @@ error_cleanup: gpr_free(port); } -static bool inner_resolve_as_ip_literal_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, char** host, - char** port, char** hostport) { +static bool inner_resolve_as_ip_literal_locked(const char* name, + const char* default_port, + grpc_lb_addresses** addrs, + char** host, char** port, + char** hostport) { gpr_split_host_port(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, @@ -489,16 +495,18 @@ static bool inner_resolve_as_ip_literal_locked( if (grpc_parse_ipv4_hostport(*hostport, &addr, false /* log errors */) || grpc_parse_ipv6_hostport(*hostport, &addr, false /* log errors */)) { GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_core::MakeUnique(); - (*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */); + *addrs = grpc_lb_addresses_create(1, nullptr); + grpc_lb_addresses_set_address( + *addrs, 0, addr.addr, addr.len, false /* is_balancer */, + nullptr /* balancer_name */, nullptr /* user_data */); return true; } return false; } -static bool resolve_as_ip_literal_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs) { +static bool resolve_as_ip_literal_locked(const char* name, + const char* default_port, + grpc_lb_addresses** addrs) { char* host = nullptr; char* port = nullptr; char* hostport = nullptr; @@ -513,14 +521,13 @@ static bool resolve_as_ip_literal_locked( static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_core::UniquePtr* addrs, - bool check_grpclb, char** service_config_json, int query_timeout_ms, - grpc_combiner* combiner) { + grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + int query_timeout_ms, grpc_combiner* combiner) { grpc_ares_request* r = static_cast(gpr_zalloc(sizeof(grpc_ares_request))); r->ev_driver = nullptr; r->on_done = on_done; - r->addresses_out = addrs; + r->lb_addrs_out = addrs; r->service_config_json_out = service_config_json; r->success = false; r->error = GRPC_ERROR_NONE; @@ -546,8 +553,8 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_core::UniquePtr* addrs, - bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) { @@ -592,8 +599,8 @@ typedef struct grpc_resolve_address_ares_request { grpc_combiner* combiner; /** the pointer to receive the resolved addresses */ grpc_resolved_addresses** addrs_out; - /** currently resolving addresses */ - grpc_core::UniquePtr addresses; + /** currently resolving lb addresses */ + grpc_lb_addresses* lb_addrs; /** closure to call when the resolve_address_ares request completes */ grpc_closure* on_resolve_address_done; /** a closure wrapping on_resolve_address_done, which should be invoked when @@ -606,7 +613,7 @@ typedef struct grpc_resolve_address_ares_request { /* pollset_set to be driven by */ grpc_pollset_set* interested_parties; /* underlying ares_request that the query is performed on */ - grpc_ares_request* ares_request = nullptr; + grpc_ares_request* ares_request; } grpc_resolve_address_ares_request; static void on_dns_lookup_done_locked(void* arg, grpc_error* error) { @@ -614,24 +621,25 @@ static void on_dns_lookup_done_locked(void* arg, grpc_error* error) { static_cast(arg); gpr_free(r->ares_request); grpc_resolved_addresses** resolved_addresses = r->addrs_out; - if (r->addresses == nullptr || r->addresses->empty()) { + if (r->lb_addrs == nullptr || r->lb_addrs->num_addresses == 0) { *resolved_addresses = nullptr; } else { *resolved_addresses = static_cast( gpr_zalloc(sizeof(grpc_resolved_addresses))); - (*resolved_addresses)->naddrs = r->addresses->size(); + (*resolved_addresses)->naddrs = r->lb_addrs->num_addresses; (*resolved_addresses)->addrs = static_cast(gpr_zalloc( sizeof(grpc_resolved_address) * (*resolved_addresses)->naddrs)); - for (size_t i = 0; i < (*resolved_addresses)->naddrs; ++i) { - GPR_ASSERT(!(*r->addresses)[i].IsBalancer()); - memcpy(&(*resolved_addresses)->addrs[i], &(*r->addresses)[i].address(), - sizeof(grpc_resolved_address)); + for (size_t i = 0; i < (*resolved_addresses)->naddrs; i++) { + GPR_ASSERT(!r->lb_addrs->addresses[i].is_balancer); + memcpy(&(*resolved_addresses)->addrs[i], + &r->lb_addrs->addresses[i].address, sizeof(grpc_resolved_address)); } } GRPC_CLOSURE_SCHED(r->on_resolve_address_done, GRPC_ERROR_REF(error)); + if (r->lb_addrs != nullptr) grpc_lb_addresses_destroy(r->lb_addrs); GRPC_COMBINER_UNREF(r->combiner, "on_dns_lookup_done_cb"); - grpc_core::Delete(r); + gpr_free(r); } static void grpc_resolve_address_invoke_dns_lookup_ares_locked( @@ -640,7 +648,7 @@ static void grpc_resolve_address_invoke_dns_lookup_ares_locked( static_cast(arg); r->ares_request = grpc_dns_lookup_ares_locked( nullptr /* dns_server */, r->name, r->default_port, r->interested_parties, - &r->on_dns_lookup_done_locked, &r->addresses, false /* check_grpclb */, + &r->on_dns_lookup_done_locked, &r->lb_addrs, false /* check_grpclb */, nullptr /* service_config_json */, GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, r->combiner); } @@ -651,7 +659,8 @@ static void grpc_resolve_address_ares_impl(const char* name, grpc_closure* on_done, grpc_resolved_addresses** addrs) { grpc_resolve_address_ares_request* r = - grpc_core::New(); + static_cast( + gpr_zalloc(sizeof(grpc_resolve_address_ares_request))); r->combiner = grpc_combiner_create(); r->addrs_out = addrs; r->on_resolve_address_done = on_done; diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h index 28082504565..9acef1d0ca9 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -21,7 +21,7 @@ #include -#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -61,9 +61,8 @@ extern void (*grpc_resolve_address_ares)(const char* name, extern grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_core::UniquePtr* addresses, - bool check_grpclb, char** service_config_json, int query_timeout_ms, - grpc_combiner* combiner); + grpc_lb_addresses** addresses, bool check_grpclb, + char** service_config_json, int query_timeout_ms, grpc_combiner* combiner); /* Cancel the pending grpc_ares_request \a request */ extern void (*grpc_cancel_ares_request_locked)(grpc_ares_request* request); @@ -90,12 +89,10 @@ bool grpc_ares_query_ipv6(); * Returns a bool indicating whether or not such an action was performed. * See https://github.com/grpc/grpc/issues/15158. */ bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs); + const char* name, const char* default_port, grpc_lb_addresses** addrs); /* Sorts destinations in lb_addrs according to RFC 6724. */ -void grpc_cares_wrapper_address_sorting_sort( - grpc_core::ServerAddressList* addresses); +void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs); #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H \ */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc index 1f4701c9994..fc78b183044 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc @@ -29,17 +29,16 @@ struct grpc_ares_request { static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_core::UniquePtr* addrs, - bool check_grpclb, char** service_config_json, int query_timeout_ms, - grpc_combiner* combiner) { + grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + int query_timeout_ms, grpc_combiner* combiner) { return NULL; } grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_core::UniquePtr* addrs, - bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {} diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc index 028d8442169..639eec2323f 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc @@ -27,8 +27,7 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs) { + const char* name, const char* default_port, grpc_lb_addresses** addrs) { return false; } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index 202452f1b2b..7e34784691f 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -23,9 +23,9 @@ #include +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_windows.h" @@ -33,9 +33,8 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } static bool inner_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, char** host, - char** port) { + const char* name, const char* default_port, grpc_lb_addresses** addrs, + char** host, char** port) { gpr_split_host_port(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, @@ -56,7 +55,7 @@ static bool inner_maybe_resolve_localhost_manually_locked( } if (gpr_stricmp(*host, "localhost") == 0) { GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_core::MakeUnique(); + *addrs = grpc_lb_addresses_create(2, nullptr); uint16_t numeric_port = grpc_strhtons(*port); // Append the ipv6 loopback address. struct sockaddr_in6 ipv6_loopback_addr; @@ -64,8 +63,10 @@ static bool inner_maybe_resolve_localhost_manually_locked( ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; ipv6_loopback_addr.sin6_family = AF_INET6; ipv6_loopback_addr.sin6_port = numeric_port; - (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), - nullptr /* args */); + grpc_lb_addresses_set_address( + *addrs, 0, &ipv6_loopback_addr, sizeof(ipv6_loopback_addr), + false /* is_balancer */, nullptr /* balancer_name */, + nullptr /* user_data */); // Append the ipv4 loopback address. struct sockaddr_in ipv4_loopback_addr; memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); @@ -73,18 +74,19 @@ static bool inner_maybe_resolve_localhost_manually_locked( ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; ipv4_loopback_addr.sin_family = AF_INET; ipv4_loopback_addr.sin_port = numeric_port; - (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), - nullptr /* args */); + grpc_lb_addresses_set_address( + *addrs, 1, &ipv4_loopback_addr, sizeof(ipv4_loopback_addr), + false /* is_balancer */, nullptr /* balancer_name */, + nullptr /* user_data */); // Let the address sorter figure out which one should be tried first. - grpc_cares_wrapper_address_sorting_sort(addrs->get()); + grpc_cares_wrapper_address_sorting_sort(*addrs); return true; } return false; } bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs) { + const char* name, const char* default_port, grpc_lb_addresses** addrs) { char* host = nullptr; char* port = nullptr; bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, 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..65ff1ec1a5b 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 @@ -26,8 +26,8 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" -#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -198,14 +198,18 @@ void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(r->name_to_resolve_)); if (r->addresses_ != nullptr) { - ServerAddressList addresses; + grpc_lb_addresses* addresses = grpc_lb_addresses_create( + r->addresses_->naddrs, nullptr /* user_data_vtable */); 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_lb_addresses_set_address( + addresses, i, &r->addresses_->addrs[i].addr, + r->addresses_->addrs[i].len, false /* is_balancer */, + nullptr /* balancer_name */, nullptr /* user_data */); } - grpc_arg new_arg = CreateServerAddressListChannelArg(&addresses); + grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses); result = grpc_channel_args_copy_and_add(r->channel_args_, &new_arg, 1); grpc_resolved_addresses_destroy(r->addresses_); + grpc_lb_addresses_destroy(addresses); // 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 258339491c1..3aa690bea41 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 @@ -28,13 +28,12 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" -#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/resolve_address.h" 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..7f690593510 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,9 +19,10 @@ #include +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/ref_counted.h" -#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/uri/uri_parser.h" #define GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR \ "grpc.fake_resolver.response_generator" 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..801734764b4 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 @@ -26,9 +26,9 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" -#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" @@ -45,8 +45,7 @@ namespace { class SockaddrResolver : public Resolver { public: /// Takes ownership of \a addresses. - SockaddrResolver(const ResolverArgs& args, - UniquePtr addresses); + SockaddrResolver(const ResolverArgs& args, grpc_lb_addresses* addresses); void NextLocked(grpc_channel_args** result, grpc_closure* on_complete) override; @@ -59,7 +58,7 @@ class SockaddrResolver : public Resolver { void MaybeFinishNextLocked(); /// the addresses that we've "resolved" - UniquePtr addresses_; + grpc_lb_addresses* addresses_ = nullptr; /// channel args grpc_channel_args* channel_args_ = nullptr; /// have we published? @@ -71,12 +70,13 @@ class SockaddrResolver : public Resolver { }; SockaddrResolver::SockaddrResolver(const ResolverArgs& args, - UniquePtr addresses) + grpc_lb_addresses* addresses) : Resolver(args.combiner), - addresses_(std::move(addresses)), + addresses_(addresses), channel_args_(grpc_channel_args_copy(args.args)) {} SockaddrResolver::~SockaddrResolver() { + grpc_lb_addresses_destroy(addresses_); grpc_channel_args_destroy(channel_args_); } @@ -100,7 +100,7 @@ void SockaddrResolver::ShutdownLocked() { void SockaddrResolver::MaybeFinishNextLocked() { if (next_completion_ != nullptr && !published_) { published_ = true; - grpc_arg arg = CreateServerAddressListChannelArg(addresses_.get()); + grpc_arg arg = grpc_lb_addresses_create_channel_arg(addresses_); *target_result_ = grpc_channel_args_copy_and_add(channel_args_, &arg, 1); GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE); next_completion_ = nullptr; @@ -127,27 +127,27 @@ OrphanablePtr CreateSockaddrResolver( grpc_slice_buffer path_parts; grpc_slice_buffer_init(&path_parts); grpc_slice_split(path_slice, ",", &path_parts); - auto addresses = MakeUnique(); + grpc_lb_addresses* addresses = grpc_lb_addresses_create( + path_parts.count, nullptr /* user_data_vtable */); bool errors_found = false; - for (size_t i = 0; i < path_parts.count; i++) { + for (size_t i = 0; i < addresses->num_addresses; i++) { grpc_uri ith_uri = *args.uri; - UniquePtr part_str(grpc_slice_to_c_string(path_parts.slices[i])); - ith_uri.path = part_str.get(); - grpc_resolved_address addr; - if (!parse(&ith_uri, &addr)) { + char* part_str = grpc_slice_to_c_string(path_parts.slices[i]); + ith_uri.path = part_str; + if (!parse(&ith_uri, &addresses->addresses[i].address)) { errors_found = true; /* GPR_TRUE */ - break; } - addresses->emplace_back(addr, nullptr /* args */); + gpr_free(part_str); + if (errors_found) break; } grpc_slice_buffer_destroy_internal(&path_parts); grpc_slice_unref_internal(path_slice); if (errors_found) { + grpc_lb_addresses_destroy(addresses); return OrphanablePtr(nullptr); } // Instantiate resolver. - return OrphanablePtr( - New(args, std::move(addresses))); + return OrphanablePtr(New(args, addresses)); } class IPv4ResolverFactory : public ResolverFactory { 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 22b06db45c4..4f7fd6b4243 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -30,11 +30,9 @@ #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/status_util.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/uri/uri_parser.h" // As per the retry design, we do not allow more than 5 retry attempts. #define MAX_MAX_RETRY_ATTEMPTS 5 @@ -101,18 +99,12 @@ void ProcessedResolverResult::ProcessLbPolicyName( } // 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; - } - } - if (found_balancer_address) { + const grpc_arg* channel_arg = + grpc_channel_args_find(resolver_result, GRPC_ARG_LB_ADDRESSES); + if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) { + grpc_lb_addresses* addresses = + static_cast(channel_arg->value.pointer.p); + if (grpc_lb_addresses_contains_balancer_address(*addresses)) { if (lb_policy_name_ != nullptr && strcmp(lb_policy_name_.get(), "grpclb") != 0) { gpr_log(GPR_INFO, diff --git a/src/core/ext/filters/client_channel/server_address.cc b/src/core/ext/filters/client_channel/server_address.cc deleted file mode 100644 index ec33cbbd956..00000000000 --- a/src/core/ext/filters/client_channel/server_address.cc +++ /dev/null @@ -1,103 +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/server_address.h" - -#include - -namespace grpc_core { - -// -// ServerAddress -// - -ServerAddress::ServerAddress(const grpc_resolved_address& address, - grpc_channel_args* args) - : address_(address), args_(args) {} - -ServerAddress::ServerAddress(const void* address, size_t address_len, - grpc_channel_args* args) - : args_(args) { - memcpy(address_.addr, address, address_len); - address_.len = static_cast(address_len); -} - -int ServerAddress::Cmp(const ServerAddress& other) const { - if (address_.len > other.address_.len) return 1; - if (address_.len < other.address_.len) return -1; - int retval = memcmp(address_.addr, other.address_.addr, address_.len); - if (retval != 0) return retval; - return grpc_channel_args_compare(args_, other.args_); -} - -bool ServerAddress::IsBalancer() const { - return grpc_channel_arg_get_bool( - 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 deleted file mode 100644 index 3a1bf1df67d..00000000000 --- a/src/core/ext/filters/client_channel/server_address.h +++ /dev/null @@ -1,108 +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_SERVER_ADDRESS_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H - -#include - -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gprpp/inlined_vector.h" -#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" - -// Channel arg key for a string indicating an address's balancer name. -#define GRPC_ARG_ADDRESS_BALANCER_NAME "grpc.address_balancer_name" - -namespace grpc_core { - -// -// ServerAddress -// - -// A server address is a grpc_resolved_address with an associated set of -// channel args. Any args present here will be merged into the channel -// args when a subchannel is created for this address. -class ServerAddress { - public: - // Takes ownership of args. - ServerAddress(const grpc_resolved_address& address, grpc_channel_args* args); - ServerAddress(const void* address, size_t address_len, - grpc_channel_args* args); - - ~ServerAddress() { grpc_channel_args_destroy(args_); } - - // Copyable. - ServerAddress(const ServerAddress& other) - : address_(other.address_), args_(grpc_channel_args_copy(other.args_)) {} - ServerAddress& operator=(const ServerAddress& other) { - address_ = other.address_; - grpc_channel_args_destroy(args_); - args_ = grpc_channel_args_copy(other.args_); - return *this; - } - - // Movable. - ServerAddress(ServerAddress&& other) - : address_(other.address_), args_(other.args_) { - other.args_ = nullptr; - } - ServerAddress& operator=(ServerAddress&& other) { - address_ = other.address_; - args_ = other.args_; - other.args_ = nullptr; - return *this; - } - - bool operator==(const ServerAddress& other) const { return Cmp(other) == 0; } - - int Cmp(const ServerAddress& other) const; - - const grpc_resolved_address& address() const { return address_; } - const grpc_channel_args* args() const { return args_; } - - bool IsBalancer() const; - - private: - grpc_resolved_address address_; - grpc_channel_args* args_; -}; - -// -// ServerAddressList -// - -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/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 9077aa97539..af55f7710e2 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -837,7 +837,7 @@ static bool publish_transport_locked(grpc_subchannel* c) { /* publish */ c->connected_subchannel.reset(grpc_core::New( - stk, c->args, c->channelz_subchannel, socket_uuid)); + stk, c->channelz_subchannel, socket_uuid)); gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", c->connected_subchannel.get(), c); @@ -1068,18 +1068,16 @@ grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) { namespace grpc_core { ConnectedSubchannel::ConnectedSubchannel( - grpc_channel_stack* channel_stack, const grpc_channel_args* args, + grpc_channel_stack* channel_stack, 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"); } diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 14f87f2c68e..69c2456ec20 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -85,31 +85,28 @@ class ConnectedSubchannel : public RefCounted { size_t parent_data_size; }; - ConnectedSubchannel( - grpc_channel_stack* channel_stack, const grpc_channel_args* args, + explicit ConnectedSubchannel( + grpc_channel_stack* channel_stack, grpc_core::RefCountedPtr channelz_subchannel, intptr_t socket_uuid); ~ConnectedSubchannel(); + grpc_channel_stack* channel_stack() { return channel_stack_; } void NotifyOnStateChange(grpc_pollset_set* interested_parties, 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_channel_stack* channel_stack() const { return channel_stack_; } - const grpc_channel_args* args() const { return args_; } - channelz::SubchannelNode* channelz_subchannel() const { + channelz::SubchannelNode* channelz_subchannel() { return channelz_subchannel_.get(); } - intptr_t socket_uuid() const { return socket_uuid_; } + intptr_t socket_uuid() { return socket_uuid_; } size_t GetInitialCallSizeEstimate(size_t parent_data_size) const; private: grpc_channel_stack* channel_stack_; - grpc_channel_args* args_; // ref counted pointer to the channelz node in this connected subchannel's // owning subchannel. grpc_core::RefCountedPtr diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc index 0839bdfef2d..1b66dceb130 100644 --- a/src/core/lib/iomgr/sockaddr_utils.cc +++ b/src/core/lib/iomgr/sockaddr_utils.cc @@ -217,7 +217,6 @@ void grpc_string_to_sockaddr(grpc_resolved_address* out, char* addr, int port) { } char* grpc_sockaddr_to_uri(const grpc_resolved_address* resolved_addr) { - if (resolved_addr->len == 0) return nullptr; grpc_resolved_address addr_normalized; if (grpc_sockaddr_is_v4mapped(resolved_addr, &addr_normalized)) { resolved_addr = &addr_normalized; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index c6ca970beee..ce65c594fe2 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -322,6 +322,7 @@ CORE_SOURCE_FILES = [ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -330,7 +331,6 @@ CORE_SOURCE_FILES = [ '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/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/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 1a7a7c9ccc9..76769b2b64a 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -21,10 +21,10 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver.h" #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/lib/channel/channel_args.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -63,9 +63,8 @@ static grpc_address_resolver_vtable test_resolver = {my_resolve_address, static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_core::UniquePtr* addresses, - bool check_grpclb, char** service_config_json, int query_timeout_ms, - grpc_combiner* combiner) { + grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, + int query_timeout_ms, grpc_combiner* combiner) { gpr_mu_lock(&g_mu); GPR_ASSERT(0 == strcmp("test", addr)); grpc_error* error = GRPC_ERROR_NONE; @@ -75,8 +74,9 @@ static grpc_ares_request* my_dns_lookup_ares_locked( error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { gpr_mu_unlock(&g_mu); - *addresses = grpc_core::MakeUnique(); - (*addresses)->emplace_back(nullptr, 0, nullptr); + *lb_addrs = grpc_lb_addresses_create(1, nullptr); + grpc_lb_addresses_set_address(*lb_addrs, 0, nullptr, 0, false, nullptr, + nullptr); } GRPC_CLOSURE_SCHED(on_done, error); return nullptr; 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..cdbe33dbe79 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -22,7 +22,6 @@ #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/lib/channel/channel_args.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/combiner.h" @@ -41,9 +40,8 @@ static grpc_combiner* g_combiner; static grpc_ares_request* (*g_default_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_core::UniquePtr* addresses, - bool check_grpclb, char** service_config_json, int query_timeout_ms, - grpc_combiner* combiner); + grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + int query_timeout_ms, grpc_combiner* combiner); // Counter incremented by test_resolve_address_impl indicating the number of // times a system-level resolution has happened. @@ -92,12 +90,11 @@ static grpc_address_resolver_vtable test_resolver = { static grpc_ares_request* test_dns_lookup_ares_locked( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_core::UniquePtr* addresses, - bool check_grpclb, char** service_config_json, int query_timeout_ms, - grpc_combiner* combiner) { + grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + int query_timeout_ms, grpc_combiner* combiner) { grpc_ares_request* result = g_default_dns_lookup_ares_locked( - dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, - addresses, check_grpclb, service_config_json, query_timeout_ms, combiner); + dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, addrs, + check_grpclb, service_config_json, query_timeout_ms, combiner); ++g_resolution_count; static grpc_millis last_resolution_time = 0; if (last_resolution_time == 0) { diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc index 3b06fe063ae..6362b95e50e 100644 --- a/test/core/client_channel/resolvers/fake_resolver_test.cc +++ b/test/core/client_channel/resolvers/fake_resolver_test.cc @@ -22,10 +22,10 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy_factory.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/resolver_registry.h" -#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/combiner.h" @@ -63,14 +63,12 @@ void on_resolution_cb(void* arg, grpc_error* error) { // 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]); - } + const grpc_lb_addresses* actual_lb_addresses = + grpc_lb_addresses_find_channel_arg(res->resolver_result); + const grpc_lb_addresses* expected_lb_addresses = + grpc_lb_addresses_find_channel_arg(res->expected_resolver_result); + GPR_ASSERT( + grpc_lb_addresses_cmp(actual_lb_addresses, expected_lb_addresses) == 0); grpc_channel_args_destroy(res->resolver_result); grpc_channel_args_destroy(res->expected_resolver_result); gpr_event_set(&res->ev, (void*)1); @@ -82,35 +80,27 @@ static grpc_channel_args* create_new_resolver_result() { const size_t num_addresses = 2; char* uri_string; char* balancer_name; - // Create address list. - grpc_core::ServerAddressList addresses; + // Create grpc_lb_addresses. + grpc_lb_addresses* addresses = + grpc_lb_addresses_create(num_addresses, nullptr); 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); grpc_uri* uri = grpc_uri_parse(uri_string, true); gpr_asprintf(&balancer_name, "balancer%" PRIuPTR, test_counter * num_addresses + i); - grpc_resolved_address address; - GPR_ASSERT(grpc_parse_uri(uri, &address)); - grpc_core::InlinedVector args_to_add; - const bool is_balancer = num_addresses % 2; - if (is_balancer) { - args_to_add.emplace_back(grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); - args_to_add.emplace_back(grpc_channel_arg_string_create( - const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), balancer_name)); - } - 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_lb_addresses_set_address_from_uri( + addresses, i, uri, bool(num_addresses % 2), balancer_name, nullptr); 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); + // Convert grpc_lb_addresses to grpc_channel_args. + const grpc_arg addresses_arg = + grpc_lb_addresses_create_channel_arg(addresses); grpc_channel_args* results = grpc_channel_args_copy_and_add(nullptr, &addresses_arg, 1); + grpc_lb_addresses_destroy(addresses); ++test_counter; return results; } diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index fbf6379a698..9b6eddee6e1 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -24,8 +24,8 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -325,7 +325,7 @@ typedef struct addr_req { char* addr; grpc_closure* on_done; grpc_resolved_addresses** addrs; - grpc_core::UniquePtr* addresses; + grpc_lb_addresses** lb_addrs; } addr_req; static void finish_resolve(void* arg, grpc_error* error) { @@ -340,9 +340,11 @@ static void finish_resolve(void* arg, grpc_error* error) { gpr_malloc(sizeof(*addrs->addrs))); addrs->addrs[0].len = 0; *r->addrs = addrs; - } else if (r->addresses != nullptr) { - *r->addresses = grpc_core::MakeUnique(); - (*r->addresses)->emplace_back(nullptr, 0, nullptr); + } else if (r->lb_addrs != nullptr) { + grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(1, nullptr); + grpc_lb_addresses_set_address(lb_addrs, 0, nullptr, 0, false, nullptr, + nullptr); + *r->lb_addrs = lb_addrs; } GRPC_CLOSURE_SCHED(r->on_done, GRPC_ERROR_NONE); } else { @@ -352,17 +354,18 @@ static void finish_resolve(void* arg, grpc_error* error) { } gpr_free(r->addr); - grpc_core::Delete(r); + gpr_free(r); } void my_resolve_address(const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_resolved_addresses** addrs) { - addr_req* r = grpc_core::New(); + grpc_resolved_addresses** addresses) { + addr_req* r = static_cast(gpr_malloc(sizeof(*r))); r->addr = gpr_strdup(addr); r->on_done = on_done; - r->addrs = addrs; + r->addrs = addresses; + r->lb_addrs = nullptr; grpc_timer_init( &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); @@ -374,14 +377,13 @@ static grpc_address_resolver_vtable fuzzer_resolver = {my_resolve_address, grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_core::UniquePtr* addresses, - bool check_grpclb, char** service_config_json, int query_timeout, - grpc_combiner* combiner) { + grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, + int query_timeout, grpc_combiner* combiner) { addr_req* r = static_cast(gpr_malloc(sizeof(*r))); r->addr = gpr_strdup(addr); r->on_done = on_done; r->addrs = nullptr; - r->addresses = addresses; + r->lb_addrs = lb_addrs; grpc_timer_init( &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 7e3b418cd94..66e8ca51614 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -28,8 +28,8 @@ #include #include #include +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr.h" #include "test/core/end2end/cq_verifier.h" @@ -47,9 +47,8 @@ static int g_resolve_port = -1; static grpc_ares_request* (*iomgr_dns_lookup_ares_locked)( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_core::UniquePtr* addresses, - bool check_grpclb, char** service_config_json, int query_timeout_ms, - grpc_combiner* combiner); + grpc_lb_addresses** addresses, bool check_grpclb, + char** service_config_json, int query_timeout_ms, grpc_combiner* combiner); static void (*iomgr_cancel_ares_request_locked)(grpc_ares_request* request); @@ -104,12 +103,11 @@ static grpc_address_resolver_vtable test_resolver = { static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_core::UniquePtr* addresses, - bool check_grpclb, char** service_config_json, int query_timeout_ms, - grpc_combiner* combiner) { + grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, + int query_timeout_ms, grpc_combiner* combiner) { if (0 != strcmp(addr, "test")) { return iomgr_dns_lookup_ares_locked( - dns_server, addr, default_port, interested_parties, on_done, addresses, + dns_server, addr, default_port, interested_parties, on_done, lb_addrs, check_grpclb, service_config_json, query_timeout_ms, combiner); } @@ -119,12 +117,15 @@ static grpc_ares_request* my_dns_lookup_ares_locked( gpr_mu_unlock(&g_mu); error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { - *addresses = grpc_core::MakeUnique(); - grpc_sockaddr_in sa; - sa.sin_family = GRPC_AF_INET; - sa.sin_addr.s_addr = 0x100007f; - sa.sin_port = grpc_htons(static_cast(g_resolve_port)); - (*addresses)->emplace_back(&sa, sizeof(sa), nullptr); + *lb_addrs = grpc_lb_addresses_create(1, nullptr); + grpc_sockaddr_in* sa = + static_cast(gpr_zalloc(sizeof(grpc_sockaddr_in))); + sa->sin_family = GRPC_AF_INET; + sa->sin_addr.s_addr = 0x100007f; + sa->sin_port = grpc_htons(static_cast(g_resolve_port)); + grpc_lb_addresses_set_address(*lb_addrs, 0, sa, sizeof(*sa), false, nullptr, + nullptr); + gpr_free(sa); gpr_mu_unlock(&g_mu); } GRPC_CLOSURE_SCHED(on_done, error); diff --git a/test/core/end2end/no_server_test.cc b/test/core/end2end/no_server_test.cc index c289e719eea..5dda748f5a5 100644 --- a/test/core/end2end/no_server_test.cc +++ b/test/core/end2end/no_server_test.cc @@ -23,7 +23,6 @@ #include #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" -#include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/test_config.h" diff --git a/test/core/util/ubsan_suppressions.txt b/test/core/util/ubsan_suppressions.txt index 8ed7d4d7fb6..63898ea3b1c 100644 --- a/test/core/util/ubsan_suppressions.txt +++ b/test/core/util/ubsan_suppressions.txt @@ -25,6 +25,7 @@ alignment:absl::little_endian::Store64 alignment:absl::little_endian::Load64 float-divide-by-zero:grpc::testing::postprocess_scenario_result enum:grpc_op_string +nonnull-attribute:grpc_lb_addresses_copy signed-integer-overflow:chrono enum:grpc_http2_error_to_grpc_status -enum:grpc_chttp2_cancel_stream +enum:grpc_chttp2_cancel_stream \ No newline at end of file diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index 124557eb567..bf321d8a89e 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -34,9 +34,7 @@ #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/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -218,31 +216,23 @@ class ClientChannelStressTest { void SetNextResolution(const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_core::ServerAddressList addresses; - for (const auto& addr : address_data) { + grpc_lb_addresses* addresses = + grpc_lb_addresses_create(address_data.size(), nullptr); + for (size_t i = 0; i < address_data.size(); ++i) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port); + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].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; - if (addr.is_balancer) { - args_to_add.emplace_back(grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); - args_to_add.emplace_back(grpc_channel_arg_string_create( - const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), - const_cast(addr.balancer_name.c_str()))); - } - 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_lb_addresses_set_address_from_uri( + addresses, i, lb_uri, address_data[i].is_balancer, + address_data[i].balancer_name.c_str(), nullptr); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } - grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); + grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); grpc_channel_args fake_result = {1, &fake_addresses}; response_generator_->SetResponse(&fake_result); + grpc_lb_addresses_destroy(addresses); } void KeepSendingRequests() { diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 929c2bb5899..1dfa91a76c7 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -35,9 +35,7 @@ #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/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/gpr/env.h" @@ -161,22 +159,24 @@ class ClientLbEnd2endTest : public ::testing::Test { } grpc_channel_args* BuildFakeResults(const std::vector& ports) { - grpc_core::ServerAddressList addresses; - for (const int& port : ports) { + grpc_lb_addresses* addresses = + grpc_lb_addresses_create(ports.size(), nullptr); + for (size_t i = 0; i < ports.size(); ++i) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", port); + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", ports[i]); 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)); - addresses.emplace_back(address.addr, address.len, nullptr /* args */); + grpc_lb_addresses_set_address_from_uri(addresses, i, lb_uri, + false /* is balancer */, + "" /* balancer name */, nullptr); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } const grpc_arg fake_addresses = - CreateServerAddressListChannelArg(&addresses); + grpc_lb_addresses_create_channel_arg(addresses); grpc_channel_args* fake_results = grpc_channel_args_copy_and_add(nullptr, &fake_addresses, 1); + grpc_lb_addresses_destroy(addresses); return fake_results; } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index bf990a07b5a..9c4cd050619 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -32,9 +32,7 @@ #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" @@ -488,27 +486,18 @@ class GrpclbEnd2endTest : public ::testing::Test { grpc::string balancer_name; }; - grpc_core::ServerAddressList CreateLbAddressesFromAddressDataList( + grpc_lb_addresses* CreateLbAddressesFromAddressDataList( const std::vector& address_data) { - grpc_core::ServerAddressList addresses; - for (const auto& addr : address_data) { + grpc_lb_addresses* addresses = + grpc_lb_addresses_create(address_data.size(), nullptr); + for (size_t i = 0; i < address_data.size(); ++i) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port); + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].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; - if (addr.is_balancer) { - args_to_add.emplace_back(grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); - args_to_add.emplace_back(grpc_channel_arg_string_create( - const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), - const_cast(addr.balancer_name.c_str()))); - } - 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_lb_addresses_set_address_from_uri( + addresses, i, lb_uri, address_data[i].is_balancer, + address_data[i].balancer_name.c_str(), nullptr); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } @@ -517,21 +506,23 @@ class GrpclbEnd2endTest : public ::testing::Test { void SetNextResolution(const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_core::ServerAddressList addresses = + grpc_lb_addresses* addresses = CreateLbAddressesFromAddressDataList(address_data); - grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); + grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); grpc_channel_args fake_result = {1, &fake_addresses}; response_generator_->SetResponse(&fake_result); + grpc_lb_addresses_destroy(addresses); } void SetNextReresolutionResponse( const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_core::ServerAddressList addresses = + grpc_lb_addresses* addresses = CreateLbAddressesFromAddressDataList(address_data); - grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); + grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); grpc_channel_args fake_result = {1, &fake_addresses}; response_generator_->SetReresolutionResponse(&fake_result); + grpc_lb_addresses_destroy(addresses); } const std::vector GetBackendPorts(const size_t start_index = 0) const { diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index 09e705df789..3eb0e7d7254 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -37,7 +37,6 @@ #include "src/core/ext/filters/client_channel/resolver.h" #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/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" @@ -168,26 +167,30 @@ void OverrideAddressSortingSourceAddrFactory( address_sorting_override_source_addr_factory_for_testing(factory); } -grpc_core::ServerAddressList BuildLbAddrInputs( - const std::vector& test_addrs) { - grpc_core::ServerAddressList addresses; - for (const auto& addr : test_addrs) { - addresses.emplace_back(TestAddressToGrpcResolvedAddress(addr), nullptr); +grpc_lb_addresses* BuildLbAddrInputs(std::vector test_addrs) { + grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(0, nullptr); + lb_addrs->addresses = + (grpc_lb_address*)gpr_zalloc(sizeof(grpc_lb_address) * test_addrs.size()); + lb_addrs->num_addresses = test_addrs.size(); + for (size_t i = 0; i < test_addrs.size(); i++) { + lb_addrs->addresses[i].address = + TestAddressToGrpcResolvedAddress(test_addrs[i]); } - return addresses; + return lb_addrs; } -void VerifyLbAddrOutputs(const grpc_core::ServerAddressList addresses, +void VerifyLbAddrOutputs(grpc_lb_addresses* lb_addrs, std::vector expected_addrs) { - EXPECT_EQ(addresses.size(), expected_addrs.size()); - for (size_t i = 0; i < addresses.size(); ++i) { + EXPECT_EQ(lb_addrs->num_addresses, expected_addrs.size()); + for (size_t i = 0; i < lb_addrs->num_addresses; i++) { char* ip_addr_str; - grpc_sockaddr_to_string(&ip_addr_str, &addresses[i].address(), + grpc_sockaddr_to_string(&ip_addr_str, &lb_addrs->addresses[i].address, false /* normalize */); EXPECT_EQ(expected_addrs[i], ip_addr_str); gpr_free(ip_addr_str); } grpc_core::ExecCtx exec_ctx; + grpc_lb_addresses_destroy(lb_addrs); } /* We need to run each test case inside of its own @@ -209,11 +212,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) { { {"1.2.3.4:443", {"4.3.2.1:443", AF_INET}}, }); - auto lb_addrs = BuildLbAddrInputs({ + auto* lb_addrs = BuildLbAddrInputs({ {"1.2.3.4:443", AF_INET}, {"5.6.7.8:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "1.2.3.4:443", "5.6.7.8:443", @@ -232,7 +235,7 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) { {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "1.2.3.4:443", "[2607:f8b0:400a:801::1002]:443", @@ -248,11 +251,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) { {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}}, {"[2607:f8b0:400a:801::1002]:443", {"[fec0::1234]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2607:f8b0:400a:801::1002]:443", "1.2.3.4:443", @@ -272,11 +275,11 @@ TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) { {"[fec0::5000]:443", {"[fec0::5001]:0", AF_INET6}}, // site-local and site-local scope }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[2000:f8b0:400a:801::1002]:443", AF_INET6}, {"[fec0::5000]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fec0::5000]:443", "[2000:f8b0:400a:801::1002]:443", @@ -295,11 +298,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) { {"[2001::5001]:443", {"[2001::5002]:0", AF_INET6}}, // matching labels }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[2002::5001]:443", AF_INET6}, {"[2001::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2001::5001]:443", "[2002::5001]:443", @@ -318,11 +321,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) { {"[2001::5001]:443", {"[2001::5002]:0", AF_INET6}}, // matching labels }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[2001::5001]:443", AF_INET6}, {"[2002::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2001::5001]:443", "[2002::5001]:443", @@ -341,11 +344,11 @@ TEST_F(AddressSortingTest, {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}}, {"1.2.3.4:443", {"5.6.7.8:0", AF_INET}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs( lb_addrs, { // The AF_INET address should be IPv4-mapped by the sort, @@ -374,11 +377,11 @@ TEST_F(AddressSortingTest, {"[::1]:443", {"[::1]:0", AF_INET6}}, {v4_compat_dest, {v4_compat_src, AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {v4_compat_dest, AF_INET6}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", v4_compat_dest, @@ -397,11 +400,11 @@ TEST_F(AddressSortingTest, {"[1234::2]:443", {"[1234::2]:0", AF_INET6}}, {"[::1]:443", {"[::1]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[1234::2]:443", AF_INET6}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs( lb_addrs, { @@ -421,11 +424,11 @@ TEST_F(AddressSortingTest, {"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}}, {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[2001::1234]:443", AF_INET6}, {"[2000::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs( lb_addrs, { // The 2000::/16 address should match the ::/0 prefix rule @@ -445,11 +448,11 @@ TEST_F( {"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}}, {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[2001::1231]:443", AF_INET6}, {"[2000::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2000::5001]:443", "[2001::1231]:443", @@ -466,11 +469,11 @@ TEST_F(AddressSortingTest, {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}}, {"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[fec0::1234]:443", AF_INET6}, {"[fc00::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fc00::5001]:443", "[fec0::1234]:443", @@ -491,11 +494,11 @@ TEST_F( {"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}}, {"[1234::2]:443", {"[1234::3]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[::ffff:1.1.1.2]:443", AF_INET6}, {"[1234::2]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { // ::ffff:0:2 should match the v4-mapped // precedence entry and be deprioritized. @@ -518,11 +521,11 @@ TEST_F(AddressSortingTest, TestPrefersSmallerScope) { {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}}, {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"[fec0::1234]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fec0::1234]:443", "[3ffe::5001]:443", @@ -543,11 +546,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) { {"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}}, {"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[3ffe:5001::]:443", AF_INET6}, {"[3ffe:1234::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:1234::]:443", "[3ffe:5001::]:443", @@ -564,11 +567,11 @@ TEST_F(AddressSortingTest, {"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}}, {"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1234]:443", "[3ffe::5001]:443", @@ -584,11 +587,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) { {"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}}, {"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[3ffe:8000::]:443", AF_INET6}, {"[3ffe:2000::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:2000::]:443", "[3ffe:8000::]:443", @@ -604,11 +607,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) { {"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}}, {"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[3ffe:6::]:443", AF_INET6}, {"[3ffe:c::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:c::]:443", "[3ffe:6::]:443", @@ -626,11 +629,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) { {"[3ffe:1111:1111:1110::]:443", {"[3ffe:1111:1111:1111::]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[3ffe:1111:1111:1110::]:443", AF_INET6}, {"[3ffe:1111:1111:1111::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:1111:1111:1111::]:443", "[3ffe:1111:1111:1110::]:443", @@ -648,11 +651,11 @@ TEST_F(AddressSortingTest, TestStableSort) { {"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}}, {"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1234]:443", "[3ffe::1235]:443", @@ -671,14 +674,14 @@ TEST_F(AddressSortingTest, TestStableSortFiveElements) { {"[3ffe::1234]:443", {"[3ffe::1204]:0", AF_INET6}}, {"[3ffe::1235]:443", {"[3ffe::1205]:0", AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[3ffe::1231]:443", AF_INET6}, {"[3ffe::1232]:443", AF_INET6}, {"[3ffe::1233]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1231]:443", "[3ffe::1232]:443", @@ -692,14 +695,14 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) { bool ipv4_supported = true; bool ipv6_supported = true; OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {}); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[3ffe::1231]:443", AF_INET6}, {"[3ffe::1232]:443", AF_INET6}, {"[3ffe::1233]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1231]:443", "[3ffe::1232]:443", @@ -713,11 +716,11 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) { bool ipv4_supported = true; bool ipv6_supported = true; OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {}); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[::ffff:5.6.7.8]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::ffff:5.6.7.8]:443", "1.2.3.4:443", @@ -741,11 +744,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) { {"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}}, {v4_compat_dest, {v4_compat_src, AF_INET6}}, }); - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[fec0::2000]:443", AF_INET6}, {v4_compat_dest, AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { // The sort should be stable since @@ -762,11 +765,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) { * (whether ipv4 loopback is available or not, an available ipv6 * loopback should be preferred). */ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) { - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"[::1]:443", AF_INET6}, {"127.0.0.1:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", "127.0.0.1:443", @@ -776,11 +779,11 @@ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) { /* Flip the order of the inputs above and expect the same output order * (try to rule out influence of arbitrary qsort ordering) */ TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) { - auto lb_addrs = BuildLbAddrInputs({ + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ {"127.0.0.1:443", AF_INET}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(&lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", "127.0.0.1:443", diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 2ac2c237cea..fe6fcb8d9cb 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -41,7 +41,6 @@ #include "src/core/ext/filters/client_channel/resolver.h" #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/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" @@ -383,19 +382,23 @@ 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); + const grpc_arg* channel_arg = + grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES); + GPR_ASSERT(channel_arg != nullptr); + GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER); + grpc_lb_addresses* addresses = + (grpc_lb_addresses*)channel_arg->value.pointer.p; gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR, - addresses->size(), args->expected_addrs.size()); - GPR_ASSERT(addresses->size() == args->expected_addrs.size()); + addresses->num_addresses, args->expected_addrs.size()); + GPR_ASSERT(addresses->num_addresses == 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 < addresses->num_addresses; i++) { + grpc_lb_address addr = addresses->addresses[i]; char* str; - grpc_sockaddr_to_string(&str, &addr.address(), 1 /* normalize */); + 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())); + GrpcLBAddress(std::string(str), addr.is_balancer)); gpr_free(str); } if (args->expected_addrs.size() != found_lb_addrs.size()) { diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 5011e19b03a..dd5bead58ca 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -923,6 +923,7 @@ 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.cc \ 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 \ @@ -958,8 +959,6 @@ 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/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_index.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 2451101f58d..0a7a4daf7de 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10074,7 +10074,6 @@ "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/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" ], @@ -10102,6 +10101,7 @@ "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_factory.cc", "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", @@ -10120,8 +10120,6 @@ "src/core/ext/filters/client_channel/resolver_result_parsing.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_index.cc", From a4e9f33b85cb9fde3cb1ed51ae4b8e28811967a7 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Tue, 13 Nov 2018 16:38:44 -0800 Subject: [PATCH 0498/2143] 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 cf4e900b82104fe792ca95f1f0b1308dc7a36b11 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Dec 2018 10:08:03 -0800 Subject: [PATCH 0499/2143] clang-format --- src/objective-c/GRPCClient/GRPCCall.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index e687a65da7d..ddc6ae054d3 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -253,7 +253,8 @@ extern id const kGRPCTrailersKey; + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path; /** - * Set the dispatch queue to be used for callbacks. Current implementation requires \a queue to be a serial queue. + * Set the dispatch queue to be used for callbacks. Current implementation requires \a queue to be a + * serial queue. * * This configuration is only effective before the call starts. */ From ef7d45d2ab2679ecd1ed08f6ce897063a4f783da Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Dec 2018 12:14:24 -0800 Subject: [PATCH 0500/2143] Add next_value and start_time --- src/core/lib/gpr/sync_posix.cc | 8 ++++++-- src/core/lib/iomgr/exec_ctx.cc | 13 +++++++++++++ src/core/lib/iomgr/timer_manager.cc | 6 ++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 4ded03055c8..6b6c6b6c4b7 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -39,7 +39,8 @@ void (*g_grpc_debug_timer_manager_stats)( int64_t abs_deadline_nsec_value, int64_t now1_sec_value, int64_t now1_nsec_value, int64_t now2_sec_value, int64_t now2_nsec_value, int64_t add_result_sec_value, int64_t add_result_nsec_value, - int64_t sub_result_sec_value, int64_t sub_result_nsec_value) = nullptr; + int64_t sub_result_sec_value, int64_t sub_result_nsec_value, + int64_t next_value, int64_t start_time_sec, int64_t start_time_nsec) = nullptr; int64_t g_timer_manager_init_count = 0; int64_t g_timer_manager_shutdown_count = 0; int64_t g_fork_count = 0; @@ -58,6 +59,9 @@ int64_t g_add_result_sec_value = -1; int64_t g_add_result_nsec_value = -1; int64_t g_sub_result_sec_value = -1; int64_t g_sub_result_nsec_value = -1; +int64_t g_next_value = -1; +int64_t g_start_time_sec = -1; +int64_t g_start_time_nsec = -1; #endif // GRPC_DEBUG_TIMER_MANAGER #ifdef GPR_LOW_LEVEL_COUNTERS @@ -212,7 +216,7 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { g_abs_deadline_nsec_value, g_now1_sec_value, g_now1_nsec_value, g_now2_sec_value, g_now2_nsec_value, g_add_result_sec_value, g_add_result_nsec_value, g_sub_result_sec_value, - g_sub_result_nsec_value); + g_sub_result_nsec_value, g_next_value, g_start_time_sec, g_start_time_nsec); } } #endif diff --git a/src/core/lib/iomgr/exec_ctx.cc b/src/core/lib/iomgr/exec_ctx.cc index d68fa0714bf..683dd2f6493 100644 --- a/src/core/lib/iomgr/exec_ctx.cc +++ b/src/core/lib/iomgr/exec_ctx.cc @@ -53,6 +53,13 @@ static void exec_ctx_sched(grpc_closure* closure, grpc_error* error) { static gpr_timespec g_start_time; +// For debug of the timer manager crash only. +// TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER +extern int64_t g_start_time_sec; +extern int64_t g_start_time_nsec; +#endif // GRPC_DEBUG_TIMER_MANAGER + static grpc_millis timespec_to_millis_round_down(gpr_timespec ts) { ts = gpr_time_sub(ts, g_start_time); double x = GPR_MS_PER_SEC * static_cast(ts.tv_sec) + @@ -117,6 +124,12 @@ void ExecCtx::TestOnlyGlobalInit(gpr_timespec new_val) { void ExecCtx::GlobalInit(void) { g_start_time = gpr_now(GPR_CLOCK_MONOTONIC); + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER + g_start_time_sec = g_start_time.tv_sec; + g_start_time_nsec = g_start_time.tv_nsec; +#endif gpr_tls_init(&exec_ctx_); } diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index ceba79f6783..143a96c9bc2 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -67,6 +67,7 @@ static void timer_thread(void* completed_thread_ptr); extern int64_t g_timer_manager_init_count; extern int64_t g_timer_manager_shutdown_count; extern int64_t g_fork_count; +extern int64_t g_next_value; #endif // GRPC_DEBUG_TIMER_MANAGER static void gc_completed_threads(void) { @@ -193,6 +194,11 @@ static bool wait_until(grpc_millis next) { gpr_log(GPR_INFO, "sleep until kicked"); } + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER + g_next_value = next; +#endif gpr_cv_wait(&g_cv_wait, &g_mu, grpc_millis_to_timespec(next, GPR_CLOCK_MONOTONIC)); From eea5f1ad3dee4d96c9b86efe89f75c973cc57eed Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Dec 2018 12:38:05 -0800 Subject: [PATCH 0501/2143] Missing nullable --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index b549f5d2bf3..4ef8cee36de 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -282,7 +282,7 @@ NS_ASSUME_NONNULL_END */ @interface GRPCCall : GRXWriter -- (instancetype)init NS_UNAVAILABLE; +- (nullable instancetype)init NS_UNAVAILABLE; /** * The container of the request headers of an RPC conforms to this protocol, which is a subset of From e9dd13bfcf8d5e699582b92376548038ab635c7c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Dec 2018 12:51:33 -0800 Subject: [PATCH 0502/2143] clang-format --- src/core/lib/gpr/sync_posix.cc | 6 ++++-- src/core/lib/iomgr/timer_manager.cc | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 6b6c6b6c4b7..c09a7598acb 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -40,7 +40,8 @@ void (*g_grpc_debug_timer_manager_stats)( int64_t now1_nsec_value, int64_t now2_sec_value, int64_t now2_nsec_value, int64_t add_result_sec_value, int64_t add_result_nsec_value, int64_t sub_result_sec_value, int64_t sub_result_nsec_value, - int64_t next_value, int64_t start_time_sec, int64_t start_time_nsec) = nullptr; + int64_t next_value, int64_t start_time_sec, + int64_t start_time_nsec) = nullptr; int64_t g_timer_manager_init_count = 0; int64_t g_timer_manager_shutdown_count = 0; int64_t g_fork_count = 0; @@ -216,7 +217,8 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { g_abs_deadline_nsec_value, g_now1_sec_value, g_now1_nsec_value, g_now2_sec_value, g_now2_nsec_value, g_add_result_sec_value, g_add_result_nsec_value, g_sub_result_sec_value, - g_sub_result_nsec_value, g_next_value, g_start_time_sec, g_start_time_nsec); + g_sub_result_nsec_value, g_next_value, g_start_time_sec, + g_start_time_nsec); } } #endif diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index 143a96c9bc2..cb123298cf5 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -194,8 +194,8 @@ static bool wait_until(grpc_millis next) { gpr_log(GPR_INFO, "sleep until kicked"); } - // For debug of the timer manager crash only. - // TODO (mxyan): remove after bug is fixed. + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER g_next_value = next; #endif From f52e54235294cb71c09d880e8f78a6661b2803f2 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 10 Dec 2018 12:45:00 -0800 Subject: [PATCH 0503/2143] Add pagination to serversockets --- src/core/lib/channel/channelz.cc | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 0cb28905181..8d449ee6721 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -204,16 +204,27 @@ ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes) ServerNode::~ServerNode() {} char* ServerNode::RenderServerSockets(intptr_t start_socket_id) { + const int kPaginationLimit = 100; grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; ChildSocketsList socket_refs; grpc_server_populate_server_sockets(server_, &socket_refs, start_socket_id); + int sockets_added = 0; + bool reached_pagination_limit = false; if (!socket_refs.empty()) { // create list of socket refs grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); for (size_t i = 0; i < socket_refs.size(); ++i) { + // check if we are over pagination limit to determine if we need to set + // the "end" element. If we don't go through this block, we know that + // when the loop terminates, we have <= to kPaginationLimit. + if (sockets_added == kPaginationLimit) { + reached_pagination_limit = true; + break; + } + sockets_added++; grpc_json* socket_ref_json = grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false); @@ -223,11 +234,10 @@ char* ServerNode::RenderServerSockets(intptr_t start_socket_id) { socket_refs[i]->remote(), GRPC_JSON_STRING, false); } } - // For now we do not have any pagination rules. In the future we could - // pick a constant for max_channels_sent for a GetServers request. - // Tracking: https://github.com/grpc/grpc/issues/16019. - json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr, - GRPC_JSON_TRUE, false); + if (!reached_pagination_limit) { + json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr, + GRPC_JSON_TRUE, false); + } char* json_str = grpc_json_dump_to_string(top_level_json, 0); grpc_json_destroy(top_level_json); return json_str; From 8cb2d0546d14574977c4943d33bb103954078bbd Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 10 Dec 2018 16:19:35 -0800 Subject: [PATCH 0504/2143] Upgrade sanity Docker image to debian:stretch * Use latest pylint in Python 3.7 (they dropped support for PY2) * Make latest pylint happy * Forced to upgrade to shellcheck 0.4.4 * Make shellcheck 0.4.4 happy * Adopt reviewers' advice to reduce global disabled rules --- .pylintrc | 10 +++++ .pylintrc-tests | 6 +++ src/python/grpcio/grpc/_auth.py | 2 +- src/python/grpcio/grpc/_channel.py | 14 +++---- src/python/grpcio/grpc/_utilities.py | 3 -- .../grpc_testing/_server/_handler.py | 2 +- src/python/grpcio_tests/tests/_runner.py | 2 +- .../protoc_plugin/_split_definitions_test.py | 8 ++-- .../protoc_plugin/beta_python_plugin_test.py | 2 +- .../tests/qps/benchmark_client.py | 2 +- .../grpcio_tests/tests/qps/client_runner.py | 2 +- .../grpcio_tests/tests/qps/worker_server.py | 2 +- .../grpcio_tests/tests/stress/client.py | 4 +- .../tests/testing/_client_application.py | 4 +- .../tests/unit/_from_grpc_import_star.py | 2 +- .../test/sanity/Dockerfile.template | 22 +++++------ tools/distrib/pylint_code.sh | 6 +-- tools/dockerfile/test/sanity/Dockerfile | 38 +++++++++---------- .../artifacts/build_artifact_protoc.sh | 1 + .../artifacts/build_artifact_ruby.sh | 2 + tools/run_tests/artifacts/run_in_workspace.sh | 3 +- .../dockerize/build_and_run_docker.sh | 2 +- .../dockerize/build_docker_and_run_tests.sh | 4 +- .../dockerize/build_interop_image.sh | 2 +- tools/run_tests/dockerize/docker_run_tests.sh | 1 + .../run_tests/helper_scripts/run_grpc-node.sh | 2 + .../helper_scripts/run_tests_in_workspace.sh | 3 +- tools/run_tests/interop/with_nvm.sh | 1 + tools/run_tests/interop/with_rvm.sh | 1 + .../performance/build_performance.sh | 1 + .../performance/build_performance_go.sh | 3 +- .../performance/build_performance_node.sh | 1 + tools/run_tests/performance/run_worker_go.sh | 3 +- .../run_tests/performance/run_worker_node.sh | 1 + tools/run_tests/performance/run_worker_php.sh | 1 + .../run_tests/performance/run_worker_ruby.sh | 1 + 36 files changed, 94 insertions(+), 70 deletions(-) diff --git a/.pylintrc b/.pylintrc index 90e8989ffcc..ba74decb047 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,3 +1,11 @@ +[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 @@ -82,3 +90,5 @@ disable= # 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/.pylintrc-tests b/.pylintrc-tests index e68755c674e..0d408fbb565 100644 --- a/.pylintrc-tests +++ b/.pylintrc-tests @@ -1,3 +1,7 @@ +[MASTER] +ignore-patterns= + .+?(beta|framework).+?\.py + [VARIABLES] # TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection @@ -115,3 +119,5 @@ disable= # 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/src/python/grpcio/grpc/_auth.py b/src/python/grpcio/grpc/_auth.py index c17824563d7..9b990f490de 100644 --- a/src/python/grpcio/grpc/_auth.py +++ b/src/python/grpcio/grpc/_auth.py @@ -46,7 +46,7 @@ class GoogleCallCredentials(grpc.AuthMetadataPlugin): # Hack to determine if these are JWT creds and we need to pass # additional_claims when getting a token - self._is_jwt = 'additional_claims' in inspect.getargspec( + self._is_jwt = 'additional_claims' in inspect.getargspec( # pylint: disable=deprecated-method credentials.get_access_token).args def __call__(self, context, callback): diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 35fa82d56bd..951c6f33ff5 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -525,7 +525,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): state, operations, deadline, rendezvous = self._prepare( request, timeout, metadata, wait_for_ready) if state is None: - raise rendezvous + raise rendezvous # pylint: disable-msg=raising-bad-type else: call = self._channel.segregated_call( 0, self._method, None, deadline, metadata, None @@ -535,7 +535,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): ),)) event = call.next_event() _handle_event(event, state, self._response_deserializer) - return state, call, + return state, call def __call__(self, request, @@ -566,7 +566,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): state, operations, deadline, rendezvous = self._prepare( request, timeout, metadata, wait_for_ready) if state is None: - raise rendezvous + raise rendezvous # pylint: disable-msg=raising-bad-type else: event_handler = _event_handler(state, self._response_deserializer) call = self._managed_call( @@ -599,7 +599,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) if serialized_request is None: - raise rendezvous + raise rendezvous # pylint: disable-msg=raising-bad-type else: state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None) operationses = ( @@ -653,7 +653,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): state.condition.notify_all() if not state.due: break - return state, call, + return state, call def __call__(self, request_iterator, @@ -745,10 +745,10 @@ class _InitialMetadataFlags(int): def with_wait_for_ready(self, wait_for_ready): if wait_for_ready is not None: if wait_for_ready: - self = self.__class__(self | cygrpc.InitialMetadataFlags.wait_for_ready | \ + return self.__class__(self | cygrpc.InitialMetadataFlags.wait_for_ready | \ cygrpc.InitialMetadataFlags.wait_for_ready_explicitly_set) elif not wait_for_ready: - self = self.__class__(self & ~cygrpc.InitialMetadataFlags.wait_for_ready | \ + return self.__class__(self & ~cygrpc.InitialMetadataFlags.wait_for_ready | \ cygrpc.InitialMetadataFlags.wait_for_ready_explicitly_set) return self diff --git a/src/python/grpcio/grpc/_utilities.py b/src/python/grpcio/grpc/_utilities.py index d90b34bcbd4..2938a38b44e 100644 --- a/src/python/grpcio/grpc/_utilities.py +++ b/src/python/grpcio/grpc/_utilities.py @@ -132,15 +132,12 @@ class _ChannelReadyFuture(grpc.Future): def result(self, timeout=None): self._block(timeout) - return None def exception(self, timeout=None): self._block(timeout) - return None def traceback(self, timeout=None): self._block(timeout) - return None def add_done_callback(self, fn): with self._condition: diff --git a/src/python/grpcio_testing/grpc_testing/_server/_handler.py b/src/python/grpcio_testing/grpc_testing/_server/_handler.py index 0e3404b0d06..100d8195f62 100644 --- a/src/python/grpcio_testing/grpc_testing/_server/_handler.py +++ b/src/python/grpcio_testing/grpc_testing/_server/_handler.py @@ -185,7 +185,7 @@ class _Handler(Handler): elif self._code is None: self._condition.wait() else: - return self._trailing_metadata, self._code, self._details, + return self._trailing_metadata, self._code, self._details def expire(self): with self._condition: diff --git a/src/python/grpcio_tests/tests/_runner.py b/src/python/grpcio_tests/tests/_runner.py index eaaa027e61f..9ef0f176840 100644 --- a/src/python/grpcio_tests/tests/_runner.py +++ b/src/python/grpcio_tests/tests/_runner.py @@ -203,7 +203,7 @@ class Runner(object): check_kill_self() time.sleep(0) case_thread.join() - except: + except: # pylint: disable=try-except-raise # re-raise the exception after forcing the with-block to end raise result.set_output(augmented_case.case, stdout_pipe.output(), diff --git a/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py b/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py index e21ea0010ad..2b735526cb0 100644 --- a/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py +++ b/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py @@ -144,7 +144,7 @@ class _ProtoBeforeGrpcProtocStyle(object): absolute_proto_file_names) pb2_grpc_protoc_exit_code = _protoc( proto_path, None, 'grpc_2_0', python_out, absolute_proto_file_names) - return pb2_protoc_exit_code, pb2_grpc_protoc_exit_code, + return pb2_protoc_exit_code, pb2_grpc_protoc_exit_code class _GrpcBeforeProtoProtocStyle(object): @@ -160,7 +160,7 @@ class _GrpcBeforeProtoProtocStyle(object): proto_path, None, 'grpc_2_0', python_out, absolute_proto_file_names) pb2_protoc_exit_code = _protoc(proto_path, python_out, None, None, absolute_proto_file_names) - return pb2_grpc_protoc_exit_code, pb2_protoc_exit_code, + return pb2_grpc_protoc_exit_code, pb2_protoc_exit_code _PROTOC_STYLES = ( @@ -243,9 +243,9 @@ class _Test(six.with_metaclass(abc.ABCMeta, unittest.TestCase)): def _services_modules(self): if self.PROTOC_STYLE.grpc_in_pb2_expected(): - return self._services_pb2, self._services_pb2_grpc, + return self._services_pb2, self._services_pb2_grpc else: - return self._services_pb2_grpc, + return (self._services_pb2_grpc,) def test_imported_attributes(self): self._protoc() 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 b46e53315e6..43c90af6a70 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 @@ -223,7 +223,7 @@ def _CreateService(payload_pb2, responses_pb2, service_pb2): server.start() channel = implementations.insecure_channel('localhost', port) stub = getattr(service_pb2, STUB_FACTORY_IDENTIFIER)(channel) - yield servicer_methods, stub, + yield servicer_methods, stub server.stop(0) diff --git a/src/python/grpcio_tests/tests/qps/benchmark_client.py b/src/python/grpcio_tests/tests/qps/benchmark_client.py index 0488450740a..fac0e44e5a4 100644 --- a/src/python/grpcio_tests/tests/qps/benchmark_client.py +++ b/src/python/grpcio_tests/tests/qps/benchmark_client.py @@ -180,7 +180,7 @@ class StreamingSyncBenchmarkClient(BenchmarkClient): self._streams = [ _SyncStream(self._stub, self._generic, self._request, self._handle_response) - for _ in xrange(config.outstanding_rpcs_per_channel) + for _ in range(config.outstanding_rpcs_per_channel) ] self._curr_stream = 0 diff --git a/src/python/grpcio_tests/tests/qps/client_runner.py b/src/python/grpcio_tests/tests/qps/client_runner.py index e79abab3c71..a57524c74e3 100644 --- a/src/python/grpcio_tests/tests/qps/client_runner.py +++ b/src/python/grpcio_tests/tests/qps/client_runner.py @@ -77,7 +77,7 @@ class ClosedLoopClientRunner(ClientRunner): def start(self): self._is_running = True self._client.start() - for _ in xrange(self._request_count): + for _ in range(self._request_count): self._client.send_request() def stop(self): diff --git a/src/python/grpcio_tests/tests/qps/worker_server.py b/src/python/grpcio_tests/tests/qps/worker_server.py index 337a94b546c..a03367ec63a 100644 --- a/src/python/grpcio_tests/tests/qps/worker_server.py +++ b/src/python/grpcio_tests/tests/qps/worker_server.py @@ -109,7 +109,7 @@ class WorkerServer(worker_service_pb2_grpc.WorkerServiceServicer): start_time = time.time() # Create a client for each channel - for i in xrange(config.client_channels): + for i in range(config.client_channels): server = config.server_targets[i % len(config.server_targets)] runner = self._create_client_runner(server, config, qps_data) client_runners.append(runner) diff --git a/src/python/grpcio_tests/tests/stress/client.py b/src/python/grpcio_tests/tests/stress/client.py index 41f2e1b6c2d..a318b308e61 100644 --- a/src/python/grpcio_tests/tests/stress/client.py +++ b/src/python/grpcio_tests/tests/stress/client.py @@ -132,9 +132,9 @@ def run_test(args): server.start() for test_server_target in test_server_targets: - for _ in xrange(args.num_channels_per_server): + for _ in range(args.num_channels_per_server): channel = _get_channel(test_server_target, args) - for _ in xrange(args.num_stubs_per_channel): + for _ in range(args.num_stubs_per_channel): stub = test_pb2_grpc.TestServiceStub(channel) runner = test_runner.TestRunner(stub, test_cases, hist, exception_queue, stop_event) diff --git a/src/python/grpcio_tests/tests/testing/_client_application.py b/src/python/grpcio_tests/tests/testing/_client_application.py index 3ddeba23735..4d42df03897 100644 --- a/src/python/grpcio_tests/tests/testing/_client_application.py +++ b/src/python/grpcio_tests/tests/testing/_client_application.py @@ -130,9 +130,9 @@ def _run_stream_stream(stub): request_pipe = _Pipe() response_iterator = stub.StreStre(iter(request_pipe)) request_pipe.add(_application_common.STREAM_STREAM_REQUEST) - first_responses = next(response_iterator), next(response_iterator), + first_responses = next(response_iterator), next(response_iterator) request_pipe.add(_application_common.STREAM_STREAM_REQUEST) - second_responses = next(response_iterator), next(response_iterator), + second_responses = next(response_iterator), next(response_iterator) request_pipe.close() try: next(response_iterator) diff --git a/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py b/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py index ad847ae03eb..1ada25382de 100644 --- a/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py +++ b/src/python/grpcio_tests/tests/unit/_from_grpc_import_star.py @@ -14,7 +14,7 @@ _BEFORE_IMPORT = tuple(globals()) -from grpc import * # pylint: disable=wildcard-import +from grpc import * # pylint: disable=wildcard-import,unused-wildcard-import _AFTER_IMPORT = tuple(globals()) diff --git a/templates/tools/dockerfile/test/sanity/Dockerfile.template b/templates/tools/dockerfile/test/sanity/Dockerfile.template index eac7f2ab013..a4f9183beac 100644 --- a/templates/tools/dockerfile/test/sanity/Dockerfile.template +++ b/templates/tools/dockerfile/test/sanity/Dockerfile.template @@ -14,28 +14,24 @@ # 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="../../python_stretch.include"/> <%include file="../../cxx_deps.include"/> #======================== # Sanity test dependencies + RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev + RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 + # Make Python 3.7 the default Python 3 version + RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 1 RUN apt-get update && apt-get install -y ${"\\"} - python-pip ${"\\"} autoconf ${"\\"} automake ${"\\"} libtool ${"\\"} curl ${"\\"} - python-virtualenv ${"\\"} - python-lxml ${"\\"} shellcheck - RUN pip install simplejson mako - + RUN python2 -m pip install simplejson mako virtualenv lxml + RUN python3 -m pip install simplejson mako virtualenv lxml + <%include file="../../clang5.include"/> - <%include file="../../run_tests_addons.include"/> - + # Define the default command. CMD ["bash"] - diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh index d17eb9fdb82..cb3966d6914 100755 --- a/tools/distrib/pylint_code.sh +++ b/tools/distrib/pylint_code.sh @@ -31,12 +31,12 @@ TEST_DIRS=( ) VIRTUALENV=python_pylint_venv -python -m virtualenv $VIRTUALENV +python3 -m virtualenv $VIRTUALENV PYTHON=$VIRTUALENV/bin/python -$PYTHON -m pip install --upgrade pip==10.0.1 -$PYTHON -m pip install pylint==1.9.2 +$PYTHON -m pip install --upgrade pip==18.1 +$PYTHON -m pip install --upgrade pylint==2.2.2 EXIT=0 for dir in "${DIRS[@]}"; do diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile index e6bdb4ee035..aeee02a50fa 100644 --- a/tools/dockerfile/test/sanity/Dockerfile +++ b/tools/dockerfile/test/sanity/Dockerfile @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM debian:jessie - +FROM debian:stretch + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ @@ -53,20 +53,19 @@ RUN apt-get update && apt-get install -y time && apt-get clean 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 Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 -# Install dependencies +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local -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 +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] #================= # C++ dependencies @@ -74,16 +73,18 @@ RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev c #======================== # Sanity test dependencies +RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 +# Make Python 3.7 the default Python 3 version +RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 1 RUN apt-get update && apt-get install -y \ - python-pip \ autoconf \ automake \ libtool \ curl \ - python-virtualenv \ - python-lxml \ shellcheck -RUN pip install simplejson mako +RUN python2 -m pip install simplejson mako virtualenv lxml +RUN python3 -m pip install simplejson mako virtualenv lxml RUN apt-get update && apt-get -y install wget xz-utils RUN wget http://releases.llvm.org/5.0.0/clang+llvm-5.0.0-linux-x86_64-ubuntu14.04.tar.xz @@ -94,8 +95,5 @@ RUN ln -s /clang+llvm-5.0.0-linux-x86_64-ubuntu14.04/bin/clang-tidy /usr/local/b ENV CLANG_TIDY=clang-tidy -RUN mkdir /var/local/jenkins - - # Define the default command. CMD ["bash"] diff --git a/tools/run_tests/artifacts/build_artifact_protoc.sh b/tools/run_tests/artifacts/build_artifact_protoc.sh index 6d433f2dad4..a5b6e2f3482 100755 --- a/tools/run_tests/artifacts/build_artifact_protoc.sh +++ b/tools/run_tests/artifacts/build_artifact_protoc.sh @@ -14,6 +14,7 @@ # limitations under the License. # Use devtoolset environment that has GCC 4.8 before set -ex +# shellcheck disable=SC1091 source scl_source enable devtoolset-2 set -ex diff --git a/tools/run_tests/artifacts/build_artifact_ruby.sh b/tools/run_tests/artifacts/build_artifact_ruby.sh index 5ab4cf21b4e..c910374376d 100755 --- a/tools/run_tests/artifacts/build_artifact_ruby.sh +++ b/tools/run_tests/artifacts/build_artifact_ruby.sh @@ -18,7 +18,9 @@ SYSTEM=$(uname | cut -f 1 -d_) cd "$(dirname "$0")/../../.." set +ex +# shellcheck disable=SC1091 [[ -s /etc/profile.d/rvm.sh ]] && . /etc/profile.d/rvm.sh +# shellcheck disable=SC1090 [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" set -ex diff --git a/tools/run_tests/artifacts/run_in_workspace.sh b/tools/run_tests/artifacts/run_in_workspace.sh index 20181e077c2..f4719b0a4ae 100755 --- a/tools/run_tests/artifacts/run_in_workspace.sh +++ b/tools/run_tests/artifacts/run_in_workspace.sh @@ -19,7 +19,8 @@ set -ex cd "$(dirname "$0")/../../.." -export repo_root=$(pwd) +repo_root=$(pwd) +export repo_root # TODO: fix file to pass shellcheck diff --git a/tools/run_tests/dockerize/build_and_run_docker.sh b/tools/run_tests/dockerize/build_and_run_docker.sh index 3f01fbc7b7d..9d0efc8b407 100755 --- a/tools/run_tests/dockerize/build_and_run_docker.sh +++ b/tools/run_tests/dockerize/build_and_run_docker.sh @@ -20,7 +20,7 @@ set -ex cd "$(dirname "$0")/../../.." git_root=$(pwd) -cd - +cd - # shellcheck disable=SC2103 # Inputs # DOCKERFILE_DIR - Directory in which Dockerfile file is located. diff --git a/tools/run_tests/dockerize/build_docker_and_run_tests.sh b/tools/run_tests/dockerize/build_docker_and_run_tests.sh index 1741b3268be..a63e1be96d2 100755 --- a/tools/run_tests/dockerize/build_docker_and_run_tests.sh +++ b/tools/run_tests/dockerize/build_docker_and_run_tests.sh @@ -20,7 +20,7 @@ set -ex cd "$(dirname "$0")/../../.." git_root=$(pwd) -cd - +cd - # shellcheck disable=SC2103 # Inputs # DOCKERFILE_DIR - Directory in which Dockerfile file is located. @@ -48,7 +48,7 @@ docker_instance_git_root=/var/local/jenkins/grpc # Run tests inside docker DOCKER_EXIT_CODE=0 # TODO: silence complaint about $TTY_FLAG expansion in some other way -# shellcheck disable=SC2086 +# shellcheck disable=SC2086,SC2154 docker run \ --cap-add SYS_PTRACE \ -e "RUN_TESTS_COMMAND=$RUN_TESTS_COMMAND" \ diff --git a/tools/run_tests/dockerize/build_interop_image.sh b/tools/run_tests/dockerize/build_interop_image.sh index 126dd4065e0..0f88787639a 100755 --- a/tools/run_tests/dockerize/build_interop_image.sh +++ b/tools/run_tests/dockerize/build_interop_image.sh @@ -16,7 +16,7 @@ # This script is invoked by run_interop_tests.py to build the docker image # for interop testing. You should never need to call this script on your own. -set -x +set -ex # Params: # INTEROP_IMAGE - name of tag of the final interop image diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh index b7686e48ba3..5214938208b 100755 --- a/tools/run_tests/dockerize/docker_run_tests.sh +++ b/tools/run_tests/dockerize/docker_run_tests.sh @@ -18,6 +18,7 @@ set -e +# shellcheck disable=SC2154 export CONFIG=$config export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer export PATH=$PATH:/usr/bin/llvm-symbolizer diff --git a/tools/run_tests/helper_scripts/run_grpc-node.sh b/tools/run_tests/helper_scripts/run_grpc-node.sh index 747aae7fd57..d14753a4d54 100755 --- a/tools/run_tests/helper_scripts/run_grpc-node.sh +++ b/tools/run_tests/helper_scripts/run_grpc-node.sh @@ -16,6 +16,8 @@ # This script runs grpc/grpc-node tests with their grpc submodule updated # to this reference +set -ex + # cd to gRPC root directory cd "$(dirname "$0")/../../.." diff --git a/tools/run_tests/helper_scripts/run_tests_in_workspace.sh b/tools/run_tests/helper_scripts/run_tests_in_workspace.sh index 790c0418816..fa7a7aac0a0 100755 --- a/tools/run_tests/helper_scripts/run_tests_in_workspace.sh +++ b/tools/run_tests/helper_scripts/run_tests_in_workspace.sh @@ -20,7 +20,8 @@ set -ex cd "$(dirname "$0")/../../.." -export repo_root="$(pwd)" +repo_root="$(pwd)" +export repo_root rm -rf "${WORKSPACE_NAME}" git clone . "${WORKSPACE_NAME}" diff --git a/tools/run_tests/interop/with_nvm.sh b/tools/run_tests/interop/with_nvm.sh index 887f9f6a9f2..55f4b2b8759 100755 --- a/tools/run_tests/interop/with_nvm.sh +++ b/tools/run_tests/interop/with_nvm.sh @@ -15,5 +15,6 @@ # limitations under the License. # Makes sure NVM is loaded before executing the command passed as an argument +# shellcheck disable=SC1090 source ~/.nvm/nvm.sh "$@" diff --git a/tools/run_tests/interop/with_rvm.sh b/tools/run_tests/interop/with_rvm.sh index 41e6efcb566..82bce9da125 100755 --- a/tools/run_tests/interop/with_rvm.sh +++ b/tools/run_tests/interop/with_rvm.sh @@ -15,5 +15,6 @@ # limitations under the License. # Makes sure RVM is loaded before executing the command passed as an argument +# shellcheck disable=SC1091 source /usr/local/rvm/scripts/rvm "$@" diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh index ab6bffdc34a..6c22e2d37d0 100755 --- a/tools/run_tests/performance/build_performance.sh +++ b/tools/run_tests/performance/build_performance.sh @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# shellcheck disable=SC1090 source ~/.rvm/scripts/rvm set -ex diff --git a/tools/run_tests/performance/build_performance_go.sh b/tools/run_tests/performance/build_performance_go.sh index 812728d4ceb..3aa203a6eed 100755 --- a/tools/run_tests/performance/build_performance_go.sh +++ b/tools/run_tests/performance/build_performance_go.sh @@ -17,7 +17,8 @@ set -ex cd "$(dirname "$0")/../../.." -export GOPATH=$(pwd)/../gopath +GOPATH=$(pwd)/../gopath +export GOPATH # Get grpc-go and the dependencies but get rid of the upstream/master version go get google.golang.org/grpc diff --git a/tools/run_tests/performance/build_performance_node.sh b/tools/run_tests/performance/build_performance_node.sh index 12e08722648..b5b5d9a1a27 100755 --- a/tools/run_tests/performance/build_performance_node.sh +++ b/tools/run_tests/performance/build_performance_node.sh @@ -15,6 +15,7 @@ set +ex +# shellcheck disable=SC1090 . "$HOME/.nvm/nvm.sh" nvm install 10 diff --git a/tools/run_tests/performance/run_worker_go.sh b/tools/run_tests/performance/run_worker_go.sh index f8e821a2656..1127f4f25ac 100755 --- a/tools/run_tests/performance/run_worker_go.sh +++ b/tools/run_tests/performance/run_worker_go.sh @@ -17,6 +17,7 @@ set -ex cd "$(dirname "$0")/../../.." -export GOPATH=$(pwd)/../gopath +GOPATH=$(pwd)/../gopath +export GOPATH "${GOPATH}/bin/worker" "$@" diff --git a/tools/run_tests/performance/run_worker_node.sh b/tools/run_tests/performance/run_worker_node.sh index 3e5dd18edb3..658cd508116 100755 --- a/tools/run_tests/performance/run_worker_node.sh +++ b/tools/run_tests/performance/run_worker_node.sh @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# shellcheck disable=SC1090 . "$HOME/.nvm/nvm.sh" nvm use 10 diff --git a/tools/run_tests/performance/run_worker_php.sh b/tools/run_tests/performance/run_worker_php.sh index 2fe2493e601..97292a9978f 100755 --- a/tools/run_tests/performance/run_worker_php.sh +++ b/tools/run_tests/performance/run_worker_php.sh @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# shellcheck disable=SC1090 source ~/.rvm/scripts/rvm set -ex diff --git a/tools/run_tests/performance/run_worker_ruby.sh b/tools/run_tests/performance/run_worker_ruby.sh index 729c5cec977..ed448463360 100755 --- a/tools/run_tests/performance/run_worker_ruby.sh +++ b/tools/run_tests/performance/run_worker_ruby.sh @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# shellcheck disable=SC1090 source ~/.rvm/scripts/rvm set -ex From 20c8cc72920b14520160c4e2001caec2b8acddc0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Dec 2018 18:06:34 -0800 Subject: [PATCH 0505/2143] nullability failing --- src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h index ca0cc51a52c..e2c3aee3d92 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h @@ -18,6 +18,8 @@ #import "GRPCChannelPool.h" +NS_ASSUME_NONNULL_BEGIN + /** Test-only interface for \a GRPCPooledChannel. */ @interface GRPCPooledChannel (Test) @@ -31,7 +33,7 @@ /** * Return the pointer to the raw channel wrapped. */ -@property(atomic, readonly) GRPCChannel *wrappedChannel; +@property(atomic, readonly, nullable) GRPCChannel *wrappedChannel; @end @@ -45,3 +47,5 @@ - (nullable instancetype)initTestPool; @end + +NS_ASSUME_NONNULL_END From b6ac1cb5b477d0182126a4b51d33ac58e66f3e83 Mon Sep 17 00:00:00 2001 From: Maxim Bunkov Date: Tue, 11 Dec 2018 14:11:00 +0500 Subject: [PATCH 0506/2143] 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 c5f344deaf84bd074419d42ed4af47e7c9ca6b42 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 11 Dec 2018 07:48:14 -0800 Subject: [PATCH 0507/2143] Revert "Revert "Allow encoding arbitrary channel args on a per-address basis."" --- BUILD | 3 +- CMakeLists.txt | 12 +- Makefile | 12 +- build.yaml | 3 +- config.m4 | 2 +- config.w32 | 2 +- gRPC-C++.podspec | 1 + gRPC-Core.podspec | 4 +- grpc.gemspec | 3 +- grpc.gyp | 8 +- package.xml | 3 +- .../filters/client_channel/client_channel.cc | 16 +- .../ext/filters/client_channel/lb_policy.h | 9 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 240 +++++++---------- .../lb_policy/grpclb/grpclb_channel.h | 2 +- .../lb_policy/grpclb/grpclb_channel_secure.cc | 33 +-- .../lb_policy/grpclb/load_balancer_api.h | 2 +- .../lb_policy/pick_first/pick_first.cc | 19 +- .../lb_policy/round_robin/round_robin.cc | 40 +-- .../lb_policy/subchannel_list.h | 53 ++-- .../client_channel/lb_policy/xds/xds.cc | 247 +++++------------- .../lb_policy/xds/xds_channel.h | 2 +- .../lb_policy/xds/xds_channel_secure.cc | 33 +-- .../lb_policy/xds/xds_load_balancer_api.h | 2 +- .../client_channel/lb_policy_factory.cc | 163 ------------ .../client_channel/lb_policy_factory.h | 86 +----- .../resolver/dns/c_ares/dns_resolver_ares.cc | 12 +- .../dns/c_ares/grpc_ares_ev_driver.cc | 1 + .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 149 +++++------ .../resolver/dns/c_ares/grpc_ares_wrapper.h | 13 +- .../dns/c_ares/grpc_ares_wrapper_fallback.cc | 9 +- .../dns/c_ares/grpc_ares_wrapper_posix.cc | 3 +- .../dns/c_ares/grpc_ares_wrapper_windows.cc | 26 +- .../resolver/dns/native/dns_resolver.cc | 14 +- .../resolver/fake/fake_resolver.cc | 3 +- .../resolver/fake/fake_resolver.h | 3 +- .../resolver/sockaddr/sockaddr_resolver.cc | 34 +-- .../client_channel/resolver_result_parsing.cc | 20 +- .../filters/client_channel/server_address.cc | 103 ++++++++ .../filters/client_channel/server_address.h | 108 ++++++++ .../ext/filters/client_channel/subchannel.cc | 6 +- .../ext/filters/client_channel/subchannel.h | 13 +- src/core/lib/iomgr/sockaddr_utils.cc | 1 + src/python/grpcio/grpc_core_dependencies.py | 2 +- .../dns_resolver_connectivity_test.cc | 12 +- .../resolvers/dns_resolver_cooldown_test.cc | 15 +- .../resolvers/fake_resolver_test.cc | 42 +-- test/core/end2end/fuzzers/api_fuzzer.cc | 28 +- test/core/end2end/goaway_server_test.cc | 29 +- test/core/end2end/no_server_test.cc | 1 + test/core/util/ubsan_suppressions.txt | 3 +- test/cpp/client/client_channel_stress_test.cc | 28 +- test/cpp/end2end/client_lb_end2end_test.cc | 18 +- test/cpp/end2end/grpclb_end2end_test.cc | 37 ++- test/cpp/naming/address_sorting_test.cc | 127 +++++---- test/cpp/naming/resolver_component_test.cc | 21 +- tools/doxygen/Doxyfile.core.internal | 3 +- .../generated/sources_and_headers.json | 4 +- 58 files changed, 845 insertions(+), 1043 deletions(-) delete mode 100644 src/core/ext/filters/client_channel/lb_policy_factory.cc create mode 100644 src/core/ext/filters/client_channel/server_address.cc create mode 100644 src/core/ext/filters/client_channel/server_address.h diff --git a/BUILD b/BUILD index 9e3e594038d..5550e583a87 100644 --- a/BUILD +++ b/BUILD @@ -1048,7 +1048,6 @@ grpc_cc_library( "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_factory.cc", "src/core/ext/filters/client_channel/lb_policy_registry.cc", "src/core/ext/filters/client_channel/parse_address.cc", "src/core/ext/filters/client_channel/proxy_mapper.cc", @@ -1057,6 +1056,7 @@ grpc_cc_library( "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/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", ], @@ -1080,6 +1080,7 @@ grpc_cc_library( "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/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", ], diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b02d778d1d..9c660c77012 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1240,7 +1240,6 @@ add_library(grpc 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -1249,6 +1248,7 @@ add_library(grpc 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/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/deadline/deadline_filter.cc @@ -1592,7 +1592,6 @@ add_library(grpc_cronet 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -1601,6 +1600,7 @@ add_library(grpc_cronet 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/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/deadline/deadline_filter.cc @@ -1963,7 +1963,6 @@ add_library(grpc_test_util 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -1972,6 +1971,7 @@ add_library(grpc_test_util 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/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/deadline/deadline_filter.cc @@ -2283,7 +2283,6 @@ add_library(grpc_test_util_unsecure 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -2292,6 +2291,7 @@ add_library(grpc_test_util_unsecure 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/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/deadline/deadline_filter.cc @@ -2617,7 +2617,6 @@ add_library(grpc_unsecure 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -2626,6 +2625,7 @@ add_library(grpc_unsecure 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/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/deadline/deadline_filter.cc @@ -3469,7 +3469,6 @@ add_library(grpc++_cronet 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_factory.cc src/core/ext/filters/client_channel/lb_policy_registry.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc @@ -3478,6 +3477,7 @@ add_library(grpc++_cronet 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/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/deadline/deadline_filter.cc diff --git a/Makefile b/Makefile index ed4e219f8b7..0163dc414a5 100644 --- a/Makefile +++ b/Makefile @@ -3735,7 +3735,6 @@ LIBGRPC_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -3744,6 +3743,7 @@ LIBGRPC_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -4081,7 +4081,6 @@ LIBGRPC_CRONET_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -4090,6 +4089,7 @@ LIBGRPC_CRONET_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -4445,7 +4445,6 @@ LIBGRPC_TEST_UTIL_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -4454,6 +4453,7 @@ LIBGRPC_TEST_UTIL_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -4751,7 +4751,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -4760,6 +4759,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -5058,7 +5058,6 @@ LIBGRPC_UNSECURE_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -5067,6 +5066,7 @@ LIBGRPC_UNSECURE_SRC = \ 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/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/deadline/deadline_filter.cc \ @@ -5885,7 +5885,6 @@ LIBGRPC++_CRONET_SRC = \ 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -5894,6 +5893,7 @@ LIBGRPC++_CRONET_SRC = \ 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/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/deadline/deadline_filter.cc \ diff --git a/build.yaml b/build.yaml index af70be8459a..4521169e6c1 100644 --- a/build.yaml +++ b/build.yaml @@ -589,6 +589,7 @@ filegroups: - 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/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: @@ -603,7 +604,6 @@ filegroups: - 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_factory.cc - src/core/ext/filters/client_channel/lb_policy_registry.cc - src/core/ext/filters/client_channel/parse_address.cc - src/core/ext/filters/client_channel/proxy_mapper.cc @@ -612,6 +612,7 @@ filegroups: - 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/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 plugin: grpc_client_channel diff --git a/config.m4 b/config.m4 index 3db660aceea..16de5204bb2 100644 --- a/config.m4 +++ b/config.m4 @@ -348,7 +348,6 @@ if test "$PHP_GRPC" != "no"; then 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_factory.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -357,6 +356,7 @@ if test "$PHP_GRPC" != "no"; then 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/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/deadline/deadline_filter.cc \ diff --git a/config.w32 b/config.w32 index 7f8b6eee5fa..be10faab9cd 100644 --- a/config.w32 +++ b/config.w32 @@ -323,7 +323,6 @@ if (PHP_GRPC != "no") { "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_factory.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy_registry.cc " + "src\\core\\ext\\filters\\client_channel\\parse_address.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " + @@ -332,6 +331,7 @@ if (PHP_GRPC != "no") { "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\\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\\deadline\\deadline_filter.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index e939bead1b7..30fcb51ee19 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -356,6 +356,7 @@ Pod::Spec.new do |s| '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/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/deadline/deadline_filter.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 1d4e1ae35c0..5ab7a49cd27 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -354,6 +354,7 @@ Pod::Spec.new do |s| '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/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/deadline/deadline_filter.h', @@ -786,7 +787,6 @@ Pod::Spec.new do |s| '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -795,6 +795,7 @@ Pod::Spec.new do |s| '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/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/deadline/deadline_filter.cc', @@ -974,6 +975,7 @@ Pod::Spec.new do |s| '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/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/deadline/deadline_filter.h', diff --git a/grpc.gemspec b/grpc.gemspec index 92b1e0be689..1ee7bec8e7d 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -290,6 +290,7 @@ Gem::Specification.new do |s| 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/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/deadline/deadline_filter.h ) @@ -725,7 +726,6 @@ Gem::Specification.new do |s| 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_factory.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.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 ) @@ -734,6 +734,7 @@ Gem::Specification.new do |s| 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/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/deadline/deadline_filter.cc ) diff --git a/grpc.gyp b/grpc.gyp index 564922ff727..00f06a1e54e 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -540,7 +540,6 @@ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -549,6 +548,7 @@ '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/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/deadline/deadline_filter.cc', @@ -799,7 +799,6 @@ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -808,6 +807,7 @@ '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/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/deadline/deadline_filter.cc', @@ -1039,7 +1039,6 @@ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -1048,6 +1047,7 @@ '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/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/deadline/deadline_filter.cc', @@ -1292,7 +1292,6 @@ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -1301,6 +1300,7 @@ '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/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/deadline/deadline_filter.cc', diff --git a/package.xml b/package.xml index bdcb12bfc5e..68fc7433cb4 100644 --- a/package.xml +++ b/package.xml @@ -295,6 +295,7 @@ + @@ -730,7 +731,6 @@ - @@ -739,6 +739,7 @@ + diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index ebc412b468d..70aac472314 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -38,6 +38,7 @@ #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/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" @@ -62,6 +63,7 @@ #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_metadata.h" +using grpc_core::ServerAddressList; using grpc_core::internal::ClientChannelMethodParams; using grpc_core::internal::ClientChannelMethodParamsTable; using grpc_core::internal::ProcessedResolverResult; @@ -383,16 +385,10 @@ static void create_new_lb_policy_locked( static void maybe_add_trace_message_for_address_changes_locked( channel_data* chand, TraceStringVector* trace_strings) { - int resolution_contains_addresses = false; - const grpc_arg* channel_arg = - grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES); - if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) { - grpc_lb_addresses* addresses = - static_cast(channel_arg->value.pointer.p); - if (addresses->num_addresses > 0) { - resolution_contains_addresses = true; - } - } + const ServerAddressList* addresses = + grpc_core::FindServerAddressListChannelArg(chand->resolver_result); + const bool resolution_contains_addresses = + addresses != nullptr && addresses->size() > 0; if (!resolution_contains_addresses && chand->previous_resolution_contained_addresses) { trace_strings->push_back(gpr_strdup("Address list became empty")); diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 7034da6249c..6b76fe5d5d7 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 { grpc_client_channel_factory* client_channel_factory = nullptr; /// Channel args from the resolver. /// Note that the LB policy gets the set of addresses from the - /// GRPC_ARG_LB_ADDRESSES channel arg. + /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. grpc_channel_args* args = nullptr; /// Load balancing config from the resolver. grpc_json* lb_config = nullptr; @@ -80,11 +80,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Will be populated with context to pass to the subchannel call, if /// needed. grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {}; - /// Upon success, \a *user_data will be set to whatever opaque information - /// may need to be propagated from the LB policy, or nullptr if not needed. - // TODO(roth): As part of revamping our metadata APIs, try to find a - // way to clean this up and C++-ify it. - void** user_data = nullptr; /// Next pointer. For internal use by LB policy. PickState* next = nullptr; }; @@ -95,7 +90,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// 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 - /// GRPC_ARG_LB_ADDRESSES channel arg. + /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. virtual void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) GRPC_ABSTRACT; 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 a46579c7f74..a9a5965ed1c 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 @@ -84,6 +84,7 @@ #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" @@ -113,6 +114,8 @@ #define GRPC_GRPCLB_RECONNECT_JITTER 0.2 #define GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS 10000 +#define GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN "grpc.grpclb_address_lb_token" + namespace grpc_core { TraceFlag grpc_lb_glb_trace(false, "glb"); @@ -121,7 +124,7 @@ namespace { class GrpcLb : public LoadBalancingPolicy { public: - GrpcLb(const grpc_lb_addresses* addresses, const Args& args); + explicit GrpcLb(const Args& args); void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; @@ -161,9 +164,6 @@ class GrpcLb : public LoadBalancingPolicy { // Our on_complete closure and the original one. grpc_closure on_complete; grpc_closure* original_on_complete; - // The LB token associated with the pick. This is set via user_data in - // the pick. - grpc_mdelem lb_token; // Stats for client-side load reporting. RefCountedPtr client_stats; // Next pending pick. @@ -329,7 +329,7 @@ class GrpcLb : public LoadBalancingPolicy { // 0 means not using fallback. int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. - grpc_lb_addresses* fallback_backend_addresses_ = nullptr; + UniquePtr fallback_backend_addresses_; // Fallback timer. bool fallback_timer_callback_pending_ = false; grpc_timer lb_fallback_timer_; @@ -349,7 +349,7 @@ class GrpcLb : public LoadBalancingPolicy { // serverlist parsing code // -// vtable for LB tokens in grpc_lb_addresses +// vtable for LB token channel arg. void* lb_token_copy(void* token) { return token == nullptr ? nullptr @@ -361,38 +361,11 @@ void lb_token_destroy(void* token) { } } int lb_token_cmp(void* token1, void* token2) { - if (token1 > token2) return 1; - if (token1 < token2) return -1; - return 0; + return GPR_ICMP(token1, token2); } -const grpc_lb_user_data_vtable lb_token_vtable = { +const grpc_arg_pointer_vtable lb_token_arg_vtable = { lb_token_copy, lb_token_destroy, lb_token_cmp}; -// Returns the backend addresses extracted from the given addresses. -grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) { - // First pass: count the number of backend addresses. - size_t num_backends = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) { - ++num_backends; - } - } - // Second pass: actually populate the addresses and (empty) LB tokens. - grpc_lb_addresses* backend_addresses = - grpc_lb_addresses_create(num_backends, &lb_token_vtable); - size_t num_copied = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) continue; - const grpc_resolved_address* addr = &addresses->addresses[i].address; - grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr, - addr->len, false /* is_balancer */, - nullptr /* balancer_name */, - (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload); - ++num_copied; - } - return backend_addresses; -} - bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) { if (server->drop) return false; const grpc_grpclb_ip_address* ip = &server->ip_address; @@ -440,30 +413,16 @@ void ParseServer(const grpc_grpclb_server* server, } // Returns addresses extracted from \a serverlist. -grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { - size_t num_valid = 0; - /* first pass: count how many are valid in order to allocate the necessary - * memory in a single block */ +ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { + ServerAddressList addresses; for (size_t i = 0; i < serverlist->num_servers; ++i) { - if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid; - } - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_valid, &lb_token_vtable); - /* second pass: actually populate the addresses and LB tokens (aka user data - * to the outside world) to be read by the RR policy during its creation. - * Given that the validity tests are very cheap, they are performed again - * instead of marking the valid ones during the first pass, as this would - * incurr in an allocation due to the arbitrary number of server */ - size_t addr_idx = 0; - for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) { - const grpc_grpclb_server* server = serverlist->servers[sl_idx]; - if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue; - GPR_ASSERT(addr_idx < num_valid); - /* address processing */ + 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); - /* lb token processing */ - void* user_data; + // LB token processing. + void* lb_token; if (server->has_load_balance_token) { const size_t lb_token_max_length = GPR_ARRAY_SIZE(server->load_balance_token); @@ -471,7 +430,7 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { strnlen(server->load_balance_token, lb_token_max_length); grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer( server->load_balance_token, lb_token_length); - user_data = + lb_token = (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr) .payload; } else { @@ -481,15 +440,16 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { "be used instead", uri); gpr_free(uri); - user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; + lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; } - grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len, - false /* is_balancer */, - nullptr /* balancer_name */, user_data); - ++addr_idx; + // Add address. + grpc_arg arg = grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token, + &lb_token_arg_vtable); + grpc_channel_args* args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + addresses.emplace_back(addr, args); } - GPR_ASSERT(addr_idx == num_valid); - return lb_addresses; + return addresses; } // @@ -829,8 +789,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_); } else { // Dispose of the fallback. - grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_); - grpclb_policy->fallback_backend_addresses_ = nullptr; + grpclb_policy->fallback_backend_addresses_.reset(); if (grpclb_policy->fallback_timer_callback_pending_) { grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_); } @@ -910,31 +869,25 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( // helper code for creating balancer channel // -grpc_lb_addresses* ExtractBalancerAddresses( - const grpc_lb_addresses* addresses) { - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - // There must be at least one balancer address, or else the - // client_channel would not have chosen this LB policy. - GPR_ASSERT(num_grpclb_addrs > 0); - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_grpclb_addrs, nullptr); - size_t lb_addresses_idx = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) continue; - if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) { - gpr_log(GPR_ERROR, - "This LB policy doesn't support user data. It will be ignored"); +ServerAddressList ExtractBalancerAddresses(const ServerAddressList& addresses) { + ServerAddressList balancer_addresses; + for (size_t i = 0; i < addresses.size(); ++i) { + if (addresses[i].IsBalancer()) { + // Strip out the is_balancer channel arg, since we don't want to + // recursively use the grpclb policy in the channel used to talk to + // the balancers. Note that we do NOT strip out the balancer_name + // channel arg, since we need that to set the authority correctly + // to talk to the balancers. + static const char* args_to_remove[] = { + GRPC_ARG_ADDRESS_IS_BALANCER, + }; + balancer_addresses.emplace_back( + addresses[i].address(), + grpc_channel_args_copy_and_remove(addresses[i].args(), args_to_remove, + GPR_ARRAY_SIZE(args_to_remove))); } - grpc_lb_addresses_set_address( - lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr, - addresses->addresses[i].address.len, false /* is balancer */, - addresses->addresses[i].balancer_name, nullptr /* user data */); } - GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx); - return lb_addresses; + return balancer_addresses; } /* Returns the channel args for the LB channel, used to create a bidirectional @@ -946,10 +899,10 @@ grpc_lb_addresses* ExtractBalancerAddresses( * above the grpclb policy. * - \a args: other args inherited from the grpclb policy. */ grpc_channel_args* BuildBalancerChannelArgs( - const grpc_lb_addresses* addresses, + const ServerAddressList& addresses, FakeResolverResponseGenerator* response_generator, const grpc_channel_args* args) { - grpc_lb_addresses* lb_addresses = ExtractBalancerAddresses(addresses); + 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 @@ -967,7 +920,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // 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. - GRPC_ARG_LB_ADDRESSES, + 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. @@ -983,10 +936,10 @@ grpc_channel_args* BuildBalancerChannelArgs( }; // Channel args to add. const grpc_arg args_to_add[] = { - // New LB addresses. + // 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. - grpc_lb_addresses_create_channel_arg(lb_addresses), + CreateServerAddressListChannelArg(&balancer_addresses), // The fake resolver response generator, which we use to inject // address updates into the LB channel. grpc_core::FakeResolverResponseGenerator::MakeChannelArg( @@ -1004,18 +957,14 @@ 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. - new_args = grpc_lb_policy_grpclb_modify_lb_channel_args(new_args); - // Clean up. - grpc_lb_addresses_destroy(lb_addresses); - return new_args; + return grpc_lb_policy_grpclb_modify_lb_channel_args(new_args); } // // ctor and dtor // -GrpcLb::GrpcLb(const grpc_lb_addresses* addresses, - const LoadBalancingPolicy::Args& args) +GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args) : LoadBalancingPolicy(args), response_generator_(MakeRefCounted()), lb_call_backoff_( @@ -1072,9 +1021,6 @@ GrpcLb::~GrpcLb() { if (serverlist_ != nullptr) { grpc_grpclb_destroy_serverlist(serverlist_); } - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } grpc_subchannel_index_unref(); } @@ -1122,7 +1068,6 @@ void GrpcLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { while ((pp = pending_picks_) != nullptr) { pending_picks_ = pp->next; pp->pick->on_complete = pp->original_on_complete; - pp->pick->user_data = nullptr; grpc_error* error = GRPC_ERROR_NONE; if (new_policy->PickLocked(pp->pick, &error)) { // Synchronous return; schedule closure. @@ -1276,9 +1221,27 @@ void GrpcLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, notify); } +// Returns the backend addresses extracted from the given addresses. +UniquePtr 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(); + for (size_t i = 0; i < addresses.size(); ++i) { + if (!addresses[i].IsBalancer()) { + backend_addresses->emplace_back( + addresses[i].address(), + grpc_channel_args_copy_and_add(addresses[i].args(), &arg, 1)); + } + } + return backend_addresses; +} + void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { + const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); + if (addresses == nullptr) { // Ignore this update. gpr_log( GPR_ERROR, @@ -1286,13 +1249,8 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { this); return; } - const grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); // Update fallback address list. - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } - 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}; @@ -1303,7 +1261,7 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { &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); + BuildBalancerChannelArgs(*addresses, response_generator_.get(), &args); // Create balancer channel if needed. if (lb_channel_ == nullptr) { char* uri_str; @@ -1509,12 +1467,17 @@ void DestroyClientStats(void* arg) { } 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 - * user_data/token available */ + // 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) { - if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) { - AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token), + 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 { @@ -1598,12 +1561,10 @@ bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, return true; } } - // Set client_stats and user_data. + // Set client_stats. if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { pp->client_stats = lb_calld_->client_stats()->Ref(); } - GPR_ASSERT(pp->pick->user_data == nullptr); - pp->pick->user_data = (void**)&pp->lb_token; // Pick via the RR policy. bool pick_done = rr_policy_->PickLocked(pp->pick, error); if (pick_done) { @@ -1668,10 +1629,11 @@ void GrpcLb::CreateRoundRobinPolicyLocked(const Args& args) { } grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { - grpc_lb_addresses* addresses; + ServerAddressList tmp_addresses; + ServerAddressList* addresses = &tmp_addresses; bool is_backend_from_grpclb_load_balancer = false; if (serverlist_ != nullptr) { - addresses = ProcessServerlist(serverlist_); + tmp_addresses = ProcessServerlist(serverlist_); is_backend_from_grpclb_load_balancer = true; } else { // If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't @@ -1680,14 +1642,14 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { // empty, in which case the new round_robin policy will keep the requested // picks pending. GPR_ASSERT(fallback_backend_addresses_ != nullptr); - addresses = grpc_lb_addresses_copy(fallback_backend_addresses_); + addresses = fallback_backend_addresses_.get(); } GPR_ASSERT(addresses != nullptr); - // Replace the LB addresses in the channel args that we pass down to + // Replace the server address list in the channel args that we pass down to // the subchannel. - static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES}; + static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST}; grpc_arg args_to_add[3] = { - grpc_lb_addresses_create_channel_arg(addresses), + CreateServerAddressListChannelArg(addresses), // A channel arg indicating if the target is a backend inferred from a // grpclb load balancer. grpc_channel_arg_integer_create( @@ -1704,7 +1666,6 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { 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); - grpc_lb_addresses_destroy(addresses); return args; } @@ -1837,19 +1798,18 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { OrphanablePtr CreateLoadBalancingPolicy( const LoadBalancingPolicy::Args& args) const override { /* Count the number of gRPC-LB addresses. There must be at least one. */ - const grpc_arg* arg = - grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES); - if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { - return nullptr; + 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; + } } - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - if (num_grpclb_addrs == 0) return nullptr; - return OrphanablePtr(New(addresses, args)); + if (!found_balancer) return nullptr; + return OrphanablePtr(New(args)); } const char* name() const override { return "grpclb"; } 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 825065a9c32..3b2dc370eb3 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 @@ -21,7 +21,7 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include /// Makes any necessary modifications to \a args for use in the grpclb /// balancer channel. 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 441efd5e23b..6e8fbdcab77 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 @@ -26,6 +26,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -42,22 +43,23 @@ int BalancerNameCmp(const grpc_core::UniquePtr& a, } RefCountedPtr CreateTargetAuthorityTable( - grpc_lb_addresses* addresses) { + const ServerAddressList& addresses) { TargetAuthorityTable::Entry* target_authority_entries = - static_cast(gpr_zalloc( - sizeof(*target_authority_entries) * addresses->num_addresses)); - for (size_t i = 0; i < addresses->num_addresses; ++i) { + 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->addresses[i].address, true) > 0); + 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); - target_authority_entries[i].value.reset( - gpr_strdup(addresses->addresses[i].balancer_name)); 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->num_addresses, - target_authority_entries, BalancerNameCmp); + TargetAuthorityTable::Create(addresses.size(), target_authority_entries, + BalancerNameCmp); gpr_free(target_authority_entries); return target_authority_table; } @@ -72,13 +74,12 @@ grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args( grpc_arg args_to_add[2]; size_t num_args_to_add = 0; // Add arg for targets info table. - const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES); - GPR_ASSERT(arg != nullptr); - GPR_ASSERT(arg->type == GRPC_ARG_POINTER); - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); + 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/grpclb/load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h index 9ca7b28d8e6..71d371c880a 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 @@ -25,7 +25,7 @@ #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/lib/iomgr/exec_ctx.h" #define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128 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 d1a05f12554..74c17612a28 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 @@ -24,6 +24,7 @@ #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/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" @@ -75,11 +76,9 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner) - : SubchannelData(subchannel_list, user_data_vtable, address, subchannel, - combiner) {} + : SubchannelData(subchannel_list, address, subchannel, combiner) {} void ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state, grpc_error* error) override; @@ -95,7 +94,7 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData> { public: PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, + const ServerAddressList& addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) @@ -337,8 +336,8 @@ void PickFirst::UpdateChildRefsLocked() { void PickFirst::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { AutoChildRefsUpdater guard(this); - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { + 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_connectivity_state_set( @@ -354,19 +353,17 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, } return; } - const grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p received update with %" PRIuPTR " addresses", this, - addresses->num_addresses); + 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); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, addresses, combiner(), + 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) { 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 2a169751317..63089afbd78 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 @@ -82,8 +82,6 @@ class RoundRobin : public LoadBalancingPolicy { // Data for a particular subchannel in a subchannel list. // This subclass adds the following functionality: - // - Tracks user_data associated with each address, which will be - // returned along with picks that select the subchannel. // - Tracks the previous connectivity state of the subchannel, so that // we know how many subchannels are in each state. class RoundRobinSubchannelData @@ -93,26 +91,9 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner) - : SubchannelData(subchannel_list, user_data_vtable, address, subchannel, - combiner), - user_data_vtable_(user_data_vtable), - user_data_(user_data_vtable_ != nullptr - ? user_data_vtable_->copy(address.user_data) - : nullptr) {} - - void UnrefSubchannelLocked(const char* reason) override { - SubchannelData::UnrefSubchannelLocked(reason); - if (user_data_ != nullptr) { - GPR_ASSERT(user_data_vtable_ != nullptr); - user_data_vtable_->destroy(user_data_); - user_data_ = nullptr; - } - } - - void* user_data() const { return user_data_; } + : SubchannelData(subchannel_list, address, subchannel, combiner) {} grpc_connectivity_state connectivity_state() const { return last_connectivity_state_; @@ -125,8 +106,6 @@ class RoundRobin : public LoadBalancingPolicy { void ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state, grpc_error* error) override; - const grpc_lb_user_data_vtable* user_data_vtable_; - void* user_data_ = nullptr; grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE; }; @@ -137,7 +116,7 @@ class RoundRobin : public LoadBalancingPolicy { public: RoundRobinSubchannelList( RoundRobin* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, grpc_combiner* combiner, + const ServerAddressList& addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, @@ -354,9 +333,6 @@ bool RoundRobin::DoPickLocked(PickState* pick) { subchannel_list_->subchannel(next_ready_index); GPR_ASSERT(sd->connected_subchannel() != nullptr); pick->connected_subchannel = sd->connected_subchannel()->Ref(); - if (pick->user_data != nullptr) { - *pick->user_data = sd->user_data(); - } if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, " @@ -667,9 +643,9 @@ void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current, void RoundRobin::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); AutoChildRefsUpdater guard(this); - if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { + 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). @@ -681,11 +657,9 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, } return; } - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses", - this, addresses->num_addresses); + this, addresses->size()); } // Replace latest_pending_subchannel_list_. if (latest_pending_subchannel_list_ != nullptr) { @@ -696,7 +670,7 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, addresses, combiner(), + 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. 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 f31401502c3..6f31a643c1d 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 @@ -26,6 +26,7 @@ #include #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/lib/channel/channel_args.h" #include "src/core/lib/debug/trace.h" @@ -141,8 +142,7 @@ class SubchannelData { protected: SubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner); virtual ~SubchannelData(); @@ -156,9 +156,8 @@ class SubchannelData { grpc_connectivity_state connectivity_state, grpc_error* error) GRPC_ABSTRACT; - // Unrefs the subchannel. May be overridden by subclasses that need - // to perform extra cleanup when unreffing the subchannel. - virtual void UnrefSubchannelLocked(const char* reason); + // Unrefs the subchannel. + void UnrefSubchannelLocked(const char* reason); private: // Updates connected_subchannel_ based on pending_connectivity_state_unsafe_. @@ -232,7 +231,7 @@ class SubchannelList : public InternallyRefCounted { protected: SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, grpc_combiner* combiner, + const ServerAddressList& addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args); @@ -277,8 +276,7 @@ class SubchannelList : public InternallyRefCounted { template SubchannelData::SubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner) : subchannel_list_(subchannel_list), subchannel_(subchannel), @@ -488,7 +486,7 @@ void SubchannelData::ShutdownLocked() { template SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, grpc_combiner* combiner, + const ServerAddressList& addresses, grpc_combiner* combiner, grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) : InternallyRefCounted(tracer), @@ -498,9 +496,9 @@ SubchannelList::SubchannelList( if (tracer_->enabled()) { gpr_log(GPR_INFO, "[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels", - tracer_->name(), policy, this, addresses->num_addresses); + tracer_->name(), policy, this, addresses.size()); } - subchannels_.reserve(addresses->num_addresses); + subchannels_.reserve(addresses.size()); // We need to remove the LB addresses in order to be able to compare the // subchannel keys of subchannels from a different batch of addresses. // We also remove the inhibit-health-checking arg, since we are @@ -508,19 +506,27 @@ 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_LB_ADDRESSES, + GRPC_ARG_SERVER_ADDRESS_LIST, GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. grpc_subchannel_args sc_args; - for (size_t i = 0; i < addresses->num_addresses; i++) { - // If there were any balancer, we would have chosen grpclb policy instead. - GPR_ASSERT(!addresses->addresses[i].is_balancer); + 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()); memset(&sc_args, 0, sizeof(grpc_subchannel_args)); - grpc_arg addr_arg = - grpc_create_subchannel_address_arg(&addresses->addresses[i].address); + InlinedVector args_to_add; + args_to_add.emplace_back( + 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]); + } + } 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); + &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); sc_args.args = new_args; grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel( client_channel_factory, &sc_args); @@ -528,8 +534,7 @@ SubchannelList::SubchannelList( if (subchannel == nullptr) { // Subchannel could not be created. if (tracer_->enabled()) { - char* address_uri = - grpc_sockaddr_to_uri(&addresses->addresses[i].address); + char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address()); gpr_log(GPR_INFO, "[%s %p] could not create subchannel for address uri %s, " "ignoring", @@ -539,8 +544,7 @@ SubchannelList::SubchannelList( continue; } if (tracer_->enabled()) { - char* address_uri = - grpc_sockaddr_to_uri(&addresses->addresses[i].address); + char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address()); gpr_log(GPR_INFO, "[%s %p] subchannel list %p index %" PRIuPTR ": Created subchannel %p for address uri %s", @@ -548,8 +552,7 @@ SubchannelList::SubchannelList( address_uri); gpr_free(address_uri); } - subchannels_.emplace_back(this, addresses->user_data_vtable, - addresses->addresses[i], subchannel, combiner); + subchannels_.emplace_back(this, addresses[i], subchannel, 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 faedc0a9194..3c25de2386c 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 @@ -79,6 +79,7 @@ #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" @@ -116,7 +117,7 @@ namespace { class XdsLb : public LoadBalancingPolicy { public: - XdsLb(const grpc_lb_addresses* addresses, const Args& args); + explicit XdsLb(const Args& args); void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; @@ -156,9 +157,6 @@ class XdsLb : public LoadBalancingPolicy { // Our on_complete closure and the original one. grpc_closure on_complete; grpc_closure* original_on_complete; - // The LB token associated with the pick. This is set via user_data in - // the pick. - grpc_mdelem lb_token; // Stats for client-side load reporting. RefCountedPtr client_stats; // Next pending pick. @@ -256,7 +254,7 @@ class XdsLb : public LoadBalancingPolicy { grpc_error* error); // Pending pick methods. - static void PendingPickSetMetadataAndContext(PendingPick* pp); + static void PendingPickCleanup(PendingPick* pp); PendingPick* PendingPickCreate(PickState* pick); void AddPendingPick(PendingPick* pp); static void OnPendingPickComplete(void* arg, grpc_error* error); @@ -319,7 +317,7 @@ class XdsLb : public LoadBalancingPolicy { // 0 means not using fallback. int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. - grpc_lb_addresses* fallback_backend_addresses_ = nullptr; + UniquePtr fallback_backend_addresses_; // Fallback timer. bool fallback_timer_callback_pending_ = false; grpc_timer lb_fallback_timer_; @@ -339,47 +337,15 @@ class XdsLb : public LoadBalancingPolicy { // serverlist parsing code // -// vtable for LB tokens in grpc_lb_addresses -void* lb_token_copy(void* token) { - return token == nullptr - ? nullptr - : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload; -} -void lb_token_destroy(void* token) { - if (token != nullptr) { - GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token}); - } -} -int lb_token_cmp(void* token1, void* token2) { - if (token1 > token2) return 1; - if (token1 < token2) return -1; - return 0; -} -const grpc_lb_user_data_vtable lb_token_vtable = { - lb_token_copy, lb_token_destroy, lb_token_cmp}; - // Returns the backend addresses extracted from the given addresses. -grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) { - // First pass: count the number of backend addresses. - size_t num_backends = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) { - ++num_backends; +UniquePtr ExtractBackendAddresses( + const ServerAddressList& addresses) { + auto backend_addresses = MakeUnique(); + for (size_t i = 0; i < addresses.size(); ++i) { + if (!addresses[i].IsBalancer()) { + backend_addresses->emplace_back(addresses[i]); } } - // Second pass: actually populate the addresses and (empty) LB tokens. - grpc_lb_addresses* backend_addresses = - grpc_lb_addresses_create(num_backends, &lb_token_vtable); - size_t num_copied = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) continue; - const grpc_resolved_address* addr = &addresses->addresses[i].address; - grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr, - addr->len, false /* is_balancer */, - nullptr /* balancer_name */, - (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload); - ++num_copied; - } return backend_addresses; } @@ -429,56 +395,17 @@ void ParseServer(const xds_grpclb_server* server, grpc_resolved_address* addr) { } // Returns addresses extracted from \a serverlist. -grpc_lb_addresses* ProcessServerlist(const xds_grpclb_serverlist* serverlist) { - size_t num_valid = 0; - /* first pass: count how many are valid in order to allocate the necessary - * memory in a single block */ +UniquePtr ProcessServerlist( + const xds_grpclb_serverlist* serverlist) { + auto addresses = MakeUnique(); for (size_t i = 0; i < serverlist->num_servers; ++i) { - if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid; - } - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_valid, &lb_token_vtable); - /* second pass: actually populate the addresses and LB tokens (aka user data - * to the outside world) to be read by the child policy during its creation. - * Given that the validity tests are very cheap, they are performed again - * instead of marking the valid ones during the first pass, as this would - * incurr in an allocation due to the arbitrary number of server */ - size_t addr_idx = 0; - for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) { - const xds_grpclb_server* server = serverlist->servers[sl_idx]; - if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue; - GPR_ASSERT(addr_idx < num_valid); - /* address processing */ + const xds_grpclb_server* server = serverlist->servers[i]; + if (!IsServerValid(serverlist->servers[i], i, false)) continue; grpc_resolved_address addr; ParseServer(server, &addr); - /* lb token processing */ - void* user_data; - if (server->has_load_balance_token) { - const size_t lb_token_max_length = - GPR_ARRAY_SIZE(server->load_balance_token); - const size_t lb_token_length = - strnlen(server->load_balance_token, lb_token_max_length); - grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer( - server->load_balance_token, lb_token_length); - user_data = - (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr) - .payload; - } else { - char* uri = grpc_sockaddr_to_uri(&addr); - gpr_log(GPR_INFO, - "Missing LB token for backend address '%s'. The empty token will " - "be used instead", - uri); - gpr_free(uri); - user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; - } - grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len, - false /* is_balancer */, - nullptr /* balancer_name */, user_data); - ++addr_idx; + addresses->emplace_back(addr, nullptr); } - GPR_ASSERT(addr_idx == num_valid); - return lb_addresses; + return addresses; } // @@ -789,8 +716,7 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( xds_grpclb_destroy_serverlist(xdslb_policy->serverlist_); } else { /* or dispose of the fallback */ - grpc_lb_addresses_destroy(xdslb_policy->fallback_backend_addresses_); - xdslb_policy->fallback_backend_addresses_ = nullptr; + xdslb_policy->fallback_backend_addresses_.reset(); if (xdslb_policy->fallback_timer_callback_pending_) { grpc_timer_cancel(&xdslb_policy->lb_fallback_timer_); } @@ -876,31 +802,15 @@ void XdsLb::BalancerCallState::OnBalancerStatusReceivedLocked( // helper code for creating balancer channel // -grpc_lb_addresses* ExtractBalancerAddresses( - const grpc_lb_addresses* addresses) { - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - // There must be at least one balancer address, or else the - // client_channel would not have chosen this LB policy. - GPR_ASSERT(num_grpclb_addrs > 0); - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_grpclb_addrs, nullptr); - size_t lb_addresses_idx = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) continue; - if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) { - gpr_log(GPR_ERROR, - "This LB policy doesn't support user data. It will be ignored"); +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]); } - grpc_lb_addresses_set_address( - lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr, - addresses->addresses[i].address.len, false /* is balancer */, - addresses->addresses[i].balancer_name, nullptr /* user data */); } - GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx); - return lb_addresses; + return balancer_addresses; } /* Returns the channel args for the LB channel, used to create a bidirectional @@ -912,10 +822,11 @@ grpc_lb_addresses* ExtractBalancerAddresses( * above the grpclb policy. * - \a args: other args inherited from the xds policy. */ grpc_channel_args* BuildBalancerChannelArgs( - const grpc_lb_addresses* addresses, + const ServerAddressList& addresses, FakeResolverResponseGenerator* response_generator, const grpc_channel_args* args) { - grpc_lb_addresses* lb_addresses = ExtractBalancerAddresses(addresses); + UniquePtr 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 @@ -933,7 +844,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // 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. - GRPC_ARG_LB_ADDRESSES, + 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. @@ -949,10 +860,10 @@ grpc_channel_args* BuildBalancerChannelArgs( }; // Channel args to add. const grpc_arg args_to_add[] = { - // New LB addresses. + // 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. - grpc_lb_addresses_create_channel_arg(lb_addresses), + CreateServerAddressListChannelArg(balancer_addresses.get()), // The fake resolver response generator, which we use to inject // address updates into the LB channel. grpc_core::FakeResolverResponseGenerator::MakeChannelArg( @@ -970,10 +881,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. - new_args = grpc_lb_policy_xds_modify_lb_channel_args(new_args); - // Clean up. - grpc_lb_addresses_destroy(lb_addresses); - return new_args; + return grpc_lb_policy_xds_modify_lb_channel_args(new_args); } // @@ -981,8 +889,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // // TODO(vishalpowar): Use lb_config in args to configure LB policy. -XdsLb::XdsLb(const grpc_lb_addresses* addresses, - const LoadBalancingPolicy::Args& args) +XdsLb::XdsLb(const LoadBalancingPolicy::Args& args) : LoadBalancingPolicy(args), response_generator_(MakeRefCounted()), lb_call_backoff_( @@ -1038,9 +945,6 @@ XdsLb::~XdsLb() { if (serverlist_ != nullptr) { xds_grpclb_destroy_serverlist(serverlist_); } - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } grpc_subchannel_index_unref(); } @@ -1088,7 +992,6 @@ void XdsLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { while ((pp = pending_picks_) != nullptr) { pending_picks_ = pp->next; pp->pick->on_complete = pp->original_on_complete; - pp->pick->user_data = nullptr; grpc_error* error = GRPC_ERROR_NONE; if (new_policy->PickLocked(pp->pick, &error)) { // Synchronous return; schedule closure. @@ -1241,21 +1144,16 @@ void XdsLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, } void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { + 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; } - const grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); // Update fallback address list. - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } - 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}; @@ -1266,7 +1164,7 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { &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); + BuildBalancerChannelArgs(*addresses, response_generator_.get(), &args); // Create balancer channel if needed. if (lb_channel_ == nullptr) { char* uri_str; @@ -1457,37 +1355,15 @@ void XdsLb::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 XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) { - /* if connected_subchannel is nullptr, no pick has been made by the - * child policy (e.g., all addresses failed to connect). There won't be any - * user_data/token available */ +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) { - if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) { - AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token), - &pp->pick->lb_token_mdelem_storage, - pp->pick->initial_metadata); - } else { - gpr_log(GPR_ERROR, - "[xdslb %p] No LB token for connected subchannel pick %p", - pp->xdslb_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 = @@ -1505,7 +1381,7 @@ void XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) { * order to unref the child policy instance upon its invocation */ void XdsLb::OnPendingPickComplete(void* arg, grpc_error* error) { PendingPick* pp = static_cast(arg); - PendingPickSetMetadataAndContext(pp); + PendingPickCleanup(pp); GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error)); Delete(pp); } @@ -1537,16 +1413,14 @@ void XdsLb::AddPendingPick(PendingPick* pp) { // completion callback even if the pick is available immediately. bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp, grpc_error** error) { - // Set client_stats and user_data. + // Set client_stats. if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { pp->client_stats = lb_calld_->client_stats()->Ref(); } - GPR_ASSERT(pp->pick->user_data == nullptr); - pp->pick->user_data = (void**)&pp->lb_token; // Pick via the child policy. bool pick_done = child_policy_->PickLocked(pp->pick, error); if (pick_done) { - PendingPickSetMetadataAndContext(pp); + PendingPickCleanup(pp); if (force_async) { GRPC_CLOSURE_SCHED(pp->original_on_complete, *error); *error = GRPC_ERROR_NONE; @@ -1608,20 +1482,19 @@ void XdsLb::CreateChildPolicyLocked(const Args& args) { } grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { - grpc_lb_addresses* addresses; 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); - addresses = ProcessServerlist(serverlist_); - is_backend_from_grpclb_load_balancer = true; + UniquePtr addresses = ProcessServerlist(serverlist_); GPR_ASSERT(addresses != nullptr); - // Replace the LB addresses in the channel args that we pass down to + 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_LB_ADDRESSES}; + static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST}; const grpc_arg args_to_add[] = { - grpc_lb_addresses_create_channel_arg(addresses), + CreateServerAddressListChannelArg(addresses.get()), // A channel arg indicating if the target is a backend inferred from a // grpclb load balancer. grpc_channel_arg_integer_create( @@ -1631,7 +1504,6 @@ grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { 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)); - grpc_lb_addresses_destroy(addresses); return args; } @@ -1765,19 +1637,18 @@ class XdsFactory : public LoadBalancingPolicyFactory { OrphanablePtr CreateLoadBalancingPolicy( const LoadBalancingPolicy::Args& args) const override { /* Count the number of gRPC-LB addresses. There must be at least one. */ - const grpc_arg* arg = - grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES); - if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { - return nullptr; + 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; + } } - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - if (num_grpclb_addrs == 0) return nullptr; - return OrphanablePtr(New(addresses, args)); + if (!found_balancer_address) return nullptr; + return OrphanablePtr(New(args)); } const char* name() const override { return "xds_experimental"; } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h index 32c4acc8a3e..f713b7f563d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h @@ -21,7 +21,7 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include /// Makes any necessary modifications to \a args for use in the xds /// balancer channel. 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 5ab72efce46..9a11f8e39fd 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 @@ -25,6 +25,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -41,22 +42,23 @@ int BalancerNameCmp(const grpc_core::UniquePtr& a, } RefCountedPtr CreateTargetAuthorityTable( - grpc_lb_addresses* addresses) { + const ServerAddressList& addresses) { TargetAuthorityTable::Entry* target_authority_entries = - static_cast(gpr_zalloc( - sizeof(*target_authority_entries) * addresses->num_addresses)); - for (size_t i = 0; i < addresses->num_addresses; ++i) { + 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->addresses[i].address, true) > 0); + 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); - target_authority_entries[i].value.reset( - gpr_strdup(addresses->addresses[i].balancer_name)); 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->num_addresses, - target_authority_entries, BalancerNameCmp); + TargetAuthorityTable::Create(addresses.size(), target_authority_entries, + BalancerNameCmp); gpr_free(target_authority_entries); return target_authority_table; } @@ -71,13 +73,12 @@ grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args( grpc_arg args_to_add[2]; size_t num_args_to_add = 0; // Add arg for targets info table. - const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES); - GPR_ASSERT(arg != nullptr); - GPR_ASSERT(arg->type == GRPC_ARG_POINTER); - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); + 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/xds/xds_load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h index 9d08defa7ef..67049956417 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 @@ -25,7 +25,7 @@ #include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/lib/iomgr/exec_ctx.h" #define XDS_SERVICE_NAME_MAX_LENGTH 128 diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.cc b/src/core/ext/filters/client_channel/lb_policy_factory.cc deleted file mode 100644 index 5c6363d2952..00000000000 --- a/src/core/ext/filters/client_channel/lb_policy_factory.cc +++ /dev/null @@ -1,163 +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 - -#include -#include - -#include "src/core/lib/channel/channel_args.h" - -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" -#include "src/core/ext/filters/client_channel/parse_address.h" - -grpc_lb_addresses* grpc_lb_addresses_create( - size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable) { - grpc_lb_addresses* addresses = - static_cast(gpr_zalloc(sizeof(grpc_lb_addresses))); - addresses->num_addresses = num_addresses; - addresses->user_data_vtable = user_data_vtable; - const size_t addresses_size = sizeof(grpc_lb_address) * num_addresses; - addresses->addresses = - static_cast(gpr_zalloc(addresses_size)); - return addresses; -} - -grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses) { - grpc_lb_addresses* new_addresses = grpc_lb_addresses_create( - addresses->num_addresses, addresses->user_data_vtable); - memcpy(new_addresses->addresses, addresses->addresses, - sizeof(grpc_lb_address) * addresses->num_addresses); - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (new_addresses->addresses[i].balancer_name != nullptr) { - new_addresses->addresses[i].balancer_name = - gpr_strdup(new_addresses->addresses[i].balancer_name); - } - if (new_addresses->addresses[i].user_data != nullptr) { - new_addresses->addresses[i].user_data = addresses->user_data_vtable->copy( - new_addresses->addresses[i].user_data); - } - } - return new_addresses; -} - -void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index, - const void* address, size_t address_len, - bool is_balancer, const char* balancer_name, - void* user_data) { - GPR_ASSERT(index < addresses->num_addresses); - if (user_data != nullptr) GPR_ASSERT(addresses->user_data_vtable != nullptr); - grpc_lb_address* target = &addresses->addresses[index]; - memcpy(target->address.addr, address, address_len); - target->address.len = static_cast(address_len); - target->is_balancer = is_balancer; - target->balancer_name = gpr_strdup(balancer_name); - target->user_data = user_data; -} - -bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses, - size_t index, const grpc_uri* uri, - bool is_balancer, - const char* balancer_name, - void* user_data) { - grpc_resolved_address address; - if (!grpc_parse_uri(uri, &address)) return false; - grpc_lb_addresses_set_address(addresses, index, address.addr, address.len, - is_balancer, balancer_name, user_data); - return true; -} - -int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1, - const grpc_lb_addresses* addresses2) { - if (addresses1->num_addresses > addresses2->num_addresses) return 1; - if (addresses1->num_addresses < addresses2->num_addresses) return -1; - if (addresses1->user_data_vtable > addresses2->user_data_vtable) return 1; - if (addresses1->user_data_vtable < addresses2->user_data_vtable) return -1; - for (size_t i = 0; i < addresses1->num_addresses; ++i) { - const grpc_lb_address* target1 = &addresses1->addresses[i]; - const grpc_lb_address* target2 = &addresses2->addresses[i]; - if (target1->address.len > target2->address.len) return 1; - if (target1->address.len < target2->address.len) return -1; - int retval = memcmp(target1->address.addr, target2->address.addr, - target1->address.len); - if (retval != 0) return retval; - if (target1->is_balancer > target2->is_balancer) return 1; - if (target1->is_balancer < target2->is_balancer) return -1; - const char* balancer_name1 = - target1->balancer_name != nullptr ? target1->balancer_name : ""; - const char* balancer_name2 = - target2->balancer_name != nullptr ? target2->balancer_name : ""; - retval = strcmp(balancer_name1, balancer_name2); - if (retval != 0) return retval; - if (addresses1->user_data_vtable != nullptr) { - retval = addresses1->user_data_vtable->cmp(target1->user_data, - target2->user_data); - if (retval != 0) return retval; - } - } - return 0; -} - -void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses) { - for (size_t i = 0; i < addresses->num_addresses; ++i) { - gpr_free(addresses->addresses[i].balancer_name); - if (addresses->addresses[i].user_data != nullptr) { - addresses->user_data_vtable->destroy(addresses->addresses[i].user_data); - } - } - gpr_free(addresses->addresses); - gpr_free(addresses); -} - -static void* lb_addresses_copy(void* addresses) { - return grpc_lb_addresses_copy(static_cast(addresses)); -} -static void lb_addresses_destroy(void* addresses) { - grpc_lb_addresses_destroy(static_cast(addresses)); -} -static int lb_addresses_cmp(void* addresses1, void* addresses2) { - return grpc_lb_addresses_cmp(static_cast(addresses1), - static_cast(addresses2)); -} -static const grpc_arg_pointer_vtable lb_addresses_arg_vtable = { - lb_addresses_copy, lb_addresses_destroy, lb_addresses_cmp}; - -grpc_arg grpc_lb_addresses_create_channel_arg( - const grpc_lb_addresses* addresses) { - return grpc_channel_arg_pointer_create( - (char*)GRPC_ARG_LB_ADDRESSES, (void*)addresses, &lb_addresses_arg_vtable); -} - -grpc_lb_addresses* grpc_lb_addresses_find_channel_arg( - const grpc_channel_args* channel_args) { - const grpc_arg* lb_addresses_arg = - grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES); - if (lb_addresses_arg == nullptr || lb_addresses_arg->type != GRPC_ARG_POINTER) - return nullptr; - return static_cast(lb_addresses_arg->value.pointer.p); -} - -bool grpc_lb_addresses_contains_balancer_address( - const grpc_lb_addresses& addresses) { - for (size_t i = 0; i < addresses.num_addresses; ++i) { - if (addresses.addresses[i].is_balancer) return true; - } - return false; -} 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 a59deadb265..a165ebafaba 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -21,91 +21,9 @@ #include -#include "src/core/lib/iomgr/resolve_address.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/lib/uri/uri_parser.h" - -// -// representation of an LB address -// - -// Channel arg key for grpc_lb_addresses. -#define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses" - -/** A resolved address alongside any LB related information associated with it. - * \a user_data, if not NULL, contains opaque data meant to be consumed by the - * gRPC LB policy. Note that no all LB policies support \a user_data as input. - * Those who don't will simply ignore it and will correspondingly return NULL in - * their namesake pick() output argument. */ -// TODO(roth): Once we figure out a better way of handling user_data in -// LB policies, convert these structs to C++ classes. -typedef struct grpc_lb_address { - grpc_resolved_address address; - bool is_balancer; - char* balancer_name; /* For secure naming. */ - void* user_data; -} grpc_lb_address; - -typedef struct grpc_lb_user_data_vtable { - void* (*copy)(void*); - void (*destroy)(void*); - int (*cmp)(void*, void*); -} grpc_lb_user_data_vtable; - -typedef struct grpc_lb_addresses { - size_t num_addresses; - grpc_lb_address* addresses; - const grpc_lb_user_data_vtable* user_data_vtable; -} grpc_lb_addresses; - -/** Returns a grpc_addresses struct with enough space for - \a num_addresses addresses. The \a user_data_vtable argument may be - NULL if no user data will be added. */ -grpc_lb_addresses* grpc_lb_addresses_create( - size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable); - -/** Creates a copy of \a addresses. */ -grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses); - -/** Sets the value of the address at index \a index of \a addresses. - * \a address is a socket address of length \a address_len. */ -void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index, - const void* address, size_t address_len, - bool is_balancer, const char* balancer_name, - void* user_data); - -/** Sets the value of the address at index \a index of \a addresses from \a uri. - * Returns true upon success, false otherwise. */ -bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses, - size_t index, const grpc_uri* uri, - bool is_balancer, - const char* balancer_name, - void* user_data); - -/** Compares \a addresses1 and \a addresses2. */ -int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1, - const grpc_lb_addresses* addresses2); - -/** Destroys \a addresses. */ -void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses); - -/** Returns a channel arg containing \a addresses. */ -grpc_arg grpc_lb_addresses_create_channel_arg( - const grpc_lb_addresses* addresses); - -/** Returns the \a grpc_lb_addresses instance in \a channel_args or NULL */ -grpc_lb_addresses* grpc_lb_addresses_find_channel_arg( - const grpc_channel_args* channel_args); - -// Returns true if addresses contains at least one balancer address. -bool grpc_lb_addresses_contains_balancer_address( - const grpc_lb_addresses& addresses); - -// -// LB policy factory -// +#include "src/core/lib/gprpp/abstract.h" +#include "src/core/lib/gprpp/orphanable.h" namespace grpc_core { 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 4ebc2c8161c..c8425ae3365 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 @@ -33,6 +33,7 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #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/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -117,7 +118,7 @@ class AresDnsResolver : public Resolver { /// retry backoff state BackOff backoff_; /// currently resolving addresses - grpc_lb_addresses* lb_addresses_ = nullptr; + UniquePtr addresses_; /// currently resolving service config char* service_config_json_ = nullptr; // has shutdown been initiated @@ -314,13 +315,13 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { r->resolving_ = false; gpr_free(r->pending_request_); r->pending_request_ = nullptr; - if (r->lb_addresses_ != nullptr) { + 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++] = - grpc_lb_addresses_create_channel_arg(r->lb_addresses_); + CreateServerAddressListChannelArg(r->addresses_.get()); char* service_config_string = nullptr; if (r->service_config_json_ != nullptr) { service_config_string = ChooseServiceConfig(r->service_config_json_); @@ -337,7 +338,7 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { r->channel_args_, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add); gpr_free(service_config_string); - grpc_lb_addresses_destroy(r->lb_addresses_); + r->addresses_.reset(); // Reset backoff state so that we start from the beginning when the // next request gets triggered. r->backoff_.Reset(); @@ -412,11 +413,10 @@ void AresDnsResolver::StartResolvingLocked() { self.release(); GPR_ASSERT(!resolving_); resolving_ = true; - lb_addresses_ = nullptr; service_config_json_ = nullptr; pending_request_ = grpc_dns_lookup_ares_locked( dns_server_, name_to_resolve_, kDefaultPort, interested_parties_, - &on_resolved_, &lb_addresses_, true /* check_grpclb */, + &on_resolved_, &addresses_, true /* check_grpclb */, request_service_config_ ? &service_config_json_ : nullptr, query_timeout_ms_, combiner()); last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc index f42b1e309df..8abc34c6edb 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -31,6 +31,7 @@ #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/iomgr/timer.h" 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 55715869b63..1b1c2303da3 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 @@ -37,12 +37,16 @@ #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/nameser.h" #include "src/core/lib/iomgr/sockaddr_utils.h" +using grpc_core::ServerAddress; +using grpc_core::ServerAddressList; + static gpr_once g_basic_init = GPR_ONCE_INIT; static gpr_mu g_init_mu; @@ -58,7 +62,7 @@ struct grpc_ares_request { /** closure to call when the request completes */ grpc_closure* on_done; /** the pointer to receive the resolved addresses */ - grpc_lb_addresses** lb_addrs_out; + grpc_core::UniquePtr* addresses_out; /** the pointer to receive the service config in JSON */ char** service_config_json_out; /** the evernt driver used by this request */ @@ -87,12 +91,11 @@ typedef struct grpc_ares_hostbyname_request { static void do_basic_init(void) { gpr_mu_init(&g_init_mu); } -static void log_address_sorting_list(grpc_lb_addresses* lb_addrs, +static void log_address_sorting_list(const ServerAddressList& addresses, const char* input_output_str) { - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { + for (size_t i = 0; i < addresses.size(); i++) { char* addr_str; - if (grpc_sockaddr_to_string(&addr_str, &lb_addrs->addresses[i].address, - true)) { + if (grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true)) { gpr_log(GPR_DEBUG, "c-ares address sorting: %s[%" PRIuPTR "]=%s", input_output_str, i, addr_str); gpr_free(addr_str); @@ -104,29 +107,28 @@ static void log_address_sorting_list(grpc_lb_addresses* lb_addrs, } } -void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs) { +void grpc_cares_wrapper_address_sorting_sort(ServerAddressList* addresses) { if (grpc_trace_cares_address_sorting.enabled()) { - log_address_sorting_list(lb_addrs, "input"); + log_address_sorting_list(*addresses, "input"); } address_sorting_sortable* sortables = (address_sorting_sortable*)gpr_zalloc( - sizeof(address_sorting_sortable) * lb_addrs->num_addresses); - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { - sortables[i].user_data = &lb_addrs->addresses[i]; - memcpy(&sortables[i].dest_addr.addr, &lb_addrs->addresses[i].address.addr, - lb_addrs->addresses[i].address.len); - sortables[i].dest_addr.len = lb_addrs->addresses[i].address.len; + sizeof(address_sorting_sortable) * addresses->size()); + for (size_t i = 0; i < addresses->size(); ++i) { + sortables[i].user_data = &(*addresses)[i]; + memcpy(&sortables[i].dest_addr.addr, &(*addresses)[i].address().addr, + (*addresses)[i].address().len); + sortables[i].dest_addr.len = (*addresses)[i].address().len; } - address_sorting_rfc_6724_sort(sortables, lb_addrs->num_addresses); - grpc_lb_address* sorted_lb_addrs = (grpc_lb_address*)gpr_zalloc( - sizeof(grpc_lb_address) * lb_addrs->num_addresses); - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { - sorted_lb_addrs[i] = *(grpc_lb_address*)sortables[i].user_data; + address_sorting_rfc_6724_sort(sortables, addresses->size()); + ServerAddressList sorted; + sorted.reserve(addresses->size()); + for (size_t i = 0; i < addresses->size(); ++i) { + sorted.emplace_back(*static_cast(sortables[i].user_data)); } gpr_free(sortables); - gpr_free(lb_addrs->addresses); - lb_addrs->addresses = sorted_lb_addrs; + *addresses = std::move(sorted); if (grpc_trace_cares_address_sorting.enabled()) { - log_address_sorting_list(lb_addrs, "output"); + log_address_sorting_list(*addresses, "output"); } } @@ -145,9 +147,9 @@ void grpc_ares_complete_request_locked(grpc_ares_request* r) { /* Invoke on_done callback and destroy the request */ r->ev_driver = nullptr; - grpc_lb_addresses* lb_addrs = *(r->lb_addrs_out); - if (lb_addrs != nullptr) { - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + ServerAddressList* addresses = r->addresses_out->get(); + if (addresses != nullptr) { + grpc_cares_wrapper_address_sorting_sort(addresses); } GRPC_CLOSURE_SCHED(r->on_done, r->error); } @@ -181,33 +183,30 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, GRPC_ERROR_UNREF(r->error); r->error = GRPC_ERROR_NONE; r->success = true; - grpc_lb_addresses** lb_addresses = r->lb_addrs_out; - if (*lb_addresses == nullptr) { - *lb_addresses = grpc_lb_addresses_create(0, nullptr); + if (*r->addresses_out == nullptr) { + *r->addresses_out = grpc_core::MakeUnique(); } - size_t prev_naddr = (*lb_addresses)->num_addresses; - size_t i; - for (i = 0; hostent->h_addr_list[i] != nullptr; i++) { - } - (*lb_addresses)->num_addresses += i; - (*lb_addresses)->addresses = static_cast( - gpr_realloc((*lb_addresses)->addresses, - sizeof(grpc_lb_address) * (*lb_addresses)->num_addresses)); - for (i = prev_naddr; i < (*lb_addresses)->num_addresses; i++) { + ServerAddressList& addresses = **r->addresses_out; + for (size_t i = 0; hostent->h_addr_list[i] != nullptr; ++i) { + grpc_core::InlinedVector args_to_add; + if (hr->is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), hr->host)); + } + grpc_channel_args* args = grpc_channel_args_copy_and_add( + nullptr, args_to_add.data(), args_to_add.size()); switch (hostent->h_addrtype) { case AF_INET6: { size_t addr_len = sizeof(struct sockaddr_in6); struct sockaddr_in6 addr; memset(&addr, 0, addr_len); - memcpy(&addr.sin6_addr, hostent->h_addr_list[i - prev_naddr], + memcpy(&addr.sin6_addr, hostent->h_addr_list[i], sizeof(struct in6_addr)); addr.sin6_family = static_cast(hostent->h_addrtype); addr.sin6_port = hr->port; - grpc_lb_addresses_set_address( - *lb_addresses, i, &addr, addr_len, - hr->is_balancer /* is_balancer */, - hr->is_balancer ? hr->host : nullptr /* balancer_name */, - nullptr /* user_data */); + addresses.emplace_back(&addr, addr_len, args); char output[INET6_ADDRSTRLEN]; ares_inet_ntop(AF_INET6, &addr.sin6_addr, output, INET6_ADDRSTRLEN); gpr_log(GPR_DEBUG, @@ -220,15 +219,11 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, size_t addr_len = sizeof(struct sockaddr_in); struct sockaddr_in addr; memset(&addr, 0, addr_len); - memcpy(&addr.sin_addr, hostent->h_addr_list[i - prev_naddr], + memcpy(&addr.sin_addr, hostent->h_addr_list[i], sizeof(struct in_addr)); addr.sin_family = static_cast(hostent->h_addrtype); addr.sin_port = hr->port; - grpc_lb_addresses_set_address( - *lb_addresses, i, &addr, addr_len, - hr->is_balancer /* is_balancer */, - hr->is_balancer ? hr->host : nullptr /* balancer_name */, - nullptr /* user_data */); + addresses.emplace_back(&addr, addr_len, args); char output[INET_ADDRSTRLEN]; ares_inet_ntop(AF_INET, &addr.sin_addr, output, INET_ADDRSTRLEN); gpr_log(GPR_DEBUG, @@ -467,11 +462,10 @@ error_cleanup: gpr_free(port); } -static bool inner_resolve_as_ip_literal_locked(const char* name, - const char* default_port, - grpc_lb_addresses** addrs, - char** host, char** port, - char** hostport) { +static bool inner_resolve_as_ip_literal_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port, char** hostport) { gpr_split_host_port(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, @@ -495,18 +489,16 @@ static bool inner_resolve_as_ip_literal_locked(const char* name, if (grpc_parse_ipv4_hostport(*hostport, &addr, false /* log errors */) || grpc_parse_ipv6_hostport(*hostport, &addr, false /* log errors */)) { GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_lb_addresses_create(1, nullptr); - grpc_lb_addresses_set_address( - *addrs, 0, addr.addr, addr.len, false /* is_balancer */, - nullptr /* balancer_name */, nullptr /* user_data */); + *addrs = grpc_core::MakeUnique(); + (*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */); return true; } return false; } -static bool resolve_as_ip_literal_locked(const char* name, - const char* default_port, - grpc_lb_addresses** addrs) { +static bool resolve_as_ip_literal_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { char* host = nullptr; char* port = nullptr; char* hostport = nullptr; @@ -521,13 +513,14 @@ static bool resolve_as_ip_literal_locked(const char* name, static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { grpc_ares_request* r = static_cast(gpr_zalloc(sizeof(grpc_ares_request))); r->ev_driver = nullptr; r->on_done = on_done; - r->lb_addrs_out = addrs; + r->addresses_out = addrs; r->service_config_json_out = service_config_json; r->success = false; r->error = GRPC_ERROR_NONE; @@ -553,8 +546,8 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) { @@ -599,8 +592,8 @@ typedef struct grpc_resolve_address_ares_request { grpc_combiner* combiner; /** the pointer to receive the resolved addresses */ grpc_resolved_addresses** addrs_out; - /** currently resolving lb addresses */ - grpc_lb_addresses* lb_addrs; + /** currently resolving addresses */ + grpc_core::UniquePtr addresses; /** closure to call when the resolve_address_ares request completes */ grpc_closure* on_resolve_address_done; /** a closure wrapping on_resolve_address_done, which should be invoked when @@ -613,7 +606,7 @@ typedef struct grpc_resolve_address_ares_request { /* pollset_set to be driven by */ grpc_pollset_set* interested_parties; /* underlying ares_request that the query is performed on */ - grpc_ares_request* ares_request; + grpc_ares_request* ares_request = nullptr; } grpc_resolve_address_ares_request; static void on_dns_lookup_done_locked(void* arg, grpc_error* error) { @@ -621,25 +614,24 @@ static void on_dns_lookup_done_locked(void* arg, grpc_error* error) { static_cast(arg); gpr_free(r->ares_request); grpc_resolved_addresses** resolved_addresses = r->addrs_out; - if (r->lb_addrs == nullptr || r->lb_addrs->num_addresses == 0) { + if (r->addresses == nullptr || r->addresses->empty()) { *resolved_addresses = nullptr; } else { *resolved_addresses = static_cast( gpr_zalloc(sizeof(grpc_resolved_addresses))); - (*resolved_addresses)->naddrs = r->lb_addrs->num_addresses; + (*resolved_addresses)->naddrs = r->addresses->size(); (*resolved_addresses)->addrs = static_cast(gpr_zalloc( sizeof(grpc_resolved_address) * (*resolved_addresses)->naddrs)); - for (size_t i = 0; i < (*resolved_addresses)->naddrs; i++) { - GPR_ASSERT(!r->lb_addrs->addresses[i].is_balancer); - memcpy(&(*resolved_addresses)->addrs[i], - &r->lb_addrs->addresses[i].address, sizeof(grpc_resolved_address)); + for (size_t i = 0; i < (*resolved_addresses)->naddrs; ++i) { + GPR_ASSERT(!(*r->addresses)[i].IsBalancer()); + memcpy(&(*resolved_addresses)->addrs[i], &(*r->addresses)[i].address(), + sizeof(grpc_resolved_address)); } } GRPC_CLOSURE_SCHED(r->on_resolve_address_done, GRPC_ERROR_REF(error)); - if (r->lb_addrs != nullptr) grpc_lb_addresses_destroy(r->lb_addrs); GRPC_COMBINER_UNREF(r->combiner, "on_dns_lookup_done_cb"); - gpr_free(r); + grpc_core::Delete(r); } static void grpc_resolve_address_invoke_dns_lookup_ares_locked( @@ -648,7 +640,7 @@ static void grpc_resolve_address_invoke_dns_lookup_ares_locked( static_cast(arg); r->ares_request = grpc_dns_lookup_ares_locked( nullptr /* dns_server */, r->name, r->default_port, r->interested_parties, - &r->on_dns_lookup_done_locked, &r->lb_addrs, false /* check_grpclb */, + &r->on_dns_lookup_done_locked, &r->addresses, false /* check_grpclb */, nullptr /* service_config_json */, GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, r->combiner); } @@ -659,8 +651,7 @@ static void grpc_resolve_address_ares_impl(const char* name, grpc_closure* on_done, grpc_resolved_addresses** addrs) { grpc_resolve_address_ares_request* r = - static_cast( - gpr_zalloc(sizeof(grpc_resolve_address_ares_request))); + grpc_core::New(); r->combiner = grpc_combiner_create(); r->addrs_out = addrs; r->on_resolve_address_done = on_done; diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h index 9acef1d0ca9..28082504565 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -21,7 +21,7 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -61,8 +61,9 @@ extern void (*grpc_resolve_address_ares)(const char* name, extern grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addresses, bool check_grpclb, - char** service_config_json, int query_timeout_ms, grpc_combiner* combiner); + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner); /* Cancel the pending grpc_ares_request \a request */ extern void (*grpc_cancel_ares_request_locked)(grpc_ares_request* request); @@ -89,10 +90,12 @@ bool grpc_ares_query_ipv6(); * Returns a bool indicating whether or not such an action was performed. * See https://github.com/grpc/grpc/issues/15158. */ bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs); + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs); /* Sorts destinations in lb_addrs according to RFC 6724. */ -void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs); +void grpc_cares_wrapper_address_sorting_sort( + grpc_core::ServerAddressList* addresses); #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H \ */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc index fc78b183044..1f4701c9994 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc @@ -29,16 +29,17 @@ struct grpc_ares_request { static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { return NULL; } grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {} diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc index 639eec2323f..028d8442169 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc @@ -27,7 +27,8 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs) { + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { return false; } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index 7e34784691f..202452f1b2b 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -23,9 +23,9 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_windows.h" @@ -33,8 +33,9 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } static bool inner_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs, - char** host, char** port) { + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port) { gpr_split_host_port(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, @@ -55,7 +56,7 @@ static bool inner_maybe_resolve_localhost_manually_locked( } if (gpr_stricmp(*host, "localhost") == 0) { GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_lb_addresses_create(2, nullptr); + *addrs = grpc_core::MakeUnique(); uint16_t numeric_port = grpc_strhtons(*port); // Append the ipv6 loopback address. struct sockaddr_in6 ipv6_loopback_addr; @@ -63,10 +64,8 @@ static bool inner_maybe_resolve_localhost_manually_locked( ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; ipv6_loopback_addr.sin6_family = AF_INET6; ipv6_loopback_addr.sin6_port = numeric_port; - grpc_lb_addresses_set_address( - *addrs, 0, &ipv6_loopback_addr, sizeof(ipv6_loopback_addr), - false /* is_balancer */, nullptr /* balancer_name */, - nullptr /* user_data */); + (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), + nullptr /* args */); // Append the ipv4 loopback address. struct sockaddr_in ipv4_loopback_addr; memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); @@ -74,19 +73,18 @@ static bool inner_maybe_resolve_localhost_manually_locked( ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; ipv4_loopback_addr.sin_family = AF_INET; ipv4_loopback_addr.sin_port = numeric_port; - grpc_lb_addresses_set_address( - *addrs, 1, &ipv4_loopback_addr, sizeof(ipv4_loopback_addr), - false /* is_balancer */, nullptr /* balancer_name */, - nullptr /* user_data */); + (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), + nullptr /* args */); // Let the address sorter figure out which one should be tried first. - grpc_cares_wrapper_address_sorting_sort(*addrs); + grpc_cares_wrapper_address_sorting_sort(addrs->get()); return true; } return false; } bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs) { + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { char* host = nullptr; char* port = nullptr; bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, 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 65ff1ec1a5b..c365f1abfd8 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 @@ -26,8 +26,8 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -198,18 +198,14 @@ void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(r->name_to_resolve_)); if (r->addresses_ != nullptr) { - grpc_lb_addresses* addresses = grpc_lb_addresses_create( - r->addresses_->naddrs, nullptr /* user_data_vtable */); + ServerAddressList addresses; for (size_t i = 0; i < r->addresses_->naddrs; ++i) { - grpc_lb_addresses_set_address( - addresses, i, &r->addresses_->addrs[i].addr, - r->addresses_->addrs[i].len, false /* is_balancer */, - nullptr /* balancer_name */, nullptr /* user_data */); + addresses.emplace_back(&r->addresses_->addrs[i].addr, + r->addresses_->addrs[i].len, nullptr /* args */); } - grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses); + 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_lb_addresses_destroy(addresses); // 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 3aa690bea41..258339491c1 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 @@ -28,12 +28,13 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/resolve_address.h" 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 7f690593510..d86111c3829 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,10 +19,9 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/ref_counted.h" -#include "src/core/lib/uri/uri_parser.h" +#include "src/core/lib/iomgr/error.h" #define GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR \ "grpc.fake_resolver.response_generator" 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 801734764b4..1654747a79f 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 @@ -26,9 +26,9 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" @@ -45,7 +45,8 @@ namespace { class SockaddrResolver : public Resolver { public: /// Takes ownership of \a addresses. - SockaddrResolver(const ResolverArgs& args, grpc_lb_addresses* addresses); + SockaddrResolver(const ResolverArgs& args, + UniquePtr addresses); void NextLocked(grpc_channel_args** result, grpc_closure* on_complete) override; @@ -58,7 +59,7 @@ class SockaddrResolver : public Resolver { void MaybeFinishNextLocked(); /// the addresses that we've "resolved" - grpc_lb_addresses* addresses_ = nullptr; + UniquePtr addresses_; /// channel args grpc_channel_args* channel_args_ = nullptr; /// have we published? @@ -70,13 +71,12 @@ class SockaddrResolver : public Resolver { }; SockaddrResolver::SockaddrResolver(const ResolverArgs& args, - grpc_lb_addresses* addresses) + UniquePtr addresses) : Resolver(args.combiner), - addresses_(addresses), + addresses_(std::move(addresses)), channel_args_(grpc_channel_args_copy(args.args)) {} SockaddrResolver::~SockaddrResolver() { - grpc_lb_addresses_destroy(addresses_); grpc_channel_args_destroy(channel_args_); } @@ -100,7 +100,7 @@ void SockaddrResolver::ShutdownLocked() { void SockaddrResolver::MaybeFinishNextLocked() { if (next_completion_ != nullptr && !published_) { published_ = true; - grpc_arg arg = grpc_lb_addresses_create_channel_arg(addresses_); + 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; @@ -127,27 +127,27 @@ OrphanablePtr CreateSockaddrResolver( grpc_slice_buffer path_parts; grpc_slice_buffer_init(&path_parts); grpc_slice_split(path_slice, ",", &path_parts); - grpc_lb_addresses* addresses = grpc_lb_addresses_create( - path_parts.count, nullptr /* user_data_vtable */); + auto addresses = MakeUnique(); bool errors_found = false; - for (size_t i = 0; i < addresses->num_addresses; i++) { + for (size_t i = 0; i < path_parts.count; i++) { grpc_uri ith_uri = *args.uri; - char* part_str = grpc_slice_to_c_string(path_parts.slices[i]); - ith_uri.path = part_str; - if (!parse(&ith_uri, &addresses->addresses[i].address)) { + UniquePtr part_str(grpc_slice_to_c_string(path_parts.slices[i])); + ith_uri.path = part_str.get(); + grpc_resolved_address addr; + if (!parse(&ith_uri, &addr)) { errors_found = true; /* GPR_TRUE */ + break; } - gpr_free(part_str); - if (errors_found) break; + addresses->emplace_back(addr, nullptr /* args */); } grpc_slice_buffer_destroy_internal(&path_parts); grpc_slice_unref_internal(path_slice); if (errors_found) { - grpc_lb_addresses_destroy(addresses); return OrphanablePtr(nullptr); } // Instantiate resolver. - return OrphanablePtr(New(args, addresses)); + return OrphanablePtr( + New(args, std::move(addresses))); } class IPv4ResolverFactory : public ResolverFactory { 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 4f7fd6b4243..22b06db45c4 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -30,9 +30,11 @@ #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/status_util.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/uri/uri_parser.h" // As per the retry design, we do not allow more than 5 retry attempts. #define MAX_MAX_RETRY_ATTEMPTS 5 @@ -99,12 +101,18 @@ void ProcessedResolverResult::ProcessLbPolicyName( } // Special case: If at least one balancer address is present, we use // the grpclb policy, regardless of what the resolver has returned. - const grpc_arg* channel_arg = - grpc_channel_args_find(resolver_result, GRPC_ARG_LB_ADDRESSES); - if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) { - grpc_lb_addresses* addresses = - static_cast(channel_arg->value.pointer.p); - if (grpc_lb_addresses_contains_balancer_address(*addresses)) { + 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; + } + } + if (found_balancer_address) { if (lb_policy_name_ != nullptr && strcmp(lb_policy_name_.get(), "grpclb") != 0) { gpr_log(GPR_INFO, diff --git a/src/core/ext/filters/client_channel/server_address.cc b/src/core/ext/filters/client_channel/server_address.cc new file mode 100644 index 00000000000..ec33cbbd956 --- /dev/null +++ b/src/core/ext/filters/client_channel/server_address.cc @@ -0,0 +1,103 @@ +/* + * + * 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/server_address.h" + +#include + +namespace grpc_core { + +// +// ServerAddress +// + +ServerAddress::ServerAddress(const grpc_resolved_address& address, + grpc_channel_args* args) + : address_(address), args_(args) {} + +ServerAddress::ServerAddress(const void* address, size_t address_len, + grpc_channel_args* args) + : args_(args) { + memcpy(address_.addr, address, address_len); + address_.len = static_cast(address_len); +} + +int ServerAddress::Cmp(const ServerAddress& other) const { + if (address_.len > other.address_.len) return 1; + if (address_.len < other.address_.len) return -1; + int retval = memcmp(address_.addr, other.address_.addr, address_.len); + if (retval != 0) return retval; + return grpc_channel_args_compare(args_, other.args_); +} + +bool ServerAddress::IsBalancer() const { + return grpc_channel_arg_get_bool( + 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 new file mode 100644 index 00000000000..3a1bf1df67d --- /dev/null +++ b/src/core/ext/filters/client_channel/server_address.h @@ -0,0 +1,108 @@ +/* + * + * 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_SERVER_ADDRESS_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H + +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#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" + +// Channel arg key for a string indicating an address's balancer name. +#define GRPC_ARG_ADDRESS_BALANCER_NAME "grpc.address_balancer_name" + +namespace grpc_core { + +// +// ServerAddress +// + +// A server address is a grpc_resolved_address with an associated set of +// channel args. Any args present here will be merged into the channel +// args when a subchannel is created for this address. +class ServerAddress { + public: + // Takes ownership of args. + ServerAddress(const grpc_resolved_address& address, grpc_channel_args* args); + ServerAddress(const void* address, size_t address_len, + grpc_channel_args* args); + + ~ServerAddress() { grpc_channel_args_destroy(args_); } + + // Copyable. + ServerAddress(const ServerAddress& other) + : address_(other.address_), args_(grpc_channel_args_copy(other.args_)) {} + ServerAddress& operator=(const ServerAddress& other) { + address_ = other.address_; + grpc_channel_args_destroy(args_); + args_ = grpc_channel_args_copy(other.args_); + return *this; + } + + // Movable. + ServerAddress(ServerAddress&& other) + : address_(other.address_), args_(other.args_) { + other.args_ = nullptr; + } + ServerAddress& operator=(ServerAddress&& other) { + address_ = other.address_; + args_ = other.args_; + other.args_ = nullptr; + return *this; + } + + bool operator==(const ServerAddress& other) const { return Cmp(other) == 0; } + + int Cmp(const ServerAddress& other) const; + + const grpc_resolved_address& address() const { return address_; } + const grpc_channel_args* args() const { return args_; } + + bool IsBalancer() const; + + private: + grpc_resolved_address address_; + grpc_channel_args* args_; +}; + +// +// ServerAddressList +// + +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/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index af55f7710e2..9077aa97539 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -837,7 +837,7 @@ static bool publish_transport_locked(grpc_subchannel* c) { /* publish */ c->connected_subchannel.reset(grpc_core::New( - stk, c->channelz_subchannel, socket_uuid)); + 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); @@ -1068,16 +1068,18 @@ grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) { namespace grpc_core { ConnectedSubchannel::ConnectedSubchannel( - grpc_channel_stack* channel_stack, + 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"); } diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 69c2456ec20..14f87f2c68e 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -85,28 +85,31 @@ class ConnectedSubchannel : public RefCounted { size_t parent_data_size; }; - explicit ConnectedSubchannel( - grpc_channel_stack* channel_stack, + ConnectedSubchannel( + grpc_channel_stack* channel_stack, const grpc_channel_args* args, grpc_core::RefCountedPtr channelz_subchannel, intptr_t socket_uuid); ~ConnectedSubchannel(); - grpc_channel_stack* channel_stack() { return channel_stack_; } void NotifyOnStateChange(grpc_pollset_set* interested_parties, 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); - channelz::SubchannelNode* channelz_subchannel() { + + grpc_channel_stack* channel_stack() const { return channel_stack_; } + const grpc_channel_args* args() const { return args_; } + channelz::SubchannelNode* channelz_subchannel() const { return channelz_subchannel_.get(); } - intptr_t socket_uuid() { return socket_uuid_; } + intptr_t socket_uuid() const { return socket_uuid_; } size_t GetInitialCallSizeEstimate(size_t parent_data_size) const; private: grpc_channel_stack* channel_stack_; + grpc_channel_args* args_; // ref counted pointer to the channelz node in this connected subchannel's // owning subchannel. grpc_core::RefCountedPtr diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc index 1b66dceb130..0839bdfef2d 100644 --- a/src/core/lib/iomgr/sockaddr_utils.cc +++ b/src/core/lib/iomgr/sockaddr_utils.cc @@ -217,6 +217,7 @@ void grpc_string_to_sockaddr(grpc_resolved_address* out, char* addr, int port) { } char* grpc_sockaddr_to_uri(const grpc_resolved_address* resolved_addr) { + if (resolved_addr->len == 0) return nullptr; grpc_resolved_address addr_normalized; if (grpc_sockaddr_is_v4mapped(resolved_addr, &addr_normalized)) { resolved_addr = &addr_normalized; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index ce65c594fe2..c6ca970beee 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -322,7 +322,6 @@ CORE_SOURCE_FILES = [ '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_factory.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', @@ -331,6 +330,7 @@ CORE_SOURCE_FILES = [ '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/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/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 76769b2b64a..1a7a7c9ccc9 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -21,10 +21,10 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver.h" #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/lib/channel/channel_args.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -63,8 +63,9 @@ static grpc_address_resolver_vtable test_resolver = {my_resolve_address, static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { gpr_mu_lock(&g_mu); GPR_ASSERT(0 == strcmp("test", addr)); grpc_error* error = GRPC_ERROR_NONE; @@ -74,9 +75,8 @@ static grpc_ares_request* my_dns_lookup_ares_locked( error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { gpr_mu_unlock(&g_mu); - *lb_addrs = grpc_lb_addresses_create(1, nullptr); - grpc_lb_addresses_set_address(*lb_addrs, 0, nullptr, 0, false, nullptr, - nullptr); + *addresses = grpc_core::MakeUnique(); + (*addresses)->emplace_back(nullptr, 0, nullptr); } GRPC_CLOSURE_SCHED(on_done, error); return nullptr; 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 cdbe33dbe79..16210b8164b 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -22,6 +22,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/lib/channel/channel_args.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/combiner.h" @@ -40,8 +41,9 @@ static grpc_combiner* g_combiner; static grpc_ares_request* (*g_default_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner); + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner); // Counter incremented by test_resolve_address_impl indicating the number of // times a system-level resolution has happened. @@ -90,11 +92,12 @@ static grpc_address_resolver_vtable test_resolver = { static grpc_ares_request* test_dns_lookup_ares_locked( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { grpc_ares_request* result = g_default_dns_lookup_ares_locked( - dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, addrs, - check_grpclb, service_config_json, query_timeout_ms, combiner); + dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, + addresses, check_grpclb, service_config_json, query_timeout_ms, combiner); ++g_resolution_count; static grpc_millis last_resolution_time = 0; if (last_resolution_time == 0) { diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc index 6362b95e50e..3b06fe063ae 100644 --- a/test/core/client_channel/resolvers/fake_resolver_test.cc +++ b/test/core/client_channel/resolvers/fake_resolver_test.cc @@ -22,10 +22,10 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.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/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/combiner.h" @@ -63,12 +63,14 @@ void on_resolution_cb(void* arg, grpc_error* error) { // We only check the addresses channel arg because that's the only one // explicitly set by the test via // FakeResolverResponseGenerator::SetResponse(). - const grpc_lb_addresses* actual_lb_addresses = - grpc_lb_addresses_find_channel_arg(res->resolver_result); - const grpc_lb_addresses* expected_lb_addresses = - grpc_lb_addresses_find_channel_arg(res->expected_resolver_result); - GPR_ASSERT( - grpc_lb_addresses_cmp(actual_lb_addresses, expected_lb_addresses) == 0); + 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); @@ -80,27 +82,35 @@ static grpc_channel_args* create_new_resolver_result() { const size_t num_addresses = 2; char* uri_string; char* balancer_name; - // Create grpc_lb_addresses. - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(num_addresses, nullptr); + // Create address list. + grpc_core::ServerAddressList addresses; 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); grpc_uri* uri = grpc_uri_parse(uri_string, true); gpr_asprintf(&balancer_name, "balancer%" PRIuPTR, test_counter * num_addresses + i); - grpc_lb_addresses_set_address_from_uri( - addresses, i, uri, bool(num_addresses % 2), balancer_name, nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(uri, &address)); + grpc_core::InlinedVector args_to_add; + const bool is_balancer = num_addresses % 2; + if (is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), balancer_name)); + } + 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); gpr_free(balancer_name); grpc_uri_destroy(uri); gpr_free(uri_string); } - // Convert grpc_lb_addresses to grpc_channel_args. - const grpc_arg addresses_arg = - grpc_lb_addresses_create_channel_arg(addresses); + // 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); - grpc_lb_addresses_destroy(addresses); ++test_counter; return results; } diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index a3de56d4f9f..fe471279841 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -24,8 +24,8 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -325,7 +325,7 @@ typedef struct addr_req { char* addr; grpc_closure* on_done; grpc_resolved_addresses** addrs; - grpc_lb_addresses** lb_addrs; + grpc_core::UniquePtr* addresses; } addr_req; static void finish_resolve(void* arg, grpc_error* error) { @@ -340,11 +340,9 @@ static void finish_resolve(void* arg, grpc_error* error) { gpr_malloc(sizeof(*addrs->addrs))); addrs->addrs[0].len = 0; *r->addrs = addrs; - } else if (r->lb_addrs != nullptr) { - grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(1, nullptr); - grpc_lb_addresses_set_address(lb_addrs, 0, nullptr, 0, false, nullptr, - nullptr); - *r->lb_addrs = lb_addrs; + } else if (r->addresses != nullptr) { + *r->addresses = grpc_core::MakeUnique(); + (*r->addresses)->emplace_back(nullptr, 0, nullptr); } GRPC_CLOSURE_SCHED(r->on_done, GRPC_ERROR_NONE); } else { @@ -354,18 +352,17 @@ static void finish_resolve(void* arg, grpc_error* error) { } gpr_free(r->addr); - gpr_free(r); + grpc_core::Delete(r); } void my_resolve_address(const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_resolved_addresses** addresses) { - addr_req* r = static_cast(gpr_malloc(sizeof(*r))); + grpc_resolved_addresses** addrs) { + addr_req* r = grpc_core::New(); r->addr = gpr_strdup(addr); r->on_done = on_done; - r->addrs = addresses; - r->lb_addrs = nullptr; + r->addrs = addrs; grpc_timer_init( &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); @@ -377,13 +374,14 @@ static grpc_address_resolver_vtable fuzzer_resolver = {my_resolve_address, grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - int query_timeout, grpc_combiner* combiner) { + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout, + grpc_combiner* combiner) { addr_req* r = static_cast(gpr_malloc(sizeof(*r))); r->addr = gpr_strdup(addr); r->on_done = on_done; r->addrs = nullptr; - r->lb_addrs = lb_addrs; + r->addresses = addresses; grpc_timer_init( &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 66e8ca51614..7e3b418cd94 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -28,8 +28,8 @@ #include #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr.h" #include "test/core/end2end/cq_verifier.h" @@ -47,8 +47,9 @@ static int g_resolve_port = -1; static grpc_ares_request* (*iomgr_dns_lookup_ares_locked)( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addresses, bool check_grpclb, - char** service_config_json, int query_timeout_ms, grpc_combiner* combiner); + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner); static void (*iomgr_cancel_ares_request_locked)(grpc_ares_request* request); @@ -103,11 +104,12 @@ static grpc_address_resolver_vtable test_resolver = { static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, - int query_timeout_ms, grpc_combiner* combiner) { + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner) { if (0 != strcmp(addr, "test")) { return iomgr_dns_lookup_ares_locked( - dns_server, addr, default_port, interested_parties, on_done, lb_addrs, + dns_server, addr, default_port, interested_parties, on_done, addresses, check_grpclb, service_config_json, query_timeout_ms, combiner); } @@ -117,15 +119,12 @@ static grpc_ares_request* my_dns_lookup_ares_locked( gpr_mu_unlock(&g_mu); error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { - *lb_addrs = grpc_lb_addresses_create(1, nullptr); - grpc_sockaddr_in* sa = - static_cast(gpr_zalloc(sizeof(grpc_sockaddr_in))); - sa->sin_family = GRPC_AF_INET; - sa->sin_addr.s_addr = 0x100007f; - sa->sin_port = grpc_htons(static_cast(g_resolve_port)); - grpc_lb_addresses_set_address(*lb_addrs, 0, sa, sizeof(*sa), false, nullptr, - nullptr); - gpr_free(sa); + *addresses = grpc_core::MakeUnique(); + grpc_sockaddr_in sa; + sa.sin_family = GRPC_AF_INET; + sa.sin_addr.s_addr = 0x100007f; + sa.sin_port = grpc_htons(static_cast(g_resolve_port)); + (*addresses)->emplace_back(&sa, sizeof(sa), nullptr); gpr_mu_unlock(&g_mu); } GRPC_CLOSURE_SCHED(on_done, error); diff --git a/test/core/end2end/no_server_test.cc b/test/core/end2end/no_server_test.cc index 5dda748f5a5..c289e719eea 100644 --- a/test/core/end2end/no_server_test.cc +++ b/test/core/end2end/no_server_test.cc @@ -23,6 +23,7 @@ #include #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/test_config.h" diff --git a/test/core/util/ubsan_suppressions.txt b/test/core/util/ubsan_suppressions.txt index 63898ea3b1c..8ed7d4d7fb6 100644 --- a/test/core/util/ubsan_suppressions.txt +++ b/test/core/util/ubsan_suppressions.txt @@ -25,7 +25,6 @@ alignment:absl::little_endian::Store64 alignment:absl::little_endian::Load64 float-divide-by-zero:grpc::testing::postprocess_scenario_result enum:grpc_op_string -nonnull-attribute:grpc_lb_addresses_copy signed-integer-overflow:chrono enum:grpc_http2_error_to_grpc_status -enum:grpc_chttp2_cancel_stream \ No newline at end of file +enum:grpc_chttp2_cancel_stream diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index bf321d8a89e..124557eb567 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -34,7 +34,9 @@ #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/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -216,23 +218,31 @@ class ClientChannelStressTest { void SetNextResolution(const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(address_data.size(), nullptr); - for (size_t i = 0; i < address_data.size(); ++i) { + grpc_core::ServerAddressList addresses; + for (const auto& addr : address_data) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port); + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port); grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); GPR_ASSERT(lb_uri != nullptr); - grpc_lb_addresses_set_address_from_uri( - addresses, i, lb_uri, address_data[i].is_balancer, - address_data[i].balancer_name.c_str(), nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + std::vector args_to_add; + if (addr.is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), + const_cast(addr.balancer_name.c_str()))); + } + 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); } - grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); + grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); grpc_channel_args fake_result = {1, &fake_addresses}; response_generator_->SetResponse(&fake_result); - grpc_lb_addresses_destroy(addresses); } void KeepSendingRequests() { diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 1dfa91a76c7..929c2bb5899 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -35,7 +35,9 @@ #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/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/gpr/env.h" @@ -159,24 +161,22 @@ class ClientLbEnd2endTest : public ::testing::Test { } grpc_channel_args* BuildFakeResults(const std::vector& ports) { - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(ports.size(), nullptr); - for (size_t i = 0; i < ports.size(); ++i) { + grpc_core::ServerAddressList addresses; + for (const int& port : ports) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", ports[i]); + 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_lb_addresses_set_address_from_uri(addresses, i, lb_uri, - false /* is balancer */, - "" /* balancer name */, nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + addresses.emplace_back(address.addr, address.len, nullptr /* args */); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } const grpc_arg fake_addresses = - grpc_lb_addresses_create_channel_arg(addresses); + CreateServerAddressListChannelArg(&addresses); grpc_channel_args* fake_results = grpc_channel_args_copy_and_add(nullptr, &fake_addresses, 1); - grpc_lb_addresses_destroy(addresses); return fake_results; } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 9c4cd050619..bf990a07b5a 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -32,7 +32,9 @@ #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" @@ -486,18 +488,27 @@ class GrpclbEnd2endTest : public ::testing::Test { grpc::string balancer_name; }; - grpc_lb_addresses* CreateLbAddressesFromAddressDataList( + grpc_core::ServerAddressList CreateLbAddressesFromAddressDataList( const std::vector& address_data) { - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(address_data.size(), nullptr); - for (size_t i = 0; i < address_data.size(); ++i) { + grpc_core::ServerAddressList addresses; + for (const auto& addr : address_data) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port); + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port); grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); GPR_ASSERT(lb_uri != nullptr); - grpc_lb_addresses_set_address_from_uri( - addresses, i, lb_uri, address_data[i].is_balancer, - address_data[i].balancer_name.c_str(), nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + std::vector args_to_add; + if (addr.is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), + const_cast(addr.balancer_name.c_str()))); + } + 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); } @@ -506,23 +517,21 @@ class GrpclbEnd2endTest : public ::testing::Test { void SetNextResolution(const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses* addresses = + grpc_core::ServerAddressList addresses = CreateLbAddressesFromAddressDataList(address_data); - grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); + grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); grpc_channel_args fake_result = {1, &fake_addresses}; response_generator_->SetResponse(&fake_result); - grpc_lb_addresses_destroy(addresses); } void SetNextReresolutionResponse( const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses* addresses = + grpc_core::ServerAddressList addresses = CreateLbAddressesFromAddressDataList(address_data); - grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); + grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); grpc_channel_args fake_result = {1, &fake_addresses}; response_generator_->SetReresolutionResponse(&fake_result); - grpc_lb_addresses_destroy(addresses); } const std::vector GetBackendPorts(const size_t start_index = 0) const { diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index 3eb0e7d7254..09e705df789 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -37,6 +37,7 @@ #include "src/core/ext/filters/client_channel/resolver.h" #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/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" @@ -167,30 +168,26 @@ void OverrideAddressSortingSourceAddrFactory( address_sorting_override_source_addr_factory_for_testing(factory); } -grpc_lb_addresses* BuildLbAddrInputs(std::vector test_addrs) { - grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(0, nullptr); - lb_addrs->addresses = - (grpc_lb_address*)gpr_zalloc(sizeof(grpc_lb_address) * test_addrs.size()); - lb_addrs->num_addresses = test_addrs.size(); - for (size_t i = 0; i < test_addrs.size(); i++) { - lb_addrs->addresses[i].address = - TestAddressToGrpcResolvedAddress(test_addrs[i]); +grpc_core::ServerAddressList BuildLbAddrInputs( + const std::vector& test_addrs) { + grpc_core::ServerAddressList addresses; + for (const auto& addr : test_addrs) { + addresses.emplace_back(TestAddressToGrpcResolvedAddress(addr), nullptr); } - return lb_addrs; + return addresses; } -void VerifyLbAddrOutputs(grpc_lb_addresses* lb_addrs, +void VerifyLbAddrOutputs(const grpc_core::ServerAddressList addresses, std::vector expected_addrs) { - EXPECT_EQ(lb_addrs->num_addresses, expected_addrs.size()); - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { + EXPECT_EQ(addresses.size(), expected_addrs.size()); + for (size_t i = 0; i < addresses.size(); ++i) { char* ip_addr_str; - grpc_sockaddr_to_string(&ip_addr_str, &lb_addrs->addresses[i].address, + grpc_sockaddr_to_string(&ip_addr_str, &addresses[i].address(), false /* normalize */); EXPECT_EQ(expected_addrs[i], ip_addr_str); gpr_free(ip_addr_str); } grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses_destroy(lb_addrs); } /* We need to run each test case inside of its own @@ -212,11 +209,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) { { {"1.2.3.4:443", {"4.3.2.1:443", AF_INET}}, }); - auto* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"1.2.3.4:443", AF_INET}, {"5.6.7.8:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "1.2.3.4:443", "5.6.7.8:443", @@ -235,7 +232,7 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) { {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "1.2.3.4:443", "[2607:f8b0:400a:801::1002]:443", @@ -251,11 +248,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) { {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}}, {"[2607:f8b0:400a:801::1002]:443", {"[fec0::1234]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2607:f8b0:400a:801::1002]:443", "1.2.3.4:443", @@ -275,11 +272,11 @@ TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) { {"[fec0::5000]:443", {"[fec0::5001]:0", AF_INET6}}, // site-local and site-local scope }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2000:f8b0:400a:801::1002]:443", AF_INET6}, {"[fec0::5000]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fec0::5000]:443", "[2000:f8b0:400a:801::1002]:443", @@ -298,11 +295,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) { {"[2001::5001]:443", {"[2001::5002]:0", AF_INET6}}, // matching labels }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2002::5001]:443", AF_INET6}, {"[2001::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2001::5001]:443", "[2002::5001]:443", @@ -321,11 +318,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) { {"[2001::5001]:443", {"[2001::5002]:0", AF_INET6}}, // matching labels }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2001::5001]:443", AF_INET6}, {"[2002::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2001::5001]:443", "[2002::5001]:443", @@ -344,11 +341,11 @@ TEST_F(AddressSortingTest, {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}}, {"1.2.3.4:443", {"5.6.7.8:0", AF_INET}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs( lb_addrs, { // The AF_INET address should be IPv4-mapped by the sort, @@ -377,11 +374,11 @@ TEST_F(AddressSortingTest, {"[::1]:443", {"[::1]:0", AF_INET6}}, {v4_compat_dest, {v4_compat_src, AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {v4_compat_dest, AF_INET6}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", v4_compat_dest, @@ -400,11 +397,11 @@ TEST_F(AddressSortingTest, {"[1234::2]:443", {"[1234::2]:0", AF_INET6}}, {"[::1]:443", {"[::1]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[1234::2]:443", AF_INET6}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs( lb_addrs, { @@ -424,11 +421,11 @@ TEST_F(AddressSortingTest, {"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}}, {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2001::1234]:443", AF_INET6}, {"[2000::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs( lb_addrs, { // The 2000::/16 address should match the ::/0 prefix rule @@ -448,11 +445,11 @@ TEST_F( {"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}}, {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2001::1231]:443", AF_INET6}, {"[2000::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2000::5001]:443", "[2001::1231]:443", @@ -469,11 +466,11 @@ TEST_F(AddressSortingTest, {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}}, {"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[fec0::1234]:443", AF_INET6}, {"[fc00::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fc00::5001]:443", "[fec0::1234]:443", @@ -494,11 +491,11 @@ TEST_F( {"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}}, {"[1234::2]:443", {"[1234::3]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[::ffff:1.1.1.2]:443", AF_INET6}, {"[1234::2]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { // ::ffff:0:2 should match the v4-mapped // precedence entry and be deprioritized. @@ -521,11 +518,11 @@ TEST_F(AddressSortingTest, TestPrefersSmallerScope) { {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}}, {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"[fec0::1234]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fec0::1234]:443", "[3ffe::5001]:443", @@ -546,11 +543,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) { {"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}}, {"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:5001::]:443", AF_INET6}, {"[3ffe:1234::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:1234::]:443", "[3ffe:5001::]:443", @@ -567,11 +564,11 @@ TEST_F(AddressSortingTest, {"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}}, {"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1234]:443", "[3ffe::5001]:443", @@ -587,11 +584,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) { {"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}}, {"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:8000::]:443", AF_INET6}, {"[3ffe:2000::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:2000::]:443", "[3ffe:8000::]:443", @@ -607,11 +604,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) { {"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}}, {"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:6::]:443", AF_INET6}, {"[3ffe:c::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:c::]:443", "[3ffe:6::]:443", @@ -629,11 +626,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) { {"[3ffe:1111:1111:1110::]:443", {"[3ffe:1111:1111:1111::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:1111:1111:1110::]:443", AF_INET6}, {"[3ffe:1111:1111:1111::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:1111:1111:1111::]:443", "[3ffe:1111:1111:1110::]:443", @@ -651,11 +648,11 @@ TEST_F(AddressSortingTest, TestStableSort) { {"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}}, {"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1234]:443", "[3ffe::1235]:443", @@ -674,14 +671,14 @@ TEST_F(AddressSortingTest, TestStableSortFiveElements) { {"[3ffe::1234]:443", {"[3ffe::1204]:0", AF_INET6}}, {"[3ffe::1235]:443", {"[3ffe::1205]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::1231]:443", AF_INET6}, {"[3ffe::1232]:443", AF_INET6}, {"[3ffe::1233]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1231]:443", "[3ffe::1232]:443", @@ -695,14 +692,14 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) { bool ipv4_supported = true; bool ipv6_supported = true; OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {}); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::1231]:443", AF_INET6}, {"[3ffe::1232]:443", AF_INET6}, {"[3ffe::1233]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1231]:443", "[3ffe::1232]:443", @@ -716,11 +713,11 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) { bool ipv4_supported = true; bool ipv6_supported = true; OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {}); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[::ffff:5.6.7.8]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::ffff:5.6.7.8]:443", "1.2.3.4:443", @@ -744,11 +741,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) { {"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}}, {v4_compat_dest, {v4_compat_src, AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[fec0::2000]:443", AF_INET6}, {v4_compat_dest, AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { // The sort should be stable since @@ -765,11 +762,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) { * (whether ipv4 loopback is available or not, an available ipv6 * loopback should be preferred). */ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) { - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[::1]:443", AF_INET6}, {"127.0.0.1:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", "127.0.0.1:443", @@ -779,11 +776,11 @@ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) { /* Flip the order of the inputs above and expect the same output order * (try to rule out influence of arbitrary qsort ordering) */ TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) { - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"127.0.0.1:443", AF_INET}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", "127.0.0.1:443", diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index fe6fcb8d9cb..2ac2c237cea 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -41,6 +41,7 @@ #include "src/core/ext/filters/client_channel/resolver.h" #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/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" @@ -382,23 +383,19 @@ 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; - const grpc_arg* channel_arg = - grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES); - GPR_ASSERT(channel_arg != nullptr); - GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER); - grpc_lb_addresses* addresses = - (grpc_lb_addresses*)channel_arg->value.pointer.p; + grpc_core::ServerAddressList* addresses = + grpc_core::FindServerAddressListChannelArg(channel_args); gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR, - addresses->num_addresses, args->expected_addrs.size()); - GPR_ASSERT(addresses->num_addresses == args->expected_addrs.size()); + 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->num_addresses; i++) { - grpc_lb_address addr = addresses->addresses[i]; + 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 */); + 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.is_balancer)); + GrpcLBAddress(std::string(str), addr.IsBalancer())); gpr_free(str); } if (args->expected_addrs.size() != found_lb_addrs.size()) { diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index dd5bead58ca..5011e19b03a 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -923,7 +923,6 @@ 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.cc \ 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 \ @@ -959,6 +958,8 @@ 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/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_index.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 0a7a4daf7de..2451101f58d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10074,6 +10074,7 @@ "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/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" ], @@ -10101,7 +10102,6 @@ "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_factory.cc", "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", @@ -10120,6 +10120,8 @@ "src/core/ext/filters/client_channel/resolver_result_parsing.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_index.cc", From 07fc27c20d694021669f2d77449da0666b6b1626 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 11 Dec 2018 08:08:34 -0800 Subject: [PATCH 0508/2143] Update channelz proto --- src/proto/grpc/channelz/channelz.proto | 38 ++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/proto/grpc/channelz/channelz.proto b/src/proto/grpc/channelz/channelz.proto index 6202e5e817d..9d73f375541 100644 --- a/src/proto/grpc/channelz/channelz.proto +++ b/src/proto/grpc/channelz/channelz.proto @@ -177,6 +177,7 @@ message SubchannelRef { // SocketRef is a reference to a Socket. message SocketRef { + // The globally unique id for this socket. Must be a positive number. int64 socket_id = 3; // An optional name associated with the socket. string name = 4; @@ -288,7 +289,8 @@ message SocketData { // include stream level or TCP level flow control info. google.protobuf.Int64Value remote_flow_control_window = 12; - // Socket options set on this socket. May be absent. + // Socket options set on this socket. May be absent if 'summary' is set + // on GetSocketRequest. repeated SocketOption option = 13; } @@ -439,12 +441,21 @@ service Channelz { message GetTopChannelsRequest { // start_channel_id indicates that only channels at or above this id should be // included in the results. + // To request the first page, this should be set to 0. To request + // subsequent pages, the client generates this value by adding 1 to + // the highest seen result ID. int64 start_channel_id = 1; + + // If non-zero, the server will return a page of results containing + // at most this many items. If zero, the server will choose a + // reasonable page size. Must never be negative. + int64 max_results = 2; } message GetTopChannelsResponse { // list of channels that the connection detail service knows about. Sorted in // ascending channel_id order. + // Must contain at least 1 result, otherwise 'end' must be true. repeated Channel channel = 1; // If set, indicates that the list of channels is the final list. Requesting // more channels can only return more if they are created after this RPC @@ -455,12 +466,21 @@ message GetTopChannelsResponse { message GetServersRequest { // start_server_id indicates that only servers at or above this id should be // included in the results. + // To request the first page, this must be set to 0. To request + // subsequent pages, the client generates this value by adding 1 to + // the highest seen result ID. int64 start_server_id = 1; + + // If non-zero, the server will return a page of results containing + // at most this many items. If zero, the server will choose a + // reasonable page size. Must never be negative. + int64 max_results = 2; } message GetServersResponse { // list of servers that the connection detail service knows about. Sorted in // ascending server_id order. + // Must contain at least 1 result, otherwise 'end' must be true. repeated Server server = 1; // If set, indicates that the list of servers is the final list. Requesting // more servers will only return more if they are created after this RPC @@ -483,12 +503,21 @@ message GetServerSocketsRequest { int64 server_id = 1; // start_socket_id indicates that only sockets at or above this id should be // included in the results. + // To request the first page, this must be set to 0. To request + // subsequent pages, the client generates this value by adding 1 to + // the highest seen result ID. int64 start_socket_id = 2; + + // If non-zero, the server will return a page of results containing + // at most this many items. If zero, the server will choose a + // reasonable page size. Must never be negative. + int64 max_results = 3; } message GetServerSocketsResponse { // list of socket refs that the connection detail service knows about. Sorted in // ascending socket_id order. + // Must contain at least 1 result, otherwise 'end' must be true. repeated SocketRef socket_ref = 1; // If set, indicates that the list of sockets is the final list. Requesting // more sockets will only return more if they are created after this RPC @@ -521,10 +550,15 @@ message GetSubchannelResponse { message GetSocketRequest { // socket_id is the identifier of the specific socket to get. int64 socket_id = 1; + + // If true, the response will contain only high level information + // that is inexpensive to obtain. Fields thay may be omitted are + // documented. + bool summary = 2; } message GetSocketResponse { // The Socket that corresponds to the requested socket_id. This field // should be set. Socket socket = 1; -} +} \ No newline at end of file From 7b1fc0faa23b2cc1807450498b8c69afb079c2d2 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 11 Dec 2018 08:22:51 -0800 Subject: [PATCH 0509/2143] Add max_results to ServerSockets --- include/grpc/grpc.h | 3 ++- src/core/lib/channel/channelz.cc | 10 ++++++---- src/core/lib/channel/channelz.h | 3 ++- src/core/lib/channel/channelz_registry.cc | 5 +++-- .../grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi | 8 +++++--- src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi | 3 ++- .../grpcio_channelz/grpc_channelz/v1/channelz.py | 3 ++- src/ruby/ext/grpc/rb_grpc_imports.generated.h | 2 +- test/core/end2end/tests/channelz.cc | 2 +- 9 files changed, 24 insertions(+), 15 deletions(-) diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index d3b74cabab5..fec7f5269e1 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -511,7 +511,8 @@ GRPCAPI char* grpc_channelz_get_server(intptr_t server_id); /* Gets all server sockets that exist in the server. */ GRPCAPI char* grpc_channelz_get_server_sockets(intptr_t server_id, - intptr_t start_socket_id); + intptr_t start_socket_id, + intptr_t max_results); /* Returns a single Channel, or else a NOT_FOUND code. The returned string is allocated and must be freed by the application. */ diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 8d449ee6721..3fcfa2a4125 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -203,8 +203,10 @@ ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes) ServerNode::~ServerNode() {} -char* ServerNode::RenderServerSockets(intptr_t start_socket_id) { - const int kPaginationLimit = 100; +char* ServerNode::RenderServerSockets(intptr_t start_socket_id, + intptr_t max_results) { + // if user does not set max_results, we choose 500. + int pagination_limit = max_results == 0 ? 500 : max_results; grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; @@ -219,8 +221,8 @@ char* ServerNode::RenderServerSockets(intptr_t start_socket_id) { for (size_t i = 0; i < socket_refs.size(); ++i) { // check if we are over pagination limit to determine if we need to set // the "end" element. If we don't go through this block, we know that - // when the loop terminates, we have <= to kPaginationLimit. - if (sockets_added == kPaginationLimit) { + // when the loop terminates, we have <= to pagination_limit. + if (sockets_added == pagination_limit) { reached_pagination_limit = true; break; } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 96a4333083a..e43792126f0 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -210,7 +210,8 @@ class ServerNode : public BaseNode { grpc_json* RenderJson() override; - char* RenderServerSockets(intptr_t start_socket_id); + char* RenderServerSockets(intptr_t start_socket_id, + intptr_t pagination_limit); // proxy methods to composed classes. void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index bc23b90a661..7cca247d64d 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -252,7 +252,8 @@ char* grpc_channelz_get_server(intptr_t server_id) { } char* grpc_channelz_get_server_sockets(intptr_t server_id, - intptr_t start_socket_id) { + intptr_t start_socket_id, + intptr_t max_results) { grpc_core::channelz::BaseNode* base_node = grpc_core::channelz::ChannelzRegistry::Get(server_id); if (base_node == nullptr || @@ -263,7 +264,7 @@ char* grpc_channelz_get_server_sockets(intptr_t server_id, // actually a server node grpc_core::channelz::ServerNode* server_node = static_cast(base_node); - return server_node->RenderServerSockets(start_socket_id); + return server_node->RenderServerSockets(start_socket_id, max_results); } char* grpc_channelz_get_channel(intptr_t channel_id) { diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi index 113f7976dd9..36c8cd121c7 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi @@ -36,15 +36,17 @@ def channelz_get_server(server_id): ' server_id==%s is valid' % server_id) return c_returned_str -def channelz_get_server_sockets(server_id, start_socket_id): +def channelz_get_server_sockets(server_id, start_socket_id, max_results): cdef char *c_returned_str = grpc_channelz_get_server_sockets( server_id, start_socket_id, + max_results, ) if c_returned_str == NULL: raise ValueError('Failed to get server sockets, please ensure your' \ - ' server_id==%s and start_socket_id==%s is valid' % - (server_id, start_socket_id)) + ' server_id==%s and start_socket_id==%s and' \ + ' max_results==%s is valid' % + (server_id, start_socket_id, max_results)) return c_returned_str def channelz_get_channel(channel_id): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 5bbc10af25d..fc7a9ba4395 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -389,7 +389,8 @@ cdef extern from "grpc/grpc.h": char* grpc_channelz_get_servers(intptr_t start_server_id) char* grpc_channelz_get_server(intptr_t server_id) char* grpc_channelz_get_server_sockets(intptr_t server_id, - intptr_t start_socket_id) + intptr_t start_socket_id, + intptr_t max_results) char* grpc_channelz_get_channel(intptr_t channel_id) char* grpc_channelz_get_subchannel(intptr_t subchannel_id) char* grpc_channelz_get_socket(intptr_t socket_id) diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py index 573b9d0d5ac..00eca311dc1 100644 --- a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py +++ b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py @@ -66,7 +66,8 @@ class ChannelzServicer(_channelz_pb2_grpc.ChannelzServicer): try: return json_format.Parse( cygrpc.channelz_get_server_sockets(request.server_id, - request.start_socket_id), + request.start_socket_id, + request.max_results), _channelz_pb2.GetServerSocketsResponse(), ) except ValueError as e: diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 56d222c7ec8..e61a35d09fa 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -272,7 +272,7 @@ extern grpc_channelz_get_servers_type grpc_channelz_get_servers_import; typedef char*(*grpc_channelz_get_server_type)(intptr_t server_id); extern grpc_channelz_get_server_type grpc_channelz_get_server_import; #define grpc_channelz_get_server grpc_channelz_get_server_import -typedef char*(*grpc_channelz_get_server_sockets_type)(intptr_t server_id, intptr_t start_socket_id); +typedef char*(*grpc_channelz_get_server_sockets_type)(intptr_t server_id, intptr_t start_socket_id, intptr_t max_results); extern grpc_channelz_get_server_sockets_type grpc_channelz_get_server_sockets_import; #define grpc_channelz_get_server_sockets grpc_channelz_get_server_sockets_import typedef char*(*grpc_channelz_get_channel_type)(intptr_t channel_id); diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 49a0bc80112..169190eec06 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -259,7 +259,7 @@ static void test_channelz(grpc_end2end_test_config config) { GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); gpr_free(json); - json = channelz_server->RenderServerSockets(0); + json = channelz_server->RenderServerSockets(0, 100); GPR_ASSERT(nullptr != strstr(json, "\"end\":true")); gpr_free(json); From a6ed43b41fec1201c3d239ee2910aac65cba9d90 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 11 Dec 2018 10:27:11 -0800 Subject: [PATCH 0510/2143] reviewer feedback --- src/core/lib/channel/channelz.cc | 20 ++++++-------------- src/proto/grpc/channelz/channelz.proto | 2 +- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 3fcfa2a4125..10d5e1b581c 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -205,28 +205,20 @@ ServerNode::~ServerNode() {} char* ServerNode::RenderServerSockets(intptr_t start_socket_id, intptr_t max_results) { - // if user does not set max_results, we choose 500. - int pagination_limit = max_results == 0 ? 500 : max_results; + // if user does not set max_results, we choose 1000. + size_t pagination_limit = max_results == 0 ? 500 : max_results; grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; ChildSocketsList socket_refs; grpc_server_populate_server_sockets(server_, &socket_refs, start_socket_id); - int sockets_added = 0; - bool reached_pagination_limit = false; + // declared early so it can be used outside of the loop. + size_t i = 0; if (!socket_refs.empty()) { // create list of socket refs grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); - for (size_t i = 0; i < socket_refs.size(); ++i) { - // check if we are over pagination limit to determine if we need to set - // the "end" element. If we don't go through this block, we know that - // when the loop terminates, we have <= to pagination_limit. - if (sockets_added == pagination_limit) { - reached_pagination_limit = true; - break; - } - sockets_added++; + for (i = 0; i < GPR_MIN(socket_refs.size(), pagination_limit); ++i) { grpc_json* socket_ref_json = grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false); @@ -236,7 +228,7 @@ char* ServerNode::RenderServerSockets(intptr_t start_socket_id, socket_refs[i]->remote(), GRPC_JSON_STRING, false); } } - if (!reached_pagination_limit) { + if (i == socket_refs.size()) { json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr, GRPC_JSON_TRUE, false); } diff --git a/src/proto/grpc/channelz/channelz.proto b/src/proto/grpc/channelz/channelz.proto index 9d73f375541..20de23f7fa3 100644 --- a/src/proto/grpc/channelz/channelz.proto +++ b/src/proto/grpc/channelz/channelz.proto @@ -561,4 +561,4 @@ message GetSocketResponse { // The Socket that corresponds to the requested socket_id. This field // should be set. Socket socket = 1; -} \ No newline at end of file +} From c7f7db65e0fdc058b4caa2b76baaa308465fda9e Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 11 Dec 2018 11:28:12 -0800 Subject: [PATCH 0511/2143] Add test and fix bug --- src/core/lib/channel/channelz.cc | 7 +- src/cpp/server/channelz/channelz_service.cc | 4 +- test/cpp/end2end/channelz_service_test.cc | 82 +++++++++++++++++++++ 3 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 10d5e1b581c..8a596ad4605 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -205,7 +205,7 @@ ServerNode::~ServerNode() {} char* ServerNode::RenderServerSockets(intptr_t start_socket_id, intptr_t max_results) { - // if user does not set max_results, we choose 1000. + // if user does not set max_results, we choose 500. size_t pagination_limit = max_results == 0 ? 500 : max_results; grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; @@ -219,9 +219,8 @@ char* ServerNode::RenderServerSockets(intptr_t start_socket_id, grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); for (i = 0; i < GPR_MIN(socket_refs.size(), pagination_limit); ++i) { - grpc_json* socket_ref_json = - grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, - GRPC_JSON_OBJECT, false); + grpc_json* socket_ref_json = grpc_json_create_child( + nullptr, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false); json_iterator = grpc_json_add_number_string_child( socket_ref_json, nullptr, "socketId", socket_refs[i]->uuid()); grpc_json_create_child(json_iterator, socket_ref_json, "name", diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc index 9ecb9de7e4b..c44a9ac0de6 100644 --- a/src/cpp/server/channelz/channelz_service.cc +++ b/src/cpp/server/channelz/channelz_service.cc @@ -79,8 +79,8 @@ Status ChannelzService::GetServer(ServerContext* unused, Status ChannelzService::GetServerSockets( ServerContext* unused, const channelz::v1::GetServerSocketsRequest* request, channelz::v1::GetServerSocketsResponse* response) { - char* json_str = grpc_channelz_get_server_sockets(request->server_id(), - request->start_socket_id()); + char* json_str = grpc_channelz_get_server_sockets( + request->server_id(), request->start_socket_id(), request->max_results()); if (json_str == nullptr) { return Status(StatusCode::INTERNAL, "grpc_channelz_get_server_sockets returned null"); diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index 29b59e4e5e1..425334d972e 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -54,6 +54,14 @@ 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 { @@ -164,6 +172,19 @@ class ChannelzServerTest : public ::testing::Test { echo_stub_ = grpc::testing::EchoTestService::NewStub(channel); } + std::unique_ptr NewEchoStub() { + static int salt = 0; + string target = "dns:localhost:" + to_string(proxy_port_); + ChannelArguments args; + // disable channelz. We only want to focus on proxy to backend outbound. + args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0); + // This ensures that gRPC will not do connection sharing. + args.SetInt("salt", salt++); + std::shared_ptr channel = + CreateCustomChannel(target, InsecureChannelCredentials(), args); + return grpc::testing::EchoTestService::NewStub(channel); + } + void SendSuccessfulEcho(int channel_idx) { EchoRequest request; EchoResponse response; @@ -651,6 +672,67 @@ TEST_F(ChannelzServerTest, GetServerSocketsTest) { EXPECT_EQ(get_server_sockets_response.socket_ref_size(), 1); } +TEST_F(ChannelzServerTest, GetServerSocketsPaginationTest) { + ResetStubs(); + ConfigureProxy(1); + std::vector> stubs; + const int kNumServerSocketsCreated = 20; + for (int i = 0; i < kNumServerSocketsCreated; ++i) { + stubs.push_back(NewEchoStub()); + EchoRequest request; + EchoResponse response; + request.set_message("Hello channelz"); + request.mutable_param()->set_backend_channel_idx(0); + ClientContext context; + Status s = stubs.back()->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + } + GetServersRequest get_server_request; + GetServersResponse get_server_response; + get_server_request.set_start_server_id(0); + ClientContext get_server_context; + Status s = channelz_stub_->GetServers(&get_server_context, get_server_request, + &get_server_response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + EXPECT_EQ(get_server_response.server_size(), 1); + // Make a request that gets all of the serversockets + { + GetServerSocketsRequest get_server_sockets_request; + GetServerSocketsResponse get_server_sockets_response; + get_server_sockets_request.set_server_id( + get_server_response.server(0).ref().server_id()); + get_server_sockets_request.set_start_socket_id(0); + ClientContext get_server_sockets_context; + s = channelz_stub_->GetServerSockets(&get_server_sockets_context, + 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 + // a serversocket. + EXPECT_EQ(get_server_sockets_response.socket_ref_size(), + kNumServerSocketsCreated + 1); + EXPECT_TRUE(get_server_sockets_response.end()); + } + // Now we make a request that exercises pagination. + { + GetServerSocketsRequest get_server_sockets_request; + GetServerSocketsResponse get_server_sockets_response; + get_server_sockets_request.set_server_id( + get_server_response.server(0).ref().server_id()); + get_server_sockets_request.set_start_socket_id(0); + const int kMaxResults = 10; + get_server_sockets_request.set_max_results(kMaxResults); + ClientContext get_server_sockets_context; + s = channelz_stub_->GetServerSockets(&get_server_sockets_context, + get_server_sockets_request, + &get_server_sockets_response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + EXPECT_EQ(get_server_sockets_response.socket_ref_size(), kMaxResults); + EXPECT_FALSE(get_server_sockets_response.end()); + } +} + TEST_F(ChannelzServerTest, GetServerListenSocketsTest) { ResetStubs(); ConfigureProxy(1); From 6b3baf26185847f02c11401c971647624ba3d039 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 11 Dec 2018 10:18:43 -0800 Subject: [PATCH 0512/2143] Add hooks for census context propagation Appease the yapf gods Reformat --- src/python/grpcio/grpc/_cython/BUILD.bazel | 73 ++++++++++--------- .../grpc/_cython/_cygrpc/_hooks.pyx.pxi | 15 ++++ .../grpc/_cython/_cygrpc/channel.pyx.pxi | 27 ++++--- .../_cython/_cygrpc/propagation_bits.pxd.pxi | 20 +++++ .../_cython/_cygrpc/propagation_bits.pyx.pxi | 20 +++++ src/python/grpcio/grpc/_cython/cygrpc.pxd | 1 + src/python/grpcio/grpc/_cython/cygrpc.pyx | 1 + src/python/grpcio/grpc/_server.py | 72 ++++++++++-------- 8 files changed, 152 insertions(+), 77 deletions(-) create mode 100644 src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi create mode 100644 src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi diff --git a/src/python/grpcio/grpc/_cython/BUILD.bazel b/src/python/grpcio/grpc/_cython/BUILD.bazel index e318298d0ab..42db7b87213 100644 --- a/src/python/grpcio/grpc/_cython/BUILD.bazel +++ b/src/python/grpcio/grpc/_cython/BUILD.bazel @@ -6,46 +6,47 @@ pyx_library( name = "cygrpc", srcs = [ "__init__.py", + "_cygrpc/_hooks.pxd.pxi", + "_cygrpc/_hooks.pyx.pxi", + "_cygrpc/arguments.pxd.pxi", + "_cygrpc/arguments.pyx.pxi", + "_cygrpc/call.pxd.pxi", + "_cygrpc/call.pyx.pxi", + "_cygrpc/channel.pxd.pxi", + "_cygrpc/channel.pyx.pxi", + "_cygrpc/channelz.pyx.pxi", + "_cygrpc/completion_queue.pxd.pxi", + "_cygrpc/completion_queue.pyx.pxi", + "_cygrpc/credentials.pxd.pxi", + "_cygrpc/credentials.pyx.pxi", + "_cygrpc/event.pxd.pxi", + "_cygrpc/event.pyx.pxi", + "_cygrpc/fork_posix.pxd.pxi", + "_cygrpc/fork_posix.pyx.pxi", + "_cygrpc/grpc.pxi", + "_cygrpc/grpc_gevent.pxd.pxi", + "_cygrpc/grpc_gevent.pyx.pxi", + "_cygrpc/grpc_string.pyx.pxi", + "_cygrpc/metadata.pxd.pxi", + "_cygrpc/metadata.pyx.pxi", + "_cygrpc/operation.pxd.pxi", + "_cygrpc/operation.pyx.pxi", + "_cygrpc/propagation_bits.pxd.pxi", + "_cygrpc/propagation_bits.pyx.pxi", + "_cygrpc/records.pxd.pxi", + "_cygrpc/records.pyx.pxi", + "_cygrpc/security.pxd.pxi", + "_cygrpc/security.pyx.pxi", + "_cygrpc/server.pxd.pxi", + "_cygrpc/server.pyx.pxi", + "_cygrpc/tag.pxd.pxi", + "_cygrpc/tag.pyx.pxi", + "_cygrpc/time.pxd.pxi", + "_cygrpc/time.pyx.pxi", "cygrpc.pxd", "cygrpc.pyx", - "_cygrpc/_hooks.pyx.pxi", - "_cygrpc/grpc_string.pyx.pxi", - "_cygrpc/arguments.pyx.pxi", - "_cygrpc/call.pyx.pxi", - "_cygrpc/channelz.pyx.pxi", - "_cygrpc/channel.pyx.pxi", - "_cygrpc/credentials.pyx.pxi", - "_cygrpc/completion_queue.pyx.pxi", - "_cygrpc/event.pyx.pxi", - "_cygrpc/fork_posix.pyx.pxi", - "_cygrpc/metadata.pyx.pxi", - "_cygrpc/operation.pyx.pxi", - "_cygrpc/records.pyx.pxi", - "_cygrpc/security.pyx.pxi", - "_cygrpc/server.pyx.pxi", - "_cygrpc/tag.pyx.pxi", - "_cygrpc/time.pyx.pxi", - "_cygrpc/grpc_gevent.pyx.pxi", - "_cygrpc/grpc.pxi", - "_cygrpc/_hooks.pxd.pxi", - "_cygrpc/arguments.pxd.pxi", - "_cygrpc/call.pxd.pxi", - "_cygrpc/channel.pxd.pxi", - "_cygrpc/credentials.pxd.pxi", - "_cygrpc/completion_queue.pxd.pxi", - "_cygrpc/event.pxd.pxi", - "_cygrpc/fork_posix.pxd.pxi", - "_cygrpc/metadata.pxd.pxi", - "_cygrpc/operation.pxd.pxi", - "_cygrpc/records.pxd.pxi", - "_cygrpc/security.pxd.pxi", - "_cygrpc/server.pxd.pxi", - "_cygrpc/tag.pxd.pxi", - "_cygrpc/time.pxd.pxi", - "_cygrpc/grpc_gevent.pxd.pxi", ], deps = [ "//:grpc", ], ) - diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi index 38cf629dc24..cd4a51a635e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi @@ -15,3 +15,18 @@ 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): + pass + +def uninstall_context(): + pass + +def build_context(): + pass + +cdef class CensusContext: + pass + +def set_census_context_on_call(_CallState call_state, CensusContext census_ctx): + pass diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index a81ff4d823b..135d224095e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -159,7 +159,8 @@ cdef void _call( _ChannelState channel_state, _CallState call_state, grpc_completion_queue *c_completion_queue, on_success, int flags, method, host, object deadline, CallCredentials credentials, - object operationses_and_user_tags, object metadata) except *: + object operationses_and_user_tags, object metadata, + object context) except *: """Invokes an RPC. Args: @@ -185,6 +186,7 @@ cdef void _call( which is an object to be used as a tag. A SendInitialMetadataOperation must be present in the first element of this value. metadata: The metadata for this call. + context: Context object for distributed tracing. """ cdef grpc_slice method_slice cdef grpc_slice host_slice @@ -208,6 +210,8 @@ cdef void _call( grpc_slice_unref(method_slice) if host_slice_ptr: grpc_slice_unref(host_slice) + if context is not None: + set_census_context_on_call(call_state, context) if credentials is not None: c_call_credentials = credentials.c() c_call_error = grpc_call_set_credentials( @@ -257,7 +261,8 @@ cdef class IntegratedCall: cdef IntegratedCall _integrated_call( _ChannelState state, int flags, method, host, object deadline, - object metadata, CallCredentials credentials, operationses_and_user_tags): + object metadata, CallCredentials credentials, operationses_and_user_tags, + object context): call_state = _CallState() def on_success(started_tags): @@ -266,7 +271,7 @@ cdef IntegratedCall _integrated_call( _call( state, call_state, state.c_call_completion_queue, on_success, flags, - method, host, deadline, credentials, operationses_and_user_tags, metadata) + method, host, deadline, credentials, operationses_and_user_tags, metadata, context) return IntegratedCall(state, call_state) @@ -308,7 +313,8 @@ cdef class SegregatedCall: cdef SegregatedCall _segregated_call( _ChannelState state, int flags, method, host, object deadline, - object metadata, CallCredentials credentials, operationses_and_user_tags): + object metadata, CallCredentials credentials, operationses_and_user_tags, + object context): cdef _CallState call_state = _CallState() cdef SegregatedCall segregated_call cdef grpc_completion_queue *c_completion_queue @@ -325,7 +331,8 @@ cdef SegregatedCall _segregated_call( try: _call( state, call_state, c_completion_queue, on_success, flags, method, host, - deadline, credentials, operationses_and_user_tags, metadata) + deadline, credentials, operationses_and_user_tags, metadata, + context) except: _destroy_c_completion_queue(c_completion_queue) raise @@ -443,10 +450,11 @@ cdef class Channel: def integrated_call( self, int flags, method, host, object deadline, object metadata, - CallCredentials credentials, operationses_and_tags): + CallCredentials credentials, operationses_and_tags, + object context = None): return _integrated_call( self._state, flags, method, host, deadline, metadata, credentials, - operationses_and_tags) + operationses_and_tags, context) def next_call_event(self): def on_success(tag): @@ -461,10 +469,11 @@ cdef class Channel: def segregated_call( self, int flags, method, host, object deadline, object metadata, - CallCredentials credentials, operationses_and_tags): + CallCredentials credentials, operationses_and_tags, + object context = None): return _segregated_call( self._state, flags, method, host, deadline, metadata, credentials, - operationses_and_tags) + operationses_and_tags, context) def check_connectivity_state(self, bint try_to_connect): with self._state.condition: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi new file mode 100644 index 00000000000..cd6e94c816c --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi @@ -0,0 +1,20 @@ +# 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. + +cdef extern from "grpc/impl/codegen/propagation_bits.h": + cdef int _GRPC_PROPAGATE_DEADLINE "GRPC_PROPAGATE_DEADLINE" + cdef int _GRPC_PROPAGATE_CENSUS_STATS_CONTEXT "GRPC_PROPAGATE_CENSUS_STATS_CONTEXT" + cdef int _GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT "GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT" + cdef int _GRPC_PROPAGATE_CANCELLATION "GRPC_PROPAGATE_CANCELLATION" + cdef int _GRPC_PROPAGATE_DEFAULTS "GRPC_PROPAGATE_DEFAULTS" diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi new file mode 100644 index 00000000000..2dcc76a2db2 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi @@ -0,0 +1,20 @@ +# 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. + +class PropagationConstants: + GRPC_PROPAGATE_DEADLINE = _GRPC_PROPAGATE_DEADLINE + GRPC_PROPAGATE_CENSUS_STATS_CONTEXT = _GRPC_PROPAGATE_CENSUS_STATS_CONTEXT + GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT = _GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT + GRPC_PROPAGATE_CANCELLATION = _GRPC_PROPAGATE_CANCELLATION + GRPC_PROPAGATE_DEFAULTS = _GRPC_PROPAGATE_DEFAULTS diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd index 8258b857bc4..64cae6b34d6 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pxd +++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd @@ -29,6 +29,7 @@ include "_cygrpc/server.pxd.pxi" include "_cygrpc/tag.pxd.pxi" include "_cygrpc/time.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 9ab919375c0..ce98fa3a8e6 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -36,6 +36,7 @@ include "_cygrpc/tag.pyx.pxi" include "_cygrpc/time.pyx.pxi" include "_cygrpc/_hooks.pyx.pxi" include "_cygrpc/channelz.pyx.pxi" +include "_cygrpc/propagation_bits.pyx.pxi" include "_cygrpc/grpc_gevent.pyx.pxi" diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 7276a7fd90e..e939f615dfd 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -480,43 +480,51 @@ def _status(rpc_event, state, serialized_response): def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - argument = argument_thunk() - if argument is not None: - response, proceed = _call_behavior(rpc_event, state, behavior, argument, - request_deserializer) - if proceed: - serialized_response = _serialize_response( - rpc_event, state, response, response_serializer) - if serialized_response is not None: - _status(rpc_event, state, serialized_response) + cygrpc.install_census_context_from_call(rpc_event.call) + try: + argument = argument_thunk() + if argument is not None: + response, proceed = _call_behavior(rpc_event, state, behavior, + argument, request_deserializer) + if proceed: + serialized_response = _serialize_response( + rpc_event, state, response, response_serializer) + if serialized_response is not None: + _status(rpc_event, state, serialized_response) + finally: + cygrpc.uninstall_context() def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - 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: + cygrpc.install_census_context_from_call(rpc_event.call) + 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: - 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 + finally: + cygrpc.uninstall_context() def _handle_unary_unary(rpc_event, state, method_handler, thread_pool): From 3bc323977fb049ac0a10306ec9c964387b204d7c Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Tue, 11 Dec 2018 13:12:39 -0800 Subject: [PATCH 0513/2143] Streaming support for callback server --- test/cpp/qps/server_callback.cc | 46 ++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/test/cpp/qps/server_callback.cc b/test/cpp/qps/server_callback.cc index 8bedd447392..4a346dd0178 100644 --- a/test/cpp/qps/server_callback.cc +++ b/test/cpp/qps/server_callback.cc @@ -34,13 +34,53 @@ class BenchmarkCallbackServiceImpl final : public BenchmarkService::ExperimentalCallbackService { public: void UnaryCall( - ServerContext* context, const SimpleRequest* request, - SimpleResponse* response, - experimental::ServerCallbackRpcController* controller) override { + ServerContext* context, const ::grpc::testing::SimpleRequest* request, + ::grpc::testing::SimpleResponse* response, + ::grpc::experimental::ServerCallbackRpcController* controller) override { auto s = SetResponse(request, response); controller->Finish(s); } + ::grpc::experimental::ServerBidiReactor<::grpc::testing::SimpleRequest, + ::grpc::testing::SimpleResponse>* + StreamingCall() override { + class Reactor + : public ::grpc::experimental::ServerBidiReactor< + ::grpc::testing::SimpleRequest, ::grpc::testing::SimpleResponse> { + public: + Reactor() {} + void OnStarted(ServerContext* context) override { StartRead(&request_); } + + void OnReadDone(bool ok) override { + if (!ok) { + Finish(::grpc::Status::OK); + return; + } + auto s = SetResponse(&request_, &response_); + if (!s.ok()) { + Finish(s); + return; + } + StartWrite(&response_); + } + + void OnWriteDone(bool ok) override { + if (!ok) { + Finish(::grpc::Status::OK); + return; + } + StartRead(&request_); + } + + void OnDone() override { delete (this); } + + private: + SimpleRequest request_; + SimpleResponse response_; + }; + return new Reactor; + } + private: static Status SetResponse(const SimpleRequest* request, SimpleResponse* response) { From 62027b7e14624283f758a7785a0a1347eda0a147 Mon Sep 17 00:00:00 2001 From: Vishal Powar Date: Fri, 30 Nov 2018 14:27:52 -0800 Subject: [PATCH 0514/2143] Changes 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 for protos - generated code for example build - adding changes for non-bazel builds - change sanity tests to ignore the generated files. --- BUILD | 25 + CMakeLists.txt | 53 + Makefile | 38 +- bazel/grpc_build_system.bzl | 1 + bazel/grpc_deps.bzl | 6 +- build.yaml | 2 + grpc.gyp | 19 + .../upb-generated/google/protobuf/any.upb.c | 24 + .../upb-generated/google/protobuf/any.upb.h | 63 + .../google/protobuf/descriptor.upb.c | 549 +++++ .../google/protobuf/descriptor.upb.h | 1879 +++++++++++++++++ .../google/protobuf/duration.upb.c | 24 + .../google/protobuf/duration.upb.h | 65 + .../google/protobuf/struct.upb.c | 88 + .../google/protobuf/struct.upb.h | 226 ++ .../google/protobuf/timestamp.upb.c | 24 + .../google/protobuf/timestamp.upb.h | 65 + .../google/protobuf/wrappers.upb.c | 87 + .../google/protobuf/wrappers.upb.h | 305 +++ src/upb/gen_build_yaml.py | 69 + 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 + .../generated/sources_and_headers.json | 21 + tools/run_tests/sanity/check_port_platform.py | 3 + 26 files changed, 3699 insertions(+), 4 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 9a2c16c6012..0d789ae7c00 100644 --- a/BUILD +++ b/BUILD @@ -2272,4 +2272,29 @@ grpc_cc_library( ], ) +# TODO: Get this into build.yaml once we start using it. +grpc_cc_library( + name = "google_protobuf", + 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 1194d0072e3..a9562960920 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5476,6 +5476,59 @@ 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/refcounted.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 7dfce79c922..e1ae7e7ad61 100644 --- a/Makefile +++ b/Makefile @@ -1411,7 +1411,7 @@ plugins: $(PROTOC_PLUGINS) privatelibs: privatelibs_c privatelibs_cxx -privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.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)/libgpr_test_util.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 @@ -10113,6 +10113,42 @@ 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/refcounted.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 + +$(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 65fe5a10aa2..06b05f79525 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -99,6 +99,7 @@ def grpc_cc_library( linkopts = if_not_windows(["-pthread"]), includes = [ "include", + "src/core/ext/upb-generated", ], alwayslink = alwayslink, data = data, diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 3eacd2b0475..2738e39abf7 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", ) @@ -195,8 +195,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-fb6f7e96895c3a9a8ae2e66516160937e7ac1779", + url = "https://github.com/google/upb/archive/fb6f7e96895c3a9a8ae2e66516160937e7ac1779.tar.gz", ) diff --git a/build.yaml b/build.yaml index 41c63d133a9..fa8d65b7606 100644 --- a/build.yaml +++ b/build.yaml @@ -5890,6 +5890,8 @@ 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 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 2b841354baf..10277110dd8 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -2638,6 +2638,25 @@ '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/refcounted.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..1005a48e909 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/any.upb.c @@ -0,0 +1,24 @@ +/* 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 "google/protobuf/any.upb.h" +#include +#include "upb/msg.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..d29265553f7 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/any.upb.h @@ -0,0 +1,63 @@ +/* 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/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +UPB_BEGIN_EXTERN_C + +struct google_protobuf_Any; +typedef struct google_protobuf_Any google_protobuf_Any; + +/* Enums */ + +/* google.protobuf.Any */ + +extern const upb_msglayout google_protobuf_Any_msginit; +UPB_INLINE google_protobuf_Any* google_protobuf_Any_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_Any_msginit, arena); +} +UPB_INLINE google_protobuf_Any* google_protobuf_Any_parsenew(upb_stringview 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_stringview +google_protobuf_Any_type_url(const google_protobuf_Any* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); +} +UPB_INLINE upb_stringview +google_protobuf_Any_value(const google_protobuf_Any* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} + +UPB_INLINE void google_protobuf_Any_set_type_url(google_protobuf_Any* msg, + upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_protobuf_Any_set_value(google_protobuf_Any* msg, + upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} + +UPB_END_EXTERN_C + +#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..f774873d614 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c @@ -0,0 +1,549 @@ +/* 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 "google/protobuf/descriptor.upb.h" +#include +#include "upb/msg.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(8, 16), 1, 0, 9, 1}, + {2, UPB_SIZE(16, 32), 2, 0, 9, 1}, + {3, UPB_SIZE(40, 80), 0, 0, 9, 3}, + {4, UPB_SIZE(44, 88), 0, 0, 11, 3}, + {5, UPB_SIZE(48, 96), 0, 1, 11, 3}, + {6, UPB_SIZE(52, 104), 0, 4, 11, 3}, + {7, UPB_SIZE(56, 112), 0, 2, 11, 3}, + {8, UPB_SIZE(32, 64), 4, 3, 11, 1}, + {9, UPB_SIZE(36, 72), 5, 5, 11, 1}, + {10, UPB_SIZE(60, 120), 0, 0, 5, 3}, + {11, UPB_SIZE(64, 128), 0, 0, 5, 3}, + {12, UPB_SIZE(24, 48), 3, 0, 9, 1}, +}; + +const upb_msglayout google_protobuf_FileDescriptorProto_msginit = { + &google_protobuf_FileDescriptorProto_submsgs[0], + &google_protobuf_FileDescriptorProto__fields[0], + UPB_SIZE(72, 144), + 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(8, 16), 1, 0, 9, 1}, {2, UPB_SIZE(20, 40), 0, 4, 11, 3}, + {3, UPB_SIZE(24, 48), 0, 0, 11, 3}, {4, UPB_SIZE(28, 56), 0, 3, 11, 3}, + {5, UPB_SIZE(32, 64), 0, 1, 11, 3}, {6, UPB_SIZE(36, 72), 0, 4, 11, 3}, + {7, UPB_SIZE(16, 32), 2, 5, 11, 1}, {8, UPB_SIZE(40, 80), 0, 6, 11, 3}, + {9, UPB_SIZE(44, 88), 0, 2, 11, 3}, {10, UPB_SIZE(48, 96), 0, 0, 9, 3}, +}; + +const upb_msglayout google_protobuf_DescriptorProto_msginit = { + &google_protobuf_DescriptorProto_submsgs[0], + &google_protobuf_DescriptorProto__fields[0], + UPB_SIZE(56, 112), + 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(8, 16), 1, 0, 9, 1}, + {2, UPB_SIZE(16, 32), 2, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = { + &google_protobuf_OneofDescriptorProto_submsgs[0], + &google_protobuf_OneofDescriptorProto__fields[0], + UPB_SIZE(24, 48), + 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(8, 16), 1, 0, 9, 1}, {2, UPB_SIZE(20, 40), 0, 2, 11, 3}, + {3, UPB_SIZE(16, 32), 2, 1, 11, 1}, {4, UPB_SIZE(24, 48), 0, 0, 11, 3}, + {5, UPB_SIZE(28, 56), 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, 16), 2, 0, 9, 1}, + {2, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {3, UPB_SIZE(16, 32), 3, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = { + &google_protobuf_EnumValueDescriptorProto_submsgs[0], + &google_protobuf_EnumValueDescriptorProto__fields[0], + UPB_SIZE(24, 48), + 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(8, 16), 1, 0, 9, 1}, + {2, UPB_SIZE(20, 40), 0, 0, 11, 3}, + {3, UPB_SIZE(16, 32), 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(8, 16), 3, 0, 9, 1}, {2, UPB_SIZE(16, 32), 4, 0, 9, 1}, + {3, UPB_SIZE(24, 48), 5, 0, 9, 1}, {4, UPB_SIZE(32, 64), 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(40, 80), + 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(32, 32), 11, 0, 9, 1}, + {8, UPB_SIZE(40, 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(48, 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(56, 80), 14, 0, 9, 1}, + {37, UPB_SIZE(64, 96), 15, 0, 9, 1}, + {39, UPB_SIZE(72, 112), 16, 0, 9, 1}, + {40, UPB_SIZE(80, 128), 17, 0, 9, 1}, + {41, UPB_SIZE(88, 144), 18, 0, 9, 1}, + {42, UPB_SIZE(24, 24), 10, 0, 8, 1}, + {44, UPB_SIZE(96, 160), 19, 0, 9, 1}, + {45, UPB_SIZE(104, 176), 20, 0, 9, 1}, + {999, UPB_SIZE(112, 192), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_FileOptions_msginit = { + &google_protobuf_FileOptions_submsgs[0], + &google_protobuf_FileOptions__fields[0], + UPB_SIZE(120, 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(8, 16), 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(24, 48), 0, 0, 5, 3}, {2, UPB_SIZE(28, 56), 0, 0, 5, 3}, + {3, UPB_SIZE(8, 16), 1, 0, 9, 1}, {4, UPB_SIZE(16, 32), 2, 0, 9, 1}, + {6, UPB_SIZE(32, 64), 0, 0, 9, 3}, +}; + +const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = { + NULL, + &google_protobuf_SourceCodeInfo_Location__fields[0], + UPB_SIZE(40, 80), + 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(24, 32), 0, 0, 5, 3}, + {2, UPB_SIZE(16, 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(32, 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..37f0139ce32 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h @@ -0,0 +1,1879 @@ +/* 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/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +UPB_BEGIN_EXTERN_C + +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; + +/* 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 */ + +extern const upb_msglayout google_protobuf_FileDescriptorSet_msginit; +UPB_INLINE google_protobuf_FileDescriptorSet* +google_protobuf_FileDescriptorSet_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_FileDescriptorSet_msginit, arena); +} +UPB_INLINE google_protobuf_FileDescriptorSet* +google_protobuf_FileDescriptorSet_parsenew(upb_stringview 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 upb_array* google_protobuf_FileDescriptorSet_file( + const google_protobuf_FileDescriptorSet* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_FileDescriptorSet_set_file( + google_protobuf_FileDescriptorSet* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.FileDescriptorProto */ + +extern const upb_msglayout google_protobuf_FileDescriptorProto_msginit; +UPB_INLINE google_protobuf_FileDescriptorProto* +google_protobuf_FileDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_FileDescriptorProto* +google_protobuf_FileDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_FileDescriptorProto_name( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_package( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); +} +UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_dependency( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(40, 80)); +} +UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_message_type( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(44, 88)); +} +UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_enum_type( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(48, 96)); +} +UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_service( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(52, 104)); +} +UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_extension( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(56, 112)); +} +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(32, 64)); +} +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(36, 72)); +} +UPB_INLINE const upb_array* +google_protobuf_FileDescriptorProto_public_dependency( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(60, 120)); +} +UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_weak_dependency( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(64, 128)); +} +UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_syntax( + const google_protobuf_FileDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)); +} + +UPB_INLINE void google_protobuf_FileDescriptorProto_set_name( + google_protobuf_FileDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_package( + google_protobuf_FileDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_dependency( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(40, 80)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_message_type( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(44, 88)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_enum_type( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(48, 96)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_service( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(52, 104)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_extension( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(56, 112)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_options( + google_protobuf_FileDescriptorProto* msg, + google_protobuf_FileOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_FileOptions*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info( + google_protobuf_FileDescriptorProto* msg, + google_protobuf_SourceCodeInfo* value) { + UPB_FIELD_AT(msg, google_protobuf_SourceCodeInfo*, UPB_SIZE(36, 72)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_public_dependency( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(60, 120)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_weak_dependency( + google_protobuf_FileDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(64, 128)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax( + google_protobuf_FileDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)) = value; +} + +/* google.protobuf.DescriptorProto */ + +extern const upb_msglayout google_protobuf_DescriptorProto_msginit; +UPB_INLINE google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_DescriptorProto* +google_protobuf_DescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_DescriptorProto_name( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_field( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_nested_type( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_enum_type( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_extension_range( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(32, 64)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_extension( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(36, 72)); +} +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(16, 32)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_oneof_decl( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(40, 80)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_reserved_range( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(44, 88)); +} +UPB_INLINE const upb_array* google_protobuf_DescriptorProto_reserved_name( + const google_protobuf_DescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(48, 96)); +} + +UPB_INLINE void google_protobuf_DescriptorProto_set_name( + google_protobuf_DescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_field( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_nested_type( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_enum_type( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_extension_range( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_extension( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(36, 72)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_options( + google_protobuf_DescriptorProto* msg, + google_protobuf_MessageOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_MessageOptions*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_oneof_decl( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(40, 80)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_reserved_range( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(44, 88)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_reserved_name( + google_protobuf_DescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(48, 96)) = value; +} + +/* google.protobuf.DescriptorProto.ExtensionRange */ + +extern const upb_msglayout + google_protobuf_DescriptorProto_ExtensionRange_msginit; +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* +google_protobuf_DescriptorProto_ExtensionRange_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, + arena); +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* +google_protobuf_DescriptorProto_ExtensionRange_parsenew(upb_stringview 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 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 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 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_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_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_FIELD_AT(msg, google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)) = + value; +} + +/* google.protobuf.DescriptorProto.ReservedRange */ + +extern const upb_msglayout + google_protobuf_DescriptorProto_ReservedRange_msginit; +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* +google_protobuf_DescriptorProto_ReservedRange_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, + arena); +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* +google_protobuf_DescriptorProto_ReservedRange_parsenew(upb_stringview 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 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 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_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_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + +/* google.protobuf.ExtensionRangeOptions */ + +extern const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit; +UPB_INLINE google_protobuf_ExtensionRangeOptions* +google_protobuf_ExtensionRangeOptions_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena); +} +UPB_INLINE google_protobuf_ExtensionRangeOptions* +google_protobuf_ExtensionRangeOptions_parsenew(upb_stringview 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 upb_array* +google_protobuf_ExtensionRangeOptions_uninterpreted_option( + const google_protobuf_ExtensionRangeOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_ExtensionRangeOptions_set_uninterpreted_option( + google_protobuf_ExtensionRangeOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.FieldDescriptorProto */ + +extern const upb_msglayout google_protobuf_FieldDescriptorProto_msginit; +UPB_INLINE google_protobuf_FieldDescriptorProto* +google_protobuf_FieldDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_FieldDescriptorProto* +google_protobuf_FieldDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_FieldDescriptorProto_name( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); +} +UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_extendee( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); +} +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 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 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 upb_stringview google_protobuf_FieldDescriptorProto_type_name( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); +} +UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_default_value( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)); +} +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 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 upb_stringview google_protobuf_FieldDescriptorProto_json_name( + const google_protobuf_FieldDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)); +} + +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name( + google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee( + google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number( + google_protobuf_FieldDescriptorProto* msg, int32_t value) { + 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_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_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_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value( + google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options( + google_protobuf_FieldDescriptorProto* msg, + google_protobuf_FieldOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_FieldOptions*, UPB_SIZE(72, 112)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index( + google_protobuf_FieldDescriptorProto* msg, int32_t value) { + 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_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)) = value; +} + +/* google.protobuf.OneofDescriptorProto */ + +extern const upb_msglayout google_protobuf_OneofDescriptorProto_msginit; +UPB_INLINE google_protobuf_OneofDescriptorProto* +google_protobuf_OneofDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_OneofDescriptorProto* +google_protobuf_OneofDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_OneofDescriptorProto_name( + const google_protobuf_OneofDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +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(16, 32)); +} + +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name( + google_protobuf_OneofDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_options( + google_protobuf_OneofDescriptorProto* msg, + google_protobuf_OneofOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_OneofOptions*, UPB_SIZE(16, 32)) = value; +} + +/* google.protobuf.EnumDescriptorProto */ + +extern const upb_msglayout google_protobuf_EnumDescriptorProto_msginit; +UPB_INLINE google_protobuf_EnumDescriptorProto* +google_protobuf_EnumDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_EnumDescriptorProto* +google_protobuf_EnumDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_EnumDescriptorProto_name( + const google_protobuf_EnumDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_value( + const google_protobuf_EnumDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); +} +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(16, 32)); +} +UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_reserved_range( + const google_protobuf_EnumDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); +} +UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_reserved_name( + const google_protobuf_EnumDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); +} + +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_name( + google_protobuf_EnumDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_value( + google_protobuf_EnumDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options( + google_protobuf_EnumDescriptorProto* msg, + google_protobuf_EnumOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_EnumOptions*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_reserved_range( + google_protobuf_EnumDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_reserved_name( + google_protobuf_EnumDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; +} + +/* google.protobuf.EnumDescriptorProto.EnumReservedRange */ + +extern const upb_msglayout + google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit; +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* +google_protobuf_EnumDescriptorProto_EnumReservedRange_new(upb_arena* arena) { + return upb_msg_new( + &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena); +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* +google_protobuf_EnumDescriptorProto_EnumReservedRange_parsenew( + upb_stringview 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 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 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_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_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + +/* google.protobuf.EnumValueDescriptorProto */ + +extern const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit; +UPB_INLINE google_protobuf_EnumValueDescriptorProto* +google_protobuf_EnumValueDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto* +google_protobuf_EnumValueDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_EnumValueDescriptorProto_name( + const google_protobuf_EnumValueDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +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 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, 32)); +} + +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name( + google_protobuf_EnumValueDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number( + google_protobuf_EnumValueDescriptorProto* msg, int32_t value) { + 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_FIELD_AT(msg, google_protobuf_EnumValueOptions*, UPB_SIZE(16, 32)) = + value; +} + +/* google.protobuf.ServiceDescriptorProto */ + +extern const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit; +UPB_INLINE google_protobuf_ServiceDescriptorProto* +google_protobuf_ServiceDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_ServiceDescriptorProto* +google_protobuf_ServiceDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_ServiceDescriptorProto_name( + const google_protobuf_ServiceDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE const upb_array* google_protobuf_ServiceDescriptorProto_method( + const google_protobuf_ServiceDescriptorProto* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); +} +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(16, 32)); +} + +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name( + google_protobuf_ServiceDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_method( + google_protobuf_ServiceDescriptorProto* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options( + google_protobuf_ServiceDescriptorProto* msg, + google_protobuf_ServiceOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_ServiceOptions*, UPB_SIZE(16, 32)) = value; +} + +/* google.protobuf.MethodDescriptorProto */ + +extern const upb_msglayout google_protobuf_MethodDescriptorProto_msginit; +UPB_INLINE google_protobuf_MethodDescriptorProto* +google_protobuf_MethodDescriptorProto_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_MethodDescriptorProto* +google_protobuf_MethodDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_MethodDescriptorProto_name( + const google_protobuf_MethodDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_input_type( + const google_protobuf_MethodDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); +} +UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_output_type( + const google_protobuf_MethodDescriptorProto* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)); +} +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(32, 64)); +} +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_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_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type( + google_protobuf_MethodDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type( + google_protobuf_MethodDescriptorProto* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options( + google_protobuf_MethodDescriptorProto* msg, + google_protobuf_MethodOptions* value) { + UPB_FIELD_AT(msg, google_protobuf_MethodOptions*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming( + google_protobuf_MethodDescriptorProto* msg, bool value) { + 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_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} + +/* google.protobuf.FileOptions */ + +extern const upb_msglayout google_protobuf_FileOptions_msginit; +UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_FileOptions_msginit, arena); +} +UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_parsenew( + upb_stringview 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 upb_stringview google_protobuf_FileOptions_java_package( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_java_outer_classname( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); +} +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_java_multiple_files( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); +} +UPB_INLINE upb_stringview +google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); +} +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_java_generic_services( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)); +} +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_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_deprecated( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)); +} +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_cc_enable_arenas( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_objc_class_prefix( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_csharp_namespace( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_swift_prefix( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(72, 112)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_php_class_prefix( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(80, 128)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_php_namespace( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(88, 144)); +} +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 upb_stringview google_protobuf_FileOptions_php_metadata_namespace( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(96, 160)); +} +UPB_INLINE upb_stringview google_protobuf_FileOptions_ruby_package( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(104, 176)); +} +UPB_INLINE const upb_array* google_protobuf_FileOptions_uninterpreted_option( + const google_protobuf_FileOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(112, 192)); +} + +UPB_INLINE void google_protobuf_FileOptions_set_java_package( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_optimize_for( + google_protobuf_FileOptions* msg, + google_protobuf_FileOptions_OptimizeMode value) { + 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_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_go_package( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services( + google_protobuf_FileOptions* msg, bool value) { + 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_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_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_FIELD_AT(msg, bool, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_deprecated( + google_protobuf_FileOptions* msg, bool value) { + 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_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_FIELD_AT(msg, bool, UPB_SIZE(23, 23)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(72, 112)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(80, 128)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_namespace( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(88, 144)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services( + google_protobuf_FileOptions* msg, bool value) { + 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_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(96, 160)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_ruby_package( + google_protobuf_FileOptions* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(104, 176)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_uninterpreted_option( + google_protobuf_FileOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(112, 192)) = value; +} + +/* google.protobuf.MessageOptions */ + +extern const upb_msglayout google_protobuf_MessageOptions_msginit; +UPB_INLINE google_protobuf_MessageOptions* google_protobuf_MessageOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_MessageOptions_msginit, arena); +} +UPB_INLINE google_protobuf_MessageOptions* +google_protobuf_MessageOptions_parsenew(upb_stringview 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_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_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_deprecated( + const google_protobuf_MessageOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)); +} +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 upb_array* google_protobuf_MessageOptions_uninterpreted_option( + const google_protobuf_MessageOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(8, 8)); +} + +UPB_INLINE void google_protobuf_MessageOptions_set_message_set_wire_format( + google_protobuf_MessageOptions* msg, bool value) { + 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_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_deprecated( + google_protobuf_MessageOptions* msg, bool value) { + 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_FIELD_AT(msg, bool, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_uninterpreted_option( + google_protobuf_MessageOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(8, 8)) = value; +} + +/* google.protobuf.FieldOptions */ + +extern const upb_msglayout google_protobuf_FieldOptions_msginit; +UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_FieldOptions_msginit, arena); +} +UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_parsenew( + upb_stringview 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 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_packed( + const google_protobuf_FieldOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); +} +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_lazy( + const google_protobuf_FieldOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)); +} +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_weak( + const google_protobuf_FieldOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)); +} +UPB_INLINE const upb_array* google_protobuf_FieldOptions_uninterpreted_option( + const google_protobuf_FieldOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 32)); +} + +UPB_INLINE void google_protobuf_FieldOptions_set_ctype( + google_protobuf_FieldOptions* msg, + google_protobuf_FieldOptions_CType value) { + 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_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_deprecated( + google_protobuf_FieldOptions* msg, bool value) { + 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_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_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_FIELD_AT(msg, bool, UPB_SIZE(27, 27)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_uninterpreted_option( + google_protobuf_FieldOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 32)) = value; +} + +/* google.protobuf.OneofOptions */ + +extern const upb_msglayout google_protobuf_OneofOptions_msginit; +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); +} +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_parsenew( + upb_stringview 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 upb_array* google_protobuf_OneofOptions_uninterpreted_option( + const google_protobuf_OneofOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_OneofOptions_set_uninterpreted_option( + google_protobuf_OneofOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.EnumOptions */ + +extern const upb_msglayout google_protobuf_EnumOptions_msginit; +UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_EnumOptions_msginit, arena); +} +UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_parsenew( + upb_stringview 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_allow_alias( + const google_protobuf_EnumOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); +} +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 upb_array* google_protobuf_EnumOptions_uninterpreted_option( + const google_protobuf_EnumOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); +} + +UPB_INLINE void google_protobuf_EnumOptions_set_allow_alias( + google_protobuf_EnumOptions* msg, bool value) { + 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_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} +UPB_INLINE void google_protobuf_EnumOptions_set_uninterpreted_option( + google_protobuf_EnumOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; +} + +/* google.protobuf.EnumValueOptions */ + +extern const upb_msglayout google_protobuf_EnumValueOptions_msginit; +UPB_INLINE google_protobuf_EnumValueOptions* +google_protobuf_EnumValueOptions_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena); +} +UPB_INLINE google_protobuf_EnumValueOptions* +google_protobuf_EnumValueOptions_parsenew(upb_stringview 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_deprecated( + const google_protobuf_EnumValueOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); +} +UPB_INLINE const upb_array* +google_protobuf_EnumValueOptions_uninterpreted_option( + const google_protobuf_EnumValueOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); +} + +UPB_INLINE void google_protobuf_EnumValueOptions_set_deprecated( + google_protobuf_EnumValueOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void google_protobuf_EnumValueOptions_set_uninterpreted_option( + google_protobuf_EnumValueOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; +} + +/* google.protobuf.ServiceOptions */ + +extern const upb_msglayout google_protobuf_ServiceOptions_msginit; +UPB_INLINE google_protobuf_ServiceOptions* google_protobuf_ServiceOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena); +} +UPB_INLINE google_protobuf_ServiceOptions* +google_protobuf_ServiceOptions_parsenew(upb_stringview 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_deprecated( + const google_protobuf_ServiceOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); +} +UPB_INLINE const upb_array* google_protobuf_ServiceOptions_uninterpreted_option( + const google_protobuf_ServiceOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); +} + +UPB_INLINE void google_protobuf_ServiceOptions_set_deprecated( + google_protobuf_ServiceOptions* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void google_protobuf_ServiceOptions_set_uninterpreted_option( + google_protobuf_ServiceOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; +} + +/* google.protobuf.MethodOptions */ + +extern const upb_msglayout google_protobuf_MethodOptions_msginit; +UPB_INLINE google_protobuf_MethodOptions* google_protobuf_MethodOptions_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_MethodOptions_msginit, arena); +} +UPB_INLINE google_protobuf_MethodOptions* +google_protobuf_MethodOptions_parsenew(upb_stringview 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_deprecated( + const google_protobuf_MethodOptions* msg) { + return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); +} +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 upb_array* google_protobuf_MethodOptions_uninterpreted_option( + const google_protobuf_MethodOptions* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 24)); +} + +UPB_INLINE void google_protobuf_MethodOptions_set_deprecated( + google_protobuf_MethodOptions* msg, bool value) { + 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_FIELD_AT(msg, google_protobuf_MethodOptions_IdempotencyLevel, + UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_MethodOptions_set_uninterpreted_option( + google_protobuf_MethodOptions* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 24)) = value; +} + +/* google.protobuf.UninterpretedOption */ + +extern const upb_msglayout google_protobuf_UninterpretedOption_msginit; +UPB_INLINE google_protobuf_UninterpretedOption* +google_protobuf_UninterpretedOption_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); +} +UPB_INLINE google_protobuf_UninterpretedOption* +google_protobuf_UninterpretedOption_parsenew(upb_stringview 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 upb_array* google_protobuf_UninterpretedOption_name( + const google_protobuf_UninterpretedOption* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(56, 80)); +} +UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_identifier_value( + const google_protobuf_UninterpretedOption* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); +} +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 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 double google_protobuf_UninterpretedOption_double_value( + const google_protobuf_UninterpretedOption* msg) { + return UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)); +} +UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_string_value( + const google_protobuf_UninterpretedOption* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); +} +UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_aggregate_value( + const google_protobuf_UninterpretedOption* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); +} + +UPB_INLINE void google_protobuf_UninterpretedOption_set_name( + google_protobuf_UninterpretedOption* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(56, 80)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value( + google_protobuf_UninterpretedOption* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value( + google_protobuf_UninterpretedOption* msg, uint64_t value) { + 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_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_FIELD_AT(msg, double, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value( + google_protobuf_UninterpretedOption* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value( + google_protobuf_UninterpretedOption* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; +} + +/* google.protobuf.UninterpretedOption.NamePart */ + +extern const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit; +UPB_INLINE google_protobuf_UninterpretedOption_NamePart* +google_protobuf_UninterpretedOption_NamePart_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, + arena); +} +UPB_INLINE google_protobuf_UninterpretedOption_NamePart* +google_protobuf_UninterpretedOption_NamePart_parsenew(upb_stringview 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 upb_stringview +google_protobuf_UninterpretedOption_NamePart_name_part( + const google_protobuf_UninterpretedOption_NamePart* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +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_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension( + google_protobuf_UninterpretedOption_NamePart* msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} + +/* google.protobuf.SourceCodeInfo */ + +extern const upb_msglayout google_protobuf_SourceCodeInfo_msginit; +UPB_INLINE google_protobuf_SourceCodeInfo* google_protobuf_SourceCodeInfo_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena); +} +UPB_INLINE google_protobuf_SourceCodeInfo* +google_protobuf_SourceCodeInfo_parsenew(upb_stringview 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 upb_array* google_protobuf_SourceCodeInfo_location( + const google_protobuf_SourceCodeInfo* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_SourceCodeInfo_set_location( + google_protobuf_SourceCodeInfo* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.SourceCodeInfo.Location */ + +extern const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit; +UPB_INLINE google_protobuf_SourceCodeInfo_Location* +google_protobuf_SourceCodeInfo_Location_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena); +} +UPB_INLINE google_protobuf_SourceCodeInfo_Location* +google_protobuf_SourceCodeInfo_Location_parsenew(upb_stringview 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 const upb_array* google_protobuf_SourceCodeInfo_Location_path( + const google_protobuf_SourceCodeInfo_Location* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); +} +UPB_INLINE const upb_array* google_protobuf_SourceCodeInfo_Location_span( + const google_protobuf_SourceCodeInfo_Location* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); +} +UPB_INLINE upb_stringview +google_protobuf_SourceCodeInfo_Location_leading_comments( + const google_protobuf_SourceCodeInfo_Location* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); +} +UPB_INLINE upb_stringview +google_protobuf_SourceCodeInfo_Location_trailing_comments( + const google_protobuf_SourceCodeInfo_Location* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); +} +UPB_INLINE const upb_array* +google_protobuf_SourceCodeInfo_Location_leading_detached_comments( + const google_protobuf_SourceCodeInfo_Location* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(32, 64)); +} + +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_path( + google_protobuf_SourceCodeInfo_Location* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_span( + google_protobuf_SourceCodeInfo_Location* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments( + google_protobuf_SourceCodeInfo_Location* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments( + google_protobuf_SourceCodeInfo_Location* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void +google_protobuf_SourceCodeInfo_Location_set_leading_detached_comments( + google_protobuf_SourceCodeInfo_Location* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(32, 64)) = value; +} + +/* google.protobuf.GeneratedCodeInfo */ + +extern const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit; +UPB_INLINE google_protobuf_GeneratedCodeInfo* +google_protobuf_GeneratedCodeInfo_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_GeneratedCodeInfo_msginit, arena); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo* +google_protobuf_GeneratedCodeInfo_parsenew(upb_stringview 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 upb_array* google_protobuf_GeneratedCodeInfo_annotation( + const google_protobuf_GeneratedCodeInfo* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_GeneratedCodeInfo_set_annotation( + google_protobuf_GeneratedCodeInfo* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.GeneratedCodeInfo.Annotation */ + +extern const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit; +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* +google_protobuf_GeneratedCodeInfo_Annotation_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, + arena); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* +google_protobuf_GeneratedCodeInfo_Annotation_parsenew(upb_stringview 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 const upb_array* google_protobuf_GeneratedCodeInfo_Annotation_path( + const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 32)); +} +UPB_INLINE upb_stringview +google_protobuf_GeneratedCodeInfo_Annotation_source_file( + const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 16)); +} +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 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 void google_protobuf_GeneratedCodeInfo_Annotation_set_path( + google_protobuf_GeneratedCodeInfo_Annotation* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 32)) = value; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file( + google_protobuf_GeneratedCodeInfo_Annotation* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin( + google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t value) { + 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_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + +UPB_END_EXTERN_C + +#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..b057ce5e4aa --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/duration.upb.c @@ -0,0 +1,24 @@ +/* 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 "google/protobuf/duration.upb.h" +#include +#include "upb/msg.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..1f40b3aed24 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/duration.upb.h @@ -0,0 +1,65 @@ +/* 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/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +UPB_BEGIN_EXTERN_C + +struct google_protobuf_Duration; +typedef struct google_protobuf_Duration google_protobuf_Duration; + +/* Enums */ + +/* google.protobuf.Duration */ + +extern const upb_msglayout google_protobuf_Duration_msginit; +UPB_INLINE google_protobuf_Duration* google_protobuf_Duration_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_Duration_msginit, arena); +} +UPB_INLINE google_protobuf_Duration* google_protobuf_Duration_parsenew( + upb_stringview 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; +} + +UPB_END_EXTERN_C + +#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..a0820e722a6 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/struct.upb.c @@ -0,0 +1,88 @@ +/* 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 "google/protobuf/struct.upb.h" +#include +#include "upb/msg.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..5493794f0e6 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/struct.upb.h @@ -0,0 +1,226 @@ +/* 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/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +UPB_BEGIN_EXTERN_C + +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; + +/* Enums */ + +typedef enum { google_protobuf_NULL_VALUE = 0 } google_protobuf_NullValue; + +/* google.protobuf.Struct */ + +extern const upb_msglayout google_protobuf_Struct_msginit; +UPB_INLINE google_protobuf_Struct* google_protobuf_Struct_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_Struct_msginit, arena); +} +UPB_INLINE google_protobuf_Struct* google_protobuf_Struct_parsenew( + upb_stringview 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 upb_array* google_protobuf_Struct_fields( + const google_protobuf_Struct* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_Struct_set_fields(google_protobuf_Struct* msg, + upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.Struct.FieldsEntry */ + +extern const upb_msglayout google_protobuf_Struct_FieldsEntry_msginit; +UPB_INLINE google_protobuf_Struct_FieldsEntry* +google_protobuf_Struct_FieldsEntry_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_Struct_FieldsEntry_msginit, arena); +} +UPB_INLINE google_protobuf_Struct_FieldsEntry* +google_protobuf_Struct_FieldsEntry_parsenew(upb_stringview 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_stringview google_protobuf_Struct_FieldsEntry_key( + const google_protobuf_Struct_FieldsEntry* msg) { + return UPB_FIELD_AT(msg, upb_stringview, 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_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, 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; +} + +/* google.protobuf.Value */ + +extern const upb_msglayout google_protobuf_Value_msginit; +UPB_INLINE google_protobuf_Value* google_protobuf_Value_new(upb_arena* arena) { + return upb_msg_new(&google_protobuf_Value_msginit, arena); +} +UPB_INLINE google_protobuf_Value* google_protobuf_Value_parsenew( + upb_stringview 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 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 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 upb_stringview +google_protobuf_Value_string_value(const google_protobuf_Value* msg) { + return UPB_READ_ONEOF(msg, upb_stringview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, + upb_stringview_make("", strlen(""))); +} +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 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 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_stringview value) { + UPB_WRITE_ONEOF(msg, upb_stringview, 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 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); +} + +/* google.protobuf.ListValue */ + +extern const upb_msglayout google_protobuf_ListValue_msginit; +UPB_INLINE google_protobuf_ListValue* google_protobuf_ListValue_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_ListValue_msginit, arena); +} +UPB_INLINE google_protobuf_ListValue* google_protobuf_ListValue_parsenew( + upb_stringview 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 upb_array* google_protobuf_ListValue_values( + const google_protobuf_ListValue* msg) { + return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_ListValue_set_values( + google_protobuf_ListValue* msg, upb_array* value) { + UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; +} + +UPB_END_EXTERN_C + +#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..90d0aed7664 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c @@ -0,0 +1,24 @@ +/* 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 "google/protobuf/timestamp.upb.h" +#include +#include "upb/msg.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..a524eb5b6d0 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h @@ -0,0 +1,65 @@ +/* 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/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +UPB_BEGIN_EXTERN_C + +struct google_protobuf_Timestamp; +typedef struct google_protobuf_Timestamp google_protobuf_Timestamp; + +/* Enums */ + +/* google.protobuf.Timestamp */ + +extern const upb_msglayout google_protobuf_Timestamp_msginit; +UPB_INLINE google_protobuf_Timestamp* google_protobuf_Timestamp_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_Timestamp_msginit, arena); +} +UPB_INLINE google_protobuf_Timestamp* google_protobuf_Timestamp_parsenew( + upb_stringview 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; +} + +UPB_END_EXTERN_C + +#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..3fa3bea1dbc --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c @@ -0,0 +1,87 @@ +/* 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 "google/protobuf/wrappers.upb.h" +#include +#include "upb/msg.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..3ae5d3b16e3 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h @@ -0,0 +1,305 @@ +/* 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/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +UPB_BEGIN_EXTERN_C + +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; + +/* Enums */ + +/* google.protobuf.DoubleValue */ + +extern const upb_msglayout google_protobuf_DoubleValue_msginit; +UPB_INLINE google_protobuf_DoubleValue* google_protobuf_DoubleValue_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_DoubleValue_msginit, arena); +} +UPB_INLINE google_protobuf_DoubleValue* google_protobuf_DoubleValue_parsenew( + upb_stringview 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 */ + +extern const upb_msglayout google_protobuf_FloatValue_msginit; +UPB_INLINE google_protobuf_FloatValue* google_protobuf_FloatValue_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_FloatValue_msginit, arena); +} +UPB_INLINE google_protobuf_FloatValue* google_protobuf_FloatValue_parsenew( + upb_stringview 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 */ + +extern const upb_msglayout google_protobuf_Int64Value_msginit; +UPB_INLINE google_protobuf_Int64Value* google_protobuf_Int64Value_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_Int64Value_msginit, arena); +} +UPB_INLINE google_protobuf_Int64Value* google_protobuf_Int64Value_parsenew( + upb_stringview 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 */ + +extern const upb_msglayout google_protobuf_UInt64Value_msginit; +UPB_INLINE google_protobuf_UInt64Value* google_protobuf_UInt64Value_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_UInt64Value_msginit, arena); +} +UPB_INLINE google_protobuf_UInt64Value* google_protobuf_UInt64Value_parsenew( + upb_stringview 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 */ + +extern const upb_msglayout google_protobuf_Int32Value_msginit; +UPB_INLINE google_protobuf_Int32Value* google_protobuf_Int32Value_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_Int32Value_msginit, arena); +} +UPB_INLINE google_protobuf_Int32Value* google_protobuf_Int32Value_parsenew( + upb_stringview 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 */ + +extern const upb_msglayout google_protobuf_UInt32Value_msginit; +UPB_INLINE google_protobuf_UInt32Value* google_protobuf_UInt32Value_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); +} +UPB_INLINE google_protobuf_UInt32Value* google_protobuf_UInt32Value_parsenew( + upb_stringview 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 */ + +extern const upb_msglayout google_protobuf_BoolValue_msginit; +UPB_INLINE google_protobuf_BoolValue* google_protobuf_BoolValue_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_BoolValue_msginit, arena); +} +UPB_INLINE google_protobuf_BoolValue* google_protobuf_BoolValue_parsenew( + upb_stringview 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 */ + +extern const upb_msglayout google_protobuf_StringValue_msginit; +UPB_INLINE google_protobuf_StringValue* google_protobuf_StringValue_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_StringValue_msginit, arena); +} +UPB_INLINE google_protobuf_StringValue* google_protobuf_StringValue_parsenew( + upb_stringview 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_stringview +google_protobuf_StringValue_value(const google_protobuf_StringValue* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_StringValue_set_value( + google_protobuf_StringValue* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; +} + +/* google.protobuf.BytesValue */ + +extern const upb_msglayout google_protobuf_BytesValue_msginit; +UPB_INLINE google_protobuf_BytesValue* google_protobuf_BytesValue_new( + upb_arena* arena) { + return upb_msg_new(&google_protobuf_BytesValue_msginit, arena); +} +UPB_INLINE google_protobuf_BytesValue* google_protobuf_BytesValue_parsenew( + upb_stringview 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_stringview +google_protobuf_BytesValue_value(const google_protobuf_BytesValue* msg) { + return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); +} + +UPB_INLINE void google_protobuf_BytesValue_set_value( + google_protobuf_BytesValue* msg, upb_stringview value) { + UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; +} + +UPB_END_EXTERN_C + +#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..0dd7bfae109 --- /dev/null +++ b/src/upb/gen_build_yaml.py @@ -0,0 +1,69 @@ +#!/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/refcounted.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/refcounted.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/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..15b3478e555 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/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index d4d5d14f079..2fea807bbb0 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8825,6 +8825,27 @@ "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/refcounted.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..8c412700e45 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): From f6ce4e361b12f48dd021c348379f51edff83d516 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 11 Dec 2018 16:28:06 -0800 Subject: [PATCH 0515/2143] Remove the ignore-pattern in .pylintrc-tests --- .pylintrc-tests | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.pylintrc-tests b/.pylintrc-tests index 0d408fbb565..8a66eec79a6 100644 --- a/.pylintrc-tests +++ b/.pylintrc-tests @@ -1,7 +1,3 @@ -[MASTER] -ignore-patterns= - .+?(beta|framework).+?\.py - [VARIABLES] # TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection From bdfb5691ad7703aee8b28febf45606917be9644e Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 11 Dec 2018 16:30:07 -0800 Subject: [PATCH 0516/2143] Strict check for $config && Enable SC2154 --- tools/run_tests/dockerize/docker_run_tests.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh index 5214938208b..bdcbd88ff9a 100755 --- a/tools/run_tests/dockerize/docker_run_tests.sh +++ b/tools/run_tests/dockerize/docker_run_tests.sh @@ -18,8 +18,7 @@ set -e -# shellcheck disable=SC2154 -export CONFIG=$config +export CONFIG=${config:?} export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer export PATH=$PATH:/usr/bin/llvm-symbolizer From 8f64f9528f45935187485dacb47cdfc822b35149 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 11 Dec 2018 16:37:44 -0800 Subject: [PATCH 0517/2143] Add ignore to .pylintrc-tests --- .pylintrc-tests | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.pylintrc-tests b/.pylintrc-tests index 8a66eec79a6..d9cc4d107ef 100644 --- a/.pylintrc-tests +++ b/.pylintrc-tests @@ -1,3 +1,10 @@ +[MASTER] +ignore= + src/python/grpcio_tests/tests/unit/beta, + src/python/grpcio_tests/tests/unit/framework, + src/python/grpcio_tests/tests/unit/framework/common, + src/python/grpcio_tests/tests/unit/framework/foundation, + [VARIABLES] # TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection From d550af373cc993ee80e9e350d60f4ca662b1ec28 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 12 Dec 2018 04:09:42 +0100 Subject: [PATCH 0518/2143] Moving ::grpc::Alarm to ::grpc_impl::Alarm. --- BUILD | 1 + CMakeLists.txt | 3 + Makefile | 3 + build.yaml | 1 + gRPC-C++.podspec | 1 + include/grpcpp/alarm.h | 93 +------------- include/grpcpp/alarm_impl.h | 116 ++++++++++++++++++ src/cpp/common/alarm.cc | 13 +- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + .../generated/sources_and_headers.json | 2 + 11 files changed, 140 insertions(+), 95 deletions(-) create mode 100644 include/grpcpp/alarm_impl.h diff --git a/BUILD b/BUILD index 9a2c16c6012..cb03e560d5e 100644 --- a/BUILD +++ b/BUILD @@ -204,6 +204,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpc++/support/sync_stream.h", "include/grpc++/support/time.h", "include/grpcpp/alarm.h", + "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 23b4bb77e75..e843397e008 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2985,6 +2985,7 @@ foreach(_hdr include/grpc++/support/sync_stream.h include/grpc++/support/time.h include/grpcpp/alarm.h + include/grpcpp/alarm_impl.h include/grpcpp/channel.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h @@ -3569,6 +3570,7 @@ foreach(_hdr include/grpc++/support/sync_stream.h include/grpc++/support/time.h include/grpcpp/alarm.h + include/grpcpp/alarm_impl.h include/grpcpp/channel.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h @@ -4504,6 +4506,7 @@ foreach(_hdr include/grpc++/support/sync_stream.h include/grpc++/support/time.h include/grpcpp/alarm.h + include/grpcpp/alarm_impl.h include/grpcpp/channel.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h diff --git a/Makefile b/Makefile index 4f7cd130120..438e5729d58 100644 --- a/Makefile +++ b/Makefile @@ -5340,6 +5340,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/support/sync_stream.h \ include/grpc++/support/time.h \ include/grpcpp/alarm.h \ + include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ @@ -5933,6 +5934,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/support/sync_stream.h \ include/grpc++/support/time.h \ include/grpcpp/alarm.h \ + include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ @@ -6835,6 +6837,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/support/sync_stream.h \ include/grpc++/support/time.h \ include/grpcpp/alarm.h \ + include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ diff --git a/build.yaml b/build.yaml index 381e649b392..74a5f5e6dca 100644 --- a/build.yaml +++ b/build.yaml @@ -1323,6 +1323,7 @@ filegroups: - include/grpc++/support/sync_stream.h - include/grpc++/support/time.h - include/grpcpp/alarm.h + - include/grpcpp/alarm_impl.h - include/grpcpp/channel.h - include/grpcpp/client_context.h - include/grpcpp/completion_queue.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 6647201714c..3da94dda4b2 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -78,6 +78,7 @@ Pod::Spec.new do |s| ss.header_mappings_dir = 'include/grpcpp' ss.source_files = 'include/grpcpp/alarm.h', + 'include/grpcpp/alarm_impl.h', 'include/grpcpp/channel.h', 'include/grpcpp/client_context.h', 'include/grpcpp/completion_queue.h', diff --git a/include/grpcpp/alarm.h b/include/grpcpp/alarm.h index 365feb4eb95..2343c1149c5 100644 --- a/include/grpcpp/alarm.h +++ b/include/grpcpp/alarm.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015 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. @@ -16,99 +16,14 @@ * */ -/// An Alarm posts the user provided tag to its associated completion queue upon -/// expiry or cancellation. #ifndef GRPCPP_ALARM_H #define GRPCPP_ALARM_H -#include - -#include -#include -#include -#include -#include -#include +#include namespace grpc { -/// A thin wrapper around \a grpc_alarm (see / \a / src/core/surface/alarm.h). -class Alarm : private GrpcLibraryCodegen { - public: - /// Create an unset completion queue alarm - Alarm(); - - /// Destroy the given completion queue alarm, cancelling it in the process. - ~Alarm(); - - /// DEPRECATED: Create and set a completion queue alarm instance associated to - /// \a cq. - /// This form is deprecated because it is inherently racy. - /// \internal We rely on the presence of \a cq for grpc initialization. If \a - /// cq were ever to be removed, a reference to a static - /// internal::GrpcLibraryInitializer instance would need to be introduced - /// here. \endinternal. - template - Alarm(CompletionQueue* cq, const T& deadline, void* tag) : Alarm() { - SetInternal(cq, TimePoint(deadline).raw_time(), tag); - } - - /// Trigger an alarm instance on completion queue \a cq at the specified time. - /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel), - /// an event with tag \a tag will be added to \a cq. If the alarm expired, the - /// event's success bit will be true, false otherwise (ie, upon cancellation). - template - void Set(CompletionQueue* cq, const T& deadline, void* tag) { - SetInternal(cq, TimePoint(deadline).raw_time(), tag); - } - - /// Alarms aren't copyable. - Alarm(const Alarm&) = delete; - Alarm& operator=(const Alarm&) = delete; - - /// Alarms are movable. - Alarm(Alarm&& rhs) : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; } - Alarm& operator=(Alarm&& rhs) { - alarm_ = rhs.alarm_; - rhs.alarm_ = nullptr; - return *this; - } - - /// Cancel a completion queue alarm. Calling this function over an alarm that - /// has already fired has no effect. - void Cancel(); - - /// NOTE: class experimental_type is not part of the public API of this class - /// TODO(vjpai): Move these contents to the public API of Alarm when - /// they are no longer experimental - class experimental_type { - public: - explicit experimental_type(Alarm* alarm) : alarm_(alarm) {} - - /// Set an alarm to invoke callback \a f. The argument to the callback - /// states whether the alarm expired at \a deadline (true) or was cancelled - /// (false) - template - void Set(const T& deadline, std::function f) { - alarm_->SetInternal(TimePoint(deadline).raw_time(), std::move(f)); - } - - private: - Alarm* alarm_; - }; - - /// 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); } - - private: - void SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag); - void SetInternal(gpr_timespec deadline, std::function f); - - internal::CompletionQueueTag* alarm_; -}; - -} // namespace grpc +typedef ::grpc_impl::Alarm Alarm; +} #endif // GRPCPP_ALARM_H diff --git a/include/grpcpp/alarm_impl.h b/include/grpcpp/alarm_impl.h new file mode 100644 index 00000000000..7844e7c8866 --- /dev/null +++ b/include/grpcpp/alarm_impl.h @@ -0,0 +1,116 @@ +/* + * + * 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. + * + */ + +/// An Alarm posts the user provided tag to its associated completion queue upon +/// expiry or cancellation. +#ifndef GRPCPP_ALARM_IMPL_H +#define GRPCPP_ALARM_IMPL_H + +#include + +#include +#include +#include +#include +#include +#include + +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 + Alarm(); + + /// Destroy the given completion queue alarm, cancelling it in the process. + ~Alarm(); + + /// DEPRECATED: Create and set a completion queue alarm instance associated to + /// \a cq. + /// This form is deprecated because it is inherently racy. + /// \internal We rely on the presence of \a cq for grpc initialization. If \a + /// cq were ever to be removed, a reference to a static + /// internal::GrpcLibraryInitializer instance would need to be introduced + /// here. \endinternal. + template + Alarm(::grpc::CompletionQueue* cq, const T& deadline, void* tag) : Alarm() { + SetInternal(cq, ::grpc::TimePoint(deadline).raw_time(), tag); + } + + /// Trigger an alarm instance on completion queue \a cq at the specified time. + /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel), + /// an event with tag \a tag will be added to \a cq. If the alarm expired, the + /// event's success bit will be true, false otherwise (ie, upon cancellation). + template + void Set(::grpc::CompletionQueue* cq, const T& deadline, void* tag) { + SetInternal(cq, ::grpc::TimePoint(deadline).raw_time(), tag); + } + + /// Alarms aren't copyable. + Alarm(const Alarm&) = delete; + Alarm& operator=(const Alarm&) = delete; + + /// Alarms are movable. + Alarm(Alarm&& rhs) : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; } + Alarm& operator=(Alarm&& rhs) { + alarm_ = rhs.alarm_; + rhs.alarm_ = nullptr; + return *this; + } + + /// Cancel a completion queue alarm. Calling this function over an alarm that + /// has already fired has no effect. + void Cancel(); + + /// NOTE: class experimental_type is not part of the public API of this class + /// TODO(vjpai): Move these contents to the public API of Alarm when + /// they are no longer experimental + class experimental_type { + public: + explicit experimental_type(Alarm* alarm) : alarm_(alarm) {} + + /// Set an alarm to invoke callback \a f. The argument to the callback + /// states whether the alarm expired at \a deadline (true) or was cancelled + /// (false) + template + void Set(const T& deadline, std::function f) { + alarm_->SetInternal(::grpc::TimePoint(deadline).raw_time(), + std::move(f)); + } + + private: + Alarm* alarm_; + }; + + /// 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); } + + private: + void SetInternal(::grpc::CompletionQueue* cq, gpr_timespec deadline, + void* tag); + void SetInternal(gpr_timespec deadline, std::function f); + + ::grpc::internal::CompletionQueueTag* alarm_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_ALARM_IMPL_H diff --git a/src/cpp/common/alarm.cc b/src/cpp/common/alarm.cc index 5819a4210bd..148f0b9bc94 100644 --- a/src/cpp/common/alarm.cc +++ b/src/cpp/common/alarm.cc @@ -31,10 +31,10 @@ #include #include "src/core/lib/debug/trace.h" -namespace grpc { +namespace grpc_impl { namespace internal { -class AlarmImpl : public CompletionQueueTag { +class AlarmImpl : public ::grpc::internal::CompletionQueueTag { public: AlarmImpl() : cq_(nullptr), tag_(nullptr) { gpr_ref_init(&refs_, 1); @@ -51,7 +51,7 @@ class AlarmImpl : public CompletionQueueTag { Unref(); return true; } - void Set(CompletionQueue* cq, gpr_timespec deadline, void* tag) { + void Set(::grpc::CompletionQueue* cq, gpr_timespec deadline, void* tag) { grpc_core::ExecCtx exec_ctx; GRPC_CQ_INTERNAL_REF(cq->cq(), "alarm"); cq_ = cq->cq(); @@ -114,13 +114,14 @@ class AlarmImpl : public CompletionQueueTag { }; } // namespace internal -static internal::GrpcLibraryInitializer g_gli_initializer; +static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer; Alarm::Alarm() : alarm_(new internal::AlarmImpl()) { g_gli_initializer.summon(); } -void Alarm::SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag) { +void Alarm::SetInternal(::grpc::CompletionQueue* cq, gpr_timespec deadline, + void* tag) { // Note that we know that alarm_ is actually an internal::AlarmImpl // but we declared it as the base pointer to avoid a forward declaration // or exposing core data structures in the C++ public headers. @@ -145,4 +146,4 @@ Alarm::~Alarm() { } void Alarm::Cancel() { static_cast(alarm_)->Cancel(); } -} // namespace grpc +} // namespace grpc_impl diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 5c19711ee91..a5f817997dc 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -925,6 +925,7 @@ 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 \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 72b247c48da..7b10bdc699f 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -926,6 +926,7 @@ 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 \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 4d9bbb0f09e..a72e574f1e4 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11431,6 +11431,7 @@ "include/grpc++/support/sync_stream.h", "include/grpc++/support/time.h", "include/grpcpp/alarm.h", + "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", @@ -11536,6 +11537,7 @@ "include/grpc++/support/sync_stream.h", "include/grpc++/support/time.h", "include/grpcpp/alarm.h", + "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", From f3caa01bf383077946f1dc2570d382f3aaf79155 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Wed, 12 Dec 2018 09:03:17 -0800 Subject: [PATCH 0519/2143] monthly update of grpc root certificates --- etc/roots.pem | 272 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 242 insertions(+), 30 deletions(-) diff --git a/etc/roots.pem b/etc/roots.pem index 3e6bbcd76ea..be598710ddd 100644 --- a/etc/roots.pem +++ b/etc/roots.pem @@ -329,36 +329,6 @@ OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS -----END CERTIFICATE----- -# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association -# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association -# Label: "Visa eCommerce Root" -# Serial: 25952180776285836048024890241505565794 -# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02 -# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62 -# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22 ------BEGIN CERTIFICATE----- -MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr -MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl -cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv -bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw -CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h -dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l -cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h -2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E -lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV -ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq -299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t -vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL -dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF -AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR -zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3 -LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd -7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw -++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt -398znM/jra6O1I7mT1GvFpLgXPYHDw== ------END CERTIFICATE----- - # Issuer: CN=AAA Certificate Services O=Comodo CA Limited # Subject: CN=AAA Certificate Services O=Comodo CA Limited # Label: "Comodo AAA Services root" @@ -4340,3 +4310,245 @@ rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV 57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 -----END CERTIFICATE----- + +# Issuer: CN=GTS Root R1 O=Google Trust Services LLC +# Subject: CN=GTS Root R1 O=Google Trust Services LLC +# Label: "GTS Root R1" +# Serial: 146587175971765017618439757810265552097 +# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85 +# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8 +# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX +mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 +zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P +fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc +vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 +Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp +zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO +Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW +k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ +DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF +lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW +Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 +d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z +XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR +gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 +d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv +J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg +DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM ++SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy +F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 +SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws +E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R2 O=Google Trust Services LLC +# Subject: CN=GTS Root R2 O=Google Trust Services LLC +# Label: "GTS Root R2" +# Serial: 146587176055767053814479386953112547951 +# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b +# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d +# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv +CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg +GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu +XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd +re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu +PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 +mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K +8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj +x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR +nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 +kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok +twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp +8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT +vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT +z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA +pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb +pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB +R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R +RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk +0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC +5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF +izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn +yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R3 O=Google Trust Services LLC +# Subject: CN=GTS Root R3 O=Google Trust Services LLC +# Label: "GTS Root R3" +# Serial: 146587176140553309517047991083707763997 +# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25 +# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5 +# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5 +-----BEGIN CERTIFICATE----- +MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A +DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk +fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA +njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R4 O=Google Trust Services LLC +# Subject: CN=GTS Root R4 O=Google Trust Services LLC +# Label: "GTS Root R4" +# Serial: 146587176229350439916519468929765261721 +# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26 +# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb +# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd +-----BEGIN CERTIFICATE----- +MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l +xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 +CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx +sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Global G2 Root O=UniTrust +# Subject: CN=UCA Global G2 Root O=UniTrust +# Label: "UCA Global G2 Root" +# Serial: 124779693093741543919145257850076631279 +# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 +# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a +# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Extended Validation Root O=UniTrust +# Subject: CN=UCA Extended Validation Root O=UniTrust +# Label: "UCA Extended Validation Root" +# Serial: 106100277556486529736699587978573607008 +# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 +# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a +# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- + +# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Label: "Certigna Root CA" +# Serial: 269714418870597844693661054334862075617 +# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 +# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 +# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- From 91e5f7c6474fd3d3939571a9406115ac330821e9 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 12 Dec 2018 09:38:44 -0800 Subject: [PATCH 0520/2143] Update urllib3 to avoid security vulnerability --- requirements.bazel.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.bazel.txt b/requirements.bazel.txt index 61e529a6ec8..7794aec752e 100644 --- a/requirements.bazel.txt +++ b/requirements.bazel.txt @@ -9,7 +9,7 @@ futures>=2.2.0 google-auth>=1.0.0 oauth2client==4.1.0 requests>=2.14.2 -urllib3==1.22 +urllib3>=1.23 chardet==3.0.4 certifi==2017.4.17 idna==2.7 From ca728e2269ddc69c7aeddd279a9b5dff501c3cbf Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 12 Dec 2018 10:11:43 -0800 Subject: [PATCH 0521/2143] Revert "Strict check for $config && Enable SC2154" This reverts commit bdfb5691ad7703aee8b28febf45606917be9644e. --- tools/run_tests/dockerize/docker_run_tests.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh index bdcbd88ff9a..5214938208b 100755 --- a/tools/run_tests/dockerize/docker_run_tests.sh +++ b/tools/run_tests/dockerize/docker_run_tests.sh @@ -18,7 +18,8 @@ set -e -export CONFIG=${config:?} +# shellcheck disable=SC2154 +export CONFIG=$config export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer export PATH=$PATH:/usr/bin/llvm-symbolizer From 3d7dce518dc048670cc22b5c19a0aaca69b479d7 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 12 Dec 2018 09:38:44 -0800 Subject: [PATCH 0522/2143] Update urllib3 to avoid security vulnerability --- requirements.bazel.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.bazel.txt b/requirements.bazel.txt index 61e529a6ec8..7794aec752e 100644 --- a/requirements.bazel.txt +++ b/requirements.bazel.txt @@ -9,7 +9,7 @@ futures>=2.2.0 google-auth>=1.0.0 oauth2client==4.1.0 requests>=2.14.2 -urllib3==1.22 +urllib3>=1.23 chardet==3.0.4 certifi==2017.4.17 idna==2.7 From dbbb38215847d84f7a5544077024d5a21aed5a8d Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 12 Dec 2018 10:24:47 -0800 Subject: [PATCH 0523/2143] Set CONFIG default value 'opt' --- tools/run_tests/dockerize/docker_run_tests.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh index 5214938208b..2a3b6f53efa 100755 --- a/tools/run_tests/dockerize/docker_run_tests.sh +++ b/tools/run_tests/dockerize/docker_run_tests.sh @@ -18,8 +18,7 @@ set -e -# shellcheck disable=SC2154 -export CONFIG=$config +export CONFIG=${config:-opt} export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer export PATH=$PATH:/usr/bin/llvm-symbolizer From 031dfd970384245209b9e6a3b526806f04fa9a59 Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Wed, 12 Dec 2018 11:29:51 -0800 Subject: [PATCH 0524/2143] Bump version to 1.17.1 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index fb87e824bec..eafa89bbaac 100644 --- a/BUILD +++ b/BUILD @@ -68,7 +68,7 @@ g_stands_for = "gizmo" core_version = "7.0.0" -version = "1.17.1-pre1" +version = "1.17.1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index df1fd85e050..946ffb34ecc 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: gizmo - version: 1.17.1-pre1 + version: 1.17.1 filegroups: - name: alts_proto headers: From ac6795a57e05523b8fa220bc5cef26abb876aae5 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 12 Dec 2018 11:40:25 -0800 Subject: [PATCH 0525/2143] Revert "Changes add a script for generating C code and build rule for protobuf" This reverts commit 62027b7e14624283f758a7785a0a1347eda0a147. --- BUILD | 25 - CMakeLists.txt | 53 - Makefile | 38 +- bazel/grpc_build_system.bzl | 1 - bazel/grpc_deps.bzl | 6 +- build.yaml | 2 - grpc.gyp | 19 - .../upb-generated/google/protobuf/any.upb.c | 24 - .../upb-generated/google/protobuf/any.upb.h | 63 - .../google/protobuf/descriptor.upb.c | 549 ----- .../google/protobuf/descriptor.upb.h | 1879 ----------------- .../google/protobuf/duration.upb.c | 24 - .../google/protobuf/duration.upb.h | 65 - .../google/protobuf/struct.upb.c | 88 - .../google/protobuf/struct.upb.h | 226 -- .../google/protobuf/timestamp.upb.c | 24 - .../google/protobuf/timestamp.upb.h | 65 - .../google/protobuf/wrappers.upb.c | 87 - .../google/protobuf/wrappers.upb.h | 305 --- src/upb/gen_build_yaml.py | 69 - 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 - .../generated/sources_and_headers.json | 21 - tools/run_tests/sanity/check_port_platform.py | 3 - 26 files changed, 4 insertions(+), 3699 deletions(-) delete mode 100644 src/core/ext/upb-generated/google/protobuf/any.upb.c delete mode 100644 src/core/ext/upb-generated/google/protobuf/any.upb.h delete mode 100644 src/core/ext/upb-generated/google/protobuf/descriptor.upb.c delete mode 100644 src/core/ext/upb-generated/google/protobuf/descriptor.upb.h delete mode 100644 src/core/ext/upb-generated/google/protobuf/duration.upb.c delete mode 100644 src/core/ext/upb-generated/google/protobuf/duration.upb.h delete mode 100644 src/core/ext/upb-generated/google/protobuf/struct.upb.c delete mode 100644 src/core/ext/upb-generated/google/protobuf/struct.upb.h delete mode 100644 src/core/ext/upb-generated/google/protobuf/timestamp.upb.c delete mode 100644 src/core/ext/upb-generated/google/protobuf/timestamp.upb.h delete mode 100644 src/core/ext/upb-generated/google/protobuf/wrappers.upb.c delete mode 100644 src/core/ext/upb-generated/google/protobuf/wrappers.upb.h delete mode 100755 src/upb/gen_build_yaml.py delete mode 100755 tools/codegen/core/gen_upb_api.sh diff --git a/BUILD b/BUILD index 034e47d1a92..5550e583a87 100644 --- a/BUILD +++ b/BUILD @@ -2274,29 +2274,4 @@ grpc_cc_library( ], ) -# TODO: Get this into build.yaml once we start using it. -grpc_cc_library( - name = "google_protobuf", - 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 08240fe82b4..9c660c77012 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5478,59 +5478,6 @@ 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/refcounted.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 950ac75695d..0163dc414a5 100644 --- a/Makefile +++ b/Makefile @@ -1411,7 +1411,7 @@ plugins: $(PROTOC_PLUGINS) privatelibs: privatelibs_c privatelibs_cxx -privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.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 +privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.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 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 @@ -10117,42 +10117,6 @@ 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/refcounted.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 - -$(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 06b05f79525..65fe5a10aa2 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -99,7 +99,6 @@ def grpc_cc_library( linkopts = if_not_windows(["-pthread"]), includes = [ "include", - "src/core/ext/upb-generated", ], alwayslink = alwayslink, data = data, diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 2738e39abf7..3eacd2b0475 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -12,7 +12,7 @@ def grpc_deps(): ) native.bind( - name = "upb_lib", + name = "upblib", actual = "@upb//:upb", ) @@ -195,8 +195,8 @@ def grpc_deps(): if "upb" not in native.existing_rules(): http_archive( name = "upb", - strip_prefix = "upb-fb6f7e96895c3a9a8ae2e66516160937e7ac1779", - url = "https://github.com/google/upb/archive/fb6f7e96895c3a9a8ae2e66516160937e7ac1779.tar.gz", + strip_prefix = "upb-9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3", + url = "https://github.com/google/upb/archive/9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3.tar.gz", ) diff --git a/build.yaml b/build.yaml index b8c2fa6b020..4521169e6c1 100644 --- a/build.yaml +++ b/build.yaml @@ -5896,8 +5896,6 @@ 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 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 d03c74d8dc1..00f06a1e54e 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -2640,25 +2640,6 @@ '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/refcounted.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 deleted file mode 100644 index 1005a48e909..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/any.upb.c +++ /dev/null @@ -1,24 +0,0 @@ -/* 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 "google/protobuf/any.upb.h" -#include -#include "upb/msg.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 deleted file mode 100644 index d29265553f7..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/any.upb.h +++ /dev/null @@ -1,63 +0,0 @@ -/* 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/msg.h" - -#include "upb/decode.h" -#include "upb/encode.h" -#include "upb/port_def.inc" -UPB_BEGIN_EXTERN_C - -struct google_protobuf_Any; -typedef struct google_protobuf_Any google_protobuf_Any; - -/* Enums */ - -/* google.protobuf.Any */ - -extern const upb_msglayout google_protobuf_Any_msginit; -UPB_INLINE google_protobuf_Any* google_protobuf_Any_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_Any_msginit, arena); -} -UPB_INLINE google_protobuf_Any* google_protobuf_Any_parsenew(upb_stringview 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_stringview -google_protobuf_Any_type_url(const google_protobuf_Any* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); -} -UPB_INLINE upb_stringview -google_protobuf_Any_value(const google_protobuf_Any* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} - -UPB_INLINE void google_protobuf_Any_set_type_url(google_protobuf_Any* msg, - upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; -} -UPB_INLINE void google_protobuf_Any_set_value(google_protobuf_Any* msg, - upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} - -UPB_END_EXTERN_C - -#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 deleted file mode 100644 index f774873d614..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c +++ /dev/null @@ -1,549 +0,0 @@ -/* 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 "google/protobuf/descriptor.upb.h" -#include -#include "upb/msg.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(8, 16), 1, 0, 9, 1}, - {2, UPB_SIZE(16, 32), 2, 0, 9, 1}, - {3, UPB_SIZE(40, 80), 0, 0, 9, 3}, - {4, UPB_SIZE(44, 88), 0, 0, 11, 3}, - {5, UPB_SIZE(48, 96), 0, 1, 11, 3}, - {6, UPB_SIZE(52, 104), 0, 4, 11, 3}, - {7, UPB_SIZE(56, 112), 0, 2, 11, 3}, - {8, UPB_SIZE(32, 64), 4, 3, 11, 1}, - {9, UPB_SIZE(36, 72), 5, 5, 11, 1}, - {10, UPB_SIZE(60, 120), 0, 0, 5, 3}, - {11, UPB_SIZE(64, 128), 0, 0, 5, 3}, - {12, UPB_SIZE(24, 48), 3, 0, 9, 1}, -}; - -const upb_msglayout google_protobuf_FileDescriptorProto_msginit = { - &google_protobuf_FileDescriptorProto_submsgs[0], - &google_protobuf_FileDescriptorProto__fields[0], - UPB_SIZE(72, 144), - 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(8, 16), 1, 0, 9, 1}, {2, UPB_SIZE(20, 40), 0, 4, 11, 3}, - {3, UPB_SIZE(24, 48), 0, 0, 11, 3}, {4, UPB_SIZE(28, 56), 0, 3, 11, 3}, - {5, UPB_SIZE(32, 64), 0, 1, 11, 3}, {6, UPB_SIZE(36, 72), 0, 4, 11, 3}, - {7, UPB_SIZE(16, 32), 2, 5, 11, 1}, {8, UPB_SIZE(40, 80), 0, 6, 11, 3}, - {9, UPB_SIZE(44, 88), 0, 2, 11, 3}, {10, UPB_SIZE(48, 96), 0, 0, 9, 3}, -}; - -const upb_msglayout google_protobuf_DescriptorProto_msginit = { - &google_protobuf_DescriptorProto_submsgs[0], - &google_protobuf_DescriptorProto__fields[0], - UPB_SIZE(56, 112), - 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(8, 16), 1, 0, 9, 1}, - {2, UPB_SIZE(16, 32), 2, 0, 11, 1}, -}; - -const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = { - &google_protobuf_OneofDescriptorProto_submsgs[0], - &google_protobuf_OneofDescriptorProto__fields[0], - UPB_SIZE(24, 48), - 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(8, 16), 1, 0, 9, 1}, {2, UPB_SIZE(20, 40), 0, 2, 11, 3}, - {3, UPB_SIZE(16, 32), 2, 1, 11, 1}, {4, UPB_SIZE(24, 48), 0, 0, 11, 3}, - {5, UPB_SIZE(28, 56), 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, 16), 2, 0, 9, 1}, - {2, UPB_SIZE(4, 4), 1, 0, 5, 1}, - {3, UPB_SIZE(16, 32), 3, 0, 11, 1}, -}; - -const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = { - &google_protobuf_EnumValueDescriptorProto_submsgs[0], - &google_protobuf_EnumValueDescriptorProto__fields[0], - UPB_SIZE(24, 48), - 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(8, 16), 1, 0, 9, 1}, - {2, UPB_SIZE(20, 40), 0, 0, 11, 3}, - {3, UPB_SIZE(16, 32), 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(8, 16), 3, 0, 9, 1}, {2, UPB_SIZE(16, 32), 4, 0, 9, 1}, - {3, UPB_SIZE(24, 48), 5, 0, 9, 1}, {4, UPB_SIZE(32, 64), 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(40, 80), - 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(32, 32), 11, 0, 9, 1}, - {8, UPB_SIZE(40, 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(48, 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(56, 80), 14, 0, 9, 1}, - {37, UPB_SIZE(64, 96), 15, 0, 9, 1}, - {39, UPB_SIZE(72, 112), 16, 0, 9, 1}, - {40, UPB_SIZE(80, 128), 17, 0, 9, 1}, - {41, UPB_SIZE(88, 144), 18, 0, 9, 1}, - {42, UPB_SIZE(24, 24), 10, 0, 8, 1}, - {44, UPB_SIZE(96, 160), 19, 0, 9, 1}, - {45, UPB_SIZE(104, 176), 20, 0, 9, 1}, - {999, UPB_SIZE(112, 192), 0, 0, 11, 3}, -}; - -const upb_msglayout google_protobuf_FileOptions_msginit = { - &google_protobuf_FileOptions_submsgs[0], - &google_protobuf_FileOptions__fields[0], - UPB_SIZE(120, 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(8, 16), 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(24, 48), 0, 0, 5, 3}, {2, UPB_SIZE(28, 56), 0, 0, 5, 3}, - {3, UPB_SIZE(8, 16), 1, 0, 9, 1}, {4, UPB_SIZE(16, 32), 2, 0, 9, 1}, - {6, UPB_SIZE(32, 64), 0, 0, 9, 3}, -}; - -const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = { - NULL, - &google_protobuf_SourceCodeInfo_Location__fields[0], - UPB_SIZE(40, 80), - 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(24, 32), 0, 0, 5, 3}, - {2, UPB_SIZE(16, 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(32, 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 deleted file mode 100644 index 37f0139ce32..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h +++ /dev/null @@ -1,1879 +0,0 @@ -/* 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/msg.h" - -#include "upb/decode.h" -#include "upb/encode.h" -#include "upb/port_def.inc" -UPB_BEGIN_EXTERN_C - -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; - -/* 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 */ - -extern const upb_msglayout google_protobuf_FileDescriptorSet_msginit; -UPB_INLINE google_protobuf_FileDescriptorSet* -google_protobuf_FileDescriptorSet_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_FileDescriptorSet_msginit, arena); -} -UPB_INLINE google_protobuf_FileDescriptorSet* -google_protobuf_FileDescriptorSet_parsenew(upb_stringview 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 upb_array* google_protobuf_FileDescriptorSet_file( - const google_protobuf_FileDescriptorSet* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_FileDescriptorSet_set_file( - google_protobuf_FileDescriptorSet* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.FileDescriptorProto */ - -extern const upb_msglayout google_protobuf_FileDescriptorProto_msginit; -UPB_INLINE google_protobuf_FileDescriptorProto* -google_protobuf_FileDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_FileDescriptorProto* -google_protobuf_FileDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_FileDescriptorProto_name( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_package( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); -} -UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_dependency( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(40, 80)); -} -UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_message_type( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(44, 88)); -} -UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_enum_type( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(48, 96)); -} -UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_service( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(52, 104)); -} -UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_extension( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(56, 112)); -} -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(32, 64)); -} -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(36, 72)); -} -UPB_INLINE const upb_array* -google_protobuf_FileDescriptorProto_public_dependency( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(60, 120)); -} -UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_weak_dependency( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(64, 128)); -} -UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_syntax( - const google_protobuf_FileDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)); -} - -UPB_INLINE void google_protobuf_FileDescriptorProto_set_name( - google_protobuf_FileDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_package( - google_protobuf_FileDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_dependency( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(40, 80)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_message_type( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(44, 88)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_enum_type( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(48, 96)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_service( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(52, 104)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_extension( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(56, 112)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_options( - google_protobuf_FileDescriptorProto* msg, - google_protobuf_FileOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_FileOptions*, UPB_SIZE(32, 64)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info( - google_protobuf_FileDescriptorProto* msg, - google_protobuf_SourceCodeInfo* value) { - UPB_FIELD_AT(msg, google_protobuf_SourceCodeInfo*, UPB_SIZE(36, 72)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_public_dependency( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(60, 120)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_weak_dependency( - google_protobuf_FileDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(64, 128)) = value; -} -UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax( - google_protobuf_FileDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)) = value; -} - -/* google.protobuf.DescriptorProto */ - -extern const upb_msglayout google_protobuf_DescriptorProto_msginit; -UPB_INLINE google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_DescriptorProto* -google_protobuf_DescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_DescriptorProto_name( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_field( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_nested_type( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_enum_type( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_extension_range( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(32, 64)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_extension( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(36, 72)); -} -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(16, 32)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_oneof_decl( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(40, 80)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_reserved_range( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(44, 88)); -} -UPB_INLINE const upb_array* google_protobuf_DescriptorProto_reserved_name( - const google_protobuf_DescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(48, 96)); -} - -UPB_INLINE void google_protobuf_DescriptorProto_set_name( - google_protobuf_DescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_field( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_nested_type( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_enum_type( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_extension_range( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(32, 64)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_extension( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(36, 72)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_options( - google_protobuf_DescriptorProto* msg, - google_protobuf_MessageOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_MessageOptions*, UPB_SIZE(16, 32)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_oneof_decl( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(40, 80)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_reserved_range( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(44, 88)) = value; -} -UPB_INLINE void google_protobuf_DescriptorProto_set_reserved_name( - google_protobuf_DescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(48, 96)) = value; -} - -/* google.protobuf.DescriptorProto.ExtensionRange */ - -extern const upb_msglayout - google_protobuf_DescriptorProto_ExtensionRange_msginit; -UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* -google_protobuf_DescriptorProto_ExtensionRange_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, - arena); -} -UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* -google_protobuf_DescriptorProto_ExtensionRange_parsenew(upb_stringview 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 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 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 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_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_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_FIELD_AT(msg, google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)) = - value; -} - -/* google.protobuf.DescriptorProto.ReservedRange */ - -extern const upb_msglayout - google_protobuf_DescriptorProto_ReservedRange_msginit; -UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* -google_protobuf_DescriptorProto_ReservedRange_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, - arena); -} -UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* -google_protobuf_DescriptorProto_ReservedRange_parsenew(upb_stringview 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 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 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_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_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; -} - -/* google.protobuf.ExtensionRangeOptions */ - -extern const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit; -UPB_INLINE google_protobuf_ExtensionRangeOptions* -google_protobuf_ExtensionRangeOptions_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena); -} -UPB_INLINE google_protobuf_ExtensionRangeOptions* -google_protobuf_ExtensionRangeOptions_parsenew(upb_stringview 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 upb_array* -google_protobuf_ExtensionRangeOptions_uninterpreted_option( - const google_protobuf_ExtensionRangeOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_ExtensionRangeOptions_set_uninterpreted_option( - google_protobuf_ExtensionRangeOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.FieldDescriptorProto */ - -extern const upb_msglayout google_protobuf_FieldDescriptorProto_msginit; -UPB_INLINE google_protobuf_FieldDescriptorProto* -google_protobuf_FieldDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_FieldDescriptorProto* -google_protobuf_FieldDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_FieldDescriptorProto_name( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); -} -UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_extendee( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); -} -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 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 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 upb_stringview google_protobuf_FieldDescriptorProto_type_name( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); -} -UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_default_value( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)); -} -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 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 upb_stringview google_protobuf_FieldDescriptorProto_json_name( - const google_protobuf_FieldDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)); -} - -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name( - google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee( - google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number( - google_protobuf_FieldDescriptorProto* msg, int32_t value) { - 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_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_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_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value( - google_protobuf_FieldDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options( - google_protobuf_FieldDescriptorProto* msg, - google_protobuf_FieldOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_FieldOptions*, UPB_SIZE(72, 112)) = value; -} -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index( - google_protobuf_FieldDescriptorProto* msg, int32_t value) { - 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_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)) = value; -} - -/* google.protobuf.OneofDescriptorProto */ - -extern const upb_msglayout google_protobuf_OneofDescriptorProto_msginit; -UPB_INLINE google_protobuf_OneofDescriptorProto* -google_protobuf_OneofDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_OneofDescriptorProto* -google_protobuf_OneofDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_OneofDescriptorProto_name( - const google_protobuf_OneofDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -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(16, 32)); -} - -UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name( - google_protobuf_OneofDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_OneofDescriptorProto_set_options( - google_protobuf_OneofDescriptorProto* msg, - google_protobuf_OneofOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_OneofOptions*, UPB_SIZE(16, 32)) = value; -} - -/* google.protobuf.EnumDescriptorProto */ - -extern const upb_msglayout google_protobuf_EnumDescriptorProto_msginit; -UPB_INLINE google_protobuf_EnumDescriptorProto* -google_protobuf_EnumDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_EnumDescriptorProto* -google_protobuf_EnumDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_EnumDescriptorProto_name( - const google_protobuf_EnumDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_value( - const google_protobuf_EnumDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); -} -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(16, 32)); -} -UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_reserved_range( - const google_protobuf_EnumDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); -} -UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_reserved_name( - const google_protobuf_EnumDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); -} - -UPB_INLINE void google_protobuf_EnumDescriptorProto_set_name( - google_protobuf_EnumDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_EnumDescriptorProto_set_value( - google_protobuf_EnumDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; -} -UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options( - google_protobuf_EnumDescriptorProto* msg, - google_protobuf_EnumOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_EnumOptions*, UPB_SIZE(16, 32)) = value; -} -UPB_INLINE void google_protobuf_EnumDescriptorProto_set_reserved_range( - google_protobuf_EnumDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; -} -UPB_INLINE void google_protobuf_EnumDescriptorProto_set_reserved_name( - google_protobuf_EnumDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; -} - -/* google.protobuf.EnumDescriptorProto.EnumReservedRange */ - -extern const upb_msglayout - google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit; -UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* -google_protobuf_EnumDescriptorProto_EnumReservedRange_new(upb_arena* arena) { - return upb_msg_new( - &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena); -} -UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* -google_protobuf_EnumDescriptorProto_EnumReservedRange_parsenew( - upb_stringview 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 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 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_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_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; -} - -/* google.protobuf.EnumValueDescriptorProto */ - -extern const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit; -UPB_INLINE google_protobuf_EnumValueDescriptorProto* -google_protobuf_EnumValueDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_EnumValueDescriptorProto* -google_protobuf_EnumValueDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_EnumValueDescriptorProto_name( - const google_protobuf_EnumValueDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -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 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, 32)); -} - -UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name( - google_protobuf_EnumValueDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number( - google_protobuf_EnumValueDescriptorProto* msg, int32_t value) { - 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_FIELD_AT(msg, google_protobuf_EnumValueOptions*, UPB_SIZE(16, 32)) = - value; -} - -/* google.protobuf.ServiceDescriptorProto */ - -extern const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit; -UPB_INLINE google_protobuf_ServiceDescriptorProto* -google_protobuf_ServiceDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_ServiceDescriptorProto* -google_protobuf_ServiceDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_ServiceDescriptorProto_name( - const google_protobuf_ServiceDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE const upb_array* google_protobuf_ServiceDescriptorProto_method( - const google_protobuf_ServiceDescriptorProto* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); -} -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(16, 32)); -} - -UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name( - google_protobuf_ServiceDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_method( - google_protobuf_ServiceDescriptorProto* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; -} -UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options( - google_protobuf_ServiceDescriptorProto* msg, - google_protobuf_ServiceOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_ServiceOptions*, UPB_SIZE(16, 32)) = value; -} - -/* google.protobuf.MethodDescriptorProto */ - -extern const upb_msglayout google_protobuf_MethodDescriptorProto_msginit; -UPB_INLINE google_protobuf_MethodDescriptorProto* -google_protobuf_MethodDescriptorProto_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena); -} -UPB_INLINE google_protobuf_MethodDescriptorProto* -google_protobuf_MethodDescriptorProto_parsenew(upb_stringview 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 upb_stringview google_protobuf_MethodDescriptorProto_name( - const google_protobuf_MethodDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_input_type( - const google_protobuf_MethodDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); -} -UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_output_type( - const google_protobuf_MethodDescriptorProto* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)); -} -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(32, 64)); -} -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_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_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type( - google_protobuf_MethodDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; -} -UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type( - google_protobuf_MethodDescriptorProto* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)) = value; -} -UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options( - google_protobuf_MethodDescriptorProto* msg, - google_protobuf_MethodOptions* value) { - UPB_FIELD_AT(msg, google_protobuf_MethodOptions*, UPB_SIZE(32, 64)) = value; -} -UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming( - google_protobuf_MethodDescriptorProto* msg, bool value) { - 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_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; -} - -/* google.protobuf.FileOptions */ - -extern const upb_msglayout google_protobuf_FileOptions_msginit; -UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_FileOptions_msginit, arena); -} -UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_parsenew( - upb_stringview 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 upb_stringview google_protobuf_FileOptions_java_package( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_java_outer_classname( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); -} -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_java_multiple_files( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); -} -UPB_INLINE upb_stringview -google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); -} -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_java_generic_services( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)); -} -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_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_deprecated( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)); -} -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_cc_enable_arenas( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_objc_class_prefix( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_csharp_namespace( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_swift_prefix( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(72, 112)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_php_class_prefix( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(80, 128)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_php_namespace( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(88, 144)); -} -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 upb_stringview google_protobuf_FileOptions_php_metadata_namespace( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(96, 160)); -} -UPB_INLINE upb_stringview google_protobuf_FileOptions_ruby_package( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(104, 176)); -} -UPB_INLINE const upb_array* google_protobuf_FileOptions_uninterpreted_option( - const google_protobuf_FileOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(112, 192)); -} - -UPB_INLINE void google_protobuf_FileOptions_set_java_package( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_optimize_for( - google_protobuf_FileOptions* msg, - google_protobuf_FileOptions_OptimizeMode value) { - 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_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_go_package( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services( - google_protobuf_FileOptions* msg, bool value) { - 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_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_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_FIELD_AT(msg, bool, UPB_SIZE(20, 20)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_deprecated( - google_protobuf_FileOptions* msg, bool value) { - 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_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_FIELD_AT(msg, bool, UPB_SIZE(23, 23)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(72, 112)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(80, 128)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_php_namespace( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(88, 144)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services( - google_protobuf_FileOptions* msg, bool value) { - 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_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(96, 160)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_ruby_package( - google_protobuf_FileOptions* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(104, 176)) = value; -} -UPB_INLINE void google_protobuf_FileOptions_set_uninterpreted_option( - google_protobuf_FileOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(112, 192)) = value; -} - -/* google.protobuf.MessageOptions */ - -extern const upb_msglayout google_protobuf_MessageOptions_msginit; -UPB_INLINE google_protobuf_MessageOptions* google_protobuf_MessageOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_MessageOptions_msginit, arena); -} -UPB_INLINE google_protobuf_MessageOptions* -google_protobuf_MessageOptions_parsenew(upb_stringview 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_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_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_deprecated( - const google_protobuf_MessageOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)); -} -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 upb_array* google_protobuf_MessageOptions_uninterpreted_option( - const google_protobuf_MessageOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(8, 8)); -} - -UPB_INLINE void google_protobuf_MessageOptions_set_message_set_wire_format( - google_protobuf_MessageOptions* msg, bool value) { - 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_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; -} -UPB_INLINE void google_protobuf_MessageOptions_set_deprecated( - google_protobuf_MessageOptions* msg, bool value) { - 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_FIELD_AT(msg, bool, UPB_SIZE(4, 4)) = value; -} -UPB_INLINE void google_protobuf_MessageOptions_set_uninterpreted_option( - google_protobuf_MessageOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(8, 8)) = value; -} - -/* google.protobuf.FieldOptions */ - -extern const upb_msglayout google_protobuf_FieldOptions_msginit; -UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_FieldOptions_msginit, arena); -} -UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_parsenew( - upb_stringview 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 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_packed( - const google_protobuf_FieldOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); -} -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_lazy( - const google_protobuf_FieldOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)); -} -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_weak( - const google_protobuf_FieldOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)); -} -UPB_INLINE const upb_array* google_protobuf_FieldOptions_uninterpreted_option( - const google_protobuf_FieldOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 32)); -} - -UPB_INLINE void google_protobuf_FieldOptions_set_ctype( - google_protobuf_FieldOptions* msg, - google_protobuf_FieldOptions_CType value) { - 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_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; -} -UPB_INLINE void google_protobuf_FieldOptions_set_deprecated( - google_protobuf_FieldOptions* msg, bool value) { - 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_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_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_FIELD_AT(msg, bool, UPB_SIZE(27, 27)) = value; -} -UPB_INLINE void google_protobuf_FieldOptions_set_uninterpreted_option( - google_protobuf_FieldOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 32)) = value; -} - -/* google.protobuf.OneofOptions */ - -extern const upb_msglayout google_protobuf_OneofOptions_msginit; -UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); -} -UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_parsenew( - upb_stringview 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 upb_array* google_protobuf_OneofOptions_uninterpreted_option( - const google_protobuf_OneofOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_OneofOptions_set_uninterpreted_option( - google_protobuf_OneofOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.EnumOptions */ - -extern const upb_msglayout google_protobuf_EnumOptions_msginit; -UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_EnumOptions_msginit, arena); -} -UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_parsenew( - upb_stringview 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_allow_alias( - const google_protobuf_EnumOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); -} -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 upb_array* google_protobuf_EnumOptions_uninterpreted_option( - const google_protobuf_EnumOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); -} - -UPB_INLINE void google_protobuf_EnumOptions_set_allow_alias( - google_protobuf_EnumOptions* msg, bool value) { - 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_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; -} -UPB_INLINE void google_protobuf_EnumOptions_set_uninterpreted_option( - google_protobuf_EnumOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; -} - -/* google.protobuf.EnumValueOptions */ - -extern const upb_msglayout google_protobuf_EnumValueOptions_msginit; -UPB_INLINE google_protobuf_EnumValueOptions* -google_protobuf_EnumValueOptions_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena); -} -UPB_INLINE google_protobuf_EnumValueOptions* -google_protobuf_EnumValueOptions_parsenew(upb_stringview 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_deprecated( - const google_protobuf_EnumValueOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); -} -UPB_INLINE const upb_array* -google_protobuf_EnumValueOptions_uninterpreted_option( - const google_protobuf_EnumValueOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); -} - -UPB_INLINE void google_protobuf_EnumValueOptions_set_deprecated( - google_protobuf_EnumValueOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; -} -UPB_INLINE void google_protobuf_EnumValueOptions_set_uninterpreted_option( - google_protobuf_EnumValueOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; -} - -/* google.protobuf.ServiceOptions */ - -extern const upb_msglayout google_protobuf_ServiceOptions_msginit; -UPB_INLINE google_protobuf_ServiceOptions* google_protobuf_ServiceOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena); -} -UPB_INLINE google_protobuf_ServiceOptions* -google_protobuf_ServiceOptions_parsenew(upb_stringview 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_deprecated( - const google_protobuf_ServiceOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); -} -UPB_INLINE const upb_array* google_protobuf_ServiceOptions_uninterpreted_option( - const google_protobuf_ServiceOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); -} - -UPB_INLINE void google_protobuf_ServiceOptions_set_deprecated( - google_protobuf_ServiceOptions* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; -} -UPB_INLINE void google_protobuf_ServiceOptions_set_uninterpreted_option( - google_protobuf_ServiceOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; -} - -/* google.protobuf.MethodOptions */ - -extern const upb_msglayout google_protobuf_MethodOptions_msginit; -UPB_INLINE google_protobuf_MethodOptions* google_protobuf_MethodOptions_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_MethodOptions_msginit, arena); -} -UPB_INLINE google_protobuf_MethodOptions* -google_protobuf_MethodOptions_parsenew(upb_stringview 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_deprecated( - const google_protobuf_MethodOptions* msg) { - return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); -} -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 upb_array* google_protobuf_MethodOptions_uninterpreted_option( - const google_protobuf_MethodOptions* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 24)); -} - -UPB_INLINE void google_protobuf_MethodOptions_set_deprecated( - google_protobuf_MethodOptions* msg, bool value) { - 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_FIELD_AT(msg, google_protobuf_MethodOptions_IdempotencyLevel, - UPB_SIZE(8, 8)) = value; -} -UPB_INLINE void google_protobuf_MethodOptions_set_uninterpreted_option( - google_protobuf_MethodOptions* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 24)) = value; -} - -/* google.protobuf.UninterpretedOption */ - -extern const upb_msglayout google_protobuf_UninterpretedOption_msginit; -UPB_INLINE google_protobuf_UninterpretedOption* -google_protobuf_UninterpretedOption_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); -} -UPB_INLINE google_protobuf_UninterpretedOption* -google_protobuf_UninterpretedOption_parsenew(upb_stringview 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 upb_array* google_protobuf_UninterpretedOption_name( - const google_protobuf_UninterpretedOption* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(56, 80)); -} -UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_identifier_value( - const google_protobuf_UninterpretedOption* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); -} -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 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 double google_protobuf_UninterpretedOption_double_value( - const google_protobuf_UninterpretedOption* msg) { - return UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)); -} -UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_string_value( - const google_protobuf_UninterpretedOption* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); -} -UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_aggregate_value( - const google_protobuf_UninterpretedOption* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); -} - -UPB_INLINE void google_protobuf_UninterpretedOption_set_name( - google_protobuf_UninterpretedOption* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(56, 80)) = value; -} -UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value( - google_protobuf_UninterpretedOption* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; -} -UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value( - google_protobuf_UninterpretedOption* msg, uint64_t value) { - 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_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_FIELD_AT(msg, double, UPB_SIZE(24, 24)) = value; -} -UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value( - google_protobuf_UninterpretedOption* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; -} -UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value( - google_protobuf_UninterpretedOption* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; -} - -/* google.protobuf.UninterpretedOption.NamePart */ - -extern const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit; -UPB_INLINE google_protobuf_UninterpretedOption_NamePart* -google_protobuf_UninterpretedOption_NamePart_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, - arena); -} -UPB_INLINE google_protobuf_UninterpretedOption_NamePart* -google_protobuf_UninterpretedOption_NamePart_parsenew(upb_stringview 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 upb_stringview -google_protobuf_UninterpretedOption_NamePart_name_part( - const google_protobuf_UninterpretedOption_NamePart* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -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_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension( - google_protobuf_UninterpretedOption_NamePart* msg, bool value) { - UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; -} - -/* google.protobuf.SourceCodeInfo */ - -extern const upb_msglayout google_protobuf_SourceCodeInfo_msginit; -UPB_INLINE google_protobuf_SourceCodeInfo* google_protobuf_SourceCodeInfo_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena); -} -UPB_INLINE google_protobuf_SourceCodeInfo* -google_protobuf_SourceCodeInfo_parsenew(upb_stringview 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 upb_array* google_protobuf_SourceCodeInfo_location( - const google_protobuf_SourceCodeInfo* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_SourceCodeInfo_set_location( - google_protobuf_SourceCodeInfo* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.SourceCodeInfo.Location */ - -extern const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit; -UPB_INLINE google_protobuf_SourceCodeInfo_Location* -google_protobuf_SourceCodeInfo_Location_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena); -} -UPB_INLINE google_protobuf_SourceCodeInfo_Location* -google_protobuf_SourceCodeInfo_Location_parsenew(upb_stringview 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 const upb_array* google_protobuf_SourceCodeInfo_Location_path( - const google_protobuf_SourceCodeInfo_Location* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); -} -UPB_INLINE const upb_array* google_protobuf_SourceCodeInfo_Location_span( - const google_protobuf_SourceCodeInfo_Location* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); -} -UPB_INLINE upb_stringview -google_protobuf_SourceCodeInfo_Location_leading_comments( - const google_protobuf_SourceCodeInfo_Location* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); -} -UPB_INLINE upb_stringview -google_protobuf_SourceCodeInfo_Location_trailing_comments( - const google_protobuf_SourceCodeInfo_Location* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); -} -UPB_INLINE const upb_array* -google_protobuf_SourceCodeInfo_Location_leading_detached_comments( - const google_protobuf_SourceCodeInfo_Location* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(32, 64)); -} - -UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_path( - google_protobuf_SourceCodeInfo_Location* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; -} -UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_span( - google_protobuf_SourceCodeInfo_Location* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; -} -UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments( - google_protobuf_SourceCodeInfo_Location* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; -} -UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments( - google_protobuf_SourceCodeInfo_Location* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; -} -UPB_INLINE void -google_protobuf_SourceCodeInfo_Location_set_leading_detached_comments( - google_protobuf_SourceCodeInfo_Location* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(32, 64)) = value; -} - -/* google.protobuf.GeneratedCodeInfo */ - -extern const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit; -UPB_INLINE google_protobuf_GeneratedCodeInfo* -google_protobuf_GeneratedCodeInfo_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_GeneratedCodeInfo_msginit, arena); -} -UPB_INLINE google_protobuf_GeneratedCodeInfo* -google_protobuf_GeneratedCodeInfo_parsenew(upb_stringview 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 upb_array* google_protobuf_GeneratedCodeInfo_annotation( - const google_protobuf_GeneratedCodeInfo* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_GeneratedCodeInfo_set_annotation( - google_protobuf_GeneratedCodeInfo* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.GeneratedCodeInfo.Annotation */ - -extern const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit; -UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* -google_protobuf_GeneratedCodeInfo_Annotation_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, - arena); -} -UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* -google_protobuf_GeneratedCodeInfo_Annotation_parsenew(upb_stringview 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 const upb_array* google_protobuf_GeneratedCodeInfo_Annotation_path( - const google_protobuf_GeneratedCodeInfo_Annotation* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 32)); -} -UPB_INLINE upb_stringview -google_protobuf_GeneratedCodeInfo_Annotation_source_file( - const google_protobuf_GeneratedCodeInfo_Annotation* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 16)); -} -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 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 void google_protobuf_GeneratedCodeInfo_Annotation_set_path( - google_protobuf_GeneratedCodeInfo_Annotation* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 32)) = value; -} -UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file( - google_protobuf_GeneratedCodeInfo_Annotation* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 16)) = value; -} -UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin( - google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t value) { - 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_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; -} - -UPB_END_EXTERN_C - -#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 deleted file mode 100644 index b057ce5e4aa..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/duration.upb.c +++ /dev/null @@ -1,24 +0,0 @@ -/* 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 "google/protobuf/duration.upb.h" -#include -#include "upb/msg.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 deleted file mode 100644 index 1f40b3aed24..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/duration.upb.h +++ /dev/null @@ -1,65 +0,0 @@ -/* 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/msg.h" - -#include "upb/decode.h" -#include "upb/encode.h" -#include "upb/port_def.inc" -UPB_BEGIN_EXTERN_C - -struct google_protobuf_Duration; -typedef struct google_protobuf_Duration google_protobuf_Duration; - -/* Enums */ - -/* google.protobuf.Duration */ - -extern const upb_msglayout google_protobuf_Duration_msginit; -UPB_INLINE google_protobuf_Duration* google_protobuf_Duration_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_Duration_msginit, arena); -} -UPB_INLINE google_protobuf_Duration* google_protobuf_Duration_parsenew( - upb_stringview 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; -} - -UPB_END_EXTERN_C - -#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 deleted file mode 100644 index a0820e722a6..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/struct.upb.c +++ /dev/null @@ -1,88 +0,0 @@ -/* 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 "google/protobuf/struct.upb.h" -#include -#include "upb/msg.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 deleted file mode 100644 index 5493794f0e6..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/struct.upb.h +++ /dev/null @@ -1,226 +0,0 @@ -/* 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/msg.h" - -#include "upb/decode.h" -#include "upb/encode.h" -#include "upb/port_def.inc" -UPB_BEGIN_EXTERN_C - -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; - -/* Enums */ - -typedef enum { google_protobuf_NULL_VALUE = 0 } google_protobuf_NullValue; - -/* google.protobuf.Struct */ - -extern const upb_msglayout google_protobuf_Struct_msginit; -UPB_INLINE google_protobuf_Struct* google_protobuf_Struct_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_Struct_msginit, arena); -} -UPB_INLINE google_protobuf_Struct* google_protobuf_Struct_parsenew( - upb_stringview 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 upb_array* google_protobuf_Struct_fields( - const google_protobuf_Struct* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_Struct_set_fields(google_protobuf_Struct* msg, - upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.Struct.FieldsEntry */ - -extern const upb_msglayout google_protobuf_Struct_FieldsEntry_msginit; -UPB_INLINE google_protobuf_Struct_FieldsEntry* -google_protobuf_Struct_FieldsEntry_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_Struct_FieldsEntry_msginit, arena); -} -UPB_INLINE google_protobuf_Struct_FieldsEntry* -google_protobuf_Struct_FieldsEntry_parsenew(upb_stringview 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_stringview google_protobuf_Struct_FieldsEntry_key( - const google_protobuf_Struct_FieldsEntry* msg) { - return UPB_FIELD_AT(msg, upb_stringview, 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_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, 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; -} - -/* google.protobuf.Value */ - -extern const upb_msglayout google_protobuf_Value_msginit; -UPB_INLINE google_protobuf_Value* google_protobuf_Value_new(upb_arena* arena) { - return upb_msg_new(&google_protobuf_Value_msginit, arena); -} -UPB_INLINE google_protobuf_Value* google_protobuf_Value_parsenew( - upb_stringview 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 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 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 upb_stringview -google_protobuf_Value_string_value(const google_protobuf_Value* msg) { - return UPB_READ_ONEOF(msg, upb_stringview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, - upb_stringview_make("", strlen(""))); -} -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 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 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_stringview value) { - UPB_WRITE_ONEOF(msg, upb_stringview, 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 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); -} - -/* google.protobuf.ListValue */ - -extern const upb_msglayout google_protobuf_ListValue_msginit; -UPB_INLINE google_protobuf_ListValue* google_protobuf_ListValue_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_ListValue_msginit, arena); -} -UPB_INLINE google_protobuf_ListValue* google_protobuf_ListValue_parsenew( - upb_stringview 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 upb_array* google_protobuf_ListValue_values( - const google_protobuf_ListValue* msg) { - return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_ListValue_set_values( - google_protobuf_ListValue* msg, upb_array* value) { - UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; -} - -UPB_END_EXTERN_C - -#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 deleted file mode 100644 index 90d0aed7664..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c +++ /dev/null @@ -1,24 +0,0 @@ -/* 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 "google/protobuf/timestamp.upb.h" -#include -#include "upb/msg.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 deleted file mode 100644 index a524eb5b6d0..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h +++ /dev/null @@ -1,65 +0,0 @@ -/* 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/msg.h" - -#include "upb/decode.h" -#include "upb/encode.h" -#include "upb/port_def.inc" -UPB_BEGIN_EXTERN_C - -struct google_protobuf_Timestamp; -typedef struct google_protobuf_Timestamp google_protobuf_Timestamp; - -/* Enums */ - -/* google.protobuf.Timestamp */ - -extern const upb_msglayout google_protobuf_Timestamp_msginit; -UPB_INLINE google_protobuf_Timestamp* google_protobuf_Timestamp_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_Timestamp_msginit, arena); -} -UPB_INLINE google_protobuf_Timestamp* google_protobuf_Timestamp_parsenew( - upb_stringview 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; -} - -UPB_END_EXTERN_C - -#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 deleted file mode 100644 index 3fa3bea1dbc..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c +++ /dev/null @@ -1,87 +0,0 @@ -/* 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 "google/protobuf/wrappers.upb.h" -#include -#include "upb/msg.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 deleted file mode 100644 index 3ae5d3b16e3..00000000000 --- a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h +++ /dev/null @@ -1,305 +0,0 @@ -/* 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/msg.h" - -#include "upb/decode.h" -#include "upb/encode.h" -#include "upb/port_def.inc" -UPB_BEGIN_EXTERN_C - -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; - -/* Enums */ - -/* google.protobuf.DoubleValue */ - -extern const upb_msglayout google_protobuf_DoubleValue_msginit; -UPB_INLINE google_protobuf_DoubleValue* google_protobuf_DoubleValue_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_DoubleValue_msginit, arena); -} -UPB_INLINE google_protobuf_DoubleValue* google_protobuf_DoubleValue_parsenew( - upb_stringview 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 */ - -extern const upb_msglayout google_protobuf_FloatValue_msginit; -UPB_INLINE google_protobuf_FloatValue* google_protobuf_FloatValue_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_FloatValue_msginit, arena); -} -UPB_INLINE google_protobuf_FloatValue* google_protobuf_FloatValue_parsenew( - upb_stringview 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 */ - -extern const upb_msglayout google_protobuf_Int64Value_msginit; -UPB_INLINE google_protobuf_Int64Value* google_protobuf_Int64Value_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_Int64Value_msginit, arena); -} -UPB_INLINE google_protobuf_Int64Value* google_protobuf_Int64Value_parsenew( - upb_stringview 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 */ - -extern const upb_msglayout google_protobuf_UInt64Value_msginit; -UPB_INLINE google_protobuf_UInt64Value* google_protobuf_UInt64Value_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_UInt64Value_msginit, arena); -} -UPB_INLINE google_protobuf_UInt64Value* google_protobuf_UInt64Value_parsenew( - upb_stringview 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 */ - -extern const upb_msglayout google_protobuf_Int32Value_msginit; -UPB_INLINE google_protobuf_Int32Value* google_protobuf_Int32Value_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_Int32Value_msginit, arena); -} -UPB_INLINE google_protobuf_Int32Value* google_protobuf_Int32Value_parsenew( - upb_stringview 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 */ - -extern const upb_msglayout google_protobuf_UInt32Value_msginit; -UPB_INLINE google_protobuf_UInt32Value* google_protobuf_UInt32Value_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); -} -UPB_INLINE google_protobuf_UInt32Value* google_protobuf_UInt32Value_parsenew( - upb_stringview 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 */ - -extern const upb_msglayout google_protobuf_BoolValue_msginit; -UPB_INLINE google_protobuf_BoolValue* google_protobuf_BoolValue_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_BoolValue_msginit, arena); -} -UPB_INLINE google_protobuf_BoolValue* google_protobuf_BoolValue_parsenew( - upb_stringview 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 */ - -extern const upb_msglayout google_protobuf_StringValue_msginit; -UPB_INLINE google_protobuf_StringValue* google_protobuf_StringValue_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_StringValue_msginit, arena); -} -UPB_INLINE google_protobuf_StringValue* google_protobuf_StringValue_parsenew( - upb_stringview 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_stringview -google_protobuf_StringValue_value(const google_protobuf_StringValue* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_StringValue_set_value( - google_protobuf_StringValue* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; -} - -/* google.protobuf.BytesValue */ - -extern const upb_msglayout google_protobuf_BytesValue_msginit; -UPB_INLINE google_protobuf_BytesValue* google_protobuf_BytesValue_new( - upb_arena* arena) { - return upb_msg_new(&google_protobuf_BytesValue_msginit, arena); -} -UPB_INLINE google_protobuf_BytesValue* google_protobuf_BytesValue_parsenew( - upb_stringview 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_stringview -google_protobuf_BytesValue_value(const google_protobuf_BytesValue* msg) { - return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)); -} - -UPB_INLINE void google_protobuf_BytesValue_set_value( - google_protobuf_BytesValue* msg, upb_stringview value) { - UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(0, 0)) = value; -} - -UPB_END_EXTERN_C - -#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 deleted file mode 100755 index 0dd7bfae109..00000000000 --- a/src/upb/gen_build_yaml.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/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/refcounted.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/refcounted.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/tools/buildgen/generate_build_additions.sh b/tools/buildgen/generate_build_additions.sh index c99ad6ee552..5a1f4a598a7 100755 --- a/tools/buildgen/generate_build_additions.sh +++ b/tools/buildgen/generate_build_additions.sh @@ -19,7 +19,6 @@ 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 deleted file mode 100755 index 9457e06f124..00000000000 --- a/tools/codegen/core/gen_upb_api.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/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 fd93cf31e05..787bef1778e 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(\.|)' diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py index 15b3478e555..b8d530cce06 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$'" diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 5b0041a250d..2451101f58d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8831,27 +8831,6 @@ "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/refcounted.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 8c412700e45..fff828eaee8 100755 --- a/tools/run_tests/sanity/check_port_platform.py +++ b/tools/run_tests/sanity/check_port_platform.py @@ -35,9 +35,6 @@ 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): From b15758ab371ced8ee541dc62869b63bc247773ea Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 12 Dec 2018 12:25:11 -0800 Subject: [PATCH 0526/2143] Fix alignment in memory counters. --- test/core/util/memory_counters.cc | 32 +++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc index 4960fe07572..d0da05d9b4d 100644 --- a/test/core/util/memory_counters.cc +++ b/test/core/util/memory_counters.cc @@ -22,6 +22,7 @@ #include #include +#include "src/core/lib/gpr/alloc.h" #include "test/core/util/memory_counters.h" static struct grpc_memory_counters g_memory_counters; @@ -42,19 +43,18 @@ static void guard_free(void* vptr); #endif static void* guard_malloc(size_t size) { - size_t* ptr; if (!size) return nullptr; NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, (gpr_atm)1); - ptr = static_cast(g_old_allocs.malloc_fn(size + sizeof(size))); - *ptr++ = size; - return ptr; + void* ptr = g_old_allocs.malloc_fn( + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size); + *static_cast(ptr) = size; + return static_cast(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); } static void* guard_realloc(void* vptr, size_t size) { - size_t* ptr = static_cast(vptr); if (vptr == nullptr) { return guard_malloc(size); } @@ -62,21 +62,25 @@ static void* guard_realloc(void* vptr, size_t size) { guard_free(vptr); return nullptr; } - --ptr; + void* ptr = + static_cast(vptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, + -*static_cast(ptr)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); - ptr = static_cast(g_old_allocs.realloc_fn(ptr, size + sizeof(size))); - *ptr++ = size; - return ptr; + ptr = g_old_allocs.realloc_fn( + ptr, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size); + *static_cast(ptr) = size; + return static_cast(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); } static void guard_free(void* vptr) { - size_t* ptr = static_cast(vptr); - if (!vptr) return; - --ptr; - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr); + if (vptr == nullptr) return; + void* ptr = + static_cast(vptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size_t)); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, + -*static_cast(ptr)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, -(gpr_atm)1); g_old_allocs.free_fn(ptr); } From a31ccd49e685b26514514f282798a9464433650b Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Wed, 12 Dec 2018 12:45:00 -0800 Subject: [PATCH 0527/2143] 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_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 | 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_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/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 +- 28 files changed, 34 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c199696a9b..b39e6f8e885 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.17.1-pre1") +set(PACKAGE_VERSION "1.17.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 18f49301d76..736583fd936 100644 --- a/Makefile +++ b/Makefile @@ -438,8 +438,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.17.1-pre1 -CSHARP_VERSION = 1.17.1-pre1 +CPP_VERSION = 1.17.1 +CSHARP_VERSION = 1.17.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 ba26e3979d6..65a3f5584d1 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.17.1-pre1' - version = '0.0.6-pre1' + # version = '1.17.1' + 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.17.1-pre1' + grpc_version = '1.17.1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 4b499208f5c..bf0d33ca3cc 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.17.1-pre1' + version = '1.17.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 5d5bd6c47f5..c781ac12117 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.17.1-pre1' + version = '1.17.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 9c453f0b192..e9a07fe0c0b 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.17.1-pre1' + version = '1.17.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 83c7fceef1a..54420ae5cc8 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.17.1-pre1' + version = '1.17.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 3e3d0c354c3..f1cfe0f6231 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.17.1RC1 - 1.17.1RC1 + 1.17.1 + 1.17.1 - beta - beta + stable + stable Apache 2.0 diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index af717f9934f..94d10196ebb 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.17.1-pre1"; } +grpc::string Version() { return "1.17.1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 1935ab77e4f..64a38f3f2d3 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.17.1-pre1 + 1.17.1 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 1209c509d03..3b7a76557da 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.17.1-pre1"; + public const string CurrentVersion = "1.17.1"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 996700b3e1e..42ed94f20a2 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.17.1-pre1 +set VERSION=1.17.1 @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 2fec12ddf89..a3a096588ad 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.17.1-pre1 +set VERSION=1.17.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 65524edad29..b68dde831bb 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.17.1-pre1' + v = '1.17.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 02d2c58a7d0..8da4d65a838 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.17.1-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.17.1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 8c3e0da603f..65f9ad4912a 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.17.1-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.17.1" #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 9e79442157f..3ae5450748a 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.17.1RC1" +#define PHP_GRPC_VERSION "1.17.1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 63e56efa6b1..effc73ed79f 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.17.1rc1""" +__version__ = """1.17.1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 03f7db3b2fe..382ed461715 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.17.1rc1' +VERSION = '1.17.1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index c0817d51dce..62f4f394fce 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.17.1rc1' +VERSION = '1.17.1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 445513c6045..ab82077c478 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.17.1rc1' +VERSION = '1.17.1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 0c89e08dfbf..096f1d30fd3 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.17.1rc1' +VERSION = '1.17.1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 5b861bc0c83..b3ec30934ab 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.17.1rc1' +VERSION = '1.17.1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 3af5e94a7d0..2d7b867937a 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.17.1.pre1' + VERSION = '1.17.1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index e27237158e0..68fba45b9b4 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.17.1.pre1' + VERSION = '1.17.1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 628315ad26e..a43a6ace9ee 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.17.1rc1' +VERSION = '1.17.1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index c32e6b34519..73658d16b7b 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.17.1-pre1 +PROJECT_NUMBER = 1.17.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 d62f540ce84..02c9e75e819 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.17.1-pre1 +PROJECT_NUMBER = 1.17.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 7dc330f298154571163603a8b568015412767cad Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 12 Oct 2018 11:56:29 -0700 Subject: [PATCH 0528/2143] Disable SRV and TXT lookups for localhost --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 9 ++++-- .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 29 +++++++++++++++++++ .../dns_resolver_connectivity_test.cc | 5 +++- test/core/end2end/fuzzers/api_fuzzer.cc | 5 +++- test/core/iomgr/resolve_address_posix_test.cc | 13 +++++++-- 5 files changed, 55 insertions(+), 6 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 c8425ae3365..fc83fc44889 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 @@ -465,11 +465,16 @@ static grpc_error* blocking_resolve_address_ares( 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; +} + 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 (resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0) { + if (should_use_ares(resolver_env)) { + gpr_log(GPR_DEBUG, "Using ares dns resolver"); address_sorting_init(); grpc_error* error = grpc_ares_init(); if (error != GRPC_ERROR_NONE) { @@ -489,7 +494,7 @@ void grpc_resolver_dns_ares_init() { void grpc_resolver_dns_ares_shutdown() { char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0) { + if (should_use_ares(resolver_env)) { address_sorting_shutdown(); grpc_ares_cleanup(); } 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 1b1c2303da3..68977567694 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 @@ -510,6 +510,28 @@ static bool resolve_as_ip_literal_locked( return out; } +static bool target_matches_localhost_inner(const char* name, char** host, + char** port) { + if (!gpr_split_host_port(name, host, port)) { + gpr_log(GPR_INFO, "Unable to split host and port for name: %s", name); + return false; + } + if (gpr_stricmp(*host, "localhost") == 0) { + return true; + } else { + return false; + } +} + +static bool target_matches_localhost(const char* name) { + char* host = nullptr; + char* port = nullptr; + bool out = target_matches_localhost_inner(name, &host, &port); + gpr_free(host); + gpr_free(port); + return out; +} + static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, @@ -536,6 +558,13 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); return r; } + // Don't query for SRV and TXT records if the target is "localhost", so + // as to cut down on lookups over the network, especially in tests: + // https://github.com/grpc/proposal/pull/79 + if (target_matches_localhost(name)) { + check_grpclb = false; + r->service_config_json_out = nullptr; + } // Look up name using c-ares lib. grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( r, dns_server, name, default_port, interested_parties, check_grpclb, 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 1a7a7c9ccc9..0cf549d01da 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -76,7 +76,10 @@ static grpc_ares_request* my_dns_lookup_ares_locked( } else { gpr_mu_unlock(&g_mu); *addresses = grpc_core::MakeUnique(); - (*addresses)->emplace_back(nullptr, 0, nullptr); + grpc_resolved_address dummy_resolved_address; + memset(&dummy_resolved_address, 0, sizeof(dummy_resolved_address)); + dummy_resolved_address.len = 123; + (*addresses)->emplace_back(dummy_resolved_address, nullptr); } GRPC_CLOSURE_SCHED(on_done, error); return nullptr; diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index fe471279841..a0b82904753 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -342,7 +342,10 @@ static void finish_resolve(void* arg, grpc_error* error) { *r->addrs = addrs; } else if (r->addresses != nullptr) { *r->addresses = grpc_core::MakeUnique(); - (*r->addresses)->emplace_back(nullptr, 0, nullptr); + grpc_resolved_address dummy_resolved_address; + memset(&dummy_resolved_address, 0, sizeof(dummy_resolved_address)); + dummy_resolved_address.len = 0; + (*r->addresses)->emplace_back(dummy_resolved_address, nullptr); } GRPC_CLOSURE_SCHED(r->on_done, GRPC_ERROR_NONE); } else { diff --git a/test/core/iomgr/resolve_address_posix_test.cc b/test/core/iomgr/resolve_address_posix_test.cc index ceeb70a1086..5785c73e225 100644 --- a/test/core/iomgr/resolve_address_posix_test.cc +++ b/test/core/iomgr/resolve_address_posix_test.cc @@ -27,6 +27,8 @@ #include #include +#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/gprpp/thd.h" #include "src/core/lib/iomgr/executor.h" @@ -163,8 +165,15 @@ int main(int argc, char** argv) { { grpc_core::ExecCtx exec_ctx; - test_unix_socket(); - test_unix_socket_path_name_too_long(); + char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); + // c-ares resolver doesn't support UDS (ability for native DNS resolver + // to handle this is only expected to be used by servers, which + // unconditionally use the native DNS resolver). + if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) { + test_unix_socket(); + test_unix_socket_path_name_too_long(); + } + gpr_free(resolver_env); } grpc_shutdown(); From 1334f8d2009eba9cf9a00bb2469e514a43cd5f22 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 12 Dec 2018 13:27:29 -0800 Subject: [PATCH 0529/2143] Revert alignment hack in New<> and Delete<>. --- src/core/lib/gprpp/memory.h | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/core/lib/gprpp/memory.h b/src/core/lib/gprpp/memory.h index e90bedcd9b4..b4b63ae771a 100644 --- a/src/core/lib/gprpp/memory.h +++ b/src/core/lib/gprpp/memory.h @@ -40,15 +40,10 @@ namespace grpc_core { -// The alignment of memory returned by gpr_malloc(). -constexpr size_t kAlignmentForDefaultAllocationInBytes = 8; - // Alternative to new, since we cannot use it (for fear of libstdc++) template inline T* New(Args&&... args) { - void* p = alignof(T) > kAlignmentForDefaultAllocationInBytes - ? gpr_malloc_aligned(sizeof(T), alignof(T)) - : gpr_malloc(sizeof(T)); + void* p = gpr_malloc(sizeof(T)); return new (p) T(std::forward(args)...); } @@ -57,11 +52,7 @@ template inline void Delete(T* p) { if (p == nullptr) return; p->~T(); - if (alignof(T) > kAlignmentForDefaultAllocationInBytes) { - gpr_free_aligned(p); - } else { - gpr_free(p); - } + gpr_free(p); } template From fd74fcf2a07a40cd18b5795614c9f71a0e463e87 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 12 Dec 2018 13:48:39 -0800 Subject: [PATCH 0530/2143] New abort with grpc.Status API * Add `abort_with_status` method in ServicerContext * Add `Status` interface similar to the design of Details in interceptor * Add 3 unit test cases for abort mechanism --- src/python/grpcio/grpc/__init__.py | 36 +++++ src/python/grpcio/grpc/_server.py | 4 + .../grpc_testing/_server/_servicer_context.py | 3 + src/python/grpcio_tests/tests/tests.json | 1 + .../grpcio_tests/tests/unit/BUILD.bazel | 1 + .../grpcio_tests/tests/unit/_abort_test.py | 124 ++++++++++++++++++ .../grpcio_tests/tests/unit/_api_test.py | 1 + 7 files changed, 170 insertions(+) create mode 100644 src/python/grpcio_tests/tests/unit/_abort_test.py diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 6022fc3ef21..441f4ac8132 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -266,6 +266,23 @@ class StatusCode(enum.Enum): UNAUTHENTICATED = (_cygrpc.StatusCode.unauthenticated, 'unauthenticated') +############################# gRPC Status ################################ + + +class Status(six.with_metaclass(abc.ABCMeta)): + """Describes the status of an RPC. + + This is an EXPERIMENTAL API. + + Attributes: + 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 + termination of the RPC. + trailing_metadata: The trailing :term:`metadata` in the RPC. + """ + + ############################# gRPC Exceptions ################################ @@ -1118,6 +1135,24 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): """ raise NotImplementedError() + @abc.abstractmethod + def abort_with_status(self, status): + """Raises an exception to terminate the RPC with a non-OK status. + + The status passed as argument will supercede any existing status code, + status message and trailing metadata. + + This is an EXPERIMENTAL API. + + Args: + status: A grpc.Status object. + + Raises: + Exception: An exception is always raised to signal the abortion the + RPC to the gRPC runtime. + """ + raise NotImplementedError() + @abc.abstractmethod def set_code(self, code): """Sets the value to be used as status code upon RPC completion. @@ -1747,6 +1782,7 @@ __all__ = ( 'Future', 'ChannelConnectivity', 'StatusCode', + 'Status', 'RpcError', 'RpcContext', 'Call', diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index e939f615dfd..3bbfa47da53 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -291,6 +291,10 @@ class _Context(grpc.ServicerContext): self._state.abortion = Exception() raise self._state.abortion + def abort_with_status(self, status): + self._state.trailing_metadata = status.trailing_metadata + self.abort(status.code, status.details) + def set_code(self, code): with self._state.condition: self._state.code = code diff --git a/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py b/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py index 90eeb130d30..5b1dfeacdf5 100644 --- a/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py +++ b/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py @@ -70,6 +70,9 @@ class ServicerContext(grpc.ServicerContext): def abort(self, code, details): raise NotImplementedError() + def abort_with_status(self, status): + raise NotImplementedError() + def set_code(self, code): self._rpc.set_code(code) diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index 9cffd3df197..44700e979e9 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -19,6 +19,7 @@ "testing._server_test.FirstServiceServicerTest", "testing._time_test.StrictFakeTimeTest", "testing._time_test.StrictRealTimeTest", + "unit._abort_test.AbortTest", "unit._api_test.AllTest", "unit._api_test.ChannelConnectivityTest", "unit._api_test.ChannelTest", diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel index de33b81e325..4f850220f8f 100644 --- a/src/python/grpcio_tests/tests/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel @@ -3,6 +3,7 @@ load("@grpc_python_dependencies//:requirements.bzl", "requirement") package(default_visibility = ["//visibility:public"]) GRPCIO_TESTS_UNIT = [ + "_abort_test.py", "_api_test.py", "_auth_context_test.py", "_auth_test.py", diff --git a/src/python/grpcio_tests/tests/unit/_abort_test.py b/src/python/grpcio_tests/tests/unit/_abort_test.py new file mode 100644 index 00000000000..6438f6897a0 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_abort_test.py @@ -0,0 +1,124 @@ +# 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. +"""Tests server context abort mechanism""" + +import unittest +import collections +import logging + +import grpc + +from tests.unit import test_common +from tests.unit.framework.common import test_constants + +_ABORT = '/test/abort' +_ABORT_WITH_STATUS = '/test/AbortWithStatus' +_INVALID_CODE = '/test/InvalidCode' + +_REQUEST = b'\x00\x00\x00' +_RESPONSE = b'\x00\x00\x00' + +_ABORT_DETAILS = 'Abandon ship!' +_ABORT_METADATA = (('a-trailing-metadata', '42'),) + + +class _Status( + collections.namedtuple( + '_Status', ('code', 'details', 'trailing_metadata')), grpc.Status): + pass + + +def abort_unary_unary(request, servicer_context): + servicer_context.abort( + grpc.StatusCode.INTERNAL, + _ABORT_DETAILS, + ) + raise Exception('This line should not be executed!') + + +def abort_with_status_unary_unary(request, servicer_context): + servicer_context.abort_with_status( + _Status( + code=grpc.StatusCode.INTERNAL, + details=_ABORT_DETAILS, + trailing_metadata=_ABORT_METADATA, + )) + raise Exception('This line should not be executed!') + + +def invalid_code_unary_unary(request, servicer_context): + servicer_context.abort( + 42, + _ABORT_DETAILS, + ) + + +class _GenericHandler(grpc.GenericRpcHandler): + + def service(self, handler_call_details): + if handler_call_details.method == _ABORT: + return grpc.unary_unary_rpc_method_handler(abort_unary_unary) + elif handler_call_details.method == _ABORT_WITH_STATUS: + return grpc.unary_unary_rpc_method_handler( + abort_with_status_unary_unary) + elif handler_call_details.method == _INVALID_CODE: + return grpc.stream_stream_rpc_method_handler( + invalid_code_unary_unary) + else: + return None + + +class AbortTest(unittest.TestCase): + + def setUp(self): + self._server = test_common.test_server() + port = self._server.add_insecure_port('[::]:0') + self._server.add_generic_rpc_handlers((_GenericHandler(),)) + self._server.start() + + self._channel = grpc.insecure_channel('localhost:%d' % port) + + def tearDown(self): + self._channel.close() + self._server.stop(0) + + def test_abort(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_ABORT)(_REQUEST) + rpc_error = exception_context.exception + + self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) + self.assertEqual(rpc_error.details(), _ABORT_DETAILS) + + def test_abort_with_status(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_ABORT_WITH_STATUS)(_REQUEST) + rpc_error = exception_context.exception + + self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) + self.assertEqual(rpc_error.details(), _ABORT_DETAILS) + self.assertEqual(rpc_error.trailing_metadata(), _ABORT_METADATA) + + def test_invalid_code(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_INVALID_CODE)(_REQUEST) + rpc_error = exception_context.exception + + self.assertEqual(rpc_error.code(), grpc.StatusCode.UNKNOWN) + self.assertEqual(rpc_error.details(), _ABORT_DETAILS) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/unit/_api_test.py b/src/python/grpcio_tests/tests/unit/_api_test.py index 38072861a49..427894bfe9f 100644 --- a/src/python/grpcio_tests/tests/unit/_api_test.py +++ b/src/python/grpcio_tests/tests/unit/_api_test.py @@ -32,6 +32,7 @@ class AllTest(unittest.TestCase): 'Future', 'ChannelConnectivity', 'StatusCode', + 'Status', 'RpcError', 'RpcContext', 'Call', From 3fc5ca0c75aae97e9201df000a5afd5f628403b8 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 12 Dec 2018 14:30:12 -0800 Subject: [PATCH 0531/2143] batch fix --- .../GRPCClient/private/GRPCInsecureChannelFactory.m | 2 +- src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m | 2 +- src/objective-c/GRPCClient/private/GRPCWrappedCall.m | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m index b802137c13a..8ad1e848f55 100644 --- a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -33,7 +33,7 @@ } - (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { - grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); + grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); GRPCFreeChannelArgs(coreChannelArgs); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 3ccc70a7448..96998895364 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -119,7 +119,7 @@ if (host.length == 0) { return NULL; } - grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs([args copy]); + grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs(args); grpc_channel *unmanagedChannel = grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); GRPCFreeChannelArgs(coreChannelArgs); diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 4edd9d3e378..1a848a4b7c3 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -307,6 +307,10 @@ - (void)channelDisconnected { @synchronized(self) { if (_call != NULL) { + // Unreference the call will lead to its cancellation in the core. Note that since + // this function is only called with a network state change, any existing GRPCCall object will + // also receive the same notification and cancel themselves with GRPCErrorCodeUnavailable, so + // the user gets GRPCErrorCodeUnavailable in this case. grpc_call_unref(_call); _call = NULL; } From 087d48a8bd74f39eabea96b495d132e3332b5927 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 12 Dec 2018 14:31:52 -0800 Subject: [PATCH 0532/2143] Update the documentation about the status code constraint --- src/python/grpcio/grpc/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 441f4ac8132..daf869b1563 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -276,7 +276,6 @@ class Status(six.with_metaclass(abc.ABCMeta)): Attributes: 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 termination of the RPC. trailing_metadata: The trailing :term:`metadata` in the RPC. @@ -1145,7 +1144,8 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): This is an EXPERIMENTAL API. Args: - status: A grpc.Status object. + status: A grpc.Status object. The status code in it must not be + StatusCode.OK. Raises: Exception: An exception is always raised to signal the abortion the From bd142d6c46ff97ccd17031d8cd272b6d2ea1206e Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 12 Dec 2018 14:19:05 -0800 Subject: [PATCH 0533/2143] Actually build CensusContext --- src/python/grpcio/grpc/_channel.py | 40 +++++++++++++++++++----------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 35fa82d56bd..96118badada 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -499,6 +499,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer + self._context = cygrpc.build_context() def _prepare(self, request, timeout, metadata, wait_for_ready): deadline, serialized_request, rendezvous = _start_unary_request( @@ -528,11 +529,12 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): raise rendezvous else: call = self._channel.segregated_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, + self._method, None, deadline, metadata, None if credentials is None else credentials._credentials, (( operations, None, - ),)) + ),), self._context) event = call.next_event() _handle_event(event, state, self._response_deserializer) return state, call, @@ -570,9 +572,10 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): else: event_handler = _event_handler(state, self._response_deserializer) call = self._managed_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, + self._method, None, deadline, metadata, None if credentials is None else credentials._credentials, - (operations,), event_handler) + (operations,), event_handler, self._context) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -587,6 +590,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer + self._context = cygrpc.build_context() def __call__(self, request, @@ -615,9 +619,10 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): ) event_handler = _event_handler(state, self._response_deserializer) call = self._managed_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, + self._method, None, deadline, metadata, None if credentials is None else credentials._credentials, - operationses, event_handler) + operationses, event_handler, self._context) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -632,6 +637,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer + self._context = cygrpc.build_context() def _blocking(self, request_iterator, timeout, metadata, credentials, wait_for_ready): @@ -640,10 +646,11 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) call = self._channel.segregated_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, + None, deadline, metadata, None if credentials is None else credentials._credentials, _stream_unary_invocation_operationses_and_tags( - metadata, initial_metadata_flags)) + metadata, initial_metadata_flags), self._context) _consume_request_iterator(request_iterator, state, call, self._request_serializer, None) while True: @@ -687,10 +694,11 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) call = self._managed_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, + None, deadline, metadata, None if credentials is None else credentials._credentials, _stream_unary_invocation_operationses( - metadata, initial_metadata_flags), event_handler) + metadata, initial_metadata_flags), event_handler, self._context) _consume_request_iterator(request_iterator, state, call, self._request_serializer, event_handler) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -706,6 +714,7 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer + self._context = cygrpc.build_context() def __call__(self, request_iterator, @@ -727,9 +736,10 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): ) event_handler = _event_handler(state, self._response_deserializer) call = self._managed_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, + None, deadline, metadata, None if credentials is None else credentials._credentials, operationses, - event_handler) + event_handler, self._context) _consume_request_iterator(request_iterator, state, call, self._request_serializer, event_handler) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -789,7 +799,7 @@ def _channel_managed_call_management(state): # pylint: disable=too-many-arguments def create(flags, method, host, deadline, metadata, credentials, - operationses, event_handler): + operationses, event_handler, context): """Creates a cygrpc.IntegratedCall. Args: @@ -804,7 +814,7 @@ def _channel_managed_call_management(state): started on the call. event_handler: A behavior to call to handle the events resultant from the operations on the call. - + context: Context object for distributed tracing. Returns: A cygrpc.IntegratedCall with which to conduct an RPC. """ @@ -815,7 +825,7 @@ def _channel_managed_call_management(state): with state.lock: call = state.channel.integrated_call(flags, method, host, deadline, metadata, credentials, - operationses_and_tags) + operationses_and_tags, context) if state.managed_calls == 0: state.managed_calls = 1 _run_channel_spin_thread(state) From 7fd68349e3ac2dbf642cb1c7907901ad51b5d6c6 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 12 Dec 2018 14:50:32 -0800 Subject: [PATCH 0534/2143] Add gRPC Python Example: Metadata --- examples/python/metadata/README.md | 6 + examples/python/metadata/helloworld_pb2.py | 134 ++++++++++++++++++ .../python/metadata/helloworld_pb2_grpc.py | 46 ++++++ examples/python/metadata/metadata_client.py | 48 +++++++ examples/python/metadata/metadata_server.py | 56 ++++++++ 5 files changed, 290 insertions(+) create mode 100644 examples/python/metadata/README.md create mode 100644 examples/python/metadata/helloworld_pb2.py create mode 100644 examples/python/metadata/helloworld_pb2_grpc.py create mode 100644 examples/python/metadata/metadata_client.py create mode 100644 examples/python/metadata/metadata_server.py diff --git a/examples/python/metadata/README.md b/examples/python/metadata/README.md new file mode 100644 index 00000000000..5aa75d504a8 --- /dev/null +++ b/examples/python/metadata/README.md @@ -0,0 +1,6 @@ +An example showing how to add custom HTTP2 headers (or [metadata](https://grpc.io/grpc/python/glossary.html) in gRPC glossary) + +HTTP2 supports initial headers and trailing headers, which gRPC utilizes both of them ([learn more](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md)). + +More complete documentation lives at [grpc.io](https://grpc.io/docs/tutorials/basic/python.html). +For API reference please see [API](https://grpc.io/grpc/python/grpc.html). diff --git a/examples/python/metadata/helloworld_pb2.py b/examples/python/metadata/helloworld_pb2.py new file mode 100644 index 00000000000..e18ab9acc7a --- /dev/null +++ b/examples/python/metadata/helloworld_pb2.py @@ -0,0 +1,134 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: helloworld.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 +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='helloworld.proto', + package='helloworld', + syntax='proto3', + serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3') +) + + + + +_HELLOREQUEST = _descriptor.Descriptor( + name='HelloRequest', + full_name='helloworld.HelloRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='helloworld.HelloRequest.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=32, + serialized_end=60, +) + + +_HELLOREPLY = _descriptor.Descriptor( + name='HelloReply', + full_name='helloworld.HelloReply', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='helloworld.HelloReply.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=62, + serialized_end=91, +) + +DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST +DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict( + DESCRIPTOR = _HELLOREQUEST, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloRequest) + )) +_sym_db.RegisterMessage(HelloRequest) + +HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict( + DESCRIPTOR = _HELLOREPLY, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloReply) + )) +_sym_db.RegisterMessage(HelloReply) + + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW')) + +_GREETER = _descriptor.ServiceDescriptor( + name='Greeter', + full_name='helloworld.Greeter', + file=DESCRIPTOR, + index=0, + options=None, + serialized_start=93, + serialized_end=166, + methods=[ + _descriptor.MethodDescriptor( + name='SayHello', + full_name='helloworld.Greeter.SayHello', + index=0, + containing_service=None, + input_type=_HELLOREQUEST, + output_type=_HELLOREPLY, + options=None, + ), +]) +_sym_db.RegisterServiceDescriptor(_GREETER) + +DESCRIPTOR.services_by_name['Greeter'] = _GREETER + +# @@protoc_insertion_point(module_scope) diff --git a/examples/python/metadata/helloworld_pb2_grpc.py b/examples/python/metadata/helloworld_pb2_grpc.py new file mode 100644 index 00000000000..18e07d16797 --- /dev/null +++ b/examples/python/metadata/helloworld_pb2_grpc.py @@ -0,0 +1,46 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +import grpc + +import helloworld_pb2 as helloworld__pb2 + + +class GreeterStub(object): + """The greeting service definition. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.SayHello = channel.unary_unary( + '/helloworld.Greeter/SayHello', + request_serializer=helloworld__pb2.HelloRequest.SerializeToString, + response_deserializer=helloworld__pb2.HelloReply.FromString, + ) + + +class GreeterServicer(object): + """The greeting service definition. + """ + + def SayHello(self, request, context): + """Sends a greeting + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_GreeterServicer_to_server(servicer, server): + rpc_method_handlers = { + 'SayHello': grpc.unary_unary_rpc_method_handler( + servicer.SayHello, + request_deserializer=helloworld__pb2.HelloRequest.FromString, + response_serializer=helloworld__pb2.HelloReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'helloworld.Greeter', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) diff --git a/examples/python/metadata/metadata_client.py b/examples/python/metadata/metadata_client.py new file mode 100644 index 00000000000..f2a8e37cc21 --- /dev/null +++ b/examples/python/metadata/metadata_client.py @@ -0,0 +1,48 @@ +# 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. +"""Example gRPC client that gets/sets metadata (HTTP2 headers)""" + +from __future__ import print_function +import logging + +import grpc + +import helloworld_pb2 +import helloworld_pb2_grpc + + +def run(): + # NOTE(gRPC Python Team): .close() is possible on a channel and should be + # used in circumstances in which the with statement does not fit the needs + # of the code. + with grpc.insecure_channel('localhost:50051') as channel: + stub = helloworld_pb2_grpc.GreeterStub(channel) + response, call = stub.SayHello.with_call( + helloworld_pb2.HelloRequest(name='you'), + metadata=( + ('initial-metadata-1', 'The value should be str'), + ('binary-metadata-bin', + b'With -bin surffix, the value can be bytes'), + ('accesstoken', 'gRPC Python is great'), + )) + + print("Greeter client received: " + response.message) + for key, value in call.trailing_metadata(): + print('Greeter client received trailing metadata: key=%s value=%s' % + (key, value)) + + +if __name__ == '__main__': + logging.basicConfig() + run() diff --git a/examples/python/metadata/metadata_server.py b/examples/python/metadata/metadata_server.py new file mode 100644 index 00000000000..a4329df79aa --- /dev/null +++ b/examples/python/metadata/metadata_server.py @@ -0,0 +1,56 @@ +# 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. +"""Example gRPC server that gets/sets metadata (HTTP2 headers)""" + +from __future__ import print_function +from concurrent import futures +import time +import logging + +import grpc + +import helloworld_pb2 +import helloworld_pb2_grpc + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +class Greeter(helloworld_pb2_grpc.GreeterServicer): + + def SayHello(self, request, context): + for key, value in context.invocation_metadata(): + print('Received initial metadata: key=%s value=%s' % (key, value)) + + context.set_trailing_metadata(( + ('checksum-bin', b'I agree'), + ('retry', 'false'), + )) + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def serve(): + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) + server.add_insecure_port('[::]:50051') + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop(0) + + +if __name__ == '__main__': + logging.basicConfig() + serve() From a69fa16dfdb7795f4918c50f607c4306e598d4d9 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 12 Dec 2018 15:06:12 -0800 Subject: [PATCH 0535/2143] Add compression example --- examples/cpp/compression/Makefile | 110 +++++++++++++++++++++ examples/cpp/compression/README.md | 84 ++++++++++++++++ examples/cpp/compression/greeter_client.cc | 93 +++++++++++++++++ examples/cpp/compression/greeter_server.cc | 76 ++++++++++++++ 4 files changed, 363 insertions(+) create mode 100644 examples/cpp/compression/Makefile create mode 100644 examples/cpp/compression/README.md create mode 100644 examples/cpp/compression/greeter_client.cc create mode 100644 examples/cpp/compression/greeter_server.cc diff --git a/examples/cpp/compression/Makefile b/examples/cpp/compression/Makefile new file mode 100644 index 00000000000..47211886ff6 --- /dev/null +++ b/examples/cpp/compression/Makefile @@ -0,0 +1,110 @@ +# +# 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. +# + +HOST_SYSTEM = $(shell uname | cut -f 1 -d_) +SYSTEM ?= $(HOST_SYSTEM) +CXX = g++ +CPPFLAGS += `pkg-config --cflags protobuf grpc` +CXXFLAGS += -std=c++11 +ifeq ($(SYSTEM),Darwin) +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -lgrpc++_reflection\ + -ldl +else +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ + -ldl +endif +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + +PROTOS_PATH = ../../protos + +vpath %.proto $(PROTOS_PATH) + +all: system-check greeter_client greeter_server + +greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + +greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + +.PRECIOUS: %.grpc.pb.cc +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + +.PRECIOUS: %.pb.cc +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + +clean: + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server + + +# The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + +PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + +SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + +system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif diff --git a/examples/cpp/compression/README.md b/examples/cpp/compression/README.md new file mode 100644 index 00000000000..13988f2c0c5 --- /dev/null +++ b/examples/cpp/compression/README.md @@ -0,0 +1,84 @@ +# gRPC C++ Message Compression Tutorial + +### Prerequisite +Make sure you have run the [hello world example](../helloworld) or understood the basics of gRPC. We will not dive into the details that have been discussed in the hello world example. + +### Get the tutorial source code + +The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: + + +```sh +$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc +``` + +Change your current directory to examples/cpp/compression + +```sh +$ cd examples/cpp/compression/ +``` + +### Generating gRPC code + +To generate the client and server side interfaces: + +```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` + +### Writing a client and a server + +The client and the server can be based on the hello world example. + +Additionally, we can configure the compression settings. + +In the client, set the default compression algorithm of the channel via the channel arg. + +```cpp + ChannelArguments args; + // Set the default compression algorithm for the channel. + args.SetCompressionAlgorithm(GRPC_COMPRESS_GZIP); + GreeterClient greeter(grpc::CreateCustomChannel( + "localhost:50051", grpc::InsecureChannelCredentials(), args)); +``` + +Each call's compression configuration can be overwritten by client context. + +```cpp + // Overwrite the call's compression algorithm to DEFLATE. + context.set_compression_algorithm(GRPC_COMPRESS_DEFLATE); +``` + +In the server, set the default compression algorithm via the server builder. + +```cpp + ServerBuilder builder; + // Set the default compression algorithm for the server. + builder.SetDefaultCompressionAlgorithm(GRPC_COMPRESS_GZIP); +``` + +Each call's compression configuration can be overwritten by server context. + +```cpp + // Overwrite the call's compression algorithm to DEFLATE. + context->set_compression_algorithm(GRPC_COMPRESS_DEFLATE); +``` + +For a working example, refer to [greeter_client.cc](greeter_client.cc) and [greeter_server.cc](greeter_server.cc). + +Build and run the (compressing) client and the server by the following commands. + +```sh +make +./greeter_server +``` + +```sh +./greeter_client +``` diff --git a/examples/cpp/compression/greeter_client.cc b/examples/cpp/compression/greeter_client.cc new file mode 100644 index 00000000000..a8428174644 --- /dev/null +++ b/examples/cpp/compression/greeter_client.cc @@ -0,0 +1,93 @@ +/* + * + * 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 +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ChannelArguments; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + HelloRequest request; + request.set_name(user); + + // Container for the data we expect from the server. + HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + + // Overwrite the call's compression algorithm to DEFLATE. + context.set_compression_algorithm(GRPC_COMPRESS_DEFLATE); + + // The actual RPC. + Status status = stub_->SayHello(&context, request, &reply); + + // Act upon its status. + if (status.ok()) { + return reply.message(); + } else { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + return "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // 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()). + ChannelArguments args; + // Set the default compression algorithm for the channel. + args.SetCompressionAlgorithm(GRPC_COMPRESS_GZIP); + GreeterClient greeter(grpc::CreateCustomChannel( + "localhost:50051", grpc::InsecureChannelCredentials(), args)); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; + + return 0; +} diff --git a/examples/cpp/compression/greeter_server.cc b/examples/cpp/compression/greeter_server.cc new file mode 100644 index 00000000000..7399017afb7 --- /dev/null +++ b/examples/cpp/compression/greeter_server.cc @@ -0,0 +1,76 @@ +/* + * + * 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 +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { + Status SayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + // Overwrite the call's compression algorithm to DEFLATE. + context->set_compression_algorithm(GRPC_COMPRESS_DEFLATE); + std::string prefix("Hello "); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + // Set the default compression algorithm for the server. + builder.SetDefaultCompressionAlgorithm(GRPC_COMPRESS_GZIP); + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} From a050ae8ddc3a64151b344fd1a4d438db9dea2acb Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 13 Dec 2018 00:29:10 +0100 Subject: [PATCH 0536/2143] Revert "better slice management for win_read" This reverts commit b0139e15425196be518b251dbdfa3b86648b4740. --- src/core/lib/iomgr/tcp_windows.cc | 57 +++++++++---------------------- 1 file changed, 16 insertions(+), 41 deletions(-) diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 86ee1010cf7..aaf9fb4ea8a 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -113,10 +113,7 @@ typedef struct grpc_tcp { grpc_closure* read_cb; grpc_closure* write_cb; - - /* garbage after the last read */ - grpc_slice_buffer last_read_buffer; - + grpc_slice read_slice; grpc_slice_buffer* write_slices; grpc_slice_buffer* read_slices; @@ -135,7 +132,6 @@ static void tcp_free(grpc_tcp* tcp) { grpc_winsocket_destroy(tcp->socket); gpr_mu_destroy(&tcp->mu); gpr_free(tcp->peer_string); - grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); if (tcp->shutting_down) GRPC_ERROR_UNREF(tcp->shutdown_error); gpr_free(tcp); @@ -184,6 +180,7 @@ static void on_read(void* tcpp, grpc_error* error) { grpc_tcp* tcp = (grpc_tcp*)tcpp; grpc_closure* cb = tcp->read_cb; grpc_winsocket* socket = tcp->socket; + grpc_slice sub; grpc_winsocket_callback_info* info = &socket->read_info; if (grpc_tcp_trace.enabled()) { @@ -197,19 +194,11 @@ static void on_read(void* tcpp, grpc_error* error) { char* utf8_message = gpr_format_message(info->wsa_error); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(utf8_message); gpr_free(utf8_message); - grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); + grpc_slice_unref_internal(tcp->read_slice); } else { if (info->bytes_transfered != 0 && !tcp->shutting_down) { - GPR_ASSERT((size_t)info->bytes_transfered <= tcp->read_slices->length); - if (static_cast(info->bytes_transfered) != - tcp->read_slices->length) { - grpc_slice_buffer_trim_end( - tcp->read_slices, - tcp->read_slices->length - - static_cast(info->bytes_transfered), - &tcp->last_read_buffer); - } - GPR_ASSERT((size_t)info->bytes_transfered == tcp->read_slices->length); + sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); + grpc_slice_buffer_add(tcp->read_slices, sub); if (grpc_tcp_trace.enabled()) { size_t i; @@ -225,7 +214,7 @@ static void on_read(void* tcpp, grpc_error* error) { if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p unref read_slice", tcp); } - grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); + grpc_slice_unref_internal(tcp->read_slice); error = tcp->shutting_down ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "TCP stream shutting down", &tcp->shutdown_error, 1) @@ -239,8 +228,6 @@ static void on_read(void* tcpp, grpc_error* error) { GRPC_CLOSURE_SCHED(cb, 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_tcp* tcp = (grpc_tcp*)ep; @@ -249,8 +236,7 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, int status; DWORD bytes_read = 0; DWORD flags = 0; - WSABUF buffers[MAX_WSABUF_COUNT]; - size_t i; + WSABUF buffer; if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p win_read", tcp); @@ -266,27 +252,18 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, tcp->read_cb = cb; tcp->read_slices = read_slices; grpc_slice_buffer_reset_and_unref_internal(read_slices); - grpc_slice_buffer_swap(read_slices, &tcp->last_read_buffer); - if (tcp->read_slices->length < DEFAULT_TARGET_READ_SIZE / 2 && - tcp->read_slices->count < MAX_WSABUF_COUNT) { - // TODO(jtattermusch): slice should be allocated using resource quota - grpc_slice_buffer_add(tcp->read_slices, - GRPC_SLICE_MALLOC(DEFAULT_TARGET_READ_SIZE)); - } + tcp->read_slice = GRPC_SLICE_MALLOC(8192); - GPR_ASSERT(tcp->read_slices->count <= MAX_WSABUF_COUNT); - for (i = 0; i < tcp->read_slices->count; i++) { - buffers[i].len = (ULONG)GRPC_SLICE_LENGTH( - tcp->read_slices->slices[i]); // we know slice size fits in 32bit. - buffers[i].buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slices->slices[i]); - } + buffer.len = (ULONG)GRPC_SLICE_LENGTH( + tcp->read_slice); // we know slice size fits in 32bit. + buffer.buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slice); TCP_REF(tcp, "read"); /* First let's try a synchronous, non-blocking read. */ - status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count, - &bytes_read, &flags, NULL, NULL); + status = + WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, NULL, NULL); info->wsa_error = status == 0 ? 0 : WSAGetLastError(); /* Did we get data immediately ? Yay. */ @@ -298,8 +275,8 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, /* Otherwise, let's retry, by queuing a read. */ memset(&tcp->socket->read_info.overlapped, 0, sizeof(OVERLAPPED)); - status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count, - &bytes_read, &flags, &info->overlapped, NULL); + status = WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, + &info->overlapped, NULL); if (status != 0) { int wsa_error = WSAGetLastError(); @@ -353,7 +330,7 @@ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, unsigned i; DWORD bytes_sent; int status; - WSABUF local_buffers[MAX_WSABUF_COUNT]; + WSABUF local_buffers[16]; WSABUF* allocated = NULL; WSABUF* buffers = local_buffers; size_t len; @@ -472,7 +449,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"); } @@ -524,7 +500,6 @@ grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket, GRPC_CLOSURE_INIT(&tcp->on_read, on_read, tcp, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&tcp->on_write, on_write, tcp, grpc_schedule_on_exec_ctx); 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); From f438d72e6c5e5bd839a255322fb91c416822f629 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 13 Dec 2018 00:29:23 +0100 Subject: [PATCH 0537/2143] Revert "basic tcp_trace support for windows" This reverts commit 5861f082607344ed42215ac341e97e4b4bbf0abc. --- src/core/lib/iomgr/tcp_windows.cc | 37 ------------------------------- 1 file changed, 37 deletions(-) diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index aaf9fb4ea8a..4b5250803d1 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -42,7 +42,6 @@ #include "src/core/lib/iomgr/tcp_windows.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/slice/slice_string_helpers.h" #if defined(__MSYS__) && defined(GPR_ARCH_64) /* Nasty workaround for nasty bug when using the 64 bits msys compiler @@ -183,10 +182,6 @@ static void on_read(void* tcpp, grpc_error* error) { grpc_slice sub; grpc_winsocket_callback_info* info = &socket->read_info; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_INFO, "TCP:%p on_read", tcp); - } - GRPC_ERROR_REF(error); if (error == GRPC_ERROR_NONE) { @@ -199,21 +194,7 @@ static void on_read(void* tcpp, grpc_error* error) { if (info->bytes_transfered != 0 && !tcp->shutting_down) { sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); grpc_slice_buffer_add(tcp->read_slices, sub); - - if (grpc_tcp_trace.enabled()) { - size_t i; - for (i = 0; i < tcp->read_slices->count; i++) { - char* dump = grpc_dump_slice(tcp->read_slices->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); - } - } } else { - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_INFO, "TCP:%p unref read_slice", tcp); - } grpc_slice_unref_internal(tcp->read_slice); error = tcp->shutting_down ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -238,10 +219,6 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, DWORD flags = 0; WSABUF buffer; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_INFO, "TCP:%p win_read", tcp); - } - if (tcp->shutting_down) { GRPC_CLOSURE_SCHED( cb, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -298,10 +275,6 @@ static void on_write(void* tcpp, grpc_error* error) { grpc_winsocket_callback_info* info = &handle->write_info; grpc_closure* cb; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_INFO, "TCP:%p on_write", tcp); - } - GRPC_ERROR_REF(error); gpr_mu_lock(&tcp->mu); @@ -335,16 +308,6 @@ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, WSABUF* buffers = local_buffers; size_t len; - if (grpc_tcp_trace.enabled()) { - size_t i; - for (i = 0; i < slices->count; i++) { - char* data = - grpc_dump_slice(slices->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); - } - } - if (tcp->shutting_down) { GRPC_CLOSURE_SCHED( cb, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( From 0f4d465452552cfaf16367241c8894034d1f575a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 12 Dec 2018 15:52:54 -0800 Subject: [PATCH 0538/2143] nit fix --- src/objective-c/GRPCClient/private/GRPCHost.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h index f1d57196424..ca3c52ea177 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.h +++ b/src/objective-c/GRPCClient/private/GRPCHost.h @@ -64,7 +64,7 @@ struct grpc_channel_credentials; withCertChain:(nullable NSString *)pemCertChain error:(NSError **)errorPtr; -@property(atomic, readwrite) GRPCTransportType transportType; +@property(atomic) GRPCTransportType transportType; + (GRPCCallOptions *)callOptionsForHost:(NSString *)host; From 827e84d0a4165e3e64d9ae0a1b8fbbaecdde0fa6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 12 Dec 2018 17:21:30 -0800 Subject: [PATCH 0539/2143] Fix unused variable error --- src/objective-c/tests/Podfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 12112f95e14..8e5f588906b 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -150,7 +150,9 @@ post_install do |installer| end # Enable NSAssert on gRPC - if target.name == 'gRPC' || target.name == 'ProtoRPC' || target.name == 'RxLibrary' + 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' From 6f083e112c509e4ef964b90eb1c3654033123878 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 12 Dec 2018 17:43:52 -0800 Subject: [PATCH 0540/2143] revert pb files --- .../lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c | 4 ++-- src/core/tsi/alts/handshaker/altscontext.pb.c | 4 ++-- src/core/tsi/alts/handshaker/handshaker.pb.c | 4 ++-- src/core/tsi/alts/handshaker/transport_security_common.pb.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c index a7b072420ec..f6538e1349f 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c @@ -75,14 +75,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_32BIT +/* If you get an error here, it means that you need to define PB_FIELD_16BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 256 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server) +PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 256 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server) #endif diff --git a/src/core/tsi/alts/handshaker/altscontext.pb.c b/src/core/tsi/alts/handshaker/altscontext.pb.c index 2320edb1eff..5fb152a558e 100644 --- a/src/core/tsi/alts/handshaker/altscontext.pb.c +++ b/src/core/tsi/alts/handshaker/altscontext.pb.c @@ -33,14 +33,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 65536 #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_32BIT +/* If you get an error here, it means that you need to define PB_FIELD_16BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_AltsContext) +PB_STATIC_ASSERT((pb_membersize(grpc_gcp_AltsContext, peer_rpc_versions) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_AltsContext) #endif diff --git a/src/core/tsi/alts/handshaker/handshaker.pb.c b/src/core/tsi/alts/handshaker/handshaker.pb.c index 8eda290e123..5450b1602d4 100644 --- a/src/core/tsi/alts/handshaker/handshaker.pb.c +++ b/src/core/tsi/alts/handshaker/handshaker.pb.c @@ -108,14 +108,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identit #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_32BIT +/* If you get an error here, it means that you need to define PB_FIELD_16BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identities) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_identity) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_ServerHandshakeParameters, local_identities) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, handshake_parameters[0]) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry, value) < 256 && pb_membersize(grpc_gcp_HandshakerReq, client_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, server_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, next) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, local_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_rpc_versions) < 256 && pb_membersize(grpc_gcp_HandshakerResp, result) < 256 && pb_membersize(grpc_gcp_HandshakerResp, status) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_Endpoint_grpc_gcp_Identity_grpc_gcp_StartClientHandshakeReq_grpc_gcp_ServerHandshakeParameters_grpc_gcp_StartServerHandshakeReq_grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_grpc_gcp_NextHandshakeMessageReq_grpc_gcp_HandshakerReq_grpc_gcp_HandshakerResult_grpc_gcp_HandshakerStatus_grpc_gcp_HandshakerResp) +PB_STATIC_ASSERT((pb_membersize(grpc_gcp_StartClientHandshakeReq, target_identities) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_identity) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartClientHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_ServerHandshakeParameters, local_identities) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, handshake_parameters[0]) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, local_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, remote_endpoint) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq, rpc_versions) < 256 && pb_membersize(grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry, value) < 256 && pb_membersize(grpc_gcp_HandshakerReq, client_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, server_start) < 256 && pb_membersize(grpc_gcp_HandshakerReq, next) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, local_identity) < 256 && pb_membersize(grpc_gcp_HandshakerResult, peer_rpc_versions) < 256 && pb_membersize(grpc_gcp_HandshakerResp, result) < 256 && pb_membersize(grpc_gcp_HandshakerResp, status) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_Endpoint_grpc_gcp_Identity_grpc_gcp_StartClientHandshakeReq_grpc_gcp_ServerHandshakeParameters_grpc_gcp_StartServerHandshakeReq_grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_grpc_gcp_NextHandshakeMessageReq_grpc_gcp_HandshakerReq_grpc_gcp_HandshakerResult_grpc_gcp_HandshakerStatus_grpc_gcp_HandshakerResp) #endif diff --git a/src/core/tsi/alts/handshaker/transport_security_common.pb.c b/src/core/tsi/alts/handshaker/transport_security_common.pb.c index aac699314e7..326b1b10ab7 100644 --- a/src/core/tsi/alts/handshaker/transport_security_common.pb.c +++ b/src/core/tsi/alts/handshaker/transport_security_common.pb.c @@ -35,14 +35,14 @@ PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -/* If you get an error here, it means that you need to define PB_FIELD_32BIT +/* If you get an error here, it means that you need to define PB_FIELD_16BIT * compile-time option. You can do that in pb.h or on compiler command line. * * The reason you need to do this is that some of your messages contain tag * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < 256 && pb_membersize(grpc_gcp_RpcProtocolVersions, min_rpc_version) < 256), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_gcp_RpcProtocolVersions_grpc_gcp_RpcProtocolVersions_Version) +PB_STATIC_ASSERT((pb_membersize(grpc_gcp_RpcProtocolVersions, max_rpc_version) < 256 && pb_membersize(grpc_gcp_RpcProtocolVersions, min_rpc_version) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_gcp_RpcProtocolVersions_grpc_gcp_RpcProtocolVersions_Version) #endif From e8d6d4785410154a64554651898807063ce41e20 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 12 Dec 2018 17:58:52 -0800 Subject: [PATCH 0541/2143] Update README for #16821 --- src/objective-c/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/objective-c/README.md b/src/objective-c/README.md index 32e3956a1ef..83775f86e17 100644 --- a/src/objective-c/README.md +++ b/src/objective-c/README.md @@ -242,3 +242,12 @@ pod `gRPC-Core`, :podspec => "." # assuming gRPC-Core.podspec is in the same dir These steps should allow gRPC to use OpenSSL and drop BoringSSL dependency. If you see any issue, file an issue to us. + +## Upgrade issue with BoringSSL +If you were using an old version of gRPC (<= v1.14) which depended on pod `BoringSSL` rather than +`BoringSSL-GRPC` and meet issue with the library like: +``` +ld: framework not found openssl +``` +updating `-framework openssl` in Other Linker Flags to `-framework openssl_grpc` in your project +may resolve this issue (see [#16821](https://github.com/grpc/grpc/issues/16821)). From e1c78993becfde9006fde8397474da4679367b29 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 11 Dec 2018 14:41:38 -0800 Subject: [PATCH 0542/2143] re-enable unit._exit_test.ExitTest --- src/python/grpcio_tests/commands.py | 8 ++++++++ src/python/grpcio_tests/tests/unit/_exit_test.py | 15 ++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 65e9a99950e..18413abab02 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -133,6 +133,14 @@ class TestGevent(setuptools.Command): # TODO(https://github.com/grpc/grpc/issues/15411) unpin gevent version # 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._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', + 'unit._exit_test.ExitTest.test_in_flight_stream_stream_call', + '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', # 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', diff --git a/src/python/grpcio_tests/tests/unit/_exit_test.py b/src/python/grpcio_tests/tests/unit/_exit_test.py index 52265375799..b429ee089f7 100644 --- a/src/python/grpcio_tests/tests/unit/_exit_test.py +++ b/src/python/grpcio_tests/tests/unit/_exit_test.py @@ -71,7 +71,6 @@ def wait(process): process.wait() -@unittest.skip('https://github.com/grpc/grpc/issues/7311') class ExitTest(unittest.TestCase): def test_unstarted_server(self): @@ -130,6 +129,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_unary_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_UNARY_CALL], @@ -138,6 +139,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_STREAM_CALL], @@ -145,6 +148,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_UNARY_CALL], @@ -153,6 +158,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_STREAM_CALL], @@ -161,6 +168,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -169,6 +178,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -178,6 +189,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + From 9decf48632e2106a56515e67c4147e1a6506b47d Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 6 Dec 2018 01:17:51 -0500 Subject: [PATCH 0543/2143] Move security credentials, connectors, and auth context to C++ This is to use `grpc_core::RefCount` to improve performnace. This commit also replaces explicit C vtables, with C++ vtable with its own compile time assertions and performance benefits. It also makes use of `RefCountedPtr` wherever possible. --- .../lb_policy/grpclb/grpclb_channel_secure.cc | 10 +- .../lb_policy/xds/xds_channel_secure.cc | 10 +- .../client/secure/secure_channel_create.cc | 17 +- .../server/secure/server_secure_chttp2.cc | 19 +- src/core/lib/gprpp/ref_counted_ptr.h | 8 +- .../lib/http/httpcli_security_connector.cc | 197 ++--- src/core/lib/http/parser.h | 10 +- .../lib/security/context/security_context.cc | 195 ++--- .../lib/security/context/security_context.h | 96 ++- .../credentials/alts/alts_credentials.cc | 84 +- .../credentials/alts/alts_credentials.h | 47 +- .../composite/composite_credentials.cc | 297 ++++--- .../composite/composite_credentials.h | 111 ++- .../lib/security/credentials/credentials.cc | 160 +--- .../lib/security/credentials/credentials.h | 208 ++--- .../credentials/fake/fake_credentials.cc | 119 ++- .../credentials/fake/fake_credentials.h | 28 +- .../google_default_credentials.cc | 83 +- .../google_default_credentials.h | 33 +- .../credentials/iam/iam_credentials.cc | 62 +- .../credentials/iam/iam_credentials.h | 22 +- .../credentials/jwt/jwt_credentials.cc | 129 ++- .../credentials/jwt/jwt_credentials.h | 39 +- .../credentials/local/local_credentials.cc | 51 +- .../credentials/local/local_credentials.h | 41 +- .../credentials/oauth2/oauth2_credentials.cc | 279 +++---- .../credentials/oauth2/oauth2_credentials.h | 101 ++- .../credentials/plugin/plugin_credentials.cc | 136 ++- .../credentials/plugin/plugin_credentials.h | 53 +- .../credentials/ssl/ssl_credentials.cc | 149 ++-- .../credentials/ssl/ssl_credentials.h | 77 +- .../alts/alts_security_connector.cc | 329 ++++---- .../alts/alts_security_connector.h | 22 +- .../fake/fake_security_connector.cc | 432 +++++----- .../fake/fake_security_connector.h | 15 +- .../local/local_security_connector.cc | 274 +++---- .../local/local_security_connector.h | 19 +- .../security_connector/security_connector.cc | 161 +--- .../security_connector/security_connector.h | 200 +++-- .../ssl/ssl_security_connector.cc | 776 +++++++++--------- .../ssl/ssl_security_connector.h | 26 +- .../security/security_connector/ssl_utils.cc | 22 +- .../security/security_connector/ssl_utils.h | 4 +- .../security/transport/client_auth_filter.cc | 100 +-- .../security/transport/security_handshaker.cc | 149 ++-- .../security/transport/server_auth_filter.cc | 28 +- src/cpp/client/secure_credentials.cc | 6 +- src/cpp/client/secure_credentials.h | 9 +- src/cpp/common/secure_auth_context.cc | 38 +- src/cpp/common/secure_auth_context.h | 11 +- src/cpp/common/secure_create_auth_context.cc | 5 +- src/cpp/server/secure_server_credentials.cc | 2 +- .../security/alts_security_connector_test.cc | 41 +- test/core/security/auth_context_test.cc | 112 +-- test/core/security/credentials_test.cc | 232 +++--- test/core/security/oauth2_utils.cc | 5 +- .../print_google_default_creds_token.cc | 9 +- test/core/security/security_connector_test.cc | 95 +-- test/core/security/ssl_server_fuzzer.cc | 11 +- .../surface/secure_channel_create_test.cc | 2 +- .../cpp/common/auth_property_iterator_test.cc | 17 +- test/cpp/common/secure_auth_context_test.cc | 14 +- test/cpp/end2end/grpclb_end2end_test.cc | 4 +- 63 files changed, 2969 insertions(+), 3072 deletions(-) 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 6e8fbdcab77..657ff693126 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 @@ -88,22 +88,18 @@ grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args( // bearer token credentials. grpc_channel_credentials* channel_credentials = grpc_channel_credentials_find_in_args(args); - grpc_channel_credentials* creds_sans_call_creds = nullptr; + grpc_core::RefCountedPtr creds_sans_call_creds; if (channel_credentials != nullptr) { creds_sans_call_creds = - grpc_channel_credentials_duplicate_without_call_credentials( - channel_credentials); + channel_credentials->duplicate_without_call_credentials(); GPR_ASSERT(creds_sans_call_creds != nullptr); args_to_remove[num_args_to_remove++] = GRPC_ARG_CHANNEL_CREDENTIALS; args_to_add[num_args_to_add++] = - grpc_channel_credentials_to_arg(creds_sans_call_creds); + grpc_channel_credentials_to_arg(creds_sans_call_creds.get()); } grpc_channel_args* result = grpc_channel_args_copy_and_add_and_remove( args, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add); // Clean up. grpc_channel_args_destroy(args); - if (creds_sans_call_creds != nullptr) { - grpc_channel_credentials_unref(creds_sans_call_creds); - } return result; } 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 9a11f8e39fd..55c646e6eed 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 @@ -87,22 +87,18 @@ grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args( // bearer token credentials. grpc_channel_credentials* channel_credentials = grpc_channel_credentials_find_in_args(args); - grpc_channel_credentials* creds_sans_call_creds = nullptr; + grpc_core::RefCountedPtr creds_sans_call_creds; if (channel_credentials != nullptr) { creds_sans_call_creds = - grpc_channel_credentials_duplicate_without_call_credentials( - channel_credentials); + channel_credentials->duplicate_without_call_credentials(); GPR_ASSERT(creds_sans_call_creds != nullptr); args_to_remove[num_args_to_remove++] = GRPC_ARG_CHANNEL_CREDENTIALS; args_to_add[num_args_to_add++] = - grpc_channel_credentials_to_arg(creds_sans_call_creds); + grpc_channel_credentials_to_arg(creds_sans_call_creds.get()); } grpc_channel_args* result = grpc_channel_args_copy_and_add_and_remove( args, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add); // Clean up. grpc_channel_args_destroy(args); - if (creds_sans_call_creds != nullptr) { - grpc_channel_credentials_unref(creds_sans_call_creds); - } return result; } 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 e73eee43537..9612698e967 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 @@ -110,14 +110,14 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( grpc_channel_args* args_with_authority = grpc_channel_args_copy_and_add(args->args, args_to_add, num_args_to_add); grpc_uri_destroy(server_uri); - grpc_channel_security_connector* subchannel_security_connector = nullptr; // Create the security connector using the credentials and target name. grpc_channel_args* new_args_from_connector = nullptr; - const grpc_security_status security_status = - grpc_channel_credentials_create_security_connector( - channel_credentials, authority.get(), args_with_authority, - &subchannel_security_connector, &new_args_from_connector); - if (security_status != GRPC_SECURITY_OK) { + 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()); @@ -125,15 +125,14 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( return nullptr; } grpc_arg new_security_connector_arg = - grpc_security_connector_to_arg(&subchannel_security_connector->base); + 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); - GRPC_SECURITY_CONNECTOR_UNREF(&subchannel_security_connector->base, - "lb_channel_create"); + subchannel_security_connector.reset(DEBUG_LOCATION, "lb_channel_create"); if (new_args_from_connector != nullptr) { grpc_channel_args_destroy(new_args_from_connector); } diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc index 6689a17da63..98fdb620704 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc @@ -31,6 +31,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/surface/api_trace.h" @@ -40,9 +41,8 @@ int grpc_server_add_secure_http2_port(grpc_server* server, const char* addr, grpc_server_credentials* creds) { grpc_core::ExecCtx exec_ctx; grpc_error* err = GRPC_ERROR_NONE; - grpc_server_security_connector* sc = nullptr; + grpc_core::RefCountedPtr sc; int port_num = 0; - grpc_security_status status; grpc_channel_args* args = nullptr; GRPC_API_TRACE( "grpc_server_add_secure_http2_port(" @@ -54,30 +54,27 @@ int grpc_server_add_secure_http2_port(grpc_server* server, const char* addr, "No credentials specified for secure server port (creds==NULL)"); goto done; } - status = grpc_server_credentials_create_security_connector(creds, &sc); - if (status != GRPC_SECURITY_OK) { + sc = creds->create_security_connector(); + if (sc == nullptr) { char* msg; gpr_asprintf(&msg, "Unable to create secure server with credentials of type %s.", - creds->type); - err = grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg), - GRPC_ERROR_INT_SECURITY_STATUS, status); + creds->type()); + err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); goto done; } // Create channel args. grpc_arg args_to_add[2]; args_to_add[0] = grpc_server_credentials_to_arg(creds); - args_to_add[1] = grpc_security_connector_to_arg(&sc->base); + args_to_add[1] = grpc_security_connector_to_arg(sc.get()); args = grpc_channel_args_copy_and_add(grpc_server_get_channel_args(server), args_to_add, GPR_ARRAY_SIZE(args_to_add)); // Add server port. err = grpc_chttp2_server_add_port(server, addr, args, &port_num); done: - if (sc != nullptr) { - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server"); - } + sc.reset(DEBUG_LOCATION, "server"); if (err != GRPC_ERROR_NONE) { const char* msg = grpc_error_string(err); diff --git a/src/core/lib/gprpp/ref_counted_ptr.h b/src/core/lib/gprpp/ref_counted_ptr.h index 1ed5d584c70..19f38d7f013 100644 --- a/src/core/lib/gprpp/ref_counted_ptr.h +++ b/src/core/lib/gprpp/ref_counted_ptr.h @@ -50,7 +50,7 @@ class RefCountedPtr { } template RefCountedPtr(RefCountedPtr&& other) { - value_ = other.value_; + value_ = static_cast(other.value_); other.value_ = nullptr; } @@ -77,7 +77,7 @@ class RefCountedPtr { static_assert(std::has_virtual_destructor::value, "T does not have a virtual dtor"); if (other.value_ != nullptr) other.value_->IncrementRefCount(); - value_ = other.value_; + value_ = static_cast(other.value_); } // Copy assignment. @@ -118,7 +118,7 @@ class RefCountedPtr { static_assert(std::has_virtual_destructor::value, "T does not have a virtual dtor"); if (value_ != nullptr) value_->Unref(); - value_ = value; + value_ = static_cast(value); } template void reset(const DebugLocation& location, const char* reason, @@ -126,7 +126,7 @@ class RefCountedPtr { static_assert(std::has_virtual_destructor::value, "T does not have a virtual dtor"); if (value_ != nullptr) value_->Unref(location, reason); - value_ = value; + value_ = static_cast(value); } // TODO(roth): This method exists solely as a transition mechanism to allow diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 1c798d368b0..6802851392c 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -29,119 +29,125 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/security/credentials/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/tsi/ssl_transport_security.h" -typedef struct { - grpc_channel_security_connector base; - tsi_ssl_client_handshaker_factory* handshaker_factory; - char* secure_peer_name; -} grpc_httpcli_ssl_channel_security_connector; +class grpc_httpcli_ssl_channel_security_connector final + : public grpc_channel_security_connector { + public: + explicit grpc_httpcli_ssl_channel_security_connector(char* secure_peer_name) + : grpc_channel_security_connector( + /*url_scheme=*/nullptr, + /*channel_creds=*/nullptr, + /*request_metadata_creds=*/nullptr), + secure_peer_name_(secure_peer_name) {} -static void httpcli_ssl_destroy(grpc_security_connector* sc) { - grpc_httpcli_ssl_channel_security_connector* c = - reinterpret_cast(sc); - if (c->handshaker_factory != nullptr) { - tsi_ssl_client_handshaker_factory_unref(c->handshaker_factory); - c->handshaker_factory = nullptr; - } - if (c->secure_peer_name != nullptr) gpr_free(c->secure_peer_name); - gpr_free(sc); -} - -static void httpcli_ssl_add_handshakers(grpc_channel_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_httpcli_ssl_channel_security_connector* c = - reinterpret_cast(sc); - tsi_handshaker* handshaker = nullptr; - if (c->handshaker_factory != nullptr) { - tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( - c->handshaker_factory, c->secure_peer_name, &handshaker); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); + ~grpc_httpcli_ssl_channel_security_connector() override { + if (handshaker_factory_ != nullptr) { + tsi_ssl_client_handshaker_factory_unref(handshaker_factory_); + } + if (secure_peer_name_ != nullptr) { + gpr_free(secure_peer_name_); } } - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(handshaker, &sc->base)); -} -static void httpcli_ssl_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_httpcli_ssl_channel_security_connector* c = - reinterpret_cast(sc); - grpc_error* error = GRPC_ERROR_NONE; - - /* Check the peer name. */ - if (c->secure_peer_name != nullptr && - !tsi_ssl_peer_matches_name(&peer, c->secure_peer_name)) { - char* msg; - gpr_asprintf(&msg, "Peer name %s is not in peer certificate", - c->secure_peer_name); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); + 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( + &options, &handshaker_factory_); } - GRPC_CLOSURE_SCHED(on_peer_checked, error); - tsi_peer_destruct(&peer); -} -static int httpcli_ssl_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_httpcli_ssl_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_httpcli_ssl_channel_security_connector* c2 = - reinterpret_cast(sc2); - return strcmp(c1->secure_peer_name, c2->secure_peer_name); -} + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) override { + tsi_handshaker* handshaker = nullptr; + if (handshaker_factory_ != nullptr) { + tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( + handshaker_factory_, secure_peer_name_, &handshaker); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + } + } + grpc_handshake_manager_add( + handshake_mgr, grpc_security_handshaker_create(handshaker, this)); + } -static grpc_security_connector_vtable httpcli_ssl_vtable = { - httpcli_ssl_destroy, httpcli_ssl_check_peer, httpcli_ssl_cmp}; + tsi_ssl_client_handshaker_factory* handshaker_factory() const { + return handshaker_factory_; + } -static grpc_security_status httpcli_ssl_channel_security_connector_create( + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* /*auth_context*/, + grpc_closure* on_peer_checked) override { + grpc_error* error = GRPC_ERROR_NONE; + + /* Check the peer name. */ + if (secure_peer_name_ != nullptr && + !tsi_ssl_peer_matches_name(&peer, secure_peer_name_)) { + char* msg; + gpr_asprintf(&msg, "Peer name %s is not in peer certificate", + secure_peer_name_); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + } + GRPC_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); + } + + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast( + other_sc); + return strcmp(secure_peer_name_, other->secure_peer_name_); + } + + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + *error = GRPC_ERROR_NONE; + return true; + } + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + const char* secure_peer_name() const { return secure_peer_name_; } + + private: + tsi_ssl_client_handshaker_factory* handshaker_factory_ = nullptr; + char* secure_peer_name_; +}; + +static grpc_core::RefCountedPtr +httpcli_ssl_channel_security_connector_create( const char* pem_root_certs, const tsi_ssl_root_certs_store* root_store, - const char* secure_peer_name, grpc_channel_security_connector** sc) { - tsi_result result = TSI_OK; - grpc_httpcli_ssl_channel_security_connector* c; - + const char* secure_peer_name) { if (secure_peer_name != nullptr && pem_root_certs == nullptr) { gpr_log(GPR_ERROR, "Cannot assert a secure peer name without a trust root."); - return GRPC_SECURITY_ERROR; + return nullptr; } - - c = static_cast( - gpr_zalloc(sizeof(grpc_httpcli_ssl_channel_security_connector))); - - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &httpcli_ssl_vtable; - if (secure_peer_name != nullptr) { - c->secure_peer_name = gpr_strdup(secure_peer_name); - } - tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); - options.pem_root_certs = pem_root_certs; - options.root_store = root_store; - result = tsi_create_ssl_client_handshaker_factory_with_options( - &options, &c->handshaker_factory); + grpc_core::RefCountedPtr c = + grpc_core::MakeRefCounted( + secure_peer_name == nullptr ? nullptr : gpr_strdup(secure_peer_name)); + tsi_result result = c->InitHandshakerFactory(pem_root_certs, root_store); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", tsi_result_to_string(result)); - httpcli_ssl_destroy(&c->base.base); - *sc = nullptr; - return GRPC_SECURITY_ERROR; + return nullptr; } - // We don't actually need a channel credentials object in this case, - // but we set it to a non-nullptr address so that we don't trigger - // assertions in grpc_channel_security_connector_cmp(). - c->base.channel_creds = (grpc_channel_credentials*)1; - c->base.add_handshakers = httpcli_ssl_add_handshakers; - *sc = &c->base; - return GRPC_SECURITY_OK; + return c; } /* handshaker */ @@ -186,10 +192,11 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host, } c->func = on_done; c->arg = arg; - grpc_channel_security_connector* sc = nullptr; - GPR_ASSERT(httpcli_ssl_channel_security_connector_create( - pem_root_certs, root_store, host, &sc) == GRPC_SECURITY_OK); - grpc_arg channel_arg = grpc_security_connector_to_arg(&sc->base); + grpc_core::RefCountedPtr sc = + httpcli_ssl_channel_security_connector_create(pem_root_certs, root_store, + 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, @@ -197,7 +204,7 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host, grpc_handshake_manager_do_handshake( c->handshake_mgr, tcp, nullptr /* channel_args */, deadline, nullptr /* acceptor */, on_handshake_done, c /* user_data */); - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); + sc.reset(DEBUG_LOCATION, "httpcli"); } const grpc_httpcli_handshaker grpc_httpcli_ssl = {"https", ssl_handshake}; diff --git a/src/core/lib/http/parser.h b/src/core/lib/http/parser.h index 1d2e13e8317..a8f47c96c85 100644 --- a/src/core/lib/http/parser.h +++ b/src/core/lib/http/parser.h @@ -70,13 +70,13 @@ typedef struct grpc_http_request { /* A response */ typedef struct grpc_http_response { /* HTTP status code */ - int status; + int status = 0; /* Headers: count and key/values */ - size_t hdr_count; - grpc_http_header* hdrs; + size_t hdr_count = 0; + grpc_http_header* hdrs = nullptr; /* Body: length and contents; contents are NOT null-terminated */ - size_t body_length; - char* body; + size_t body_length = 0; + char* body = nullptr; } grpc_http_response; typedef struct { diff --git a/src/core/lib/security/context/security_context.cc b/src/core/lib/security/context/security_context.cc index 16f40b4f55d..8443ee0695a 100644 --- a/src/core/lib/security/context/security_context.cc +++ b/src/core/lib/security/context/security_context.cc @@ -23,6 +23,8 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/arena.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/security/context/security_context.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/call.h" @@ -50,13 +52,11 @@ grpc_call_error grpc_call_set_credentials(grpc_call* call, ctx = static_cast( grpc_call_context_get(call, GRPC_CONTEXT_SECURITY)); if (ctx == nullptr) { - ctx = grpc_client_security_context_create(grpc_call_get_arena(call)); - ctx->creds = grpc_call_credentials_ref(creds); + ctx = grpc_client_security_context_create(grpc_call_get_arena(call), creds); grpc_call_context_set(call, GRPC_CONTEXT_SECURITY, ctx, grpc_client_security_context_destroy); } else { - grpc_call_credentials_unref(ctx->creds); - ctx->creds = grpc_call_credentials_ref(creds); + ctx->creds = creds != nullptr ? creds->Ref() : nullptr; } return GRPC_CALL_OK; @@ -66,33 +66,45 @@ grpc_auth_context* grpc_call_auth_context(grpc_call* call) { void* sec_ctx = grpc_call_context_get(call, GRPC_CONTEXT_SECURITY); GRPC_API_TRACE("grpc_call_auth_context(call=%p)", 1, (call)); if (sec_ctx == nullptr) return nullptr; - return grpc_call_is_client(call) - ? GRPC_AUTH_CONTEXT_REF( - ((grpc_client_security_context*)sec_ctx)->auth_context, - "grpc_call_auth_context client") - : GRPC_AUTH_CONTEXT_REF( - ((grpc_server_security_context*)sec_ctx)->auth_context, - "grpc_call_auth_context server"); + if (grpc_call_is_client(call)) { + auto* sc = static_cast(sec_ctx); + if (sc->auth_context == nullptr) { + return nullptr; + } else { + return sc->auth_context + ->Ref(DEBUG_LOCATION, "grpc_call_auth_context client") + .release(); + } + } else { + auto* sc = static_cast(sec_ctx); + if (sc->auth_context == nullptr) { + return nullptr; + } else { + return sc->auth_context + ->Ref(DEBUG_LOCATION, "grpc_call_auth_context server") + .release(); + } + } } void grpc_auth_context_release(grpc_auth_context* context) { GRPC_API_TRACE("grpc_auth_context_release(context=%p)", 1, (context)); - GRPC_AUTH_CONTEXT_UNREF(context, "grpc_auth_context_unref"); + if (context == nullptr) return; + context->Unref(DEBUG_LOCATION, "grpc_auth_context_unref"); } /* --- grpc_client_security_context --- */ grpc_client_security_context::~grpc_client_security_context() { - grpc_call_credentials_unref(creds); - GRPC_AUTH_CONTEXT_UNREF(auth_context, "client_security_context"); + auth_context.reset(DEBUG_LOCATION, "client_security_context"); if (extension.instance != nullptr && extension.destroy != nullptr) { extension.destroy(extension.instance); } } grpc_client_security_context* grpc_client_security_context_create( - gpr_arena* arena) { + gpr_arena* arena, grpc_call_credentials* creds) { return new (gpr_arena_alloc(arena, sizeof(grpc_client_security_context))) - grpc_client_security_context(); + grpc_client_security_context(creds != nullptr ? creds->Ref() : nullptr); } void grpc_client_security_context_destroy(void* ctx) { @@ -104,7 +116,7 @@ void grpc_client_security_context_destroy(void* ctx) { /* --- grpc_server_security_context --- */ grpc_server_security_context::~grpc_server_security_context() { - GRPC_AUTH_CONTEXT_UNREF(auth_context, "server_security_context"); + auth_context.reset(DEBUG_LOCATION, "server_security_context"); if (extension.instance != nullptr && extension.destroy != nullptr) { extension.destroy(extension.instance); } @@ -126,69 +138,11 @@ void grpc_server_security_context_destroy(void* ctx) { static grpc_auth_property_iterator empty_iterator = {nullptr, 0, nullptr}; -grpc_auth_context* grpc_auth_context_create(grpc_auth_context* chained) { - grpc_auth_context* ctx = - static_cast(gpr_zalloc(sizeof(grpc_auth_context))); - gpr_ref_init(&ctx->refcount, 1); - if (chained != nullptr) { - ctx->chained = GRPC_AUTH_CONTEXT_REF(chained, "chained"); - ctx->peer_identity_property_name = - ctx->chained->peer_identity_property_name; - } - return ctx; -} - -#ifndef NDEBUG -grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* ctx, - const char* file, int line, - const char* reason) { - if (ctx == nullptr) return nullptr; - if (grpc_trace_auth_context_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&ctx->refcount.count); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "AUTH_CONTEXT:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", ctx, val, - val + 1, reason); - } -#else -grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* ctx) { - if (ctx == nullptr) return nullptr; -#endif - gpr_ref(&ctx->refcount); - return ctx; -} - -#ifndef NDEBUG -void grpc_auth_context_unref(grpc_auth_context* ctx, const char* file, int line, - const char* reason) { - if (ctx == nullptr) return; - if (grpc_trace_auth_context_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&ctx->refcount.count); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "AUTH_CONTEXT:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", ctx, val, - val - 1, reason); - } -#else -void grpc_auth_context_unref(grpc_auth_context* ctx) { - if (ctx == nullptr) return; -#endif - if (gpr_unref(&ctx->refcount)) { - size_t i; - GRPC_AUTH_CONTEXT_UNREF(ctx->chained, "chained"); - if (ctx->properties.array != nullptr) { - for (i = 0; i < ctx->properties.count; i++) { - grpc_auth_property_reset(&ctx->properties.array[i]); - } - gpr_free(ctx->properties.array); - } - gpr_free(ctx); - } -} - const char* grpc_auth_context_peer_identity_property_name( const grpc_auth_context* ctx) { GRPC_API_TRACE("grpc_auth_context_peer_identity_property_name(ctx=%p)", 1, (ctx)); - return ctx->peer_identity_property_name; + return ctx->peer_identity_property_name(); } int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context* ctx, @@ -204,13 +158,13 @@ int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context* ctx, name != nullptr ? name : "NULL"); return 0; } - ctx->peer_identity_property_name = prop->name; + ctx->set_peer_identity_property_name(prop->name); return 1; } int grpc_auth_context_peer_is_authenticated(const grpc_auth_context* ctx) { GRPC_API_TRACE("grpc_auth_context_peer_is_authenticated(ctx=%p)", 1, (ctx)); - return ctx->peer_identity_property_name == nullptr ? 0 : 1; + return ctx->is_authenticated(); } grpc_auth_property_iterator grpc_auth_context_property_iterator( @@ -226,16 +180,17 @@ const grpc_auth_property* grpc_auth_property_iterator_next( grpc_auth_property_iterator* it) { GRPC_API_TRACE("grpc_auth_property_iterator_next(it=%p)", 1, (it)); if (it == nullptr || it->ctx == nullptr) return nullptr; - while (it->index == it->ctx->properties.count) { - if (it->ctx->chained == nullptr) return nullptr; - it->ctx = it->ctx->chained; + while (it->index == it->ctx->properties().count) { + if (it->ctx->chained() == nullptr) return nullptr; + it->ctx = it->ctx->chained(); it->index = 0; } if (it->name == nullptr) { - return &it->ctx->properties.array[it->index++]; + return &it->ctx->properties().array[it->index++]; } else { - while (it->index < it->ctx->properties.count) { - const grpc_auth_property* prop = &it->ctx->properties.array[it->index++]; + while (it->index < it->ctx->properties().count) { + const grpc_auth_property* prop = + &it->ctx->properties().array[it->index++]; GPR_ASSERT(prop->name != nullptr); if (strcmp(it->name, prop->name) == 0) { return prop; @@ -262,30 +217,22 @@ grpc_auth_property_iterator grpc_auth_context_peer_identity( GRPC_API_TRACE("grpc_auth_context_peer_identity(ctx=%p)", 1, (ctx)); if (ctx == nullptr) return empty_iterator; return grpc_auth_context_find_properties_by_name( - ctx, ctx->peer_identity_property_name); + ctx, ctx->peer_identity_property_name()); } -static void ensure_auth_context_capacity(grpc_auth_context* ctx) { - if (ctx->properties.count == ctx->properties.capacity) { - ctx->properties.capacity = - GPR_MAX(ctx->properties.capacity + 8, ctx->properties.capacity * 2); - ctx->properties.array = static_cast( - gpr_realloc(ctx->properties.array, - ctx->properties.capacity * sizeof(grpc_auth_property))); +void grpc_auth_context::ensure_capacity() { + if (properties_.count == properties_.capacity) { + properties_.capacity = + GPR_MAX(properties_.capacity + 8, properties_.capacity * 2); + properties_.array = static_cast(gpr_realloc( + properties_.array, properties_.capacity * sizeof(grpc_auth_property))); } } -void grpc_auth_context_add_property(grpc_auth_context* ctx, const char* name, - const char* value, size_t value_length) { - grpc_auth_property* prop; - GRPC_API_TRACE( - "grpc_auth_context_add_property(ctx=%p, name=%s, value=%*.*s, " - "value_length=%lu)", - 6, - (ctx, name, (int)value_length, (int)value_length, value, - (unsigned long)value_length)); - ensure_auth_context_capacity(ctx); - prop = &ctx->properties.array[ctx->properties.count++]; +void grpc_auth_context::add_property(const char* name, const char* value, + size_t value_length) { + ensure_capacity(); + grpc_auth_property* prop = &properties_.array[properties_.count++]; prop->name = gpr_strdup(name); prop->value = static_cast(gpr_malloc(value_length + 1)); memcpy(prop->value, value, value_length); @@ -293,20 +240,35 @@ void grpc_auth_context_add_property(grpc_auth_context* ctx, const char* name, prop->value_length = value_length; } -void grpc_auth_context_add_cstring_property(grpc_auth_context* ctx, - const char* name, - const char* value) { - grpc_auth_property* prop; +void grpc_auth_context_add_property(grpc_auth_context* ctx, const char* name, + const char* value, size_t value_length) { GRPC_API_TRACE( - "grpc_auth_context_add_cstring_property(ctx=%p, name=%s, value=%s)", 3, - (ctx, name, value)); - ensure_auth_context_capacity(ctx); - prop = &ctx->properties.array[ctx->properties.count++]; + "grpc_auth_context_add_property(ctx=%p, name=%s, value=%*.*s, " + "value_length=%lu)", + 6, + (ctx, name, (int)value_length, (int)value_length, value, + (unsigned long)value_length)); + ctx->add_property(name, value, value_length); +} + +void grpc_auth_context::add_cstring_property(const char* name, + const char* value) { + ensure_capacity(); + grpc_auth_property* prop = &properties_.array[properties_.count++]; prop->name = gpr_strdup(name); prop->value = gpr_strdup(value); prop->value_length = strlen(value); } +void grpc_auth_context_add_cstring_property(grpc_auth_context* ctx, + const char* name, + const char* value) { + GRPC_API_TRACE( + "grpc_auth_context_add_cstring_property(ctx=%p, name=%s, value=%s)", 3, + (ctx, name, value)); + ctx->add_cstring_property(name, value); +} + void grpc_auth_property_reset(grpc_auth_property* property) { gpr_free(property->name); gpr_free(property->value); @@ -314,12 +276,17 @@ void grpc_auth_property_reset(grpc_auth_property* property) { } static void auth_context_pointer_arg_destroy(void* p) { - GRPC_AUTH_CONTEXT_UNREF((grpc_auth_context*)p, "auth_context_pointer_arg"); + if (p != nullptr) { + static_cast(p)->Unref(DEBUG_LOCATION, + "auth_context_pointer_arg"); + } } static void* auth_context_pointer_arg_copy(void* p) { - return GRPC_AUTH_CONTEXT_REF((grpc_auth_context*)p, - "auth_context_pointer_arg"); + auto* ctx = static_cast(p); + return ctx == nullptr + ? nullptr + : ctx->Ref(DEBUG_LOCATION, "auth_context_pointer_arg").release(); } static int auth_context_pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); } diff --git a/src/core/lib/security/context/security_context.h b/src/core/lib/security/context/security_context.h index e45415f63b8..b43ee5e62d5 100644 --- a/src/core/lib/security/context/security_context.h +++ b/src/core/lib/security/context/security_context.h @@ -21,6 +21,8 @@ #include +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/security/credentials/credentials.h" @@ -40,39 +42,59 @@ struct grpc_auth_property_array { size_t capacity = 0; }; -struct grpc_auth_context { - grpc_auth_context() { gpr_ref_init(&refcount, 0); } - - struct grpc_auth_context* chained = nullptr; - grpc_auth_property_array properties; - gpr_refcount refcount; - const char* peer_identity_property_name = nullptr; - grpc_pollset* pollset = nullptr; -}; - -/* Creation. */ -grpc_auth_context* grpc_auth_context_create(grpc_auth_context* chained); - -/* Refcounting. */ -#ifndef NDEBUG -#define GRPC_AUTH_CONTEXT_REF(p, r) \ - grpc_auth_context_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_AUTH_CONTEXT_UNREF(p, r) \ - grpc_auth_context_unref((p), __FILE__, __LINE__, (r)) -grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* policy, - const char* file, int line, - const char* reason); -void grpc_auth_context_unref(grpc_auth_context* policy, const char* file, - int line, const char* reason); -#else -#define GRPC_AUTH_CONTEXT_REF(p, r) grpc_auth_context_ref((p)) -#define GRPC_AUTH_CONTEXT_UNREF(p, r) grpc_auth_context_unref((p)) -grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* policy); -void grpc_auth_context_unref(grpc_auth_context* policy); -#endif - void grpc_auth_property_reset(grpc_auth_property* property); +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_auth_context + : public grpc_core::RefCounted { + public: + explicit grpc_auth_context( + grpc_core::RefCountedPtr chained) + : grpc_core::RefCounted( + &grpc_trace_auth_context_refcount), + chained_(std::move(chained)) { + if (chained_ != nullptr) { + peer_identity_property_name_ = chained_->peer_identity_property_name_; + } + } + + ~grpc_auth_context() { + chained_.reset(DEBUG_LOCATION, "chained"); + if (properties_.array != nullptr) { + for (size_t i = 0; i < properties_.count; i++) { + grpc_auth_property_reset(&properties_.array[i]); + } + gpr_free(properties_.array); + } + } + + const grpc_auth_context* chained() const { return chained_.get(); } + const grpc_auth_property_array& properties() const { return properties_; } + + bool is_authenticated() const { + return peer_identity_property_name_ != nullptr; + } + const char* peer_identity_property_name() const { + return peer_identity_property_name_; + } + void set_peer_identity_property_name(const char* name) { + peer_identity_property_name_ = name; + } + + void ensure_capacity(); + void add_property(const char* name, const char* value, size_t value_length); + void add_cstring_property(const char* name, const char* value); + + private: + grpc_core::RefCountedPtr chained_; + grpc_auth_property_array properties_; + const char* peer_identity_property_name_ = nullptr; +}; + /* --- grpc_security_context_extension --- Extension to the security context that may be set in a filter and accessed @@ -88,16 +110,18 @@ struct grpc_security_context_extension { Internal client-side security context. */ struct grpc_client_security_context { - grpc_client_security_context() = default; + explicit grpc_client_security_context( + grpc_core::RefCountedPtr creds) + : creds(std::move(creds)) {} ~grpc_client_security_context(); - grpc_call_credentials* creds = nullptr; - grpc_auth_context* auth_context = nullptr; + grpc_core::RefCountedPtr creds; + grpc_core::RefCountedPtr auth_context; grpc_security_context_extension extension; }; grpc_client_security_context* grpc_client_security_context_create( - gpr_arena* arena); + gpr_arena* arena, grpc_call_credentials* creds); void grpc_client_security_context_destroy(void* ctx); /* --- grpc_server_security_context --- @@ -108,7 +132,7 @@ struct grpc_server_security_context { grpc_server_security_context() = default; ~grpc_server_security_context(); - grpc_auth_context* auth_context = nullptr; + grpc_core::RefCountedPtr auth_context; grpc_security_context_extension extension; }; diff --git a/src/core/lib/security/credentials/alts/alts_credentials.cc b/src/core/lib/security/credentials/alts/alts_credentials.cc index 1fbef4ae0c7..06546492bc7 100644 --- a/src/core/lib/security/credentials/alts/alts_credentials.cc +++ b/src/core/lib/security/credentials/alts/alts_credentials.cc @@ -33,40 +33,47 @@ #define GRPC_CREDENTIALS_TYPE_ALTS "Alts" #define GRPC_ALTS_HANDSHAKER_SERVICE_URL "metadata.google.internal:8080" -static void alts_credentials_destruct(grpc_channel_credentials* creds) { - grpc_alts_credentials* alts_creds = - reinterpret_cast(creds); - grpc_alts_credentials_options_destroy(alts_creds->options); - gpr_free(alts_creds->handshaker_service_url); +grpc_alts_credentials::grpc_alts_credentials( + const grpc_alts_credentials_options* options, + const char* handshaker_service_url) + : grpc_channel_credentials(GRPC_CREDENTIALS_TYPE_ALTS), + options_(grpc_alts_credentials_options_copy(options)), + handshaker_service_url_(handshaker_service_url == nullptr + ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) + : gpr_strdup(handshaker_service_url)) {} + +grpc_alts_credentials::~grpc_alts_credentials() { + grpc_alts_credentials_options_destroy(options_); + gpr_free(handshaker_service_url_); } -static void alts_server_credentials_destruct(grpc_server_credentials* creds) { - grpc_alts_server_credentials* alts_creds = - reinterpret_cast(creds); - grpc_alts_credentials_options_destroy(alts_creds->options); - gpr_free(alts_creds->handshaker_service_url); -} - -static grpc_security_status alts_create_security_connector( - grpc_channel_credentials* creds, - grpc_call_credentials* request_metadata_creds, const char* target_name, - const grpc_channel_args* args, grpc_channel_security_connector** sc, +grpc_core::RefCountedPtr +grpc_alts_credentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target_name, const grpc_channel_args* args, grpc_channel_args** new_args) { return grpc_alts_channel_security_connector_create( - creds, request_metadata_creds, target_name, sc); + this->Ref(), std::move(call_creds), target_name); } -static grpc_security_status alts_server_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc) { - return grpc_alts_server_security_connector_create(creds, sc); +grpc_alts_server_credentials::grpc_alts_server_credentials( + const grpc_alts_credentials_options* options, + const char* handshaker_service_url) + : grpc_server_credentials(GRPC_CREDENTIALS_TYPE_ALTS), + options_(grpc_alts_credentials_options_copy(options)), + handshaker_service_url_(handshaker_service_url == nullptr + ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) + : gpr_strdup(handshaker_service_url)) {} + +grpc_core::RefCountedPtr +grpc_alts_server_credentials::create_security_connector() { + return grpc_alts_server_security_connector_create(this->Ref()); } -static const grpc_channel_credentials_vtable alts_credentials_vtable = { - alts_credentials_destruct, alts_create_security_connector, - /*duplicate_without_call_credentials=*/nullptr}; - -static const grpc_server_credentials_vtable alts_server_credentials_vtable = { - alts_server_credentials_destruct, alts_server_create_security_connector}; +grpc_alts_server_credentials::~grpc_alts_server_credentials() { + grpc_alts_credentials_options_destroy(options_); + gpr_free(handshaker_service_url_); +} grpc_channel_credentials* grpc_alts_credentials_create_customized( const grpc_alts_credentials_options* options, @@ -74,17 +81,7 @@ grpc_channel_credentials* grpc_alts_credentials_create_customized( if (!enable_untrusted_alts && !grpc_alts_is_running_on_gcp()) { return nullptr; } - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_alts_credentials))); - creds->options = grpc_alts_credentials_options_copy(options); - creds->handshaker_service_url = - handshaker_service_url == nullptr - ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) - : gpr_strdup(handshaker_service_url); - creds->base.type = GRPC_CREDENTIALS_TYPE_ALTS; - creds->base.vtable = &alts_credentials_vtable; - gpr_ref_init(&creds->base.refcount, 1); - return &creds->base; + return grpc_core::New(options, handshaker_service_url); } grpc_server_credentials* grpc_alts_server_credentials_create_customized( @@ -93,17 +90,8 @@ grpc_server_credentials* grpc_alts_server_credentials_create_customized( if (!enable_untrusted_alts && !grpc_alts_is_running_on_gcp()) { return nullptr; } - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_alts_server_credentials))); - creds->options = grpc_alts_credentials_options_copy(options); - creds->handshaker_service_url = - handshaker_service_url == nullptr - ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) - : gpr_strdup(handshaker_service_url); - creds->base.type = GRPC_CREDENTIALS_TYPE_ALTS; - creds->base.vtable = &alts_server_credentials_vtable; - gpr_ref_init(&creds->base.refcount, 1); - return &creds->base; + return grpc_core::New(options, + handshaker_service_url); } grpc_channel_credentials* grpc_alts_credentials_create( diff --git a/src/core/lib/security/credentials/alts/alts_credentials.h b/src/core/lib/security/credentials/alts/alts_credentials.h index 810117f2bea..cc6d5222b16 100644 --- a/src/core/lib/security/credentials/alts/alts_credentials.h +++ b/src/core/lib/security/credentials/alts/alts_credentials.h @@ -27,18 +27,45 @@ #include "src/core/lib/security/credentials/credentials.h" /* Main struct for grpc ALTS channel credential. */ -typedef struct grpc_alts_credentials { - grpc_channel_credentials base; - grpc_alts_credentials_options* options; - char* handshaker_service_url; -} grpc_alts_credentials; +class grpc_alts_credentials final : public grpc_channel_credentials { + public: + grpc_alts_credentials(const grpc_alts_credentials_options* options, + const char* handshaker_service_url); + ~grpc_alts_credentials() 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_alts_credentials_options* options() const { return options_; } + grpc_alts_credentials_options* mutable_options() { return options_; } + const char* handshaker_service_url() const { return handshaker_service_url_; } + + private: + grpc_alts_credentials_options* options_; + char* handshaker_service_url_; +}; /* Main struct for grpc ALTS server credential. */ -typedef struct grpc_alts_server_credentials { - grpc_server_credentials base; - grpc_alts_credentials_options* options; - char* handshaker_service_url; -} grpc_alts_server_credentials; +class grpc_alts_server_credentials final : public grpc_server_credentials { + public: + grpc_alts_server_credentials(const grpc_alts_credentials_options* options, + const char* handshaker_service_url); + ~grpc_alts_server_credentials() override; + + grpc_core::RefCountedPtr + create_security_connector() override; + + const grpc_alts_credentials_options* options() const { return options_; } + grpc_alts_credentials_options* mutable_options() { return options_; } + const char* handshaker_service_url() const { return handshaker_service_url_; } + + private: + grpc_alts_credentials_options* options_; + char* handshaker_service_url_; +}; /** * This method creates an ALTS channel credential object with customized diff --git a/src/core/lib/security/credentials/composite/composite_credentials.cc b/src/core/lib/security/credentials/composite/composite_credentials.cc index b8f409260f0..85dcd4693bc 100644 --- a/src/core/lib/security/credentials/composite/composite_credentials.cc +++ b/src/core/lib/security/credentials/composite/composite_credentials.cc @@ -20,8 +20,10 @@ #include "src/core/lib/security/credentials/composite/composite_credentials.h" -#include +#include +#include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/surface/api_trace.h" @@ -31,36 +33,83 @@ /* -- Composite call credentials. -- */ -typedef struct { +static void composite_call_metadata_cb(void* arg, grpc_error* error); + +grpc_call_credentials_array::~grpc_call_credentials_array() { + for (size_t i = 0; i < num_creds_; ++i) { + creds_array_[i].~RefCountedPtr(); + } + if (creds_array_ != nullptr) { + gpr_free(creds_array_); + } +} + +grpc_call_credentials_array::grpc_call_credentials_array( + const grpc_call_credentials_array& that) + : num_creds_(that.num_creds_) { + reserve(that.capacity_); + for (size_t i = 0; i < num_creds_; ++i) { + new (&creds_array_[i]) + grpc_core::RefCountedPtr(that.creds_array_[i]); + } +} + +void grpc_call_credentials_array::reserve(size_t capacity) { + if (capacity_ >= capacity) { + return; + } + grpc_core::RefCountedPtr* new_arr = + static_cast*>(gpr_malloc( + sizeof(grpc_core::RefCountedPtr) * capacity)); + if (creds_array_ != nullptr) { + for (size_t i = 0; i < num_creds_; ++i) { + new (&new_arr[i]) grpc_core::RefCountedPtr( + std::move(creds_array_[i])); + creds_array_[i].~RefCountedPtr(); + } + gpr_free(creds_array_); + } + creds_array_ = new_arr; + capacity_ = capacity; +} + +namespace { +struct grpc_composite_call_credentials_metadata_context { + grpc_composite_call_credentials_metadata_context( + grpc_composite_call_credentials* composite_creds, + grpc_polling_entity* pollent, grpc_auth_metadata_context auth_md_context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata) + : composite_creds(composite_creds), + pollent(pollent), + auth_md_context(auth_md_context), + md_array(md_array), + on_request_metadata(on_request_metadata) { + GRPC_CLOSURE_INIT(&internal_on_request_metadata, composite_call_metadata_cb, + this, grpc_schedule_on_exec_ctx); + } + grpc_composite_call_credentials* composite_creds; - size_t creds_index; + size_t creds_index = 0; grpc_polling_entity* pollent; grpc_auth_metadata_context auth_md_context; grpc_credentials_mdelem_array* md_array; grpc_closure* on_request_metadata; grpc_closure internal_on_request_metadata; -} grpc_composite_call_credentials_metadata_context; - -static void composite_call_destruct(grpc_call_credentials* creds) { - grpc_composite_call_credentials* c = - reinterpret_cast(creds); - for (size_t i = 0; i < c->inner.num_creds; i++) { - grpc_call_credentials_unref(c->inner.creds_array[i]); - } - gpr_free(c->inner.creds_array); -} +}; +} // namespace static void composite_call_metadata_cb(void* arg, grpc_error* error) { grpc_composite_call_credentials_metadata_context* ctx = static_cast(arg); if (error == GRPC_ERROR_NONE) { + const grpc_call_credentials_array& inner = ctx->composite_creds->inner(); /* See if we need to get some more metadata. */ - if (ctx->creds_index < ctx->composite_creds->inner.num_creds) { - grpc_call_credentials* inner_creds = - ctx->composite_creds->inner.creds_array[ctx->creds_index++]; - if (grpc_call_credentials_get_request_metadata( - inner_creds, ctx->pollent, ctx->auth_md_context, ctx->md_array, - &ctx->internal_on_request_metadata, &error)) { + if (ctx->creds_index < inner.size()) { + if (inner.get(ctx->creds_index++) + ->get_request_metadata( + ctx->pollent, ctx->auth_md_context, ctx->md_array, + &ctx->internal_on_request_metadata, &error)) { // Synchronous response, so call ourselves recursively. composite_call_metadata_cb(arg, error); GRPC_ERROR_UNREF(error); @@ -73,76 +122,86 @@ static void composite_call_metadata_cb(void* arg, grpc_error* error) { gpr_free(ctx); } -static bool composite_call_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context auth_md_context, +bool grpc_composite_call_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context auth_md_context, grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, grpc_error** error) { - grpc_composite_call_credentials* c = - reinterpret_cast(creds); grpc_composite_call_credentials_metadata_context* ctx; - ctx = static_cast( - gpr_zalloc(sizeof(grpc_composite_call_credentials_metadata_context))); - ctx->composite_creds = c; - ctx->pollent = pollent; - ctx->auth_md_context = auth_md_context; - ctx->md_array = md_array; - ctx->on_request_metadata = on_request_metadata; - GRPC_CLOSURE_INIT(&ctx->internal_on_request_metadata, - composite_call_metadata_cb, ctx, grpc_schedule_on_exec_ctx); + ctx = grpc_core::New( + this, pollent, auth_md_context, md_array, on_request_metadata); bool synchronous = true; - while (ctx->creds_index < ctx->composite_creds->inner.num_creds) { - grpc_call_credentials* inner_creds = - ctx->composite_creds->inner.creds_array[ctx->creds_index++]; - if (grpc_call_credentials_get_request_metadata( - inner_creds, ctx->pollent, ctx->auth_md_context, ctx->md_array, - &ctx->internal_on_request_metadata, error)) { + const grpc_call_credentials_array& inner = ctx->composite_creds->inner(); + while (ctx->creds_index < inner.size()) { + if (inner.get(ctx->creds_index++) + ->get_request_metadata(ctx->pollent, ctx->auth_md_context, + ctx->md_array, + &ctx->internal_on_request_metadata, error)) { if (*error != GRPC_ERROR_NONE) break; } else { synchronous = false; // Async return. break; } } - if (synchronous) gpr_free(ctx); + if (synchronous) grpc_core::Delete(ctx); return synchronous; } -static void composite_call_cancel_get_request_metadata( - grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { - grpc_composite_call_credentials* c = - reinterpret_cast(creds); - for (size_t i = 0; i < c->inner.num_creds; ++i) { - grpc_call_credentials_cancel_get_request_metadata( - c->inner.creds_array[i], md_array, GRPC_ERROR_REF(error)); +void grpc_composite_call_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { + for (size_t i = 0; i < inner_.size(); ++i) { + inner_.get(i)->cancel_get_request_metadata(md_array, GRPC_ERROR_REF(error)); } GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable composite_call_credentials_vtable = { - composite_call_destruct, composite_call_get_request_metadata, - composite_call_cancel_get_request_metadata}; +static size_t get_creds_array_size(const grpc_call_credentials* creds, + bool is_composite) { + return is_composite + ? static_cast(creds) + ->inner() + .size() + : 1; +} -static grpc_call_credentials_array get_creds_array( - grpc_call_credentials** creds_addr) { - grpc_call_credentials_array result; - grpc_call_credentials* creds = *creds_addr; - result.creds_array = creds_addr; - result.num_creds = 1; - if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) { - result = *grpc_composite_call_credentials_get_credentials(creds); +void grpc_composite_call_credentials::push_to_inner( + grpc_core::RefCountedPtr creds, bool is_composite) { + if (!is_composite) { + inner_.push_back(std::move(creds)); + return; } - return result; + auto composite_creds = + static_cast(creds.get()); + for (size_t i = 0; i < composite_creds->inner().size(); ++i) { + inner_.push_back(std::move(composite_creds->inner_.get_mutable(i))); + } +} + +grpc_composite_call_credentials::grpc_composite_call_credentials( + grpc_core::RefCountedPtr creds1, + grpc_core::RefCountedPtr creds2) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) { + const bool creds1_is_composite = + strcmp(creds1->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0; + const bool creds2_is_composite = + strcmp(creds2->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0; + const size_t size = get_creds_array_size(creds1.get(), creds1_is_composite) + + get_creds_array_size(creds2.get(), creds2_is_composite); + inner_.reserve(size); + push_to_inner(std::move(creds1), creds1_is_composite); + push_to_inner(std::move(creds2), creds2_is_composite); +} + +static grpc_core::RefCountedPtr +composite_call_credentials_create( + grpc_core::RefCountedPtr creds1, + grpc_core::RefCountedPtr creds2) { + return grpc_core::MakeRefCounted( + std::move(creds1), std::move(creds2)); } grpc_call_credentials* grpc_composite_call_credentials_create( grpc_call_credentials* creds1, grpc_call_credentials* creds2, void* reserved) { - size_t i; - size_t creds_array_byte_size; - grpc_call_credentials_array creds1_array; - grpc_call_credentials_array creds2_array; - grpc_composite_call_credentials* c; GRPC_API_TRACE( "grpc_composite_call_credentials_create(creds1=%p, creds2=%p, " "reserved=%p)", @@ -150,120 +209,40 @@ grpc_call_credentials* grpc_composite_call_credentials_create( GPR_ASSERT(reserved == nullptr); GPR_ASSERT(creds1 != nullptr); GPR_ASSERT(creds2 != nullptr); - c = static_cast( - gpr_zalloc(sizeof(grpc_composite_call_credentials))); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE; - c->base.vtable = &composite_call_credentials_vtable; - gpr_ref_init(&c->base.refcount, 1); - creds1_array = get_creds_array(&creds1); - creds2_array = get_creds_array(&creds2); - c->inner.num_creds = creds1_array.num_creds + creds2_array.num_creds; - creds_array_byte_size = c->inner.num_creds * sizeof(grpc_call_credentials*); - c->inner.creds_array = - static_cast(gpr_zalloc(creds_array_byte_size)); - for (i = 0; i < creds1_array.num_creds; i++) { - grpc_call_credentials* cur_creds = creds1_array.creds_array[i]; - c->inner.creds_array[i] = grpc_call_credentials_ref(cur_creds); - } - for (i = 0; i < creds2_array.num_creds; i++) { - grpc_call_credentials* cur_creds = creds2_array.creds_array[i]; - c->inner.creds_array[i + creds1_array.num_creds] = - grpc_call_credentials_ref(cur_creds); - } - return &c->base; -} -const grpc_call_credentials_array* -grpc_composite_call_credentials_get_credentials(grpc_call_credentials* creds) { - const grpc_composite_call_credentials* c = - reinterpret_cast(creds); - GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); - return &c->inner; -} - -grpc_call_credentials* grpc_credentials_contains_type( - grpc_call_credentials* creds, const char* type, - grpc_call_credentials** composite_creds) { - size_t i; - if (strcmp(creds->type, type) == 0) { - if (composite_creds != nullptr) *composite_creds = nullptr; - return creds; - } else if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) { - const grpc_call_credentials_array* inner_creds_array = - grpc_composite_call_credentials_get_credentials(creds); - for (i = 0; i < inner_creds_array->num_creds; i++) { - if (strcmp(type, inner_creds_array->creds_array[i]->type) == 0) { - if (composite_creds != nullptr) *composite_creds = creds; - return inner_creds_array->creds_array[i]; - } - } - } - return nullptr; + return composite_call_credentials_create(creds1->Ref(), creds2->Ref()) + .release(); } /* -- Composite channel credentials. -- */ -static void composite_channel_destruct(grpc_channel_credentials* creds) { - grpc_composite_channel_credentials* c = - reinterpret_cast(creds); - grpc_channel_credentials_unref(c->inner_creds); - grpc_call_credentials_unref(c->call_creds); -} - -static grpc_security_status composite_channel_create_security_connector( - grpc_channel_credentials* creds, grpc_call_credentials* call_creds, +grpc_core::RefCountedPtr +grpc_composite_channel_credentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - grpc_composite_channel_credentials* c = - reinterpret_cast(creds); - grpc_security_status status = GRPC_SECURITY_ERROR; - - GPR_ASSERT(c->inner_creds != nullptr && c->call_creds != nullptr && - c->inner_creds->vtable != nullptr && - c->inner_creds->vtable->create_security_connector != nullptr); + grpc_channel_args** new_args) { + GPR_ASSERT(inner_creds_ != nullptr && call_creds_ != nullptr); /* If we are passed a call_creds, create a call composite to pass it downstream. */ if (call_creds != nullptr) { - grpc_call_credentials* composite_call_creds = - grpc_composite_call_credentials_create(c->call_creds, call_creds, - nullptr); - status = c->inner_creds->vtable->create_security_connector( - c->inner_creds, composite_call_creds, target, args, sc, new_args); - grpc_call_credentials_unref(composite_call_creds); + return inner_creds_->create_security_connector( + composite_call_credentials_create(call_creds_, std::move(call_creds)), + target, args, new_args); } else { - status = c->inner_creds->vtable->create_security_connector( - c->inner_creds, c->call_creds, target, args, sc, new_args); + return inner_creds_->create_security_connector(call_creds_, target, args, + new_args); } - return status; } -static grpc_channel_credentials* -composite_channel_duplicate_without_call_credentials( - grpc_channel_credentials* creds) { - grpc_composite_channel_credentials* c = - reinterpret_cast(creds); - return grpc_channel_credentials_ref(c->inner_creds); -} - -static grpc_channel_credentials_vtable composite_channel_credentials_vtable = { - composite_channel_destruct, composite_channel_create_security_connector, - composite_channel_duplicate_without_call_credentials}; - grpc_channel_credentials* grpc_composite_channel_credentials_create( grpc_channel_credentials* channel_creds, grpc_call_credentials* call_creds, void* reserved) { - grpc_composite_channel_credentials* c = - static_cast(gpr_zalloc(sizeof(*c))); GPR_ASSERT(channel_creds != nullptr && call_creds != nullptr && reserved == nullptr); GRPC_API_TRACE( "grpc_composite_channel_credentials_create(channel_creds=%p, " "call_creds=%p, reserved=%p)", 3, (channel_creds, call_creds, reserved)); - c->base.type = channel_creds->type; - c->base.vtable = &composite_channel_credentials_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->inner_creds = grpc_channel_credentials_ref(channel_creds); - c->call_creds = grpc_call_credentials_ref(call_creds); - return &c->base; + return grpc_core::New( + channel_creds->Ref(), call_creds->Ref()); } diff --git a/src/core/lib/security/credentials/composite/composite_credentials.h b/src/core/lib/security/credentials/composite/composite_credentials.h index a952ad57f1e..6b7fca13708 100644 --- a/src/core/lib/security/credentials/composite/composite_credentials.h +++ b/src/core/lib/security/credentials/composite/composite_credentials.h @@ -21,39 +21,104 @@ #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/credentials/credentials.h" -typedef struct { - grpc_call_credentials** creds_array; - size_t num_creds; -} grpc_call_credentials_array; +// TODO(soheil): Replace this with InlinedVector once #16032 is resolved. +class grpc_call_credentials_array { + public: + grpc_call_credentials_array() = default; + grpc_call_credentials_array(const grpc_call_credentials_array& that); -const grpc_call_credentials_array* -grpc_composite_call_credentials_get_credentials( - grpc_call_credentials* composite_creds); + ~grpc_call_credentials_array(); -/* Returns creds if creds is of the specified type or the inner creds of the - specified type (if found), if the creds is of type COMPOSITE. - If composite_creds is not NULL, *composite_creds will point to creds if of - type COMPOSITE in case of success. */ -grpc_call_credentials* grpc_credentials_contains_type( - grpc_call_credentials* creds, const char* type, - grpc_call_credentials** composite_creds); + void reserve(size_t capacity); + + // Must reserve before pushing any data. + void push_back(grpc_core::RefCountedPtr cred) { + GPR_DEBUG_ASSERT(capacity_ > num_creds_); + new (&creds_array_[num_creds_++]) + grpc_core::RefCountedPtr(std::move(cred)); + } + + const grpc_core::RefCountedPtr& get(size_t i) const { + GPR_DEBUG_ASSERT(i < num_creds_); + return creds_array_[i]; + } + grpc_core::RefCountedPtr& get_mutable(size_t i) { + GPR_DEBUG_ASSERT(i < num_creds_); + return creds_array_[i]; + } + + size_t size() const { return num_creds_; } + + private: + grpc_core::RefCountedPtr* creds_array_ = nullptr; + size_t num_creds_ = 0; + size_t capacity_ = 0; +}; /* -- Composite channel credentials. -- */ -typedef struct { - grpc_channel_credentials base; - grpc_channel_credentials* inner_creds; - grpc_call_credentials* call_creds; -} grpc_composite_channel_credentials; +class grpc_composite_channel_credentials : public grpc_channel_credentials { + public: + grpc_composite_channel_credentials( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr call_creds) + : grpc_channel_credentials(channel_creds->type()), + inner_creds_(std::move(channel_creds)), + call_creds_(std::move(call_creds)) {} + + ~grpc_composite_channel_credentials() override = default; + + grpc_core::RefCountedPtr + duplicate_without_call_credentials() override { + return inner_creds_; + } + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + const grpc_channel_credentials* inner_creds() const { + return inner_creds_.get(); + } + const grpc_call_credentials* call_creds() const { return call_creds_.get(); } + grpc_call_credentials* mutable_call_creds() { return call_creds_.get(); } + + private: + grpc_core::RefCountedPtr inner_creds_; + grpc_core::RefCountedPtr call_creds_; +}; /* -- Composite call credentials. -- */ -typedef struct { - grpc_call_credentials base; - grpc_call_credentials_array inner; -} grpc_composite_call_credentials; +class grpc_composite_call_credentials : public grpc_call_credentials { + public: + grpc_composite_call_credentials( + grpc_core::RefCountedPtr creds1, + grpc_core::RefCountedPtr creds2); + ~grpc_composite_call_credentials() override = default; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + const grpc_call_credentials_array& inner() const { return inner_; } + + private: + void push_to_inner(grpc_core::RefCountedPtr creds, + bool is_composite); + + grpc_call_credentials_array inner_; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_COMPOSITE_COMPOSITE_CREDENTIALS_H \ */ diff --git a/src/core/lib/security/credentials/credentials.cc b/src/core/lib/security/credentials/credentials.cc index c43cb440ebf..90452d68d61 100644 --- a/src/core/lib/security/credentials/credentials.cc +++ b/src/core/lib/security/credentials/credentials.cc @@ -39,120 +39,24 @@ /* -- Common. -- */ -grpc_credentials_metadata_request* grpc_credentials_metadata_request_create( - grpc_call_credentials* creds) { - grpc_credentials_metadata_request* r = - static_cast( - gpr_zalloc(sizeof(grpc_credentials_metadata_request))); - r->creds = grpc_call_credentials_ref(creds); - return r; -} - -void grpc_credentials_metadata_request_destroy( - grpc_credentials_metadata_request* r) { - grpc_call_credentials_unref(r->creds); - grpc_http_response_destroy(&r->response); - gpr_free(r); -} - -grpc_channel_credentials* grpc_channel_credentials_ref( - grpc_channel_credentials* creds) { - if (creds == nullptr) return nullptr; - gpr_ref(&creds->refcount); - return creds; -} - -void grpc_channel_credentials_unref(grpc_channel_credentials* creds) { - if (creds == nullptr) return; - if (gpr_unref(&creds->refcount)) { - if (creds->vtable->destruct != nullptr) { - creds->vtable->destruct(creds); - } - gpr_free(creds); - } -} - void grpc_channel_credentials_release(grpc_channel_credentials* creds) { GRPC_API_TRACE("grpc_channel_credentials_release(creds=%p)", 1, (creds)); grpc_core::ExecCtx exec_ctx; - grpc_channel_credentials_unref(creds); -} - -grpc_call_credentials* grpc_call_credentials_ref(grpc_call_credentials* creds) { - if (creds == nullptr) return nullptr; - gpr_ref(&creds->refcount); - return creds; -} - -void grpc_call_credentials_unref(grpc_call_credentials* creds) { - if (creds == nullptr) return; - if (gpr_unref(&creds->refcount)) { - if (creds->vtable->destruct != nullptr) { - creds->vtable->destruct(creds); - } - gpr_free(creds); - } + if (creds) creds->Unref(); } void grpc_call_credentials_release(grpc_call_credentials* creds) { GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds)); grpc_core::ExecCtx exec_ctx; - grpc_call_credentials_unref(creds); -} - -bool grpc_call_credentials_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error) { - if (creds == nullptr || creds->vtable->get_request_metadata == nullptr) { - return true; - } - return creds->vtable->get_request_metadata(creds, pollent, context, md_array, - on_request_metadata, error); -} - -void grpc_call_credentials_cancel_get_request_metadata( - grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { - if (creds == nullptr || - creds->vtable->cancel_get_request_metadata == nullptr) { - return; - } - creds->vtable->cancel_get_request_metadata(creds, md_array, error); -} - -grpc_security_status grpc_channel_credentials_create_security_connector( - grpc_channel_credentials* channel_creds, const char* target, - const grpc_channel_args* args, grpc_channel_security_connector** sc, - grpc_channel_args** new_args) { - *new_args = nullptr; - if (channel_creds == nullptr) { - return GRPC_SECURITY_ERROR; - } - GPR_ASSERT(channel_creds->vtable->create_security_connector != nullptr); - return channel_creds->vtable->create_security_connector( - channel_creds, nullptr, target, args, sc, new_args); -} - -grpc_channel_credentials* -grpc_channel_credentials_duplicate_without_call_credentials( - grpc_channel_credentials* channel_creds) { - if (channel_creds != nullptr && channel_creds->vtable != nullptr && - channel_creds->vtable->duplicate_without_call_credentials != nullptr) { - return channel_creds->vtable->duplicate_without_call_credentials( - channel_creds); - } else { - return grpc_channel_credentials_ref(channel_creds); - } + if (creds) creds->Unref(); } static void credentials_pointer_arg_destroy(void* p) { - grpc_channel_credentials_unref(static_cast(p)); + static_cast(p)->Unref(); } static void* credentials_pointer_arg_copy(void* p) { - return grpc_channel_credentials_ref( - static_cast(p)); + return static_cast(p)->Ref().release(); } static int credentials_pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); } @@ -191,63 +95,35 @@ grpc_channel_credentials* grpc_channel_credentials_find_in_args( return nullptr; } -grpc_server_credentials* grpc_server_credentials_ref( - grpc_server_credentials* creds) { - if (creds == nullptr) return nullptr; - gpr_ref(&creds->refcount); - return creds; -} - -void grpc_server_credentials_unref(grpc_server_credentials* creds) { - if (creds == nullptr) return; - if (gpr_unref(&creds->refcount)) { - if (creds->vtable->destruct != nullptr) { - creds->vtable->destruct(creds); - } - if (creds->processor.destroy != nullptr && - creds->processor.state != nullptr) { - creds->processor.destroy(creds->processor.state); - } - gpr_free(creds); - } -} - void grpc_server_credentials_release(grpc_server_credentials* creds) { GRPC_API_TRACE("grpc_server_credentials_release(creds=%p)", 1, (creds)); grpc_core::ExecCtx exec_ctx; - grpc_server_credentials_unref(creds); + if (creds) creds->Unref(); } -grpc_security_status grpc_server_credentials_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc) { - if (creds == nullptr || creds->vtable->create_security_connector == nullptr) { - gpr_log(GPR_ERROR, "Server credentials cannot create security context."); - return GRPC_SECURITY_ERROR; - } - return creds->vtable->create_security_connector(creds, sc); -} - -void grpc_server_credentials_set_auth_metadata_processor( - grpc_server_credentials* creds, grpc_auth_metadata_processor processor) { +void grpc_server_credentials::set_auth_metadata_processor( + const grpc_auth_metadata_processor& processor) { GRPC_API_TRACE( "grpc_server_credentials_set_auth_metadata_processor(" "creds=%p, " "processor=grpc_auth_metadata_processor { process: %p, state: %p })", - 3, (creds, (void*)(intptr_t)processor.process, processor.state)); - if (creds == nullptr) return; - if (creds->processor.destroy != nullptr && - creds->processor.state != nullptr) { - creds->processor.destroy(creds->processor.state); - } - creds->processor = processor; + 3, (this, (void*)(intptr_t)processor.process, processor.state)); + DestroyProcessor(); + processor_ = processor; +} + +void grpc_server_credentials_set_auth_metadata_processor( + grpc_server_credentials* creds, grpc_auth_metadata_processor processor) { + GPR_DEBUG_ASSERT(creds != nullptr); + creds->set_auth_metadata_processor(processor); } static void server_credentials_pointer_arg_destroy(void* p) { - grpc_server_credentials_unref(static_cast(p)); + static_cast(p)->Unref(); } static void* server_credentials_pointer_arg_copy(void* p) { - return grpc_server_credentials_ref(static_cast(p)); + return static_cast(p)->Ref().release(); } static int server_credentials_pointer_cmp(void* a, void* b) { diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h index 3878958b38b..4091ef3dfb5 100644 --- a/src/core/lib/security/credentials/credentials.h +++ b/src/core/lib/security/credentials/credentials.h @@ -26,6 +26,7 @@ #include #include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/http/httpcli.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/polling_entity.h" @@ -90,44 +91,46 @@ void grpc_override_well_known_credentials_path_getter( #define GRPC_ARG_CHANNEL_CREDENTIALS "grpc.channel_credentials" -typedef struct { - void (*destruct)(grpc_channel_credentials* c); +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_channel_credentials + : grpc_core::RefCounted { + public: + explicit grpc_channel_credentials(const char* type) : type_(type) {} + virtual ~grpc_channel_credentials() = default; - grpc_security_status (*create_security_connector)( - grpc_channel_credentials* c, grpc_call_credentials* call_creds, + // Creates a security connector for the channel. May also create new channel + // args for the channel to be used in place of the passed in const args if + // returned non NULL. In that case the caller is responsible for destroying + // new_args after channel creation. + virtual grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args); + grpc_channel_args** new_args) { + // Tell clang-tidy that call_creds cannot be passed as const-ref. + call_creds.reset(); + GRPC_ABSTRACT; + } - grpc_channel_credentials* (*duplicate_without_call_credentials)( - grpc_channel_credentials* c); -} grpc_channel_credentials_vtable; + // Creates a version of the channel credentials without any attached call + // credentials. This can be used in order to open a channel to a non-trusted + // gRPC load balancer. + virtual grpc_core::RefCountedPtr + duplicate_without_call_credentials() { + // By default we just increment the refcount. + return Ref(); + } -struct grpc_channel_credentials { - const grpc_channel_credentials_vtable* vtable; - const char* type; - gpr_refcount refcount; + const char* type() const { return type_; } + + GRPC_ABSTRACT_BASE_CLASS + + private: + const char* type_; }; -grpc_channel_credentials* grpc_channel_credentials_ref( - grpc_channel_credentials* creds); -void grpc_channel_credentials_unref(grpc_channel_credentials* creds); - -/* Creates a security connector for the channel. May also create new channel - args for the channel to be used in place of the passed in const args if - returned non NULL. In that case the caller is responsible for destroying - new_args after channel creation. */ -grpc_security_status grpc_channel_credentials_create_security_connector( - grpc_channel_credentials* creds, const char* target, - const grpc_channel_args* args, grpc_channel_security_connector** sc, - grpc_channel_args** new_args); - -/* Creates a version of the channel credentials without any attached call - credentials. This can be used in order to open a channel to a non-trusted - gRPC load balancer. */ -grpc_channel_credentials* -grpc_channel_credentials_duplicate_without_call_credentials( - grpc_channel_credentials* creds); - /* Util to encapsulate the channel credentials in a channel arg. */ grpc_arg grpc_channel_credentials_to_arg(grpc_channel_credentials* credentials); @@ -158,44 +161,39 @@ void grpc_credentials_mdelem_array_destroy(grpc_credentials_mdelem_array* list); /* --- grpc_call_credentials. --- */ -typedef struct { - void (*destruct)(grpc_call_credentials* c); - bool (*get_request_metadata)(grpc_call_credentials* c, - grpc_polling_entity* pollent, - grpc_auth_metadata_context context, - grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, - grpc_error** error); - void (*cancel_get_request_metadata)(grpc_call_credentials* c, - grpc_credentials_mdelem_array* md_array, - grpc_error* error); -} grpc_call_credentials_vtable; +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_call_credentials + : public grpc_core::RefCounted { + public: + explicit grpc_call_credentials(const char* type) : type_(type) {} + virtual ~grpc_call_credentials() = default; -struct grpc_call_credentials { - const grpc_call_credentials_vtable* vtable; - const char* type; - gpr_refcount refcount; + // Returns true if completed synchronously, in which case \a error will + // be set to indicate the result. Otherwise, \a on_request_metadata will + // be invoked asynchronously when complete. \a md_array will be populated + // with the resulting metadata once complete. + virtual bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) GRPC_ABSTRACT; + + // Cancels a pending asynchronous operation started by + // grpc_call_credentials_get_request_metadata() with the corresponding + // value of \a md_array. + virtual void cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) GRPC_ABSTRACT; + + const char* type() const { return type_; } + + GRPC_ABSTRACT_BASE_CLASS + + private: + const char* type_; }; -grpc_call_credentials* grpc_call_credentials_ref(grpc_call_credentials* creds); -void grpc_call_credentials_unref(grpc_call_credentials* creds); - -/// Returns true if completed synchronously, in which case \a error will -/// be set to indicate the result. Otherwise, \a on_request_metadata will -/// be invoked asynchronously when complete. \a md_array will be populated -/// with the resulting metadata once complete. -bool grpc_call_credentials_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error); - -/// Cancels a pending asynchronous operation started by -/// grpc_call_credentials_get_request_metadata() with the corresponding -/// value of \a md_array. -void grpc_call_credentials_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error); - /* Metadata-only credentials with the specified key and value where asynchronicity can be simulated for testing. */ grpc_call_credentials* grpc_md_only_test_credentials_create( @@ -203,27 +201,41 @@ grpc_call_credentials* grpc_md_only_test_credentials_create( /* --- grpc_server_credentials. --- */ -typedef struct { - void (*destruct)(grpc_server_credentials* c); - grpc_security_status (*create_security_connector)( - grpc_server_credentials* c, grpc_server_security_connector** sc); -} grpc_server_credentials_vtable; +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_server_credentials + : public grpc_core::RefCounted { + public: + explicit grpc_server_credentials(const char* type) : type_(type) {} -struct grpc_server_credentials { - const grpc_server_credentials_vtable* vtable; - const char* type; - gpr_refcount refcount; - grpc_auth_metadata_processor processor; + virtual ~grpc_server_credentials() { DestroyProcessor(); } + + virtual grpc_core::RefCountedPtr + create_security_connector() GRPC_ABSTRACT; + + const char* type() const { return type_; } + + const grpc_auth_metadata_processor& auth_metadata_processor() const { + return processor_; + } + void set_auth_metadata_processor( + const grpc_auth_metadata_processor& processor); + + GRPC_ABSTRACT_BASE_CLASS + + private: + void DestroyProcessor() { + if (processor_.destroy != nullptr && processor_.state != nullptr) { + processor_.destroy(processor_.state); + } + } + + const char* type_; + grpc_auth_metadata_processor processor_ = + grpc_auth_metadata_processor(); // Zero-initialize the C struct. }; -grpc_security_status grpc_server_credentials_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc); - -grpc_server_credentials* grpc_server_credentials_ref( - grpc_server_credentials* creds); - -void grpc_server_credentials_unref(grpc_server_credentials* creds); - #define GRPC_SERVER_CREDENTIALS_ARG "grpc.server_credentials" grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials* c); @@ -233,15 +245,27 @@ grpc_server_credentials* grpc_find_server_credentials_in_args( /* -- Credentials Metadata Request. -- */ -typedef struct { - grpc_call_credentials* creds; +struct grpc_credentials_metadata_request { + explicit grpc_credentials_metadata_request( + grpc_core::RefCountedPtr creds) + : creds(std::move(creds)) {} + ~grpc_credentials_metadata_request() { + grpc_http_response_destroy(&response); + } + + grpc_core::RefCountedPtr creds; grpc_http_response response; -} grpc_credentials_metadata_request; +}; -grpc_credentials_metadata_request* grpc_credentials_metadata_request_create( - grpc_call_credentials* creds); +inline grpc_credentials_metadata_request* +grpc_credentials_metadata_request_create( + grpc_core::RefCountedPtr creds) { + return grpc_core::New(std::move(creds)); +} -void grpc_credentials_metadata_request_destroy( - grpc_credentials_metadata_request* r); +inline void grpc_credentials_metadata_request_destroy( + grpc_credentials_metadata_request* r) { + grpc_core::Delete(r); +} #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/fake/fake_credentials.cc b/src/core/lib/security/credentials/fake/fake_credentials.cc index d3e0e8c8168..337dd7679fd 100644 --- a/src/core/lib/security/credentials/fake/fake_credentials.cc +++ b/src/core/lib/security/credentials/fake/fake_credentials.cc @@ -33,49 +33,45 @@ /* -- Fake transport security credentials. -- */ -static grpc_security_status fake_transport_security_create_security_connector( - grpc_channel_credentials* c, grpc_call_credentials* call_creds, - const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - *sc = - grpc_fake_channel_security_connector_create(c, call_creds, target, args); - return GRPC_SECURITY_OK; +namespace { +class grpc_fake_channel_credentials final : public grpc_channel_credentials { + public: + grpc_fake_channel_credentials() + : grpc_channel_credentials( + GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY) {} + ~grpc_fake_channel_credentials() override = default; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override { + return grpc_fake_channel_security_connector_create( + this->Ref(), std::move(call_creds), target, args); + } +}; + +class grpc_fake_server_credentials final : public grpc_server_credentials { + public: + grpc_fake_server_credentials() + : grpc_server_credentials( + GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY) {} + ~grpc_fake_server_credentials() override = default; + + grpc_core::RefCountedPtr + create_security_connector() override { + return grpc_fake_server_security_connector_create(this->Ref()); + } +}; +} // namespace + +grpc_channel_credentials* grpc_fake_transport_security_credentials_create() { + return grpc_core::New(); } -static grpc_security_status -fake_transport_security_server_create_security_connector( - grpc_server_credentials* c, grpc_server_security_connector** sc) { - *sc = grpc_fake_server_security_connector_create(c); - return GRPC_SECURITY_OK; -} - -static grpc_channel_credentials_vtable - fake_transport_security_credentials_vtable = { - nullptr, fake_transport_security_create_security_connector, nullptr}; - -static grpc_server_credentials_vtable - fake_transport_security_server_credentials_vtable = { - nullptr, fake_transport_security_server_create_security_connector}; - -grpc_channel_credentials* grpc_fake_transport_security_credentials_create( - void) { - grpc_channel_credentials* c = static_cast( - gpr_zalloc(sizeof(grpc_channel_credentials))); - c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY; - c->vtable = &fake_transport_security_credentials_vtable; - gpr_ref_init(&c->refcount, 1); - return c; -} - -grpc_server_credentials* grpc_fake_transport_security_server_credentials_create( - void) { - grpc_server_credentials* c = static_cast( - gpr_malloc(sizeof(grpc_server_credentials))); - memset(c, 0, sizeof(grpc_server_credentials)); - c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY; - gpr_ref_init(&c->refcount, 1); - c->vtable = &fake_transport_security_server_credentials_vtable; - return c; +grpc_server_credentials* +grpc_fake_transport_security_server_credentials_create() { + return grpc_core::New(); } grpc_arg grpc_fake_transport_expected_targets_arg(char* expected_targets) { @@ -92,46 +88,25 @@ const char* grpc_fake_transport_get_expected_targets( /* -- Metadata-only test credentials. -- */ -static void md_only_test_destruct(grpc_call_credentials* creds) { - grpc_md_only_test_credentials* c = - reinterpret_cast(creds); - GRPC_MDELEM_UNREF(c->md); -} - -static bool md_only_test_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error) { - grpc_md_only_test_credentials* c = - reinterpret_cast(creds); - grpc_credentials_mdelem_array_add(md_array, c->md); - if (c->is_async) { +bool grpc_md_only_test_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { + grpc_credentials_mdelem_array_add(md_array, md_); + if (is_async_) { GRPC_CLOSURE_SCHED(on_request_metadata, GRPC_ERROR_NONE); return false; } return true; } -static void md_only_test_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { +void grpc_md_only_test_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable md_only_test_vtable = { - md_only_test_destruct, md_only_test_get_request_metadata, - md_only_test_cancel_get_request_metadata}; - grpc_call_credentials* grpc_md_only_test_credentials_create( const char* md_key, const char* md_value, bool is_async) { - grpc_md_only_test_credentials* c = - static_cast( - gpr_zalloc(sizeof(grpc_md_only_test_credentials))); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; - c->base.vtable = &md_only_test_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->md = grpc_mdelem_from_slices(grpc_slice_from_copied_string(md_key), - grpc_slice_from_copied_string(md_value)); - c->is_async = is_async; - return &c->base; + return grpc_core::New(md_key, md_value, + is_async); } diff --git a/src/core/lib/security/credentials/fake/fake_credentials.h b/src/core/lib/security/credentials/fake/fake_credentials.h index e89e6e24cca..b7f6a1909fc 100644 --- a/src/core/lib/security/credentials/fake/fake_credentials.h +++ b/src/core/lib/security/credentials/fake/fake_credentials.h @@ -55,10 +55,28 @@ const char* grpc_fake_transport_get_expected_targets( /* -- Metadata-only Test credentials. -- */ -typedef struct { - grpc_call_credentials base; - grpc_mdelem md; - bool is_async; -} grpc_md_only_test_credentials; +class grpc_md_only_test_credentials : public grpc_call_credentials { + public: + grpc_md_only_test_credentials(const char* md_key, const char* md_value, + bool is_async) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_OAUTH2), + md_(grpc_mdelem_from_slices(grpc_slice_from_copied_string(md_key), + grpc_slice_from_copied_string(md_value))), + is_async_(is_async) {} + ~grpc_md_only_test_credentials() override { GRPC_MDELEM_UNREF(md_); } + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + private: + grpc_mdelem md_; + bool is_async_; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_FAKE_FAKE_CREDENTIALS_H */ 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 0674540d01c..a86a17d5864 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 @@ -30,6 +30,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/http/httpcli.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/load_file.h" @@ -72,20 +73,11 @@ typedef struct { grpc_http_response response; } metadata_server_detector; -static void google_default_credentials_destruct( - grpc_channel_credentials* creds) { - grpc_google_default_channel_credentials* c = - reinterpret_cast(creds); - grpc_channel_credentials_unref(c->alts_creds); - grpc_channel_credentials_unref(c->ssl_creds); -} - -static grpc_security_status google_default_create_security_connector( - grpc_channel_credentials* creds, grpc_call_credentials* call_creds, +grpc_core::RefCountedPtr +grpc_google_default_channel_credentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - grpc_google_default_channel_credentials* c = - reinterpret_cast(creds); + grpc_channel_args** new_args) { bool is_grpclb_load_balancer = grpc_channel_arg_get_bool( grpc_channel_args_find(args, GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER), false); @@ -95,22 +87,22 @@ static grpc_security_status google_default_create_security_connector( false); bool use_alts = is_grpclb_load_balancer || is_backend_from_grpclb_load_balancer; - grpc_security_status status = GRPC_SECURITY_ERROR; /* Return failure if ALTS is selected but not running on GCE. */ if (use_alts && !g_is_on_gce) { gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE."); - goto end; + return nullptr; } - status = use_alts ? c->alts_creds->vtable->create_security_connector( - c->alts_creds, call_creds, target, args, sc, new_args) - : c->ssl_creds->vtable->create_security_connector( - c->ssl_creds, call_creds, target, args, sc, new_args); -/* grpclb-specific channel args are removed from the channel args set - * to ensure backends and fallback adresses will have the same set of channel - * args. By doing that, it guarantees the connections to backends will not be - * torn down and re-connected when switching in and out of fallback mode. - */ -end: + + grpc_core::RefCountedPtr sc = + use_alts ? alts_creds_->create_security_connector(call_creds, target, + args, new_args) + : ssl_creds_->create_security_connector(call_creds, target, args, + new_args); + /* grpclb-specific channel args are removed from the channel args set + * to ensure backends and fallback adresses will have the same set of channel + * args. By doing that, it guarantees the connections to backends will not be + * torn down and re-connected when switching in and out of fallback mode. + */ if (use_alts) { static const char* args_to_remove[] = { GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER, @@ -119,13 +111,9 @@ end: *new_args = grpc_channel_args_copy_and_add_and_remove( args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), nullptr, 0); } - return status; + return sc; } -static grpc_channel_credentials_vtable google_default_credentials_vtable = { - google_default_credentials_destruct, - google_default_create_security_connector, nullptr}; - static void on_metadata_server_detection_http_response(void* user_data, grpc_error* error) { metadata_server_detector* detector = @@ -215,11 +203,11 @@ static int is_metadata_server_reachable() { /* Takes ownership of creds_path if not NULL. */ static grpc_error* create_default_creds_from_path( - char* creds_path, grpc_call_credentials** creds) { + char* creds_path, grpc_core::RefCountedPtr* creds) { grpc_json* json = nullptr; grpc_auth_json_key key; grpc_auth_refresh_token token; - grpc_call_credentials* result = nullptr; + grpc_core::RefCountedPtr result; grpc_slice creds_data = grpc_empty_slice(); grpc_error* error = GRPC_ERROR_NONE; if (creds_path == nullptr) { @@ -276,9 +264,9 @@ end: return error; } -grpc_channel_credentials* grpc_google_default_credentials_create(void) { +grpc_channel_credentials* grpc_google_default_credentials_create() { grpc_channel_credentials* result = nullptr; - grpc_call_credentials* call_creds = nullptr; + grpc_core::RefCountedPtr call_creds; grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Failed to create Google credentials"); grpc_error* err; @@ -316,7 +304,8 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) { gpr_mu_unlock(&g_state_mu); if (g_metadata_server_available) { - call_creds = grpc_google_compute_engine_credentials_create(nullptr); + call_creds = grpc_core::RefCountedPtr( + grpc_google_compute_engine_credentials_create(nullptr)); if (call_creds == nullptr) { error = grpc_error_add_child( error, GRPC_ERROR_CREATE_FROM_STATIC_STRING( @@ -327,23 +316,23 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) { end: if (call_creds != nullptr) { /* Create google default credentials. */ - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_google_default_channel_credentials))); - creds->base.vtable = &google_default_credentials_vtable; - creds->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_GOOGLE_DEFAULT; - gpr_ref_init(&creds->base.refcount, 1); - creds->ssl_creds = + grpc_channel_credentials* ssl_creds = grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr); - GPR_ASSERT(creds->ssl_creds != nullptr); + GPR_ASSERT(ssl_creds != nullptr); grpc_alts_credentials_options* options = grpc_alts_credentials_client_options_create(); - creds->alts_creds = grpc_alts_credentials_create(options); + grpc_channel_credentials* alts_creds = + grpc_alts_credentials_create(options); grpc_alts_credentials_options_destroy(options); - result = grpc_composite_channel_credentials_create(&creds->base, call_creds, - nullptr); + auto creds = + grpc_core::MakeRefCounted( + alts_creds != nullptr ? alts_creds->Ref() : nullptr, + ssl_creds != nullptr ? ssl_creds->Ref() : nullptr); + if (ssl_creds) ssl_creds->Unref(); + if (alts_creds) alts_creds->Unref(); + result = grpc_composite_channel_credentials_create( + creds.get(), call_creds.get(), nullptr); GPR_ASSERT(result != nullptr); - grpc_channel_credentials_unref(&creds->base); - grpc_call_credentials_unref(call_creds); } else { gpr_log(GPR_ERROR, "Could not create google default credentials: %s", grpc_error_string(error)); 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 b9e2efb04fa..bf00f7285ad 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 @@ -21,6 +21,7 @@ #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/credentials/credentials.h" #define GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY "gcloud" @@ -39,11 +40,33 @@ "/" GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE #endif -typedef struct { - grpc_channel_credentials base; - grpc_channel_credentials* alts_creds; - grpc_channel_credentials* ssl_creds; -} grpc_google_default_channel_credentials; +class grpc_google_default_channel_credentials + : public grpc_channel_credentials { + public: + grpc_google_default_channel_credentials( + grpc_core::RefCountedPtr alts_creds, + grpc_core::RefCountedPtr ssl_creds) + : grpc_channel_credentials(GRPC_CHANNEL_CREDENTIALS_TYPE_GOOGLE_DEFAULT), + alts_creds_(std::move(alts_creds)), + ssl_creds_(std::move(ssl_creds)) {} + + ~grpc_google_default_channel_credentials() override = default; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + const grpc_channel_credentials* alts_creds() const { + return alts_creds_.get(); + } + const grpc_channel_credentials* ssl_creds() const { return ssl_creds_.get(); } + + private: + grpc_core::RefCountedPtr alts_creds_; + grpc_core::RefCountedPtr ssl_creds_; +}; namespace grpc_core { namespace internal { diff --git a/src/core/lib/security/credentials/iam/iam_credentials.cc b/src/core/lib/security/credentials/iam/iam_credentials.cc index 5d92fa88c45..5cd561f676a 100644 --- a/src/core/lib/security/credentials/iam/iam_credentials.cc +++ b/src/core/lib/security/credentials/iam/iam_credentials.cc @@ -22,6 +22,7 @@ #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/surface/api_trace.h" #include @@ -29,32 +30,37 @@ #include #include -static void iam_destruct(grpc_call_credentials* creds) { - grpc_google_iam_credentials* c = - reinterpret_cast(creds); - grpc_credentials_mdelem_array_destroy(&c->md_array); +grpc_google_iam_credentials::~grpc_google_iam_credentials() { + grpc_credentials_mdelem_array_destroy(&md_array_); } -static bool iam_get_request_metadata(grpc_call_credentials* creds, - grpc_polling_entity* pollent, - grpc_auth_metadata_context context, - grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, - grpc_error** error) { - grpc_google_iam_credentials* c = - reinterpret_cast(creds); - grpc_credentials_mdelem_array_append(md_array, &c->md_array); +bool grpc_google_iam_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { + grpc_credentials_mdelem_array_append(md_array, &md_array_); return true; } -static void iam_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { +void grpc_google_iam_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable iam_vtable = { - iam_destruct, iam_get_request_metadata, iam_cancel_get_request_metadata}; +grpc_google_iam_credentials::grpc_google_iam_credentials( + const char* token, const char* authority_selector) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_IAM) { + grpc_mdelem md = grpc_mdelem_from_slices( + grpc_slice_from_static_string(GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY), + grpc_slice_from_copied_string(token)); + grpc_credentials_mdelem_array_add(&md_array_, md); + GRPC_MDELEM_UNREF(md); + md = grpc_mdelem_from_slices( + grpc_slice_from_static_string(GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY), + grpc_slice_from_copied_string(authority_selector)); + grpc_credentials_mdelem_array_add(&md_array_, md); + GRPC_MDELEM_UNREF(md); +} grpc_call_credentials* grpc_google_iam_credentials_create( const char* token, const char* authority_selector, void* reserved) { @@ -66,21 +72,7 @@ grpc_call_credentials* grpc_google_iam_credentials_create( GPR_ASSERT(reserved == nullptr); GPR_ASSERT(token != nullptr); GPR_ASSERT(authority_selector != nullptr); - grpc_google_iam_credentials* c = - static_cast(gpr_zalloc(sizeof(*c))); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_IAM; - c->base.vtable = &iam_vtable; - gpr_ref_init(&c->base.refcount, 1); - grpc_mdelem md = grpc_mdelem_from_slices( - grpc_slice_from_static_string(GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY), - grpc_slice_from_copied_string(token)); - grpc_credentials_mdelem_array_add(&c->md_array, md); - GRPC_MDELEM_UNREF(md); - md = grpc_mdelem_from_slices( - grpc_slice_from_static_string(GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY), - grpc_slice_from_copied_string(authority_selector)); - grpc_credentials_mdelem_array_add(&c->md_array, md); - GRPC_MDELEM_UNREF(md); - - return &c->base; + return grpc_core::MakeRefCounted( + token, authority_selector) + .release(); } diff --git a/src/core/lib/security/credentials/iam/iam_credentials.h b/src/core/lib/security/credentials/iam/iam_credentials.h index a45710fe0f8..36f5ee89307 100644 --- a/src/core/lib/security/credentials/iam/iam_credentials.h +++ b/src/core/lib/security/credentials/iam/iam_credentials.h @@ -23,9 +23,23 @@ #include "src/core/lib/security/credentials/credentials.h" -typedef struct { - grpc_call_credentials base; - grpc_credentials_mdelem_array md_array; -} grpc_google_iam_credentials; +class grpc_google_iam_credentials : public grpc_call_credentials { + public: + grpc_google_iam_credentials(const char* token, + const char* authority_selector); + ~grpc_google_iam_credentials() override; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + private: + grpc_credentials_mdelem_array md_array_; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_IAM_IAM_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.cc b/src/core/lib/security/credentials/jwt/jwt_credentials.cc index 05c08a68b01..f2591a1ea5e 100644 --- a/src/core/lib/security/credentials/jwt/jwt_credentials.cc +++ b/src/core/lib/security/credentials/jwt/jwt_credentials.cc @@ -23,6 +23,8 @@ #include #include +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/surface/api_trace.h" #include @@ -30,71 +32,66 @@ #include #include -static void jwt_reset_cache(grpc_service_account_jwt_access_credentials* c) { - GRPC_MDELEM_UNREF(c->cached.jwt_md); - c->cached.jwt_md = GRPC_MDNULL; - if (c->cached.service_url != nullptr) { - gpr_free(c->cached.service_url); - c->cached.service_url = nullptr; +void grpc_service_account_jwt_access_credentials::reset_cache() { + GRPC_MDELEM_UNREF(cached_.jwt_md); + cached_.jwt_md = GRPC_MDNULL; + if (cached_.service_url != nullptr) { + gpr_free(cached_.service_url); + cached_.service_url = nullptr; } - c->cached.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); + cached_.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); } -static void jwt_destruct(grpc_call_credentials* creds) { - grpc_service_account_jwt_access_credentials* c = - reinterpret_cast(creds); - grpc_auth_json_key_destruct(&c->key); - jwt_reset_cache(c); - gpr_mu_destroy(&c->cache_mu); +grpc_service_account_jwt_access_credentials:: + ~grpc_service_account_jwt_access_credentials() { + grpc_auth_json_key_destruct(&key_); + reset_cache(); + gpr_mu_destroy(&cache_mu_); } -static bool jwt_get_request_metadata(grpc_call_credentials* creds, - grpc_polling_entity* pollent, - grpc_auth_metadata_context context, - grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, - grpc_error** error) { - grpc_service_account_jwt_access_credentials* c = - reinterpret_cast(creds); +bool grpc_service_account_jwt_access_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { gpr_timespec refresh_threshold = gpr_time_from_seconds( GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN); /* See if we can return a cached jwt. */ grpc_mdelem jwt_md = GRPC_MDNULL; { - gpr_mu_lock(&c->cache_mu); - if (c->cached.service_url != nullptr && - strcmp(c->cached.service_url, context.service_url) == 0 && - !GRPC_MDISNULL(c->cached.jwt_md) && - (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, - gpr_now(GPR_CLOCK_REALTIME)), - refresh_threshold) > 0)) { - jwt_md = GRPC_MDELEM_REF(c->cached.jwt_md); + gpr_mu_lock(&cache_mu_); + if (cached_.service_url != nullptr && + strcmp(cached_.service_url, context.service_url) == 0 && + !GRPC_MDISNULL(cached_.jwt_md) && + (gpr_time_cmp( + gpr_time_sub(cached_.jwt_expiration, gpr_now(GPR_CLOCK_REALTIME)), + refresh_threshold) > 0)) { + jwt_md = GRPC_MDELEM_REF(cached_.jwt_md); } - gpr_mu_unlock(&c->cache_mu); + gpr_mu_unlock(&cache_mu_); } if (GRPC_MDISNULL(jwt_md)) { char* jwt = nullptr; /* Generate a new jwt. */ - gpr_mu_lock(&c->cache_mu); - jwt_reset_cache(c); - jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url, - c->jwt_lifetime, nullptr); + gpr_mu_lock(&cache_mu_); + reset_cache(); + jwt = grpc_jwt_encode_and_sign(&key_, context.service_url, jwt_lifetime_, + nullptr); if (jwt != nullptr) { char* md_value; gpr_asprintf(&md_value, "Bearer %s", jwt); gpr_free(jwt); - c->cached.jwt_expiration = - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime); - c->cached.service_url = gpr_strdup(context.service_url); - c->cached.jwt_md = grpc_mdelem_from_slices( + cached_.jwt_expiration = + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), jwt_lifetime_); + cached_.service_url = gpr_strdup(context.service_url); + cached_.jwt_md = grpc_mdelem_from_slices( grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY), grpc_slice_from_copied_string(md_value)); gpr_free(md_value); - jwt_md = GRPC_MDELEM_REF(c->cached.jwt_md); + jwt_md = GRPC_MDELEM_REF(cached_.jwt_md); } - gpr_mu_unlock(&c->cache_mu); + gpr_mu_unlock(&cache_mu_); } if (!GRPC_MDISNULL(jwt_md)) { @@ -106,29 +103,15 @@ static bool jwt_get_request_metadata(grpc_call_credentials* creds, return true; } -static void jwt_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { +void grpc_service_account_jwt_access_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable jwt_vtable = { - jwt_destruct, jwt_get_request_metadata, jwt_cancel_get_request_metadata}; - -grpc_call_credentials* -grpc_service_account_jwt_access_credentials_create_from_auth_json_key( - grpc_auth_json_key key, gpr_timespec token_lifetime) { - grpc_service_account_jwt_access_credentials* c; - if (!grpc_auth_json_key_is_valid(&key)) { - gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation"); - return nullptr; - } - c = static_cast( - gpr_zalloc(sizeof(grpc_service_account_jwt_access_credentials))); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_JWT; - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &jwt_vtable; - c->key = key; +grpc_service_account_jwt_access_credentials:: + grpc_service_account_jwt_access_credentials(grpc_auth_json_key key, + gpr_timespec token_lifetime) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_JWT), key_(key) { gpr_timespec max_token_lifetime = grpc_max_auth_token_lifetime(); if (gpr_time_cmp(token_lifetime, max_token_lifetime) > 0) { gpr_log(GPR_INFO, @@ -136,10 +119,20 @@ grpc_service_account_jwt_access_credentials_create_from_auth_json_key( static_cast(max_token_lifetime.tv_sec)); token_lifetime = grpc_max_auth_token_lifetime(); } - c->jwt_lifetime = token_lifetime; - gpr_mu_init(&c->cache_mu); - jwt_reset_cache(c); - return &c->base; + jwt_lifetime_ = token_lifetime; + gpr_mu_init(&cache_mu_); + reset_cache(); +} + +grpc_core::RefCountedPtr +grpc_service_account_jwt_access_credentials_create_from_auth_json_key( + grpc_auth_json_key key, gpr_timespec token_lifetime) { + if (!grpc_auth_json_key_is_valid(&key)) { + gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation"); + return nullptr; + } + return grpc_core::MakeRefCounted( + key, token_lifetime); } static char* redact_private_key(const char* json_key) { @@ -182,9 +175,7 @@ grpc_call_credentials* grpc_service_account_jwt_access_credentials_create( } GPR_ASSERT(reserved == nullptr); grpc_core::ExecCtx exec_ctx; - grpc_call_credentials* creds = - grpc_service_account_jwt_access_credentials_create_from_auth_json_key( - grpc_auth_json_key_create_from_string(json_key), token_lifetime); - - return creds; + return grpc_service_account_jwt_access_credentials_create_from_auth_json_key( + grpc_auth_json_key_create_from_string(json_key), token_lifetime) + .release(); } diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.h b/src/core/lib/security/credentials/jwt/jwt_credentials.h index 5c3d34aa566..5af909f44df 100644 --- a/src/core/lib/security/credentials/jwt/jwt_credentials.h +++ b/src/core/lib/security/credentials/jwt/jwt_credentials.h @@ -24,25 +24,44 @@ #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/jwt/json_token.h" -typedef struct { - grpc_call_credentials base; +class grpc_service_account_jwt_access_credentials + : public grpc_call_credentials { + public: + grpc_service_account_jwt_access_credentials(grpc_auth_json_key key, + gpr_timespec token_lifetime); + ~grpc_service_account_jwt_access_credentials() override; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + const gpr_timespec& jwt_lifetime() const { return jwt_lifetime_; } + const grpc_auth_json_key& key() const { return key_; } + + private: + void reset_cache(); // Have a simple cache for now with just 1 entry. We could have a map based on // the service_url for a more sophisticated one. - gpr_mu cache_mu; + gpr_mu cache_mu_; struct { - grpc_mdelem jwt_md; - char* service_url; + grpc_mdelem jwt_md = GRPC_MDNULL; + char* service_url = nullptr; gpr_timespec jwt_expiration; - } cached; + } cached_; - grpc_auth_json_key key; - gpr_timespec jwt_lifetime; -} grpc_service_account_jwt_access_credentials; + grpc_auth_json_key key_; + gpr_timespec jwt_lifetime_; +}; // Private constructor for jwt credentials from an already parsed json key. // Takes ownership of the key. -grpc_call_credentials* +grpc_core::RefCountedPtr grpc_service_account_jwt_access_credentials_create_from_auth_json_key( grpc_auth_json_key key, gpr_timespec token_lifetime); diff --git a/src/core/lib/security/credentials/local/local_credentials.cc b/src/core/lib/security/credentials/local/local_credentials.cc index 3ccfa2b9086..6f6f95a34a7 100644 --- a/src/core/lib/security/credentials/local/local_credentials.cc +++ b/src/core/lib/security/credentials/local/local_credentials.cc @@ -29,49 +29,36 @@ #define GRPC_CREDENTIALS_TYPE_LOCAL "Local" -static void local_credentials_destruct(grpc_channel_credentials* creds) {} - -static void local_server_credentials_destruct(grpc_server_credentials* creds) {} - -static grpc_security_status local_create_security_connector( - grpc_channel_credentials* creds, - grpc_call_credentials* request_metadata_creds, const char* target_name, - const grpc_channel_args* args, grpc_channel_security_connector** sc, +grpc_core::RefCountedPtr +grpc_local_credentials::create_security_connector( + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const grpc_channel_args* args, grpc_channel_args** new_args) { return grpc_local_channel_security_connector_create( - creds, request_metadata_creds, args, target_name, sc); + this->Ref(), std::move(request_metadata_creds), args, target_name); } -static grpc_security_status local_server_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc) { - return grpc_local_server_security_connector_create(creds, sc); +grpc_core::RefCountedPtr +grpc_local_server_credentials::create_security_connector() { + return grpc_local_server_security_connector_create(this->Ref()); } -static const grpc_channel_credentials_vtable local_credentials_vtable = { - local_credentials_destruct, local_create_security_connector, - /*duplicate_without_call_credentials=*/nullptr}; - -static const grpc_server_credentials_vtable local_server_credentials_vtable = { - local_server_credentials_destruct, local_server_create_security_connector}; +grpc_local_credentials::grpc_local_credentials( + grpc_local_connect_type connect_type) + : grpc_channel_credentials(GRPC_CREDENTIALS_TYPE_LOCAL), + connect_type_(connect_type) {} grpc_channel_credentials* grpc_local_credentials_create( grpc_local_connect_type connect_type) { - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_local_credentials))); - creds->connect_type = connect_type; - creds->base.type = GRPC_CREDENTIALS_TYPE_LOCAL; - creds->base.vtable = &local_credentials_vtable; - gpr_ref_init(&creds->base.refcount, 1); - return &creds->base; + return grpc_core::New(connect_type); } +grpc_local_server_credentials::grpc_local_server_credentials( + grpc_local_connect_type connect_type) + : grpc_server_credentials(GRPC_CREDENTIALS_TYPE_LOCAL), + connect_type_(connect_type) {} + grpc_server_credentials* grpc_local_server_credentials_create( grpc_local_connect_type connect_type) { - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_local_server_credentials))); - creds->connect_type = connect_type; - creds->base.type = GRPC_CREDENTIALS_TYPE_LOCAL; - creds->base.vtable = &local_server_credentials_vtable; - gpr_ref_init(&creds->base.refcount, 1); - return &creds->base; + return grpc_core::New(connect_type); } diff --git a/src/core/lib/security/credentials/local/local_credentials.h b/src/core/lib/security/credentials/local/local_credentials.h index 47358b04bc1..60a8a4f64ca 100644 --- a/src/core/lib/security/credentials/local/local_credentials.h +++ b/src/core/lib/security/credentials/local/local_credentials.h @@ -25,16 +25,37 @@ #include "src/core/lib/security/credentials/credentials.h" -/* Main struct for grpc local channel credential. */ -typedef struct grpc_local_credentials { - grpc_channel_credentials base; - grpc_local_connect_type connect_type; -} grpc_local_credentials; +/* Main class for grpc local channel credential. */ +class grpc_local_credentials final : public grpc_channel_credentials { + public: + explicit grpc_local_credentials(grpc_local_connect_type connect_type); + ~grpc_local_credentials() override = default; -/* Main struct for grpc local server credential. */ -typedef struct grpc_local_server_credentials { - grpc_server_credentials base; - grpc_local_connect_type connect_type; -} grpc_local_server_credentials; + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + grpc_local_connect_type connect_type() const { return connect_type_; } + + private: + grpc_local_connect_type connect_type_; +}; + +/* Main class for grpc local server credential. */ +class grpc_local_server_credentials final : public grpc_server_credentials { + public: + explicit grpc_local_server_credentials(grpc_local_connect_type connect_type); + ~grpc_local_server_credentials() override = default; + + grpc_core::RefCountedPtr + create_security_connector() override; + + grpc_local_connect_type connect_type() const { return connect_type_; } + + private: + grpc_local_connect_type connect_type_; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_LOCAL_LOCAL_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc index 44b093557f3..ad63b01e754 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc @@ -22,6 +22,7 @@ #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/util/json_util.h" #include "src/core/lib/surface/api_trace.h" @@ -105,13 +106,12 @@ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token* refresh_token) { // Oauth2 Token Fetcher credentials. // -static void oauth2_token_fetcher_destruct(grpc_call_credentials* creds) { - grpc_oauth2_token_fetcher_credentials* c = - reinterpret_cast(creds); - GRPC_MDELEM_UNREF(c->access_token_md); - gpr_mu_destroy(&c->mu); - grpc_pollset_set_destroy(grpc_polling_entity_pollset_set(&c->pollent)); - grpc_httpcli_context_destroy(&c->httpcli_context); +grpc_oauth2_token_fetcher_credentials:: + ~grpc_oauth2_token_fetcher_credentials() { + GRPC_MDELEM_UNREF(access_token_md_); + gpr_mu_destroy(&mu_); + grpc_pollset_set_destroy(grpc_polling_entity_pollset_set(&pollent_)); + grpc_httpcli_context_destroy(&httpcli_context_); } grpc_credentials_status @@ -209,25 +209,29 @@ static void on_oauth2_token_fetcher_http_response(void* user_data, grpc_credentials_metadata_request* r = static_cast(user_data); grpc_oauth2_token_fetcher_credentials* c = - reinterpret_cast(r->creds); + reinterpret_cast(r->creds.get()); + c->on_http_response(r, error); +} + +void grpc_oauth2_token_fetcher_credentials::on_http_response( + grpc_credentials_metadata_request* r, grpc_error* error) { grpc_mdelem access_token_md = GRPC_MDNULL; grpc_millis token_lifetime; grpc_credentials_status status = grpc_oauth2_token_fetcher_credentials_parse_server_response( &r->response, &access_token_md, &token_lifetime); // Update cache and grab list of pending requests. - gpr_mu_lock(&c->mu); - c->token_fetch_pending = false; - c->access_token_md = GRPC_MDELEM_REF(access_token_md); - c->token_expiration = + gpr_mu_lock(&mu_); + token_fetch_pending_ = false; + access_token_md_ = GRPC_MDELEM_REF(access_token_md); + token_expiration_ = status == GRPC_CREDENTIALS_OK ? gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_millis(token_lifetime, GPR_TIMESPAN)) : gpr_inf_past(GPR_CLOCK_MONOTONIC); - grpc_oauth2_pending_get_request_metadata* pending_request = - c->pending_requests; - c->pending_requests = nullptr; - gpr_mu_unlock(&c->mu); + grpc_oauth2_pending_get_request_metadata* pending_request = pending_requests_; + pending_requests_ = nullptr; + gpr_mu_unlock(&mu_); // Invoke callbacks for all pending requests. while (pending_request != nullptr) { if (status == GRPC_CREDENTIALS_OK) { @@ -239,42 +243,40 @@ static void on_oauth2_token_fetcher_http_response(void* user_data, } GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, error); grpc_polling_entity_del_from_pollset_set( - pending_request->pollent, grpc_polling_entity_pollset_set(&c->pollent)); + pending_request->pollent, grpc_polling_entity_pollset_set(&pollent_)); grpc_oauth2_pending_get_request_metadata* prev = pending_request; pending_request = pending_request->next; gpr_free(prev); } GRPC_MDELEM_UNREF(access_token_md); - grpc_call_credentials_unref(r->creds); + Unref(); grpc_credentials_metadata_request_destroy(r); } -static bool oauth2_token_fetcher_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error) { - grpc_oauth2_token_fetcher_credentials* c = - reinterpret_cast(creds); +bool grpc_oauth2_token_fetcher_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { // Check if we can use the cached token. grpc_millis refresh_threshold = GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS * GPR_MS_PER_SEC; grpc_mdelem cached_access_token_md = GRPC_MDNULL; - gpr_mu_lock(&c->mu); - if (!GRPC_MDISNULL(c->access_token_md) && + gpr_mu_lock(&mu_); + if (!GRPC_MDISNULL(access_token_md_) && gpr_time_cmp( - gpr_time_sub(c->token_expiration, gpr_now(GPR_CLOCK_MONOTONIC)), + gpr_time_sub(token_expiration_, gpr_now(GPR_CLOCK_MONOTONIC)), gpr_time_from_seconds(GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN)) > 0) { - cached_access_token_md = GRPC_MDELEM_REF(c->access_token_md); + cached_access_token_md = GRPC_MDELEM_REF(access_token_md_); } if (!GRPC_MDISNULL(cached_access_token_md)) { - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&mu_); grpc_credentials_mdelem_array_add(md_array, cached_access_token_md); GRPC_MDELEM_UNREF(cached_access_token_md); return true; } // Couldn't get the token from the cache. - // Add request to c->pending_requests and start a new fetch if needed. + // Add request to pending_requests_ and start a new fetch if needed. grpc_oauth2_pending_get_request_metadata* pending_request = static_cast( gpr_malloc(sizeof(*pending_request))); @@ -282,41 +284,37 @@ static bool oauth2_token_fetcher_get_request_metadata( pending_request->on_request_metadata = on_request_metadata; pending_request->pollent = pollent; grpc_polling_entity_add_to_pollset_set( - pollent, grpc_polling_entity_pollset_set(&c->pollent)); - pending_request->next = c->pending_requests; - c->pending_requests = pending_request; + pollent, grpc_polling_entity_pollset_set(&pollent_)); + pending_request->next = pending_requests_; + pending_requests_ = pending_request; bool start_fetch = false; - if (!c->token_fetch_pending) { - c->token_fetch_pending = true; + if (!token_fetch_pending_) { + token_fetch_pending_ = true; start_fetch = true; } - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&mu_); if (start_fetch) { - grpc_call_credentials_ref(creds); - c->fetch_func(grpc_credentials_metadata_request_create(creds), - &c->httpcli_context, &c->pollent, - on_oauth2_token_fetcher_http_response, - grpc_core::ExecCtx::Get()->Now() + refresh_threshold); + Ref().release(); + fetch_oauth2(grpc_credentials_metadata_request_create(this->Ref()), + &httpcli_context_, &pollent_, + on_oauth2_token_fetcher_http_response, + grpc_core::ExecCtx::Get()->Now() + refresh_threshold); } return false; } -static void oauth2_token_fetcher_cancel_get_request_metadata( - grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { - grpc_oauth2_token_fetcher_credentials* c = - reinterpret_cast(creds); - gpr_mu_lock(&c->mu); +void grpc_oauth2_token_fetcher_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { + gpr_mu_lock(&mu_); grpc_oauth2_pending_get_request_metadata* prev = nullptr; - grpc_oauth2_pending_get_request_metadata* pending_request = - c->pending_requests; + grpc_oauth2_pending_get_request_metadata* pending_request = pending_requests_; while (pending_request != nullptr) { if (pending_request->md_array == md_array) { // Remove matching pending request from the list. if (prev != nullptr) { prev->next = pending_request->next; } else { - c->pending_requests = pending_request->next; + pending_requests_ = pending_request->next; } // Invoke the callback immediately with an error. GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, @@ -327,96 +325,89 @@ static void oauth2_token_fetcher_cancel_get_request_metadata( prev = pending_request; pending_request = pending_request->next; } - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&mu_); GRPC_ERROR_UNREF(error); } -static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials* c, - grpc_fetch_oauth2_func fetch_func) { - memset(c, 0, sizeof(grpc_oauth2_token_fetcher_credentials)); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; - gpr_ref_init(&c->base.refcount, 1); - gpr_mu_init(&c->mu); - c->token_expiration = gpr_inf_past(GPR_CLOCK_MONOTONIC); - c->fetch_func = fetch_func; - c->pollent = - grpc_polling_entity_create_from_pollset_set(grpc_pollset_set_create()); - grpc_httpcli_context_init(&c->httpcli_context); +grpc_oauth2_token_fetcher_credentials::grpc_oauth2_token_fetcher_credentials() + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_OAUTH2), + token_expiration_(gpr_inf_past(GPR_CLOCK_MONOTONIC)), + pollent_(grpc_polling_entity_create_from_pollset_set( + grpc_pollset_set_create())) { + gpr_mu_init(&mu_); + grpc_httpcli_context_init(&httpcli_context_); } // // Google Compute Engine credentials. // -static grpc_call_credentials_vtable compute_engine_vtable = { - oauth2_token_fetcher_destruct, oauth2_token_fetcher_get_request_metadata, - oauth2_token_fetcher_cancel_get_request_metadata}; +namespace { -static void compute_engine_fetch_oauth2( - grpc_credentials_metadata_request* metadata_req, - grpc_httpcli_context* httpcli_context, grpc_polling_entity* pollent, - grpc_iomgr_cb_func response_cb, grpc_millis deadline) { - grpc_http_header header = {(char*)"Metadata-Flavor", (char*)"Google"}; - grpc_httpcli_request request; - memset(&request, 0, sizeof(grpc_httpcli_request)); - request.host = (char*)GRPC_COMPUTE_ENGINE_METADATA_HOST; - request.http.path = (char*)GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH; - request.http.hdr_count = 1; - request.http.hdrs = &header; - /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host - channel. This would allow us to cancel an authentication query when under - extreme memory pressure. */ - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("oauth2_credentials"); - grpc_httpcli_get( - httpcli_context, pollent, resource_quota, &request, deadline, - GRPC_CLOSURE_CREATE(response_cb, metadata_req, grpc_schedule_on_exec_ctx), - &metadata_req->response); - grpc_resource_quota_unref_internal(resource_quota); -} +class grpc_compute_engine_token_fetcher_credentials + : public grpc_oauth2_token_fetcher_credentials { + public: + grpc_compute_engine_token_fetcher_credentials() = default; + ~grpc_compute_engine_token_fetcher_credentials() override = default; + + protected: + void fetch_oauth2(grpc_credentials_metadata_request* metadata_req, + grpc_httpcli_context* http_context, + grpc_polling_entity* pollent, + grpc_iomgr_cb_func response_cb, + grpc_millis deadline) override { + grpc_http_header header = {(char*)"Metadata-Flavor", (char*)"Google"}; + grpc_httpcli_request request; + memset(&request, 0, sizeof(grpc_httpcli_request)); + request.host = (char*)GRPC_COMPUTE_ENGINE_METADATA_HOST; + request.http.path = (char*)GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH; + request.http.hdr_count = 1; + request.http.hdrs = &header; + /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host + channel. This would allow us to cancel an authentication query when under + extreme memory pressure. */ + grpc_resource_quota* resource_quota = + grpc_resource_quota_create("oauth2_credentials"); + grpc_httpcli_get(http_context, pollent, resource_quota, &request, deadline, + GRPC_CLOSURE_CREATE(response_cb, metadata_req, + grpc_schedule_on_exec_ctx), + &metadata_req->response); + grpc_resource_quota_unref_internal(resource_quota); + } +}; + +} // namespace grpc_call_credentials* grpc_google_compute_engine_credentials_create( void* reserved) { - grpc_oauth2_token_fetcher_credentials* c = - static_cast( - gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials))); GRPC_API_TRACE("grpc_compute_engine_credentials_create(reserved=%p)", 1, (reserved)); GPR_ASSERT(reserved == nullptr); - init_oauth2_token_fetcher(c, compute_engine_fetch_oauth2); - c->base.vtable = &compute_engine_vtable; - return &c->base; + return grpc_core::MakeRefCounted< + grpc_compute_engine_token_fetcher_credentials>() + .release(); } // // Google Refresh Token credentials. // -static void refresh_token_destruct(grpc_call_credentials* creds) { - grpc_google_refresh_token_credentials* c = - reinterpret_cast(creds); - grpc_auth_refresh_token_destruct(&c->refresh_token); - oauth2_token_fetcher_destruct(&c->base.base); +grpc_google_refresh_token_credentials:: + ~grpc_google_refresh_token_credentials() { + grpc_auth_refresh_token_destruct(&refresh_token_); } -static grpc_call_credentials_vtable refresh_token_vtable = { - refresh_token_destruct, oauth2_token_fetcher_get_request_metadata, - oauth2_token_fetcher_cancel_get_request_metadata}; - -static void refresh_token_fetch_oauth2( +void grpc_google_refresh_token_credentials::fetch_oauth2( grpc_credentials_metadata_request* metadata_req, grpc_httpcli_context* httpcli_context, grpc_polling_entity* pollent, grpc_iomgr_cb_func response_cb, grpc_millis deadline) { - grpc_google_refresh_token_credentials* c = - reinterpret_cast( - metadata_req->creds); grpc_http_header header = {(char*)"Content-Type", (char*)"application/x-www-form-urlencoded"}; grpc_httpcli_request request; char* body = nullptr; gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING, - c->refresh_token.client_id, c->refresh_token.client_secret, - c->refresh_token.refresh_token); + refresh_token_.client_id, refresh_token_.client_secret, + refresh_token_.refresh_token); memset(&request, 0, sizeof(grpc_httpcli_request)); request.host = (char*)GRPC_GOOGLE_OAUTH2_SERVICE_HOST; request.http.path = (char*)GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH; @@ -437,20 +428,19 @@ static void refresh_token_fetch_oauth2( gpr_free(body); } -grpc_call_credentials* +grpc_google_refresh_token_credentials::grpc_google_refresh_token_credentials( + grpc_auth_refresh_token refresh_token) + : refresh_token_(refresh_token) {} + +grpc_core::RefCountedPtr grpc_refresh_token_credentials_create_from_auth_refresh_token( grpc_auth_refresh_token refresh_token) { - grpc_google_refresh_token_credentials* c; if (!grpc_auth_refresh_token_is_valid(&refresh_token)) { gpr_log(GPR_ERROR, "Invalid input for refresh token credentials creation"); return nullptr; } - c = static_cast( - gpr_zalloc(sizeof(grpc_google_refresh_token_credentials))); - init_oauth2_token_fetcher(&c->base, refresh_token_fetch_oauth2); - c->base.base.vtable = &refresh_token_vtable; - c->refresh_token = refresh_token; - return &c->base.base; + return grpc_core::MakeRefCounted( + refresh_token); } static char* create_loggable_refresh_token(grpc_auth_refresh_token* token) { @@ -478,59 +468,50 @@ grpc_call_credentials* grpc_google_refresh_token_credentials_create( gpr_free(loggable_token); } GPR_ASSERT(reserved == nullptr); - return grpc_refresh_token_credentials_create_from_auth_refresh_token(token); + return grpc_refresh_token_credentials_create_from_auth_refresh_token(token) + .release(); } // // Oauth2 Access Token credentials. // -static void access_token_destruct(grpc_call_credentials* creds) { - grpc_access_token_credentials* c = - reinterpret_cast(creds); - GRPC_MDELEM_UNREF(c->access_token_md); +grpc_access_token_credentials::~grpc_access_token_credentials() { + GRPC_MDELEM_UNREF(access_token_md_); } -static bool access_token_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error) { - grpc_access_token_credentials* c = - reinterpret_cast(creds); - grpc_credentials_mdelem_array_add(md_array, c->access_token_md); +bool grpc_access_token_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { + grpc_credentials_mdelem_array_add(md_array, access_token_md_); return true; } -static void access_token_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { +void grpc_access_token_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable access_token_vtable = { - access_token_destruct, access_token_get_request_metadata, - access_token_cancel_get_request_metadata}; +grpc_access_token_credentials::grpc_access_token_credentials( + const char* access_token) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) { + char* token_md_value; + gpr_asprintf(&token_md_value, "Bearer %s", access_token); + grpc_core::ExecCtx exec_ctx; + access_token_md_ = grpc_mdelem_from_slices( + grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY), + grpc_slice_from_copied_string(token_md_value)); + gpr_free(token_md_value); +} grpc_call_credentials* grpc_access_token_credentials_create( const char* access_token, void* reserved) { - grpc_access_token_credentials* c = - static_cast( - gpr_zalloc(sizeof(grpc_access_token_credentials))); GRPC_API_TRACE( "grpc_access_token_credentials_create(access_token=, " "reserved=%p)", 1, (reserved)); GPR_ASSERT(reserved == nullptr); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; - c->base.vtable = &access_token_vtable; - gpr_ref_init(&c->base.refcount, 1); - char* token_md_value; - gpr_asprintf(&token_md_value, "Bearer %s", access_token); - grpc_core::ExecCtx exec_ctx; - c->access_token_md = grpc_mdelem_from_slices( - grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY), - grpc_slice_from_copied_string(token_md_value)); - - gpr_free(token_md_value); - return &c->base; + return grpc_core::MakeRefCounted(access_token) + .release(); } diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h index 12a1d4484fe..510a78b484a 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h @@ -54,46 +54,91 @@ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token* refresh_token); // This object is a base for credentials that need to acquire an oauth2 token // from an http service. -typedef void (*grpc_fetch_oauth2_func)(grpc_credentials_metadata_request* req, - grpc_httpcli_context* http_context, - grpc_polling_entity* pollent, - grpc_iomgr_cb_func cb, - grpc_millis deadline); - -typedef struct grpc_oauth2_pending_get_request_metadata { +struct grpc_oauth2_pending_get_request_metadata { grpc_credentials_mdelem_array* md_array; grpc_closure* on_request_metadata; grpc_polling_entity* pollent; struct grpc_oauth2_pending_get_request_metadata* next; -} grpc_oauth2_pending_get_request_metadata; +}; -typedef struct { - grpc_call_credentials base; - gpr_mu mu; - grpc_mdelem access_token_md; - gpr_timespec token_expiration; - bool token_fetch_pending; - grpc_oauth2_pending_get_request_metadata* pending_requests; - grpc_httpcli_context httpcli_context; - grpc_fetch_oauth2_func fetch_func; - grpc_polling_entity pollent; -} grpc_oauth2_token_fetcher_credentials; +class grpc_oauth2_token_fetcher_credentials : public grpc_call_credentials { + public: + grpc_oauth2_token_fetcher_credentials(); + ~grpc_oauth2_token_fetcher_credentials() override; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + void on_http_response(grpc_credentials_metadata_request* r, + grpc_error* error); + + GRPC_ABSTRACT_BASE_CLASS + + protected: + virtual void fetch_oauth2(grpc_credentials_metadata_request* req, + grpc_httpcli_context* httpcli_context, + grpc_polling_entity* pollent, grpc_iomgr_cb_func cb, + grpc_millis deadline) GRPC_ABSTRACT; + + private: + gpr_mu mu_; + grpc_mdelem access_token_md_ = GRPC_MDNULL; + gpr_timespec token_expiration_; + bool token_fetch_pending_ = false; + grpc_oauth2_pending_get_request_metadata* pending_requests_ = nullptr; + grpc_httpcli_context httpcli_context_; + grpc_polling_entity pollent_; +}; // Google refresh token credentials. -typedef struct { - grpc_oauth2_token_fetcher_credentials base; - grpc_auth_refresh_token refresh_token; -} grpc_google_refresh_token_credentials; +class grpc_google_refresh_token_credentials final + : public grpc_oauth2_token_fetcher_credentials { + public: + grpc_google_refresh_token_credentials(grpc_auth_refresh_token refresh_token); + ~grpc_google_refresh_token_credentials() override; + + const grpc_auth_refresh_token& refresh_token() const { + return refresh_token_; + } + + protected: + void fetch_oauth2(grpc_credentials_metadata_request* req, + grpc_httpcli_context* httpcli_context, + grpc_polling_entity* pollent, grpc_iomgr_cb_func cb, + grpc_millis deadline) override; + + private: + grpc_auth_refresh_token refresh_token_; +}; // Access token credentials. -typedef struct { - grpc_call_credentials base; - grpc_mdelem access_token_md; -} grpc_access_token_credentials; +class grpc_access_token_credentials final : public grpc_call_credentials { + public: + grpc_access_token_credentials(const char* access_token); + ~grpc_access_token_credentials() override; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + private: + grpc_mdelem access_token_md_; +}; // Private constructor for refresh token credentials from an already parsed // refresh token. Takes ownership of the refresh token. -grpc_call_credentials* +grpc_core::RefCountedPtr grpc_refresh_token_credentials_create_from_auth_refresh_token( grpc_auth_refresh_token token); diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.cc b/src/core/lib/security/credentials/plugin/plugin_credentials.cc index 4015124298b..52982fdb8f1 100644 --- a/src/core/lib/security/credentials/plugin/plugin_credentials.cc +++ b/src/core/lib/security/credentials/plugin/plugin_credentials.cc @@ -35,20 +35,17 @@ grpc_core::TraceFlag grpc_plugin_credentials_trace(false, "plugin_credentials"); -static void plugin_destruct(grpc_call_credentials* creds) { - grpc_plugin_credentials* c = - reinterpret_cast(creds); - gpr_mu_destroy(&c->mu); - if (c->plugin.state != nullptr && c->plugin.destroy != nullptr) { - c->plugin.destroy(c->plugin.state); +grpc_plugin_credentials::~grpc_plugin_credentials() { + gpr_mu_destroy(&mu_); + if (plugin_.state != nullptr && plugin_.destroy != nullptr) { + plugin_.destroy(plugin_.state); } } -static void pending_request_remove_locked( - grpc_plugin_credentials* c, - grpc_plugin_credentials_pending_request* pending_request) { +void grpc_plugin_credentials::pending_request_remove_locked( + pending_request* pending_request) { if (pending_request->prev == nullptr) { - c->pending_requests = pending_request->next; + pending_requests_ = pending_request->next; } else { pending_request->prev->next = pending_request->next; } @@ -62,17 +59,17 @@ static void pending_request_remove_locked( // cancelled out from under us. // When this returns, r->cancelled indicates whether the request was // cancelled before completion. -static void pending_request_complete( - grpc_plugin_credentials_pending_request* r) { - gpr_mu_lock(&r->creds->mu); - if (!r->cancelled) pending_request_remove_locked(r->creds, r); - gpr_mu_unlock(&r->creds->mu); +void grpc_plugin_credentials::pending_request_complete(pending_request* r) { + GPR_DEBUG_ASSERT(r->creds == this); + gpr_mu_lock(&mu_); + if (!r->cancelled) pending_request_remove_locked(r); + gpr_mu_unlock(&mu_); // Ref to credentials not needed anymore. - grpc_call_credentials_unref(&r->creds->base); + Unref(); } static grpc_error* process_plugin_result( - grpc_plugin_credentials_pending_request* r, const grpc_metadata* md, + grpc_plugin_credentials::pending_request* r, const grpc_metadata* md, size_t num_md, grpc_status_code status, const char* error_details) { grpc_error* error = GRPC_ERROR_NONE; if (status != GRPC_STATUS_OK) { @@ -119,8 +116,8 @@ static void plugin_md_request_metadata_ready(void* request, /* called from application code */ grpc_core::ExecCtx exec_ctx(GRPC_EXEC_CTX_FLAG_IS_FINISHED | GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP); - grpc_plugin_credentials_pending_request* r = - static_cast(request); + grpc_plugin_credentials::pending_request* r = + static_cast(request); if (grpc_plugin_credentials_trace.enabled()) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin returned " @@ -128,7 +125,7 @@ static void plugin_md_request_metadata_ready(void* request, r->creds, r); } // Remove request from pending list if not previously cancelled. - pending_request_complete(r); + r->creds->pending_request_complete(r); // If it has not been cancelled, process it. if (!r->cancelled) { grpc_error* error = @@ -143,65 +140,59 @@ static void plugin_md_request_metadata_ready(void* request, gpr_free(r); } -static bool plugin_get_request_metadata(grpc_call_credentials* creds, - grpc_polling_entity* pollent, - grpc_auth_metadata_context context, - grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, - grpc_error** error) { - grpc_plugin_credentials* c = - reinterpret_cast(creds); +bool grpc_plugin_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { bool retval = true; // Synchronous return. - if (c->plugin.get_metadata != nullptr) { + if (plugin_.get_metadata != nullptr) { // Create pending_request object. - grpc_plugin_credentials_pending_request* pending_request = - static_cast( - gpr_zalloc(sizeof(*pending_request))); - pending_request->creds = c; - pending_request->md_array = md_array; - pending_request->on_request_metadata = on_request_metadata; + pending_request* request = + static_cast(gpr_zalloc(sizeof(*request))); + request->creds = this; + request->md_array = md_array; + request->on_request_metadata = on_request_metadata; // Add it to the pending list. - gpr_mu_lock(&c->mu); - if (c->pending_requests != nullptr) { - c->pending_requests->prev = pending_request; + gpr_mu_lock(&mu_); + if (pending_requests_ != nullptr) { + pending_requests_->prev = request; } - pending_request->next = c->pending_requests; - c->pending_requests = pending_request; - gpr_mu_unlock(&c->mu); + request->next = pending_requests_; + pending_requests_ = request; + gpr_mu_unlock(&mu_); // Invoke the plugin. The callback holds a ref to us. if (grpc_plugin_credentials_trace.enabled()) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: invoking plugin", - c, pending_request); + this, request); } - grpc_call_credentials_ref(creds); + Ref().release(); grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX]; size_t num_creds_md = 0; grpc_status_code status = GRPC_STATUS_OK; const char* error_details = nullptr; - if (!c->plugin.get_metadata(c->plugin.state, context, - plugin_md_request_metadata_ready, - pending_request, creds_md, &num_creds_md, - &status, &error_details)) { + if (!plugin_.get_metadata( + plugin_.state, context, plugin_md_request_metadata_ready, request, + creds_md, &num_creds_md, &status, &error_details)) { if (grpc_plugin_credentials_trace.enabled()) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin will return " "asynchronously", - c, pending_request); + this, request); } return false; // Asynchronous return. } // Returned synchronously. // Remove request from pending list if not previously cancelled. - pending_request_complete(pending_request); + request->creds->pending_request_complete(request); // If the request was cancelled, the error will have been returned // asynchronously by plugin_cancel_get_request_metadata(), so return // false. Otherwise, process the result. - if (pending_request->cancelled) { + if (request->cancelled) { if (grpc_plugin_credentials_trace.enabled()) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p was cancelled, error " "will be returned asynchronously", - c, pending_request); + this, request); } retval = false; } else { @@ -209,10 +200,10 @@ static bool plugin_get_request_metadata(grpc_call_credentials* creds, gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin returned " "synchronously", - c, pending_request); + this, request); } - *error = process_plugin_result(pending_request, creds_md, num_creds_md, - status, error_details); + *error = process_plugin_result(request, creds_md, num_creds_md, status, + error_details); } // Clean up. for (size_t i = 0; i < num_creds_md; ++i) { @@ -220,51 +211,42 @@ static bool plugin_get_request_metadata(grpc_call_credentials* creds, grpc_slice_unref_internal(creds_md[i].value); } gpr_free((void*)error_details); - gpr_free(pending_request); + gpr_free(request); } return retval; } -static void plugin_cancel_get_request_metadata( - grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { - grpc_plugin_credentials* c = - reinterpret_cast(creds); - gpr_mu_lock(&c->mu); - for (grpc_plugin_credentials_pending_request* pending_request = - c->pending_requests; +void grpc_plugin_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { + gpr_mu_lock(&mu_); + for (pending_request* pending_request = pending_requests_; pending_request != nullptr; pending_request = pending_request->next) { if (pending_request->md_array == md_array) { if (grpc_plugin_credentials_trace.enabled()) { - gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", c, + gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", this, pending_request); } pending_request->cancelled = true; GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, GRPC_ERROR_REF(error)); - pending_request_remove_locked(c, pending_request); + pending_request_remove_locked(pending_request); break; } } - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&mu_); GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable plugin_vtable = { - plugin_destruct, plugin_get_request_metadata, - plugin_cancel_get_request_metadata}; +grpc_plugin_credentials::grpc_plugin_credentials( + grpc_metadata_credentials_plugin plugin) + : grpc_call_credentials(plugin.type), plugin_(plugin) { + gpr_mu_init(&mu_); +} grpc_call_credentials* grpc_metadata_credentials_create_from_plugin( grpc_metadata_credentials_plugin plugin, void* reserved) { - grpc_plugin_credentials* c = - static_cast(gpr_zalloc(sizeof(*c))); GRPC_API_TRACE("grpc_metadata_credentials_create_from_plugin(reserved=%p)", 1, (reserved)); GPR_ASSERT(reserved == nullptr); - c->base.type = plugin.type; - c->base.vtable = &plugin_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->plugin = plugin; - gpr_mu_init(&c->mu); - return &c->base; + return grpc_core::New(plugin); } diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.h b/src/core/lib/security/credentials/plugin/plugin_credentials.h index caf990efa15..77a957e5137 100644 --- a/src/core/lib/security/credentials/plugin/plugin_credentials.h +++ b/src/core/lib/security/credentials/plugin/plugin_credentials.h @@ -25,22 +25,45 @@ extern grpc_core::TraceFlag grpc_plugin_credentials_trace; -struct grpc_plugin_credentials; +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_plugin_credentials final : public grpc_call_credentials { + public: + struct pending_request { + bool cancelled; + struct grpc_plugin_credentials* creds; + grpc_credentials_mdelem_array* md_array; + grpc_closure* on_request_metadata; + struct pending_request* prev; + struct pending_request* next; + }; -typedef struct grpc_plugin_credentials_pending_request { - bool cancelled; - struct grpc_plugin_credentials* creds; - grpc_credentials_mdelem_array* md_array; - grpc_closure* on_request_metadata; - struct grpc_plugin_credentials_pending_request* prev; - struct grpc_plugin_credentials_pending_request* next; -} grpc_plugin_credentials_pending_request; + explicit grpc_plugin_credentials(grpc_metadata_credentials_plugin plugin); + ~grpc_plugin_credentials() override; -typedef struct grpc_plugin_credentials { - grpc_call_credentials base; - grpc_metadata_credentials_plugin plugin; - gpr_mu mu; - grpc_plugin_credentials_pending_request* pending_requests; -} grpc_plugin_credentials; + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + // Checks if the request has been cancelled. + // If not, removes it from the pending list, so that it cannot be + // cancelled out from under us. + // When this returns, r->cancelled indicates whether the request was + // cancelled before completion. + void pending_request_complete(pending_request* r); + + private: + void pending_request_remove_locked(pending_request* pending_request); + + grpc_metadata_credentials_plugin plugin_; + gpr_mu mu_; + pending_request* pending_requests_ = nullptr; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_PLUGIN_PLUGIN_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.cc b/src/core/lib/security/credentials/ssl/ssl_credentials.cc index 3d6f2f200a3..83db86f1eac 100644 --- a/src/core/lib/security/credentials/ssl/ssl_credentials.cc +++ b/src/core/lib/security/credentials/ssl/ssl_credentials.cc @@ -44,22 +44,27 @@ void grpc_tsi_ssl_pem_key_cert_pairs_destroy(tsi_ssl_pem_key_cert_pair* kp, gpr_free(kp); } -static void ssl_destruct(grpc_channel_credentials* creds) { - grpc_ssl_credentials* c = reinterpret_cast(creds); - gpr_free(c->config.pem_root_certs); - grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pair, 1); - if (c->config.verify_options.verify_peer_destruct != nullptr) { - c->config.verify_options.verify_peer_destruct( - c->config.verify_options.verify_peer_callback_userdata); +grpc_ssl_credentials::grpc_ssl_credentials( + const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const verify_peer_options* verify_options) + : grpc_channel_credentials(GRPC_CHANNEL_CREDENTIALS_TYPE_SSL) { + build_config(pem_root_certs, pem_key_cert_pair, verify_options); +} + +grpc_ssl_credentials::~grpc_ssl_credentials() { + gpr_free(config_.pem_root_certs); + grpc_tsi_ssl_pem_key_cert_pairs_destroy(config_.pem_key_cert_pair, 1); + if (config_.verify_options.verify_peer_destruct != nullptr) { + config_.verify_options.verify_peer_destruct( + config_.verify_options.verify_peer_callback_userdata); } } -static grpc_security_status ssl_create_security_connector( - grpc_channel_credentials* creds, grpc_call_credentials* call_creds, +grpc_core::RefCountedPtr +grpc_ssl_credentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - grpc_ssl_credentials* c = reinterpret_cast(creds); - grpc_security_status status = GRPC_SECURITY_OK; + 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 && i < args->num_args; i++) { @@ -74,52 +79,47 @@ static grpc_security_status ssl_create_security_connector( static_cast(arg->value.pointer.p); } } - status = grpc_ssl_channel_security_connector_create( - creds, call_creds, &c->config, target, overridden_target_name, - ssl_session_cache, sc); - if (status != GRPC_SECURITY_OK) { - return status; + grpc_core::RefCountedPtr sc = + grpc_ssl_channel_security_connector_create( + this->Ref(), std::move(call_creds), &config_, target, + overridden_target_name, ssl_session_cache); + if (sc == nullptr) { + return sc; } 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 status; + return sc; } -static grpc_channel_credentials_vtable ssl_vtable = { - ssl_destruct, ssl_create_security_connector, nullptr}; - -static void ssl_build_config(const char* pem_root_certs, - grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, - const verify_peer_options* verify_options, - grpc_ssl_config* config) { - if (pem_root_certs != nullptr) { - config->pem_root_certs = gpr_strdup(pem_root_certs); - } +void grpc_ssl_credentials::build_config( + const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const verify_peer_options* verify_options) { + config_.pem_root_certs = gpr_strdup(pem_root_certs); if (pem_key_cert_pair != nullptr) { GPR_ASSERT(pem_key_cert_pair->private_key != nullptr); GPR_ASSERT(pem_key_cert_pair->cert_chain != nullptr); - config->pem_key_cert_pair = static_cast( + config_.pem_key_cert_pair = static_cast( gpr_zalloc(sizeof(tsi_ssl_pem_key_cert_pair))); - config->pem_key_cert_pair->cert_chain = + config_.pem_key_cert_pair->cert_chain = gpr_strdup(pem_key_cert_pair->cert_chain); - config->pem_key_cert_pair->private_key = + config_.pem_key_cert_pair->private_key = gpr_strdup(pem_key_cert_pair->private_key); + } else { + config_.pem_key_cert_pair = nullptr; } if (verify_options != nullptr) { - memcpy(&config->verify_options, verify_options, + memcpy(&config_.verify_options, verify_options, sizeof(verify_peer_options)); } else { // Otherwise set all options to default values - memset(&config->verify_options, 0, sizeof(verify_peer_options)); + memset(&config_.verify_options, 0, sizeof(verify_peer_options)); } } grpc_channel_credentials* grpc_ssl_credentials_create( const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, const verify_peer_options* verify_options, void* reserved) { - grpc_ssl_credentials* c = static_cast( - gpr_zalloc(sizeof(grpc_ssl_credentials))); GRPC_API_TRACE( "grpc_ssl_credentials_create(pem_root_certs=%s, " "pem_key_cert_pair=%p, " @@ -127,12 +127,9 @@ grpc_channel_credentials* grpc_ssl_credentials_create( "reserved=%p)", 4, (pem_root_certs, pem_key_cert_pair, verify_options, reserved)); GPR_ASSERT(reserved == nullptr); - c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL; - c->base.vtable = &ssl_vtable; - gpr_ref_init(&c->base.refcount, 1); - ssl_build_config(pem_root_certs, pem_key_cert_pair, verify_options, - &c->config); - return &c->base; + + return grpc_core::New(pem_root_certs, pem_key_cert_pair, + verify_options); } // @@ -145,21 +142,29 @@ struct grpc_ssl_server_credentials_options { grpc_ssl_server_certificate_config_fetcher* certificate_config_fetcher; }; -static void ssl_server_destruct(grpc_server_credentials* creds) { - grpc_ssl_server_credentials* c = - reinterpret_cast(creds); - grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pairs, - c->config.num_key_cert_pairs); - gpr_free(c->config.pem_root_certs); +grpc_ssl_server_credentials::grpc_ssl_server_credentials( + const grpc_ssl_server_credentials_options& options) + : grpc_server_credentials(GRPC_CHANNEL_CREDENTIALS_TYPE_SSL) { + if (options.certificate_config_fetcher != nullptr) { + config_.client_certificate_request = options.client_certificate_request; + certificate_config_fetcher_ = *options.certificate_config_fetcher; + } else { + build_config(options.certificate_config->pem_root_certs, + options.certificate_config->pem_key_cert_pairs, + options.certificate_config->num_key_cert_pairs, + options.client_certificate_request); + } } -static grpc_security_status ssl_server_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc) { - return grpc_ssl_server_security_connector_create(creds, sc); +grpc_ssl_server_credentials::~grpc_ssl_server_credentials() { + grpc_tsi_ssl_pem_key_cert_pairs_destroy(config_.pem_key_cert_pairs, + config_.num_key_cert_pairs); + gpr_free(config_.pem_root_certs); +} +grpc_core::RefCountedPtr +grpc_ssl_server_credentials::create_security_connector() { + return grpc_ssl_server_security_connector_create(this->Ref()); } - -static grpc_server_credentials_vtable ssl_server_vtable = { - ssl_server_destruct, ssl_server_create_security_connector}; tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs( const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, @@ -179,18 +184,15 @@ tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs( return tsi_pairs; } -static void ssl_build_server_config( +void grpc_ssl_server_credentials::build_config( const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, size_t num_key_cert_pairs, - grpc_ssl_client_certificate_request_type client_certificate_request, - grpc_ssl_server_config* config) { - config->client_certificate_request = client_certificate_request; - if (pem_root_certs != nullptr) { - config->pem_root_certs = gpr_strdup(pem_root_certs); - } - config->pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( + grpc_ssl_client_certificate_request_type client_certificate_request) { + config_.client_certificate_request = client_certificate_request; + config_.pem_root_certs = gpr_strdup(pem_root_certs); + config_.pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( pem_key_cert_pairs, num_key_cert_pairs); - config->num_key_cert_pairs = num_key_cert_pairs; + config_.num_key_cert_pairs = num_key_cert_pairs; } grpc_ssl_server_certificate_config* grpc_ssl_server_certificate_config_create( @@ -200,9 +202,7 @@ grpc_ssl_server_certificate_config* grpc_ssl_server_certificate_config_create( grpc_ssl_server_certificate_config* config = static_cast( gpr_zalloc(sizeof(grpc_ssl_server_certificate_config))); - if (pem_root_certs != nullptr) { - config->pem_root_certs = gpr_strdup(pem_root_certs); - } + config->pem_root_certs = gpr_strdup(pem_root_certs); if (num_key_cert_pairs > 0) { GPR_ASSERT(pem_key_cert_pairs != nullptr); config->pem_key_cert_pairs = static_cast( @@ -311,7 +311,6 @@ grpc_server_credentials* grpc_ssl_server_credentials_create_ex( grpc_server_credentials* grpc_ssl_server_credentials_create_with_options( grpc_ssl_server_credentials_options* options) { grpc_server_credentials* retval = nullptr; - grpc_ssl_server_credentials* c = nullptr; if (options == nullptr) { gpr_log(GPR_ERROR, @@ -331,23 +330,7 @@ grpc_server_credentials* grpc_ssl_server_credentials_create_with_options( goto done; } - c = static_cast( - gpr_zalloc(sizeof(grpc_ssl_server_credentials))); - c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL; - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &ssl_server_vtable; - - if (options->certificate_config_fetcher != nullptr) { - c->config.client_certificate_request = options->client_certificate_request; - c->certificate_config_fetcher = *options->certificate_config_fetcher; - } else { - ssl_build_server_config(options->certificate_config->pem_root_certs, - options->certificate_config->pem_key_cert_pairs, - options->certificate_config->num_key_cert_pairs, - options->client_certificate_request, &c->config); - } - - retval = &c->base; + retval = grpc_core::New(*options); done: grpc_ssl_server_credentials_options_destroy(options); diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.h b/src/core/lib/security/credentials/ssl/ssl_credentials.h index 0fba413876e..e1174327b30 100644 --- a/src/core/lib/security/credentials/ssl/ssl_credentials.h +++ b/src/core/lib/security/credentials/ssl/ssl_credentials.h @@ -24,27 +24,70 @@ #include "src/core/lib/security/security_connector/ssl/ssl_security_connector.h" -typedef struct { - grpc_channel_credentials base; - grpc_ssl_config config; -} grpc_ssl_credentials; +class grpc_ssl_credentials : public grpc_channel_credentials { + public: + grpc_ssl_credentials(const char* pem_root_certs, + grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const verify_peer_options* verify_options); -struct grpc_ssl_server_certificate_config { - grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs; - size_t num_key_cert_pairs; - char* pem_root_certs; + ~grpc_ssl_credentials() override; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + private: + void build_config(const char* pem_root_certs, + grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const verify_peer_options* verify_options); + + grpc_ssl_config config_; }; -typedef struct { - grpc_ssl_server_certificate_config_callback cb; - void* user_data; -} grpc_ssl_server_certificate_config_fetcher; +struct grpc_ssl_server_certificate_config { + grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs = nullptr; + size_t num_key_cert_pairs = 0; + char* pem_root_certs = nullptr; +}; -typedef struct { - grpc_server_credentials base; - grpc_ssl_server_config config; - grpc_ssl_server_certificate_config_fetcher certificate_config_fetcher; -} grpc_ssl_server_credentials; +struct grpc_ssl_server_certificate_config_fetcher { + grpc_ssl_server_certificate_config_callback cb = nullptr; + void* user_data; +}; + +class grpc_ssl_server_credentials final : public grpc_server_credentials { + public: + grpc_ssl_server_credentials( + const grpc_ssl_server_credentials_options& options); + ~grpc_ssl_server_credentials() override; + + grpc_core::RefCountedPtr + create_security_connector() override; + + bool has_cert_config_fetcher() const { + return certificate_config_fetcher_.cb != nullptr; + } + + grpc_ssl_certificate_config_reload_status FetchCertConfig( + grpc_ssl_server_certificate_config** config) { + GPR_DEBUG_ASSERT(has_cert_config_fetcher()); + return certificate_config_fetcher_.cb(certificate_config_fetcher_.user_data, + config); + } + + const grpc_ssl_server_config& config() const { return config_; } + + private: + void build_config( + const char* pem_root_certs, + grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, size_t num_key_cert_pairs, + grpc_ssl_client_certificate_request_type client_certificate_request); + + grpc_ssl_server_config config_; + grpc_ssl_server_certificate_config_fetcher certificate_config_fetcher_; +}; tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs( const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, 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 dd71c8bc606..6db70ef1720 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 @@ -28,6 +28,7 @@ #include #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/credentials/alts/alts_credentials.h" #include "src/core/lib/security/transport/security_handshaker.h" #include "src/core/lib/slice/slice_internal.h" @@ -35,64 +36,9 @@ #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" #include "src/core/tsi/transport_security.h" -typedef struct { - grpc_channel_security_connector base; - char* target_name; -} grpc_alts_channel_security_connector; +namespace { -typedef struct { - grpc_server_security_connector base; -} grpc_alts_server_security_connector; - -static void alts_channel_destroy(grpc_security_connector* sc) { - if (sc == nullptr) { - return; - } - auto c = reinterpret_cast(sc); - grpc_call_credentials_unref(c->base.request_metadata_creds); - grpc_channel_credentials_unref(c->base.channel_creds); - gpr_free(c->target_name); - gpr_free(sc); -} - -static void alts_server_destroy(grpc_security_connector* sc) { - if (sc == nullptr) { - return; - } - auto c = reinterpret_cast(sc); - grpc_server_credentials_unref(c->base.server_creds); - gpr_free(sc); -} - -static void alts_channel_add_handshakers( - grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) { - tsi_handshaker* handshaker = nullptr; - auto c = reinterpret_cast(sc); - grpc_alts_credentials* creds = - reinterpret_cast(c->base.channel_creds); - GPR_ASSERT(alts_tsi_handshaker_create( - creds->options, c->target_name, creds->handshaker_service_url, - true, interested_parties, &handshaker) == TSI_OK); - grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( - handshaker, &sc->base)); -} - -static void alts_server_add_handshakers( - grpc_server_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) { - tsi_handshaker* handshaker = nullptr; - auto c = reinterpret_cast(sc); - grpc_alts_server_credentials* creds = - reinterpret_cast(c->base.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, &sc->base)); -} - -static void alts_set_rpc_protocol_versions( +void alts_set_rpc_protocol_versions( grpc_gcp_rpc_protocol_versions* rpc_versions) { grpc_gcp_rpc_protocol_versions_set_max(rpc_versions, GRPC_PROTOCOL_VERSION_MAX_MAJOR, @@ -102,17 +48,131 @@ static void alts_set_rpc_protocol_versions( GRPC_PROTOCOL_VERSION_MIN_MINOR); } +void atls_check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { + *auth_context = + grpc_core::internal::grpc_alts_auth_context_from_tsi_peer(&peer); + tsi_peer_destruct(&peer); + grpc_error* error = + *auth_context != nullptr + ? GRPC_ERROR_NONE + : GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Could not get ALTS auth context from TSI peer"); + GRPC_CLOSURE_SCHED(on_peer_checked, error); +} + +class grpc_alts_channel_security_connector final + : public grpc_channel_security_connector { + public: + grpc_alts_channel_security_connector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name) + : grpc_channel_security_connector(/*url_scheme=*/nullptr, + std::move(channel_creds), + std::move(request_metadata_creds)), + target_name_(gpr_strdup(target_name)) { + grpc_alts_credentials* creds = + static_cast(mutable_channel_creds()); + alts_set_rpc_protocol_versions(&creds->mutable_options()->rpc_versions); + } + + ~grpc_alts_channel_security_connector() override { gpr_free(target_name_); } + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_manager) override { + tsi_handshaker* handshaker = nullptr; + const grpc_alts_credentials* creds = + static_cast(channel_creds()); + GPR_ASSERT(alts_tsi_handshaker_create(creds->options(), target_name_, + creds->handshaker_service_url(), true, + interested_parties, + &handshaker) == TSI_OK); + grpc_handshake_manager_add( + handshake_manager, grpc_security_handshaker_create(handshaker, this)); + } + + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + atls_check_peer(peer, auth_context, on_peer_checked); + } + + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast(other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) return c; + return strcmp(target_name_, other->target_name_); + } + + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + if (host == nullptr || strcmp(host, target_name_) != 0) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "ALTS call host does not match target name"); + } + return true; + } + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + private: + char* target_name_; +}; + +class grpc_alts_server_security_connector final + : public grpc_server_security_connector { + public: + grpc_alts_server_security_connector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(/*url_scheme=*/nullptr, + std::move(server_creds)) { + grpc_alts_server_credentials* creds = + reinterpret_cast(mutable_server_creds()); + alts_set_rpc_protocol_versions(&creds->mutable_options()->rpc_versions); + } + ~grpc_alts_server_security_connector() override = default; + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* 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)); + } + + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + atls_check_peer(peer, auth_context, on_peer_checked); + } + + int cmp(const grpc_security_connector* other) const override { + return server_security_connector_cmp( + static_cast(other)); + } +}; +} // namespace + namespace grpc_core { namespace internal { - -grpc_security_status grpc_alts_auth_context_from_tsi_peer( - const tsi_peer* peer, grpc_auth_context** ctx) { - if (peer == nullptr || ctx == nullptr) { +grpc_core::RefCountedPtr +grpc_alts_auth_context_from_tsi_peer(const tsi_peer* peer) { + if (peer == nullptr) { gpr_log(GPR_ERROR, "Invalid arguments to grpc_alts_auth_context_from_tsi_peer()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - *ctx = nullptr; /* Validate certificate type. */ const tsi_peer_property* cert_type_prop = tsi_peer_get_property_by_name(peer, TSI_CERTIFICATE_TYPE_PEER_PROPERTY); @@ -120,14 +180,14 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer( strncmp(cert_type_prop->value.data, TSI_ALTS_CERTIFICATE_TYPE, cert_type_prop->value.length) != 0) { gpr_log(GPR_ERROR, "Invalid or missing certificate type property."); - return GRPC_SECURITY_ERROR; + return nullptr; } /* Validate RPC protocol versions. */ const tsi_peer_property* rpc_versions_prop = tsi_peer_get_property_by_name(peer, TSI_ALTS_RPC_VERSIONS); if (rpc_versions_prop == nullptr) { gpr_log(GPR_ERROR, "Missing rpc protocol versions property."); - return GRPC_SECURITY_ERROR; + return nullptr; } grpc_gcp_rpc_protocol_versions local_versions, peer_versions; alts_set_rpc_protocol_versions(&local_versions); @@ -138,19 +198,19 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer( grpc_slice_unref_internal(slice); if (!decode_result) { gpr_log(GPR_ERROR, "Invalid peer rpc protocol versions."); - return GRPC_SECURITY_ERROR; + return nullptr; } /* TODO: Pass highest common rpc protocol version to grpc caller. */ bool check_result = grpc_gcp_rpc_protocol_versions_check( &local_versions, &peer_versions, nullptr); if (!check_result) { gpr_log(GPR_ERROR, "Mismatch of local and peer rpc protocol versions."); - return GRPC_SECURITY_ERROR; + return nullptr; } /* Create auth context. */ - *ctx = grpc_auth_context_create(nullptr); + auto ctx = grpc_core::MakeRefCounted(nullptr); grpc_auth_context_add_cstring_property( - *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_ALTS_TRANSPORT_SECURITY_TYPE); size_t i = 0; for (i = 0; i < peer->property_count; i++) { @@ -158,132 +218,47 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer( /* Add service account to auth context. */ if (strcmp(tsi_prop->name, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 0) { grpc_auth_context_add_property( - *ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, tsi_prop->value.data, - tsi_prop->value.length); + ctx.get(), TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, + tsi_prop->value.data, tsi_prop->value.length); GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( - *ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 1); + ctx.get(), TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 1); } } - if (!grpc_auth_context_peer_is_authenticated(*ctx)) { + if (!grpc_auth_context_peer_is_authenticated(ctx.get())) { gpr_log(GPR_ERROR, "Invalid unauthenticated peer."); - GRPC_AUTH_CONTEXT_UNREF(*ctx, "test"); - *ctx = nullptr; - return GRPC_SECURITY_ERROR; + ctx.reset(DEBUG_LOCATION, "test"); + return nullptr; } - return GRPC_SECURITY_OK; + return ctx; } } // namespace internal } // namespace grpc_core -static void alts_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_security_status status; - status = grpc_core::internal::grpc_alts_auth_context_from_tsi_peer( - &peer, auth_context); - tsi_peer_destruct(&peer); - grpc_error* error = - status == GRPC_SECURITY_OK - ? GRPC_ERROR_NONE - : GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Could not get ALTS auth context from TSI peer"); - GRPC_CLOSURE_SCHED(on_peer_checked, error); -} - -static int alts_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_alts_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_alts_channel_security_connector* c2 = - reinterpret_cast(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - return strcmp(c1->target_name, c2->target_name); -} - -static int alts_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_alts_server_security_connector* c1 = - reinterpret_cast(sc1); - grpc_alts_server_security_connector* c2 = - reinterpret_cast(sc2); - return grpc_server_security_connector_cmp(&c1->base, &c2->base); -} - -static grpc_security_connector_vtable alts_channel_vtable = { - alts_channel_destroy, alts_check_peer, alts_channel_cmp}; - -static grpc_security_connector_vtable alts_server_vtable = { - alts_server_destroy, alts_check_peer, alts_server_cmp}; - -static bool alts_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_alts_channel_security_connector* alts_sc = - reinterpret_cast(sc); - if (host == nullptr || alts_sc == nullptr || - strcmp(host, alts_sc->target_name) != 0) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "ALTS call host does not match target name"); - } - return true; -} - -static void alts_cancel_check_call_host(grpc_channel_security_connector* sc, - grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} - -grpc_security_status grpc_alts_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target_name, - grpc_channel_security_connector** sc) { - if (channel_creds == nullptr || sc == nullptr || target_name == nullptr) { +grpc_core::RefCountedPtr +grpc_alts_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name) { + if (channel_creds == nullptr || target_name == nullptr) { gpr_log( GPR_ERROR, "Invalid arguments to grpc_alts_channel_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - auto c = static_cast( - gpr_zalloc(sizeof(grpc_alts_channel_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &alts_channel_vtable; - c->base.add_handshakers = alts_channel_add_handshakers; - c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = alts_check_call_host; - c->base.cancel_check_call_host = alts_cancel_check_call_host; - grpc_alts_credentials* creds = - reinterpret_cast(c->base.channel_creds); - alts_set_rpc_protocol_versions(&creds->options->rpc_versions); - c->target_name = gpr_strdup(target_name); - *sc = &c->base; - return GRPC_SECURITY_OK; + return grpc_core::MakeRefCounted( + std::move(channel_creds), std::move(request_metadata_creds), target_name); } -grpc_security_status grpc_alts_server_security_connector_create( - grpc_server_credentials* server_creds, - grpc_server_security_connector** sc) { - if (server_creds == nullptr || sc == nullptr) { +grpc_core::RefCountedPtr +grpc_alts_server_security_connector_create( + grpc_core::RefCountedPtr server_creds) { + if (server_creds == nullptr) { gpr_log( GPR_ERROR, "Invalid arguments to grpc_alts_server_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - auto c = static_cast( - gpr_zalloc(sizeof(grpc_alts_server_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &alts_server_vtable; - c->base.server_creds = grpc_server_credentials_ref(server_creds); - c->base.add_handshakers = alts_server_add_handshakers; - grpc_alts_server_credentials* creds = - reinterpret_cast(c->base.server_creds); - alts_set_rpc_protocol_versions(&creds->options->rpc_versions); - *sc = &c->base; - return GRPC_SECURITY_OK; + return grpc_core::MakeRefCounted( + std::move(server_creds)); } diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.h b/src/core/lib/security/security_connector/alts/alts_security_connector.h index d2e057a76aa..b96dc36b302 100644 --- a/src/core/lib/security/security_connector/alts/alts_security_connector.h +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.h @@ -36,12 +36,13 @@ * - sc: address of ALTS channel security connector instance to be returned from * the method. * - * It returns GRPC_SECURITY_OK on success, and an error stauts code on failure. + * It returns nullptr on failure. */ -grpc_security_status grpc_alts_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target_name, - grpc_channel_security_connector** sc); +grpc_core::RefCountedPtr +grpc_alts_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name); /** * This method creates an ALTS server security connector. @@ -50,17 +51,18 @@ grpc_security_status grpc_alts_channel_security_connector_create( * - sc: address of ALTS server security connector instance to be returned from * the method. * - * It returns GRPC_SECURITY_OK on success, and an error status code on failure. + * It returns nullptr on failure. */ -grpc_security_status grpc_alts_server_security_connector_create( - grpc_server_credentials* server_creds, grpc_server_security_connector** sc); +grpc_core::RefCountedPtr +grpc_alts_server_security_connector_create( + grpc_core::RefCountedPtr server_creds); namespace grpc_core { namespace internal { /* Exposed only for testing. */ -grpc_security_status grpc_alts_auth_context_from_tsi_peer( - const tsi_peer* peer, grpc_auth_context** ctx); +grpc_core::RefCountedPtr +grpc_alts_auth_context_from_tsi_peer(const tsi_peer* peer); } // namespace internal } // 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 5c0c89b88f2..d2cdaaac77c 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 @@ -31,6 +31,7 @@ #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" @@ -38,91 +39,183 @@ #include "src/core/lib/security/transport/target_authority_table.h" #include "src/core/tsi/fake_transport_security.h" -typedef struct { - grpc_channel_security_connector base; - char* target; - char* expected_targets; - bool is_lb_channel; - char* target_name_override; -} grpc_fake_channel_security_connector; - -static void fake_channel_destroy(grpc_security_connector* sc) { - grpc_fake_channel_security_connector* c = - reinterpret_cast(sc); - grpc_call_credentials_unref(c->base.request_metadata_creds); - gpr_free(c->target); - gpr_free(c->expected_targets); - gpr_free(c->target_name_override); - gpr_free(c); -} - -static void fake_server_destroy(grpc_security_connector* sc) { gpr_free(sc); } - -static bool fake_check_target(const char* target_type, const char* target, - const char* set_str) { - GPR_ASSERT(target_type != nullptr); - GPR_ASSERT(target != nullptr); - char** set = nullptr; - size_t set_size = 0; - gpr_string_split(set_str, ",", &set, &set_size); - bool found = false; - for (size_t i = 0; i < set_size; ++i) { - if (set[i] != nullptr && strcmp(target, set[i]) == 0) found = true; +namespace { +class grpc_fake_channel_security_connector final + : public grpc_channel_security_connector { + public: + grpc_fake_channel_security_connector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target, const grpc_channel_args* args) + : grpc_channel_security_connector(GRPC_FAKE_SECURITY_URL_SCHEME, + std::move(channel_creds), + std::move(request_metadata_creds)), + target_(gpr_strdup(target)), + expected_targets_( + gpr_strdup(grpc_fake_transport_get_expected_targets(args))), + is_lb_channel_(grpc_core::FindTargetAuthorityTableInArgs(args) != + 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) { + target_name_override_ = + gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg)); + } else { + target_name_override_ = nullptr; + } } - for (size_t i = 0; i < set_size; ++i) { - gpr_free(set[i]); - } - gpr_free(set); - return found; -} -static void fake_secure_name_check(const char* target, - const char* expected_targets, - bool is_lb_channel) { - if (expected_targets == nullptr) return; - char** lbs_and_backends = nullptr; - size_t lbs_and_backends_size = 0; - bool success = false; - gpr_string_split(expected_targets, ";", &lbs_and_backends, - &lbs_and_backends_size); - if (lbs_and_backends_size > 2 || lbs_and_backends_size == 0) { - gpr_log(GPR_ERROR, "Invalid expected targets arg value: '%s'", - expected_targets); - goto done; + ~grpc_fake_channel_security_connector() override { + gpr_free(target_); + gpr_free(expected_targets_); + if (target_name_override_ != nullptr) gpr_free(target_name_override_); } - if (is_lb_channel) { - if (lbs_and_backends_size != 2) { - gpr_log(GPR_ERROR, - "Invalid expected targets arg value: '%s'. Expectations for LB " - "channels must be of the form 'be1,be2,be3,...;lb1,lb2,...", - expected_targets); + + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override; + + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast(other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) return c; + c = strcmp(target_, other->target_); + if (c != 0) return c; + if (expected_targets_ == nullptr || other->expected_targets_ == nullptr) { + c = GPR_ICMP(expected_targets_, other->expected_targets_); + } else { + c = strcmp(expected_targets_, other->expected_targets_); + } + if (c != 0) return c; + return GPR_ICMP(is_lb_channel_, other->is_lb_channel_); + } + + 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)); + } + + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + char* authority_hostname = nullptr; + char* authority_ignored_port = nullptr; + char* target_hostname = nullptr; + char* target_ignored_port = nullptr; + gpr_split_host_port(host, &authority_hostname, &authority_ignored_port); + gpr_split_host_port(target_, &target_hostname, &target_ignored_port); + if (target_name_override_ != nullptr) { + char* fake_security_target_name_override_hostname = nullptr; + char* fake_security_target_name_override_ignored_port = nullptr; + gpr_split_host_port(target_name_override_, + &fake_security_target_name_override_hostname, + &fake_security_target_name_override_ignored_port); + if (strcmp(authority_hostname, + fake_security_target_name_override_hostname) != 0) { + gpr_log(GPR_ERROR, + "Authority (host) '%s' != Fake Security Target override '%s'", + host, fake_security_target_name_override_hostname); + abort(); + } + gpr_free(fake_security_target_name_override_hostname); + gpr_free(fake_security_target_name_override_ignored_port); + } else if (strcmp(authority_hostname, target_hostname) != 0) { + gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", + authority_hostname, target_hostname); + abort(); + } + gpr_free(authority_hostname); + gpr_free(authority_ignored_port); + gpr_free(target_hostname); + gpr_free(target_ignored_port); + return true; + } + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + char* target() const { return target_; } + char* expected_targets() const { return expected_targets_; } + bool is_lb_channel() const { return is_lb_channel_; } + char* target_name_override() const { return target_name_override_; } + + private: + bool fake_check_target(const char* target_type, const char* target, + const char* set_str) const { + GPR_ASSERT(target_type != nullptr); + GPR_ASSERT(target != nullptr); + char** set = nullptr; + size_t set_size = 0; + gpr_string_split(set_str, ",", &set, &set_size); + bool found = false; + for (size_t i = 0; i < set_size; ++i) { + if (set[i] != nullptr && strcmp(target, set[i]) == 0) found = true; + } + for (size_t i = 0; i < set_size; ++i) { + gpr_free(set[i]); + } + gpr_free(set); + return found; + } + + void fake_secure_name_check() const { + if (expected_targets_ == nullptr) return; + char** lbs_and_backends = nullptr; + size_t lbs_and_backends_size = 0; + bool success = false; + gpr_string_split(expected_targets_, ";", &lbs_and_backends, + &lbs_and_backends_size); + if (lbs_and_backends_size > 2 || lbs_and_backends_size == 0) { + gpr_log(GPR_ERROR, "Invalid expected targets arg value: '%s'", + expected_targets_); goto done; } - if (!fake_check_target("LB", target, lbs_and_backends[1])) { - gpr_log(GPR_ERROR, "LB target '%s' not found in expected set '%s'", - target, lbs_and_backends[1]); - goto done; + if (is_lb_channel_) { + if (lbs_and_backends_size != 2) { + gpr_log(GPR_ERROR, + "Invalid expected targets arg value: '%s'. Expectations for LB " + "channels must be of the form 'be1,be2,be3,...;lb1,lb2,...", + expected_targets_); + goto done; + } + if (!fake_check_target("LB", target_, lbs_and_backends[1])) { + gpr_log(GPR_ERROR, "LB target '%s' not found in expected set '%s'", + target_, lbs_and_backends[1]); + goto done; + } + success = true; + } else { + if (!fake_check_target("Backend", target_, lbs_and_backends[0])) { + gpr_log(GPR_ERROR, "Backend target '%s' not found in expected set '%s'", + target_, lbs_and_backends[0]); + goto done; + } + success = true; } - success = true; - } else { - if (!fake_check_target("Backend", target, lbs_and_backends[0])) { - gpr_log(GPR_ERROR, "Backend target '%s' not found in expected set '%s'", - target, lbs_and_backends[0]); - goto done; + done: + for (size_t i = 0; i < lbs_and_backends_size; ++i) { + gpr_free(lbs_and_backends[i]); } - success = true; + gpr_free(lbs_and_backends); + if (!success) abort(); } -done: - for (size_t i = 0; i < lbs_and_backends_size; ++i) { - gpr_free(lbs_and_backends[i]); - } - gpr_free(lbs_and_backends); - if (!success) abort(); -} -static void fake_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { + char* target_; + char* expected_targets_; + bool is_lb_channel_; + char* target_name_override_; +}; + +static void fake_check_peer( + grpc_security_connector* sc, tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { const char* prop_name; grpc_error* error = GRPC_ERROR_NONE; *auth_context = nullptr; @@ -147,164 +240,65 @@ static void fake_check_peer(grpc_security_connector* sc, tsi_peer peer, "Invalid value for cert type property."); goto end; } - *auth_context = grpc_auth_context_create(nullptr); + *auth_context = grpc_core::MakeRefCounted(nullptr); grpc_auth_context_add_cstring_property( - *auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + auth_context->get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_FAKE_TRANSPORT_SECURITY_TYPE); end: GRPC_CLOSURE_SCHED(on_peer_checked, error); tsi_peer_destruct(&peer); } -static void fake_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - fake_check_peer(sc, peer, auth_context, on_peer_checked); - grpc_fake_channel_security_connector* c = - reinterpret_cast(sc); - fake_secure_name_check(c->target, c->expected_targets, c->is_lb_channel); +void grpc_fake_channel_security_connector::check_peer( + tsi_peer peer, grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { + fake_check_peer(this, peer, auth_context, on_peer_checked); + fake_secure_name_check(); } -static void fake_server_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - fake_check_peer(sc, peer, auth_context, on_peer_checked); -} +class grpc_fake_server_security_connector + : public grpc_server_security_connector { + public: + grpc_fake_server_security_connector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(GRPC_FAKE_SECURITY_URL_SCHEME, + std::move(server_creds)) {} + ~grpc_fake_server_security_connector() override = default; -static int fake_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_fake_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_fake_channel_security_connector* c2 = - reinterpret_cast(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - c = strcmp(c1->target, c2->target); - if (c != 0) return c; - if (c1->expected_targets == nullptr || c2->expected_targets == nullptr) { - c = GPR_ICMP(c1->expected_targets, c2->expected_targets); - } else { - c = strcmp(c1->expected_targets, c2->expected_targets); + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + fake_check_peer(this, peer, auth_context, on_peer_checked); } - if (c != 0) return c; - return GPR_ICMP(c1->is_lb_channel, c2->is_lb_channel); -} -static int fake_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - return grpc_server_security_connector_cmp( - reinterpret_cast(sc1), - reinterpret_cast(sc2)); -} - -static bool fake_channel_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_fake_channel_security_connector* c = - reinterpret_cast(sc); - char* authority_hostname = nullptr; - char* authority_ignored_port = nullptr; - char* target_hostname = nullptr; - char* target_ignored_port = nullptr; - gpr_split_host_port(host, &authority_hostname, &authority_ignored_port); - gpr_split_host_port(c->target, &target_hostname, &target_ignored_port); - if (c->target_name_override != nullptr) { - char* fake_security_target_name_override_hostname = nullptr; - char* fake_security_target_name_override_ignored_port = nullptr; - gpr_split_host_port(c->target_name_override, - &fake_security_target_name_override_hostname, - &fake_security_target_name_override_ignored_port); - if (strcmp(authority_hostname, - fake_security_target_name_override_hostname) != 0) { - gpr_log(GPR_ERROR, - "Authority (host) '%s' != Fake Security Target override '%s'", - host, fake_security_target_name_override_hostname); - abort(); - } - gpr_free(fake_security_target_name_override_hostname); - gpr_free(fake_security_target_name_override_ignored_port); - } else if (strcmp(authority_hostname, target_hostname) != 0) { - gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", - authority_hostname, target_hostname); - abort(); + 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)); } - gpr_free(authority_hostname); - gpr_free(authority_ignored_port); - gpr_free(target_hostname); - gpr_free(target_ignored_port); - return true; -} -static void fake_channel_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} - -static void fake_channel_add_handshakers( - grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add( - handshake_mgr, - grpc_security_handshaker_create( - tsi_create_fake_handshaker(true /* is_client */), &sc->base)); -} - -static void fake_server_add_handshakers(grpc_server_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add( - handshake_mgr, - grpc_security_handshaker_create( - tsi_create_fake_handshaker(false /* is_client */), &sc->base)); -} - -static grpc_security_connector_vtable fake_channel_vtable = { - fake_channel_destroy, fake_channel_check_peer, fake_channel_cmp}; - -static grpc_security_connector_vtable fake_server_vtable = { - fake_server_destroy, fake_server_check_peer, fake_server_cmp}; - -grpc_channel_security_connector* grpc_fake_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target, - const grpc_channel_args* args) { - grpc_fake_channel_security_connector* c = - static_cast( - gpr_zalloc(sizeof(*c))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; - c->base.base.vtable = &fake_channel_vtable; - c->base.channel_creds = channel_creds; - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = fake_channel_check_call_host; - c->base.cancel_check_call_host = fake_channel_cancel_check_call_host; - c->base.add_handshakers = fake_channel_add_handshakers; - c->target = gpr_strdup(target); - const char* expected_targets = grpc_fake_transport_get_expected_targets(args); - c->expected_targets = gpr_strdup(expected_targets); - c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != 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) { - c->target_name_override = - gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg)); + int cmp(const grpc_security_connector* other) const override { + return server_security_connector_cmp( + static_cast(other)); } - return &c->base; +}; +} // namespace + +grpc_core::RefCountedPtr +grpc_fake_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target, const grpc_channel_args* args) { + return grpc_core::MakeRefCounted( + std::move(channel_creds), std::move(request_metadata_creds), target, + args); } -grpc_server_security_connector* grpc_fake_server_security_connector_create( - grpc_server_credentials* server_creds) { - grpc_server_security_connector* c = - static_cast( - gpr_zalloc(sizeof(grpc_server_security_connector))); - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &fake_server_vtable; - c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; - c->server_creds = server_creds; - c->add_handshakers = fake_server_add_handshakers; - return c; +grpc_core::RefCountedPtr +grpc_fake_server_security_connector_create( + grpc_core::RefCountedPtr server_creds) { + return grpc_core::MakeRefCounted( + std::move(server_creds)); } diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.h b/src/core/lib/security/security_connector/fake/fake_security_connector.h index fdfe048c6e7..344a2349a49 100644 --- a/src/core/lib/security/security_connector/fake/fake_security_connector.h +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.h @@ -24,19 +24,22 @@ #include #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/security_connector/security_connector.h" #define GRPC_FAKE_SECURITY_URL_SCHEME "http+fake_security" /* Creates a fake connector that emulates real channel security. */ -grpc_channel_security_connector* grpc_fake_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target, - const grpc_channel_args* args); +grpc_core::RefCountedPtr +grpc_fake_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target, const grpc_channel_args* args); /* Creates a fake connector that emulates real server security. */ -grpc_server_security_connector* grpc_fake_server_security_connector_create( - grpc_server_credentials* server_creds); +grpc_core::RefCountedPtr +grpc_fake_server_security_connector_create( + grpc_core::RefCountedPtr server_creds); #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_FAKE_FAKE_SECURITY_CONNECTOR_H \ */ 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 008a98df281..7a59e54e9a7 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 @@ -30,6 +30,7 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/security/credentials/local/local_credentials.h" #include "src/core/lib/security/transport/security_handshaker.h" @@ -39,153 +40,145 @@ #define GRPC_UDS_URL_SCHEME "unix" #define GRPC_LOCAL_TRANSPORT_SECURITY_TYPE "local" -typedef struct { - grpc_channel_security_connector base; - char* target_name; -} grpc_local_channel_security_connector; +namespace { -typedef struct { - grpc_server_security_connector base; -} grpc_local_server_security_connector; - -static void local_channel_destroy(grpc_security_connector* sc) { - if (sc == nullptr) { - return; - } - auto c = reinterpret_cast(sc); - grpc_call_credentials_unref(c->base.request_metadata_creds); - grpc_channel_credentials_unref(c->base.channel_creds); - gpr_free(c->target_name); - gpr_free(sc); -} - -static void local_server_destroy(grpc_security_connector* sc) { - if (sc == nullptr) { - return; - } - auto c = reinterpret_cast(sc); - grpc_server_credentials_unref(c->base.server_creds); - gpr_free(sc); -} - -static void local_channel_add_handshakers( - grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) { - 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, &sc->base)); -} - -static void local_server_add_handshakers( - grpc_server_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) { - 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, &sc->base)); -} - -static int local_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_local_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_local_channel_security_connector* c2 = - reinterpret_cast(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - return strcmp(c1->target_name, c2->target_name); -} - -static int local_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_local_server_security_connector* c1 = - reinterpret_cast(sc1); - grpc_local_server_security_connector* c2 = - reinterpret_cast(sc2); - return grpc_server_security_connector_cmp(&c1->base, &c2->base); -} - -static grpc_security_status local_auth_context_create(grpc_auth_context** ctx) { - if (ctx == nullptr) { - gpr_log(GPR_ERROR, "Invalid arguments to local_auth_context_create()"); - return GRPC_SECURITY_ERROR; - } +grpc_core::RefCountedPtr local_auth_context_create() { /* Create auth context. */ - *ctx = grpc_auth_context_create(nullptr); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); grpc_auth_context_add_cstring_property( - *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_LOCAL_TRANSPORT_SECURITY_TYPE); GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( - *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME) == 1); - return GRPC_SECURITY_OK; + ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME) == 1); + return ctx; } -static void local_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_security_status status; +void local_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { /* Create an auth context which is necessary to pass the santiy check in - * {client, server}_auth_filter that verifies if the peer's auth context is + * {client, server}_auth_filter that verifies if the pepp's auth context is * obtained during handshakes. The auth context is only checked for its * existence and not actually used. */ - status = local_auth_context_create(auth_context); - grpc_error* error = status == GRPC_SECURITY_OK + *auth_context = local_auth_context_create(); + grpc_error* error = *auth_context != nullptr ? GRPC_ERROR_NONE : GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Could not create local auth context"); GRPC_CLOSURE_SCHED(on_peer_checked, error); } -static grpc_security_connector_vtable local_channel_vtable = { - local_channel_destroy, local_check_peer, local_channel_cmp}; +class grpc_local_channel_security_connector final + : public grpc_channel_security_connector { + public: + grpc_local_channel_security_connector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name) + : grpc_channel_security_connector(GRPC_UDS_URL_SCHEME, + std::move(channel_creds), + std::move(request_metadata_creds)), + target_name_(gpr_strdup(target_name)) {} -static grpc_security_connector_vtable local_server_vtable = { - local_server_destroy, local_check_peer, local_server_cmp}; + ~grpc_local_channel_security_connector() override { gpr_free(target_name_); } -static bool local_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_local_channel_security_connector* local_sc = - reinterpret_cast(sc); - if (host == nullptr || local_sc == nullptr || - strcmp(host, local_sc->target_name) != 0) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "local call host does not match target name"); + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* 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)); } - return true; -} -static void local_cancel_check_call_host(grpc_channel_security_connector* sc, - grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast( + other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) return c; + return strcmp(target_name_, other->target_name_); + } -grpc_security_status grpc_local_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, - const grpc_channel_args* args, const char* target_name, - grpc_channel_security_connector** sc) { - if (channel_creds == nullptr || sc == nullptr || target_name == nullptr) { + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + local_check_peer(this, peer, auth_context, on_peer_checked); + } + + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + if (host == nullptr || strcmp(host, target_name_) != 0) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "local call host does not match target name"); + } + return true; + } + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + const char* target_name() const { return target_name_; } + + private: + char* target_name_; +}; + +class grpc_local_server_security_connector final + : public grpc_server_security_connector { + public: + grpc_local_server_security_connector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(GRPC_UDS_URL_SCHEME, + 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 { + 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)); + } + + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + local_check_peer(this, peer, auth_context, on_peer_checked); + } + + int cmp(const grpc_security_connector* other) const override { + return server_security_connector_cmp( + static_cast(other)); + } +}; +} // namespace + +grpc_core::RefCountedPtr +grpc_local_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const grpc_channel_args* args, const char* target_name) { + if (channel_creds == nullptr || target_name == nullptr) { gpr_log( GPR_ERROR, "Invalid arguments to grpc_local_channel_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } // Check if local_connect_type is UDS. Only UDS is supported for now. grpc_local_credentials* creds = - reinterpret_cast(channel_creds); - if (creds->connect_type != UDS) { + static_cast(channel_creds.get()); + if (creds->connect_type() != UDS) { gpr_log(GPR_ERROR, "Invalid local channel type to " "grpc_local_channel_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } // Check if target_name is a valid UDS address. const grpc_arg* server_uri_arg = @@ -196,51 +189,30 @@ grpc_security_status grpc_local_channel_security_connector_create( gpr_log(GPR_ERROR, "Invalid target_name to " "grpc_local_channel_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - auto c = static_cast( - gpr_zalloc(sizeof(grpc_local_channel_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &local_channel_vtable; - c->base.add_handshakers = local_channel_add_handshakers; - c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = local_check_call_host; - c->base.cancel_check_call_host = local_cancel_check_call_host; - c->base.base.url_scheme = - creds->connect_type == UDS ? GRPC_UDS_URL_SCHEME : nullptr; - c->target_name = gpr_strdup(target_name); - *sc = &c->base; - return GRPC_SECURITY_OK; + return grpc_core::MakeRefCounted( + channel_creds, request_metadata_creds, target_name); } -grpc_security_status grpc_local_server_security_connector_create( - grpc_server_credentials* server_creds, - grpc_server_security_connector** sc) { - if (server_creds == nullptr || sc == nullptr) { +grpc_core::RefCountedPtr +grpc_local_server_security_connector_create( + grpc_core::RefCountedPtr server_creds) { + if (server_creds == nullptr) { gpr_log( GPR_ERROR, "Invalid arguments to grpc_local_server_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } // Check if local_connect_type is UDS. Only UDS is supported for now. - grpc_local_server_credentials* creds = - reinterpret_cast(server_creds); - if (creds->connect_type != UDS) { + const grpc_local_server_credentials* creds = + static_cast(server_creds.get()); + if (creds->connect_type() != UDS) { gpr_log(GPR_ERROR, "Invalid local server type to " "grpc_local_server_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - auto c = static_cast( - gpr_zalloc(sizeof(grpc_local_server_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &local_server_vtable; - c->base.server_creds = grpc_server_credentials_ref(server_creds); - c->base.base.url_scheme = - creds->connect_type == UDS ? GRPC_UDS_URL_SCHEME : nullptr; - c->base.add_handshakers = local_server_add_handshakers; - *sc = &c->base; - return GRPC_SECURITY_OK; + return grpc_core::MakeRefCounted( + std::move(server_creds)); } diff --git a/src/core/lib/security/security_connector/local/local_security_connector.h b/src/core/lib/security/security_connector/local/local_security_connector.h index 5369a2127aa..6eee0ca9a6c 100644 --- a/src/core/lib/security/security_connector/local/local_security_connector.h +++ b/src/core/lib/security/security_connector/local/local_security_connector.h @@ -34,13 +34,13 @@ * - sc: address of local channel security connector instance to be returned * from the method. * - * It returns GRPC_SECURITY_OK on success, and an error stauts code on failure. + * It returns nullptr on failure. */ -grpc_security_status grpc_local_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, - const grpc_channel_args* args, const char* target_name, - grpc_channel_security_connector** sc); +grpc_core::RefCountedPtr +grpc_local_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const grpc_channel_args* args, const char* target_name); /** * This method creates a local server security connector. @@ -49,10 +49,11 @@ grpc_security_status grpc_local_channel_security_connector_create( * - sc: address of local server security connector instance to be returned from * the method. * - * It returns GRPC_SECURITY_OK on success, and an error status code on failure. + * It returns nullptr on failure. */ -grpc_security_status grpc_local_server_security_connector_create( - grpc_server_credentials* server_creds, grpc_server_security_connector** sc); +grpc_core::RefCountedPtr +grpc_local_server_security_connector_create( + grpc_core::RefCountedPtr server_creds); #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_LOCAL_SECURITY_CONNECTOR_H \ */ diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 02cecb0eb1e..96a19605466 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -35,150 +35,67 @@ #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/load_system_roots.h" +#include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/lib/security/transport/security_handshaker.h" grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount( false, "security_connector_refcount"); -void grpc_channel_security_connector_add_handshakers( - grpc_channel_security_connector* connector, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - if (connector != nullptr) { - connector->add_handshakers(connector, interested_parties, handshake_mgr); - } -} +grpc_server_security_connector::grpc_server_security_connector( + const char* url_scheme, + grpc_core::RefCountedPtr server_creds) + : grpc_security_connector(url_scheme), + server_creds_(std::move(server_creds)) {} -void grpc_server_security_connector_add_handshakers( - grpc_server_security_connector* connector, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - if (connector != nullptr) { - connector->add_handshakers(connector, interested_parties, handshake_mgr); - } -} +grpc_channel_security_connector::grpc_channel_security_connector( + const char* url_scheme, + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds) + : grpc_security_connector(url_scheme), + channel_creds_(std::move(channel_creds)), + request_metadata_creds_(std::move(request_metadata_creds)) {} +grpc_channel_security_connector::~grpc_channel_security_connector() {} -void grpc_security_connector_check_peer(grpc_security_connector* sc, - tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - if (sc == nullptr) { - GRPC_CLOSURE_SCHED(on_peer_checked, - GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "cannot check peer -- no security connector")); - tsi_peer_destruct(&peer); - } else { - sc->vtable->check_peer(sc, peer, auth_context, on_peer_checked); - } -} - -int grpc_security_connector_cmp(grpc_security_connector* sc, - grpc_security_connector* other) { +int grpc_security_connector_cmp(const grpc_security_connector* sc, + const grpc_security_connector* other) { if (sc == nullptr || other == nullptr) return GPR_ICMP(sc, other); - int c = GPR_ICMP(sc->vtable, other->vtable); - if (c != 0) return c; - return sc->vtable->cmp(sc, other); + return sc->cmp(other); } -int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1, - grpc_channel_security_connector* sc2) { - GPR_ASSERT(sc1->channel_creds != nullptr); - GPR_ASSERT(sc2->channel_creds != nullptr); - int c = GPR_ICMP(sc1->channel_creds, sc2->channel_creds); +int grpc_channel_security_connector::channel_security_connector_cmp( + const grpc_channel_security_connector* other) const { + const grpc_channel_security_connector* other_sc = + static_cast(other); + GPR_ASSERT(channel_creds() != nullptr); + GPR_ASSERT(other_sc->channel_creds() != nullptr); + int c = GPR_ICMP(channel_creds(), other_sc->channel_creds()); if (c != 0) return c; - c = GPR_ICMP(sc1->request_metadata_creds, sc2->request_metadata_creds); - if (c != 0) return c; - c = GPR_ICMP((void*)sc1->check_call_host, (void*)sc2->check_call_host); - if (c != 0) return c; - c = GPR_ICMP((void*)sc1->cancel_check_call_host, - (void*)sc2->cancel_check_call_host); - if (c != 0) return c; - return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers); + return GPR_ICMP(request_metadata_creds(), other_sc->request_metadata_creds()); } -int grpc_server_security_connector_cmp(grpc_server_security_connector* sc1, - grpc_server_security_connector* sc2) { - GPR_ASSERT(sc1->server_creds != nullptr); - GPR_ASSERT(sc2->server_creds != nullptr); - int c = GPR_ICMP(sc1->server_creds, sc2->server_creds); - if (c != 0) return c; - return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers); -} - -bool grpc_channel_security_connector_check_call_host( - grpc_channel_security_connector* sc, const char* host, - grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, - grpc_error** error) { - if (sc == nullptr || sc->check_call_host == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "cannot check call host -- no security connector"); - return true; - } - return sc->check_call_host(sc, host, auth_context, on_call_host_checked, - error); -} - -void grpc_channel_security_connector_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error) { - if (sc == nullptr || sc->cancel_check_call_host == nullptr) { - GRPC_ERROR_UNREF(error); - return; - } - sc->cancel_check_call_host(sc, on_call_host_checked, error); -} - -#ifndef NDEBUG -grpc_security_connector* grpc_security_connector_ref( - grpc_security_connector* sc, const char* file, int line, - const char* reason) { - if (sc == nullptr) return nullptr; - if (grpc_trace_security_connector_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SECURITY_CONNECTOR:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", sc, - val, val + 1, reason); - } -#else -grpc_security_connector* grpc_security_connector_ref( - grpc_security_connector* sc) { - if (sc == nullptr) return nullptr; -#endif - gpr_ref(&sc->refcount); - return sc; -} - -#ifndef NDEBUG -void grpc_security_connector_unref(grpc_security_connector* sc, - const char* file, int line, - const char* reason) { - if (sc == nullptr) return; - if (grpc_trace_security_connector_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SECURITY_CONNECTOR:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", sc, - val, val - 1, reason); - } -#else -void grpc_security_connector_unref(grpc_security_connector* sc) { - if (sc == nullptr) return; -#endif - if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc); +int grpc_server_security_connector::server_security_connector_cmp( + const grpc_server_security_connector* other) const { + const grpc_server_security_connector* other_sc = + static_cast(other); + GPR_ASSERT(server_creds() != nullptr); + GPR_ASSERT(other_sc->server_creds() != nullptr); + return GPR_ICMP(server_creds(), other_sc->server_creds()); } static void connector_arg_destroy(void* p) { - GRPC_SECURITY_CONNECTOR_UNREF((grpc_security_connector*)p, - "connector_arg_destroy"); + static_cast(p)->Unref(DEBUG_LOCATION, + "connector_arg_destroy"); } static void* connector_arg_copy(void* p) { - return GRPC_SECURITY_CONNECTOR_REF((grpc_security_connector*)p, - "connector_arg_copy"); + return static_cast(p) + ->Ref(DEBUG_LOCATION, "connector_arg_copy") + .release(); } static int connector_cmp(void* a, void* b) { - return grpc_security_connector_cmp(static_cast(a), - static_cast(b)); + return static_cast(a)->cmp( + static_cast(b)); } static const grpc_arg_pointer_vtable connector_arg_vtable = { diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index 4c921a87931..d90aa8c4dab 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.h @@ -26,6 +26,7 @@ #include #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/tcp_server.h" @@ -34,8 +35,6 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount; -/* --- status enum. --- */ - typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status; /* --- security_connector object. --- @@ -43,55 +42,34 @@ typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status; A security connector object represents away to configure the underlying transport security mechanism and check the resulting trusted peer. */ -typedef struct grpc_security_connector grpc_security_connector; - #define GRPC_ARG_SECURITY_CONNECTOR "grpc.security_connector" -typedef struct { - void (*destroy)(grpc_security_connector* sc); - void (*check_peer)(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked); - int (*cmp)(grpc_security_connector* sc, grpc_security_connector* other); -} grpc_security_connector_vtable; +class grpc_security_connector + : public grpc_core::RefCounted { + public: + explicit grpc_security_connector(const char* url_scheme) + : grpc_core::RefCounted( + &grpc_trace_security_connector_refcount), + url_scheme_(url_scheme) {} + virtual ~grpc_security_connector() = default; -struct grpc_security_connector { - const grpc_security_connector_vtable* vtable; - gpr_refcount refcount; - const char* url_scheme; + /* Check the peer. Callee takes ownership of the peer object. + When done, sets *auth_context and invokes on_peer_checked. */ + virtual void check_peer( + tsi_peer peer, grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) GRPC_ABSTRACT; + + /* Compares two security connectors. */ + virtual int cmp(const grpc_security_connector* other) const GRPC_ABSTRACT; + + const char* url_scheme() const { return url_scheme_; } + + GRPC_ABSTRACT_BASE_CLASS + + private: + const char* url_scheme_; }; -/* Refcounting. */ -#ifndef NDEBUG -#define GRPC_SECURITY_CONNECTOR_REF(p, r) \ - grpc_security_connector_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) \ - grpc_security_connector_unref((p), __FILE__, __LINE__, (r)) -grpc_security_connector* grpc_security_connector_ref( - grpc_security_connector* policy, const char* file, int line, - const char* reason); -void grpc_security_connector_unref(grpc_security_connector* policy, - const char* file, int line, - const char* reason); -#else -#define GRPC_SECURITY_CONNECTOR_REF(p, r) grpc_security_connector_ref((p)) -#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) grpc_security_connector_unref((p)) -grpc_security_connector* grpc_security_connector_ref( - grpc_security_connector* policy); -void grpc_security_connector_unref(grpc_security_connector* policy); -#endif - -/* Check the peer. Callee takes ownership of the peer object. - When done, sets *auth_context and invokes on_peer_checked. */ -void grpc_security_connector_check_peer(grpc_security_connector* sc, - tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked); - -/* Compares two security connectors. */ -int grpc_security_connector_cmp(grpc_security_connector* sc, - grpc_security_connector* other); - /* Util to encapsulate the connector in a channel arg. */ grpc_arg grpc_security_connector_to_arg(grpc_security_connector* sc); @@ -107,71 +85,89 @@ grpc_security_connector* grpc_security_connector_find_in_args( A channel security connector object represents a way to configure the underlying transport security mechanism on the client side. */ -typedef struct grpc_channel_security_connector grpc_channel_security_connector; +class grpc_channel_security_connector : public grpc_security_connector { + public: + grpc_channel_security_connector( + const char* url_scheme, + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds); + ~grpc_channel_security_connector() override; -struct grpc_channel_security_connector { - grpc_security_connector base; - grpc_channel_credentials* channel_creds; - grpc_call_credentials* request_metadata_creds; - bool (*check_call_host)(grpc_channel_security_connector* sc, const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error); - void (*cancel_check_call_host)(grpc_channel_security_connector* sc, - grpc_closure* on_call_host_checked, - grpc_error* error); - void (*add_handshakers)(grpc_channel_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); + /// Checks that the host that will be set for a call is acceptable. + /// Returns true if completed synchronously, in which case \a error will + /// be set to indicate the result. Otherwise, \a on_call_host_checked + /// will be invoked when complete. + virtual bool check_call_host(const char* host, + grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) GRPC_ABSTRACT; + /// Cancels a pending asychronous call to + /// grpc_channel_security_connector_check_call_host() with + /// \a on_call_host_checked as its callback. + virtual void cancel_check_call_host(grpc_closure* on_call_host_checked, + 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_ABSTRACT; + + const grpc_channel_credentials* channel_creds() const { + return channel_creds_.get(); + } + grpc_channel_credentials* mutable_channel_creds() { + return channel_creds_.get(); + } + const grpc_call_credentials* request_metadata_creds() const { + return request_metadata_creds_.get(); + } + grpc_call_credentials* mutable_request_metadata_creds() { + return request_metadata_creds_.get(); + } + + GRPC_ABSTRACT_BASE_CLASS + + protected: + // Helper methods to be used in subclasses. + int channel_security_connector_cmp( + const grpc_channel_security_connector* other) const; + + private: + grpc_core::RefCountedPtr channel_creds_; + grpc_core::RefCountedPtr request_metadata_creds_; }; -/// A helper function for use in grpc_security_connector_cmp() implementations. -int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1, - grpc_channel_security_connector* sc2); - -/// Checks that the host that will be set for a call is acceptable. -/// Returns true if completed synchronously, in which case \a error will -/// be set to indicate the result. Otherwise, \a on_call_host_checked -/// will be invoked when complete. -bool grpc_channel_security_connector_check_call_host( - grpc_channel_security_connector* sc, const char* host, - grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, - grpc_error** error); - -/// Cancels a pending asychronous call to -/// grpc_channel_security_connector_check_call_host() with -/// \a on_call_host_checked as its callback. -void grpc_channel_security_connector_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error); - -/* Registers handshakers with \a handshake_mgr. */ -void grpc_channel_security_connector_add_handshakers( - grpc_channel_security_connector* connector, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); - /* --- server_security_connector object. --- A server security connector object represents a way to configure the underlying transport security mechanism on the server side. */ -typedef struct grpc_server_security_connector grpc_server_security_connector; +class grpc_server_security_connector : public grpc_security_connector { + public: + grpc_server_security_connector( + const char* url_scheme, + grpc_core::RefCountedPtr server_creds); + ~grpc_server_security_connector() override = default; -struct grpc_server_security_connector { - grpc_security_connector base; - grpc_server_credentials* server_creds; - void (*add_handshakers)(grpc_server_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); + virtual void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) + GRPC_ABSTRACT; + + const grpc_server_credentials* server_creds() const { + return server_creds_.get(); + } + grpc_server_credentials* mutable_server_creds() { + return server_creds_.get(); + } + + GRPC_ABSTRACT_BASE_CLASS + + protected: + // Helper methods to be used in subclasses. + int server_security_connector_cmp( + const grpc_server_security_connector* other) const; + + private: + grpc_core::RefCountedPtr server_creds_; }; -/// A helper function for use in grpc_security_connector_cmp() implementations. -int grpc_server_security_connector_cmp(grpc_server_security_connector* sc1, - grpc_server_security_connector* sc2); - -void grpc_server_security_connector_add_handshakers( - grpc_server_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); - #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SECURITY_CONNECTOR_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 20a9533dd13..14b2c4030f2 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 @@ -30,6 +30,7 @@ #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/ssl/ssl_credentials.h" @@ -39,172 +40,10 @@ #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security.h" -typedef struct { - grpc_channel_security_connector base; - tsi_ssl_client_handshaker_factory* client_handshaker_factory; - char* target_name; - char* overridden_target_name; - const verify_peer_options* verify_options; -} grpc_ssl_channel_security_connector; - -typedef struct { - grpc_server_security_connector base; - tsi_ssl_server_handshaker_factory* server_handshaker_factory; -} grpc_ssl_server_security_connector; - -static bool server_connector_has_cert_config_fetcher( - grpc_ssl_server_security_connector* c) { - GPR_ASSERT(c != nullptr); - grpc_ssl_server_credentials* server_creds = - reinterpret_cast(c->base.server_creds); - GPR_ASSERT(server_creds != nullptr); - return server_creds->certificate_config_fetcher.cb != nullptr; -} - -static void ssl_channel_destroy(grpc_security_connector* sc) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast(sc); - grpc_channel_credentials_unref(c->base.channel_creds); - grpc_call_credentials_unref(c->base.request_metadata_creds); - tsi_ssl_client_handshaker_factory_unref(c->client_handshaker_factory); - c->client_handshaker_factory = nullptr; - if (c->target_name != nullptr) gpr_free(c->target_name); - if (c->overridden_target_name != nullptr) gpr_free(c->overridden_target_name); - gpr_free(sc); -} - -static void ssl_server_destroy(grpc_security_connector* sc) { - grpc_ssl_server_security_connector* c = - reinterpret_cast(sc); - grpc_server_credentials_unref(c->base.server_creds); - tsi_ssl_server_handshaker_factory_unref(c->server_handshaker_factory); - c->server_handshaker_factory = nullptr; - gpr_free(sc); -} - -static void ssl_channel_add_handshakers(grpc_channel_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast(sc); - // Instantiate TSI handshaker. - tsi_handshaker* tsi_hs = nullptr; - tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( - c->client_handshaker_factory, - c->overridden_target_name != nullptr ? c->overridden_target_name - : c->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. - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); -} - -/* Attempts to replace the server_handshaker_factory with a new factory using - * the provided grpc_ssl_server_certificate_config. Should new factory creation - * fail, the existing factory will not be replaced. Returns true on success (new - * factory created). */ -static bool try_replace_server_handshaker_factory( - grpc_ssl_server_security_connector* sc, - const grpc_ssl_server_certificate_config* config) { - if (config == nullptr) { - gpr_log(GPR_ERROR, - "Server certificate config callback returned invalid (NULL) " - "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_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; - grpc_ssl_server_credentials* server_creds = - reinterpret_cast(sc->base.server_creds); - tsi_result result = tsi_create_ssl_server_handshaker_factory_ex( - cert_pairs, config->num_key_cert_pairs, config->pem_root_certs, - 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); - 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; - } - tsi_ssl_server_handshaker_factory_unref(sc->server_handshaker_factory); - sc->server_handshaker_factory = new_handshaker_factory; - return true; -} - -/* Attempts to fetch the server certificate config if a callback is available. - * Current certificate config will continue to be used if the callback returns - * an error. Returns true if new credentials were sucessfully loaded. */ -static bool try_fetch_ssl_server_credentials( - grpc_ssl_server_security_connector* sc) { - grpc_ssl_server_certificate_config* certificate_config = nullptr; - bool status; - - GPR_ASSERT(sc != nullptr); - if (!server_connector_has_cert_config_fetcher(sc)) return false; - - grpc_ssl_server_credentials* server_creds = - reinterpret_cast(sc->base.server_creds); - grpc_ssl_certificate_config_reload_status cb_result = - server_creds->certificate_config_fetcher.cb( - server_creds->certificate_config_fetcher.user_data, - &certificate_config); - if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) { - gpr_log(GPR_DEBUG, "No change in SSL server credentials."); - status = false; - } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) { - status = try_replace_server_handshaker_factory(sc, certificate_config); - } else { - // Log error, continue using previously-loaded credentials. - gpr_log(GPR_ERROR, - "Failed fetching new server credentials, continuing to " - "use previously-loaded credentials."); - status = false; - } - - if (certificate_config != nullptr) { - grpc_ssl_server_certificate_config_destroy(certificate_config); - } - return status; -} - -static void ssl_server_add_handshakers(grpc_server_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_ssl_server_security_connector* c = - reinterpret_cast(sc); - // Instantiate TSI handshaker. - try_fetch_ssl_server_credentials(c); - tsi_handshaker* tsi_hs = nullptr; - tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker( - c->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; - } - // Create handshakers. - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); -} - -static grpc_error* ssl_check_peer(grpc_security_connector* sc, - const char* peer_name, const tsi_peer* peer, - grpc_auth_context** auth_context) { +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 = @@ -230,245 +69,384 @@ static grpc_error* ssl_check_peer(grpc_security_connector* sc, return GRPC_ERROR_NONE; } -static void ssl_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast(sc); - const char* target_name = c->overridden_target_name != nullptr - ? c->overridden_target_name - : c->target_name; - grpc_error* error = ssl_check_peer(sc, target_name, &peer, auth_context); - if (error == GRPC_ERROR_NONE && - c->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 = c->verify_options->verify_peer_callback( - target_name, peer_pem, - c->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); - } +class grpc_ssl_channel_security_connector final + : public grpc_channel_security_connector { + public: + grpc_ssl_channel_security_connector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const grpc_ssl_config* config, 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)), + verify_options_(&config->verify_options) { + char* port; + gpr_split_host_port(target_name, &target_name_, &port); + gpr_free(port); + } + + ~grpc_ssl_channel_security_connector() override { + tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); + if (target_name_ != nullptr) gpr_free(target_name_); + if (overridden_target_name_ != nullptr) gpr_free(overridden_target_name_); + } + + 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; + memset(&options, 0, sizeof(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; } - } - GRPC_CLOSURE_SCHED(on_peer_checked, error); - tsi_peer_destruct(&peer); -} - -static void ssl_server_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_error* error = ssl_check_peer(sc, nullptr, &peer, auth_context); - tsi_peer_destruct(&peer); - GRPC_CLOSURE_SCHED(on_peer_checked, error); -} - -static int ssl_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_ssl_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_ssl_channel_security_connector* c2 = - reinterpret_cast(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - c = strcmp(c1->target_name, c2->target_name); - if (c != 0) return c; - return (c1->overridden_target_name == nullptr || - c2->overridden_target_name == nullptr) - ? GPR_ICMP(c1->overridden_target_name, c2->overridden_target_name) - : strcmp(c1->overridden_target_name, c2->overridden_target_name); -} - -static int ssl_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - return grpc_server_security_connector_cmp( - reinterpret_cast(sc1), - reinterpret_cast(sc2)); -} - -static bool ssl_channel_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast(sc); - 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 (c->overridden_target_name != nullptr && - strcmp(host, c->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; -} - -static void ssl_channel_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} - -static grpc_security_connector_vtable ssl_channel_vtable = { - ssl_channel_destroy, ssl_channel_check_peer, ssl_channel_cmp}; - -static grpc_security_connector_vtable ssl_server_vtable = { - ssl_server_destroy, ssl_server_check_peer, ssl_server_cmp}; - -grpc_security_status grpc_ssl_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, - const grpc_ssl_config* config, const char* target_name, - const char* overridden_target_name, - tsi_ssl_session_cache* ssl_session_cache, - grpc_channel_security_connector** sc) { - tsi_result result = TSI_OK; - grpc_ssl_channel_security_connector* c; - char* port; - bool has_key_cert_pair; - tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); - options.alpn_protocols = - grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols); - - if (config == nullptr || target_name == nullptr) { - gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); - goto error; - } - if (config->pem_root_certs == nullptr) { - // Use default root certificates. - options.pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); - options.root_store = grpc_core::DefaultSslRootStore::GetRootStore(); - if (options.pem_root_certs == nullptr) { - gpr_log(GPR_ERROR, "Could not get default pem root certs."); - goto error; - } - } else { - options.pem_root_certs = config->pem_root_certs; - } - c = static_cast( - gpr_zalloc(sizeof(grpc_ssl_channel_security_connector))); - - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &ssl_channel_vtable; - c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; - c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = ssl_channel_check_call_host; - c->base.cancel_check_call_host = ssl_channel_cancel_check_call_host; - c->base.add_handshakers = ssl_channel_add_handshakers; - gpr_split_host_port(target_name, &c->target_name, &port); - gpr_free(port); - if (overridden_target_name != nullptr) { - c->overridden_target_name = gpr_strdup(overridden_target_name); - } - c->verify_options = &config->verify_options; - - 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; - 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; - result = tsi_create_ssl_client_handshaker_factory_with_options( - &options, &c->client_handshaker_factory); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - ssl_channel_destroy(&c->base.base); - *sc = nullptr; - goto error; - } - *sc = &c->base; - gpr_free((void*)options.alpn_protocols); - return GRPC_SECURITY_OK; - -error: - gpr_free((void*)options.alpn_protocols); - return GRPC_SECURITY_ERROR; -} - -static grpc_ssl_server_security_connector* -grpc_ssl_server_security_connector_initialize( - grpc_server_credentials* server_creds) { - grpc_ssl_server_security_connector* c = - static_cast( - gpr_zalloc(sizeof(grpc_ssl_server_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; - c->base.base.vtable = &ssl_server_vtable; - c->base.add_handshakers = ssl_server_add_handshakers; - c->base.server_creds = grpc_server_credentials_ref(server_creds); - return c; -} - -grpc_security_status grpc_ssl_server_security_connector_create( - grpc_server_credentials* gsc, grpc_server_security_connector** sc) { - tsi_result result = TSI_OK; - grpc_ssl_server_credentials* server_credentials = - reinterpret_cast(gsc); - grpc_security_status retval = GRPC_SECURITY_OK; - - GPR_ASSERT(server_credentials != nullptr); - GPR_ASSERT(sc != nullptr); - - grpc_ssl_server_security_connector* c = - grpc_ssl_server_security_connector_initialize(gsc); - if (server_connector_has_cert_config_fetcher(c)) { - // Load initial credentials from certificate_config_fetcher: - if (!try_fetch_ssl_server_credentials(c)) { - gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher."); - retval = GRPC_SECURITY_ERROR; - } - } else { - size_t num_alpn_protocols = 0; - const char** alpn_protocol_strings = - grpc_fill_alpn_protocol_strings(&num_alpn_protocols); - 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, - 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), - &c->server_handshaker_factory); - gpr_free((void*)alpn_protocol_strings); + 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)); - retval = GRPC_SECURITY_ERROR; + return GRPC_SECURITY_ERROR; } + return GRPC_SECURITY_OK; } - if (retval == GRPC_SECURITY_OK) { - *sc = &c->base; - } else { - if (c != nullptr) ssl_server_destroy(&c->base.base); - if (sc != nullptr) *sc = nullptr; + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) override { + // 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. + grpc_handshake_manager_add(handshake_mgr, + grpc_security_handshaker_create(tsi_hs, this)); } - return retval; + + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + 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_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); + } + + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + 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_); + } + + 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; + } + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + private: + tsi_ssl_client_handshaker_factory* client_handshaker_factory_; + char* target_name_; + char* overridden_target_name_; + const verify_peer_options* verify_options_; +}; + +class grpc_ssl_server_security_connector + : public grpc_server_security_connector { + public: + grpc_ssl_server_security_connector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(GRPC_SSL_URL_SCHEME, + std::move(server_creds)) {} + + ~grpc_ssl_server_security_connector() override { + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + } + + bool has_cert_config_fetcher() const { + return static_cast(server_creds()) + ->has_cert_config_fetcher(); + } + + const tsi_ssl_server_handshaker_factory* server_handshaker_factory() const { + return server_handshaker_factory_; + } + + grpc_security_status InitializeHandshakerFactory() { + 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; + } + } 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); + 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, + 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_); + 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; + } + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) override { + // Instantiate TSI handshaker. + try_fetch_ssl_server_credentials(); + 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; + } + // Create handshakers. + grpc_handshake_manager_add(handshake_mgr, + grpc_security_handshaker_create(tsi_hs, this)); + } + + void check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + grpc_error* error = ssl_check_peer(nullptr, &peer, auth_context); + tsi_peer_destruct(&peer); + GRPC_CLOSURE_SCHED(on_peer_checked, error); + } + + int cmp(const grpc_security_connector* other) const override { + return server_security_connector_cmp( + static_cast(other)); + } + + private: + /* Attempts to fetch the server certificate config if a callback is available. + * Current certificate config will continue to be used if the callback returns + * an error. Returns true if new credentials were sucessfully loaded. */ + 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 = + server_creds->FetchCertConfig(&certificate_config); + if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) { + gpr_log(GPR_DEBUG, "No change in SSL server credentials."); + status = false; + } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) { + status = try_replace_server_handshaker_factory(certificate_config); + } else { + // Log error, continue using previously-loaded credentials. + gpr_log(GPR_ERROR, + "Failed fetching new server credentials, continuing to " + "use previously-loaded credentials."); + status = false; + } + + if (certificate_config != nullptr) { + grpc_ssl_server_certificate_config_destroy(certificate_config); + } + return status; + } + + /* Attempts to replace the server_handshaker_factory with a new factory using + * the provided grpc_ssl_server_certificate_config. Should new factory + * creation fail, the existing factory will not be replaced. Returns true on + * success (new factory created). */ + bool try_replace_server_handshaker_factory( + const grpc_ssl_server_certificate_config* config) { + if (config == nullptr) { + gpr_log(GPR_ERROR, + "Server certificate config callback returned invalid (NULL) " + "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_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, + 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); + 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); + return true; + } + + void set_server_handshaker_factory( + tsi_ssl_server_handshaker_factory* new_factory) { + if (server_handshaker_factory_) { + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + } + server_handshaker_factory_ = new_factory; + } + + tsi_ssl_server_handshaker_factory* server_handshaker_factory_ = nullptr; +}; +} // namespace + +grpc_core::RefCountedPtr +grpc_ssl_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const grpc_ssl_config* config, const char* target_name, + const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache) { + if (config == nullptr || target_name == nullptr) { + 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); + if (result != GRPC_SECURITY_OK) { + return nullptr; + } + return c; +} + +grpc_core::RefCountedPtr +grpc_ssl_server_security_connector_create( + grpc_core::RefCountedPtr server_credentials) { + GPR_ASSERT(server_credentials != nullptr); + grpc_core::RefCountedPtr c = + grpc_core::MakeRefCounted( + std::move(server_credentials)); + const grpc_security_status retval = c->InitializeHandshakerFactory(); + if (retval != GRPC_SECURITY_OK) { + return nullptr; + } + return c; } diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.h b/src/core/lib/security/security_connector/ssl/ssl_security_connector.h index 9b805906061..70e26e338aa 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.h +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.h @@ -25,6 +25,7 @@ #include "src/core/lib/security/security_connector/security_connector.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security_interface.h" @@ -47,20 +48,21 @@ typedef struct { This function returns GRPC_SECURITY_OK in case of success or a specific error code otherwise. */ -grpc_security_status grpc_ssl_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, +grpc_core::RefCountedPtr +grpc_ssl_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, const grpc_ssl_config* config, const char* target_name, const char* overridden_target_name, - tsi_ssl_session_cache* ssl_session_cache, - grpc_channel_security_connector** sc); + tsi_ssl_session_cache* ssl_session_cache); /* Config for ssl servers. */ typedef struct { - tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs; - size_t num_key_cert_pairs; - char* pem_root_certs; - grpc_ssl_client_certificate_request_type client_certificate_request; + tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = nullptr; + size_t num_key_cert_pairs = 0; + char* pem_root_certs = nullptr; + grpc_ssl_client_certificate_request_type client_certificate_request = + GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE; } grpc_ssl_server_config; /* Creates an SSL server_security_connector. @@ -69,9 +71,9 @@ typedef struct { This function returns GRPC_SECURITY_OK in case of success or a specific error code otherwise. */ -grpc_security_status grpc_ssl_server_security_connector_create( - grpc_server_credentials* server_credentials, - grpc_server_security_connector** sc); +grpc_core::RefCountedPtr +grpc_ssl_server_security_connector_create( + grpc_core::RefCountedPtr server_credentials); #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_SSL_SECURITY_CONNECTOR_H \ */ diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index fbf41cfbc7c..29030f07ad6 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -30,6 +30,7 @@ #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/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/security_connector/load_system_roots.h" @@ -141,16 +142,17 @@ int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) { return r; } -grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) { +grpc_core::RefCountedPtr grpc_ssl_peer_to_auth_context( + const tsi_peer* peer) { size_t i; - grpc_auth_context* ctx = nullptr; const char* peer_identity_property_name = nullptr; /* The caller has checked the certificate type property. */ GPR_ASSERT(peer->property_count >= 1); - ctx = grpc_auth_context_create(nullptr); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); grpc_auth_context_add_cstring_property( - ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_SSL_TRANSPORT_SECURITY_TYPE); for (i = 0; i < peer->property_count; i++) { const tsi_peer_property* prop = &peer->properties[i]; @@ -160,24 +162,26 @@ grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) { if (peer_identity_property_name == nullptr) { peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME; } - grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME, + grpc_auth_context_add_property(ctx.get(), GRPC_X509_CN_PROPERTY_NAME, prop->value.data, prop->value.length); } else if (strcmp(prop->name, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME; - grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME, + grpc_auth_context_add_property(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME, prop->value.data, prop->value.length); } else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) { - grpc_auth_context_add_property(ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME, + grpc_auth_context_add_property(ctx.get(), + GRPC_X509_PEM_CERT_PROPERTY_NAME, prop->value.data, prop->value.length); } else if (strcmp(prop->name, TSI_SSL_SESSION_REUSED_PEER_PROPERTY) == 0) { - grpc_auth_context_add_property(ctx, GRPC_SSL_SESSION_REUSED_PROPERTY, + grpc_auth_context_add_property(ctx.get(), + GRPC_SSL_SESSION_REUSED_PROPERTY, prop->value.data, prop->value.length); } } if (peer_identity_property_name != nullptr) { GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( - ctx, peer_identity_property_name) == 1); + ctx.get(), peer_identity_property_name) == 1); } return ctx; } diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index 6f6d473311b..c9cd1a1d9c5 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -26,6 +26,7 @@ #include #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security_interface.h" @@ -47,7 +48,8 @@ grpc_get_tsi_client_certificate_request_type( const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols); /* Exposed for testing only. */ -grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer); +grpc_core::RefCountedPtr grpc_ssl_peer_to_auth_context( + const tsi_peer* peer); tsi_peer grpc_shallow_peer_from_ssl_auth_context( const grpc_auth_context* auth_context); void grpc_shallow_peer_destruct(tsi_peer* peer); diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 6955e8698e2..66f86b8bc52 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -55,7 +55,7 @@ struct call_data { // that the memory is not initialized. void destroy() { grpc_credentials_mdelem_array_destroy(&md_array); - grpc_call_credentials_unref(creds); + creds.reset(); grpc_slice_unref_internal(host); grpc_slice_unref_internal(method); grpc_auth_metadata_context_reset(&auth_md_context); @@ -64,7 +64,7 @@ struct call_data { gpr_arena* arena; grpc_call_stack* owning_call; grpc_call_combiner* call_combiner; - grpc_call_credentials* creds = nullptr; + grpc_core::RefCountedPtr creds; grpc_slice host = grpc_empty_slice(); grpc_slice method = grpc_empty_slice(); /* pollset{_set} bound to this call; if we need to make external @@ -83,8 +83,18 @@ struct call_data { /* We can have a per-channel credentials. */ struct channel_data { - grpc_channel_security_connector* security_connector; - grpc_auth_context* auth_context; + 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 @@ -98,10 +108,11 @@ void grpc_auth_metadata_context_reset( gpr_free(const_cast(auth_md_context->method_name)); auth_md_context->method_name = nullptr; } - GRPC_AUTH_CONTEXT_UNREF( - (grpc_auth_context*)auth_md_context->channel_auth_context, - "grpc_auth_metadata_context"); - auth_md_context->channel_auth_context = nullptr; + if (auth_md_context->channel_auth_context != nullptr) { + const_cast(auth_md_context->channel_auth_context) + ->Unref(DEBUG_LOCATION, "grpc_auth_metadata_context"); + auth_md_context->channel_auth_context = nullptr; + } } static void add_error(grpc_error** combined, grpc_error* error) { @@ -175,7 +186,10 @@ void grpc_auth_metadata_context_build( auth_md_context->service_url = service_url; auth_md_context->method_name = method_name; auth_md_context->channel_auth_context = - GRPC_AUTH_CONTEXT_REF(auth_context, "grpc_auth_metadata_context"); + auth_context == nullptr + ? nullptr + : auth_context->Ref(DEBUG_LOCATION, "grpc_auth_metadata_context") + .release(); gpr_free(service); gpr_free(host_and_port); } @@ -184,8 +198,8 @@ static void cancel_get_request_metadata(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); call_data* calld = static_cast(elem->call_data); if (error != GRPC_ERROR_NONE) { - grpc_call_credentials_cancel_get_request_metadata( - calld->creds, &calld->md_array, GRPC_ERROR_REF(error)); + calld->creds->cancel_get_request_metadata(&calld->md_array, + GRPC_ERROR_REF(error)); } } @@ -197,7 +211,7 @@ static void send_security_metadata(grpc_call_element* elem, static_cast( batch->payload->context[GRPC_CONTEXT_SECURITY].value); grpc_call_credentials* channel_call_creds = - chand->security_connector->request_metadata_creds; + chand->security_connector->mutable_request_metadata_creds(); int call_creds_has_md = (ctx != nullptr) && (ctx->creds != nullptr); if (channel_call_creds == nullptr && !call_creds_has_md) { @@ -207,8 +221,9 @@ static void send_security_metadata(grpc_call_element* elem, } if (channel_call_creds != nullptr && call_creds_has_md) { - calld->creds = grpc_composite_call_credentials_create(channel_call_creds, - ctx->creds, nullptr); + calld->creds = grpc_core::RefCountedPtr( + grpc_composite_call_credentials_create(channel_call_creds, + ctx->creds.get(), nullptr)); if (calld->creds == nullptr) { grpc_transport_stream_op_batch_finish_with_failure( batch, @@ -220,22 +235,22 @@ static void send_security_metadata(grpc_call_element* elem, return; } } else { - calld->creds = grpc_call_credentials_ref( - call_creds_has_md ? ctx->creds : channel_call_creds); + calld->creds = + call_creds_has_md ? ctx->creds->Ref() : channel_call_creds->Ref(); } grpc_auth_metadata_context_build( - chand->security_connector->base.url_scheme, calld->host, calld->method, - chand->auth_context, &calld->auth_md_context); + chand->security_connector->url_scheme(), calld->host, calld->method, + chand->auth_context.get(), &calld->auth_md_context); GPR_ASSERT(calld->pollent != nullptr); GRPC_CALL_STACK_REF(calld->owning_call, "get_request_metadata"); GRPC_CLOSURE_INIT(&calld->async_result_closure, on_credentials_metadata, batch, grpc_schedule_on_exec_ctx); grpc_error* error = GRPC_ERROR_NONE; - if (grpc_call_credentials_get_request_metadata( - calld->creds, calld->pollent, calld->auth_md_context, - &calld->md_array, &calld->async_result_closure, &error)) { + if (calld->creds->get_request_metadata( + calld->pollent, calld->auth_md_context, &calld->md_array, + &calld->async_result_closure, &error)) { // Synchronous return; invoke on_credentials_metadata() directly. on_credentials_metadata(batch, error); GRPC_ERROR_UNREF(error); @@ -279,9 +294,8 @@ static void cancel_check_call_host(void* arg, grpc_error* error) { call_data* calld = static_cast(elem->call_data); channel_data* chand = static_cast(elem->channel_data); if (error != GRPC_ERROR_NONE) { - grpc_channel_security_connector_cancel_check_call_host( - chand->security_connector, &calld->async_result_closure, - GRPC_ERROR_REF(error)); + chand->security_connector->cancel_check_call_host( + &calld->async_result_closure, GRPC_ERROR_REF(error)); } } @@ -299,16 +313,16 @@ static void auth_start_transport_stream_op_batch( 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); + 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); - GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter"); + sec_ctx->auth_context.reset(DEBUG_LOCATION, "client_auth_filter"); sec_ctx->auth_context = - GRPC_AUTH_CONTEXT_REF(chand->auth_context, "client_auth_filter"); + chand->auth_context->Ref(DEBUG_LOCATION, "client_auth_filter"); } if (batch->send_initial_metadata) { @@ -327,8 +341,8 @@ static void auth_start_transport_stream_op_batch( grpc_schedule_on_exec_ctx); char* call_host = grpc_slice_to_c_string(calld->host); grpc_error* error = GRPC_ERROR_NONE; - if (grpc_channel_security_connector_check_call_host( - chand->security_connector, call_host, chand->auth_context, + if (chand->security_connector->check_call_host( + call_host, chand->auth_context.get(), &calld->async_result_closure, &error)) { // Synchronous return; invoke on_host_checked() directly. on_host_checked(batch, error); @@ -374,6 +388,10 @@ static void destroy_call_elem(grpc_call_element* elem, /* Constructor for channel_data */ static grpc_error* init_channel_elem(grpc_channel_element* elem, grpc_channel_element_args* args) { + /* The first and the last filters tend to be implemented differently to + handle the case that there's no 'next' filter to call on the up or down + path */ + GPR_ASSERT(!args->is_last); grpc_security_connector* sc = grpc_security_connector_find_in_args(args->channel_args); if (sc == nullptr) { @@ -386,33 +404,15 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Auth context missing from client auth filter args"); } - - /* grab pointers to our data from the channel element */ - channel_data* chand = static_cast(elem->channel_data); - - /* The first and the last filters tend to be implemented differently to - handle the case that there's no 'next' filter to call on the up or down - path */ - GPR_ASSERT(!args->is_last); - - /* initialize members */ - chand->security_connector = - reinterpret_cast( - GRPC_SECURITY_CONNECTOR_REF(sc, "client_auth_filter")); - chand->auth_context = - GRPC_AUTH_CONTEXT_REF(auth_context, "client_auth_filter"); + new (elem->channel_data) channel_data( + static_cast(sc), auth_context); return GRPC_ERROR_NONE; } /* Destructor for channel data */ static void destroy_channel_elem(grpc_channel_element* elem) { - /* grab pointers to our data from the channel element */ channel_data* chand = static_cast(elem->channel_data); - grpc_channel_security_connector* sc = chand->security_connector; - if (sc != nullptr) { - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "client_auth_filter"); - } - GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter"); + chand->~channel_data(); } const grpc_channel_filter grpc_client_auth_filter = { diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index 854a1c4af97..48d6901e883 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/handshaker_registry.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/transport/secure_endpoint.h" #include "src/core/lib/security/transport/tsi_error.h" @@ -38,34 +39,62 @@ #define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256 -typedef struct { +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); + } + } + grpc_handshaker base; // State set at creation time. tsi_handshaker* handshaker; - grpc_security_connector* connector; + grpc_core::RefCountedPtr connector; gpr_mu mu; - gpr_refcount refs; + grpc_core::RefCount refs; - bool shutdown; + bool 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; + grpc_handshaker_args* args = nullptr; + grpc_closure* on_handshake_done = nullptr; - unsigned char* handshake_buffer; 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_auth_context* auth_context; - tsi_handshaker_result* handshaker_result; -} security_handshaker; + grpc_core::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; @@ -85,26 +114,6 @@ static size_t move_read_buffer_into_handshake_buffer(security_handshaker* h) { return bytes_in_read_buffer; } -static void security_handshaker_unref(security_handshaker* h) { - if (gpr_unref(&h->refs)) { - gpr_mu_destroy(&h->mu); - tsi_handshaker_destroy(h->handshaker); - tsi_handshaker_result_destroy(h->handshaker_result); - if (h->endpoint_to_destroy != nullptr) { - grpc_endpoint_destroy(h->endpoint_to_destroy); - } - if (h->read_buffer_to_destroy != nullptr) { - grpc_slice_buffer_destroy_internal(h->read_buffer_to_destroy); - gpr_free(h->read_buffer_to_destroy); - } - gpr_free(h->handshake_buffer); - grpc_slice_buffer_destroy_internal(&h->outgoing); - GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake"); - GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake"); - gpr_free(h); - } -} - // Set args fields to NULL, saving the endpoint and read buffer for // later destruction. static void cleanup_args_for_failure_locked(security_handshaker* h) { @@ -194,7 +203,7 @@ static void on_peer_checked_inner(security_handshaker* h, grpc_error* error) { tsi_handshaker_result_destroy(h->handshaker_result); h->handshaker_result = nullptr; // Add auth context to channel args. - grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context); + 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); @@ -211,7 +220,7 @@ static void on_peer_checked(void* arg, grpc_error* error) { gpr_mu_lock(&h->mu); on_peer_checked_inner(h, error); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); } static grpc_error* check_peer_locked(security_handshaker* h) { @@ -222,8 +231,7 @@ static grpc_error* check_peer_locked(security_handshaker* h) { return grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Peer extraction failed"), result); } - grpc_security_connector_check_peer(h->connector, peer, &h->auth_context, - &h->on_peer_checked); + h->connector->check_peer(peer, &h->auth_context, &h->on_peer_checked); return GRPC_ERROR_NONE; } @@ -281,7 +289,7 @@ static void on_handshake_next_done_grpc_wrapper( if (error != GRPC_ERROR_NONE) { security_handshake_failed_locked(h, error); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); } else { gpr_mu_unlock(&h->mu); } @@ -317,7 +325,7 @@ static void on_handshake_data_received_from_peer(void* arg, grpc_error* error) { h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Handshake read failed", &error, 1)); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); return; } // Copy all slices received. @@ -329,7 +337,7 @@ static void on_handshake_data_received_from_peer(void* arg, grpc_error* error) { if (error != GRPC_ERROR_NONE) { security_handshake_failed_locked(h, error); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); } else { gpr_mu_unlock(&h->mu); } @@ -343,7 +351,7 @@ static void on_handshake_data_sent_to_peer(void* arg, grpc_error* error) { h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Handshake write failed", &error, 1)); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); return; } // We may be done. @@ -355,7 +363,7 @@ static void on_handshake_data_sent_to_peer(void* arg, grpc_error* error) { if (error != GRPC_ERROR_NONE) { security_handshake_failed_locked(h, error); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); return; } } @@ -368,7 +376,7 @@ static void on_handshake_data_sent_to_peer(void* arg, grpc_error* error) { static void security_handshaker_destroy(grpc_handshaker* handshaker) { security_handshaker* h = reinterpret_cast(handshaker); - security_handshaker_unref(h); + h->Unref(); } static void security_handshaker_shutdown(grpc_handshaker* handshaker, @@ -393,14 +401,14 @@ static void security_handshaker_do_handshake(grpc_handshaker* handshaker, gpr_mu_lock(&h->mu); h->args = args; h->on_handshake_done = on_handshake_done; - gpr_ref(&h->refs); + h->Ref(); size_t bytes_received_size = move_read_buffer_into_handshake_buffer(h); grpc_error* error = do_handshaker_next_locked(h, h->handshake_buffer, bytes_received_size); if (error != GRPC_ERROR_NONE) { security_handshake_failed_locked(h, error); gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->Unref(); return; } gpr_mu_unlock(&h->mu); @@ -410,27 +418,32 @@ 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 = static_cast( - gpr_zalloc(sizeof(security_handshaker))); - grpc_handshaker_init(&security_handshaker_vtable, &h->base); - h->handshaker = handshaker; - h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake"); - gpr_mu_init(&h->mu); - gpr_ref_init(&h->refs, 1); - h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE; - h->handshake_buffer = - static_cast(gpr_malloc(h->handshake_buffer_size)); - GRPC_CLOSURE_INIT(&h->on_handshake_data_sent_to_peer, - on_handshake_data_sent_to_peer, h, - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&h->on_handshake_data_received_from_peer, - on_handshake_data_received_from_peer, h, - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&h->on_peer_checked, on_peer_checked, h, - grpc_schedule_on_exec_ctx); - grpc_slice_buffer_init(&h->outgoing); + security_handshaker* h = + grpc_core::New(handshaker, connector); return &h->base; } @@ -477,8 +490,9 @@ static void client_handshaker_factory_add_handshakers( grpc_channel_security_connector* security_connector = reinterpret_cast( grpc_security_connector_find_in_args(args)); - grpc_channel_security_connector_add_handshakers( - security_connector, interested_parties, handshake_mgr); + if (security_connector) { + security_connector->add_handshakers(interested_parties, handshake_mgr); + } } static void server_handshaker_factory_add_handshakers( @@ -488,8 +502,9 @@ static void server_handshaker_factory_add_handshakers( grpc_server_security_connector* security_connector = reinterpret_cast( grpc_security_connector_find_in_args(args)); - grpc_server_security_connector_add_handshakers( - security_connector, interested_parties, handshake_mgr); + if (security_connector) { + security_connector->add_handshakers(interested_parties, handshake_mgr); + } } static void handshaker_factory_destroy( diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc index 362f49a5843..f93eb4275e3 100644 --- a/src/core/lib/security/transport/server_auth_filter.cc +++ b/src/core/lib/security/transport/server_auth_filter.cc @@ -39,8 +39,12 @@ enum async_state { }; struct channel_data { - grpc_auth_context* auth_context; - grpc_server_credentials* creds; + channel_data(grpc_auth_context* auth_context, grpc_server_credentials* creds) + : auth_context(auth_context->Ref()), creds(creds->Ref()) {} + ~channel_data() { auth_context.reset(DEBUG_LOCATION, "server_auth_filter"); } + + grpc_core::RefCountedPtr auth_context; + grpc_core::RefCountedPtr creds; }; struct call_data { @@ -58,7 +62,7 @@ struct call_data { grpc_server_security_context_create(args.arena); channel_data* chand = static_cast(elem->channel_data); server_ctx->auth_context = - GRPC_AUTH_CONTEXT_REF(chand->auth_context, "server_auth_filter"); + chand->auth_context->Ref(DEBUG_LOCATION, "server_auth_filter"); if (args.context[GRPC_CONTEXT_SECURITY].value != nullptr) { args.context[GRPC_CONTEXT_SECURITY].destroy( args.context[GRPC_CONTEXT_SECURITY].value); @@ -208,7 +212,8 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { call_data* calld = static_cast(elem->call_data); grpc_transport_stream_op_batch* batch = calld->recv_initial_metadata_batch; if (error == GRPC_ERROR_NONE) { - if (chand->creds != nullptr && chand->creds->processor.process != nullptr) { + if (chand->creds != nullptr && + chand->creds->auth_metadata_processor().process != nullptr) { // We're calling out to the application, so we need to make sure // to drop the call combiner early if we get cancelled. GRPC_CLOSURE_INIT(&calld->cancel_closure, cancel_call, elem, @@ -218,9 +223,10 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { GRPC_CALL_STACK_REF(calld->owning_call, "server_auth_metadata"); calld->md = metadata_batch_to_md_array( batch->payload->recv_initial_metadata.recv_initial_metadata); - chand->creds->processor.process( - chand->creds->processor.state, chand->auth_context, - calld->md.metadata, calld->md.count, on_md_processing_done, elem); + chand->creds->auth_metadata_processor().process( + chand->creds->auth_metadata_processor().state, + chand->auth_context.get(), calld->md.metadata, calld->md.count, + on_md_processing_done, elem); return; } } @@ -290,23 +296,19 @@ static void destroy_call_elem(grpc_call_element* elem, static grpc_error* init_channel_elem(grpc_channel_element* elem, grpc_channel_element_args* args) { GPR_ASSERT(!args->is_last); - channel_data* chand = static_cast(elem->channel_data); grpc_auth_context* auth_context = grpc_find_auth_context_in_args(args->channel_args); GPR_ASSERT(auth_context != nullptr); - chand->auth_context = - GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter"); grpc_server_credentials* creds = grpc_find_server_credentials_in_args(args->channel_args); - chand->creds = grpc_server_credentials_ref(creds); + new (elem->channel_data) channel_data(auth_context, creds); return GRPC_ERROR_NONE; } /* Destructor for channel data */ static void destroy_channel_elem(grpc_channel_element* elem) { channel_data* chand = static_cast(elem->channel_data); - GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "server_auth_filter"); - grpc_server_credentials_unref(chand->creds); + chand->~channel_data(); } const grpc_channel_filter grpc_server_auth_filter = { diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index d0abe441a6a..4d0ed355aba 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -261,10 +261,10 @@ void MetadataCredentialsPluginWrapper::InvokePlugin( grpc_status_code* status_code, const char** error_details) { std::multimap metadata; - // const_cast is safe since the SecureAuthContext does not take owndership and - // the object is passed as a const ref to plugin_->GetMetadata. + // const_cast is safe since the SecureAuthContext only inc/dec the refcount + // and the object is passed as a const ref to plugin_->GetMetadata. SecureAuthContext cpp_channel_auth_context( - const_cast(context.channel_auth_context), false); + const_cast(context.channel_auth_context)); Status status = plugin_->GetMetadata(context.service_url, context.method_name, cpp_channel_auth_context, &metadata); diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 613f1d6dc2c..4918bd5a4d7 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -24,6 +24,7 @@ #include #include +#include "src/core/lib/security/credentials/credentials.h" #include "src/cpp/server/thread_pool_interface.h" namespace grpc { @@ -31,7 +32,9 @@ namespace grpc { class SecureChannelCredentials final : public ChannelCredentials { public: explicit SecureChannelCredentials(grpc_channel_credentials* c_creds); - ~SecureChannelCredentials() { grpc_channel_credentials_release(c_creds_); } + ~SecureChannelCredentials() { + if (c_creds_ != nullptr) c_creds_->Unref(); + } grpc_channel_credentials* GetRawCreds() { return c_creds_; } std::shared_ptr CreateChannel( @@ -51,7 +54,9 @@ class SecureChannelCredentials final : public ChannelCredentials { class SecureCallCredentials final : public CallCredentials { public: explicit SecureCallCredentials(grpc_call_credentials* c_creds); - ~SecureCallCredentials() { grpc_call_credentials_release(c_creds_); } + ~SecureCallCredentials() { + if (c_creds_ != nullptr) c_creds_->Unref(); + } grpc_call_credentials* GetRawCreds() { return c_creds_; } bool ApplyToCall(grpc_call* call) override; diff --git a/src/cpp/common/secure_auth_context.cc b/src/cpp/common/secure_auth_context.cc index 1d66dd3d1f1..7a2b5afed69 100644 --- a/src/cpp/common/secure_auth_context.cc +++ b/src/cpp/common/secure_auth_context.cc @@ -22,19 +22,12 @@ namespace grpc { -SecureAuthContext::SecureAuthContext(grpc_auth_context* ctx, - bool take_ownership) - : ctx_(ctx), take_ownership_(take_ownership) {} - -SecureAuthContext::~SecureAuthContext() { - if (take_ownership_) grpc_auth_context_release(ctx_); -} - std::vector SecureAuthContext::GetPeerIdentity() const { - if (!ctx_) { + if (ctx_ == nullptr) { return std::vector(); } - grpc_auth_property_iterator iter = grpc_auth_context_peer_identity(ctx_); + grpc_auth_property_iterator iter = + grpc_auth_context_peer_identity(ctx_.get()); std::vector identity; const grpc_auth_property* property = nullptr; while ((property = grpc_auth_property_iterator_next(&iter))) { @@ -45,20 +38,20 @@ std::vector SecureAuthContext::GetPeerIdentity() const { } grpc::string SecureAuthContext::GetPeerIdentityPropertyName() const { - if (!ctx_) { + if (ctx_ == nullptr) { return ""; } - const char* name = grpc_auth_context_peer_identity_property_name(ctx_); + const char* name = grpc_auth_context_peer_identity_property_name(ctx_.get()); return name == nullptr ? "" : name; } std::vector SecureAuthContext::FindPropertyValues( const grpc::string& name) const { - if (!ctx_) { + if (ctx_ == nullptr) { return std::vector(); } grpc_auth_property_iterator iter = - grpc_auth_context_find_properties_by_name(ctx_, name.c_str()); + grpc_auth_context_find_properties_by_name(ctx_.get(), name.c_str()); const grpc_auth_property* property = nullptr; std::vector values; while ((property = grpc_auth_property_iterator_next(&iter))) { @@ -68,9 +61,9 @@ std::vector SecureAuthContext::FindPropertyValues( } AuthPropertyIterator SecureAuthContext::begin() const { - if (ctx_) { + if (ctx_ != nullptr) { grpc_auth_property_iterator iter = - grpc_auth_context_property_iterator(ctx_); + grpc_auth_context_property_iterator(ctx_.get()); const grpc_auth_property* property = grpc_auth_property_iterator_next(&iter); return AuthPropertyIterator(property, &iter); @@ -85,19 +78,20 @@ AuthPropertyIterator SecureAuthContext::end() const { void SecureAuthContext::AddProperty(const grpc::string& key, const grpc::string_ref& value) { - if (!ctx_) return; - grpc_auth_context_add_property(ctx_, key.c_str(), value.data(), value.size()); + if (ctx_ == nullptr) return; + grpc_auth_context_add_property(ctx_.get(), key.c_str(), value.data(), + value.size()); } bool SecureAuthContext::SetPeerIdentityPropertyName(const grpc::string& name) { - if (!ctx_) return false; - return grpc_auth_context_set_peer_identity_property_name(ctx_, + if (ctx_ == nullptr) return false; + return grpc_auth_context_set_peer_identity_property_name(ctx_.get(), name.c_str()) != 0; } bool SecureAuthContext::IsPeerAuthenticated() const { - if (!ctx_) return false; - return grpc_auth_context_peer_is_authenticated(ctx_) != 0; + if (ctx_ == nullptr) return false; + return grpc_auth_context_peer_is_authenticated(ctx_.get()) != 0; } } // namespace grpc diff --git a/src/cpp/common/secure_auth_context.h b/src/cpp/common/secure_auth_context.h index 142617959cb..2e8f7937211 100644 --- a/src/cpp/common/secure_auth_context.h +++ b/src/cpp/common/secure_auth_context.h @@ -21,15 +21,17 @@ #include -struct grpc_auth_context; +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/security/context/security_context.h" namespace grpc { class SecureAuthContext final : public AuthContext { public: - SecureAuthContext(grpc_auth_context* ctx, bool take_ownership); + explicit SecureAuthContext(grpc_auth_context* ctx) + : ctx_(ctx != nullptr ? ctx->Ref() : nullptr) {} - ~SecureAuthContext() override; + ~SecureAuthContext() override = default; bool IsPeerAuthenticated() const override; @@ -50,8 +52,7 @@ class SecureAuthContext final : public AuthContext { virtual bool SetPeerIdentityPropertyName(const grpc::string& name) override; private: - grpc_auth_context* ctx_; - bool take_ownership_; + grpc_core::RefCountedPtr ctx_; }; } // namespace grpc diff --git a/src/cpp/common/secure_create_auth_context.cc b/src/cpp/common/secure_create_auth_context.cc index bc1387c8d75..908c46629e6 100644 --- a/src/cpp/common/secure_create_auth_context.cc +++ b/src/cpp/common/secure_create_auth_context.cc @@ -20,6 +20,7 @@ #include #include #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/cpp/common/secure_auth_context.h" namespace grpc { @@ -28,8 +29,8 @@ std::shared_ptr CreateAuthContext(grpc_call* call) { if (call == nullptr) { return std::shared_ptr(); } - return std::shared_ptr( - new SecureAuthContext(grpc_call_auth_context(call), true)); + grpc_core::RefCountedPtr ctx(grpc_call_auth_context(call)); + return std::make_shared(ctx.get()); } } // namespace grpc diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc index ebb17def32b..453e76eb25d 100644 --- a/src/cpp/server/secure_server_credentials.cc +++ b/src/cpp/server/secure_server_credentials.cc @@ -61,7 +61,7 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor( metadata.insert(std::make_pair(StringRefFromSlice(&md[i].key), StringRefFromSlice(&md[i].value))); } - SecureAuthContext context(ctx, false); + SecureAuthContext context(ctx); AuthMetadataProcessor::OutputMetadata consumed_metadata; AuthMetadataProcessor::OutputMetadata response_metadata; diff --git a/test/core/security/alts_security_connector_test.cc b/test/core/security/alts_security_connector_test.cc index 9378236338d..bcba3408216 100644 --- a/test/core/security/alts_security_connector_test.cc +++ b/test/core/security/alts_security_connector_test.cc @@ -33,40 +33,34 @@ using grpc_core::internal::grpc_alts_auth_context_from_tsi_peer; /* This file contains unit tests of grpc_alts_auth_context_from_tsi_peer(). */ static void test_invalid_input_failure() { - tsi_peer peer; - grpc_auth_context* ctx; - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(nullptr, &ctx) == - GRPC_SECURITY_ERROR); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, nullptr) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(nullptr); + GPR_ASSERT(ctx == nullptr); } static void test_empty_certificate_type_failure() { tsi_peer peer; - grpc_auth_context* ctx = nullptr; GPR_ASSERT(tsi_construct_peer(0, &peer) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); GPR_ASSERT(ctx == nullptr); tsi_peer_destruct(&peer); } static void test_empty_peer_property_failure() { tsi_peer peer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, &peer.properties[0]) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); GPR_ASSERT(ctx == nullptr); tsi_peer_destruct(&peer); } static void test_missing_rpc_protocol_versions_property_failure() { tsi_peer peer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, @@ -74,23 +68,22 @@ static void test_missing_rpc_protocol_versions_property_failure() { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, "alice", &peer.properties[1]) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); GPR_ASSERT(ctx == nullptr); tsi_peer_destruct(&peer); } static void test_unknown_peer_property_failure() { tsi_peer peer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, &peer.properties[0]) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( "unknown", "alice", &peer.properties[1]) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); GPR_ASSERT(ctx == nullptr); tsi_peer_destruct(&peer); } @@ -119,7 +112,6 @@ static bool test_identity(const grpc_auth_context* ctx, static void test_alts_peer_to_auth_context_success() { tsi_peer peer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, @@ -144,11 +136,12 @@ static void test_alts_peer_to_auth_context_success() { GRPC_SLICE_START_PTR(serialized_peer_versions)), GRPC_SLICE_LENGTH(serialized_peer_versions), &peer.properties[2]) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_OK); - GPR_ASSERT( - test_identity(ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, "alice")); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); + GPR_ASSERT(ctx != nullptr); + GPR_ASSERT(test_identity(ctx.get(), TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, + "alice")); + ctx.reset(DEBUG_LOCATION, "test"); grpc_slice_unref(serialized_peer_versions); tsi_peer_destruct(&peer); } diff --git a/test/core/security/auth_context_test.cc b/test/core/security/auth_context_test.cc index 9a39afb8006..e7e0cb2ed94 100644 --- a/test/core/security/auth_context_test.cc +++ b/test/core/security/auth_context_test.cc @@ -19,114 +19,122 @@ #include #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "test/core/util/test_config.h" #include static void test_empty_context(void) { - grpc_auth_context* ctx = grpc_auth_context_create(nullptr); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); grpc_auth_property_iterator it; gpr_log(GPR_INFO, "test_empty_context"); GPR_ASSERT(ctx != nullptr); - GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == nullptr); - it = grpc_auth_context_peer_identity(ctx); + GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx.get()) == + nullptr); + it = grpc_auth_context_peer_identity(ctx.get()); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_property_iterator(ctx); + it = grpc_auth_context_property_iterator(ctx.get()); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_find_properties_by_name(ctx, "foo"); + it = grpc_auth_context_find_properties_by_name(ctx.get(), "foo"); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "bar") == - 0); - GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == nullptr); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + GPR_ASSERT( + grpc_auth_context_set_peer_identity_property_name(ctx.get(), "bar") == 0); + GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx.get()) == + nullptr); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_simple_context(void) { - grpc_auth_context* ctx = grpc_auth_context_create(nullptr); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); grpc_auth_property_iterator it; size_t i; gpr_log(GPR_INFO, "test_simple_context"); GPR_ASSERT(ctx != nullptr); - grpc_auth_context_add_cstring_property(ctx, "name", "chapi"); - grpc_auth_context_add_cstring_property(ctx, "name", "chapo"); - grpc_auth_context_add_cstring_property(ctx, "foo", "bar"); - GPR_ASSERT(ctx->properties.count == 3); - GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "name") == - 1); + grpc_auth_context_add_cstring_property(ctx.get(), "name", "chapi"); + grpc_auth_context_add_cstring_property(ctx.get(), "name", "chapo"); + grpc_auth_context_add_cstring_property(ctx.get(), "foo", "bar"); + GPR_ASSERT(ctx->properties().count == 3); + GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx.get(), + "name") == 1); - GPR_ASSERT( - strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0); - it = grpc_auth_context_property_iterator(ctx); - for (i = 0; i < ctx->properties.count; i++) { + GPR_ASSERT(strcmp(grpc_auth_context_peer_identity_property_name(ctx.get()), + "name") == 0); + it = grpc_auth_context_property_iterator(ctx.get()); + for (i = 0; i < ctx->properties().count; i++) { const grpc_auth_property* p = grpc_auth_property_iterator_next(&it); - GPR_ASSERT(p == &ctx->properties.array[i]); + GPR_ASSERT(p == &ctx->properties().array[i]); } GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_find_properties_by_name(ctx, "foo"); + it = grpc_auth_context_find_properties_by_name(ctx.get(), "foo"); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[2]); + &ctx->properties().array[2]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_peer_identity(ctx); + it = grpc_auth_context_peer_identity(ctx.get()); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[0]); + &ctx->properties().array[0]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[1]); + &ctx->properties().array[1]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_chained_context(void) { - grpc_auth_context* chained = grpc_auth_context_create(nullptr); - grpc_auth_context* ctx = grpc_auth_context_create(chained); + grpc_core::RefCountedPtr chained = + grpc_core::MakeRefCounted(nullptr); + grpc_auth_context* chained_ptr = chained.get(); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(std::move(chained)); + grpc_auth_property_iterator it; size_t i; gpr_log(GPR_INFO, "test_chained_context"); - GRPC_AUTH_CONTEXT_UNREF(chained, "chained"); - grpc_auth_context_add_cstring_property(chained, "name", "padapo"); - grpc_auth_context_add_cstring_property(chained, "foo", "baz"); - grpc_auth_context_add_cstring_property(ctx, "name", "chapi"); - grpc_auth_context_add_cstring_property(ctx, "name", "chap0"); - grpc_auth_context_add_cstring_property(ctx, "foo", "bar"); - GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "name") == - 1); + grpc_auth_context_add_cstring_property(chained_ptr, "name", "padapo"); + grpc_auth_context_add_cstring_property(chained_ptr, "foo", "baz"); + grpc_auth_context_add_cstring_property(ctx.get(), "name", "chapi"); + grpc_auth_context_add_cstring_property(ctx.get(), "name", "chap0"); + grpc_auth_context_add_cstring_property(ctx.get(), "foo", "bar"); + GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx.get(), + "name") == 1); - GPR_ASSERT( - strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0); - it = grpc_auth_context_property_iterator(ctx); - for (i = 0; i < ctx->properties.count; i++) { + GPR_ASSERT(strcmp(grpc_auth_context_peer_identity_property_name(ctx.get()), + "name") == 0); + it = grpc_auth_context_property_iterator(ctx.get()); + for (i = 0; i < ctx->properties().count; i++) { const grpc_auth_property* p = grpc_auth_property_iterator_next(&it); - GPR_ASSERT(p == &ctx->properties.array[i]); + GPR_ASSERT(p == &ctx->properties().array[i]); } - for (i = 0; i < chained->properties.count; i++) { + for (i = 0; i < chained_ptr->properties().count; i++) { const grpc_auth_property* p = grpc_auth_property_iterator_next(&it); - GPR_ASSERT(p == &chained->properties.array[i]); + GPR_ASSERT(p == &chained_ptr->properties().array[i]); } GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_find_properties_by_name(ctx, "foo"); + it = grpc_auth_context_find_properties_by_name(ctx.get(), "foo"); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[2]); + &ctx->properties().array[2]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &chained->properties.array[1]); + &chained_ptr->properties().array[1]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_peer_identity(ctx); + it = grpc_auth_context_peer_identity(ctx.get()); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[0]); + &ctx->properties().array[0]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[1]); + &ctx->properties().array[1]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &chained->properties.array[0]); + &chained_ptr->properties().array[0]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } int main(int argc, char** argv) { diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index a7a6050ec0a..b3a81617865 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -46,19 +46,6 @@ using grpc_core::internal::grpc_flush_cached_google_default_credentials; using grpc_core::internal::set_gce_tenancy_checker_for_testing; -/* -- Mock channel credentials. -- */ - -static grpc_channel_credentials* grpc_mock_channel_credentials_create( - const grpc_channel_credentials_vtable* vtable) { - grpc_channel_credentials* c = - static_cast(gpr_malloc(sizeof(*c))); - memset(c, 0, sizeof(*c)); - c->type = "mock"; - c->vtable = vtable; - gpr_ref_init(&c->refcount, 1); - return c; -} - /* -- Constants. -- */ static const char test_google_iam_authorization_token[] = "blahblahblhahb"; @@ -377,9 +364,9 @@ static void run_request_metadata_test(grpc_call_credentials* creds, grpc_auth_metadata_context auth_md_ctx, request_metadata_state* state) { grpc_error* error = GRPC_ERROR_NONE; - if (grpc_call_credentials_get_request_metadata( - creds, &state->pollent, auth_md_ctx, &state->md_array, - &state->on_request_metadata, &error)) { + if (creds->get_request_metadata(&state->pollent, auth_md_ctx, + &state->md_array, &state->on_request_metadata, + &error)) { // Synchronous result. Invoke the callback directly. check_request_metadata(state, error); GRPC_ERROR_UNREF(error); @@ -400,7 +387,7 @@ static void test_google_iam_creds(void) { grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, nullptr, nullptr}; run_request_metadata_test(creds, auth_md_ctx, state); - grpc_call_credentials_unref(creds); + creds->Unref(); } static void test_access_token_creds(void) { @@ -412,28 +399,36 @@ static void test_access_token_creds(void) { grpc_access_token_credentials_create("blah", nullptr); grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, nullptr, nullptr}; - GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); + GPR_ASSERT(strcmp(creds->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); run_request_metadata_test(creds, auth_md_ctx, state); - grpc_call_credentials_unref(creds); + creds->Unref(); } -static grpc_security_status check_channel_oauth2_create_security_connector( - grpc_channel_credentials* c, grpc_call_credentials* call_creds, - const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - GPR_ASSERT(strcmp(c->type, "mock") == 0); - GPR_ASSERT(call_creds != nullptr); - GPR_ASSERT(strcmp(call_creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); - return GRPC_SECURITY_OK; -} +namespace { +class check_channel_oauth2 final : public grpc_channel_credentials { + public: + check_channel_oauth2() : grpc_channel_credentials("mock") {} + ~check_channel_oauth2() override = default; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override { + GPR_ASSERT(strcmp(type(), "mock") == 0); + GPR_ASSERT(call_creds != nullptr); + GPR_ASSERT(strcmp(call_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == + 0); + return nullptr; + } +}; +} // namespace static void test_channel_oauth2_composite_creds(void) { grpc_core::ExecCtx exec_ctx; grpc_channel_args* new_args; - grpc_channel_credentials_vtable vtable = { - nullptr, check_channel_oauth2_create_security_connector, nullptr}; grpc_channel_credentials* channel_creds = - grpc_mock_channel_credentials_create(&vtable); + grpc_core::New(); grpc_call_credentials* oauth2_creds = grpc_access_token_credentials_create("blah", nullptr); grpc_channel_credentials* channel_oauth2_creds = @@ -441,9 +436,8 @@ static void test_channel_oauth2_composite_creds(void) { nullptr); grpc_channel_credentials_release(channel_creds); grpc_call_credentials_release(oauth2_creds); - GPR_ASSERT(grpc_channel_credentials_create_security_connector( - channel_oauth2_creds, nullptr, nullptr, nullptr, &new_args) == - GRPC_SECURITY_OK); + channel_oauth2_creds->create_security_connector(nullptr, nullptr, nullptr, + &new_args); grpc_channel_credentials_release(channel_oauth2_creds); } @@ -467,47 +461,54 @@ static void test_oauth2_google_iam_composite_creds(void) { grpc_call_credentials* composite_creds = grpc_composite_call_credentials_create(oauth2_creds, google_iam_creds, nullptr); - grpc_call_credentials_unref(oauth2_creds); - grpc_call_credentials_unref(google_iam_creds); - GPR_ASSERT( - strcmp(composite_creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); - const grpc_call_credentials_array* creds_array = - grpc_composite_call_credentials_get_credentials(composite_creds); - GPR_ASSERT(creds_array->num_creds == 2); - GPR_ASSERT(strcmp(creds_array->creds_array[0]->type, + oauth2_creds->Unref(); + google_iam_creds->Unref(); + GPR_ASSERT(strcmp(composite_creds->type(), + GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); + const grpc_call_credentials_array& creds_array = + static_cast(composite_creds) + ->inner(); + GPR_ASSERT(creds_array.size() == 2); + GPR_ASSERT(strcmp(creds_array.get(0)->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); - GPR_ASSERT(strcmp(creds_array->creds_array[1]->type, - GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); + GPR_ASSERT( + strcmp(creds_array.get(1)->type(), GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); run_request_metadata_test(composite_creds, auth_md_ctx, state); - grpc_call_credentials_unref(composite_creds); + composite_creds->Unref(); } -static grpc_security_status -check_channel_oauth2_google_iam_create_security_connector( - grpc_channel_credentials* c, grpc_call_credentials* call_creds, - const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - const grpc_call_credentials_array* creds_array; - GPR_ASSERT(strcmp(c->type, "mock") == 0); - GPR_ASSERT(call_creds != nullptr); - GPR_ASSERT(strcmp(call_creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == - 0); - creds_array = grpc_composite_call_credentials_get_credentials(call_creds); - GPR_ASSERT(strcmp(creds_array->creds_array[0]->type, - GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); - GPR_ASSERT(strcmp(creds_array->creds_array[1]->type, - GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); - return GRPC_SECURITY_OK; -} +namespace { +class check_channel_oauth2_google_iam final : public grpc_channel_credentials { + public: + check_channel_oauth2_google_iam() : grpc_channel_credentials("mock") {} + ~check_channel_oauth2_google_iam() override = default; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override { + GPR_ASSERT(strcmp(type(), "mock") == 0); + GPR_ASSERT(call_creds != nullptr); + GPR_ASSERT( + strcmp(call_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); + const grpc_call_credentials_array& creds_array = + static_cast(call_creds.get()) + ->inner(); + GPR_ASSERT(strcmp(creds_array.get(0)->type(), + GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); + GPR_ASSERT(strcmp(creds_array.get(1)->type(), + GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); + return nullptr; + } +}; +} // namespace static void test_channel_oauth2_google_iam_composite_creds(void) { grpc_core::ExecCtx exec_ctx; grpc_channel_args* new_args; - grpc_channel_credentials_vtable vtable = { - nullptr, check_channel_oauth2_google_iam_create_security_connector, - nullptr}; grpc_channel_credentials* channel_creds = - grpc_mock_channel_credentials_create(&vtable); + grpc_core::New(); grpc_call_credentials* oauth2_creds = grpc_access_token_credentials_create("blah", nullptr); grpc_channel_credentials* channel_oauth2_creds = @@ -524,9 +525,8 @@ static void test_channel_oauth2_google_iam_composite_creds(void) { grpc_channel_credentials_release(channel_oauth2_creds); grpc_call_credentials_release(google_iam_creds); - GPR_ASSERT(grpc_channel_credentials_create_security_connector( - channel_oauth2_iam_creds, nullptr, nullptr, nullptr, - &new_args) == GRPC_SECURITY_OK); + channel_oauth2_iam_creds->create_security_connector(nullptr, nullptr, nullptr, + &new_args); grpc_channel_credentials_release(channel_oauth2_iam_creds); } @@ -578,7 +578,7 @@ static int httpcli_get_should_not_be_called(const grpc_httpcli_request* request, return 1; } -static void test_compute_engine_creds_success(void) { +static void test_compute_engine_creds_success() { grpc_core::ExecCtx exec_ctx; expected_md emd[] = { {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}}; @@ -603,7 +603,7 @@ static void test_compute_engine_creds_success(void) { run_request_metadata_test(creds, auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); } @@ -620,7 +620,7 @@ static void test_compute_engine_creds_failure(void) { grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override, httpcli_post_should_not_be_called); run_request_metadata_test(creds, auth_md_ctx, state); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); } @@ -692,7 +692,7 @@ static void test_refresh_token_creds_success(void) { run_request_metadata_test(creds, auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); } @@ -709,7 +709,7 @@ static void test_refresh_token_creds_failure(void) { grpc_httpcli_set_override(httpcli_get_should_not_be_called, refresh_token_httpcli_post_failure); run_request_metadata_test(creds, auth_md_ctx, state); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); } @@ -762,7 +762,7 @@ static char* encode_and_sign_jwt_should_not_be_called( static grpc_service_account_jwt_access_credentials* creds_as_jwt( grpc_call_credentials* creds) { GPR_ASSERT(creds != nullptr); - GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_JWT) == 0); + GPR_ASSERT(strcmp(creds->type(), GRPC_CALL_CREDENTIALS_TYPE_JWT) == 0); return reinterpret_cast(creds); } @@ -773,7 +773,7 @@ static void test_jwt_creds_lifetime(void) { grpc_call_credentials* jwt_creds = grpc_service_account_jwt_access_credentials_create( json_key_string, grpc_max_auth_token_lifetime(), nullptr); - GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime, + GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(), grpc_max_auth_token_lifetime()) == 0); grpc_call_credentials_release(jwt_creds); @@ -782,8 +782,8 @@ static void test_jwt_creds_lifetime(void) { GPR_ASSERT(gpr_time_cmp(grpc_max_auth_token_lifetime(), token_lifetime) > 0); jwt_creds = grpc_service_account_jwt_access_credentials_create( json_key_string, token_lifetime, nullptr); - GPR_ASSERT( - gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime, token_lifetime) == 0); + GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(), + token_lifetime) == 0); grpc_call_credentials_release(jwt_creds); // Cropped lifetime. @@ -791,7 +791,7 @@ static void test_jwt_creds_lifetime(void) { token_lifetime = gpr_time_add(grpc_max_auth_token_lifetime(), add_to_max); jwt_creds = grpc_service_account_jwt_access_credentials_create( json_key_string, token_lifetime, nullptr); - GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime, + GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(), grpc_max_auth_token_lifetime()) == 0); grpc_call_credentials_release(jwt_creds); @@ -834,7 +834,7 @@ static void test_jwt_creds_success(void) { run_request_metadata_test(creds, auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); - grpc_call_credentials_unref(creds); + creds->Unref(); gpr_free(json_key_string); gpr_free(expected_md_value); grpc_jwt_encode_and_sign_set_override(nullptr); @@ -856,7 +856,7 @@ static void test_jwt_creds_signing_failure(void) { run_request_metadata_test(creds, auth_md_ctx, state); gpr_free(json_key_string); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_jwt_encode_and_sign_set_override(nullptr); } @@ -875,8 +875,6 @@ static void set_google_default_creds_env_var_with_file_contents( static void test_google_default_creds_auth_key(void) { grpc_core::ExecCtx exec_ctx; - grpc_service_account_jwt_access_credentials* jwt; - grpc_google_default_channel_credentials* default_creds; grpc_composite_channel_credentials* creds; char* json_key = test_json_key_str(); grpc_flush_cached_google_default_credentials(); @@ -885,37 +883,39 @@ static void test_google_default_creds_auth_key(void) { gpr_free(json_key); creds = reinterpret_cast( grpc_google_default_credentials_create()); - default_creds = reinterpret_cast( - creds->inner_creds); - GPR_ASSERT(default_creds->ssl_creds != nullptr); - jwt = reinterpret_cast( - creds->call_creds); + auto* default_creds = + reinterpret_cast( + creds->inner_creds()); + GPR_ASSERT(default_creds->ssl_creds() != nullptr); + auto* jwt = + reinterpret_cast( + creds->call_creds()); GPR_ASSERT( - strcmp(jwt->key.client_id, + strcmp(jwt->key().client_id, "777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") == 0); - grpc_channel_credentials_unref(&creds->base); + creds->Unref(); gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ } static void test_google_default_creds_refresh_token(void) { grpc_core::ExecCtx exec_ctx; - grpc_google_refresh_token_credentials* refresh; - grpc_google_default_channel_credentials* default_creds; grpc_composite_channel_credentials* creds; grpc_flush_cached_google_default_credentials(); set_google_default_creds_env_var_with_file_contents( "refresh_token_google_default_creds", test_refresh_token_str); creds = reinterpret_cast( grpc_google_default_credentials_create()); - default_creds = reinterpret_cast( - creds->inner_creds); - GPR_ASSERT(default_creds->ssl_creds != nullptr); - refresh = reinterpret_cast( - creds->call_creds); - GPR_ASSERT(strcmp(refresh->refresh_token.client_id, + auto* default_creds = + reinterpret_cast( + creds->inner_creds()); + GPR_ASSERT(default_creds->ssl_creds() != nullptr); + auto* refresh = + reinterpret_cast( + creds->call_creds()); + GPR_ASSERT(strcmp(refresh->refresh_token().client_id, "32555999999.apps.googleusercontent.com") == 0); - grpc_channel_credentials_unref(&creds->base); + creds->Unref(); gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ } @@ -965,16 +965,16 @@ static void test_google_default_creds_gce(void) { /* Verify that the default creds actually embeds a GCE creds. */ GPR_ASSERT(creds != nullptr); - GPR_ASSERT(creds->call_creds != nullptr); + GPR_ASSERT(creds->call_creds() != nullptr); grpc_httpcli_set_override(compute_engine_httpcli_get_success_override, httpcli_post_should_not_be_called); - run_request_metadata_test(creds->call_creds, auth_md_ctx, state); + run_request_metadata_test(creds->mutable_call_creds(), auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(g_test_gce_tenancy_checker_called == true); /* Cleanup. */ - grpc_channel_credentials_unref(&creds->base); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); grpc_override_well_known_credentials_path_getter(nullptr); } @@ -1003,14 +1003,14 @@ static void test_google_default_creds_non_gce(void) { grpc_google_default_credentials_create()); /* Verify that the default creds actually embeds a GCE creds. */ GPR_ASSERT(creds != nullptr); - GPR_ASSERT(creds->call_creds != nullptr); + GPR_ASSERT(creds->call_creds() != nullptr); grpc_httpcli_set_override(compute_engine_httpcli_get_success_override, httpcli_post_should_not_be_called); - run_request_metadata_test(creds->call_creds, auth_md_ctx, state); + run_request_metadata_test(creds->mutable_call_creds(), auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(g_test_gce_tenancy_checker_called == true); /* Cleanup. */ - grpc_channel_credentials_unref(&creds->base); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); grpc_override_well_known_credentials_path_getter(nullptr); } @@ -1121,7 +1121,7 @@ static void test_metadata_plugin_success(void) { GPR_ASSERT(state == PLUGIN_INITIAL_STATE); run_request_metadata_test(creds, auth_md_ctx, md_state); GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE); - grpc_call_credentials_unref(creds); + creds->Unref(); GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE); } @@ -1149,7 +1149,7 @@ static void test_metadata_plugin_failure(void) { GPR_ASSERT(state == PLUGIN_INITIAL_STATE); run_request_metadata_test(creds, auth_md_ctx, md_state); GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE); - grpc_call_credentials_unref(creds); + creds->Unref(); GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE); } @@ -1176,25 +1176,23 @@ static void test_channel_creds_duplicate_without_call_creds(void) { grpc_channel_credentials* channel_creds = grpc_fake_transport_security_credentials_create(); - grpc_channel_credentials* dup = - grpc_channel_credentials_duplicate_without_call_credentials( - channel_creds); + grpc_core::RefCountedPtr dup = + channel_creds->duplicate_without_call_credentials(); GPR_ASSERT(dup == channel_creds); - grpc_channel_credentials_unref(dup); + dup.reset(); grpc_call_credentials* call_creds = grpc_access_token_credentials_create("blah", nullptr); grpc_channel_credentials* composite_creds = grpc_composite_channel_credentials_create(channel_creds, call_creds, nullptr); - grpc_call_credentials_unref(call_creds); - dup = grpc_channel_credentials_duplicate_without_call_credentials( - composite_creds); + call_creds->Unref(); + dup = composite_creds->duplicate_without_call_credentials(); GPR_ASSERT(dup == channel_creds); - grpc_channel_credentials_unref(dup); + dup.reset(); - grpc_channel_credentials_unref(channel_creds); - grpc_channel_credentials_unref(composite_creds); + channel_creds->Unref(); + composite_creds->Unref(); } typedef struct { diff --git a/test/core/security/oauth2_utils.cc b/test/core/security/oauth2_utils.cc index 469129a6d03..c9e205ab743 100644 --- a/test/core/security/oauth2_utils.cc +++ b/test/core/security/oauth2_utils.cc @@ -86,9 +86,8 @@ char* grpc_test_fetch_oauth2_token_with_credentials( grpc_schedule_on_exec_ctx); grpc_error* error = GRPC_ERROR_NONE; - if (grpc_call_credentials_get_request_metadata(creds, &request.pops, null_ctx, - &request.md_array, - &request.closure, &error)) { + if (creds->get_request_metadata(&request.pops, null_ctx, &request.md_array, + &request.closure, &error)) { // Synchronous result; invoke callback directly. on_oauth2_response(&request, error); GRPC_ERROR_UNREF(error); diff --git a/test/core/security/print_google_default_creds_token.cc b/test/core/security/print_google_default_creds_token.cc index 4d251391ff2..398c58c6e17 100644 --- a/test/core/security/print_google_default_creds_token.cc +++ b/test/core/security/print_google_default_creds_token.cc @@ -96,11 +96,10 @@ int main(int argc, char** argv) { grpc_schedule_on_exec_ctx); error = GRPC_ERROR_NONE; - if (grpc_call_credentials_get_request_metadata( - (reinterpret_cast(creds)) - ->call_creds, - &sync.pops, context, &sync.md_array, &sync.on_request_metadata, - &error)) { + if (reinterpret_cast(creds) + ->mutable_call_creds() + ->get_request_metadata(&sync.pops, context, &sync.md_array, + &sync.on_request_metadata, &error)) { // Synchronous response. Invoke callback directly. on_metadata_response(&sync, error); GRPC_ERROR_UNREF(error); diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index e82a8627d40..2a31763c73c 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -27,6 +27,7 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/lib/security/security_connector/ssl_utils.h" @@ -83,22 +84,22 @@ static int check_ssl_peer_equivalence(const tsi_peer* original, static void test_unauthenticated_ssl_peer(void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, &peer.properties[0]) == TSI_OK); - ctx = grpc_ssl_peer_to_auth_context(&peer); + grpc_core::RefCountedPtr ctx = + grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); - GPR_ASSERT(!grpc_auth_context_peer_is_authenticated(ctx)); - GPR_ASSERT(check_transport_security_type(ctx)); + GPR_ASSERT(!grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT(check_transport_security_type(ctx.get())); - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static int check_identity(const grpc_auth_context* ctx, @@ -175,7 +176,6 @@ static int check_x509_pem_cert(const grpc_auth_context* ctx, static void test_cn_only_ssl_peer_to_auth_context(void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; const char* expected_cn = "cn1"; const char* expected_pem_cert = "pem_cert1"; GPR_ASSERT(tsi_construct_peer(3, &peer) == TSI_OK); @@ -188,26 +188,27 @@ static void test_cn_only_ssl_peer_to_auth_context(void) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, &peer.properties[2]) == TSI_OK); - ctx = grpc_ssl_peer_to_auth_context(&peer); + grpc_core::RefCountedPtr ctx = + grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); - GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); - GPR_ASSERT(check_identity(ctx, GRPC_X509_CN_PROPERTY_NAME, &expected_cn, 1)); - GPR_ASSERT(check_transport_security_type(ctx)); - GPR_ASSERT(check_x509_cn(ctx, expected_cn)); - GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); + GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT( + check_identity(ctx.get(), GRPC_X509_CN_PROPERTY_NAME, &expected_cn, 1)); + GPR_ASSERT(check_transport_security_type(ctx.get())); + GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); + GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_cn_and_one_san_ssl_peer_to_auth_context(void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; const char* expected_cn = "cn1"; const char* expected_san = "san1"; const char* expected_pem_cert = "pem_cert1"; @@ -224,27 +225,28 @@ static void test_cn_and_one_san_ssl_peer_to_auth_context(void) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, &peer.properties[3]) == TSI_OK); - ctx = grpc_ssl_peer_to_auth_context(&peer); - GPR_ASSERT(ctx != nullptr); - GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); - GPR_ASSERT( - check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, &expected_san, 1)); - GPR_ASSERT(check_transport_security_type(ctx)); - GPR_ASSERT(check_x509_cn(ctx, expected_cn)); - GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + grpc_core::RefCountedPtr ctx = + grpc_ssl_peer_to_auth_context(&peer); + GPR_ASSERT(ctx != nullptr); + GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT( + check_identity(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME, &expected_san, 1)); + GPR_ASSERT(check_transport_security_type(ctx.get())); + GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); + GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); + + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; const char* expected_cn = "cn1"; const char* expected_sans[] = {"san1", "san2", "san3"}; const char* expected_pem_cert = "pem_cert1"; @@ -265,28 +267,28 @@ static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) { TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, expected_sans[i], &peer.properties[3 + i]) == TSI_OK); } - ctx = grpc_ssl_peer_to_auth_context(&peer); + grpc_core::RefCountedPtr ctx = + grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); - GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); - GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans, - GPR_ARRAY_SIZE(expected_sans))); - GPR_ASSERT(check_transport_security_type(ctx)); - GPR_ASSERT(check_x509_cn(ctx, expected_cn)); - GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); + GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT(check_identity(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME, + expected_sans, GPR_ARRAY_SIZE(expected_sans))); + GPR_ASSERT(check_transport_security_type(ctx.get())); + GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); + GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context( void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; const char* expected_cn = "cn1"; const char* expected_pem_cert = "pem_cert1"; const char* expected_sans[] = {"san1", "san2", "san3"}; @@ -311,21 +313,22 @@ static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context( TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, expected_sans[i], &peer.properties[5 + i]) == TSI_OK); } - ctx = grpc_ssl_peer_to_auth_context(&peer); + grpc_core::RefCountedPtr ctx = + grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); - GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); - GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans, - GPR_ARRAY_SIZE(expected_sans))); - GPR_ASSERT(check_transport_security_type(ctx)); - GPR_ASSERT(check_x509_cn(ctx, expected_cn)); - GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); + GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT(check_identity(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME, + expected_sans, GPR_ARRAY_SIZE(expected_sans))); + GPR_ASSERT(check_transport_security_type(ctx.get())); + GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); + GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static const char* roots_for_override_api = "roots for override api"; diff --git a/test/core/security/ssl_server_fuzzer.cc b/test/core/security/ssl_server_fuzzer.cc index d2bbb7c1c2e..c9380126dd0 100644 --- a/test/core/security/ssl_server_fuzzer.cc +++ b/test/core/security/ssl_server_fuzzer.cc @@ -82,16 +82,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ca_cert, &pem_key_cert_pair, 1, 0, nullptr); // Create security connector - grpc_server_security_connector* sc = nullptr; - grpc_security_status status = - grpc_server_credentials_create_security_connector(creds, &sc); - GPR_ASSERT(status == GRPC_SECURITY_OK); + grpc_core::RefCountedPtr sc = + creds->create_security_connector(); + GPR_ASSERT(sc != nullptr); grpc_millis deadline = GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(); struct handshake_state state; state.done_callback_called = false; grpc_handshake_manager* handshake_mgr = grpc_handshake_manager_create(); - grpc_server_security_connector_add_handshakers(sc, nullptr, handshake_mgr); + 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); @@ -110,7 +109,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { GPR_ASSERT(state.done_callback_called); grpc_handshake_manager_destroy(handshake_mgr); - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "test"); + sc.reset(DEBUG_LOCATION, "test"); grpc_server_credentials_release(creds); grpc_slice_unref(cert_slice); grpc_slice_unref(key_slice); diff --git a/test/core/surface/secure_channel_create_test.cc b/test/core/surface/secure_channel_create_test.cc index 5610d1ec4ab..e9bb815f6ee 100644 --- a/test/core/surface/secure_channel_create_test.cc +++ b/test/core/surface/secure_channel_create_test.cc @@ -39,7 +39,7 @@ void test_unknown_scheme_target(void) { GPR_ASSERT(0 == strcmp(elem->filter->name, "lame-client")); grpc_core::ExecCtx exec_ctx; GRPC_CHANNEL_INTERNAL_UNREF(chan, "test"); - grpc_channel_credentials_unref(creds); + creds->Unref(); } void test_security_connector_already_in_arg(void) { diff --git a/test/cpp/common/auth_property_iterator_test.cc b/test/cpp/common/auth_property_iterator_test.cc index 9634555e4b5..5a2844d518a 100644 --- a/test/cpp/common/auth_property_iterator_test.cc +++ b/test/cpp/common/auth_property_iterator_test.cc @@ -40,15 +40,14 @@ class TestAuthPropertyIterator : public AuthPropertyIterator { class AuthPropertyIteratorTest : public ::testing::Test { protected: void SetUp() override { - ctx_ = grpc_auth_context_create(nullptr); - grpc_auth_context_add_cstring_property(ctx_, "name", "chapi"); - grpc_auth_context_add_cstring_property(ctx_, "name", "chapo"); - grpc_auth_context_add_cstring_property(ctx_, "foo", "bar"); - EXPECT_EQ(1, - grpc_auth_context_set_peer_identity_property_name(ctx_, "name")); + ctx_ = grpc_core::MakeRefCounted(nullptr); + grpc_auth_context_add_cstring_property(ctx_.get(), "name", "chapi"); + grpc_auth_context_add_cstring_property(ctx_.get(), "name", "chapo"); + grpc_auth_context_add_cstring_property(ctx_.get(), "foo", "bar"); + EXPECT_EQ(1, grpc_auth_context_set_peer_identity_property_name(ctx_.get(), + "name")); } - void TearDown() override { grpc_auth_context_release(ctx_); } - grpc_auth_context* ctx_; + grpc_core::RefCountedPtr ctx_; }; TEST_F(AuthPropertyIteratorTest, DefaultCtor) { @@ -59,7 +58,7 @@ TEST_F(AuthPropertyIteratorTest, DefaultCtor) { TEST_F(AuthPropertyIteratorTest, GeneralTest) { grpc_auth_property_iterator c_iter = - grpc_auth_context_property_iterator(ctx_); + grpc_auth_context_property_iterator(ctx_.get()); const grpc_auth_property* property = grpc_auth_property_iterator_next(&c_iter); TestAuthPropertyIterator iter(property, &c_iter); diff --git a/test/cpp/common/secure_auth_context_test.cc b/test/cpp/common/secure_auth_context_test.cc index 6461f497433..03b3a9fdd8e 100644 --- a/test/cpp/common/secure_auth_context_test.cc +++ b/test/cpp/common/secure_auth_context_test.cc @@ -33,7 +33,7 @@ class SecureAuthContextTest : public ::testing::Test {}; // Created with nullptr TEST_F(SecureAuthContextTest, EmptyContext) { - SecureAuthContext context(nullptr, true); + SecureAuthContext context(nullptr); EXPECT_TRUE(context.GetPeerIdentity().empty()); EXPECT_TRUE(context.GetPeerIdentityPropertyName().empty()); EXPECT_TRUE(context.FindPropertyValues("").empty()); @@ -42,8 +42,10 @@ TEST_F(SecureAuthContextTest, EmptyContext) { } TEST_F(SecureAuthContextTest, Properties) { - grpc_auth_context* ctx = grpc_auth_context_create(nullptr); - SecureAuthContext context(ctx, true); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); + SecureAuthContext context(ctx.get()); + ctx.reset(); context.AddProperty("name", "chapi"); context.AddProperty("name", "chapo"); context.AddProperty("foo", "bar"); @@ -60,8 +62,10 @@ TEST_F(SecureAuthContextTest, Properties) { } TEST_F(SecureAuthContextTest, Iterators) { - grpc_auth_context* ctx = grpc_auth_context_create(nullptr); - SecureAuthContext context(ctx, true); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); + SecureAuthContext context(ctx.get()); + ctx.reset(); context.AddProperty("name", "chapi"); context.AddProperty("name", "chapo"); context.AddProperty("foo", "bar"); diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index bf990a07b5a..2eaacd429de 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -414,8 +414,8 @@ class GrpclbEnd2endTest : public ::testing::Test { std::shared_ptr creds( new SecureChannelCredentials(grpc_composite_channel_credentials_create( channel_creds, call_creds, nullptr))); - grpc_call_credentials_unref(call_creds); - grpc_channel_credentials_unref(channel_creds); + call_creds->Unref(); + channel_creds->Unref(); channel_ = CreateCustomChannel(uri.str(), creds, args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } From e6e10814993b5e6af93675bd468755786de1e20d Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Tue, 11 Dec 2018 10:29:08 -0800 Subject: [PATCH 0544/2143] Add support for Callback Client Streaming benchmarks --- test/cpp/qps/client.h | 28 ++--- test/cpp/qps/client_callback.cc | 176 ++++++++++++++++++++++++++++---- 2 files changed, 174 insertions(+), 30 deletions(-) diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 668d9419169..0b9837660be 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -236,6 +236,21 @@ class Client { return 0; } + bool IsClosedLoop() { return closed_loop_; } + + gpr_timespec NextIssueTime(int thread_idx) { + const gpr_timespec result = next_time_[thread_idx]; + next_time_[thread_idx] = + gpr_time_add(next_time_[thread_idx], + gpr_time_from_nanos(interarrival_timer_.next(thread_idx), + GPR_TIMESPAN)); + return result; + } + + bool ThreadCompleted() { + return static_cast(gpr_atm_acq_load(&thread_pool_done_)); + } + protected: bool closed_loop_; gpr_atm thread_pool_done_; @@ -289,14 +304,6 @@ class Client { } } - gpr_timespec NextIssueTime(int thread_idx) { - const gpr_timespec result = next_time_[thread_idx]; - next_time_[thread_idx] = - gpr_time_add(next_time_[thread_idx], - gpr_time_from_nanos(interarrival_timer_.next(thread_idx), - GPR_TIMESPAN)); - return result; - } std::function NextIssuer(int thread_idx) { return closed_loop_ ? std::function() : std::bind(&Client::NextIssueTime, this, thread_idx); @@ -380,10 +387,6 @@ class Client { double interval_start_time_; }; - bool ThreadCompleted() { - return static_cast(gpr_atm_acq_load(&thread_pool_done_)); - } - virtual void ThreadFunc(size_t thread_idx, Client::Thread* t) = 0; std::vector> threads_; @@ -442,6 +445,7 @@ class ClientImpl : public Client { config.payload_config()); } virtual ~ClientImpl() {} + const RequestType* request() { return &request_; } protected: const int cores_; diff --git a/test/cpp/qps/client_callback.cc b/test/cpp/qps/client_callback.cc index 87889e36dc5..00d5853a8e8 100644 --- a/test/cpp/qps/client_callback.cc +++ b/test/cpp/qps/client_callback.cc @@ -73,6 +73,20 @@ class CallbackClient virtual ~CallbackClient() {} + /** + * The main thread of the benchmark will be waiting on DestroyMultithreading. + * Increment the rpcs_done_ variable to signify that the Callback RPC + * after thread completion is done. When the last outstanding rpc increments + * the counter it should also signal the main thread's conditional variable. + */ + void NotifyMainThreadOfThreadCompletion() { + std::lock_guard l(shutdown_mu_); + rpcs_done_++; + if (rpcs_done_ == total_outstanding_rpcs_) { + shutdown_cv_.notify_one(); + } + } + protected: size_t num_threads_; size_t total_outstanding_rpcs_; @@ -93,23 +107,6 @@ class CallbackClient ThreadFuncImpl(t, thread_idx); } - virtual void ScheduleRpc(Thread* t, size_t thread_idx, - size_t ctx_vector_idx) = 0; - - /** - * The main thread of the benchmark will be waiting on DestroyMultithreading. - * Increment the rpcs_done_ variable to signify that the Callback RPC - * after thread completion is done. When the last outstanding rpc increments - * the counter it should also signal the main thread's conditional variable. - */ - void NotifyMainThreadOfThreadCompletion() { - std::lock_guard l(shutdown_mu_); - rpcs_done_++; - if (rpcs_done_ == total_outstanding_rpcs_) { - shutdown_cv_.notify_one(); - } - } - private: int NumThreads(const ClientConfig& config) { int num_threads = config.async_client_threads(); @@ -157,7 +154,7 @@ class CallbackUnaryClient final : public CallbackClient { void InitThreadFuncImpl(size_t thread_idx) override { return; } private: - void ScheduleRpc(Thread* t, size_t thread_idx, size_t vector_idx) override { + void ScheduleRpc(Thread* t, size_t thread_idx, size_t vector_idx) { if (!closed_loop_) { gpr_timespec next_issue_time = NextIssueTime(thread_idx); // Start an alarm callback to run the internal callback after @@ -199,11 +196,154 @@ class CallbackUnaryClient final : public CallbackClient { } }; +class CallbackStreamingClient : public CallbackClient { + public: + CallbackStreamingClient(const ClientConfig& config) + : CallbackClient(config), + messages_per_stream_(config.messages_per_stream()) { + for (int ch = 0; ch < config.client_channels(); ch++) { + for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) { + ctx_.emplace_back( + new CallbackClientRpcContext(channels_[ch].get_stub())); + } + } + StartThreads(num_threads_); + } + ~CallbackStreamingClient() {} + + void AddHistogramEntry(double start_, bool ok, void* thread_ptr) { + // Update Histogram with data from the callback run + HistogramEntry entry; + if (ok) { + entry.set_value((UsageTimer::Now() - start_) * 1e9); + } + ((Client::Thread*)thread_ptr)->UpdateHistogram(&entry); + } + + int messages_per_stream() { return messages_per_stream_; } + + protected: + const int messages_per_stream_; +}; + +class CallbackStreamingPingPongClient : public CallbackStreamingClient { + public: + CallbackStreamingPingPongClient(const ClientConfig& config) + : CallbackStreamingClient(config) {} + ~CallbackStreamingPingPongClient() {} +}; + +class CallbackStreamingPingPongReactor final + : public grpc::experimental::ClientBidiReactor { + public: + CallbackStreamingPingPongReactor( + CallbackStreamingPingPongClient* client, + std::unique_ptr ctx) + : client_(client), ctx_(std::move(ctx)), messages_issued_(0) {} + + void StartNewRpc() { + if (client_->ThreadCompleted()) return; + start_ = UsageTimer::Now(); + ctx_->stub_->experimental_async()->StreamingCall(&(ctx_->context_), this); + StartWrite(client_->request()); + StartCall(); + } + + void OnWriteDone(bool ok) override { + if (!ok || client_->ThreadCompleted()) { + if (!ok) gpr_log(GPR_ERROR, "Error writing RPC"); + StartWritesDone(); + return; + } + StartRead(&ctx_->response_); + } + + void OnReadDone(bool ok) override { + client_->AddHistogramEntry(start_, ok, thread_ptr_); + + if (client_->ThreadCompleted() || !ok || + (client_->messages_per_stream() != 0 && + ++messages_issued_ >= client_->messages_per_stream())) { + if (!ok) { + gpr_log(GPR_ERROR, "Error reading RPC"); + } + StartWritesDone(); + return; + } + StartWrite(client_->request()); + } + + void OnDone(const Status& s) override { + if (client_->ThreadCompleted() || !s.ok()) { + client_->NotifyMainThreadOfThreadCompletion(); + return; + } + ctx_.reset(new CallbackClientRpcContext(ctx_->stub_)); + ScheduleRpc(); + } + + void ScheduleRpc() { + if (client_->ThreadCompleted()) return; + + if (!client_->IsClosedLoop()) { + gpr_timespec next_issue_time = client_->NextIssueTime(thread_idx_); + // Start an alarm callback to run the internal callback after + // next_issue_time + ctx_->alarm_.experimental().Set(next_issue_time, + [this](bool ok) { StartNewRpc(); }); + } else { + StartNewRpc(); + } + } + + void set_thread_ptr(void* ptr) { thread_ptr_ = ptr; } + void set_thread_idx(int thread_idx) { thread_idx_ = thread_idx; } + + CallbackStreamingPingPongClient* client_; + std::unique_ptr ctx_; + int thread_idx_; // Needed to update histogram entries + void* thread_ptr_; // Needed to update histogram entries + double start_; // Track message start time + int messages_issued_; // Messages issued by this stream +}; + +class CallbackStreamingPingPongClientImpl final + : public CallbackStreamingPingPongClient { + public: + CallbackStreamingPingPongClientImpl(const ClientConfig& config) + : CallbackStreamingPingPongClient(config) { + for (size_t i = 0; i < total_outstanding_rpcs_; i++) + reactor_.emplace_back( + new CallbackStreamingPingPongReactor(this, std::move(ctx_[i]))); + } + ~CallbackStreamingPingPongClientImpl() {} + + bool ThreadFuncImpl(Client::Thread* t, size_t thread_idx) override { + for (size_t vector_idx = thread_idx; vector_idx < total_outstanding_rpcs_; + vector_idx += num_threads_) { + reactor_[vector_idx]->set_thread_ptr(t); + reactor_[vector_idx]->set_thread_idx(thread_idx); + reactor_[vector_idx]->ScheduleRpc(); + } + return true; + } + + void InitThreadFuncImpl(size_t thread_idx) override {} + + private: + std::vector> reactor_; +}; + +// TODO(mhaidry) : Implement Streaming from client, server and both ways + std::unique_ptr CreateCallbackClient(const ClientConfig& config) { switch (config.rpc_type()) { case UNARY: return std::unique_ptr(new CallbackUnaryClient(config)); case STREAMING: + return std::unique_ptr( + new CallbackStreamingPingPongClientImpl(config)); case STREAMING_FROM_CLIENT: case STREAMING_FROM_SERVER: case STREAMING_BOTH_WAYS: From 45b3230ef2b6a4a7e4c7a2348fa65b2c59fe579a Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 12 Dec 2018 17:16:12 -0800 Subject: [PATCH 0545/2143] Add grpcio-status extension package * The new package has 2 API `from_call` and `to_status` * Utilize the experimental API `abort_with_status` * Add 5 unit test cases --- requirements.bazel.txt | 1 + src/python/grpcio_status/.gitignore | 3 + src/python/grpcio_status/MANIFEST.in | 3 + src/python/grpcio_status/README.rst | 9 + .../grpcio_status/grpc_status/BUILD.bazel | 14 ++ .../grpcio_status/grpc_status/__init__.py | 13 ++ .../grpcio_status/grpc_status/rpc_status.py | 88 +++++++++ src/python/grpcio_status/grpc_version.py | 17 ++ src/python/grpcio_status/setup.py | 86 +++++++++ src/python/grpcio_tests/setup.py | 1 + .../grpcio_tests/tests/status/BUILD.bazel | 19 ++ .../grpcio_tests/tests/status/__init__.py | 13 ++ .../tests/status/_grpc_status_test.py | 175 ++++++++++++++++++ src/python/grpcio_tests/tests/tests.json | 1 + .../grpcio_status/grpc_version.py.template | 19 ++ tools/distrib/pylint_code.sh | 1 + .../artifacts/build_artifact_python.sh | 5 + .../run_tests/helper_scripts/build_python.sh | 8 +- 18 files changed, 475 insertions(+), 1 deletion(-) create mode 100644 src/python/grpcio_status/.gitignore create mode 100644 src/python/grpcio_status/MANIFEST.in create mode 100644 src/python/grpcio_status/README.rst create mode 100644 src/python/grpcio_status/grpc_status/BUILD.bazel create mode 100644 src/python/grpcio_status/grpc_status/__init__.py create mode 100644 src/python/grpcio_status/grpc_status/rpc_status.py create mode 100644 src/python/grpcio_status/grpc_version.py create mode 100644 src/python/grpcio_status/setup.py create mode 100644 src/python/grpcio_tests/tests/status/BUILD.bazel create mode 100644 src/python/grpcio_tests/tests/status/__init__.py create mode 100644 src/python/grpcio_tests/tests/status/_grpc_status_test.py create mode 100644 templates/src/python/grpcio_status/grpc_version.py.template diff --git a/requirements.bazel.txt b/requirements.bazel.txt index 7794aec752e..e97843794e4 100644 --- a/requirements.bazel.txt +++ b/requirements.bazel.txt @@ -13,3 +13,4 @@ urllib3>=1.23 chardet==3.0.4 certifi==2017.4.17 idna==2.7 +googleapis-common-protos==1.5.5 diff --git a/src/python/grpcio_status/.gitignore b/src/python/grpcio_status/.gitignore new file mode 100644 index 00000000000..19d1523efde --- /dev/null +++ b/src/python/grpcio_status/.gitignore @@ -0,0 +1,3 @@ +build/ +grpcio_status.egg-info/ +dist/ diff --git a/src/python/grpcio_status/MANIFEST.in b/src/python/grpcio_status/MANIFEST.in new file mode 100644 index 00000000000..eca719a9c20 --- /dev/null +++ b/src/python/grpcio_status/MANIFEST.in @@ -0,0 +1,3 @@ +include grpc_version.py +recursive-include grpc_status *.py +global-exclude *.pyc diff --git a/src/python/grpcio_status/README.rst b/src/python/grpcio_status/README.rst new file mode 100644 index 00000000000..dc2f7b1dab1 --- /dev/null +++ b/src/python/grpcio_status/README.rst @@ -0,0 +1,9 @@ +gRPC Python Status Proto +=========================== + +Reference package for GRPC Python status proto mapping. + +Dependencies +------------ + +Depends on the `grpcio` package, available from PyPI via `pip install grpcio`. diff --git a/src/python/grpcio_status/grpc_status/BUILD.bazel b/src/python/grpcio_status/grpc_status/BUILD.bazel new file mode 100644 index 00000000000..223a077c3f2 --- /dev/null +++ b/src/python/grpcio_status/grpc_status/BUILD.bazel @@ -0,0 +1,14 @@ +load("@grpc_python_dependencies//:requirements.bzl", "requirement") + +package(default_visibility = ["//visibility:public"]) + +py_library( + name = "grpc_status", + srcs = ["rpc_status.py",], + deps = [ + "//src/python/grpcio/grpc:grpcio", + requirement('protobuf'), + requirement('googleapis-common-protos'), + ], + imports=["../",], +) diff --git a/src/python/grpcio_status/grpc_status/__init__.py b/src/python/grpcio_status/grpc_status/__init__.py new file mode 100644 index 00000000000..38fdfc9c5cf --- /dev/null +++ b/src/python/grpcio_status/grpc_status/__init__.py @@ -0,0 +1,13 @@ +# 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. diff --git a/src/python/grpcio_status/grpc_status/rpc_status.py b/src/python/grpcio_status/grpc_status/rpc_status.py new file mode 100644 index 00000000000..36c8eba37d5 --- /dev/null +++ b/src/python/grpcio_status/grpc_status/rpc_status.py @@ -0,0 +1,88 @@ +# 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. +"""Reference implementation for status mapping in gRPC Python.""" + +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 = dict([(x.value[0], x) for x in grpc.StatusCode]) + +_GRPC_DETAILS_METADATA_KEY = 'grpc-status-details-bin' + + +class _Status( + collections.namedtuple( + '_Status', ('code', 'details', 'trailing_metadata')), grpc.Status): + pass + + +def _code_to_grpc_status_code(code): + try: + return _CODE_TO_GRPC_CODE_MAPPING[code] + except KeyError: + raise ValueError('Invalid status code %s' % code) + + +def from_call(call): + """Returns a google.rpc.status.Status message corresponding to a given grpc.Call. + + Args: + call: A grpc.Call instance. + + Returns: + A google.rpc.status.Status message representing the status of the RPC. + + Raises: + ValueError: If the status code, status message is inconsistent with the rich status + inside of the google.rpc.status.Status. + """ + for key, value in call.trailing_metadata(): + if key == _GRPC_DETAILS_METADATA_KEY: + rich_status = status_pb2.Status.FromString(value) + if call.code().value[0] != rich_status.code: + raise ValueError( + 'Code in Status proto (%s) doesn\'t match status code (%s)' + % (_code_to_grpc_status_code(rich_status.code), + call.code())) + if call.details() != rich_status.message: + raise ValueError( + 'Message in Status proto (%s) doesn\'t match status details (%s)' + % (rich_status.message, call.details())) + return rich_status + return None + + +def to_status(status): + """Convert a google.rpc.status.Status message to grpc.Status. + + Args: + status: a google.rpc.status.Status message representing the non-OK status + to terminate the RPC with and communicate it to the client. + + Returns: + A grpc.Status instance. + """ + return _Status( + code=_code_to_grpc_status_code(status.code), + details=status.message, + trailing_metadata=((_GRPC_DETAILS_METADATA_KEY, + status.SerializeToString()),)) diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py new file mode 100644 index 00000000000..e009843b94f --- /dev/null +++ b/src/python/grpcio_status/grpc_version.py @@ -0,0 +1,17 @@ +# 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. + +# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! + +VERSION = '1.18.0.dev0' diff --git a/src/python/grpcio_status/setup.py b/src/python/grpcio_status/setup.py new file mode 100644 index 00000000000..0601498bc51 --- /dev/null +++ b/src/python/grpcio_status/setup.py @@ -0,0 +1,86 @@ +# 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. +"""Setup module for the GRPC Python package's status mapping.""" + +import os + +import setuptools + +# Ensure we're in the proper directory whether or not we're being used by pip. +os.chdir(os.path.dirname(os.path.abspath(__file__))) + +# Break import-style to ensure we can actually find our local modules. +import grpc_version + + +class _NoOpCommand(setuptools.Command): + """No-op command.""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + pass + + +CLASSIFIERS = [ + 'Development Status :: 5 - Production/Stable', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'License :: OSI Approved :: Apache Software License', +] + +PACKAGE_DIRECTORIES = { + '': '.', +} + +INSTALL_REQUIRES = ( + 'protobuf>=3.6.0', + 'grpcio>={version}'.format(version=grpc_version.VERSION), + 'googleapis-common-protos>=1.5.5', +) + +SETUP_REQUIRES = () +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', + version=grpc_version.VERSION, + description='Status proto mapping for gRPC', + author='The gRPC Authors', + author_email='grpc-io@googlegroups.com', + url='https://grpc.io', + license='Apache License 2.0', + classifiers=CLASSIFIERS, + package_dir=PACKAGE_DIRECTORIES, + packages=setuptools.find_packages('.'), + install_requires=INSTALL_REQUIRES, + setup_requires=SETUP_REQUIRES, + cmdclass=COMMAND_CLASS) diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py index f56425ac6d3..f9cb9d0cec9 100644 --- a/src/python/grpcio_tests/setup.py +++ b/src/python/grpcio_tests/setup.py @@ -40,6 +40,7 @@ INSTALL_REQUIRES = ( 'coverage>=4.0', 'enum34>=1.0.4', 'grpcio>={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', diff --git a/src/python/grpcio_tests/tests/status/BUILD.bazel b/src/python/grpcio_tests/tests/status/BUILD.bazel new file mode 100644 index 00000000000..937e50498e0 --- /dev/null +++ b/src/python/grpcio_tests/tests/status/BUILD.bazel @@ -0,0 +1,19 @@ +load("@grpc_python_dependencies//:requirements.bzl", "requirement") + +package(default_visibility = ["//visibility:public"]) + +py_test( + name = "grpc_status_test", + srcs = ["_grpc_status_test.py"], + main = "_grpc_status_test.py", + size = "small", + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_status/grpc_status:grpc_status", + "//src/python/grpcio_tests/tests/unit:test_common", + "//src/python/grpcio_tests/tests/unit/framework/common:common", + requirement('protobuf'), + requirement('googleapis-common-protos'), + ], + imports = ["../../",], +) diff --git a/src/python/grpcio_tests/tests/status/__init__.py b/src/python/grpcio_tests/tests/status/__init__.py new file mode 100644 index 00000000000..38fdfc9c5cf --- /dev/null +++ b/src/python/grpcio_tests/tests/status/__init__.py @@ -0,0 +1,13 @@ +# 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. diff --git a/src/python/grpcio_tests/tests/status/_grpc_status_test.py b/src/python/grpcio_tests/tests/status/_grpc_status_test.py new file mode 100644 index 00000000000..5969338736f --- /dev/null +++ b/src/python/grpcio_tests/tests/status/_grpc_status_test.py @@ -0,0 +1,175 @@ +# 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. +"""Tests of grpc_status.""" + +import unittest + +import logging +import traceback + +import grpc +from grpc_status import rpc_status + +from tests.unit import test_common + +from google.protobuf import any_pb2 +from google.rpc import code_pb2, status_pb2, error_details_pb2 + +_STATUS_OK = '/test/StatusOK' +_STATUS_NOT_OK = '/test/StatusNotOk' +_ERROR_DETAILS = '/test/ErrorDetails' +_INCONSISTENT = '/test/Inconsistent' +_INVALID_CODE = '/test/InvalidCode' + +_REQUEST = b'\x00\x00\x00' +_RESPONSE = b'\x01\x01\x01' + +_GRPC_DETAILS_METADATA_KEY = 'grpc-status-details-bin' + +_STATUS_DETAILS = 'This is an error detail' +_STATUS_DETAILS_ANOTHER = 'This is another error detail' + + +def _ok_unary_unary(request, servicer_context): + return _RESPONSE + + +def _not_ok_unary_unary(request, servicer_context): + servicer_context.abort(grpc.StatusCode.INTERNAL, _STATUS_DETAILS) + + +def _error_details_unary_unary(request, servicer_context): + details = any_pb2.Any() + details.Pack( + error_details_pb2.DebugInfo( + stack_entries=traceback.format_stack(), + detail='Intensionally invoked')) + rich_status = status_pb2.Status( + code=code_pb2.INTERNAL, + message=_STATUS_DETAILS, + details=[details], + ) + servicer_context.abort_with_status(rpc_status.to_status(rich_status)) + + +def _inconsistent_unary_unary(request, servicer_context): + rich_status = status_pb2.Status( + code=code_pb2.INTERNAL, + message=_STATUS_DETAILS, + ) + servicer_context.set_code(grpc.StatusCode.NOT_FOUND) + servicer_context.set_details(_STATUS_DETAILS_ANOTHER) + # User put inconsistent status information in trailing metadata + servicer_context.set_trailing_metadata(((_GRPC_DETAILS_METADATA_KEY, + rich_status.SerializeToString()),)) + + +def _invalid_code_unary_unary(request, servicer_context): + rich_status = status_pb2.Status( + code=42, + message='Invalid code', + ) + servicer_context.abort_with_status(rpc_status.to_status(rich_status)) + + +class _GenericHandler(grpc.GenericRpcHandler): + + def service(self, handler_call_details): + if handler_call_details.method == _STATUS_OK: + return grpc.unary_unary_rpc_method_handler(_ok_unary_unary) + elif handler_call_details.method == _STATUS_NOT_OK: + return grpc.unary_unary_rpc_method_handler(_not_ok_unary_unary) + elif handler_call_details.method == _ERROR_DETAILS: + return grpc.unary_unary_rpc_method_handler( + _error_details_unary_unary) + elif handler_call_details.method == _INCONSISTENT: + return grpc.unary_unary_rpc_method_handler( + _inconsistent_unary_unary) + elif handler_call_details.method == _INVALID_CODE: + return grpc.unary_unary_rpc_method_handler( + _invalid_code_unary_unary) + else: + return None + + +class StatusTest(unittest.TestCase): + + def setUp(self): + self._server = test_common.test_server() + self._server.add_generic_rpc_handlers((_GenericHandler(),)) + port = self._server.add_insecure_port('[::]:0') + self._server.start() + + self._channel = grpc.insecure_channel('localhost:%d' % port) + + def tearDown(self): + self._server.stop(None) + self._channel.close() + + def test_status_ok(self): + try: + _, call = self._channel.unary_unary(_STATUS_OK).with_call(_REQUEST) + except grpc.RpcError as rpc_error: + self.fail(rpc_error) + # Succeed RPC doesn't have status + status = rpc_status.from_call(call) + self.assertIs(status, None) + + def test_status_not_ok(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_STATUS_NOT_OK).with_call(_REQUEST) + rpc_error = exception_context.exception + + self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) + # Failed RPC doesn't automatically generate status + status = rpc_status.from_call(rpc_error) + self.assertIs(status, None) + + def test_error_details(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_ERROR_DETAILS).with_call(_REQUEST) + rpc_error = exception_context.exception + + status = rpc_status.from_call(rpc_error) + self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) + self.assertEqual(status.code, code_pb2.Code.Value('INTERNAL')) + + # Check if the underlying proto message is intact + self.assertEqual(status.details[0].Is( + error_details_pb2.DebugInfo.DESCRIPTOR), True) + info = error_details_pb2.DebugInfo() + status.details[0].Unpack(info) + self.assertIn('_error_details_unary_unary', info.stack_entries[-1]) + + def test_code_message_validation(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_INCONSISTENT).with_call(_REQUEST) + rpc_error = exception_context.exception + self.assertEqual(rpc_error.code(), grpc.StatusCode.NOT_FOUND) + + # Code/Message validation failed + self.assertRaises(ValueError, rpc_status.from_call, rpc_error) + + def test_invalid_code(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_INVALID_CODE).with_call(_REQUEST) + rpc_error = exception_context.exception + self.assertEqual(rpc_error.code(), grpc.StatusCode.UNKNOWN) + # Invalid status code exception raised during coversion + self.assertIn('Invalid status code', rpc_error.details()) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index 44700e979e9..b27e6f26938 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -15,6 +15,7 @@ "protoc_plugin._split_definitions_test.SplitProtoSingleProtocExecutionProtocStyleTest", "protoc_plugin.beta_python_plugin_test.PythonPluginTest", "reflection._reflection_servicer_test.ReflectionServicerTest", + "status._grpc_status_test.StatusTest", "testing._client_test.ClientTest", "testing._server_test.FirstServiceServicerTest", "testing._time_test.StrictFakeTimeTest", diff --git a/templates/src/python/grpcio_status/grpc_version.py.template b/templates/src/python/grpcio_status/grpc_version.py.template new file mode 100644 index 00000000000..727e01edb93 --- /dev/null +++ b/templates/src/python/grpcio_status/grpc_version.py.template @@ -0,0 +1,19 @@ +%YAML 1.2 +--- | + # 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. + + # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! + + VERSION = '${settings.python_version.pep440()}' diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh index d17eb9fdb82..8a5f7af6c6c 100755 --- a/tools/distrib/pylint_code.sh +++ b/tools/distrib/pylint_code.sh @@ -24,6 +24,7 @@ DIRS=( 'src/python/grpcio_health_checking/grpc_health' 'src/python/grpcio_reflection/grpc_reflection' 'src/python/grpcio_testing/grpc_testing' + 'src/python/grpcio_status/grpc_status' ) TEST_DIRS=( diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index 605470325ab..18eb70c8574 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -123,6 +123,11 @@ then ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_reflection/setup.py \ preprocess build_package_protos sdist cp -r src/python/grpcio_reflection/dist/* "$ARTIFACT_DIR" + + # Build grpcio_status source distribution + ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_status/setup.py \ + preprocess build_package_protos sdist + cp -r src/python/grpcio_status/dist/* "$ARTIFACT_DIR" fi cp -r dist/* "$ARTIFACT_DIR" diff --git a/tools/run_tests/helper_scripts/build_python.sh b/tools/run_tests/helper_scripts/build_python.sh index e43f1fb429c..7cd1ef9d517 100755 --- a/tools/run_tests/helper_scripts/build_python.sh +++ b/tools/run_tests/helper_scripts/build_python.sh @@ -204,12 +204,18 @@ $VENV_PYTHON "$ROOT/src/python/grpcio_reflection/setup.py" preprocess $VENV_PYTHON "$ROOT/src/python/grpcio_reflection/setup.py" build_package_protos pip_install_dir "$ROOT/src/python/grpcio_reflection" +# Build/install status proto mapping +$VENV_PYTHON "$ROOT/src/python/grpcio_status/setup.py" preprocess +$VENV_PYTHON "$ROOT/src/python/grpcio_status/setup.py" build_package_protos +pip_install_dir "$ROOT/src/python/grpcio_status" + # Install testing pip_install_dir "$ROOT/src/python/grpcio_testing" # Build/install tests $VENV_PYTHON -m pip install coverage==4.4 oauth2client==4.1.0 \ - google-auth==1.0.0 requests==2.14.2 + google-auth==1.0.0 requests==2.14.2 \ + googleapis-common-protos==1.5.5 $VENV_PYTHON "$ROOT/src/python/grpcio_tests/setup.py" preprocess $VENV_PYTHON "$ROOT/src/python/grpcio_tests/setup.py" build_package_protos pip_install_dir "$ROOT/src/python/grpcio_tests" From 4ec4c0b6b44976fedada0f50fe3c823314491f2a Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Thu, 13 Dec 2018 10:56:32 -0800 Subject: [PATCH 0546/2143] Set SSL_CTX_set_verify even if pem_client_root_certs is null --- src/core/tsi/ssl_transport_security.cc | 47 +++++++++++++------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index d6a72ada0d8..efaf733503e 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -1850,31 +1850,30 @@ tsi_result tsi_create_ssl_server_handshaker_factory_with_options( break; } SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names); - switch (options->client_certificate_request) { - case TSI_DONT_REQUEST_CLIENT_CERTIFICATE: - SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_NONE, nullptr); - break; - case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: - SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, - NullVerifyCallback); - break; - case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY: - SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, nullptr); - break; - case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: - SSL_CTX_set_verify( - impl->ssl_contexts[i], - SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, - NullVerifyCallback); - break; - case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY: - SSL_CTX_set_verify( - impl->ssl_contexts[i], - SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr); - break; - } - /* TODO(jboeuf): Add revocation verification. */ } + switch (options->client_certificate_request) { + case TSI_DONT_REQUEST_CLIENT_CERTIFICATE: + SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_NONE, nullptr); + break; + case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, + NullVerifyCallback); + break; + case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, nullptr); + break; + case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + NullVerifyCallback); + break; + case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + nullptr); + break; + } + /* TODO(jboeuf): Add revocation verification. */ result = extract_x509_subject_names_from_pem_cert( options->pem_key_cert_pairs[i].cert_chain, From 5ea2ed602b9d7dfec109c520446e6e0570840d45 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 12 Dec 2018 18:52:26 -0800 Subject: [PATCH 0547/2143] Move most c-ares logs under a tracer --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 42 ++++++++++------- .../dns/c_ares/grpc_ares_ev_driver.cc | 47 ++++++++++++------- .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 43 +++++++++-------- 3 files changed, 74 insertions(+), 58 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 fc83fc44889..abacd0c960d 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 @@ -170,7 +170,7 @@ AresDnsResolver::AresDnsResolver(const ResolverArgs& args) } AresDnsResolver::~AresDnsResolver() { - gpr_log(GPR_DEBUG, "destroying AresDnsResolver"); + GRPC_CARES_TRACE_LOG("resolver:%p destroying AresDnsResolver", this); if (resolved_result_ != nullptr) { grpc_channel_args_destroy(resolved_result_); } @@ -182,7 +182,8 @@ AresDnsResolver::~AresDnsResolver() { void AresDnsResolver::NextLocked(grpc_channel_args** target_result, grpc_closure* on_complete) { - gpr_log(GPR_DEBUG, "AresDnsResolver::NextLocked() is called."); + GRPC_CARES_TRACE_LOG("resolver:%p AresDnsResolver::NextLocked() is called.", + this); GPR_ASSERT(next_completion_ == nullptr); next_completion_ = on_complete; target_result_ = target_result; @@ -225,12 +226,14 @@ void AresDnsResolver::ShutdownLocked() { void AresDnsResolver::OnNextResolutionLocked(void* arg, grpc_error* error) { AresDnsResolver* r = static_cast(arg); GRPC_CARES_TRACE_LOG( - "%p re-resolution timer fired. error: %s. shutdown_initiated_: %d", r, - grpc_error_string(error), r->shutdown_initiated_); + "resolver:%p re-resolution timer fired. error: %s. shutdown_initiated_: " + "%d", + r, grpc_error_string(error), r->shutdown_initiated_); r->have_next_resolution_timer_ = false; if (error == GRPC_ERROR_NONE && !r->shutdown_initiated_) { if (!r->resolving_) { - GRPC_CARES_TRACE_LOG("%p start resolving due to re-resolution timer", r); + GRPC_CARES_TRACE_LOG( + "resolver:%p start resolving due to re-resolution timer", r); r->StartResolvingLocked(); } } @@ -327,8 +330,8 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { service_config_string = ChooseServiceConfig(r->service_config_json_); gpr_free(r->service_config_json_); if (service_config_string != nullptr) { - gpr_log(GPR_INFO, "selected service config choice: %s", - service_config_string); + 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); @@ -344,11 +347,11 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { r->backoff_.Reset(); } else if (!r->shutdown_initiated_) { const char* msg = grpc_error_string(error); - gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg); + GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed: %s", r, msg); 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)); + GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed (will retry): %s", + r, grpc_error_string(error)); GPR_ASSERT(!r->have_next_resolution_timer_); r->have_next_resolution_timer_ = true; // TODO(roth): We currently deal with this ref manually. Once the @@ -357,9 +360,10 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { RefCountedPtr self = r->Ref(DEBUG_LOCATION, "retry-timer"); self.release(); if (timeout > 0) { - gpr_log(GPR_DEBUG, "retrying in %" PRId64 " milliseconds", timeout); + GRPC_CARES_TRACE_LOG("resolver:%p retrying in %" PRId64 " milliseconds", + r, timeout); } else { - gpr_log(GPR_DEBUG, "retrying immediately"); + GRPC_CARES_TRACE_LOG("resolver:%p retrying immediately", r); } grpc_timer_init(&r->next_resolution_timer_, next_try, &r->on_next_resolution_); @@ -385,10 +389,10 @@ void AresDnsResolver::MaybeStartResolvingLocked() { if (ms_until_next_resolution > 0) { const grpc_millis last_resolution_ago = grpc_core::ExecCtx::Get()->Now() - last_resolution_timestamp_; - gpr_log(GPR_DEBUG, - "In cooldown from last resolution (from %" PRId64 - " ms ago). Will resolve again in %" PRId64 " ms", - last_resolution_ago, ms_until_next_resolution); + GRPC_CARES_TRACE_LOG( + "resolver:%p In cooldown from last resolution (from %" PRId64 + " ms ago). Will resolve again in %" PRId64 " ms", + this, last_resolution_ago, ms_until_next_resolution); 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 @@ -405,7 +409,6 @@ void AresDnsResolver::MaybeStartResolvingLocked() { } void AresDnsResolver::StartResolvingLocked() { - gpr_log(GPR_DEBUG, "Start resolving."); // 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. @@ -420,6 +423,8 @@ void AresDnsResolver::StartResolvingLocked() { request_service_config_ ? &service_config_json_ : nullptr, query_timeout_ms_, combiner()); last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); + GRPC_CARES_TRACE_LOG("resolver:%p Started resolving. pending_request_:%p", + this, pending_request_); } void AresDnsResolver::MaybeFinishNextLocked() { @@ -427,7 +432,8 @@ void AresDnsResolver::MaybeFinishNextLocked() { *target_result_ = resolved_result_ == nullptr ? nullptr : grpc_channel_args_copy(resolved_result_); - gpr_log(GPR_DEBUG, "AresDnsResolver::MaybeFinishNextLocked()"); + GRPC_CARES_TRACE_LOG("resolver:%p AresDnsResolver::MaybeFinishNextLocked()", + this); GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE); next_completion_ = nullptr; published_version_ = resolved_version_; diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc index 8abc34c6edb..d99c2e30047 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -90,15 +90,18 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver); static grpc_ares_ev_driver* grpc_ares_ev_driver_ref( grpc_ares_ev_driver* ev_driver) { - gpr_log(GPR_DEBUG, "Ref ev_driver %" PRIuPTR, (uintptr_t)ev_driver); + GRPC_CARES_TRACE_LOG("request:%p Ref ev_driver %p", ev_driver->request, + ev_driver); gpr_ref(&ev_driver->refs); return ev_driver; } static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) { - gpr_log(GPR_DEBUG, "Unref ev_driver %" PRIuPTR, (uintptr_t)ev_driver); + GRPC_CARES_TRACE_LOG("request:%p Unref ev_driver %p", ev_driver->request, + ev_driver); if (gpr_unref(&ev_driver->refs)) { - gpr_log(GPR_DEBUG, "destroy ev_driver %" PRIuPTR, (uintptr_t)ev_driver); + GRPC_CARES_TRACE_LOG("request:%p destroy ev_driver %p", ev_driver->request, + ev_driver); GPR_ASSERT(ev_driver->fds == nullptr); GRPC_COMBINER_UNREF(ev_driver->combiner, "free ares event driver"); ares_destroy(ev_driver->channel); @@ -108,7 +111,8 @@ static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) { } static void fd_node_destroy_locked(fd_node* fdn) { - gpr_log(GPR_DEBUG, "delete fd: %s", fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p delete fd: %s", fdn->ev_driver->request, + fdn->grpc_polled_fd->GetName()); GPR_ASSERT(!fdn->readable_registered); GPR_ASSERT(!fdn->writable_registered); GPR_ASSERT(fdn->already_shutdown); @@ -136,7 +140,7 @@ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, memset(&opts, 0, sizeof(opts)); opts.flags |= ARES_FLAG_STAYOPEN; int status = ares_init_options(&(*ev_driver)->channel, &opts, ARES_OPT_FLAGS); - gpr_log(GPR_DEBUG, "grpc_ares_ev_driver_create_locked"); + GRPC_CARES_TRACE_LOG("request:%p grpc_ares_ev_driver_create_locked", request); if (status != ARES_SUCCESS) { char* err_msg; gpr_asprintf(&err_msg, "Failed to init ares channel. C-ares error: %s", @@ -203,8 +207,9 @@ static fd_node* pop_fd_node_locked(fd_node** head, ares_socket_t as) { static void on_timeout_locked(void* arg, grpc_error* error) { grpc_ares_ev_driver* driver = static_cast(arg); GRPC_CARES_TRACE_LOG( - "ev_driver=%p on_timeout_locked. driver->shutting_down=%d. err=%s", - driver, driver->shutting_down, grpc_error_string(error)); + "request:%p ev_driver=%p on_timeout_locked. driver->shutting_down=%d. " + "err=%s", + driver->request, driver, driver->shutting_down, grpc_error_string(error)); if (!driver->shutting_down && error == GRPC_ERROR_NONE) { grpc_ares_ev_driver_shutdown_locked(driver); } @@ -216,7 +221,8 @@ static void on_readable_locked(void* arg, grpc_error* error) { grpc_ares_ev_driver* ev_driver = fdn->ev_driver; const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked(); fdn->readable_registered = false; - gpr_log(GPR_DEBUG, "readable on %s", fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p readable on %s", fdn->ev_driver->request, + fdn->grpc_polled_fd->GetName()); if (error == GRPC_ERROR_NONE) { do { ares_process_fd(ev_driver->channel, as, ARES_SOCKET_BAD); @@ -239,7 +245,8 @@ static void on_writable_locked(void* arg, grpc_error* error) { grpc_ares_ev_driver* ev_driver = fdn->ev_driver; const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked(); fdn->writable_registered = false; - gpr_log(GPR_DEBUG, "writable on %s", fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p writable on %s", ev_driver->request, + fdn->grpc_polled_fd->GetName()); if (error == GRPC_ERROR_NONE) { ares_process_fd(ev_driver->channel, ARES_SOCKET_BAD, as); } else { @@ -278,7 +285,8 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) { fdn->grpc_polled_fd = ev_driver->polled_fd_factory->NewGrpcPolledFdLocked( socks[i], ev_driver->pollset_set, ev_driver->combiner); - gpr_log(GPR_DEBUG, "new fd: %s", fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p new fd: %s", ev_driver->request, + fdn->grpc_polled_fd->GetName()); fdn->ev_driver = ev_driver; fdn->readable_registered = false; fdn->writable_registered = false; @@ -295,8 +303,9 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) { if (ARES_GETSOCK_READABLE(socks_bitmask, i) && !fdn->readable_registered) { grpc_ares_ev_driver_ref(ev_driver); - gpr_log(GPR_DEBUG, "notify read on: %s", - fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p notify read on: %s", + ev_driver->request, + fdn->grpc_polled_fd->GetName()); fdn->grpc_polled_fd->RegisterForOnReadableLocked(&fdn->read_closure); fdn->readable_registered = true; } @@ -304,8 +313,9 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) { // has not been registered with this socket. if (ARES_GETSOCK_WRITABLE(socks_bitmask, i) && !fdn->writable_registered) { - gpr_log(GPR_DEBUG, "notify write on: %s", - fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p notify write on: %s", + ev_driver->request, + fdn->grpc_polled_fd->GetName()); grpc_ares_ev_driver_ref(ev_driver); fdn->grpc_polled_fd->RegisterForOnWriteableLocked( &fdn->write_closure); @@ -332,7 +342,8 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) { // If the ev driver has no working fd, all the tasks are done. if (new_list == nullptr) { ev_driver->working = false; - gpr_log(GPR_DEBUG, "ev driver stop working"); + GRPC_CARES_TRACE_LOG("request:%p ev driver stop working", + ev_driver->request); } } @@ -345,9 +356,9 @@ void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) { ? GRPC_MILLIS_INF_FUTURE : ev_driver->query_timeout_ms + grpc_core::ExecCtx::Get()->Now(); GRPC_CARES_TRACE_LOG( - "ev_driver=%p grpc_ares_ev_driver_start_locked. timeout in %" PRId64 - " ms", - ev_driver, timeout); + "request:%p ev_driver=%p grpc_ares_ev_driver_start_locked. timeout in " + "%" PRId64 " ms", + ev_driver->request, ev_driver, timeout); grpc_ares_ev_driver_ref(ev_driver); grpc_timer_init(&ev_driver->query_timeout, timeout, &ev_driver->on_timeout_locked); 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 68977567694..1a7e5d06268 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 @@ -96,11 +96,11 @@ static void log_address_sorting_list(const ServerAddressList& addresses, for (size_t i = 0; i < addresses.size(); i++) { char* addr_str; if (grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true)) { - gpr_log(GPR_DEBUG, "c-ares address sorting: %s[%" PRIuPTR "]=%s", + gpr_log(GPR_INFO, "c-ares address sorting: %s[%" PRIuPTR "]=%s", input_output_str, i, addr_str); gpr_free(addr_str); } else { - gpr_log(GPR_DEBUG, + gpr_log(GPR_INFO, "c-ares address sorting: %s[%" PRIuPTR "]=", input_output_str, i); } @@ -209,10 +209,10 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, addresses.emplace_back(&addr, addr_len, args); char output[INET6_ADDRSTRLEN]; ares_inet_ntop(AF_INET6, &addr.sin6_addr, output, INET6_ADDRSTRLEN); - gpr_log(GPR_DEBUG, - "c-ares resolver gets a AF_INET6 result: \n" - " addr: %s\n port: %d\n sin6_scope_id: %d\n", - output, ntohs(hr->port), addr.sin6_scope_id); + GRPC_CARES_TRACE_LOG( + "request:%p c-ares resolver gets a AF_INET6 result: \n" + " addr: %s\n port: %d\n sin6_scope_id: %d\n", + r, output, ntohs(hr->port), addr.sin6_scope_id); break; } case AF_INET: { @@ -226,10 +226,10 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, addresses.emplace_back(&addr, addr_len, args); char output[INET_ADDRSTRLEN]; ares_inet_ntop(AF_INET, &addr.sin_addr, output, INET_ADDRSTRLEN); - gpr_log(GPR_DEBUG, - "c-ares resolver gets a AF_INET result: \n" - " addr: %s\n port: %d\n", - output, ntohs(hr->port)); + GRPC_CARES_TRACE_LOG( + "request:%p c-ares resolver gets a AF_INET result: \n" + " addr: %s\n port: %d\n", + r, output, ntohs(hr->port)); break; } } @@ -252,9 +252,9 @@ 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); - gpr_log(GPR_DEBUG, "on_query_srv_done_locked"); + GRPC_CARES_TRACE_LOG("request:%p on_query_srv_done_locked", r); if (status == ARES_SUCCESS) { - gpr_log(GPR_DEBUG, "on_query_srv_done_locked ARES_SUCCESS"); + GRPC_CARES_TRACE_LOG("request:%p on_query_srv_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) { @@ -297,9 +297,9 @@ static const char g_service_config_attribute_prefix[] = "grpc_config="; static void on_txt_done_locked(void* arg, int status, int timeouts, unsigned char* buf, int len) { - gpr_log(GPR_DEBUG, "on_txt_done_locked"); 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; @@ -332,7 +332,8 @@ static void on_txt_done_locked(void* arg, int status, int timeouts, service_config_len += result->length; } (*r->service_config_json_out)[service_config_len] = '\0'; - gpr_log(GPR_INFO, "found service config: %s", *r->service_config_json_out); + GRPC_CARES_TRACE_LOG("request:%p found service config: %s", r, + *r->service_config_json_out); } // Clean up. ares_free_data(reply); @@ -358,12 +359,6 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( grpc_error* error = GRPC_ERROR_NONE; grpc_ares_hostbyname_request* hr = nullptr; ares_channel* channel = nullptr; - /* TODO(zyc): Enable tracing after #9603 is checked in */ - /* if (grpc_dns_trace) { - gpr_log(GPR_DEBUG, "resolve_address (blocking): name=%s, default_port=%s", - name, default_port); - } */ - /* parse name, splitting it into host and port parts */ char* host; char* port; @@ -388,7 +383,7 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver); // If dns_server is specified, use it. if (dns_server != nullptr) { - gpr_log(GPR_INFO, "Using DNS server %s", dns_server); + GRPC_CARES_TRACE_LOG("request:%p Using DNS server %s", r, dns_server); grpc_resolved_address addr; if (grpc_parse_ipv4_hostport(dns_server, &addr, false /* log_errors */)) { r->dns_server_addr.family = AF_INET; @@ -513,7 +508,7 @@ static bool resolve_as_ip_literal_locked( static bool target_matches_localhost_inner(const char* name, char** host, char** port) { if (!gpr_split_host_port(name, host, port)) { - gpr_log(GPR_INFO, "Unable to split host and port for name: %s", name); + gpr_log(GPR_ERROR, "Unable to split host and port for name: %s", name); return false; } if (gpr_stricmp(*host, "localhost") == 0) { @@ -547,6 +542,10 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( r->success = false; r->error = GRPC_ERROR_NONE; r->pending_queries = 0; + GRPC_CARES_TRACE_LOG( + "request:%p c-ares grpc_dns_lookup_ares_locked_impl name=%s, " + "default_port=%s", + 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); From 48ac4ee48a56582c86f2ada6d3281e37590c57c4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 13 Dec 2018 11:21:45 -0800 Subject: [PATCH 0548/2143] Test assert failure --- src/objective-c/tests/InteropTests.m | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 3665e9705d8..656af188884 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -197,7 +197,8 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testEmptyUnaryRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnaryWithV2API"]; + __weak XCTestExpectation *expectReceive = [self expectationWithDescription:@"EmptyUnaryWithV2API received message"]; + __weak XCTestExpectation *expectComplete = [self expectationWithDescription:@"EmptyUnaryWithV2API completed"]; GPBEmpty *request = [GPBEmpty message]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; @@ -212,11 +213,12 @@ BOOL isRemoteInteropTest(NSString *host) { if (message) { id expectedResponse = [GPBEmpty message]; XCTAssertEqualObjects(message, expectedResponse); - [expectation fulfill]; + [expectReceive fulfill]; } } closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { XCTAssertNil(error, @"Unexpected error: %@", error); + [expectComplete fulfill]; }] callOptions:options]; [call start]; @@ -249,9 +251,9 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testLargeUnaryRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectRecvMessage = + __weak XCTestExpectation *expectReceive = [self expectationWithDescription:@"LargeUnaryWithV2API received message"]; - __weak XCTestExpectation *expectRecvComplete = + __weak XCTestExpectation *expectComplete = [self expectationWithDescription:@"LargeUnaryWithV2API received complete"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -277,12 +279,12 @@ BOOL isRemoteInteropTest(NSString *host) { [NSMutableData dataWithLength:314159]; XCTAssertEqualObjects(message, expectedResponse); - [expectRecvMessage fulfill]; + [expectReceive fulfill]; } } closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { XCTAssertNil(error, @"Unexpected error: %@", error); - [expectRecvComplete fulfill]; + [expectComplete fulfill]; }] callOptions:options]; [call start]; From dc502a80988763abefb70938d020123ef0422e18 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 13 Dec 2018 11:27:26 -0800 Subject: [PATCH 0549/2143] clang-format --- src/objective-c/tests/InteropTests.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 656af188884..717dfd81f7d 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -197,8 +197,10 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testEmptyUnaryRPCWithV2API { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectReceive = [self expectationWithDescription:@"EmptyUnaryWithV2API received message"]; - __weak XCTestExpectation *expectComplete = [self expectationWithDescription:@"EmptyUnaryWithV2API completed"]; + __weak XCTestExpectation *expectReceive = + [self expectationWithDescription:@"EmptyUnaryWithV2API received message"]; + __weak XCTestExpectation *expectComplete = + [self expectationWithDescription:@"EmptyUnaryWithV2API completed"]; GPBEmpty *request = [GPBEmpty message]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; From 0f0822d53f37ea9da8bf838e5b3c62b05afe2f10 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 13 Dec 2018 16:33:02 -0800 Subject: [PATCH 0550/2143] WIP: Utilize the GitHub Check Feature --- tools/profiling/bloat/bloat_diff.py | 4 +- tools/profiling/ios_bin/binary_size.py | 4 +- .../microbenchmarks/bm_diff/bm_main.py | 4 +- tools/profiling/qps/qps_diff.py | 4 +- tools/run_tests/python_utils/check_on_pr.py | 98 +++++++++++++++++++ 5 files changed, 106 insertions(+), 8 deletions(-) create mode 100644 tools/run_tests/python_utils/check_on_pr.py diff --git a/tools/profiling/bloat/bloat_diff.py b/tools/profiling/bloat/bloat_diff.py index 91611c2ca4a..36189151e9e 100755 --- a/tools/profiling/bloat/bloat_diff.py +++ b/tools/profiling/bloat/bloat_diff.py @@ -25,7 +25,7 @@ import sys sys.path.append( os.path.join( os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils')) -import comment_on_pr +import check_on_pr argp = argparse.ArgumentParser(description='Perform diff on microbenchmarks') @@ -90,4 +90,4 @@ for lib in LIBS: text += '\n\n' print text -comment_on_pr.comment_on_pr('```\n%s\n```' % text) +check_on_pr.check_on_pr('Bloat Difference', '```\n%s\n```' % text) diff --git a/tools/profiling/ios_bin/binary_size.py b/tools/profiling/ios_bin/binary_size.py index d4d134fef37..f0c8dd01a01 100755 --- a/tools/profiling/ios_bin/binary_size.py +++ b/tools/profiling/ios_bin/binary_size.py @@ -26,7 +26,7 @@ from parse_link_map import parse_link_map sys.path.append( os.path.join( os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils')) -import comment_on_pr +import check_on_pr # Only show diff 1KB or greater diff_threshold = 1000 @@ -147,4 +147,4 @@ for frameworks in [False, True]: print text -comment_on_pr.comment_on_pr('```\n%s\n```' % text) +check_on_pr.check_on_pr('Binary Size', '```\n%s\n```' % text) diff --git a/tools/profiling/microbenchmarks/bm_diff/bm_main.py b/tools/profiling/microbenchmarks/bm_diff/bm_main.py index 96c63ba060e..e5061b24f57 100755 --- a/tools/profiling/microbenchmarks/bm_diff/bm_main.py +++ b/tools/profiling/microbenchmarks/bm_diff/bm_main.py @@ -30,7 +30,7 @@ import subprocess sys.path.append( os.path.join( os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils')) -import comment_on_pr +import check_on_pr sys.path.append( os.path.join( @@ -152,7 +152,7 @@ def main(args): if note: text = note + '\n\n' + text print('%s' % text) - comment_on_pr.comment_on_pr('```\n%s\n```' % text) + check_on_pr.check_on_pr('Benchmark', '```\n%s\n```' % text) if __name__ == '__main__': diff --git a/tools/profiling/qps/qps_diff.py b/tools/profiling/qps/qps_diff.py index 393f862b4db..2c73b236e25 100755 --- a/tools/profiling/qps/qps_diff.py +++ b/tools/profiling/qps/qps_diff.py @@ -33,7 +33,7 @@ import bm_speedup sys.path.append( os.path.join( os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils')) -import comment_on_pr +import check_on_pr def _args(): @@ -164,7 +164,7 @@ def main(args): else: text = '[qps] No significant performance differences' print('%s' % text) - comment_on_pr.comment_on_pr('```\n%s\n```' % text) + check_on_pr.check_on_pr('QPS', '```\n%s\n```' % text) if __name__ == '__main__': diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py new file mode 100644 index 00000000000..96418bf2d3a --- /dev/null +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -0,0 +1,98 @@ +# 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. + +from __future__ import print_function +import os +import json +import time +import datetime + +import requests +import jwt + +_GITHUB_API_PREFIX = 'https://api.github.com' +_GITHUB_REPO = 'lidizheng/grpc' +_GITHUB_APP_ID = 22288 +_INSTALLATION_ID = 516307 +_GITHUB_APP_KEY = open(os.environ['HOME'] + '/.ssh/google-grpc-checker.2018-12-13.private-key.pem', 'r').read() + +_ACCESS_TOKEN_CACHE = None + +def _jwt_token(): + return jwt.encode({ + 'iat': int(time.time()), + 'exp': int(time.time() + 60 * 10), # expire in 10 minutes + 'iss': _GITHUB_APP_ID, + }, _GITHUB_APP_KEY, algorithm='RS256') + +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', + } + ) + _ACCESS_TOKEN_CACHE = {'token': resp.json()['token'], 'exp': time.time()+60} + return _ACCESS_TOKEN_CACHE['token'] + +def _call(url, method='GET', json=None): + if not url.startswith('https://'): + url = _GITHUB_API_PREFIX + url + headers={ + 'Authorization': 'Bearer %s' % _access_token(), + 'Accept': 'application/vnd.github.antiope-preview+json', + } + return requests.request( + method=method, + url=url, + headers=headers, + json=json) + +def _latest_commit(): + resp = _call('/repos/%s/pulls/%s/commits' % (_GITHUB_REPO, os.environ['ghprbPullId'])) + return resp.json()[-1] + +def check_on_pr(name, summary, success=True): + """Create/Update a check on current pull request. + + The check runs are aggregated by their name, so newer check will update the + older check with the same name. + + Requires environment variable 'ghprbPullId' to indicate which pull request + should be updated. + + Args: + name: The name of the check. + summary: A str in Markdown to be used as the detail information of the check. + success: A bool indicates whether the check is succeed or not. + """ + if 'ghprbPullId' not in os.environ: + print('Missing ghprbPullId env var: not commenting') + return + commit = _latest_commit() + resp = _call('/repos/%s/check-runs' % _GITHUB_REPO, method='POST', json={ + 'name': name, + 'head_sha': commit['sha'], + 'status': 'completed', + 'completed_at': '%sZ' % datetime.datetime.utcnow().replace(microsecond=0).isoformat(), + 'conclusion': 'success' if success else 'failure', + 'output': { + 'title': name, + 'summary': summary, + } + }) + print('Result of Creating/Updating Check on PR:', json.dumps(resp.json(), indent=2)) From b4ccbdb124e11dd740cd042cfab88aa38e34398d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 13 Dec 2018 16:48:28 -0800 Subject: [PATCH 0551/2143] Remove some annotations in GRPCRequestHeader --- src/objective-c/GRPCClient/GRPCCall.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 4ef8cee36de..f36b814cec3 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -370,11 +370,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (nullable id)objectForKeyedSubscript:(nonnull id)key; -- (void)setObject:(nullable id)obj forKeyedSubscript:(nonnull id)key; +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)obj forKeyedSubscript:(id)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(nonnull id)key; +- (void)removeObjectForKey:(id)key; @end #pragma clang diagnostic push From 63e73e428fdfaf940074bb59753cd26ad24d3b49 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 13 Dec 2018 16:51:58 -0800 Subject: [PATCH 0552/2143] Metadata tutorial --- examples/cpp/metadata/Makefile | 96 +++ examples/cpp/metadata/README.md | 69 +++ examples/cpp/metadata/greeter_client | Bin 0 -> 267800 bytes examples/cpp/metadata/greeter_client.cc | 95 +++ examples/cpp/metadata/greeter_client.o | Bin 0 -> 101304 bytes examples/cpp/metadata/greeter_server | Bin 0 -> 278392 bytes examples/cpp/metadata/greeter_server.cc | 82 +++ examples/cpp/metadata/greeter_server.o | Bin 0 -> 112144 bytes examples/cpp/metadata/helloworld.grpc.pb.cc | 70 +++ examples/cpp/metadata/helloworld.grpc.pb.h | 197 ++++++ examples/cpp/metadata/helloworld.grpc.pb.o | Bin 0 -> 398496 bytes examples/cpp/metadata/helloworld.pb.cc | 638 ++++++++++++++++++++ examples/cpp/metadata/helloworld.pb.h | 419 +++++++++++++ examples/cpp/metadata/helloworld.pb.o | Bin 0 -> 111592 bytes 14 files changed, 1666 insertions(+) create mode 100644 examples/cpp/metadata/Makefile create mode 100644 examples/cpp/metadata/README.md create mode 100755 examples/cpp/metadata/greeter_client create mode 100644 examples/cpp/metadata/greeter_client.cc create mode 100644 examples/cpp/metadata/greeter_client.o create mode 100755 examples/cpp/metadata/greeter_server create mode 100644 examples/cpp/metadata/greeter_server.cc create mode 100644 examples/cpp/metadata/greeter_server.o create mode 100644 examples/cpp/metadata/helloworld.grpc.pb.cc create mode 100644 examples/cpp/metadata/helloworld.grpc.pb.h create mode 100644 examples/cpp/metadata/helloworld.grpc.pb.o create mode 100644 examples/cpp/metadata/helloworld.pb.cc create mode 100644 examples/cpp/metadata/helloworld.pb.h create mode 100644 examples/cpp/metadata/helloworld.pb.o diff --git a/examples/cpp/metadata/Makefile b/examples/cpp/metadata/Makefile new file mode 100644 index 00000000000..46be8bfaa3c --- /dev/null +++ b/examples/cpp/metadata/Makefile @@ -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. +# + HOST_SYSTEM = $(shell uname | cut -f 1 -d_) +SYSTEM ?= $(HOST_SYSTEM) +CXX = g++ +CPPFLAGS += `pkg-config --cflags protobuf grpc` +CXXFLAGS += -std=c++11 +ifeq ($(SYSTEM),Darwin) +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -lgrpc++_reflection\ + -ldl +else +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ + -ldl +endif +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + PROTOS_PATH = ../../protos + vpath %.proto $(PROTOS_PATH) + all: system-check greeter_client greeter_server + greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + .PRECIOUS: %.grpc.pb.cc +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + .PRECIOUS: %.pb.cc +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + clean: + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server + # The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif diff --git a/examples/cpp/metadata/README.md b/examples/cpp/metadata/README.md new file mode 100644 index 00000000000..7b33074ba1e --- /dev/null +++ b/examples/cpp/metadata/README.md @@ -0,0 +1,69 @@ +# Metadata Example + +## Overview + +This example shows you how to add custom headers on the client and server and +how to access them. + +Custom metadata must follow the "Custom-Metadata" format listed in +https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md, with the +exception of binary headers, which don't have to be base64 encoded. + +### Get the tutorial source code + The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: + ```sh +$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc +``` + Change your current directory to examples/cpp/metadata + ```sh +$ cd examples/cpp/metadata +``` + +### Generating gRPC code + To generate the client and server side interfaces: + ```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + ```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` +### Try it! +Build client and server: + +```sh +$ make +``` + +Run the server, which will listen on port 50051: + +```sh +$ ./greeter_server +``` + +Run the client (in a different terminal): + +```sh +$ ./greeter_client +``` + +If things go smoothly, you will see in the client terminal: + +"Client received initial metadata from server: initial metadata value" +"Client received trailing metadata from server: trailing metadata value" +"Client received message: Hello World" + + +And in the server terminal: + +"Header key: custom-bin , value: " +"Header key: custom-header , value: Custom Value" +"Header key: user-agent , value: grpc-c++/1.16.0-dev grpc-c/6.0.0-dev (linux; chttp2; gao)" + +Note that the value for custom-bin doesn't print nicely because it's a binary +value. You can indicate a binary value through appending "-bin" to the header key. + +We did not add the user-agent metadata as a custom header. This shows how +the gRPC framework adds some headers under the hood that may show up in the +metadata map. diff --git a/examples/cpp/metadata/greeter_client b/examples/cpp/metadata/greeter_client new file mode 100755 index 0000000000000000000000000000000000000000..929a51c3a5b426131d0573b2e5cd91da16f1ecf4 GIT binary patch literal 267800 zcmdqK3tXJV)jz(upcswd1;sn@igzF(5;c_=S2vnO3_+~vs+ZZB=Wu*{os zzdHSJf{|9w&b=k+Te7cunsUTux$;9)x$;94zIhfZu+KbA``9*q=jwd#^DN}?W1ht2 zr|A8rD*oR0yQ;D&1asb+yy8{KDYOit`XVk7F zU;V}7_vRe>(1lgcU%d6Q3gk85OFHB5O&!(olfvmOEk698zUsV|jMTAXeOr(B&Fh%w z+a;?r_0rC9W7DPu_8#XOGcJAfxUr)HXQnUooi$@+QOjPVd@VlT4QKW2>&rURzsu;9 zhbvZ$&KcX{E7)f=s>y1bcHCLrS!enVoN->x;TbKyu{Y=V&Pw%_kLzCH+daeQD;<4S zj_?9De2w@v<9ju}OYr>`zTd{zeDtu91-=j9`w+el4`E=vQW_+JE06e$g8`0@!@cb>l&*S@ohV|;_OZxe;e!hz5 zYxw>S-{0f=I==k8sUE(!@O&HJeth4>_mB9#kM9TgI{1Ew?^b+2!gtzp_jad#5LmJN zgi8;)@VCzt)~(s{)M4LP{b~0hi>DoW>4C@o@R!vO9sBvRD}S7p``EyBbANWpaZ9h+ z^W~>dv|Jp!Gk#HvG_iTb{Zvbynoy@`BS|c=OY@t2eAX^v!*8A3M|k z>ek_BH*Sb5?^rW&w?}G!pa+V}o@PVD~0iiI5) zXJ@rs^oO!odD@-IDT@|VXx{>#7%Cm!

LvYO3=Q>NReJDEDZ5Vo zc%SE<+UM!TQeTI>GtOqd?)9zTkkyR z*6!Ue`t3jVedN*)?g`)W;DWn)+xMGs&TDU8KY76|M_-dYexL55XZJrlIBxYji$@3F z`D@z^l~eYA`hu%F_I~8>_s@Iro4?uAeAu~{y_>ai_U#ovxUK)>yS6;_!(V0p^jFXP z^GDZQaYW-eZ+-aqD`%BWKK+14F1=*;+{f~7p1PtveB%jMec9Ogz|))F{MJ8~uYdc( z@BeLb_=d_$#x(A~{@s@Kvmd@7^qvySN&=+ezKfm+2 zr_kj|KQ(*#eA;Bk;aqoYV)z3vKqxZe^9+noB0Bdcq5lXBQX>4xV-v$qPr^^m$%*lo z?wJ^V7wmANdItea1V8!E#PE-HPYmDl#KiE56B5I(J3cYIDTy4;pXl=)K0^9F-&0BG zPXd0Tb_J5a4^0ApAPJu*?30-O)+BPyL(q|kpN?eoll05r9*OCcCDFqhlIY2oN${Ua zf`4=p`ApAA%+InU@Gp|+^KO7A8eg9$q4RzceQQdhw;8)7=5smd?3X~VK8La;>aUu- z#PCOw^l#II#Q6K>CWfDuM9z0-C&nL#pePZa%}Mm+)Fk>=m4u(EN#y?<1XYRZy*>&2 zl_dRMdt72VCnv$bKFN3=m!#ewCef2KlE6!n$YDzoIV=J^k^W3eBIo(z6Sw!!Bzkpl z5_^7o5{nP=7aw%e7&EiAk0MaOi5xVMh;9yexdZpV}nyd^|}%{`P40_-{q$X4I%x(R)vq^^0^ob zI+TO6x8kQj!>6Euq<>ej!tc}Y4`62qzxJ03fbdK{FN%E9eVvU8pZdqo?pkgOHT^GKx0mlAU&|4?Uld!u{#_J)|2_&H(DVxqQ}_!tKFp?kIuI|h-q(gz z`aunE1!IKIepdlF9{4#|w>R*yO24Y>eKCn%T?zdp|D9S7jXqD*^7+AE6depJ`P6Cp z4}7T7S84d2SXU!IUj2Dc>%Uij>M^dUPb~~C>A#`- z@#N78z7qXH{sUV6Mz5X$KZN&aJ;_q&zHy*Ky-nBsYxMS2>G%D7nR@-t$l*A26Y)DW zKQIgO`7P`%`8n_%mA*;C+eMz~zO3&k{Hccd@D}I~;q{(zy=;F)r~ig{ezu6eNb^q|CNe9)K5NNX!{WG@VQyru~H3(xscEP=wFVb za;+zZ+b@vIdT-R@(a^tC%c0jp|0CUB-=3=|e4y!1M7v1GJB}_g{jT}HUE|*?^r4>` zj&N5#*J8ku&e9DkZS-nbx2wg&&()&;2aVAG^Dy42Z~a=%rd@Amss8Qq(3ygcV7(jf zRrMPE{~7w7@Z*B2y~|X#??UiNJt@@or&Ggc!7dU1^|cD{vKI6OdR#2g`i9{npH|I( z`cV*+_1P;+(K%_XB4F0V58qwEo8DK*=vMh0qV0os99_1L;&Y+LF8%#L1z+PC*Kh5r z=s)|gqT8$K9}9-rF7No7q2Z@$JJzJ}i}iSE(c{Immu{VOyn243*5?9`-MAL?h(Gq{ zitvWf>Y0TOB|K|Dr`5wZW&+yYa*)B;xZE9fwR@uLv9de}Z~xA3BaydYG!~odtrV)2HdzYx#de z`@2EUIJ#@R!uRUWh1zapzpDrvKL38a!q2%vwRa!&@D)QpS?|0O1weK3c`QryZ@2D8 zB<1rf$bs_g-Cyw^(C|NNKjQQFk#i;}I)xf;{874=zgHiYAvmXeR%`hn+>*~$bOiOS z+v67+QxtxowzpXt|0|3~wrin|uZ$e_)%LdEBhNb^H?}L=GcG0y|NHr}wEZ#k57qI; z?ft4k6OUDEJvsCf1vhhz-|Kq2J@xvqZ&lw=*HkyJc|Lcma!>JZfpuR%$+s8rmi+Pw_;um^2!!0s;ez)Y^rEz zDl1c{i4iZJJ$XT0-GZ86fnlJax)$VWD{68lO=}3&RunfiRM##jYHG-xG+o%3Q46}@ zz+W`GIHxRMko-mG%`R>_rL3%S$&%dM+`M@ejn$Q?pG9X>7B}VQRxYe)C~In{sBUVU zQRy$Pz(0P!uk7O4=Xn{(&7Bo&Y^+!ioLSuz%*#0^*fgu+nt4H~r>IW2^DkyeZ^0Pn zr%Y>XtX@!iRZaG#UvqwQQ;bd`wsI%whMZkd ziQc&;Z^{gMY3EfIoxOPHx=@tNt1717@^a3qZmg_msIptx zm{`3=h$465^qOEr!`T%zHS;PeuS{Gjp>R)`6P(`=Y+RVQh^xm_MCWHLs;|k-pH@>- zR|$bktASz%tNe>7*AZh!jmF$l&aaiCx)AghA}ns2(sWIIu&laveqG|yMk=|v7<6-i zJG)|0@XUM}(_h1CZZ353?CRR;#)as&V*eZ&Hw zjyrl+ZeBy2&^&7PN1C@d?kDELgUT=uQj4coz%^GDS6>@!oLe`op`qd$f6>B(Ml#k_ z#q|}H!IH*c)y%ru1xjSaBNR0zkpH-PB^v(;C6rqLS3I|_siNl0YnpH~ABe z{Sm`CcXCy5enoRl6C8mKY&7%iHzyCX?q;UlsT9INDpr-QiJezd_-=WkBKo0c7A!ncjBQws`YgjfoR*QsEjk$~{HG*{_X5W1X7In4x(3bOu|L zHG=+JCJ`&qb$pGb{LdJMv+};id*n`3aRvTuq_3&2MxgvP(v3|bY8n}ZY#ZI9k9iYi z=&Kk;&B~M&@K^6#aK6(WmN!Y}s}sxW5u#xt6$?EQ8;dwglsnl3GmLW?xFmCzuCgZ* zlgZ4>oxU(wc_jnpX|+|hvP(Q=PiMESN3nQ6ufP-UgD}E9&NphC>-~!`8!B47ZDQW( zJGhLSzR!k}L?8tn_z#$m^J|M2HaAsa-Z-Zja}RKP-eSM97YX8ecNqSM!XYbwOVp2U z^|_PH^b^u&cXEWtMBBuZiG3^`$w-TnH`y92j8NzoOlY!`!$krbZwwWu+j%)f6%CC+ zT3fM!9tWFXqMt}4Y|)4%fxJm3a%c!vHjBwAt6}6(_BEPlO#@A6=WRp63Ul-6|K?UK zaHrT;Bw{w!f1D~cHPl@bTa`&Nll(Wh{waxllik6I{6At+toAKvsINT!cvk;9}ge))Lq-(K2BQsl99mT+$63aIYCp<6Dz+oO6ii5RP#Z47W&5dg5 zhcYLFg{zcoX_yECdi541Qhh~r!wg2a_#f%qoU-B|*8y@Hn`U5jhbT2zP?{mx6$0|-=9kUl zOe~0%`ruW~6*V)kDntw-`AOvzQ)?M!U05rsYmk!X&y_$rUh)5n`XF}_mIJv67n~Dp z#B>u2-;0Z6v~FvFO-!i$W<0~>#+foR+90LLWySSnm37TnrK&2!_Cs*S%-K`04^rDK zdlGqNGwUj^EUT}psjj@npXc|Zb7rC65Kut{WCEOI$SQ4D9X@$M*@Bwt`v3CrsizJ9 zwVE-x@~X0?3Oy}1{=#c2?IE0-C{qtXZO7(q9grzcS@;QvNXlCUwk6A|4ktg8xC)K=AC$(5#8 zRN0lTJtEy^DeKOC7zwo{(m~`ng^s_vQf48O@)%~71(#sSy?PM>gNhnh4CA27uA+x7 zlQ5^Qfoo|-hdgzhU!TZ>c>5$*T!@O|xN<%pD~$=-qQ>gTnsm&^(8U|`xdP$-6XP2$ zPY0JYnMGf(dEGWA9wG?k#2Ef(oZY1P)wNarIXYC-j3x@B5^9F+l;Z-iyh#htkqtro zBY`ITsU`6d!nNt>Xln!xgyw37gl^C!Vah9AGp3XD)Cj_MWMP}4I}hy@|^lg`bBIdtAWFq!JVm9!NWBLXF%eJB@l8<#uE_*T^~$K zU8N2^W}G{R%Xx6Vi*2uo4gFef8P~)@k0OvLE&%3P^(q1x5j!Oqz}u99cKIXd7|AkH zOE3nEVKZhSaqno$m}nxP9mqtrEHZszMQts1(syoRj_D72sS#%!5Pe856_-JU6irl6 zg<*=VibjbfN3=AVvMCOYVrWw_LIJmB{JqHkMe$+G7@`JPWhHDx(JAt?uD(bP4J2)x7%siE!G(>6g%PYh&gE(c>VQ|r z%$!s9ih0$Ga}laQ=__yu$340vN+9P4b*NO_ls6@|M50zwFn55_nO9N6gNpNtz?!>u zgNUXoC@Tb5Bb`$$)@8>PokyI`($GzSJkKk zIXg}VU3k9qpzt*h2M=q@aKf&Vdo0i?NDn7)>#i=V3Dz!XT38n3F*3Dbigi51q&11g z0wy=fhQVa0npB0dZbduMesskw%ye*ggXf=SfF*d&xeUt5_58Yqt8t#u4cNKTq8gNM z8Z-~5ip^?17^$g|8Q)ImA?Fct)>R1Xcn_c_V}pn%f&m~Yh!8_UNuSJu#kxveNBmIJ z1$IJ;N{bd5B}SEykHj97h&n~RGuoLuv8))qQ;$R2ms))SAp|Vuw3f!>5g-gU&-^b(#1Pt_VVQ*rYf!+fcAMi z&dKz=f0JCGM#_lnjINlu{!R?N$;v8;Flw)6WNw?R#%u6Oz#?U`5bBB5X~3!)%$XWq zu+grr@0?~r&u5i22Ai~b6qSf`v(>eg4MDE5@#JwL_p3O;8of5Nbqf$WSXOo?wA3|7 zML5?|R&`Bn#UjwGtZ3w>ql7PD#S^_Gve=b#5w_%)DQmwosygXkF^f|;)DS>5;mFk@ znRM;Ag3IIorK*H*?ipzYV2&DKd-UvJ;NKB@a{N4vD=(1R^lxYJtr)w zy&9{7W!x=V6lC;Ssiu+ebG4O=>d~Qy1G!B$zoNRv2PlSs)@_Jt2{x7&1s5qq1{#=+ z%kC3UNK3yAvk2#SePuy*4>INy=>x1Ilgmd&Ny>=S>8!`C*`Z( zrKNyRIw?2TH@&oU+L<%Ta!;BVpEJo$+P_cA%axaa^s8L*dyL#Nr``?XjdNq=_P||y zqj4J@{~M#T%#&rAw=4b~4csyKmmj?DrhhS4!AM(`BbLH6rC45-AQk>HX>)&}qM>fV z+f{Ig#}9KzSEW;h@-8~fdPeQQe~J?C;!FHr@|<}5ZQ*SzFP_TCRI;*!d-DL0R(y_k z=kZ#rFALwIqp!i6qp7|&yl=`6YuFdRO@8x%)p%2S7hi{)pW^!gUfN_nKNUkigt&M0 z-LA{L{NR-kdy4OuI$b6CV|{CNy6M=P@e1J>-*0sKD#;)1dl6}V%zcvPJ;VO%6ueX4 zGil(X?o#kI9{5R{6}-y>?=7V~aCe^v-l^$#d*S+hz8(*}Tf_T2@S)7Zg?_&WK6*D* zuj7Hw)bK$Me9dHqKjeXb_Y?*9?WO85a=1>vpPKH0uRcKGWqRO)n}khYmIr=dw}NMT z;Ds7q;DNVj`h{M2zTz|Bfp5_8A`ko~{k~(l2kz7Fvo7?&`!$_<4}6@K+Y%3a;S;J| zZ60`+=D))O-z8P?zuE&Y((q0X{Hw>uHf|^xVdj;i3e`pk8kn7&AlmY9=N%Oqr(F?@6)gLz|DOjogTP(55CI-H}?&! z^T5qL4c#8NxnHN(3)kbc&jUC2k@S1u<~{F058T|hG30@p`#gO5eP*MF<~`|D58T{; zlkS0=dnqzKaPuB{wg+zR@5%AN&HK{@9=LhGKPMyJJ`d^l_zOJn*KSdEpwI(9_*Mlk z^1#2;_XL!B;QKzL@XI}LbKlQG58T}6QSX62sq0@Z)Y*aK{6$*XZ>I7%haG${TziJxVf*W$OG@t_idDW;GG&??}3|pR@yvpUyI_u z!vi<+?DW9vHU1h8-1xzD9(aew@Aklr-u8On-5S5o12_8bc;LR}ivJ-G+{iywj~kS=2`%VHLc(2AU^}zd0zj)x?n*SCL-0hu~9+}sPb&I9k%_mlN_;HH23JaE&$ zjt6e~cgO=b_g$sx{xtG8`kCp08~x1oz>R(udf;7J4n-cgxj(7g12^}jE%dh zo~7l}=7F1g-Bx?xh5DYPH6FORCv2SuZthj;@xc2vojwoT-1Fpk;N~8|ArIW#|CFlz zgOPuWz85Op0}tqQmIrR`8_V&)&Hamo9=N#&vB(4O*Y}n=hsVz^OnS%zpT0~vvP{o? zm(OT;jt73^588bwA}6z71bv;UDi}`+O}Hz76lQ@DH=_yDWSg z-f!WTTKMZMd>h_p!H)rcx-R1+fg68Ix!L%c+WvUq*-79FlfaD~_0lQOB-Cg5Qw@-kAj6l?2|M1m2qj-k$_Mm;`S8fVW-74|w6m4|w6m-gx0dR==NX=|j3T z9&LEPj)zIdhPUXr%L_N_%3gR^5`43M>BaY1`eWBykOW?o1YT;%*`{OSdT+f&mKc#Q>jEchY|K4`(~EclQG zzsiDVTlWHAZo$p{w%lXYSD{L7zg`z5{6-7k+}};O9aorpr3u$dgi^}fk4g9k0#W~% zdx{Ca&w`tKy$Nr(;4PYe!u67qoA`J3%-j1;#p|HS-1HFEVzkHnO9`Nv2p8uN-g*}7wYqsTkt(B_(BVg zt6SYqy#?RXh2n3yS@1Lq-eSScm}YjH1>eiU@37#wg4g}5w&3Q@S7vrvaQp9&tg+y@ za@hTJS#Vq>>weZ*aB~MRGrKJ~u26M9Jr?{>7wYr%TJS6j-eR12PM!P71Hu@*ejf*)tWvn;r|Q_nKiz__w%}7Oc&7#bh6P_^!OyVZT^791g0HjS(=2$m1wYe* z_gL`h7QEMj`z?5%1wY$@_gnCDEVyIA0~UPHg3qwvLl*oz3+~hNV%pA`7ChC0&$8g@ z7JRk^&$Qs@TktFkUSz?uE%*f%Jja61vET(3yx4*lTJX6RJYc~~EO?OxztDo0TJVc3 zc)11trUhSU!7sMp^%ne63%|I%A-G@;0vtmZW=w@8)$tx z^(o(Q{*wR=AN4f;O*^a*znB)zqW#189JPUIh8)peN&kxJ(M)$s`WH+ybd7dN`ln1Y zl(>UjcB`nM^ZOi1thRRHhjs zM0+Kj$27y~Xt$(~W11m)v`f;5GtJN;+9~M+nP$ik?U3}|Ofyu7wn%y$(+m-!^^zXV zG(-Dnxun0i2Wf`%(IQEI$}~fVXrZJ(WSUD#(Hu#?%QQoXXqKd3XPTiyG+oj!G0l)6 z>XY=dOmhh+I`~hv|4F8^nC_SK2BsM@M0+LuE2inxqurAJ1=9=>qFs{yDboxMqMefd z5z`C_q8*aHnQ4Xs(H2SH$n-Hx*Gu|(rn8wYm-MwvAIo%+q#KxK2oNol^c74W&vcHY z=P`W((^-35l?>yBng`gNx1vZLveeu-(i>ZniB&oWIH9Uc6K z^gq*uO!rHA1JiWL(OyaaifOvyXt$()!8BcPv`f-IW%?|pJ0<-irs;~K9g@D8X}aKO zi==O4nyxomFX`)<4lrFV>1&yu!E}+N8<;+q=|V|g!8BcNG)L0&n5L_ZW=Z;Drs-m% z>5`tqG+k@dC+TyUrb~?uej)wOG+k-5U(%;CO&1#Nm2@7{be+*|Ngu~FU1qdP(uXrm zR~hY;^npy%MMgU$y*JZzjnNiKk7JrHFvW^I6(qkUBsUK(HhbPB{S2z?7jt=>4VxVETUn z9Gd>|mksyNKPm076+-{Ar)c$KX_SBGE+B^UU&o^)aO_toAK3iWm_TSSu-Q2yFltNS z#jlz&LGUU~a1RnpMz3Y+U%`g2`Q$+B)Q>yytAzaQ5on)!9OygaA#o>wf3~DN2fR^a zr-h9Dc33ftH1y=r{DK!v!+c_M55!Ljujx^X9 zXEy)_4ww=84T=z<83ksB9Ol0S9^ivBFPV1fw96F#HWxMVT#Qv*JjcHAa2xWF z^goA$hE!95;W2PL#m#z<*^kTtC?)}daRx8~A(4I)<<)-Kkm_F4Fb#c;*7W`it$7gU zTDQiijPok;H=?(|&D8G@>C?Xr4|k~I&in9`8$VE)=YmzI`N zshl7w6{_kwsG`7-r&6}iQU~fH>M$Pa0(qQ%E94=dba}LPr*5R+*xq^U5azXZXEJ?y zj&K{rU~p!^0~%5fpl=3_qg)g+R5RlI1uo7Y{4bP3%W0+(c;+P*U!@pBYcPg7fsbdz zxr+GVjLutxH-O078n6-LZHua(K;f-ZRktP(E<)Vt?<8^{RN_E+`;qRa661-!^7rD2 zudlU#RO`^Fv|Bk~FVi?Zc=iCN8&CAPe;uCq#&FZtcEb>;QNEW#jyOF09|%1;km~%B zA`3l<4Ad+`|1ra8xHR4QU&I}O&=!u&;Nkd5M$z6~*%x?jf(p3Q=O7o&L8(sCua_d5BJH1nW65#$5!Klh|%Q z8NEff>~^zs%aH08JR%O=E9x9lQja))V+V@)i#X3i0MKjELYIop`zf_n|GpWGSLz?H ztK^J-B}&WfkI6U-HGd|g!bO?w{?91n-#POT*O|JVN*SUl2SR z0h^Xi7Ch3)Bg+u}6#zlw%8fRExJu$KZshhY=?W(IkaifUe*eWqX&PzBY`3 z79h1i@%khFHQV!WZKQ$S{GN$!T3`-a83BXTj@G5nO@O- z-DMH~D;R?1-FHNeQo|mZjbB9LWfK7`jEH)K4#`Yhp;kDTgB2gcL_9)<5r^(Azq+EbUI+x~3%& zfA28D#SxgB`*#g-ps~CvJF2&}yCvlBBv6@F2zx4~9?O@$@fAq0Wt|CHb|+efFAAz5 z+YMD1nA~1MgVC=*?|(8p9P+QhuxfQifkfI5yW9M0Q4U{>Qib#i%AxD-Yxmz5@^4LB z>+fnE9JQi5ZRO9<>~{ZFaC0YICyma^TNUW^acL{tlu*$75$7PNhO!?mn&?uL&>c-n zmA3Lv7W(tY5W_YjQQDz2 zZ#Oa|+K0ii#I{=jjFxp6EnTq@ie$vuh>^_aVsw{lNGnmJXwU>Zl@kSqkSDK!H zEzMF&6XABKWKEm@5syf(6sHhzju^B=x_@}qFp2bcG@nC*y#7p# zFoYa0yoV{$7-oTTHF$gsaAf#95fo4PK*5)j_t2Ao{z-SsCTRPLKVbGJwjJ@6(!35* zxmX4>gWIK!ubC6J)nEWw(xHF-2%-K&0NG98PJob@Z{W}wp{H${SAyouP(Ml5lYHyb z<(OgVNP;a~zO_Rbe_|nnozSCPWmL^>Fu*q}dN@K6}tvU@=V-Bx}DRQoB^7B4kyy46PC{?+K0*C=t|>K{9m5 z6C8(N4QUaRC>(?2ZnAKL2%JIk4H%Q;SnQ-o_6J#vbab$#SVM_HhRArX836M}`ObHn zfq?8=Sa%GBU_MltxZv112)#8y^_DG)4UmrRuub^c5m^2-J4iasJE;eYL(s;-rU~*3 zyu1NV3$++jX<llxJ6>gGncSP}rvVBj?WP^|PFBTK&;R~m~6;`_AzB&6nDTu7l> zn);JzoFz5$6Rp`3Jpll8%|7U>n-pf%X6S|>DTwnwB7;>T){SL>ie#lq*2*Ou9PO*rgF&&>{8)4wnrsXz zpYdkV(#{p#%}1gs{lMwLvj@*^Jn@Z9^Ah-yDqUtBp6gJi3(qb**Wih7tgLNrsr^8X zIBjAoRX`+wumT_-%u34+z@m9lZFKII5u9?V%!xBD!$Vuqq%-{EVS!;guWyy<8fr21PX5(F+UNc|BD&^GvXgi_y_-{dD zJv00HL(voy5! zJt%y5eAyr3X83(*icRo8GQWxiDKgH;0nZiGcv~pjMn~wg1l(d)b5lq@)c=p(I^mlJ-ltiY$^87M&yA9?m zLHKZ`)1or$sar2<>V-ljjYI5M!kyut4(Exf+ZnJ`n7S3vWW{FqyZ7(t4F6?u3K3@- zO1i$uo#8*Kb06mT;1bh1itpOTrtYBJ#v!~fm6YTvvX7~;13EQ*K`KHRS+Y|3| zjJjBg=T#Gl2QpN9GF5x_VtdeYyR#wI4F6RLwj<8;w*WVhi95spwa)z?Fy)=$55n&L z>ofdGqd_^G@zE>RZ1+3RAA5#>(QAtLJE>PtqSy@oO^i%?HvXp4ybiYXX&KDPX88M{ zz1ug#4}qqhFy2J+|N0Dnx@z;^U$)wO3tHlt;g`Rvn!SeRN1APB_#c3I&kX;MVx#^~ zXZUxCz!@ap#n=fP$7cACK!HZi@JshmE!^@4OZnnv__ysr4497uGyGkUmuQCH2kGbz zdlNsC&Z#gV83c>}znsGyHqRR9Z9qUn+oNR-DKw<2fxzvfku8B_lZH zMwzc?wBupcN%diofXt%Bk)rLbOZ$Ayhit+m+~+K&$l#r^C!8iWvM&mg3I7E=YN%vm-M;gc{~jTw=YH>Vo5HYQk2)yd710jp&gKpoUn6fFLzp;Gj(C{$MN9ALgCl}LvXLptfXY8>IjSA-T@ zRq5G2HV{+?MZXR(2(%KCM`iI=sWJwNv4bP*nOnYIy3bj<+*0eu{7IJ1OZ=@DMC%z2NrB4&J zZcRXg+a!a{EQ(^Y6k%2LQVut%$5;@T1A(GIjO%UC=0dZkE9Q$kFa!H(%95vgCh(H5 zs!n(qDYTol7I#I+c-wZx`96wsicqMR(+Sd}gdbm>D4iXHw1VPN-w#EM)u&*}*RNw%lBZTH};M=|f zZE6DochK5a*5TilyZNtna+mPzPe{j*tIElIyV*$Ft5zAiS-@#|f`xqC*ihN+3R$V> z3*eJ(?+7A@qaJ6 z7JfXS*b`CeHrft;jVAm7LqWTPevXRePg6y0e<=q~i=gW0spihdkc+9^(oUajxpuAR z#Td}gzihEI^l#`cGa-Yo&)+jbWy1cEj5|)qa2`^0b0#qLgiJJNCNNZ&za*W^6$B`Z z9Dy5ro{izUK<2$*y;HQ>EEokV*jbYWTPZ!zyb~$L2gGTj3{V)a?Bu1Pg z+4UH`Ay}F)HY?=XDf_>K+uPj_rzLy>3g@}m8RM--Y&ac` zYqke)?%C7>UjnZhYKGiP`r$ix=IJ#w;1)Cn?iHobGjPOkSs)LMLEedoM~q;lym)pH zfPp84FXbc`5Pw98glPB0DGh3c8~9(l{+KjSqW(FSh&YJT;0WXV0r*G8C!g!CMr%g7 z(o!A~^-zEOLlOUHlsKIJMut5ob~1`dGyFsCCM1HFqxSWMnqNUdXc_YSuV8s3;vZDS z2Tk$8zp?mMbuwZol%Dp$U`zl)L{k{VgqgfUjHc`(QkJ|8wqx<-OGH3E97fe~1ot0M zb;LOu>Jy`B31v&5JtcaTvUi)GjUgGYjd6{SiD*1JIhI+mzK)TF%Hg0tYZrZ8sA`Wt z@i|g+#$yubWzvli7^8?mISLcb7?u)GsJT~*2!5G$Qm610?VyGv-;5Oo|FJ90mzt^x z02hK203y9&n||jMLffpi{(I_e_14>_09L(kU^tDaS1Z(xw3Um+(zG;GG2nL1{!(GY znevs}_s$el=^f{~@JY0V;f%7Xm?iV}e>h`WEZ0=ZH(#t)q`Ni>x(QXL)feXOfC`Qr znKWT3-B32$mIXq+8Z(@-e-q7DoPKc<<#YCiihAfNje>4OoX-$pdUDB!-e2b1Njf)X zWyNTOQ?_8r7avio`W_!i(W>u`k-1iV9gxw8`r_IoQflpn^de5@X9hbK71Ka*&$;>U zG-KjY+kpnJI3oU4^$Mj6w?XOn7^P_*N|1>)Bjcnej#sA%P6}P_wX)>>W<(T;v|%Ir zj0h>8x@FnAY#LIyaSrlc=Ff#78A566c8Vl7!(qcfzpf9BoIxNZ()x6^b*_2@tDx)`aVhNbH7gNc=ZvIfMuRoWK>xVf>dugGw^--Y%w=t$ffhpR|NdXLf$pt^M+w9Yl3X0zKequ6;V(>M&Q&^u;kq4%yV zTzfNOZ-tEWFBDaKVXBxS6puKUa}5yhRC$&Xn|L+{yhNN5EnPFoJDIIR^jy7#;s8#B z`Xl@7JkBbbM?V(lL)_W9$CurOqXLQLvj#{1R8DN9sm_2R__br zW6mw;VW7G)oN|){{OBYd4S;=zF7pt1NeLGA(F$1DaQ^d`E7v?3P1FbPT_z2!Bj2VN zwn6IxMeBM^>qER66i-V#drM@Zer7zgA|*w&ULm%V3McO$AYc*h(e@_*OIyq2P+QSh zqi!zsZPIJ}H`4R+b=3CorP-v5Y3=_?TeFd;=kz)>W}s+h8|2=CXA7p1OHfImT|W}X z8&rN2i8$?otCe3M6{6cv0u^MsV+u3tWvM0X*^?rihl*%G{Slp-}5 znh*LN$i&y*359%LD^V`8T9)4Fnt;9%V~Z#DBdxeoW2HPge}WGO0R{6hbct4a6%Al=YOjTcQ?S))0A^C* zS`vh-VTP;`=f~1t2tHFT66$DE*#8gaJj6~9F~@Ims4wjq-#}7#Kof?yo(MFJF9Q07^@NM7q;jxuBgFgT-JG;l4gCSrj|m{yve&q5RyyqCNCO@@J7$c2GcgDhx7_H z)x*jeytn~;Vw`Mo9ylBvo~lAf zu+yE%I`_Ipmy=UH5$E^hK`M_p{z)tdON4a?j3ymYyZjf}QVN7-_0Ckrx*zd4c!2rR zG)ulgIuRk;-rR#lrC#vXHzV}Pj8IP?^rFPCc;y``PD~{%`_y15Y64<&H>~wK)YOHV z)&Oq}%WOKG)VciDtF6Ifgz!u=LM_dU`mOo-%~Zutn87u+?b<;U%fA*sIHL2Ga|M|Z zsu8CgqJV{m>DGYrW3su9s$rdmF@^Tio&Aa$EMbs>)WzVXzjU1(m1&wtjK6I{d;p3Yj|sB=yT^nVNxyQ zub7PfI!%wpsUR>j^hdf?_ciuPA_zb?@o6E{$JXADm<|%pk@ezfm%DQkF)t89#swmV zA@Rv-(s2Vy8yn&^&h}jYR~wAEqLwTa8RHE;==B=tbtm+CH6(>~ z8gaTPjj(K3tlNmQ9|A040IpxqKVv-+6pf#uy12LZ4@ahvgVeGd7lytERPX?F)1n9b6=U~XeR z0b^tkl@6K^dc>R>9wCI4Qh9@FNQGM;#pptSLnuC!wzlv{Pd}L%keVP7DG(`CaUp+m z$1qfsPI#m+6LO@ zsXb$%n<&sc6q*9yC*b}@*JiAB<)!>k5t_F~?M*CSx`xCT^Np~s_1{D>DB>#*S=$pA zp(pL_iI0&WMmvS}lJ|s^@$<+KQhkpIDT1@n=w1!p4Di6AF(;l%ZfCMu<)}YlLt@^- z^bj|q^>keInpvS!{KJ$hC>>-&Uw)Vk(bAB*X#!nY$HgJ`I2fa1MvjOHiIHOY<#l$zPC#2C`KerH8>J^HCUVI{H}|2NduO&E zwc!$J_`~u*!^?%`Oc3p*KK&6IjDuGuc_bBD)C;!_MI{!A48M%rK1jvf85GlM@~xNO z;&cr90jDOWV*C`vK%QZspXN%YgU~=?L1wN-CtR%rG7R6bf%c4#E|$i8AP+Q#+nGX( z^50FA68oLne%8bc)nZ?Fr zKO3V49E8I`->*ysQXF)#*uYQ{*jC#YPYdu7E?#9o195EsfYO5>l7&SvjLo6M2 zDXNlIj*_n_X_h#+7$XbPGE`xorD82h@9eK%8tZ63K$pbnK4@hxN9I|y* zw$6G8StIbsxw&!EWt_F^f303f2efg)gTV z(#)#>Ch`B}GFaIE0a0_wzo0~%Mi$dsLHn~73FlE76GtoS!@o0Y3y6P!O2N6BNkyDj z*-%Y4gx}G-SW(39pfRd7Vx#>|T5Etgvd9;JvEag5Z(tNnO<;5XX!RHq7}Z0CRfE$H z>3j`pARR9;emzZP)$g!m48L9b*Pz1o9XVIUZ{~RKKXqVk5%P}jD zr|FcJ4zOC+1xbE=Q(*D4wqHK=Iom6r?6kG?dS5T{9jU%B+X!ge{n*-#*-y!z0__|W zP_0j)YtFUUbuz*^3BLzs;`pUADtga9MNq)R{WKh^IPA+gsOWYI3#nmxs*G6X;M#_W zGXRj$|Kjw^d`KTDRt>1TYqNz{d$v654mAZN7Xw2aJY;omWmOdo#eeVEt~(RbPM%m5-zAc zNV8+EvEi2$`AlrSaZ z6-hb;updN*mS9m;)}Okxo?Xq8grb3{1WPJM4Hbbw4e3_JQQY%M6fBGWdJZf zyb1$kd3GCQkHn27iS4&(Lvt=-_P@>+1N3Kk&;S+DPRXomM!E_6NfEv8-hmPq|3j!} z{{=!NhdRouf@d;O9&j;MV_P0%k{!|UnHilcZ`esuijgHbUF`%^s|1rss;Kh{)agzg zM5u1r7ocY&+h;r;%8o@F-8RKWgpsieai#8Qvn%xrAb}m$8h8tiDy$*$jG+89DiiDH z*eGUi8O|&}r$?}n*E@H+-ImQRc@gQ@46hu$hB4QSkqDd4aVNH2?9^$0mXa8-Sb#9` z`0pGa3F;BL@6Rk0HMRq20jSCP#+^gRmd-*QMNm3e4zU<($jSeFqSPRpif4u*^wX~;%}EP0S>spcV@&zO=pmXg?3&*+5KZzB$|2!A|R zEW#V|@K}VRq!vNzzh})NrjdiHcLxLE4v9TzE$kiIoDnucO+c=cw!58!UQ7*qt&Qav z5rKdPM0OOts^}W(lx|8gj`Z4AjO!si4H^$>W<4f;ya`;bEh`+g-jBg2@h7z}FtTZw zfrru!hv5#jWF|_Ks-RrMC8y&{ByvreEf0h&nJ{`{p)YgbDZ8xxFd73bDb4|vZfH;s zVzC0G3wdnHJ;RmABC9p0)jiwK}ddU zw`|6UAD1v2_eFrU=sn~m?B7J8w*16w!?@IhI@Hs!lEd{&l?WHX!JAq=c!dQ6IKb@I z&!x`rq|wRIEwZiMxzM~#f$-9f*c`RtAgZO%Yp>4=gu_`BS{SF8!Yd0!j1gzfpV$e8 zA*k0Xl_TA7j4U|2xcAY>YcV`~ySt?%QaJ7oi%ur6B($u8uwvBl<{B=>x6%W<;>!2c zKcp;qulcNQaT_lI9K z;rfE%`kdi<3_`u$ZSg>!jz`S3Tv54JQ!z1DSZUad%-En-!qR(Ju98KZU;h}^>G zg%!c!L%dHa(F}GrVy4b+E#5;cpvKUs#a5V&_Z4vb%EO<3WL6#^~gDmk_BebL5G;aK>YKE{DQsY$iern$C9f-U&DMHQa|YmU~KS?3)u| z>$YO2m%$svfwzY2wxS+)4mt!g4fEhGFY$6QBUN2{Xs`|M2!}K7$&F)v3uaL**d=Sa z9E&PvPDdV2qMaCMpStIn#7o !5#mb9)^`LbvddzX1=<=`(g?!SbwEa-r4*GN6ozk<#tA z9SgyF4_NO856_(;vf3gKSbntv>eCGp9;mOhdQ*R*aDSw6Te}ODMeGT*H^4Z~8l1^4 zXfNqje?o)&a~f0P;BccHPHgkPjrMc{40Tj1huW-$OWqEsqh-j&_MR+8G*QD(P?a9# zR*IT@>+={chBMCizG(OoJgDIyJH_8E#s2yYY1g0S;cDbWRV-B%tCC`dIkRVHtT_(* zZ2-E@ws6b~XMA&_^lqH(Q#ofO$T4+`YLeo43?6+xC~SHY6!gtINPhc| zdQGHxI)=l=Q>AN)0u7$BmrwcpEhh>A8WLB}>(%}6d z2>0Yf7VHWJMe`uXyv^6%;7g5Yy-P5}aVW;3kVll#Zla0PfE+jJRPqTc6C4lUJ=X`nI@r|v@Es? z>iDx1g{g*u8-n|B+$7+J;8y%C?XsnX$xo^@x3wG6VyuUmPYjDkYuK7XC5puq#q(1{ z6cKs2qPRqf;+gM?C=P@~#JaL@Tzy{gmpD?RV*+PPAS*Y!_nj1_ipY$eHP%Z-+k=RW ziiAP6W3XF4$A)|3yNO8jn)bFCInDpsQa0`riBVHNl!x261*&md+of?qv~jqX7qe8- zfk1tW+%pdPT!KEV&(Y(0E5vBc5C?8gVUMCS3qWFu|Gi}hpt+Pr)J!~h=e zy?&Y!T%!`)y?9V7#`wqOx*uI2ou>rNc(brzM2QK}Y^5nNE*~=A67ipH1KCLgN zl)@PY+{j0M5Dyt|QdHEkPb`>d0)i(9l1sg8XWEJzMBF^D-i+_r*@5;8a{{4hfk5a2 zjHj~;kS;{J6zOu7(_K!A0b^;IC>2vmvPCqdr(r+lh93xR^o+*kyWvQn7ehs*1K&c* z3DGk4wG|Z&)bIxngP^fsG3{*pBkyD7SLaJV%##QDAxmtgZv&=3P_Cu@nSr$FSUHsS z<5`_bU1EE#Xh|_z;_pJm>#**JmdHx7%N2bE6GdYE`Y`ga6;T2$qxEyKX#JQdwX9$7 zBw_3sdANGMNcBd0oAk!Pc&OemQZV&-B*qcO8hgb0p(+IE#`^WqtUx2nRE4Fw!jvMB z1ain)eI}p7_2t9$rNi|_u==jC7n>1#tIF5`$2Co{zJzkpZdtwgXmEbhx z5AtwZ`z_Vl|M`xz_Ch?^+KfjP@&g(483hg<`P4DG67nr-Oy!LiE+cvI>xLpFE(ovA#m>(pOHx zzLE;t3%M|vwu+;}(c78S2+C_UO**-vt5KaAJJUfs6TglW&X{sE)s(hryVhE+4;i}z zSHbzp4wgSNuDm^W(Db55CFe(ZbFdn5a76=M(v^p~*wP3IOmKSH>+|3+^}3j`?W7eR zUm3y`!P7)b^B1h7mQKA559i0x1BZo$$k=JQbZl$wkq@^;=F}AFiO5B>kcVx@_>$T9goi6p2M?LI0K6x zpqoB$k~&=D68iD)v=gK&0O8{)H0ARyz7apwvGjQT01pWyrH^|bDGi{4aasUo#n*Pq z8nu6DBNzl9I4^)Fy10?QfAA;HAWTWE}YTQ%18csJjC>Zq==txRA%@4 ztJ3N5rRS;AXR6Y7#!Bl>+YOsJO8jjQjfi_~3PJKR;@|m`>?2FZEm+%U5&cJiKE%{r z5W+o29#D%^S1r(z8L4LS#m%cFap%**8M6*|M~m5O zGqJDCtk}y~sa4iM9y}z#F%>)d8bNiQzI8Ft_1CHF__1Tgt&C3T_vO&UL{vZl+t4Ft zhl+x|V?_n@^7d$}2$5OYnr)0vsqjb0LWS{sNkj3M51&h(H}CowqhK&huPyHWsqc6GU81c z=`4}YFQqDxd=kqICoZlNfAJ9AuKas1$#Zt~w(}Z+@&_2>E@8V0bj{QPem8EdrKwcu~G@7SZ`&C!_jPBhb&k~=m@{k&l5}&zAbr5G*l3=C(8*Was=i~ z$R^apHLA*lc|$f`96d7vhKM3g)X>N8Ws1lMZADhB*Vz-9t`B9i)IlyhF+GJvJ{=YG zlk}@@y~vY#A#ADi8C5BZq#_ziRT98ED>Vd62c3{i*~OTVJbl$yjM(+BxT+i7eSVhnu>?c zg#<rd z8kt5hFMVftctaauA+>;xt#n>6N|3YPzJx!Owl=I7a{pr5aC6^qbMJ6-&oB>%OECN= z;^H+oDz)`z;?LTTudzFn(Jz-l4&k69Z-Bca5(TK^gL0(eSuoxY#$g7i<22Futt`ZG zpcH39QR)-ERpA!V=(2w*M&&jo#z9cg$6TZ`(AL$*4ew-mUT+g)Rb&iSrFl0z&E~14 zviosCJJy&=P5M5hm5T$aXxbV=STdaPhGZ6@mnFFn?c~fa&K*r7ai!%|Fc!2E+2(a} zHX@vH)Bz*n!jT?Qv-%s#C7ki>UQz@srK`Hd>_YzHW^N)MEFiPqqU<<+_TlQQ;^&p6 z_?c)H;?7bHAAJ~sy&#Ea#Ccnq>E3YmBw0emoJt7>4*SEZN1SH_4_cwi$B1|iH;H_Ef*|Y6|afml3$<1eEo4PaNjp$H4sYd zowGWUOkho^uKGQ!`9O)EH?aUC-Hm7?8X0lQa2mk<1M#yYTLwD10o1W0AbY#2)E;iB zW9?G7otq=XH4ml~Mu_qFsYaotZj5KB6)x}u6*G*q`oo!I$Bjo0KYXE*v6kPf)WPy2 zS)i{l<7KpL1ZKL$2}Vf#?SP%~6R8O`0ShJOp%XQUTz_^cB*%J^cYBQ#`a zeW4gh6a%IRdDE3&Lli0n@xLTv0IbH{N&maJI+AJDFfAn*(>flz&taYG+vR+8#wU%q z!@+3$pIAy3n*G3wI6ooNyj3R*hlz_Hv_*bUfoVO~VG#Cf@E;VIR;d@IsPJn@Wt_Bw z$1nQuzSD1@RAj9;5Z+@no~Q_~u!$4;_$v(h*h@>o!V<#doi)@B&nRNdk#b@IP}A?3 z(WxrOVvyfqw@TsDP?#s+gwIl1Cm}Llh|qpGxXwkdS(F(9y6o^jSuqs_ZIl2UPe?;J z9b~5DAcAP0lTMe+U;-z;j)ggXHn8~%XxVEDHZIn}yY`W`1CfjB>6!$3Tl*7RJaR=9 zno*PHj_+KP5(^dBecQK!eQY&%DvR^R(m8EkIskm(w^_RIR+ zzb-)A&ROXoL=ZP`G10czu(;7ULyZ9}d~(A;919p0`N-dip#f6+W%N0yR6Fl&5`l9^?3Usr4nvHbQ~ z+^0rLI-GI!Zf;bg8w=KPUk_F%bvl*lCF<1(sqH-{CV4b9t~c+XymkM5yJ3XK!2Rjz z@%4fB1Gq6Wp&dq^^q;18!bo~L=ekWvDCjlD%M;~?GyZqicwTs%3U#hEZP1#AMPRp0 zC*gN8UhTHGpqG_abMltWGu@#lhGalJDpnx0%8^vK9}i6A`s5MrC9r*^!i+e7Uq3t? zkv|Oq3ckq7v8bL_H?lGnzwiSug0D?Tg2Et*F^J1U7#Ru>Zd=1PYt9%0D5LaD zM2Jcu9R4QTtxp!{IQzF)xdZ_bt(%FSmLPl-*>>qk|Bs6UeUn@?VkZUi5vC0*MgZkP z=>=y27pFCSG&j}-hreuR_+l9!W9NYz$iG6H($=nQL5>my?hA5NpcEBL>K!a}^i zETGR^JxQAqJ9E`ogDh};8s_odv-L7Jm?y4`P3F@zBp#1WUEH4{& z&Yg?ox16^cQ-`^Dp`if8N7f0C++H8vk7FujNFLNT*ihg4*}`nbXfhVgpNz+F?_&}^ z#FVV;OEmu~o6UDX^o&)#)WS6V5j=!v>Usl7E4J@N&%}8Sb2HxZt+M4G zdcqO)d$eC3tNP>-?!^N(s7D^*ZUUj@@?aMhN~FC?l~D&$`w&myZpN&bM@ct!#Tr%}dz?0fVy<4Kp!L!dJQW+ANq*i18ATf{k* z9ER^N$1njmhbe9{lXG(=xoH{64MEOLIEbjZ;iX``SU$(qgEK>aBWusS%S@Lw#Ln({ z%pWjIqTfI^!08;b?W@>f+5-LqF@VVc(}zPRlr1>}Hc8OK{uVvVPlnBfU1$Np9u3Oj z$wR@wI77Cw#c!|`QY)fhSWqqRx{cZ<3m`>IvYP%+!zzO+fDJlRKIrXSH85OHH_)EVu5-l%^PZ4^o}2kR*Ypmp9 zE5^x?1U9o)ukQ7U0-j8A*UfX5+w$&| zG?nl7S54VF3f!jhDXC?3gYGC6nD8v1)}2L_N)hnsOY#Blbyg@}Da4brQ02%BaWK)? z)v%cQY4>SfMr2InJtXq&qO9&NZY$N@g=~R`tv-m;)t&OoQqFx;DD5V^S0vh9^2jn8 zvF{ZVO@&tu+8MdB%mHWBv&qUbU;MsGzLVz!Z<1c$yCtB#R2;d6*(zE8t*TlwF`~m! z-?&y4c)1jgEL9n+{$ZbhZBq-OvR+?1yP40EHnA1ah!iFCE{Uyd*C=UJeyCf0djdaC z-O9(+nuVRHZe=Y1S$trdTRpvRn_c_2*|o+>z&!0SC>rq%R>>JY<(?Vcn0%bP5q9nUfUHPn!2_tA++d7rOGTx)hRXk0%qXc1l*=J{>XfX+T`XyW$0;Dq6tSP z;F7H>jJ>X>jCHF7##rj-|CAZ8lAJteKdx8Di#$U{9lf0V1J!gKl86rz@xM5FY4JW9 zbY!`9$H>h^#z@Y=Bxm73Eq!}Fs9QDrO}{XE({d;$V7$_5v0tE9ua(*Us>~)EoRqY) zeJvl~a0lVyFO<9OH?q7ZBZebCcAhM7o;-r(WvL5?S2lk_DvgZQ^nqE&`R&G>>X8iF zDI=gsFPq=`4B{poDk6r~6;(cgO0r7qIy83IO0pc6Qd!jLQ$Q-!4VJv?CM!+* zUX&bloFvEEXn0Px*DzN~5*S-Hyu3PP4?MK5k{x%X(X)O@^GsU$hpOEjry|7WjQE9Y zGf54?(;sN2;gBQnsx3XfSX9$dGbF5Pla-_q>K2vjlnvctU)i&K^(jh~^c9j_Wju<1 ze@CXeEH%@P2GKpQtqDE|KIY%+Pr>p_9nXN2Sb^DQ#a_Xe+8unA}?;ejch1c?4d^( zRBeQGWH_E-mpSu2RUsIWCW&#fcDwhfazFK1_dY}Jr^^IW;@VTXEi^m!y_(VuPzz9s zUn1d?D04Kq_!C!W6ZH3TfB%n0wjGS$2cvl+X5OT>Go?dDJT}RXz`}I$)Mh1M7G8eU6mJ2Xf|CWUp;5 zk^2&vtJV$r_upK7jq-5|M3;{giemS#Y35S?yz&Y2=Mq`s)u|*&DwSTUO6yNVE6(Fa zOEs_3(;%Jw z{`2!$TSyaMYR&hehlt+Mf1$|uMaS0^5`phLND|TBAhcVtfhqwUpRmKY_9@JvP|-_A zGg1BYEG^F+Svd`H&x08lCG6ltC!hR^)I<-ByC|>D&>2`wsr(TEMRke5ae}U-Bkx4U zvqOGJ2*-<@p4JhmdLCum-$zN<7BE08MN)rNg524qu&Q~JvgVS}w{v#I9f@goR;lT1 znx4|)$#Wa0u#vH7F0x(wOHCs8_EblG<;I@lC{>mJy=F=^(wAZ1{*L!yee5KK=B5-@ z4>jXk(oT_#)}ttq=_O|@)=TFVQJYiBHLubFz=SJ ztF*dm@%xh}Rn%6=@1{qkVn~O?Kkjc(_l(x7TZqA+g^x7Li2YweejDTPn}2`SD-wK7 zUsfbo-KV#yca96T$&)vg6m|I+m9k!mic#0n9(LR9uy$(70%ym_`E}8#XL>m%OQI9s zbXLx`%I)duR#wio%k6O%@AN5}opSpgx4OY^l-th|urAh-o=R4$78uKE>R93j5C9aC*UI zUv_t#o?V2!_wq1Fd1WZtNUuw*{T&~_EqRlMS~u3L$eitPM-}I`sKWVl?K}FkQk5OQ`?MpT1`%6K-YqV`uhxarLz}UUeacs2|OFyjDky+J;eEql|G| z#B5uBEmlAh)oBRaGmk09CUiPCZEBgMHGDsztFz zkywtz+>PlxZIauo)NPR4X1N`&(o5!+A#x`t|8i?T=DGU|E8Y*TMXjmp!rB+xFI}&) zS6xO(KkaeO=p<(SniM7&^>F&A8k|MIu(D-drT&KM6npk!YJpC=DD0?OJ=HdSPBo*t zOwx~N{-we5hVUQ#TijW_$T>$2(ymT1%TO{R_6?HjY(bG9<#{%ZfP4W*frTfP!u@5}4_R7p$j zJlWszKitaJ^2WzhN*lFAam(gPaYZlWN{Q&aD>CVSc(D(o%kJThzX$R9z_%4hM10bE zZjxk!^`4mm6Ov}B-NU*%z2(0?gKXK~&{AWuzFS4B&GI;h6F@4r%KYa)C{G4u=`<$U zX$01gJE=VSTWGXL>fo7OWPc`3J(??N80VkiSsuNGkBnA|dFHq0Z2XBzjN?8eT`NED znT%B4$5cy2+8SY>?JUPd)G351d&r?U-bD1$2aGl)jzo z?)uMvhlh=rYn)gO?$j%~yQl0yRct6PB&l4w->CWl2LZCz9hRvWu?YS^j@r_ddnNjl znPOG<6QjQ;Pe*Q(s^Qt@9gGoq1mKj-MAKg0i2}GsSSo3xGQ0Mu{oPHKP%R00zX|Ck zSSCi)g1(O+TYrueh>x3Z1BEvz;dc>zbh8*kIveua%5`Mlt2)K7MPrGfX4zpqv3QRj z4I>JVb^B&Jb$G8CN^yHsdolPi(ZXqC?CpzLH zLyfM8>a1&BMGlEYZj;+dzhI;oHDP6e9$zWEUfMeq{S-M8Xp7NfWc7F=QgdtHSF?uq zI?6;-8BtP#VSPiSeZ6)+XpS#-@)nXkzED}X^9}C3{jJDuSV?t8yhL#Jk(Ab|DL$au zNLeXCTXp2-BwIyy=Sb&Ss}V)QeMm6!dp<{{y!^7Upz^DKa9Eo6DB9@lqN%nf-oW`> zBD1;cTKE7fr?!%l4JE@m4Lz>wl!Ex1Y61-E^m0jU*69R zc`r|oBCjq&o_p-%V`o@uADt<8?n$v9+mAi+Zfm{GPVwjZ?MNn&tbBSF7bn8B_R@mH z(ai|1sV3F8vlXNapg%?HJl^sh_i+Za^Y{*#AZsC6#^ZE31)(2bV?6HtT{rX+(!eL$127cl>+1OJzk+Gu(XVkngZq54v{EA@5;SiZbG$ zGmfa-4pcyHEqjpQY;DUCQL(9-FRAk-xPYp8ZkxYGc6GdVE7>h;`&dL>B__z`bEa7- zf;k&&q>_NF)$7-4xW?rAqwC(w%}#l`7S@tQ8~fDTn+!mdcJ^M@KJI&XDBq9$U1aUd zkamLKe{o``%6&O4n3Bfz0IqvTl9b_aN;h256sLB{y8-Gq+iHK-B%2|%KWP-;SiS@& z+UJ)`wDsz#y$qFGFVy-}2~nqkfWy?&mw3`hYm;NY37`+he?-FyQ7;5RH!e^yRXA?D zXp@inV--#nFWoA4ddd%j(vrtMoZTs$0tf*|4wMteHcohw1-ZIBvF+qvaEmRc2g zT8^9qtlO;YU00_QeF<+-1Ms_*q4yi)nnfi{;GF6of>-DLTxLvwhQmvNAhw-ZCt90b9 zi&f;`NaQ_4&LQ-^taMg(bUog|Iq4pCT#pKrRNjylk*A8tJGIEiw8;BJWT`Du+A-Gu zY}fzgpMrRCV6Ot#_3u*A2Q638CoCYk-K@&TkEAWsg(qJ}QQFnn`=H|Tn);1$4b}9~ zdaCcB;x%fzr}o=a-p0x&$MuLZax=v4kHlJbzMeyi=j(L7e#N*7J3oWDJHBzTHWfj~ z%F8JmC5V`;u3mQz_K5MVj^FD|cVUuLx8Y{wmP1;G{jnw-@owiy-G)>hmOe!~02U4; zhp%`1Ju-)PzpT>JnS6p;_2GlAD#~n!Y};Jq>e0h&+tgH8DZfTXc5Hp{JzK@K9W;E@ zCg=-)N-|8(P!yYyCeDsZ;kM38GBn!$UWE!s-H2RN0#0Ab*&|_$$3=}@JiRnw~ci6%Q z6)(6s>oK<3sY*hIAZk~Wo>aA=|BxMWB_!hYi}-&fhoQSgOh8Og3w zX6{%ftJ0pGMb@95rMRD!geax>KC4RhW2xFs;odDTi)bNP#^YyHza{>emt#CGcB)8S zUWxH|jpNN5)kqA+F4*~hP&uEYphv+rlT&5x|Mi<KV?6?@_Lox@PDxWMuCTUEX1dz0(_D2CH75+q9-5r40Y3i_|xuAkTIW`DJgBd^t{qxvf7%>-q_?rsfU zsqPunWp7vC>QK&qxn5i42`BwHC{Zhu*7^-p)of%7Y~{utOS~u&j1(?dPmjww8t*%V zYq@3}#F+*`OP->49c8t=-U)8+i}GtpEKJCUl$_e0jxq4t>O(p9?-|+#38|0L%0&4; z`6)v-XT^wJQGTe2$DDOw?UVfXB0G9_h^B$J;*4L<2=-`CRg>r*z8!0~I(Fap<@O(1 zCDGY;s$pKB@K)36hzxykd8v!E{B{oVd+NVG~w)xc9;I6Pv}oR{JL0Lg4q@D{dCGW47^ zUBPDg!GfH%Ka)GF`i7jk^*^*HoWpRPoVv~Gwobj}%v7#*oc6bGDIeRsM#64fFB08l z_ldVlJRN~zKXa_Qb)?=oj=|lTsumBr?`?5~z*+?~?rT(cfQss6RhhV@D_zvMYb=ds z&c@A3Yo@eHc||PQrV>!I6Q*w-@%na;K#_guMboIJJkC_+YJ{>-f3BSevTMZuI`Ln? zJ1n&u;&AL2cu92KqLPp&&v)}H2|t(r#M!?u#K!f?xa^O3FSmx@^{GWH=*Qi@17{%@A5LAOrfVq#(Bw8mjx#aC}CdmtR7L1$ifHTbitg53Qp1K{1mt zIC)0h`_2O4eyY46qOn=VV!q^I zq;i+2jm;~o$evfKjcMxEX>3lVh@8ge%r{kI^A!bO)Y$AL$59)bzkf?5pxTeH#$u__ z3Ze2fx?Y7fHXkC?x3M{g_+QZ2Y+R|*?%CK(79v_>Q+R<>yZ?`k&C+T~I!a@6_a>#2 zWml43Vz;{WPMtZM^tp8^LsONbj@#J0NC_EZoYiT%#4|>z$IV2pM6}!Jy&aP0o8=jl z(dd09-My$W0RsAxt@*9g^wGWFtR1x zD2>hOsNmFi$2Y6RHoCESQgW+Y#W7sR2qKt`&0F$-LryY;Qy=q~NOVV}lbtGZ=R9*7 zo8w!&XHH|Y^`ad1gI1Tssa)&g2rQA_} zPJz-6(g=LHLmID1#At^!x__-&hb{%~TAqDKV_YhEtedb5kY#MYLmDeoTNLGx#yvC! zEXh2q(`c~M=rP<0JESqSMw(UcAi`YT&?Vayt(J=Lg@-iaA5?{_DreXsjaS%)P>oI4 zA&q~xDjOVA5T%6-)9+F8xJ!olr|r(SFbBjF7lAZ*GMJekjCNjqaM=OFS`X=P`tDx zwiUt-X*lzvpqd}~?|t4SV==W9qBg*oc&jbZht$wkR!G!Zr}KCjllz?T6~TM{-s90- zJs+)Bk7RBYv37L&>#BqYD4>M(QZDsZ=1jHCYLN7Q+3$Quh6O5rJ=Tum-K_UmJ6ds% z%G9BV<-)f=iTe1h=#LMo$Ad0idQEu&%#l;W z9?^_Md=FGa^!F7({~RgedLG$UlYyR0plg4Y%R@FoRW-F2RlZ3bqr3W88iBXe_56>y zr&FKs-gwEk!>Ly$w@#-%5 z@RvcWqe#Nn$}Cm)+Nvt|=b>s@-N$@yU#aMRo~y6c7|9%pMa$Z@54T`K-M4R-r$sz< zI(tmAzvFjjyA7N+XNJ;MuU-91c9L`hRVe24#s~ulb!2$>$l`ual&jHgJkzG;`{iOc zE$uXscK2Q>Ut=S$_KxGV)m>}vI38C$?(RFf;46SYwg(5Nd|3<4|jp?Ms?P^=hYGk6l0+Mhk;mA5$5s|@qRu<{)?SqRf!m@bx5 z23F-VCCIIv!efeRJ92@+pAGL6r1G&fI*?f7CsKrZdCjcQtPpmRApg`a9>`B-ah;W{ zeq^kZ3VQqD#>fWt2HYaNfDAQ9~3?pLWsL!O8V z6g4d)*Su4qLwM`stTn48@BZue>QF2_#~Gh%-KrLfd40eC+8uU)oVtZU#KGjGpbO>I zniJP7hqqrk6t5v6C$5EFE~uITZPIS7;uppuLv`{Rjau`0RU)ZRjn*$`DopQ zD*$^>SN~ikru;SvdHb=RmGuw86JWIpAZd$@Q)s)f56kYdEY7beb)0)8IZ{8mbx4<; z`m)$et+pJIRAUTh1)znv&Dgk^+!9{d#QxPK>?=PB%o%>&a(%NvOr_5+mdfC1uy#;* zzW*#EL|xm@6W8>n@cP$o*T_O$?awwGmta3xqhNE5fO8IFe@C)36C1;yDutv|AzZzb z6=}W78Z)JJfqm=W1$ymU{~pkrtQXk&zdBT@sBY_iBH|#^ z75VGu@mZDU%}SH(uSxzNR1xNXjbKY8SlxtA?1^%Jom&;Tu1=G-iB)cg4pG7tfuQ;` ztkrYW5+<)J87$2W!DxLy~z^S14N6sT9~{zR2(U0tIx^JcN{O!=*X6QXX;VwI>0 z$?fdrvh&h^-FdRSTQ_04s9tx;V|(c@f|81w`8sZ~SV`K8lFWW4TyAG`4kFYeHFxWn z&qfoAS{rz@K@z-C?$zd!s`sCMCQ{j83zRem38;GJKdJmp=%-UZUs8Wm9)+cz>88$b zWWoSD_10pQdZV5>cDyA+k=pE?q`p&9|BKvvsn@uvfApf8`U-7bWi_I_ah0v%dR?_t zeVKPUbGq-Vrbb(tfR7b1C#G+@WYsTF_$uWS6TW$YD8P=(U|W9~Q*GAfR+8=_7TPtd ztiRWBn+hlPSmluCoXaHH0(Zo>I?a^F*V(4l^+V!LYgyFmoF zb$e2Zx^;4!e4)BkzJl6A>G?i9Rh&WD-cpXgzvCE@oLQVx)AMvPt>R_G{IwCpsgt7! z^5Na8(#ZO*zWD3m}0^#f&`W(lE}VcfhA zDD|E>UYzk&@0nwTKI6P+jwuGpSWvgWkBN0{o8P@x8eZ@GxN|yK_tidDzVb)G36>YRj8`oGE@d6|ily{pscs)A zThHpdIO-gDhh*;-45+)qRa>cS{7u)YS4ydS-_Gfo?nag7 zAxZNQQBxX=_c|I2B_-W8s~kb!!RQ31A z1hox~p@Pa#q77QS{XNN>jC|!^_^)EgA!XI>X-c*ux6MGlh zNCMIJ-P)sB$ZRnNNZ3nRwN`C^%DD?z_2d;6m*pH1-Ink(17+$%%Dcmo7#S<&)FU@>8&*(3@c%C8o%ODWxWI~ zwC%_fn1wkBE}~4M{P)MAB8J;M;|Kr(!U@=-N|8UDxu|-Q!;a($U1PF9w)TP|T}37z_9w+%99Hf$Olk1<8 z48MeK_<+o(rE8dgdG&nJ{t~q0Pu!cg%XCFCzBK7Rd4xP;B5A`_%d=7`&8^`LW=kLb z%R$*XG}Cz9ZhC&xrB^^`Tf@Fd*)xZ>ii40u5y$>+P1V_~%lt$Y9!jg2O6i0yu?I>^ zU*!AUn&Sf`l+=0btKz+_MM*s8(Vr!dU3G3xw$1D$Ms<6=Lw0vmeeoj2BS(L?CZ(Sj zeGdUU7Mvh^kuOPT^E$na_8X^u5hg`-08+x8_UpDP?fyJ=`kJ1nLpw$K zV2Nq3KB=~ylI2|z^Qro&=IAqi-W-S0(ieG)$`U*5OBzl+bNkky+h(aXI_VHuSyy_fmhNFa#87>ftxI?<43mV- z>?IH^u}-pYeBdvrybV8+%?YVEDuH_?6zN5`#7Vw33S%O2p*zxbr}&JT(XEpSi2J)q zZKz<^#HjC0O2O`XF^f?2Mv>Rbv_HR6(oL1*E!%_E z{G7T`PlNMj)_yv(_P4ns{zM;`l=IT(2_3zYMEk#lf@9xt;_DwKn2v<*f$ceKe-W26 z>G#zikxJ5a*H2kA<@za$rxg66e)(u8{NH~e%?|Pi!DWxXIEy~x3;rYo))DVoqwJ)w zC6>CE3;Q_>|CTlO-BIeFT#u<fAMeRIL;Cd15yj>f-&|e1GBluXpTzRQn~GE7f^n%QopWZNJ~mrf zcI$xteR|(iymDpX3Y#7`vrq5KtBQ+5#Z?0??UOXG@KzOgK+0$@fzhV)!C#5OAo(0? z>cl>0lva#hQB}EYba74LO_gQED~+&I`ztXE#Cmy>yS%tZ;}ddn7cA|iO6fvNc3Mpv zn8}Wo9NFfGD7Vz%%d0AG8X+Z?8Y(GWIYO0LbXh1m+Rnct44gAjyGw@SE*Yie7^J+g zY}}-o_SNj-P+?JFsBl4PsAP&b)6~M1#WUy3OD`BZVSf3I}2Crzs;4;7Y{7guGA8gu4_E-ENkR#P)}?AUQj3s;sdE6}bwbJ@Jm*s;q> z3abi2RfVOYl{1%R&nx7=Y!%PR!kn?`UTKX@x9vt=?NH(TIMc4Kod3u5&o+8NS!t-) zt$^Y6FLh<XoC4 zD5ui0m7|uHmOJK&+CC7avT{r*UOHx3MN#pJ;_@*f1_hT^6;|DTgr3inoHGU%f0-GZ$!JER#9D6RDQl`jNsB+L&ZT_+~vhp z!K&iIqGH~!{F3=pwXZSXNP89x4#;m^mlEVD^-S=yW-SQZO%f z=CtgB-0V4*=jWuZEGu1BT%erD3udXf64mr8is{l+UkM{5-}0#%`TO7Ke@hjfUWNW= zi$&~Qjk@$|%Bm=Jgry!jc?yOqLUcUJ)Bl6?=n<~mlD_yB;RaCAl_zxUI zf?H#}7G$*DA&hZ)18Y_BvQS0UGbAQ1nv4wk%y|Q%8QGF z%PXpa)#cPA9;t5W%iD2TS!pq4tzy##l$D7Ub@eV7U2!AUv;V$ix!Cd?b0KZn&C*+x zSC^GlhQ7Ri7OuRtd|9|!T9K8ED#}zDkDgatUNl>Gu&H*&N4PqhO}jGYvWjvV`s!sN zrHg7;7=4r${b%{p^`<&Rvq#?eQ?+0;nxu}9iht9}73fvP*oJ08`mbq)%Swui=5e<& zzhX*NRpG6vL8XdrajU5s83mz{m+I;?dTH^B((=?1BSu&=)KCd`4N~}8o>TIY?w2f& zn~Fmv6-5Olh2=$M#Z?8;25Y^~t}Lu7ylFJDSMeN;Ld7+qQJ1b1Z*WFuL{|N9f#j1M zNCpKfmZwfreltZ%iN>%J+tMgX3p7HxPgSV6sKCOH^ab(Hwv(W;^blWFysWr%mBg^D z`Q^nml~e)Ty11$e$1W`oN`IhoK-pVVfXc#K%PIL3Zi&vRk3Lzr1kvM z%~Ehx1#u($kZE=$mvWn@y14wp6_Y1dR2EkiQYV8&#dHnDsSBtbCIO=&?<gV)`H8o{~2ON^oL*H8udHOGuEy`< zCOG%yk-5H%oJh5;WaKog+POCo`5!xRZsjuS7maX^ZiB=1>QO3l=8Y>D8*Xp)$j97PST1`= zW4>d~R~&x)yioO0cRJ$gE*DyV?CsaUhwC3QNY7tYdJ{c4BXl(a?CGOX6eugnWo~GyEI*8`oPQfmJxBia3Fs$*)?!l`H zs2lj`26A(zFLZjI{EP_28F9I~M?_V(5%FVn4AG)T>i^%W-*$b|y{Gggc7GAsM(KuW zg0xY(VN#by!xWLf|Fpr3%%5K;7u7cMFe3fP_B9qSd5gtMhGX$!g-Cv!Uqj}X0T%Jb z*#n>g=77cje~yB3myRU|vHv3M>-ev@Oys~Os-TGYj(>kyme`@Jv*o4%8S}&yG@QBPDUAc_815e zl4pJ+Ax~3TLv#LQh#PIa@=MO2m+AEpd-BTEnOU3Kxp3#kRmS9%M3ejJl-ZW}Qu`~; z-byrm{-5ltpx%FPT{794R=qM*aZ`}Bw(4SQnYtNOqSqqrJH0xr#}h12>8ZZ6rptU? zuQ3E=V?mZWn0>J1Y{%92qntqK9w|rG>dROc_yR#rFi#YT$hv~wk+Rf|R!POm(Bui} z=@Z6UYU8O#VmIm4CfW4(Pu7>>&Pcd8=d0{q;+SbiPjokMy@!wC?g0;gMc|vCoai2y zVp;zH$Ae@3exmy*>HGxDINP!=K1Mk3T5uiM?;j_+8^Kht6`T!rf_H$)ta@(+^T6$3 zBbf2&iS9P=nSY+>w$8PzLtqdb&KJX{gSlW4cpJD5d=%UP?gsaQ2f)K%CcoR5G|aMY zIDVo#4Q%?Hbil80!Z!qtXJ@WK?&G?<_kgd)cXuBKlM*;;f1YK{0EdBBgVVtcU=g@5 z(A~WOybat5-UGIPgL`#%cY+PQySr0{Th_~92AITF>LPG7xEfppZUfhWd%!JVJNPts z96XEt=ivF|voGm_4{?5=1ngoveiQf=&ZX>Wpso43n?(R%516%~& z0Imin59;pT4lV+l!P~yl-F+0?%8}SKUOo8>m#3v2+( z!QJ4~;6d}PKTUH7<9$W?H7H}Kb z0X_vL4M8t36?_fM0pA5nz{DW&!Rg>ma2?nJJ`Q$(uYyUkyMH$E!E7)Gd=M-Fe-3T{ z4}v?vPVfMj!Wr$O;H6;Svn;C!Oat4&TrmIK?(Q=1d2kcB58MTIf(O9Cyn1#N%mVuk zrJTVuum;Qp>%lVcX>b#G0Ne$>10Dc7z@wmb9`UKaXMt&8CYTH6f@Rf)?mEb0$2v-kEL9|UgNsEo4_Kl9ef!KP9t9z5+Cfv!Id&F z4cr9&8q8ddzfGWhDWkmy%Sb<0ko2m+P2f6k7dVTvNe95A;4yIUMbu~Zpi;r{;6yMV zoCAiyb>LQT8`uQC3ATYlGP=9Fzz4wKSlW3o3v30KfG5B;;J`_=Yv5F{8LR;hf%kzH zpOxAM2Elogi4WcnE&*G?bzq;1@k4MNxEH(=JPdvW_T~J6m5F`9955H$1XhCWU_E%& zCEeYP;CQeVECD;gHDEID^*#%xgDqel_$F8hc7pX_{H4SPQ^8j7QLqbq15DxDY$a3C z8@vr%0`3IYfD@;YZ!iyR23LWHz?2!(AAUMuA~+1p1*e0Hz#{NAa2?nH?f|d8obm!! zfk(l~Ipq5y@(HGaO<*oqHk0y}=inyrJK!#`5j+5%GmH3O2G}=){sBw_Gk8fd7tGBi z-{5z^dT=+`2)2W*;0?2}8~6a2JPEsj>ENt6_zT$YO8f;}4mN=I&857+m%+o}K`?Q$ zWqkk+1OEk12b1TKZ!ie11M|ThU?aE}d=)$lc7ll)d-^=jdW!M|+Q%t(x5HJKz1RKCb;BIggco5tM9s_rQ1GC5vI3Bc?6CWG^hQO&{ zJ-8Tb1V^r*euJ4{7kCetLVL9f%m9;0u`_rMxC2}a?gj4z4}&|vMB1%pFcxES0G)_@1W2f$7Ur^(OS1!MFh&25tazz(>InFteO`1kM6?fvdp-;CNw=sOd?1A|~Am;=5HmVi|u^aZzpyTIqc1E72*`(AA4{Oqor4dOLOl9|aeIZQyF~6L1@t zxtekYmxAr!Ch$1;3^-&CegbBKAA^g)j5~-AE(W)O!|$fNz&!9U*ber+lJUlR(gk;c z3&DM04VZi{dV>?eCa@B01Gj)(V4n??S03dCW`d>QBCrNr4c-fG1OEry11_m0U9jJM zv{zS=E|?BJ1?GW22P?r=upV5#k$M4c01tw@!DC?JCj4_Q{U10U%mDMjxnKw^0~^2{ z;BN3m@F4g$cnmxS4xC55ts_1-2h0c8f+6q;umRi)?gj_kPrku)unYVbI3%BO*VoB6 zxD;FjZUI+=JHTyV7uXD*RZqPHGeB!TdV)c4377@G3N8WLz%}5=Z_r+X8DKMbA9x7d z3R+iN){ns;_!^i6c7RL30S^!#Yyr1}y}n6&@Eq_EI1#iK;KyJPtOB#ZP2dvn8E_3) z(m;H$4QvL3n~4wJ0wylRKfz(3dI*HXX04DjFJLU6=`_$yclZUt9^P2i(o zJGd7-4t@j>**tOVygg5ALqunDXJ+raz5F7QDxrI7gym;t^7E(BY_ z8t^E%6|^2DKKKLh5cmRUEyW&S5c~s}1^yLW0)F%u{swk|yTD$L)2@S~z@y;RVBclv z3#Nfz19QPvunc?`+ywp$+yy3opZMTR@F=(t>{~?t3XTV#1@plcFa&-MHh_J1(oTT6 z;6d;qunX)2hZIx)p1@zgTyPOs2CfDl2e*L-z&+rnU^_VEN&F2g0f#JSyaz44lwaK+VxV}b1)sOe4cU!KLu;R z@h?!$;9Rf?EC<`bJHamSelX<*#!X-b_%yf>d>O0(-vqaUAAwEa=U^K+dJplzPhP}N zZlszvGkyRU@5MjC2CyEi-;ce(k{0X*&UpoUfy=V0dv7O zz%uYCxCtEaHu1qU@Br8jc7g-np`Q^4)gw3wD7`;8%W6e!*0* z3!Dt5tfW4Jnc%;`Mc|NkDL*j%J?soF2V1}=!4B{cm=q#Bm2hRdGfEnOUa1q!7t^+&3^WG=lt1Rm>Fde)G z%mdegmEaz*9()yS1lzz?aPS|o8(0Dk#LrfPBzz;V0`5r$cUdpMv`%06K*9A0$XPNN1@TZ!5t`~n1{H5@d zOg`lCtKk>IPc`}MwFxx@5&7HTZ-e)<-yZn;;QN{JXL|D6;cMVUmTR8{9xspMZp+J6 zHKq5%b*qEc8M?mE&cI2zF^TYug>PdKMsGM8GnfvzY=~|jQI8N55u2g#?SHMH^R%F z*dUY7^Y~WyJ7dW2gfEBp(=VB}E(D)t%D>%{pAO#u?^oyZ;CI8HW5&PUi(d&Z_B+?) zjW(qo{(1O`CV#URzY)F_KHKEuvs3`_pH}#Pz~_hYy3rH96MjTujQsavOa&jU%?T1e z1OFKYe+JiycQLVY>crKaj`_$KLYVUjng13cs~4)7<|Z2q-S89P{p!d;_+juVX8d_x{A2K<-&rPqjmHn9gB~1%9}k}b@7D(8 z!}o^w(=P;n4Ey`(*8qPM-cP^X@E^tC55jlA`{{QKzAZ-lfhRHFfKM~+L%$?0EdDVb z{{0y7^Wnw6qQy@o{%ZX1;x|ro-^+F4WeYqXo~iqlc=&BvBN_6 zJoxjFCV!odKa6Kt6i^4Y`WDxT&&>B^h^^|pa3zFWh#t2x)=K3<~5G;L1_(?*yj%t@|~3^UKO`EkNL#Qfn*GfYB?3Ls@X3?JG0 z&WY|naGm(^JTEOhru(fZB;j%iH@BU7gPg>JMz~or_Dgt71d4sjXb|81{fX{Nxpwuw zRp(v!P4LHK@Vnp#zk9;BT{{5Z2Y#F>|0XRz$g`vHL*QG@{AwLva&(mQc`fgq=sw$& zvB=Xg9sX7LX!S~Lu@E17242;Rx8{2JlyWxe#Tvq$bI7h2d&0w+^OowlVA7I+dnCBM3KLhVqFV@-V z$Ep`Q3G=Dw7^7YsAdK~=*!7~5Fe5*RT`vYEv+nU{|9X*$A1&>$>&0nTd1V|?FN(z9 zKD6t_XL(+@h~%ev5s&U{viA~lQ-%`A`{pT;A7Q` zRKh&K*~Dn|Li)};e5?WfENKIVprjjX(Y_mC;Z19t?+p<_)hp)G5BN_gQmlW&F|1bmX#zA z>F~?o!^$K6a;2c~dGKG4!B@h+0PknxdiW<|@Qv_W;is53GS+lj;h&2UzY~6EjQFxp z_)3iU>F`bPerq~;@V|}`zY@L~KHB^}NS^B9pN0Po^~m*i-Cpc<`l#K6DUPx3a}a)B z4E`AWRCvGsU?9rn!28YN$HUKpr&;lIyu$O*eE7-mR5_0~*2O~b7r@t;eEdq+hZ^A5 z!2@1=V~t}s#I5jSO&%XzVf*Mo_*m;=$KYjM>`XKMLQnsJO#Z9kee(~0OAJ0AUe@iR z)pMyMAzQv5-vD13BmQpqBKnp2rvCBTKqCJj{DbghGphZL!N1VUe_e1O9d%#Qk2X&d z`QzbFhWA@H&4&-b`^|4d@Sn48JJQt8nBOY`?ZyO;E%@O+u`4aC%c{w_S`whqeT4R4fu(2{ev7YjIrJp zWFhr1VG!l<#ymI+z8&7LJzN6+Df|pGe*6^IRvXY^Nbm0MRieWvLkH>i$~;@_M9vL_ z^J{Zj;ID=EvtFc&Y!1e_>|i%mg6f!g&ekwBD_;+}D&46DH z@2BHJ_(kv+n(@oM_%-mA@X_ifl(m)rO5i7&@r`=f1b-*IpFg$P^8MP5F8Ia7$8Eg) z8GBzTbdC#S$j^YE1s`pFOUil)g7e^S<2vysO2R1vsnn!`>qlIpX)v zz;9;WmpCC@PQpgLCPG%M7UTp^@vlD}@B`re+J__-TP1#-sYm<5c1<SUfFFKpx9>b^H~d2Q3(WZT8k)#I2ww!h+vMYa=*m9^-vtkN`WgG`1B06PYm3Lj ze?)vgJ|Dgvz6$Yf{^Rw8Tjd{q^Z@_1qXB*xykFhl4L=$F6~ue;_p1CsSqJ&=F#JGs z4k5nQN6*1Uhc3b#Jk8(6@{Uojf&MzmJBP=K@7EVBgij>?{iNmTSnHNS4SW^6U;M4` zx51xl#<%wgQQc~SzZ1T}_gS;>+OQg!l8CP4F!-_+9YN z!!v#JbTQ6z9DtYi0tcDAF>g8wzXRTHov1IyZh-gev(n&q!Y?xA$Lj+HD*y0@;r-gk zGI)7kFcEjP0fjJ%JV(yOFWb zM+TH7e!m$0=OSZ?Aw$nU)Syx194GKG!VQh%#?duluxccPA42DT>fXm0Y5I--F< zB;4||ISa^j;xHpzyq+jXS|QSUk}#;`$tmC(P65`M0<7{`PiwKmQp*=kySKG(9CBneegVFZzP`tL^yF{7>X>gRhUF z-yZn;;3pB*Epy|1Sv&j=_-Or&%;%58%lpM)V{e{I+VT$ZlWs2VM_WyqOt>S?bJ26=W2eiin( z!Q@4TeLg{K7Q{F95avf*C(4Vbj?E<8_r1EB#UOmfUr%(0_1O}}o*M;;UqqNSF~W%L z<=yapK6ytKtC9a6LWcZOM`9mCpDXT9s7u@wSldgFZbjBXWNqL_9&im$Z{vK@G581I zqm_f?eFzb^!av4!;?Ed`n|XiOvvVec#8voSwDJ-?7Qx>PPja3NW1g}aelzdi5|!28*^9sWD;(ef|loJd5`uSTx_Jl?Z`_^+{6 zGi=o@Z(J0-cOdi=EsOHc3+L(N&IrI6E`y3aPlg8*!46Bw}Wu)gp+nG@h&5r(U!Fk zreCUU`vN13Vf(}AlS~-DwX(!?z6SswtsaZMY539S=T{${gmSd$Y6Tg3laHmLH_G=@YvljZ==%6h1i7mII+ny2K-L!aKx>a6T zHN*b~ezM6MYqp2r{{rt16L1`y6o%ig;Q@~9JjF8mKoUUYfPv*|#J{uq2N@%{84NHv-T@3)RI9)2l&v^GZ7fA~f46HNV$HQx|?RgCxz@MSUh-SErd zDN3)5jlH6S@HOz!>a*x~3_j$;2jPbxxDq~(>%{A6JRF~m*PGlTBZKC58)5wF)k66D z;Qjj68u$kIXnm8&-wOYY81kFo?}GOm`?tYwg^%U~%J1-jN8$6CVpb1i4$^U zrX_j=Da6-C`ImJTd`k>|3H;0Oeq-V_Hjg@<4%A2429@-;!yhF6B9ph*oPs=ShEE=? z*Gt?yNPX5vQq)}LFkvnw4B(|<_+uhNynJ{+e;x)e-wT>)#*d$_Dy--@9li!W+IUj< zBKSMuqm_m5>)cUwreKMYbN@)m51PS;iL5{65pbcn*r}wV&jO*Y_^ zTi`=77TCf7&#^5wNw`7JVN(dV6FKi+6n(C~7w*$Y&fY_lJRXJ*WcaW9CZhZ?;`_B_ z!{8zyll;rQ4Srq>z6*Ya499%bDmr8m=1Ic%%}*A= z?}EpJJsEOHiCc-k8omksN|QI7ybO&rA6?6j3IwD{JSyuZSZaImzwDt=f(HHe;OnGcKA=={o4KG@VzJd z*X<#hmURkzH2Vk9DHA>kezvKf`13TcjF%8*9ATpM^CDvnd^-FqkuvmlsPdB?gn5%N ze(MB#;opIu79m4SHH2q};ZMLb?D5LcnBOK|!r1!a==DEHlwt4|d_E9X7mPE;IfO|k zj9)uh0zVNxnk_}g4R(A#ekc4$9~~ur3w#QE*qT{ z__Ivjm~*wjkA(NlKm0IwKmSb1((!%s58q7uN;Ca)O+>WgEPF z>(Osa(*^&o4==V3;xA%@)8ZJHolg&Mj6)Jm(&I8I_pGV(;poZIyccGvR~Ad)UyPBD zHSo{H;J3r?hWE2`Gkhcb$!7X9yz~#jKMX(G(hoG58|*x8ePKWF7n;V#MD8-wr?7)X!ey z8^*H(`0}UlPjH?1eR5&=YW#P-vObEOn#=t2(KnlQ8Te>*M&@N{@Jrw&9XE~HUr)F{ zu`aNw*V^9k-}2I0NZ5B{q*Vjo7K7gk{|3BYd*1}#3h!J0;a`TQ8hg6Z-iq0z%(~$J z06)v*Lt^+(4SY%r z|Je%PFNXXkc=5l9rhSa_!ENwo!AG;Nv>9FS;@_{B@x3|wb5aq+4)RUXr(@`m1-}!% zk10o2BNcxM`~&bJ%WX6Ckuk-ufxjQ#&(F8R-wGcsA0o3Eeg(W=IURy8j1iv~nXEi` zzj_da&xIdo>TjR96FcVMM_KSc;5zX#v@qM=?|JQE33C1?h8`Q>e+=)JkDc&R4t{oO zfq&3Pek!_kqUYD({~eE>KW3Ed=;?gR=OcZ#Mr=Cp3f?iC=5O=y@Y7@P`S9c5&qtP< zjxi<*!B2u0y(wqLeMCH^t^ zMeu$;H87X`4|qSH7!N-K-mmS?htGs(i7707IgKUhhv4V?q%S_T4aLR2G8au8o8rmP z=T+3`PUP%CPC4OD=GwKRG4^YRzZTxlPRHSM;r-h1AuMbZ!u#1N6JEZ99<7fJqS7Mx zO87aZemW0RrL-l?8p1q8n5)e&GA}a9a|dA#5XP@9-wXdP{0LKqao*!Fde6g4#TGt|F9W9{yil?F|5tuMLZ@7b-=5 z5&Wm{V@%#ypI!&wYeqzUHT2&BpAJ9VjBn2mq`n-$kLA1j=?UZ|Fvzo^>`&O=%@93~ zBInYX{^wcbRrG7&uQJoI9Z}+^!OM5}Uk~G7b?uZ3pE-+nUYIkw^)aDZO%^478T^(j zy1RcJ7XN@7e-nI8Zg=a%`l|QoAK$DdHQUB;zg_~IsKWm9nWidV)H}DOTMaGeQU@KV{aq~Z_&uEf@gWm zlVPke2jLsw{pKNA@DITI^%YCt?}zVi$~V?c*TCNygWnEc9)oX&UmSx!1V0DfZ{3X- z#jU9^_#phm7KQg^?3s#gY5cb}DAKGyB9T_fRM&9~>c zPaEN+yzM!zgli+*74vO*Ta9prJSlhimiY$@qmQ3uToSyBx&*JrOQv2?#!J(Z~G z{`R5gW503hZ4vysMcv&WAlKvn;PUI>XI&q?-ifX|;6H8gf1i6V{7~Zi^>2sa&w}?G zTPDt@|AA+u;psQet3$)!li^32yuB_d`b~!)93%ZA_|xH8hVkSZ?`yAv&xD_D@-kTC zUgaPD=>q@s_rf>9OIX*w_8dce;wW`sH~h0)C;p9^Xtou*ymb092${Ns?>(Dx;tSkz zN`t=_KH54~kT|*U8{j+4_~M`MdTCS=Cby9D%4V2&z0fcE*NY7JpvfC!-$t9i*yKq= zrhdx*@#`JLzX3imB_glJ`CdNkX?;MrO##9k@8{V>zuRy}0C}QMkO}gv75=`JW%Iu6 zAN-6M@z>bAU;ORxQ;8pqm;APnkLlFCztSfqZZz^C_5FRXU+O^4Aml_FtBRatd}us; zjo9sGLynZ6y;l~5OJ7J`CLH2Cn@JdB?Kz(?O@z5HB8)7%icLfC2jHWPXM}HneGR<~ zhR-m0W8XLg-wXLz*^6(SFKvK7MtnbhH~jnXcbV~xcdQP=Pep#F$=~AD!DH}?;r-gf zfed69!uyraczD0~LDI~(^OWCe5c9l`PpI7RMH4u$C&ws=rV-Qg3o~W^Q9&56X6G# zX&7~74ScE(A0*Cp_`&d7%=luPltarM*KYZ26(@^TM2&;{AklY#(q>ie0_}gjqrEI z;9KF#;B!p*_JItsUnjii=V#yK#f;Zu@agay;QiL!^WZnZM_c<6U#r0vCH+UZPQ08E zj^k^(-fed3-B#qBQs%E`6MXL&d>ecmyx*9u3;tyINv55QHII}6#@+CK<(L6KAO^n> z-h!WM%D30=gFLH&KL?(r8P5h%uZ^=a+X$0On1N;(d+jyIvpw)x@Ui;hLxeev`2b65 zUOMs9RpTKttR;*+;RngJQx^6+)AC5_@vtSdaimi$52p4@{(Ah>eku1SWcLf!B~I;^ zx+##;Fa6$LIsG!$_MY7@tEykdlz!<``lU|o7bG0vr}j&-l8IV|oF&MK7diG{cXwRy z$_X0-*30pX#9HG6A0}FFCa|EL+ z?^!&a66E|5sIXQRSy$RNX@%J;%`oBg_IgeD*1E0rPt1n>}C@yd~&g!x=6pK4) z;+Wg523up%qVI(WniaUpy1`T1eLg2J-zwM72W5k;ae+5`Sx@x}boR22^ct$N(f^9T zBXQR9Kz*F`tS$Ha9Kya3A9y)ny%!(&QNTKu5I7RB)+Pqt4p^;;Q;r9$hF;;x^&854 z*;go_Mq9{No8#g?k0(=sqw!XKeBhmUYiEKN>EwpEsU30F=SEgeUKba?CC+-$e$;me zp+^U%Tl00SlWqyzY5mwH``jT4KW5*Zu_EyIIIBAFew=k*T;Pp3>sxW7xZYqFWxtC9 zYvQcDK!vs0kv)vYFE6mbD)TfFt6AL-pB~qDXyBT-ae?fFLP*N`4$n_@nC`e!u7WBG z++uCA1)eg72MbAIo&BKym5ip}i3@z_fg15$W%i^gfqbh}Un9T!;q&4Kk7RcE zr??sW6XJdok5~LXA-gHj+LuTmw9tR(IP#vjz$3k_7vfH>>unv0Yl{D@mvtgB(9z4< z5(vE2%X+w%JbA9SolbUqsdcBmp0wb52-+MUc(#|dPi%8zDZ6Rc0Ohh12;Gn z7xz2K?O)^id=_VYO#++w5L@;u;^FO5CAUgQiGO-r{|f>u<7(sjd^65^M4md42tPb) z4D;Z)1#1HM=U0y=THg?@pG*k665uBj3cek%wg%=Xbwzq`7-VUnwwF~C_(#C{RoqQ~ z2v~O~+#mm|fc1ztu%vf(T*}bE$hf?~LvdDdpf=7TpUjnwgpqXF+`vPJLAJ}$7ixAkdU$=$uJPvUd`(#txS5cp{?Yj0wpy_eOV82BYm0utt#UTe_5XIB3^ zLchE{`sW5V$5{n|b#c~{k~h*%ni!aAE!Nk0qre#h+xy_vE&m^T?*boJRqc;YA0Q%> zH$r(>0inEVX7UEazNT&3G>u6p50&X8nKYqECQc@4i--jgQ4zsMn^b;r|k6XF0l)y?eyI1rKKNuee8j0J8gb_?5^oM-Lh-! zzotJqb4TB3E!N#Q)bGBDLZ{|O6-$??sIkd z=YRiffq%BZKU?6RE%474DAxj8&(&|HT&?#xckBJ((^Lc5#P2uhv1hR@yc@lj4shO; z*i=angR7bMYwPs$#r1kWw?XgryUP#M-#veqA~Uz>eJ=0%32_1}x1m;le>?A&G=}NL z4pMqs`TeeZe(%2=KV?DPk2u88+o7g8+${&ujB7qp3={oc(+oU`2DrNP-M3E{Z0J-Q1(+V z?^m~LJ@kaC!SQ z#OHRfel1_HZ}h(B8}+?j{D6Kw;ezn@7xQ;l^X|XbR+c~G-fF_!axJv7GOZ8(?xd5H3PfzJDj{rozBR*$JHZ~)6sg=<`{+4gz1 ze%`?6Pjw4tSSzs4bM^a8_8Dt6ay@UKSGkYH|HLza%WtnC;x_--4=yF{^V1gMCH#3_ z<@YSqo9|huC*SiXt2ZmK#ryoQ_j#-L+3LMz8}-;$dl%Z1?Y+UCGgqHbc#kFex$qvn zRs+3nIltH*g3N;3OD=zWts?He#DAN-&(C|Gt=yjQ?a1YipSi@X+)&`N{KE7X``+%C z2FeMx362%Jwuf&UjE~ul+uNTvdG*@jecsB?L+mH3^Q=Jq1zY8Po_k^O{p9-%-sdge z=dIr7*oVTupXGg?>wVt9&r3Y{Fzcc)omJlFP2T6N-e>!@fB*eH@>WHE>H|lFKmWx0 zypiM3==>!SF2An}?!ely!m-)w^pD;7xqC=|c_2SuzNgATEZewi7VmBy5`W*y?`4fr zu3hvN`_pTG%gUdZQ$VVBQRJEy*qP-v@eizCyK5`!_Xd7GfOogf#lPh?&HkRH^)opv z=ljX!*4}Uzo|g;$Uw1w0YE{Hr+ZDHZOa6MfUavQtbFJ5_f7AEDCs*_}e!i(qzyBLQ zTfLs==Z9PM`+?!~165@8kV3-k;(9&%Ez^HlNS?k-XROzKHjg zy!Y@v%KL@9Z{+3muW68q`AB?vK@JChGcC4L%;awv-?<>C!}#lBCeOn7E-{mXVf^(mldoZX*Oc_loU%vCX8#Z>Gie zj;;Dq6uwVv&*`NdFb%Vj&7(ysGKcL~m_Nh#{;@5bSHt)lV^MN=8fK|YZ#pbk)crjz zb|4hiD12sYEBQS5qiL~&Vsj6VDt~aWnEPAaetPT=Zj1!K6un|9+J8^_UF|!G#}T~M z!{1EY{IpiS9)C?a!!%N$3fOO0sY;;7NPl;&%%YjGL|6g7CJ!6~55BA)9 z9ln2T)_&SPrZ4;nxV+bMe6Kg*vs^RqL&0B9`EY{5v7>>@drf(Z(lPqtUY>$zn=g3J zm9ugM|DuPVLHugs(@9^{a*Pb z@rQ|nth-Jn{vRHG7V$?s{2bzs61VrgmH6Wx{zu|--=j~o^3_n#q%v+KNk9XrExTi z{xNIkdqHhVZ2#D7`Vo!aY#iNkyFSmx(LB(X`uvFaO#M36NBqBuTl;*J_)d3dK^I4e zKW`)cR^mqg7sOkLFChKBU^vKgFC)H?xQ*Z4%8cJPd+%%G_b?B)@p}Yu>n|I>vpw9# z?{OY(lTc`;#Ae2-s28Dm-8JBFNMHJkhlrc}{M8l(nutHh@~hsb^gl!VXgFS^{xRaG z5|=aO1>bOvmhU0{s+A|+PrM%rmdL9)cPn7>`KQ1u$>$9pR{HusV({^Ekc9ZYV2*uza8e#FB~9)8rrO&(tC;U-TmC2sBW-{>#L4W=o;U>55_i&Tj4|=%C?T0!5}q=%c_-s<5dx1aWKliSaF zxXJC`dbr8k51po*WAb*NJyafA9FWOFDHSCTk3#t=u-&mbE!X3~-QFqvSor@yOf6FWBgciy z-$r~F;s@~;uiHz@zw2fNnu(`??+rT5=PR&Y$;Cd%@(0TVfeSTu*GuZ8pZNEP z-@I4}xYx&befd>M7{8nN;|D6fob;Dsy+q1CeXjz?6CWo2#rqVP zNBlzIQSJ69a8#+}nvR79p?~nv`ds_%@xblx;Ez_ZeCM|nt>c$x6F+ocrSn$e_YkkY zS^<1?*NenAy-CX-Nqim{Tk7*gwhz=8cgb1wf?xa>{cP>IGde=>zfM&;*6%~WqxyFv z%Rhgs(m70Tu^$oN^r!;I68|glxrZrzd+xDsl=j>+wu*LW70Y)5m*-mC$x*~F1upfx z`e_BMo?D2Y{YIs4^_h+dRLb9aK={4hN!;QadP)Di#4VodapH5pz)}5p18|}L>@8aG z?JWNX;uiM;vhLa+FD~UTAJF=If%r|t&;F?baz>|I&k%2ZOh4D@Ew(RSTpU|n#H9hTP#LxPX7M#WM&jF8m-!~tkbdGyO3*w`@PQoAZ z+zoqa%g-hLE|wqqvI6snKg#l_G0t)}@t0VB)>joUxpBy$`rM!WTyf*``NX$+e0w`_ zixXT+`cD9ldanb}AX0x@?}r$4R}#3i+t45Mv(@Jk;+#sGhrO->mq*Q;vZR+_f2aRQ-2Cvr9d5ub<+|$=L>SeVO$k-Ey8j@H2ewg}{aWZQWYl zJjl-xw>a0MS^iCLQ92gKCi=Hr8-PoHS^SFi*LB2WjI*=x`+eZ@+%J0b%S$Z(Fyjl1 z&cR?XDgWf5`oNR*u{hsMpSy*8ZsY4N;P&n;>Tah)a7jB1ZcvoXhja0ie(nXuzpuC0 zbPNP}?sMN$z}mTn__;SJ4s*|4S>VzR7AI_S=1VNU+s#^TUzYzB@zY*bU?K4(XmEM% z!-M+1ra#Deg@RkWYZJ@QgMlW`wRlE*?keC?-r{H9&+_LHAEo>;xqT(^zaFB`#pB%d zUE;^xsGrfi?)tOQ*(F?l7A6{b?z1;&Iiuf1{O;QnkLxY=apJ3Lluirr=ZW9@3>U~Yo9*g(he3^Wc>4KmVc#7>7PnEKX>KfzhzvD@&Dgg{?2MG{|1&n1&Yd> zF+W<|6RQwvz5-Fq`z0S(tm7qxP8_D-v27pWZ`19=YM1Qr-=J{$m=lCOZiXyNeddClZf9+{omxzCBWsq_T+ds{087s|BaU^ zozL*OKOk;#%KDXxQS`cjDt|h?t3aro0BK~3EGJY@h=CvP?jxWy#PgMF# zJbCpM;8M>O8-x3gGl;+EB&FX>J$xqd-w}V}4+`M*-PQPK z8Jnf+(MP^b>C9j|?8ow_5r2a6#GZQ%@e8S69mw*31TO8f)oY(OLa<2x+CCQR-@AzW z`rFPBP-4GWoWOL_-w(L-yTw^vLHwJ*qsIH&=IV2Idrk{N?7ORLuHxOhYkPi__{V@t z{ja5b#APydR3zJ03RPnoB&N#I zzxEM*-aUGY9koEq`||1m;8E@HJj*{#yY(Q_Sqeo(>RHA2#qf03M&R$ z;8FCaC$;>8lt0ElO~ik8u+k~;5AhpVAH#o7y!j{kKu%Y&V;3p?!#EFGe|-(O@I&l8 zrT-UOu%3rN@ssCTe6>AyIdGwW(gRxXY?jXue}?`ysBP{#kNCr$zVQI@ zN2tH;&+>mHzWP1|AYRytxX>S+ zru9FDw4Nd!qds8#wsJ)@{j-1z9ovtHW^vbzz=h8(o_jX&Cmg{;q{CLhjjRXUfx zMeB1U%Rfqdfb%uF+g(S#L(4x$-1y;x#BF~i*wS6s0FRP0cL101vVr~$tIyNKZ6D(S zq%*BepL_4$6fl~-#BE<=p5;GAd?EcFP{Z8yOW@Kz7Ds*=@x%6zdcyC-b+O-*Ki9QK z*MAFeY5%1UDFKr|&k?tMm)4%Uc4+w-ocFEWE+B6EhK4vFeU?)o(GW1ttvW%I&*E4BRfv>y%cCEh~8{8s&0?2p7-|ERzs;t5O~j^F;EfW7a# zfy?~Xy2JDhYH>3j3$mx$N>MXA{PZY@)O@##vZk#@S# zzY2I%eSX98zF+s0GnCE`zNych!I$_j@fP}XHWEMjom&1|KUCmj#NS2y9{N@GA^vgV zZ{xUYAindvqU*UBxU~Nq%2ng5)x@X0Ronkn^3Myz@3~qDTmK&SZXI`z)Bm$4pL+vv zp>O+(pC*3InTp>>{ctn!kEIlU`aT6tAijxs3&-gQ@upSL@0ABG&pn3x{C<|-HLbYq zLxxyz*KFWX{rFyom-^GLB%PW!PjSBo`?>4v&S*N%19$EGZ7pa0zFU{#zMt?0;-8`2 zZT+%)x0d()$?d?S>i;2@Kbv;qLe}#I;&;BJfYEQtXg|K>`PrT)Zu{JcWA$~h>N1t}L^~=<=l+F*orUl=?@-4un-JbQv*N0gCq?@(iESA3ocoaWOS)=cJ z?I*S1@hpEVaN$qeziaQ6cI8fG;e2i7Hxd7L>Pt2r{{me4 z#rDS;pT8libPhd6-|G#m&syS^PoatUnL}E>^Hl|mZ@*65@>smU^51xmmY@9{1&$~F zF!9&Y`rJ1WKP;!^eLN35s^9Nq`7`fP0$(JZU%T=%VzzIc(|K&)Vb*`E7PRqoG;!OP zZ12@X{65NogGfI|{ON?&-`e>}6zCw{FsjczhwWqSe=6~tSbxLU5Wn~ceV~n(yNUbj{!b8}b+bOu z`fLBS`rNw56yKlqSw?)zUlcfu_-5k%ddEw|Kk_3j$Zm+$uT%OrenWA4?rp?p9HjMs z3+c~VujMaiT*UW?|BU!KKUBc_W!l*oznFJsd+~v90&ZnU!rhhu7rx53-JqB|J%vu z&zGTd^0`W9I_2j~(z%JaACK_>@n^kp_iNxXFIYYblUMt{U+G`;suJFd^!tF@--O)l zb1ZN96n@P5Zy|nw=P%uFgVMMBJ|_3-fJgDwDu=^AbDn!#%=r0X(%GBsY5lSX%0n~>4Tt)nW|5U=CBK=p1&+VDwkgpM6b)nMn^{$TrH<`(z?)D9q zKkg+(Z5+KyeAAB=xAvL+A*J8?isIH^Yl+XGU-2;gI(9el2Pjt`Cf<0F(s_*fSc3R_ ziCey@V~O8I{Lv};zK0S&;=@Ykh@UI42k}#h`|Ii7CO(IL&gCqB(npkzZ;yP1_`RfW z{QMwrYZH=iw_`u5boQpbZ|!p@am(Xl^?#YT??;+>vC^6TfKoSEv6Q&4hnz|LzNfVO zovhU7iNE!5Z8wu|2YpQV6LD4_RQx!WUj|&p^<#|3XdwPMmbW|zvxwgXJgOb`zeMTy z@qY7&`*9tk#HVjn!e^5HgT&9Ef7r&$ABo4v|3|X?oR8~spXIu$y|4IT<-O`SpPt0> z&l9&iYjVbxTpzns%YXDW{X9c&v7Z8udf)hE(fD=1<+(pZ)TmtVC7s{9@-t%V*irVr zy`RwX{m5$}BYvObFfdG;E`2MsF#5Z221^Zb3 z72@}QT>;~hs!uDOl`kl6{j!qy%wH*PzW|r#?&8^l-(vZtlqW}!&d#4vI=&uw5%9fP zCV2Z#mS1+YqWc(~%azV=XKBALA^uL{mjBLZ?(#2M{#okD)}HSs{)iVxu?4vFyXDtP zlKxXH|9#qzjl>5(tMsqAR{@*fKL%Xrq|Z~liskQRdEdXf@N-J%QtC^!EPo|&%Xjw- z@zbx+@-t}v?oa#*;+yVQU?)=6 zE1i>tp$BX7NYEz~#9&KdylF%hklM zcv*3ipDz(VhwGlZlFs5U>U;Td3#)+(eczAT@+HN0^X%^Hh<}%Qpgs4ntF^qZKYW(B z<&Qg*_4x^Lf4wsHWu?=0qZYLJVlnYWe^%Vu|Kr3HT>rKD%(zDB%w+w|o?Q)G`q%RJ z8T}7AoRtgQ9w40yeyJeU!PxF!QTi9MolPDN0T=owe@n~XMOt?_JV2O#PPta;yheM< z_;W4sgg3tKA>MM-6i4A-Nv8&XNI#xKIW|Q6N#aj_Q-OKJUnB1O(|(0{C5mrf1}^mP zJV~E>66w7CtBN0oevoUS-eP&;mVfji;} z0GIK;!HWYqkL9nVKgamt72;VF$>sn5GPuUWs;!p;%=XY3cl-%I=f zmfwr?pC<0FYtOz#>$#QnT*C6F0T=qWc=1$Qi0}3nEokHYW#X29_diJI8yL4y@AYTk zLO=FxEok%L;hPn=Je_-xPAlPqKcGHi<6_OfDV^tUR03;B=X=BtyG;RW zpIvW_uIKDB_=Uj5uCaV<#-HB+F7M^b`B#bie%Jj_4=I27?OGq37rsgSnFkdA^fbM{ zNPOS>^|STYf%v`DXV!<54`=Duv9|#i`p+|dGI$dc^|Z zQT_OCmj90D*ZPqwKO<)OqQUm=>cPAs^;tzfp3(m{aX)T(_kY*&Kju7Te0~P;4L?@8 zM(3l%f7hVx@K!$eHsDe9-}O$Ve=+2fTyN1^?487ya>6`>_y>qz@`wU6iQhu}6W>)} z4e{MDfr{LlxkUk!KUKh`9ejV$2=VjT{zm^{;zzxvbWR}scY|)!dtCus=r<2&I~>mP zG4!|K!<iD!uWanAn-coh8;?@>CvoOkAv&ew?7{7r!ai9bsGCfcWm5`QDcztrai z>Ny7y?=X-9883r_X(ya^Cv=1HgqJ{CVvw#LxY_zL&*uJw`eYKB_pxth;sx zpGmv<>$!czKlME=SI6>K5r1H-0#=`I0Jk<|QFr^H!%OYH=ZSB=Kug&4HEbLTAu_i>*Ibr|L1{A`&{xxC18Grmr3Ul>P1J9{xZC$$h{4ed*>7X58zUt z3&Fo~Sv~iGJQe(zg<8+JejWP=@#nxtaxKzZ?3cv-xXRVv*Y%D)xz1wzc@=Pb7D>3< zlfdP<{hXKE_+{0Dig&Z!-a-6y;(LR??LbN$0gr{k|${^O+cTjJMo9nI#8(f`o$Ex*!&#{XX- zekbEYY`iq0y`-LJu|18>SAaWyJ69Wc9iMynkF>nMKK^mwQva%b4|650{x`DxEc$Q% zm2~K=T7nVQhCramqUM*?; zo+o~n=a2dw@guk%xhVIgC%@Kh^TTrJg^Zj_nXLFF#J>w%`X%P&A=%~0XnA#t!;v5FgQP!A@3#S$_ua&GE*nR`EJNqb z|3}|zHuKb>+1)i4xX`)&HvPOG@rQx$&A)@UBOouL@Rh)Yj-8M4G=H?>=Zc>|J~6(! z4!FpflQ_@r!Sau@{GA+#R?qgWO2^;dbT#pJQtw5}x@!vBUFvh|pY*fg3F7`b`}x47 zK8KyB<*lCIVfkyoM{*smx7Z(v`+n~up3>*~{>cr*ulu?ZFumnQ;(q+wPQO$--`uR_ zZ5#~}U$S6|`-0{~><;1&V7`@WFTKTnO8kVcDsUk27&=JW$KNk`H1P!WRcnVUiTn1; zX^`VW=irRi$Le_<@qLd{`~*Jt_r#xJd85DZ8KrX$>;FcU?*uM#b%=7+>i>S0_v03B zVtG54!TS9nmVc4+i#>PoueIOpJdAg1bz_$SmvOp*a&k}N*8-RK_3geN5cmD7uQ~eG z=*4^Uv&B9tqSzh+JZgO14qV#7&Y!5|kNyZ;>f`&ns{c#zT^DP`PiFbch<}Q9*%`!7 zd``Rog*OY+q$wuPKsZYj9|JdKE zyt4C@Ob)jIk7}PQfJ-}ENI%IO(wX+(if@IVNiLH!^~C*seEr0`AJXzi>MgdBxF6>^ z^>@lYEnm=rZ)W*9#P9i(0z<^xfJ;5?oD8eaCy4uT6!#Ffb6ZSqJWss$Yf89>^b@~V z`hHy2BI0&_)7jcRu}#E%J!IPRO6QxeDq)K0*jI=@+NA`neSS~;T*}GWtk3K}D4q15 z6)?T%Wa2MOQ92DQ|1siEa~ z(Ec_0*R%XA`rl@;{1%qq!U@gf&-284C4m?&3`2Jv_(!FGkLR!JCho_RuLZt0e;d5r z&+><}V7^xO)kI=c{Rt07dA0pmP zea!0f?meVF2gUZJe#PRk2T@-5$IfTilV7A?5`52?ox@@6vjMm~cZl=gQ7r#oz@yry z`eiL|=d4+o9^z?F?%hh<-HGfG zLE=Y}p{zYWPu%xczZZ<;`sEI#znag*x!A59wlY4%+F`+TeeTaFAL>|snD_~ltHv9@ zC;k!Yw{Kzjqjyp|{yv>Yi2o<|g?*0YKfkk<_xE8vN!-p6oW=4x!A~UZ-%3BsJBgnF z-0DWi-8xu)+Tq&2#wR}{egN7-u2%PdEY<+KPTI}RBYQLP9^k@1>v*n~&9ff>F7BL%*xk?R_sM{uIZN%?q1}`*HhI;MbG- zT#V<)W%K^O65qhMkp_KCY&WdSNckA&i$jPnA-et`UA^=u`+5&E@UCTDIY zep#o|dAoic`x9~B-=2nFSjLN;Pq|!w7P}X?JojtO3VeH-5^9G2B)Fe9<|^XHussjw za}PkjN_jhXct7IPu|OmE?VLBQ{1V`z?`@^NH;d)p4_w;c&h51McN6LO`5bN~{#(pf za#?%shILta?*3ORVdLk0iO-`xZ~S>aao=xzCviJ(*ZTM8z@|w&OP@Qn zSL*}w(_K4boJ)Otf1T`)75wewTbtJ|BEALkLoORHKPEmM`h{F(C!TPa(pkAs@k`ye zh#v-S?@q|wzF!7^mUJGb95DHLF7yMb=NvxQ&hwdlgyL6hRqDs{A#Wr8JI)I>9^Xe? z_)9M9um3~*BkUK`OBcLF=|6C*61Mh#KXHG3VJq=194}OZVtX8^bXqyTm>x0@xb)-o z=PCWy=`FU7`280s@J8a-kS17j5I>pxM#=QV(3( z+0XmBl=yLvC}C^Q3~@gW_D+Yh5`o*}EdPmaZGWS4=+XLIKW^t#;{JZ0>w(KWYv&-^ z`~H~ar{Aa#HT!fbkr?tNnH_ z=rKayU$;HW;rwynb}?}KZ2*ql;qX#B?&qX`0Oi|U{^+gHGot8h1TOX2Fh%Qc<9Fuq ziof953s)1LzEugIN&2r?d5)KZh_ArB67}4xfXj3JxYJ(|e;?(K(P@9H_LrTbevv&F zxX|h0{A=TPb(NO4^XaYp@_2N8^1y|T?}xvQ`13v5J~qD}g7=j2onAdZPyCm#`{mkQ ze-^u_TFbw1o8mT~{)G7XOD)7_uU0x7-m&|L`+9OyqtcnbM9Z6A@gw4X{Lf3oXG6Zq zW%A@hCq(nlRSrj7_Xk|@n9Vy60C)QT1xja@ejWQAaCt9(Kjxt)D(>gwJsG&YJ4v|P zT`ceKXTRnorE_SfKG(+4e-hvARi$!@5qq1K_xa&n#0LhIj_G^fBJSsl-sfbc^8nmiOiDp~>j?%{d(Q&X7KL zD(RdLT-w3Uqj)><=kM2o^I86<#QpqH@kL7K`K?;e#>D{f{i%TOPdb-d`TtR%o_IC- zPwMkI&YMlduOgmff7v*i0r@56H$9~VP0k-j++V*qkGSt|d5HK6v`3EMbEh^beSaPN zDB=%Ne>S^d4e{4JKD>(f%aos1|2>x~{hQf7hF?hh2HF=k)*dA8=jVUZGNrTRds^{o z*8gPUJ2z{;|10quiT6;?H~#z$aerUr>G-{yXFa?7eZU?6P|-Gh=}K1~S|kOP>9KdR z{Eg3PMc%{u{DS!V_SJgYy#Iye%KtO()PiTS{5~!E+#`FmytUgZ;(lI;D~SJ&kKCH{o>ULPm!uWSF6xY%uS+5GZwtJ3f9R@~;z!``8|A7|1|{38$Pi+*vc z-hV~>e)u`$TA^@kuQqKTKmSi0xb(}a$F*P^%dZA5atsQtL(H%Kh@-Cs+RZHmG&h*^A}qF64I$9{`CGze9-q=jB`a-B~R1SKz`Yvnls%-0cKCRq%T^YeCaL|AqK}AFI!`c9?O7 zmOr0#%-_{U{0`Vda#{Hsi2M7FKLv+?$eH^OREc_kK0fvn;IsI5@b(AbQcvGcek}OO z>6zqntIr^CDevcf{VH+4J=@={<@dcopPJ;u&nNEZ2Y!h7?X~*8HXogMrqY@5k`gd^ z_(kHrfBR+P{=T_`Qc7p!E#dauNZj{F{gSx&edW4QA0OMiO6mCe@P83M0Q0bP5Vff6vg;5p#ZFaG}hy}FbihP-*_1mH4$ zn?J8~60FZE;Eo?&r}ek>f{Tg!=Uf~Ixh&=Ve2@P|{2NDv+xhs6K6ke(^?|qO*Rj)q z3!UnN6j;FeOvU^pc<)@rpCbMp;(5*&rxO3%>ge(NJaD0N)gem9c9n%+bNR%!NvS7VGm0>G#gm@o4t-);^{G3F8=9uX-Kn+{*UsVEKkM(e3kY;PSqH{@Y&@fAZH#;H{ib_vqL1exBr5 zS1v!CAL;3t(-rH^dy{lhGVHzcQ&=UKiiq^Pj%N) zJ22Fr$!EIf)K|sh(S=eyeS>|ebS{@(pUMp8bL(S0x%5CL)jcvWupU1Nd`h8YK2)?f z)8C(6o6Yri&l&2R)72GAozb3ejyDeVWx6tJ`-U^AuI%7&J~z^p$5&@G#~V_q)%o6B zCf%J%cjfy=GpV7`WTL7RMaH#Mney(7n&MBggI$@{zSc#fqe*=}9@3YUy6VSxbsDwo zN~2j&`PB;6^{pPv<}&!u(g;$6BdM-+>zWgBG-ReHJ<^{~;U{ZSL)remuJuBbI@Zyj_tkR{UvoTz=Y?8Oo%=-HZA%{oV7lk5Pg4zOysi_&pkC z#b74evphY#W?Mz8*VuE$P`YtV$NHhn7z)N~*0f~vt?8~cneMR^PpoMg98LH46$>Zo zjT2MFVVFu}9NL_yX~F)tebe z54(2V)?<45`XOpK;`$&e(iqI{r`xDvbyeZ*=M4{IFfYsucjfwqME0!!jpS&uMg#-i zbsLo84fDFY1HW#9%*3x{pcut55UB|h2|T_AG6nCI@9T2%vk#qkHa=wsQ|ZBOyt|4= z`CQf47fUT}UNL`OGk!ACnQBU*r{Yz`?yZief?ZkCa;apjSa{Cr+)!6RE(gV&h~dn- zuHN+E>Wr&Jy1P5sx>6n=5{L0bDh07QfU1`%k*F=Dlp5|EgrH2emePZ$Ez&DrE>Ryr zwYzV4D4p->ji4)HJ3!YjStAWm6dsAhn)!W$BA;@(Y;IvDpYH1)UY3a#SIyNmPP`Nu z#0jXB40HW&c~eWI2pPjK=baY)%bKcfJab-K+q~1;o6bl^|Gv5|^7qZ@&P;zw|1V$b zG5oe{y%XDf?lx*(6JG?0uwqEY$8bvS1CZv+v)!5ShqBclGl8=2P(QXBY~w`|4X!Ed zO%^zQ(f`ZVz0z;WRhR4;^_*?guv(eSez~;WRgt%{b*%iWvb9vEihkBM>RB6Kp2_!S zyY0tK-I;-*Y(6vCwZ1ts3WhEL%2s|mNR@k|+WPU+<>Q;1Z&inEfa2uZC*P5El@b#{dOK-qWPG2)GA%v@etS5$y9&A4Na zh&M_Tihc!E08EtbPUq9;xJh~(M&4lGFlJ3KMr%uZs!rLZ!UHR6Aob*#`j*Vv_WVd^ zvTa#=K3+B4o6cprQ$zV&lk#f3ZUNMb!AyUXm^WNbBgu*o-n0PUp;d~uYQqjZY2U0Y z=qd5KHrn|xZA3N?CtJ~gRjGyo(}=#-p0Dr8=GLZj-A!%FmWPIAp|9FAxzRrKz#^?u zfdyJnpLn%=o5?N6qNCR3`HXlXsAnd@I8~|eC{M2FNVT<~@9T1zfh-JpydOLhP`R7h z7pIandDPfxCnyq6b&S9fk?MnL-PAk~Pc8*mV`_hQMtl@uiDFf+aXgkxCKtqAbG7Fi z2hwZcHINo=JF7Ektt~Zy*4Ultf*(T^YiaeNrjAq+J>=>lyw}uGRRoeN@cJv->q;bJ z_~jQQgvYB&N?8@rfZ*o>o3ox!Xd zYp3hn>eZRNHd(8ZEc_DuG1SGL)wu|bQPQe19bn{1^Hk?uC!n>qL)*0HYaQ6M zbm5RRO_KfA);@0{IK2*>4w0aY9vC#$gPFA$Hgw8h#Kfyc2K!*01_a1>-xKpqGTB&g zH#N1_rV3~MI(do%E1)HyA|Gf zB6I=A%jrQpBmps*g~KVEgUhHrpQuiW;4C1ifoykQPhUpdf7$`nHRZJsn_I%dBP^&E zRux{b3f40`kMeSEOvyX@QYfrx#jAB_ErCes&*YNH=FT{TQ9?;#>T4K)udr_*J=BCD zHeTLHw%4X0!1^=8!%g^8IL74JGWiNnGFjKviFshK@DhpC%1oE|GTm$76?S~=$gCvK zuEX8lEvPDb0x@0?h?spEyD*Sb;%aGX6Bq2#WOB3(upp_P{`6|h6FT;iEz3^nA5B)l zXRR;eHFdp+!WBd9nZfSmXp!{ljEPK;OU)ZxpAt=}QD)CBIEjXvTG9TEBHJ;U_hcdE zI#S#AZN=jq>CXNPMirdW_1T`D;Y?nARm(!J98hUxiiA!Gw^q0FEjl-et9-n6fx6f+ zX5KN98Og*OsMyVevktzjUd;RjUcm&_)(QELL4~0di9@>B-!@^WJW*{yWOwF0(%Q9d zSQo{0$zf1A-TYIDAZ(%YEjFzRLQR2o9UTIXu zicV7@b`0rb)lj}o9yAzFnc^MNH%%99kEifY6ojf&J2Zfaym0Wx8N zQI{82Zc>AoIGUD<`b08P&sNZ?wr6V*`E8;4VWvs2w^fw4Wx7VSw>^EwQ*rE9s-YHn z#N>c_%_|6m3nlpkt-?@QLDcjt_a~O5;Pm zr`W4Bo9Wnb_Wz0@ZB1#H1^wCKOlVyBEsZ`C&P1=lsas;M)zex_HV6E~DA^oX1WP27 zrUr!@zJdry#35e6N&`dCG-P!s)h|AqWFjFx+0rj64xV`Rioy2Yk$iV{?O@x;U=mAy zt;qtsxl(3wyZA8^A4tJQF9GfwR*km2<506Yh0h(mp0SrUkL@d3~^bwj~)Q4o>FY~ok zZJ~Jmib2;@^9n0_X!hWYKOk*Lu~(3=CNoO-Um7!t4LtiT(U4g;l*z%*Fqp?;dRly6 z&@br32n~RGT3-}Ls9L}_T{ceRw7SGNt$}e`KX!EZARhWa1SQp^JN(y6W%GZoF%iKEM9ukM@VzP6af!h zK(}=YzxV|s9Co4sRizr?W}tt;m8;f~W&R>4r`0L3vrFqYQ5-e_nxY9xXOoNI37O+# z6bn4&hB6oYl*>V}u+I z+Bz_BJdLsX zUoL~7p@DQ>RGLI}z$SA;W?p|^dN|Xa?AuO@%vqaofR);Ru4WZOR1$UN!%PCkbKz~u ztjx*W+^8BagmeX~#Ep9hjIdV$YkS3hj#m|Z%JKT*->vEfgrtL(RO+q{_j97wsWdR2 zOJYdeYk}>8Ol<64b{LMKCF{lF>+328QqUTL$(=KUu03Bj>YQ5>;}Z`0wM^S|B5d1k zz_M>o7ob?ky>KQb+vuAKPtE^8Qy(Ry*P|gFpfGjE8y3SXWB8u9OIBwFt>M6xBf|&= z(qKPT0_?l+%cCT?Ts(RC;<5;RNxmG2*Pb%CW)KFQ3zxtzYTDPPvHAf;wot3W=!zn2 zRoEtB7L|6aOI}_s6k2J)$SaU?3IpozHkHsI@vPDVe2tsX;;vJugf|1)B=M|)Ud7O zpP3AQP#NzUeLnusD7){Rfh0_L(670DUhbqljP5M}l(8KkaDe6om$agGTvOmC*k z1;Wk~SAK4FW>GFX;2f%;74%=QYi$v7M{KkOiLyg!{0lP}m(Xo7XgX5u(7VON0lS+X z6!K+g&<R8LeXTDM+e7WP{Ko@7+TLxpl(p&bt!N~ z+;e)xs}^VSE%1uN6Bb$@l`$P&GK5EXK6JIzKzb0%H?q2cc``GQ>KSYrcW6RwWM~4c z*RVkgjmfuY;lQrN^xP*A9?t!n&0(4jtRbyHgaXA^!DBT!t7&167^Jsbpz=pfoO(Ea5@l-xah6WT`~T(3KrEo4XOGE8y|4C7-B8H>;<;154Qba4VQp zh|+W;tPFcS7^^;Gh@pwFy*wkxrG&qDU`rL82tvykvJfT#urS6fyD+TQjD|- zj!e_0&40-7nutK0F>yO2UvQj3L0Kg0H1#R?pxPJ6Du)wfTE*~uz0K)TdeU1V4^G=< z1u;EXxkEh zMk`==q3#7yBeXrl3N~yi8lhn){8??|ix8{igb%)TaBgi3X*gwBvLILrt&pg;^-2r7 zVU$S|WC;`{QC`*YYItOG6r_lY<_k}b4hngD<5gHWvuGA|@OsNd@j8CpnwE`#SolaL zC2j+PB;Xp-MQV(wV6#{cMR>&+bp;>2TWpv3hI&~ROy@F5Y9xNsg*3&YhX5qT5^U-$ zCCDoB_1HoXJ$dK_RbY1I6lanoqzUS(mK#XHMhWstVTKG92=!TYqv_-(8-2f}1t@fC ztUvYZVHdFi1m?a8`DFS0% zz%CsK6J>Qxz&e3>6D$lXN*O_*giN_EqC%r+0%m(fZ(=;OtxmP7@|=L^`%F5gr6y-$ zz`m*FDFm3NT4aL_)J)waYmY>1p2aJ zh12OTGR;=?Sguhe;w1qHDJ&K0YnB}kz8REAoH96^?#Z;J*D@YJ9j-PuoM!I^;|@nG zs+mwS(t@hK#6N9wB#n1yI!}2yUxIuYtU)zu&;l(JaakIo<^I$VE%&EXF=@dEeltg! zJkpVsmav;vKpu7X4W>r09w4%aUZa8x`v;OFm4&Up>f!c;h`uVTQfTPN=8><)A9NyI z!eJ2%@zdF=4l8-sJY*w2V8D!qEf_cT1sowkv1J3)oAxV5Qf#YzoV%eAcoVPDHPj|< z5!P1X0;z0^*uHjg!!>9qL@lT|N#zz)Fd`@By&?F4svUbb}WtjjsSDoqOc(XM`iJHsI{4V1%Q$5GRf# z7}>Q5^?<%5({5=z!UQcaKv4;-FUTBa-k}|xrQ856DgqozMfE<3DH+>#!irKmqMTB) z(*zYkBmj1g7aPJNHB((^l5m5}iPwl2^Cyvl-1o(4{c>y)l2y|_@eVe~3bQG|sIhEU zYHDj;)EROLf=S^{5{+cJdM{I1#DO`-1Qt(Zkd^LqLY#vw4mFyk5#D4_1xXbiJ)XG* zletRwgmF1BDw4*6+ElG62Ex|P>&Cv=WNW=!Th0!(N=V$_aSXsI)9&`jZEI%!2hdE& zzwjaM_-Zf|7pMM3iR*FAiX>#JUpWtM8M|9&24#Wq?nQyaD-iSTLVJ>IAn!mhS2*+7B*-yrQsx3ktz6NQQ&75Xj%+nlt24EmcV3ZU-M;*P5#!4=T)1 zuG`&+q;nQc?uNcJTZs@8jdWQTN7ZW>BzhE4m}N z+*9(nf|C?`Uc1(%HU0}S7oqcW=VE`_y!lP3_?+rObMy~m@gys*BDhoowU7e7Kn}TV z;9cET+*`==f&Pz(d;^t{lCT5r#`7Od%XA3Kz3^&+TlUi6pM7e-} zEnd~`d{YatwMSVvyk!q5rv?ymW8rd5vXmEEK=-DK()DZnpu{0BLnjb91IIu1an#Fr zQr-@%Y7|Gvgv5@9%m=?W3eWN_>39vp=((tfA%;0?yratvt*o>-@P^q{RP%7V8F@ts8NOB1N0q<;0-XRANqIPOXf;@wXae3*IAQJ1RzY ze`e5sg7}>fv6atd*G~|$x|l3%G}O7J4XjFau%+@`GBLv>G{a!uY1hDz|H?WEY-g;a z1zY)!i3&k9rjHj`@*mBKF(EQaR&d2@T9d+Jq~xO5KK8|`aXWSm4XsbfUTbUt#ir-c z)-I=~D8;du!k%A0N~TJEU8V+V<)v8y%T!@aH2SHg#bpk`=38>dq($+@6Nn<|M>ZL_PO!gIGCatH64*A2SBu)<7_q&j@>WN9 zF2oUA*cb`1g^5$#7tMGi_Cl(-33yDkd5kkBl`)M~f=;6C-~{o`c-|pl4OoIMW=k^+ zj5}~^`*X@za)tJV#WIS>71wr@r?0ELm{ZoH?Cn&qYF=N z85!ura<~w$pzKm#;t!$Rnk_pi!n<99qDEv#stjs-L~%p5vT3~9<>;AU!@~_d2ykvw zLh1+K3MLk&Pws&@YfdN!zXJi8dzsJ zQV_32I=W7<4)T$fVd!$p#u7*`%x+7-p>2wZghYd48<^y}a~aoMZW1nhh395(k+YnS z6=ISjU2<(VIX5n>{q701mRtrHXDcxwlh0^o?@B1QdqF0bb-7L3U93&W`Yrc+Tc=g! zqi%6#5WD6iy_9a9!(5mOsih2i4hh+?iv_cCKp;cuDEDYt%ZrHCD=9B)qNRJd;)#`M zr0>W}W|r!N#mM^4D$XK}=J>JT)tJ(H zs|&d)Y)Qu!UR`yA!v`5gQ!WD-9FtrS{h^RbCaB^zQ zA*~R9XOyYL{>Trxq!U#LY8-akQCu=02uR7T=B&i%kPBat49hs<2dDX16sJ?0p^E+A zvJ*lY90D}6I)~}e1$w2Sxpg{ayt1lWRouFpNEGIZ;D$b|9l+X*+Cfxk^HPyc(<&jZ=kk{>3=Yf6_X75XS6w_vPRR=dsW@rO!5m#A9UH{6AcqT!yT8KaSZ zWi}zXHGk~HlCOPZBo&xM9YV{k4pnC)5*Vv+{29v2K}B^Tu(44l+V8`kil85*t#scZA2oi9JFK z#_{T=;eyqJ1Q8TaVAn}Co*~$l!^~s2G(0cRu8Jz4MHNVJf(8waX^+H?1WQ)1OyYI6 zd&>@2ajgXDGXAB*ZTP*aim6qKYSDNXb@5BtVIR^&HCb-h(hU0OxaPi~u;yN}C>+uO z<8@}o$qKQ{=H?j3mx+ZTUUcEaYdsf^Q~e=NgB)*b5Ki<(rL3WPQ*m+|+rqyrQpMvU znl*V=pea~>kM0d$+P1-U4S9IeY<;*o-j zr?~&fGSSi|Db0CbQ4tfDk#idjaW4YMSJHUK&J^`IbV1G-2w6Je7xmMZc6WQ?=2W2vZUggLLQ zK!XFKGyo}baes1JZZcY@Qg4)PIXNZ>Ic~6DqnOyqi^Fv-5R91vQ(?VBL&(sMQ6?Oe zcqr;PHv_SA-AF+R_v`SslCm=RbOI@EceZ=sr>M!h{N&n^#dPe_YC9b&tnLM;`Gjnb zk%G-x%c<=e*hB-IV{RVTRxe$oE~CGfS`20$i!>fXY;c&*BlL3J6kW1pWYMt56AA^r z4O^8XEZ{ml)~u;dLiya{y5Ev!wA)Dj-w=-Vw#eb44CQnMH=DYap#E#;Dhy~&n9v%8 zh>&pJ5S6w_w(6XMJ;**mCMt%y>9S5iDXWnbQ#G2Y(h4CaXwPfRELeS z8F{R2*;zqns@W_>LE_nlQTvI;=zkH$4UEe`QU?2??5kCeJ1?c8tYA*& z*4Dv{NO|24QgJ(QqP|i}ykN5x*sOvBBzm2)eB(Bn88k@?Vb(=~$mEGoZ-Y7gYKyr` zAyaUYh~{+*#-mv{&bH4+!su~6>FtdclNFeya0Q^}+vmeDLrh{`4yI(C5NwJKPB7Gv z`9M<6uYku(lI3gkLzs`nUe#6V<>{enoXw08wD8n9_~jgU;?}K8!3{T@m6+iC`qXF@ zgs<$;uvMMm^*9`QKv#A8!jrKa0xeO)(W=Kd&6i}chgHN-o(4AwIDfFW2dt2C9~GI5 zfJSsdY7LI_EEgysO;CAU#)rEk=XXyQ(?4Q1?BHB&yP`OSpF3*S_JIhS ziTFubf2?$0STBj#V^(T$IYUzv4HqyMl>SBGQpQV4L2WMS3E4OZ89Zr0f+f3%#_NT0 z9zJ9Uz+naM2*!c%C~}84A<>LzA7eWCMi|G9@K6Ya?!b=HHKaTmXuQ>~(VbI~l^vrG z-;+b$96ugEeyNgY;v!0uOLVZ_wHkG~U z)yOO!onGD26h&nz8s{RbRV85CVp#g;-ys=&#RKr77C1RhwzVi+LG5W+U=xBn z1XdN|x~iZw{FquOont(0V3J%pNbMBd-c*159twO_=&J!XT zCCO;;n6N^+QMyyn_PyC|%Q>r!5s}2T5WHIOD@M*-WnUwi3`|**<5`4UnJ0U=9Q)zb z?U-~(oC$G4xbX%FE^XuqQgP^o8ZtT+oh^pK`WQo);dUhhM&%$-ZQodUn`=NZrfWy07q_h_xr0jDfq{Q)X&37zpDpj zU!7%h-@XJt+!-7k3PAxAuN~0Sc(JF`9X#U&83eZGm)L)%iTZC=0hvCH=oF`djojKID_Z&QTGI^*mLpm&8#6KfOm)$ab3IaS1ob zA*dC{#4`DrHflw2IZi*Fx;@LeAw^LPYR6;CAzjBaebstFZnKGqBX9|R=vAL2>qXq8 zg)v`#;045a9r{Ldu-i$hlFDr&Ue~2+NP0d4So{tjZG*cln<7;F!z}!6 z$W>DMj3`?Rt6HOdT{x~;Y*(K7NgW`>xR4+&dx5(1WmEC?`mQu!43#{s{+%!f*VKv6Wgfl*neA zAwBrPnT5qo%JOE>TfIWMP-q?qI1JVHAA|k!4=^FeYlJ7VBY8Pg3a54_TLTfEzE!Er zPYMH39pO%OZ})f0E6QCShv$Vt3HI0_12*}(EPNt)iw>TC|lI4kUU zsxK)ntg3;A71*!XhZ8=N{lhGSTTh``w_{@PrmN_{{_unsY;V(Qww0f6J10BekSO%x zB-uu05mgA;+V<*3NF^*W)6rdW?6TO9<=?J+ULMF)r#J>yQ_9MVF0e#gl8Tz<-IY`U z1lO)QeS7;5yvvskck*@*^Bqxa#t@=Ec6n2X(hu@$(Ai?UXZ&u6*AzAV)@-&vQDe3x zi~yHK3KFXud!-~p-Kg8aqFRPOP1LsbkKl|`^jE6DxaFKHZuF*hWcMdl_3Ls-h>#uN z7S5uG#e63G7Ho*nz}1Nw@+0UE)^{omI&>~ozs-v8SKXHB>BoWhNNkF&WVP-jL8n+D z@nj)?AO`?mda}*K2AZGHVPO!u{aArD>pCo|YUVmP+y>wV3LFEb?;mh>C7op%3>5OF zQ&VFCAye4A0&|(~9bVt?mRr5lVjU^b!4u9`wqi(Hb2!46?U`j(fk0f5_soEH2FoIt zN1`N*XZsu*U?r}|hJ(sWcY=i_jQ1v{nMmvT>zz_Dd(%Mc>f2041X`u3zMNagq)&H$ zYk2pd3`Fh2R!xbp%{`@rasI|wFrHGnhfvp{3L6Pa;`WS-%B-40{P<~LA}Uil<1EDw z%NX_LGs4sbGr|O;TqWWs-PHwuzoetz{;-Z6Ib1y1){%0I{f}#rJ8tvz)wozs^vgjuzSzu%$z)9CV zihGJBA(-_8_7IpC3jy0U;ny={>$s+M^ z&hM_X@-loDD4DE75*=hMlw?Od)(l6Ii$^hPX9r$GcUi&TRgsBYpI2b<9nWZ?ydAF! zBrS3te@k3cBFI7sa}u?M5dV&>EJevep_e%^dV`z1SwIBf9Vh5r(6G)WTzVp#>_`s@ zj>z>H?&q9o@ zt6NBXtH`X-6^&k3j4wHO$SGZzSv}R)1mE9Li7%fF*B|v|J0f1|Oc&$@2P<^rfZ>9z zTzOR*O=K-q@Bs-EM{$lOr}m-x)O+}4W_X$@8=ahsRh z>B2d!jBkFdzBVo|N(YCRgfQJZ4cs4L1u>C`BSLO4jdd&Nn+TClWjoJ;p9OJFNaWpU zE-H%(p6C?d5`Q1zO%HABPsjmf^WEV#E?4_P?D+5N9}dMZQRWsSyYb#)KcqDEv}T|4 zkD3au49gm@%wS<{vAE0O6gg$b1%zOY-t&Hhf`i~MK)_(gAtH4Vv!m4Mr73?K3lXbY zF1)NL=5{p_Q)87TXrqjRqJ;!l;Iyy1)?qg;;>(h4VAHPBw<}%2x0%HGb44!>akfwZ zhfTU~t#Gs@2AA$FDyxV@WesewP*1d`@i((&>qJt1`82mVNPYh*aR3dw)IaBFA2K|N)}TiO>(ebLl9@Hl>hoZh>I+T?b;R7CmN8-%7SGj$B-WrV6=^U>5k3vBs~) zUc3P*F*~yPbiYhU!_9pIeR@qA_8@C&Q##n;Ab@I*tNSXIg1lu$5#%O^&tw-8$9JSVS0rH*Q-N~TtZ zSF{6+-v3 z@JuxbL^qavjqp)G$?8HJYWUqk>O#C4Drq3+tvb0UPX>Auif7u}dPKzh;#RLrq|5iV zR_fO1Dy=|G#)?c{!_0xN6dpDKV*#NXMW!^(PmbF@t4-Q&O1& zx4ltWnv63#tKGzodgLdQUDLswSi!{9&VtYrJlCZV0;|Fa;7Tm>^*lB-O3c z5@NQ75%U&4Sv}NDp+RUWZut^2KU#3L`EnxElpq1?t;&%{V$m^7%Zd;s`$3n@wN zu{6@bGGcXB?QrGH&ztbkS^G`D5c^(Wy9 za|MI_nLr>!QNP*F(1%8FgYGjj@ibloScWGY&x7i`(^J0T9j=#@npIp;E{WLUj=NA8 zP;F0tdbOVN2(@S!8NeiNz$VKQK947YM;2FOZ%qcr1&i60hy!&euohmb55$@zQK;~aeXE`=d5-%k znXJ{rT}KQ18s?|kn_aizXCY_G_VbJ!xuHB0l&Rry(;!nItgP+b-5`us(MsI$cabSP zSy=U!6d;8JMWF#VN0SqgTf&BRyuJ&&Idc%Q5T(feIGW+krOINVCcNRvaeard!{2|F z@z}yCSaNiB(eoQp>%zSr;q`@QdxxC99oT0EgT-@0dS1w70ak(N7|iAdkOjk{+GPY! z0PhRG6h(o^7T8KyJ;olQ;)<+45td!Tvq%sTyJpfxh8Yy>Hw`L~R|(p0s8zv!V;F)| zG?aOw%R4bq+QYY_@gwT9!N#lh9)lVCYswA5)06Ob0DY+9d%= z@J2^CzGP-EnZtnv6-Qkv2yjiQ8)||C3}#rF9}zw0vqn%y5+;BiFq*{-uqp2|ze&O?5P&$W)WMCdi#3f#P zp2g}m!Tv}Og2|jkG>M|Zd_G~(TPF8Tq({t*n_$;Ndz&PyMg7i^Rtvt0uv*}&UL=!C zNznNua!N&Qz*m<{D^o@ehq;OVl`L+J8Nfa!8KSPUOqsDM(Sh-X#c&Ze_jTqZx3>os&BHjb+pxuLrk#Vy5aVEmBs$) z&7>uha-BNV%JE_3d9~%4-rGZh>Am^MIlCtS>?Ugq@ zRM?=mOm^tOoCu3bJ+wWvMK9c3#b}74mvKAdOL++29rGcr@~GL zsE8B9J2sU40Ti55#%Ru#9t>?c35x;6wa`%dG%KOSc1Ne>@!7AeEFv3vsc=HxI!N!}%uC=XvJYgqZ=0ta`5aKPyP@1!^X*VH##?!sIuTBg zu&D78%y_BWT%E-G|KKoca_^dF&;J$B{Th?Jev5hpD9eTUr!MFj9itF7V!idu)+cKxH`PW|bo;H0QGSl24no{taBIR1DpCoRe- zZ^09hT~b?|jO>Paz<_fb*b8swHWau8wMw%&<{Zy*)4i3bhD!l7e#UY7e%T$g!RmHa zsus zXu=l=mgx$Cga%e4vL(H~Q=%QPNSMmzQk`xuc&d=EDb!n%1tF-@nG2{OVxf@iKm@c* zDcnaMnltnq<4K$|T!4=_D<%3t)wc1A9np`X%#x@Eb5m&4{%U_R*+zR;;-io^aKZ!} z&Thvxm7+5|Iz}X{H#w&S{8@oi=Ary>;nJpMMeMlpv@CgcsexX$y(>8Q&9(1|?TK26 zth8!48LO0KR&>Uch+n1i>eTA~z9Bc{N({8(v>#8d8^W&YzI;Cd3>YSl&AQv;X-gJz zO_$7lqN9y*8?a<{wIGz%MV-jnU5r73T`eKM*dnn!J(ymN!(+0A!@4FfNM-v&>&wrF zJlZI*wzr+rpeSDmVyIo-w>szc?X-9GW(Lym6nkn}>$0<)Xm2Rk_pMqYUXvUg87S5S zOWRJNi`$eC_$naY3oJBIBWyB8QKeB^c7(Yh6A1dL6zlAUS~$u_l!s6#bIE8ZG+jK7 z!+F#hkjWvs2C2x;h=@;ak~)TBk(s+r!K=~{!B%E2Upvs_$Du(Dx4NIYSuhRJr8(4w_1k73sl zyee|?RBdNwb>EmMiEyBW9eRbF@bb)=H< z=w$zzGd2@~ z&g8L~Uqv$IGCBocGTha$b0hOGRnT)ngD3E8$&n=6WAF#2lJiezaFs5v7uR^lR?2D|@}C5Ewwxue?NcamuHn31S!P^B zajU)V|0>cfF%>5~RfSUSVP!y_L*UlHPVJvP ztifSTd;&J$2SZHw?nV1+)Els2Uy_6~Ow!H(2o90yQTv&lOexvVydc%ST%%_FUbY1d zmzAb?P6h=*Xy}gLWfYja#+64WkPQXz8Ra1K_^(6}koJiTcC_>qB1$JDZdE00A%*dH z7yJu+zQe9HGb#KYE>6-_Mfs5^45mylz_Ad0rO72r1V_>ZWl7tGj25pq#uzhVvJ;yX zMuzj*fh7p<&g4{qbyI&tOhI8GlbU=(X;g?Tc1()n+hRh30U%-5+Wqd-b!;XW zg4Ye33WP6Q+@Nem49DGsLLLKYShpu(OL0tyzsVm*CMiW5gdd_9-I>(A4&gyi%*zT^ zMl*=>q8@Q89XR^LDSBb%2E~YInW)Kpve`kZE2|vbN}~*3>vC;0m02FC?4Lm57kBhS zZK}C5F2>^D&b;3UHyg4^WFLGOwUk5zP;*ca0Ua!h$0^G8xzZ*WIDk&1f`=UO+;6br8pOu_&9Z|H)MncipI4@ znBRUFPiA;EGohF~$2!QcoEirNmi+ac_F|wux4Q3gy0SlK#1cC3}RKODs^-( za{1>&m}3>uq;qfXzz9)ZI@~M~2;s9CFa@BA^$BmV0I>7gvkOgzrE9Wao^6qG6&KvV zJQSP?u}H`*Px>q>G`}q|QmuaS$YXpWZTPU>9yV)KoeQTRHOg{Y5RK~Q>CWxbQ=*Rp z=8GK>hVY^{I&KcO08JwRGSgk*YcK;5UkS37dQ`%$P+^Rp4ILjssSY9yLl!`52>J(* z8Y-#+O{Lx1Z`2yY6VBbm^{Q2Ey*AWM!JhY#XLVNjJ@TWOA3D( z7kd|1igMvnIh=P_vrmaN-g2Q9UT1+Pl~1epK@nw*jqtVRuVG%hF%z!1O-{PJe3u(F zQrm>afk(J78}YeMDanIwkE@sSaJ|!+fuz>SH)Yl?$b&2??m-bQ!Na%s&oxWg@;uzc z>S$>NPWSf+EJLka;(Ci}O(m;S#IT$hN zQKd0*e{Oh~A6M<*$(kXMBfUSmDpdklnVEJx2IezK3A4_95)X=0El9~8)xZX9#1ts? z$ML5ws(q#LkSnYg+a?iEZ~YECDQ`8~#M0h8VEvW>t%X_4mGwhZ>J{QU6nP!hIfqP^ zuzW3)#}q#Y#TK#y)dIrjffRDncu*0JG55QpZgWm#aJ+)=lh-u#&_KV*LLB}QQJhyB z1FcfLAiDmzy{qPd>I;d|9}?~W^oOlEQsNRMX+B39382Mj`&cxPnN^#^+ITVUyHW;I3aR?St=x}8`OH6^uSCPuVBI(p+O@&<*Q(+?7NCf}( zN_mE;NfT%O8edy=O!eGMNKdqR_I@Gl zS$?yeeD4JUlU%eaU4P% zxF5uWrG^fFx6>4DXm&0ut1W95@LaPL}UgBo519*I2n@hO>wd*yuwgV zbhHA(V>E_n%!ZH6-l41hP?63Uj2i0pI`i@m8DeXsRxHpp%16?ok_KxOLFW*j1j6%= z=fpzRci(FD8KfhTwIr}+LjdT}(B!d(*=v30Q)M4mAHK;Cq*dPq5$4o0a=r2Sw;Fcc zG6ifUg{|m@5ipxPoBc*BF6 z)J?zI?DR)xL5$|S5@Q9~`V@SjzHs8XxsNi}V4M6lpzVt(7YWorOPJ77Dt0upB}7jC zyS=SGJn!Q<;bo3F&b6YXhAFxNPBc`thy4L=3^tk1>y!U~hd*~IPt@uaP$@PWCxhlq zfN#6aHux0}0D}jBR4Rsq^VzJoV_MFcjX&u`OU1+BK;Jk;bPMQdhKG3pvB=wNWzfQr zIVw+l(RaC;iiu!Z}N1lB2*|PSNwi+H6%!gFzeE_#j5KF zSHWkn(?ks-L?R_33I738Rx1&ZfA~PaO+A@&@;}7g;|MtkFRoIgQNoM7%i%?yhVK2S zVl-KPN|J^rdz8B1ItV9OQD-nYXxSovh1Gj}%m7c%H&Bj|Qo8F4DT+YA{3GN{@Ab7d zLQkYO^p;Rnn32jW3pSeEbvnhkgi0LBwzx=SF2lcGql!pYS3*fy&b0!(mnf#WP%wJ8 zvdp2zA=M4$IcFoBID6<)3Z-4>bnEpt z+1+OZu4x{4scxRy&UfuQ|I{%^DIrvbCeX^^yMp50283dhzXp#7xw9~lMZo2oP;l1`kCX;ktXr) z)y)%*yUL1zqZoB0)01|P@i{~V5L-w3HX@>Awr$@=R>d@yVRnIbqRwj}zA*ks^)04X zhqZ))ZTWg2iY({J?I;%q>D9NoJn&|56S5wFYs+7==f_`|Rf-@um?4qMV9JG)o&;^U zzQMVJ6)Xi+c60JB1nCfS4iPySd^m7RKdSGyPAgUD%cq_5_+>ZusP@jlOg@yBZTGs( zJ*tFg#X*tQ?+YL&96}HkEFQ?uPY7;1A6H0eE!6uXNp9O#s(ZbRC0JO)_#sbwy+n*R z`}O+cEC(D1u4lG#2%m=@r@9ihyIqAq^k^E(7KSQnmo9x{phG1QDHOz6H#+PZM=t(g}86dtjo+?&_Fh=cI4hwFhBLr9I|gQEM;|D_WJu3$0A! zHzK9LFm16#;Fgg{-EA?_J)|~@0w_h6YT}V5Muhq)$Z}h7bOa<0dG;BdJ(TaE{Ss(H z8(?uZz%(B9qBkKO#Nu8-xbJgmz#4w{JPob94 zLlQv9#!jc>O&#`WXDIH&R+sRs-V&p;n8$UBPK+cbq_`cNZd%s*EkJ==3}ZCX<9u|* zm=BfoV?14ZS_Oivqe3kn!Ex_^SGi33#ny7+1FbBB1Nf+WufNw@%Lp>1l=|lD$u81M z*qCd*&zqYSp2=<%_uX42kqbMx3w*y^ga2+g8k{sn^F#W-%Bdr#Fo+0rW0G#5#V(#X zb4a|4&I%p6G8IfXUtUcErlan3#k{{b2i9w@BCG3MC^C|v$E(*5PPqUd&%dyV#|Waw zB?&uCK)=hmkLUSh;krz&!8{b_RCEO+3OPQ$A1_gICG3rCN(XhLDp&4xhxNlIm5329 zF|64s1ZHN&PN~>--v&LC3OpZ4J65tqAOcbA0ZE&>uJdSgh3v{MioHV^%KQulYmA(z zOj`og#7AM(aoO2ja84?%Wwj(q&QN+*HIVnn+S`XBX zWtLy)Yn~F}n_6@Lc|5UyW`z(48$7)+=D|U8(rs`$3AxUZRdeAN6 zNpUB;Yqq8DPE#c$afJLmf|UzG%#r2282&VfFR`x>twz#Fr{3xs3oHYM&LZtEC-a;U zLGo87@gI5K!i}4oRSYDb7a=e#%)?1k`Bi~PL($779V1mJ3$>o}fb($IDYlv{b!fWS z1?w_4`f8UgKmDjEyoxM_EW8>D)uhs2wGw(j;2f$~i?M<%HaBkUXou^mfXI3u+=Otc z;5lY26+~sv@$ejkxW>Z$kGjTxJA5IYnk7XR&9xP@nYed{$p9Qv1&;C6_n?gWBsqf z-9#1Mk_K5i>AbqkhUpu1@EHR~pn&lQmMbk#VaLN22Rb#n!dbdf9+Y5c7di7epc7l? zf~{RdhD}ifJvaNtEc0qQPw5ZAgQTcuUd%JKoI|eBk`WcOvmh%P9IC@je_50$tkgP5 z&78y03=NV{*B0ZtFm`!xUUD`)Dy*wz`9%qKt!g zoW{E0IG`ct^>4`mVG>|+dYU;MiWFO|Z0->!EjYgSbq4-xBQ@(QxcLgV6&5g2a%*tW(oClQ;~Id?r>v12xp}f3&3wSua&ZB zRa?X=n!i#SfVQh7`bN0o18*rlFg<3n6)sqOtp+Ok_kzk>lmaJGb-5{Rn|K z>LM80%8;T7Y0Z5;r9CKMOzLnN_w#!N{yeWo!%<@Kpk_r|wtbA8 z4&%pOd5|7ow4`CQkw5 z5d}=v!5AgzE3E4t%Pgr69@>lUK3fA)!kPSdMQ+;Im4gP>i>-0S{6&F+@vkAXldgn? ze1Zya=qi_E`5QcsJ;m$_RWn%hzvgzA~yG znRiFslk)yat9|fF>!4JocgOYNajAT8*2VE;I~vG0s1QXieD6&S-wm4WIyEqR{r0F- z2G9=wv0FasVTZWQN@a%Ml?OedqAQh~$F;)&3U}3x4{#8Dhod(dHIo*D`v7X34_2#F z7*CF&`*a*SI}XWLTJN+PXx|&riSY@a24wT4GT1GtELLguzwh7>pTX<1=1^;9N4MV% zPC>tQ|6azMFXE-`_souNm)sv?|C!)@1@GPVBhy~D-w%Etw!ek%|MT(3Jw5+pv!mN* zOoPvx<9sPN-d()^GG5yL$rt1Yy50V!yr+-p-nISn@^R@6Y(IyWw*Sy{m~Nk5Ha|3* zu>XF7&p&pq|ATG$p>F?S8tC=wd35_0e*Ryl{kuETUbj!=ZHca*u2Zkyd|dh|cBqT= zc-y=3jcy;C`_c1jd%gc(n)WxOS?OOr+0pGa(}3E48?UhaZ}1u2qUrY14=ZuNRiGkg8|`5%JzPfdH>{^BET zDO)|ie)>+({-7@pT({5a56w2b|38}c`uu)w+UxdrG{K#}C1;;@|AZHvQQLpx*K&T{ z-U%K+c>X^J?eD)M?RER^ef+@r(|*&B{)!#<{Fk1QE79$J9T=uTc>cfR^RM7VW1IdS zUwX-GzSr%)@daJKwtwHWf8Vr!@|?Dm z?UMhN8|&PpukODf*MI*7IsY};*!iL7)p7I~ZQS!ec~ROwc~KhPr-M3w+FrNMqOse) zv?T3IOVa*tvav_dcDns~(EjO5(*Eg7((p~&Qg-yZ_2cK!o{pvcckN|qzxJ}U|9~#e z`CD@KY4-(l{^j6vZJ)P(>0xOrXYvp5raAvLGoQbQum6IV-uLt7=QKa{+RaD2dHh6< d`es|tB;We)N~N#mwEyrq8R +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class CustomHeaderClient { + public: + CustomHeaderClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + HelloRequest request; + request.set_name(user); + + // Container for the data we expect from the server. + HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + + // Setting custom metadata to be sent to the server + context.AddMetadata("custom-header", "Custom Value"); + + // Setting custom binary metadata + char bytes[8] = {'\0', '\1', '\2', '\3', + '\4', '\5', '\6', '\7'}; + context.AddMetadata("custom-bin", grpc::string(bytes, 8)); + + // The actual RPC. + Status status = stub_->SayHello(&context, request, &reply); + + // Act upon its status. + if (status.ok()) { + std::cout << "Client received initial metadata from server: " << context.GetServerInitialMetadata().find("custom-server-metadata")->second << std::endl; + std::cout << "Client received trailing metadata from server: " << context.GetServerTrailingMetadata().find("custom-trailing-metadata")->second << std::endl; + return reply.message(); + } else { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + return "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // 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()). + CustomHeaderClient greeter(grpc::CreateChannel( + "localhost:50051", grpc::InsecureChannelCredentials())); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Client received message: " << reply << std::endl; + return 0; +} diff --git a/examples/cpp/metadata/greeter_client.o b/examples/cpp/metadata/greeter_client.o new file mode 100644 index 0000000000000000000000000000000000000000..483cb0741cf7ac3f32e14729cb8280d97346ecfc GIT binary patch literal 101304 zcmc(I34B$>_5TgeXmBG|RNU$#qT&K1AwY0zSf0K>z?6XE`UuH`M6xw`!QfJ{0VRc4 zs%UYk#i}iBZA)9UxJTtjwY4p^v_ryKID)x^pwYL1vnK|d)bMKwWdygdk<^!2~ zzjL-Zv);M)&D93xIp6W_7(De@~-T?8B;Qx>5{wEM`r0Yi@ew40%3h^eoehlKr z;r|ox|4G80g7|6p{|x-^f&b{IXDNOT;^*mlGsOQx*IOX|8T@~N?q7uX=kWg*bpH~> zzohG5LHujF-U{(===x=de@oZfApRX){{iCdbo~m%uhR7&A%2anUx)Y&x_%Sl9d!LC zi2qF2Z$bPvUB5%|yAc0{u6IKGSGs-=;$3w8KE(e^*MEcf1G?T#@rM-u9pe8-*Lx`b z2;zUx^*<@zOYy%T{+O=+4e=**{U3<`OV|4##sa`Hz=}JFt|Jg1K-akt9|->sg8zAh z4Tkt&x;_NrL+Sc3h!3ahArR-&^$`$%hOUpKcqqk3QG7JS$I$gKh>xY~<0w8J;uGll zM2J62*C$aNrFb~R1$2Ef#3ShX6o^ly>(d~{<_rIv(^mOJesb@P+SOc z5nUHUJeICYARb58;~}0v*QF3or0cUOK8NCSAwG|;&xiPPbX^AVB)Xmq@f5nA3UQ3C zFQE8BisKZQQ#_60=@eH$JcF)hLVOWjS5o|Wif2JwMc1<-oy1oqJ z%jx_-cw5LEJ#sjSx4{bu+~+ z5PyNLTOn?v>lDQ8biEkjYv{Uz;w2DYOV`&?d_BZB!2d78{~HPW62zVGe@?vXoyQ?| z;wy9EuM=P1)1HeRoipUo=dOGnljB`C?CombvvSU!_{!Mc-9w(u@7iii$;n^s;yb(A z-v;uXE1j;`C+Z@9W$f*o=kT%%EWdivfC3TQ5Wmv5FWS7I7s&tF?@(_)YKQK+yG61%UCc zN6Ikjj%`5g=qtGXn|D3uZ*boe?;fX;Jd$pjG)8By>p2jrSh}{vyZ)d+ z90?)g1hXHsYR_VjtdqL7{}ty3@vi3~yKeq=MKs`Mk^ys0ySB49&F1E4*QpBd8AGD1 z7R80Mn>J(lUQU$~s!Z1npLDhF?Y!ZWoc7|IZrHmI#+UZfC1 z8rhz~*0u9N@V8gx<6Z5$q0aBV5~m2hFi6}jY;CC-)t0JGwYQC`O{S{r8`?(AuWxe3 zw70d6X=tvgZWvSFRMXI2n;e6rEiGf}8(SL2)HK&77bcs=)HKv5n^K9I=B8A#BQ?6t zsc))J)mJwp8bMZVb*ehinyg9IFHY7bw9@>;bquE72vut)IDBkc;CLFH%2-5 z-(*j7^TLMYn3mS&RP+4y1!JmPlTFoasn+_Yg5p>Cpv{uVn4nQMPVzbwhhH zI{duo%sCYmXGekd0Qg@PJt-fr(V3rt|3}hw1Y%4_oUh^1K|kU>2J>~kGo`&P)!Z1p z7!^7->Sk13vbr|e%6I5(7_*ckqwFoVG|GOAE@%ZYZOPWf$yP9!BN3Jm;vIP}kg+I(uAU;kY8_n&#Gq+K|zW$+ouYg-LYi{OY#)nuIQm zv(HY0w5d52g;J=m1)F8y!2oLR-j$BmR<}bi-@nx*X$TU8)0dcc`&wUYU0Wm#T4hljw<_oI+25YWB@K*vLh(9pGg z*O`_9!!tv4>z$k9(5LU)mouay_l_JVk-IF%`ECwObX2wTS0um4h>`qSAn(#@8> z&*OWyo=SRlfu@am{;vc7uLV2T4tdmB)-z=JW-K$f-QwiLe->jKfC4LFZ0C^92Zz)7`AuBhmbJ{Ni?`(Js=kt`Er*Rx(`<}oq z04ajgOXYiL1g`F7e@q>!2r28&M1fQLTQ$ygah%Ih39O8P8N+s!ly_|o@>O*0VC9g? z90G+htGs;D6{?*LoiOH}9OpV{Vcj{okL5TUbB?FRCZ=%rHd(hJ}v?1Z2>p=aDu2J4}<&Uq7B8NlxNp{aBay6ZUIWxB;EC%&DVOLY&K zH$J!Axr(|*terQ#zZ5E7yz8kIpQvY^r7F6k1EcQc8~%$Rbd}mv}O4pA&P8S{u)FFY+3#~M7dj*zX8#KTb92G(Lvy` zgx`L3+x-ZNgTz9W_?yS`L{o<{yv57#oLhiw9+Cw;bBAK??$(Kh+^PgOKT;^^b<0B; z#gr?T>msMruAhMctChKrs8a3j-k=KV4lLC2uHEsj|9a+XN)iP_)G}POV$(%mpdZ_0 zwZKlMJGPo>*&2kpwp4Weg}R8?3ZPoyD#TGh^k-c#0o3am-UBO3%s_jncU8~&Qu}() zzCJtc{au1WgP661_uhC=1SdnsDcsQf|_Z0{kz#8zO@B!0);a* zvMr!a&i1G>keOh$EJVzNuWkD}jKAV4sxEm)ReW8=_<`Nu(tXX5No1S+>rJZBz`BBN zA7l})B#1WTtL`jH*7;o%gR{$_8gQM%T-x7$yQKqMI^hMzRI_2fiPa!L>kf8)eb90L9qinhm;052ojnIr{|pOgD!#Mzf~-1>-fTck=+A3EYV$EnP{ z#A#6NeBV8%y>l1LV8}69G^Qk!}Rn@ zcpQ-IJJp=0YYwo(v=2L+=oXUq$rfu$~AGwBrE}R>)2guoOO*5?x zD0+BYv++{xHm*_tFFdz-y``rwswSj9f1+jDI?$${uU)U`Wd<}H{G*pe74gqhUBjAf zt4}o3r31b#_vvoIOIN zWuI^_0T09hU!sc69`Km1ww^htT$tqDb-rH)HoPFFvM{4_M?b9aIGdFS&UJCYW)4hp zv9Wo?E5+aiQxklaT?tw1o&i~ly-?l-a{lF+#y-dg{klA%*Lxbq9(PLFxi<$^q~H;A zhVmV_SwC2U{ch)@0@qbs*2D8#^4fkA3a04N!>K2tm7!)Y1_Y zZRc|!$#q1KS26fXgr(Y3e9uZsWoOSYHjeH=r`ywkN%~sk&hxB+&QRMsZ`kd?11hey zc*1&bE!>N3SDi0*xU34MLB889;Qy@}@~t*?;gXx=!>$f$j{lizSx@_^&?#d@g6c=P z?!wBsRm?G=svItb?K(iwi{8=gztHpHmeTotVIN!MFn=qx1Ga~Cu{-Tc58Zmm=P4XqhM^Ybkua{q;G&ey{Q-|vCvfI`+S0po|0YPfvN#xJaj0kdbndQ z5JD}2TBDzxRh{*6xLcHfG0)!0kIq}yoJ}wb*ig|0&l8L)K!KOtiLp(oQpyhy zYWwgRX(hf(jQv3rN=4V7{WSmxk2Q8VC{SA=?R&%X9STHG3F=ucqnTKD7Jhxbz7x&DA@Fj2!w z+%=;I{JYgj&84;tFqbw?xS)2(^(MXEcpM}E9p)TkrjKpi^^*{CKX?P2hZ8yJ4PQOs zw*_jB1uOX7SnnmZyKd~&sJ(g|*p0)=#OKs&livLr&bu%kx~(IW>F2~=Nck!Vq`-oq zcsu7#pglWz`O10a{)Ph07t6EZ(Rd?7dl^Qm{^nocpFw{@Sj*p=-d?a>hwLsUC}T z6?Y#Du+nUKrVQq%xUx=nbabHI}c`K%wZ|KB1RZ8&!)R zs)7a!#8!;yC%LN9=?W6;u-w83I@ZmXdN#4vF29lfyHGv#dIx-+G~{de%#o{|fs^59 zcO1x0(`I4I9_hAh_2}l62Ch!2nz%*0-hr9WA@MG^6nszYs^+Md%JA$H(QPfzci5le zu>keTzz+3v+bRo`mrKFo^vVv9GSk@<3~8>+R6%5vktlkZ;$8tH3Dw%KL-4!{s6pS8)Kc3K@WR! z9wa@rl4elCwPQ1-kCEwDd;D)xdVx&8Qm01&I{=o{F{qAK+VF-aVgH*-CP3ZFV=M z`^pUb{RI$!{P{{ae0L7lZay#d@=-|X$IA5CUV0^^pDNRI5k zoCoO`Z1yarbdx>Ezb*}bPa6Imy`*D4)>D1>0P2@7AMwsevI`kk+fZurFAI?j;mtI2Yr^<9u$7fTzFAsxeDFG-yMd`M2aSf%PBIQ%v zL;j7FexgjD>)E%B(hrvDF)w`&rK2o2f1=+XiUT}^QvAdDZ}a#|DBae_%%*f(ACjVU zn}64&N#986H%j{kUF-UH8>L_8OV-Md{_Jgyj#K>e|1C(rxu?W194Bly0&w3M%(d`VXakY=;kdWjst(9{V^@O6j&b zGMCbAb)+Lr`r0(gep==EX&KR+E@^7L^am;3G=IZ9Zl-ioSz;SsMP-e@$qSA>k->V5ivk^d z7@@*=`0Jy?$q`_vtMD*I;+%yMm%FHUm6UF>1^HVj-R95Lly2)AH&FUisb4&^Y^8L} zgKHo7y8*I*`gc>h%|8B}hb_HO8D?%5D8G`@ZTV|SlfF8Q{0)?@BKE%+o42NszdH?o zzM5FV?;)lCaAE=Xs{AS4=ATMRx7pW{CVe%f$EE&3QDboxQvJFgu6=Dt_gi-$CFY}p~p}XePyn|@Ur5-WY(2G0p`(T+a`rfE&$ncwDnND-vC}3rjZd&6&7F)o_*#n#p z_nFco&I%LkM4T^M@Rb&Pl?Cq(;rcgY9**{Lh&Z?Mr5j`akRx#HA21}~{~%%iNeb1^ zJ&5zYs@IUVj_6fAgzI7OAH#F-AL&1@?r04Ru6Glz=C*Ln@`i!INPjocPoWrpFOB%? zbg#w@xW?ZN=Qy6|RX8d--R|n+$gm5llmj7GA*AYF-`H1lK0XfIOdI(o1l~&aV7te_`T7;%ClF4N^Dn|r4B)2$Bj)$B z0lbp%lLGjSghvB7+7NLb!6+0W&QC+w!z2gyt-t`cD!fZL{_Y9`<55`0LOXHK3W?7n zyfA>@OE~UVA?ddhUK+rUgEb+Pe{KN3oba*$elOv;SA~@S7U9_MO8gjDb3ysIKZV4n z6VB_qoZsbyjL;t=-^Qf?n@!* z@jBu>rm*0jh}sb+h$8({VGxjr+ASxX6mgyngNpt+3%=QcZ?WJnSnwAu_%AH@OBVcB z7JRD(f7ya>v*5qC;D4~-uUPOuT5z5{_>&{fn|^@qBF>*I_*)kI9Si=h1>b4G-?QNF zTkyYG@ZA>tLks?Q3%ad5Y#aELgES@0ni9Dhp`4iN`eg2Ex<47K1#S#aFVDI6jWkIMeEh;y8U{&)+{ zqjgXYkIF$jYLPSCf}d=`PqE;qS#aE4DjXsX?lu(;5eIjl3Wta@%7Txv;5_R4Wknp^ zu__!Q4$lVsX%Po^vI>WY!?Of`TEscqLVu10=UGKi&iNMlG7FBoWQ9Y-;aP}3E#lzr zS>X_IF0|l0Yw`0$9NcXy93l?xz7-A;2Y2HNhlo4-@ux)`+^H)ZBJNvne_F)BUA)2} z;^3}c;Sh0n7UfTiIJnzaI7A$tUHQ`@&Se&Qo^=K3ud>kdY%EBRJBNis#Hq31NejNv zg5yqO;Sh0f=do~zIJgs8I7A%Wl`I@0PO}AXvEaB05e^Y2Wx;V*vv7zw9TpsSJPU`2 zb6p6Z4D(xDC&`EBBn;&`Qhy`P^&xsph^SrD1R-3ulAKFPj#?KZl8Cd^A_sR|3x|la z+=Aa6!fyt>jsp)jf$)IB;h`iDo>n+KGz7w{3O_u6I?mq|eryOoRxL>IYL=HgU*WjY z>kmIx_=$cH?%q+(S3qtr#g`XV4ho}XT5h46cg`X0_ z+Z29U2!B%HBSZK{3O^%+k3I~cGeh_yg^vp1KT$ZYI{L$Z6n?HBguAO%5q>U&uT=Q7 z5WYjTETvZ|it_t6PtHLzk^ztW= z5^+}p{Rt6=ULN>i@DDBehj3g)4+of6he1Fh`pd{rTEsazgdq@djtIN|^RqTiZ_5+eHRIRk!D2ty#^L@ju@f7A5g{!QcI{!QcI{!QcI z{!QbjViXDyC*1ELQN#)Ndm2AIBtzrj{!ruL{!rs*S>%NKNlic6LO;fW7h3Ql3tnu& z$6D|b3qH<*tGD-|w1_hygdqUWDHeR91wY$@pJTzp;|mf-obxR7=Uedbc%?satj_Fe~}QLn=JGd7JP;U50B$W7;!GL&{taU&s*?W z7QD)W&$i%mEcnG1{1OX3*MeVa!7sDmms{{FEclfc{3;6`o<|{J#F=NIueRXxEqILu zueIPw3%5AEO@&GUu?mz zvEUsRe2E3W)`DMW!LPUAH(2m5TJZ350TRMlA*6OFxdT?gZSV_v;q=O$z^-D~D%z+bsBQg|Bt#;Z}vi!GQ(NT`qnCU7exu zyIuUJbX5Vk$<8W8f3Hi=Gn-b0-{<0w($(#N4M!|)T`4=wVaRC504%HbB6d!*T( zdJF!51>a!7@3z?U4A2)i_q+CRkH1Ud54bqbfcIJOBZs1#hg^Do(kNBEdJQYA96H0_Qs}&LeI);HGkHRP^6->7#V@fWp7;;yklC=4h0^!Ns@J z)op;AOy8I3$oaK}{$qtdK~(fT zA>5sE9O`|_#aVt6;KRi_@JOO~)Iz^c;m^2o_z5FQmDf9T@S%vG2M4ZOhlqlfx&veB@~;=kKnZQo8C;`0Fmte*Tfd z|LNj9F8ovBdqa3Rbi4)5zg+xAx_VRLe{yl|Cx@Mm^#6A8>*(rAg}>$E=hD^P3jdFb zLvg6^wuOE;C@OH?b?Lz^D%2}{pNq5n-zz*^-=eV8Sm5MPZSwk`l)}C5Tex3(QQ?DK zde(cuSt!T*UWMsDuW;{s6`o-{s_-GM9OyPx_*miI_bObDSHT3nz}e&Gi^u)v75iHgGoc9Sz3)sIU#;+5*FWWC&yN5%wTs^~ExeE8bhhcv{sBrIl82<9<(D5jT?`V$?kadf~z3-qnUpW(y z-un)U@mhs@-^sAv9SZlplVSQ3p<)+^@1U5z)q?*_;of&Ohf{u!oQQJ9hy2s6aPNDY zsYJh5;oSg;MR=D?l4&x)BBPtNz=P-Vs!oBZv z*gwafhxFd}IgH<-aPRvZmh+*)z3+3_Kj)v1a=h$=r#@8s^``!tPNrgQM z_r7Qy05`RZw-vqj9n>X6KYTjM3FB7*KHORC%4eA?0OxBGp`v>f zz4yHn)4XM&A6$X*z3--Y92~1~@B1k3Kd%FvWlFubBR)tX`g)y(ev<|NAHWO5cUC+; zer%y14FypkzQ1DoYXFai&2gNCdW)}wKKX8RO^uVdtSVJeG_j=~PP)6MzAfn;bp}b7 zRTPyb5(`sxt#IgDqPivpXW=DU7RQPU!)U4%7|isLFmobsG_@ycIyw|hvZJQ1x@loD zQQZWBYinbb7uVMZ>53DHYB+xmj$*S=6pu?Jf|3$#a9~_RGFBOu2R3-}>~zHw3{q?B z+ghqqHFXBL#YH~30ZMQ$_^`eiPwxw45E*Ne3#!{2QVBStZc(D8xuL#hNesxaP{vln z)@(IkaciQwb)g2w*Dq{pZcP$JA#f*K6)z!0sn#WlRI`K%t81HEv;rWSS%N1amZ}Zd znyMQrii;Obu5YStT@q_;ZEl^a4^f<+R7PmpisEsLW>j}fYERY8ZeEmZs;FO(Ou=?; zRmqw*G}Ubt+kV zL4C5Jc9O0RU_e#s$!s@oQ&BOSYl^<+RjanbB0Ey)ZBi%J&F zY)(~H*DOlbWC&q5%VK8!vEz;W71i^T4GI0%ZgmE{R=bPS>P=&LNznyx@aRP?DX4L6 z35*+|-pzo+Q~ftq^D`D;&BKJuEJ%});!@=b&dC&2U-VzA?Y;5X%%$pS(v!x*vAU8m z=d>ziB1Kjkd*`xRsVkLPR~kFV70pPd>Y8hrxx6;n*wUOzHq|VtNG^s79RjSz?}sQ` zj>b*M)+&EC)sR>*cI+b6olI_D0E6l!t@W@0DvW#jwj$XC(;#f&B`|2?k;5=6p#ypA zuZ6qjCN-6*P3m)E@xBmeAQx6#G zbmwg|y_Be?K$c(|TR0-RE!G#~P4ZmxEk?MO_Cc{L!&PSTmFIYv2*ZTEsHmt|o`_st z111*1{Jk}SCoiYk%4=d()$k_* z4X~SYc~x=3*OdCDY1$30fTDu7YwLTInO?mpnvj?^A1YBYnZVu_A9c#Pkf(<`yO_!h zxVREB3iX0mn{Y+~6*Q@x5=sE8^y>cTRvn&hjI7K2a(_-Ym=kM-GG4#jKC;dszC%Up+xJrU|W@+^Hey*H=n zhGn$K(6UtBgtpatITsmr{-&~Tx~8!b1}GXFFS_7@DroAnCrz%1DYs5nBQlL;MTJRx zG=+tU+N2)U{K;c=G9BMOd7SF8G+|XL+a7F65jMS&uocD4i?mE-nr{d$?rrE+@@(UJ zaSX?Gm<2Q>Ez^P`MPVHI6|*<;`%F@7Doy)JCXSn*TnJCjYJLz-9h+>bwWUp{X>M$R zVLgTumBwUaO=Al-IpvXtRBUEdLh4aeZgLyc>gHL~gEY?6OGd-=XEdx1b#x?PpZKC#4639AQ{#-1C7_CU`Z=*wfV@%2q@$yU{kla?5arBI%xaRz!? zm?EH~s1=N*sbVusP&-n^B^M@BRms-H$<}gMx`R0%`$agUxMU&pORczSTAN&$Y?22X zSOt%B1(D4CDi>s| zv$zN*!PPLaXo82JrkZ5m)T<_LYfx6JtE)sOow4Obh2VEG*EdSoB@|XPL)o;oRWD3J zAB1zXQb5#`F80f6!8#*ucwWGs9;$?$ya+^J0FRVybubfx9L|JUK#{OO^(uCDK}j76 z46>lHwgE@lUKAHk0KdcCT%EDAsm z4xJ~|ZI*yGOt+d}TomhQfsU&_)v#m=EH|ZE+iO5Q%!{+G9kJNhg^(eYX*pFcDvsk> zC$o|;k#0+swk1=Ers~EdRHgkA<})EJ47<%@YMQlxY%d;J+`{??lWbTa!&lYnF$t=3;3)~_jG+gl8d$1= zhaZ~bKz{o?l`mNU4?du3oSvaqrTVb?LC%Am!NYBX>B-NOCwk}`uPZ?_PT?+qXV@xQ zltVyG08Q18`$Jp1FsA$FCrkmpHulh_CFC?~n%-d1UlRF&)!5~kER6Nu@0(dXEhf9& zPQFjM&s2(MOL*9FW%Qm)LB=yPLys>V)wiyLYm#Yn;51c-i^s!5U9zUVHEDR=p{CPZ z)zuRqzd6~z&NVzx!s?N+{P(X94!nxsy04a2_$KQ|i-1sFe9+m!CqL?87#Ex1F)>v% zj+e9f4GHv*MdNDg@y#NQ+z8)&)!;*&t1eZIA0zG0xL9mjjoS}Fu$VprKXHQdBypjN zC)L?5xcQ3{XBFP0BKuJvq|NZYo>OHPTdZDSX>awuELLn;76UsLG`C(;-3rgby7|f1 z8MuN43k9j7@vX_mX81S{)>3s1Q!jo>R5epWxhn-mLF-F2d{@+qM0gY8N(7|?@}gxN zI8m?SCE!85x&iaSYkAhCJTQ!w^1u~YJ_)&!^WvYXe@SEaDyDX(ZOj7_WTrMH7D z1^Y&>Y}k5I?JW(-1oWnOD0%r@n4DLo#woCT+SC?&*Bhgmj#o-W{V^=4DTA*Ymn#Im z1)bjC1?Wy4yBw>w`?vwJPkcSnrxm;87w}nDul)^7dBIdWu?T+V zVsjKWEpU?l6wEM`;d}~AgpU&FW1)T=Qv37S6N;gb9v}@*@NNz1$C+Cxc(%2EVO`2L zd<@(~X#%KjNG|w4(Cq7C2ByZMUtvDmj-UFN8#mQi7-Ym3jp?UjSdVoj2C=4@Kspid z6l<9&=%U^~p|Bid&t~6R+XU!E@mmFcJR68+;Ok(5&o0nIYuD(t7)wUg=c7ga_4(*P zWYRa4#KjDn)DF<_;!}su5prz^ooMj0UKoOIa3VjY^1K*-dfJ+tU)_M;G0nG?L1AK6 z6}|!j=`hX32Zy?31AM5cCZWB}L8k$SWfBTAOniw}l$fn1qH2)=XQ9)o#wTF@NuLn9 zlii|Ece3m1-S0^@eo>RvEPMKZJ`8!oLN6WXz;)U*81|~W4{tZs+i>u=+rGWoo*EGP zv#S)cU@@h>Ez#88&;Sq5>gUAe@bV)zzfyfu3HAUj{BXSa8knyxgda<(ue9j}arP4& zT+FFaubpDE8r6r**~`FQU%f7J*6U4>S@_BOehS7F2>dO4 zvtAunQd{BIgHR<%2RxHW4Q>VQ$H}NFvX*xE)DM3>U>PEG1_wet{K8)^Hq8X}u+B!m z=jVAx(Rdf)7lrtXlkhm!+YAg>2H&ww$!omsB-F$%Xuc}lu!X(~Mzj~>TP)0&5uZ8(*V1KmD>AG>MuL$~WI4bpxMO3x=ak!i4 z7IHZ(6HbFC<#PQs4UUD2)%Z6X`U3F-V1Jor-S4R16r0M!FE^{Y!pkoG+ps;?H&#wp zZLNRhOV^JF*W)ud{PazADzU{d{rB8Hy?-^A!j3?&Z4>N$gV}=C1e0C;h%q0xr^4A4 z^(}hVVf{I4;5TT#pR>B}s|}03YC$IOrH*8tZT?gs{KE}38E%0u?GlUYTT}3v3*;v= z=H7qifU8RC*CXnO`_=R77Z;(EY8tBB+SJQcSo>Jetf;DtT~FB5%VuXpncgn^VyM2k zP4%iJ`0FD50eGUetvLZZL)11TagYlV=@(MUU+`62hu%ZWI))qHdFd}ZEI+DIFVakG zYJo00Me5ZUeDA*W>9su|&u*)6eyptm0D+GQe z?SzM0%^e8;$I_m2ydxmeKP~8aM_9yP75G<#oW}%ykHEJH{M&@1oRtFqiNIG0{29X0 zysZNNg`k)DdR@?CzNS#V-VyXNUmprw>OGwJFnSzl*q=uU9OakO{RskpUeFIG9P_(b z;Nu1UWr0rmXLq3 zz=2E!aE)rGbc@@;tAMg`w@9`};x`DK_q9ZNJk^uwPts!4$(^{nB;&;b?-cm4grgkU zUSK4ej=lx+(ufz)l{oR5dwuMyz%Mts0_QRQkqa3tn zBi+OH(<&hS*9ASxVfy!pu99M;zfaK57x*^>-YW2Q0>571_Y3@1fy?&zU4ctEj|g1W zw;q9iQ^@~?z$N`bgkydm6!bj4BmR)UWw|^caM(Ux1*E@A;9SoUzgOUgXmZtWd(>*MhpB2AqTcsRsrRIOW+q1j&hz9cv9d`2|Oim**|v?j`Fb`H2@EWuj)wk zw{kwSPT*1w*ISmuI~zYG=%t+31&(ttZr9u{F<-L({I{T&{qwAxwEta!OZz_(xb)8fXb8!X^hXko z(X+tI`6?6i&k6h@L62p~^j8TS>j{oA807p=&P%Tr^5wkrdLiddA^*z)NBJlV!)*fp zqM*ND;Qu4=9|?Smz;p+uK2aOsDW1TOtBM&Qy9=L=l=Ax?PE4^@N*{V-q1!DlY6C)Wsi zIo_=l^tekp)2|V@^xIuR&WnP6ouEhmoI?ItFX*M8pB41i2sv8?y_`?JN_fx@?+AKX zA3hYgY>)pDxa>EEpd%r0`Hm#}k0Bf**>9XIaM`Ylg&gdo*q@UG{m%tnDRAtIm_8x! zmju38;4)ud7Pz$ME`dw>?+aYgZx*xqqDMJz3w*x7agBxTX(SxwNWTpi^zRD#vji@m zTgwD4>8A@^(#z+gzX?QU%i;5E0P;OY zOcwO(E%xLJIZ>j=_9CCBWVswD=%xJ!30(FAc>9N z(x?C;9DLSbIa2R1Az%7`ub}61R!|Pk?OD!DEndwljurSkflI%&2>dgG{)+-XLg4oZ z{5XO0b1OhTd!`C{S&o+pT=oyLK1e%n5%jVjxJ%%;HqL(7L^#&}69xXJpg%_7(*K{e z;3rw|sKDj8BmFPih0GVPlYt00$J(>MN!VE+aOsDW1uomQ#AUul2zuG?;oO=1Hd*M! zd37zMVc_)#^yjI9UY6qnxMZ;p&G|IFYA3s;HL}xM*=@X;6D@inF4=R z;AaW^ZGn#x_-=uZ7WhX3A0zPp2)t0>d60Jum|rI+NhAmDoG#=` zIr4c#)@M0?C=+rdz3urWkLaO_I5SW=g($^{&lEW8MSKJPp}@}_LHbfk58_fUuO%XB z)Iv|NgK{dto_qqNoX-n8Goha)=;b_oF5o;5FCalk`Y@566eBGy2`HpY;F!i?9$g@Y|9QM$8o(#g{kj0o{X$Ow=l7#K0{Go@ zuQCMJtoL=oqm&oKk78Pg%LIP3z~>2^pD{6csld5!M|_>Yc@B(tkHC*ZfWi)eAI~7h zXdp%0SKxhA;M@igFBAA@5umV0;J1)2Oj;^%E)&GN1Rh0z!g_%ZXAt5S1YRKUodV~v z5|icnFt=I6&!T#VZ2XLXc!j`mO_M`|z)Ki}c$L8USs0Ta7C1lSApVHJ`5hVJ+XT*i z1>$=I{y79F48?{80qrlt3koFypUoh|vjsj!;3 z@^*n=E$H_Oe38J19i(qCuMGk(6*#X+V)9&p^RpY`9RhDgfWlgV^D{UmZ4&qwm>A;i z0_SfJFnO=Q+XVeE8aUDZl)y^`-Y)RD0$(if4uM}I@U;T(5cnp6FA?~5fnO`|y#nX4 z2$P2m)4+_D+KFX%1MBw)l zhS6++e_h}yf!`8w9>h;6D=h9)bT@;6v%b3hn=iz)J+aQQ)%${)oV@6gbwy21>hL;ExLWdjD?ZAoLQdcHFn4j$2Q9bdr)pVg!BKplljga^Aju6EoYCJ zC~e1(jb2y-TNHHEB;llVr~nN~ED9~$%Hk_F?ZXTX<}z5t=W*c=RSe1A`A>$UxiY2~ zr*!#wvOoPQ6aHQgx$+CJ9tu=6K<8a~H8Km;7a9(a+RuFS^BG#kx|?y%`r8;^tFT&; z;h|H02g_e$`A@Rw^Jz|gMR1fJZ1My9>@~MG)E0^JOu`2{`57f2@8%fzNuAo)F?%lj zZCTb_z5gh0|13!(Q`w2bC3c`0xWo97}}zdE=oB(=}gkoVSyJw-yo`>=hDwwA_z$UJQR;GP-N$0KdH;-O0i z_Fx;oL-wn)6g$w!^8&oqGf-O%dZz>ga}nAYv$yTA@Dv!|;R&Ai-95Gp9cgddUV%v3 z_R1iux6V1^6KR4u9+2II`f@l;(7?VPH`8}{hQnh*LQT`00XV`Xq_=;!mJf;VW4|0c zj>RwE^wgua88M8-cG~a*9}XzlY?a0*zWA-{hhd2he+kJQh&IP#6&%eG($~jcE%3CF z_0E~N=eN5JRoc^GxZ}eeZg?l+e%$#i{jTc+Y=F1PE>u%Dhu*G;13mnCJFxrf$-ubV zx4XA7x4zm1jV`m31Vkb2->&KQt=Ro;5j%7B=>#CZ)PZq!nj?E$pQ)}byS?u-If}@Y zKQOt29sTs_+ z*0;)ud$iKoEt4vH$cA9wHj*P3=PrgQb|dvbe6ngo>7 zQGTE5=_Y0qKIMZ>+?qZxy_feShK;e;);cf-h-c9ZEa=1V2D4@BhUu=8i<2Kd6`j~+dkeGK9|FPc8hg$@Z0`?S;`^&I%Io)2A%Y$aYS`bojd#|8Iv^sX zrvHW%@4x~)w*fvX_AQ*yuVE=YH5guNDI-TxR4kFZPcy^{$XH=>S^@H<@46-)LGSXLxo6{n!EXk$sX3J# zec{YGquNr{HH(NpS(jMQTHTn0PdQtg+grpBV)pZLXR+hZPjY+`%IGeSV%(z>_w6`< z?m4#c#|`|8v*52Je)<`p+A|;bCuO}H+w}8q$))|cUoZ1*d&{ANSVAApQS4xMx0&ZT!m&{J+nFe>L&T`tye@_}3Zu9|w%>=GbOG`U->0|8}@% zK8|htPa61N$%6j{1OKa8@NYBl|1k@G-uFo6ANxekH^;X8<6guVB>(Gh&wL!)_;F8C z43Z!Bfn+|8ZTz^mR)`+}=HuALk9)TU`QOZfpU=~h_T%|Dte0b({*ea#JF?J^dpu&0 z`u_y?te0b({xag1{l`OD*dI6O|8o}l@k}cW(*C#Lp6%w?X8$|`Kb}v)d>q^O8w~t- z{sHrGY~$}R@Ndb2e;M&h|Kon?te0b({#6EkY}3rgv5kL?!G7FNo%uMn@vk%J$2QG; z9NYNU8}#FTl+4Gmjeny-KkjSDd>q^OpEU5}evHh=v5kMT!Tz0D@NYHnH zJ6n+#A_`@f-!#%dt&ApMxX$KgojsVT1j+A3N*i*rtD@f&VXA^KoqBf1mhe`@{1Tn2%!{{~iN>UKaeH z80^P$8(1&LHvM@-AnPBVzrcJP+xUkPfy_Ui1HpV8+xSl)0;wO*d0;+{ZTuq*{P;}4 zd>q^OOAP$DUpDh`Y~wF8@Z-4w%*U~fzrw&jGzt(SM{2{P;}AdO5b~UuxjT^B3 zIJWU`BLZ1}@jM6Sa@ozBLkLPMIAICQSO$Pn%L4Uw}9NYLe8~E|OY3AeD#=q6T|NSiZUo-IIIUB5( zW1Ie+#4qa)o^!!`9NYMJ8}#FO8_dVCjsFvaempmW`8c-m^SUzhzi zp0B`qIgWx%fYn*J5V>Il@i)~@_!Ce5DTz78_53K0tx&+ zj|El`f6)Fo6&(AE>4WzdLW0Tv`9Iej>}T}EQ-AV2OYuj~&bj5OH)RiF*p|6{;R_TNhSk8(BZi+~#ER~G&UGqnF77XFuse_R^< zA40k*|7C{!-vPA2{2v3EH|0N%_6a{DjsA%i{$k=kA`SnQ7XGQke?l65d{1t&e;)D6 zJ*`nxu>5WWW|RNs8vKX*!w3EMBa8lHXrJzmSNr{oyxBLH&QU z=$}RUc?jS#De|j@x))7 zhJPIJoBX%>7n+g#DfHj{00r&;f<^yQ(my7kKafoa-*cMuuP6Po{2nmqUv1I9f%F%o z(ZAB7f4d?74;l3LSoFV4`gf+$|Aa;VZqh%G_|gBk?|;z$_@2vD{*TkZad{g3A6WEP zzN8sDg#Pas^q0WEY0`f*bzD*6=LppK!WiH;mH!K*U)I0x0cSA(?H2vxN&iJYZQ=f_ z#iD-)>6i8I`v(0VSoGga`qTB_=RxL8{##3o+tb)z3j8Mj<^NJMMo~BftUntd4*KtD z(jV-9T4>_M{#Qca4~gSjrxNDbCi_$KqiA%Pji$kp5$Z zZoCZYKgXhfy+J>oR}s{|*rNY%8n{kPqyGyQ{XGW%KVi`Sutk3f=}(vcZ(H>5Hsl}A z(+K9@Imlf8Gc(Npzb*RneytrR>pz~)5!8Q?MSqI)(=eok!QWu{f6cF~+q5ZI$5}i~Zw?e--p^G6c)-af|&s$bLSD4efss z1Od4UT&^d=b2i!(wEsD3c(aL~qoDn(h(9=gJ^DD!k*@yT0{kZbZ^w^yA+VijKMv_Z z`~PauKc4ibtAB4>^zSz4$1WwP|Fnb6^>0>&`7Z!|Q~vX|WA6R=-wO9Z{T&wltr_OO z&7wbQ(EqYQ|936=Z_QBuLl*s|2L0O%`d=db!FKU5>0bdnGN7+zc*|mc300hQ_2&(X z{gnp$u}THYZ~P(V`g0K}#`Q57g6*#e_)Ybvj`Yj%=M@kX)W6K4|5no9A(g{*(9bto z^sgoT%#ZE&j|TnQE&30ng^x?p=>M%ne?Ddw!aVg?&!6%8@nHT>fDRgc8tlKWBK>2D zpQB*@j{$y@|654E^#7X%{r6k+-$we+V8s*%_1|mJzmD_|BR=&1pA7onvFLx2^q-qX z{|<}(O$PmM8T5~Ybt;qp_mcj@)98QD!hhh2n(@>${NDh6Q~7N**#EA<{(oBZpGEr9 z)!)Bc^zS77ak3xFZ>K?j1vtp$zh$JKx0J-$(jS zaW(6Up#HC0^v4bQ-#6&rXVJfz^i$+o5!C;&MgKg5{=XUYPak6T|DQ-P3=h75WhKM? z7XDqtPtCw(3G(OXoAu|>gKMeFsV{>0KLq$q<=V|O(O*XT=`q%|BB=lO z7XDeppYHklHx~O>8|?qcVE;+5PGf36Eu#SHmhu<)-U{u_PT!{hJs zz;7zQ^^|`({{9PO112K_mZ(V+j|vFINZ)e6(;-(k_e)}TLP&>w^6T$BG#ApPZ(Z;pcbF9Uv)|2L5S zdBlk0XRbm27cBZ0L^Wf&`9p(6fBtKlU)KMF4En!r(Z4D~{cA1y%SgYh|AP(s-?Hfc zG3ifN{%=_H&o$^j#GwD2qs-<166yb;cBA_@SpMUI-&FoBq`!wavHTA+=>MKY|MkN) zW4iI@TNeF=uWNqk{~-qbA6xX_P5Mj8evX3q|Hz_0ZqR>(L4WPhX8*rT`k{OE1rXs2 z?^yWX&X7NOj9LFbEd0Uz|JK5vSD?*2%V(|DC81vdzp4JrBmc?vdo*M|*niH20!E(% zpC3y||3y+6TnFv10)CVJ)uca8{8)d78T5bIqJJ6bPuG6mv+&=SA^$rT`?nkF-|+_f z%Z@esZxiYNK^p&^1N>+-vKf?|AuQ}dq|CdH+#-RO}R~fDXev|&WZ)z&29x9;z zlMVXcwdlXsqCe>WKUws*81$cF&_C@2bN(MC{U?(B90m2qfZvq=6$bsM8T3D7(Z7xK zr>lQQfPo-3RR7-1kbkL#e=qUh$r-0OnE&g5-<1D#l>ZLm!}34VkpDAbfHm2FD=i$H zo<{$vz;Dt&Y=>r)^>36x|7{lin@E2_8vTE<@V`p@!S)mM-=8h^7aHs@G}wRsNoN1; zA^k_9b43X1p9uUW|HXG`raI!s@+&sz|B*$1-f5bDywHu8LH+ogWzxUlPnuDVza<9! z=S0okEHy|^2a@ug7dFg1?K$kB>m~? z-wfb4>7Q%Rf4)Kg2NwOG9jP;(uKeG#=wCtlW%-vG^f$mf0pL*oUz(x*g}`sh|2l*I z$p-x&SoF`zQ2%=t{hJK>ryBG(k1*%If%FIKKl)0B-4^~YX2{GSvSSi~e~A z{TCbb9|kXIP5IxHq5eGJH|4*>pntAG|0;|Amr4K0Y0Cc=i~iLH{g)Z^|J$PfAEcj# zVb_Xa{riVS|9a9d$A8?@Fpng0y=Xqu?ElY#TnzW?$o(7Ce>L!%{J)*_^Yb^>zpD)T zhrk3A;L!N{4CznT{u37dUlM=1_H!BVo9ut#ZJlNI6WU*Gu>V<${=a0X|4EDf9R~e1 z2K^&Pnf;do<${6C&^PcGeJ#Vuz;DX`UW5LmLI3R*{b!Q?iBcI{2ld}-(Vzd0W|Z}J zp+WyqFhHWr;QC=L=}%XG+ARF78S-zo@Gm9)$$|U_+s`w=Z}NW`$a}?zZiVrI`*Z*b2 zPtyRGD^N|HJm5FkUuv-bdV~ElEc$<7@qbW%+@inEp#O^o{oTNieRRalp}yEo`q|%{ z%=a9xVEs%$@mkW)<%H$8)S&-9%73u_>`0@Z)!oJV1CH5X(2x7iv)yc059#N6#&UO( z{^0sKh){v!7m1(wIL?J}#T1y2)7~KdfcZ`y@z47VQ|g%QXY>`|SM`qpieI4omto;T zK>y?Z^~}%tM|*<0k-n}B{{mmBj=O-+)PD_zM_{pYfdy2?UikfQuVVa3w_JGYMgVXh>qR!Jt1R7_eEl zt0_vwciO5=t&jM^fC7sk8*SD2PJPDrT|+gswx-sS|M#4kxjTFJE&^>o|Nj50%ia0T z%$YN1&YU^(xRa&sq8TGcjBu#WD92A66zWy%3k2*?PgOsv8+~WXc?d6&oF&UkCYPQxkx)HVJDgTiJ!fL>X*F|C zsj04QYCfeof8r?di#*mja*PWv3k z9?p)`OFPDlPMhl4Z;WHqnDmijMvwGNOJCqPt8j(4W#18w7Kh`8vw9A2IH$Sy7@6`! z z4aXvUoAJE{-)r%`4&N4h)n^%gTrUHycrM5H1{rRX&l~0Q=Xl9ZBz2)-{;Kz{y+=S%YUD|o(!?;H5ODY3WYvrj(%B%kl% z`5wOS{qs-&a4D_1)4dzq@Af#5>bm&kS5Q`!{EM z9(v@G6PGOB=k?9mM_)XtCF_|%_x<00J>}x5%eMLM3EgtvpU-`D{eJuOyj)he=jZQ) zuF6p~oKDy7{5h;>ckY`DeWH{x=_1uUm1% z`}@0|ndW|T+whAU)8b@I!buX}n)+o-%t51shK3D5rC^U5iQKf1cP|NEh#zN^X( zyD4SQiC^#k(&oKxemZ5tJ*=&j+sFZ|;_4|wv@&mRcg^632gdV>cRp8eMQ*H4^(%W;dd#_b>WzIf0K z-aMbB?+I`W*$K6b8{c~|8xZ|^_tzO9>Y zdpzsckH7G*I~HGYbmQ3{eEIAfXO&Mp^WY~hy<~6KGkGhgEDwfmJo&008ap1@vhn?E z|G8}KhZp?f?-N5eR9!Nv@u0OIx2&D{#Q7PAPFc1seeKJe^M3pD6(d(4=JiF-ef7}q z*L-(g$4jK5wx61P9gh8MVop8D9)ARe2w4(7FO0HJ|8NregHHSOPr_i?@iTF>J-+Qk zd;AoaJ-%cgd;C7wX}fX<0ovhz-rFAEaH>7NZxZ}3FpzfiPd&vR_a~9Vv^B>00#`rRVv`Mx&o`)v|Bt4^~oH)Ah*+=cW9+R(4gwNL+K zlJ?qnf_?f^lgMYkB>i{H9`nFE zBzF6JaOh0n(&6}JlKxeZB>i1U?BRXK*w^>UByz4v(!P_S5Jx%oaeVx&U>5Ere+KYl zJS<%IaY9=ZekqI|rLU(66+Xv_hhrFYD1G)xB7LU9k$}=4GAMur62JU-frn+eBA3H) zI^<7uT278HcMkf|c$%%>3s>7fB!$kT_OZt6)Q@OdAozo}C|2iCLhmc+!>S&oD z=%-5jK*?t_O&0N4DjtrHz$ca4b(5fTsKk%R7W7>U1U^UN!?1hAf7?-le!j$?hd_uQ z|AivGn#X<)yGQsrkBWq8GW}0Z5am`}C(@JN)2CU=IaSgxU=;Iq*)Ct5Dbg28{5GT~ z`Zo*+K(*Ia$eHk(PX!Kh!Jjp#Ak{Zp%K2c4p9jV$eT#+9{o&_OebbK-^;PX&j($gS z?vQd$7i>BD_YmpBM~n0xNq@?Ck-pv1E;UY3?gOI)0a?7`XtX2obHwL@0QEQeJT2>+ z`BxEsQ3QD~g8sbk1RZok{=6sYU-y*=UnTJr&>?=T`gVqF z7pq=Xp+VCfhd4a4zLJdNLDrvihw~P}IJ!B1-i1C8{fA^bo;Fh8E6^?^|12qgrB|oP zdM%K8;uOgpS4+L>wdnJp>_)t&T0viuahwOa?dRCr(L;-G+NX%+lkTXO{X*%2K9 zWqK6HpL?NK++G$w=SjPlFLBk64nq4Unobl(HR6(bh7XI*2cJez}uL=u4SFrvc znxOyFowB_wa{Cl=Cb_j+=uAdK5dSwl%*8rP{f7Vv|E5~-uk85+;FIV$rTys;*&M~N zOO*b>bpm)@WOMw5?csrrGO2Iq{`^@a`OnS+W7_9HsSn%t6a>_|{84)g`e#K&Vl*p% zn&dcDFZuLIycK##{8;KbS9L$va8LGcr1A3JHjRytcbtA5_Dgc~XScxZr?5s9kz2{?dyWK#Bf6qXqqIC7nAl9#Q&C*^a8euaR=Neo!P- z<(}@c=ks!ze$;xAUhzK__Ll5MSFX@cs6BtypoihF0 z14O;@r-*tfIUGD*$TMt_=iacxBxf zuCKv2zq--yYnWX;y{4|#H@k994dTk@FRZIAZ}e9-_{+;hQu~A#&zv~Fu5NyfFJCc` zUtJ4wwUsrl+^G$|+R74tLv`(ZufM^SJDu4mtOZ?g;P%ce$u7_1L~if7GfVuF%FC;o zn_Vtf&Ya4|>ME2^SqrO5{4Q73g35++e?w)pzp=2&T~djE+-^tt#WT;fGT?F*`x+Z7 z=lhDP{l1*+vwi;J%EfbhT#mPnxpOa~oYssn&L>T6Y^blyJss+AC zV&aoZd<~1Lt9)A2jw_X2R5xE1H{Io?(({27`4;(VP<&POkL13vy1_T2u3=%Ne{#u{ z)%7!~eKm7M6XsOcxh77po9mlfSXCue`c;UY&hzB^8$ooo+VL&a7PMo0i9Y`bSuGxuA|XtE6nYysrzkp>vt+LTqNJb?= z&0%U>^C_-?SK}Y;#-Ej^vx}*tDP@IR+6BoF@gNo)yuB`+e*ll zkD+*WoxieX+G4-2v8Z}swcl;q_Y=CaYvNqryvn8;KL!Hn$l2;>(h=R2cVPpJ8U`Ym zjJdNauZA%bb|;}z#I;vWp4ncr>y)b?oelP#l9p(1?~^8nPF@e4rsE5CCN@! zjOeb9T{D8A_&4CufUf4X58lLHJ5Ebo_{={O=fsvvPi9^l(iOeg*z*q_L*D z8jkXhNH;c#sA(iGWXH)Z`j|6;yT0&Y#H>tM0eAK8Ip@3GU^%%wU!7214;Kv+shI0w zZ!F?0k!zxIX2{Pa$0gZtX)3#&m{eqrYx)9T)s^HhPpzG+D?9sB`gC^3dKB~bbMh_z zJ_y6zqxnW{Q@wj3W<%aZJ0@nGzJtrS>HAC!l5nJ;1OEl{ab9i7f+qi5%o}GlVeSEL z&t2pe_QJ-mH@o3~$sN)hIJ_(@#jBnv;46PqdXkX+Or&K$2*2awck>g*+4* z7nEzVo85&S8mkW#r`tK%-pYnXA6Z+rftCT*W}n)TV*TwX@d2wm?@NjeoN%=bKaPE9{t!wI5BD{0()BW2-VrW|IGbp?|Xd*rYeG z-S`im6svvn8|tf0I*Hf%s7ARIc1-}qMZN}_ZTOn~u6%TOIg>TjZ}-%uB%jAzF2xkq zbp+(3SY}=QY*xys2=;A|aKDlAPO(MK8Dy>~ml`DMXfk zHUw8xJ*T0vVKJ%ud|xee5z7#MQ>~3sRWWh&8C$C6*%dHGz`o%v#!&qx=U^u{?5BYkV{* zJ-^A<v313Du!qgVlTCW+tT7+nhQP zH3)i2`K&ouPxoQbMzn7>EFUI2-6>@YXLvB}Ic`?ljeb_bdUDZ@sQ-~ERNVt0<)jm9ZPyTQ4G3h-o{n^c;to6PC;P0N*2Ejr|Dhf`vFfUFf2CYDP$P|1?s~UQXp~q3Bt%Iy zQG-cBJZJrpfiNdF5X#=KHj{L&bWEs+LbUN#_2>Vf70HJ(!!|&bz32-QR0-v^7@yf% zkU_K>>>aru<_M%bq-jmnHQ4!dO@xP3M7y80v_o0f;OB*bU0(|!^Vo>}N%Yowe*@g1 zauN;c{Oy_C=}}!WpWpfhkp< zOZipgx|Fk*Sl7Vqks#+C46W9*E*@Kj6HMD1^ROHotBY0LFdGqj?PU6~b4%+)<*LH5 zYzk2Wf*78qb1zj_EznyTQr&=@NvrQ~%Gkme{9>NvSckHtmHY2F54rQIYv;OWNe5jr zW9OE}BxR|HYXVCLOC8V$bY?ksiytR+Zz#?K&dHq*MQQNiAD#!mkuFr*Q;fL*=051+FFG?oj30IDM4w$aGD(UkTo->Qqbm8?Z(%luD>Zql2 z12r+9&kGWmRAS~L_iP#v39ZEs^S_yQNWXaF6=@80rsy=7mI@0pm&eLpqjcuDt z2TRQG)F5unoXj`0W$S;)qxYUG%>cQL=!-{`K;ELaPotQm(#hi!dWvGEpnfOK0XUDA?5RGD(9mcQ(w;JdEB|8 z+(}+KlQyks-aKCeEyVd6CevQjbeh;`(-fDUj+Z|{%g&vNMLeEp>TY8aDp2~}+r!(%s)?HAmd_}i zDJo|tSkcx=DkmaU11BnqXy1v`;Nz9ni{*G3e65Sbg=S+CD_@toI`%h1v9bqKx-0}bE+4);1WRTD{0h^|&;!qQx_mo~ui9ctuIVqH@O_)Z&Zq2Ezp@XG!Xx?b9Z}Gg5S5dIqJgbBa z)UI&jZ6|}sjB^^w^c`5qBCZd)RoYVM)~~a=5owJ8tZ832q(Z6Wz%?q zb9B3U&Na7@P6WW6Webcg%ev;piQ>;eQ#4lphg!guQ$Cely9L#-+ZYSIRoddY-s(B7 z^72Is?aGB>RF>Ccak_j_b%P(vfmHonuRRrhu37rr8gYPX*Xf`M&tr9BzUE*qR$Gn} zkyW%O2AzWRaALad>hc<2?R@_NEJ5JdpV;8WS|_xz#;!YI!jh~fO@yj(QOIi+v>WwD zQxs!Tg2Og+Uab%;Vep+z{xfksudd;0oIf>vYg%~{70Oc;nuAl|YF`A5)YQ<#Xm|9G zTz)>A%mjA51<;bQPDCfT0T3yO5M4q@pO^)Ubyc#A_^u{1?1mJD7A;gtj3OZ)c3(&$ z;?(=@XeSn^O3*s>IAo6%AoTw#G!U#PiFnr~l-qc9Wj%CCTD@Ji6w_U#AB)^>){j_a z>ur@+oT5+8CJza0>_G|YHgz{^<#Le*SK_c7%%C`Vyz8RLtD?iwtS`HxyLo&HS7aBX zi5!D>os;P~c0x`r#-yV#bW&KP-BA@a>g>jNGEtZ~7DnyWG*i&+U*lq|h%OZN53VPh zum-Hw!8VG%3WINUoZVA%beiJwMxS5WT2_g;F}u1JudLAO9UVKj8_NYJ*c6dAyKX*Q z8O>zxMr)YX&5J`#<#QL;RxSk1s>(*%3ubo;tXRA$JM&*P8*WryxfnWjM^$tG9UD8D zx*8lhKhE1N&~b&8=>%r!7TcpmVVu#e3qrL5&)lUOuS#cL$F}JWH*@i$QW` zT3UNG77fd3Q*NP;BCEt?7DHui)xvr-BfL@Cjhu%C1_w|mzSL+4s2RKb3w;YkLh@Cx zCcv9~NJ6ya`%epTblXwxqeel*9JsfQw7dwYcCO>>>C?+6oSN-8yQpy5^zxijb8y!W z|1K*7o_ngx<(OVpHg#HIx$D#k@iDo2Q2%{u4&Dc(k9>Vk1aRZwDEW(SKcsis@Y)*g zMI4DQ{ikBplX6qsp7?hp(vHHv4h{)iP$#M)2gQptDm~>CTu^@crNRi{Ll}JoCHh5_ z_GDa-6TeeAmN*hQ1+7tz5jOwP{g2816Qv|ikvt}z;*QeoC@!9gT_{;@!mV)txTas` ziu)>^2z!rPj5mr?9oObjtcc$ezv(?&C%#RGRPRMC-)hFAb@8&QdJng9=r#yeu;Bd?Z?@olS%SY73;xlJE!7n{S;2joxrhGrS%YrwbAo%IF;Ni_eK4A;~rNnzIc)FBlp9Qaw z^!qKice3Equ;4dJe9(elF5h=`jE`^M{u5=`f_F(e=@$GQiDz2y{7s_1Sr)uq@}F(N z-`ZR7pKrmPvKZ55cO)a;D=2Wc)JDPCh-mn9+v!cTJS>-6m+^Q_-u)HTkv_)Mf$J>&p%7xJr?{B zx4`=>xJT+qzXg9VL!>t>__q=twBRR8`a>2xeTJapknd9~`!n)vfu~z=^WGv0uI?pq zT5xrrPL>5%_p@YMaCM(Tz6DqJ$P`#`bq|8qf~$Kd$}G6LzoWu}t9zR2Ex5YxrrCn4 zdum!NxO&gO-GZxoSXNtbb_5&AP^!LOINL*6T*^zFV1sc*-|+sQt8Pei5#f8aJ@Pn;Hf zo5Zs%_#fpx6!{kXQ;8Q?aCOg=$AYVSWV{x9VmF<{r!Tl1?wBV|JofcfRZ!U@?USk?+S_Z%@$m>Z;J(gWTi;oX2CPt z1>Rx7FPHW0wBV|JyDa#bs|1~}1@D*lQuSJJbzfV*1@DmexD8qGu*5UvJtwN&d*%4( zwctY%ueabW(r;XtU&){a zSN9@0q(83Ypzb*;u;5wpev<_jT-~45VZqhCU_BPRARz2>uLbXy^!qJ%Sf(Ge;Hq4Q z^s^NIL+TzD3$E^eaawS7Pgb@Cua|TREO?8=y%t>EDS}eHIpLPqb^r6FoS4e)kEVzHCx5YJJGcf3{|?>L3gC$xnh8B*7OX z!JCudElKdsBzUIQUOJ!7BzRU5JUaTuL+ z_&yrmtl?=I-lE~EuTylJhVQGTZ`W{jmo7!G*6<81eTRnQN@DZVso}UX+x&ECc&3S> zpK7?eGo7Nt8h*HzzDL7xHL&^V)$k)t6n0O;$7^`Mh6@c7k%opJt)(B-@MAQ5NW+iS zaEB|Vx5sICs)ir0;prN#?rx^&Obs{h+6L~_@KZE8SsH$-hG%Q|X&Rod;n^BqpyBeU z4aa&kJV#6K)$j=#UZ&x>8eXB{c^bYz!zXHZy@pTH@MaC4tl=#he!7OYY4{l$-mc+i zYWQjmpQ7O%8vYXv@6_<0YIv817if65hELV-u!c|9@E#36OT&9L+^yk#8a_kA`!)P* z4L3BrP{Ri`{2UD*((rRN+#%=JWIKyAJXOPsH9TFzXKHw+hM%Y5P7U{Jc$S8rui@Dm zK1;*%HM~T_3p9MThI=%;RKvX*eu0LUY50X2UZLS-8oofoFVgUO4ZlRgn>GAW4R6u# z%Qd`B!^<_iUBl;S_-YNW((n!qpR3`W8t&8ZE)8Fx;oTZut>Iw}ze2-%H2g{p@73@c z4e!(Nt2De{!y7c*(C|hL_q1+H^#oJKJvrXtSrPV+9PahBZb{wj7|uHi(D1Rx;NP?( z3-F7=T*GMpFh0i~LSb@UqP-m6kHX}#M8g~&L*Y>r?&9!B3X|&+?cnhDPasS#OSGNC z-%yxbm1qlxzoamAvuHhsKc+CbCeaEGze8biNupj3zeZtlMWO{9ev!iDf<&`9{2YbH zQrOAibrdF7B%03Q$0L#w1vZ0P?%heXg!DLP?%hdXa$Ea zrZ7zbPAIT5>4lD4u#3}h&niYB8AE2 zhz|aX>VFi4ofPip@F5f?*CX1?;r%E~&OtQH;V~2@S0mcR;gJ+37bDui;qMY$yJDUaQGSulZy~-=Wqjs$u)?!aQF%elS>e-=kOc~)6_Rw!QqQ3 zOs+xH%i&oRCYK;uz~OT!Os+sQo5Ry6OfEpw$>Gx}OhbP(ox?d4rXfG-;P8nQrlCGM z_)l(s3KvkgpTmbxn1=RfFNgP|@H7gCIXs5KG{i@{I6RWVG_*%MIQ;!%2-A=rZRhYe z6sDm(+QQ*4DNI9nw4TEsQ`ke{3J$+R;X(>~Is6)h&!KPuhhL;H4c*af4nId>8nUBK z4zHsy4b{p47!!Zf5tD>!^Hg=r{_ zdO19c!WUDxfWzNBJl-*{9bx{s{#+P%^>R<(V^8a+gWlOip_GgNffc>bxKD=YG3CoY zIUK_o+mYwnv?I|u(B zX`a?82O$GE13zOu!6{dCjdvL1&_ad>|7=Y;9O*_7J1xZ6UpIp!>O;vdi_Sv|`n7HZ zqEPhqhqx|HDeEY0+M4Gs+f30I6w^I{C8%=Kpz%lKSrJZK6iSS z5o0SX#Xw3oQVhSqIj5FRon3*9WIKHqt-F>F8CEW-Cc0;O;95`ud6j zpKo-cVB^+fz)oPZXT`hzR8QbT<0y=yD5j6fNP|r>_5v_)aADwiWT6C2$WRn8DE`;r z0b_RNB~ve*dYRx~=i<_ME}n#LgNwuMxY)BGGey zA0BQO*^SRIvTpcXM4k>-jT9;=l($Y0O(W=Wu&#)P@}3tlPZ6a8QCvHzC{plKC|h8O zfresr7zcHMJc>FX4~EkD(Hc(OK!T(C&Y=dOxYlqch0nyO25wJ4w=#+`Vk%OPplt?D zB)N#hP|b+(R}6_N!5^R$Qci~nfoEQ#@l}RC)QLXSf%JGrjH@VpD5L9M<_!?>)(JLZ zyloZb6Ue-Eh~hduAus$?cLyc*1WFBbp?-w>sVm`$wsQC4iLaxze?;rhh_qX&!(JxS z^x)ZpG+{i^=I(Ah@r|WTTN8#+6TN(2kvL-f9s>6So*PIteorC`JckIB%w7K(#b~H3 z-S`9i6i;9)^-SMU_(_bSzI#$z;CU}pz@$D4v8WDmt>RppICZc97Uwxn;ANtbf(Rve z77r1*hKNZ)&SG{@>4@@IBltL!w#m zh!`{+qs$>8^@#CzYCtxB5#wbD0D8?@Xi|}Jzb37fzo(({LjB`)l{mWv{+^WEC&@Sq zG=0mYLf*`v`&$z7+r}LDfvRkyio0ma6|m*fe21o7_8@e58B!U)0-Ksn=0h?)5%)Ik z3#1do#@HAekO9@ON7Q(ybPR(K>0!ih!uurQ=A$X7k5YY`QC=JRKnoJJK=Jw`?)R3W z@QAxlve54dQa8Y(Ak{PZxwMsGsf){Jq5p{(3{ChyEOZ?yDZD&<-DMH?8$`^K=spT> zKxS6H1K`8AE_v^|t5bvS`zE{JYuK}!qA+X`18wf7J)u&3-SdRO-ONsVEwz^@x84>OVjR^wevSe+`YqaFB4L3>fbX! z9gXsfyd!#B!z}@K2Z6%0LfBI`OtI^1>Fw?+}qODxVu^hM=TGgt@sV9 z9dvI4H}_)bB%`z9Rso$kCT&HV5DHp9VjK$95cZ=*5?z8EvZ2XRrLFivOaAf+lpOu- zTd+swmx**s)BzMD-)DbuIM{Cqd_ZZh`DS=nC%Bx-kFLT$?E@p)TbFEe_?I#zwxH1P z-LZ(bvqgJuAWh_s821PuSiB8L3z@Ho(F^`GPMY>d`OzQHOWTF!?L`c+_Mx*h>vqe7 z-qMZU(iQ8W2u6$z=*jfF0L^6@(khh5u^lqD=dV&)jNT~G*B}>2>*+yAixgi-tB5Gc z{1u#%>~NQ`!5b-^ar@UYi4Yj{k-E7YZnU8T!%VtyEzCZC#PuzNuQcX}h?!iNpd<#W zfTamEic)y&a_)nSy;S!jV0#C~8slNB22zYe$Ycde!7z_TFM(GwJsw?}Wh70w+kw)~ zHusYjkzUDzLc|y~sEKqwbBV%=Wo#3K#|p?Iog~qvB)rhLxnIYL^dCxI$Ulx#l1R~s zXjl^>{c1e5BQTQu&WQCGWUvuyow2uw`1i#cA)_$XcoE$ZV%lBQTIlm0yU37s6A%(pvv86?>kHT?(eigv*>ml;btn-GKYs zU@48t-9k*oWRTZRLl1+?v2g%Xq)`+F z$`^shXMiKZ-2tcggg*=XD&jrx9MCUhvn++CEq@oYKep`=<7P?`bhi_gi@7tCbGyWF zG|_}@wTR*dz5mZ}^(O$NW&(E%LSl}ABMJjsbed;?W>KJ@NEQ(J)-4s7VM$MdYPf70 zO|CtG^$W<^2|PuslA@Zy74+M4#tMpQD)xj{)Z@q6^F^Ki@TFE~A8I1&%!yF#9QYNV7zxZ00OKHJb(U@=V+q(rN@&v8M*Ll#AI*D3|`7U$STiJ+F`Btv&B&T#gX9E#Q&FIr0%#f^}TY_Oa0v)!|73pEfonsrhS7KfmXgZ}aS3%tDdH}Dca zxp&dzeuSL5nI0~d1dwOYbB22;miwN>+;7I^#$p1GeNumHsaY2nQb;XT`N=d+lbZU8 z+U$dtfP{<*kQKLxQj2s?;Ia-hHB`T}y(r*oL!GIE0^@r_OMY{rtgGEX<2-N*xtCqIA(sZKqwZf;5Ykr+D6rcyXW41@%L zcreQ~I~a@XNwv|qpL=l1Lp&$Wco+|9MU&3(Pl5%8?Ob^?PuEaNIv0jMzX2Kp;YW-X z>OW%Ao=M@0os?zD{JSwLx{`E)xr-RKGyHuiu}lyJ?{bEJI`vj<=18-fGT8V|eTIKC zr4MEN{U+uOQN$ZhVNKpX73CAiyluezgcJS0F~fg>$44?=FR;ncXZU|ojM5Y_dJqYM zXZWqycI34olnj1k48ko41YBdV~;6f)H6GM zM0*o@#*fVK&y8{S8P@2M&G5@Z+$=*onBgBFctDbfu?+%Hvux91+05`OQ2Ast{KsH9 zq})b8Znm7+&G1_?V`Ur5wvlZ}S$&r_!@u(m=<>ZtWn@ECKQ_ZZF~-KTVpX#T`j?7s z-VcfQn!+OEy;Yap=y56ti{*=Lt$_#Z%HEi?R2KH7;H z{x{UscRa&ikFDDs&G1{H8p8Q$Q6n01Xw%^M8U9309x)F1OrPO9C3?iCQ25Ze^FEH7 z;jjKUZeE@CUzy=Q%@$3Y;Xf;YxEcOe;7_aCe_)1x+`%Nih~YpUn#jPd=NNX;4k zQ!@4z2ro9nzgMDnlkh_0Uj8snqz4ftDbglRNg~B49~0?V8XR|JhCdDF*hZ{%#t9`AJqa`yfcGyH~h+xjdpE)o%Xed5O)r7oJ{S=EI7 zfecZfOi`bGsXpig|D?9jX83QivmG&x{s6f0Ow1Yn(=zsMFlC+L55n&L`!oF9k)RyP zc>i5(wtF>r)Mxl-zb|;dnRtg1#b)?-L)-P)_`^c;+Nq{nxHBi4;ctF_XJ_~qfu@`= zUQXoy{TcprQRnD8TAf=_6Uz+W`<|%wYBE1uZ8gJx0F7mt;Xgr%lFf_yp}Ie+MCe`r z-VFaf7C1S{_mS@ej$fLAk$us(fTL)P1n%Cg z?pNSpx?e#{z}qOr*44%q-^LLlZvoa-k*JG(2wDaS5OO*(m5Pf z+*UemZzW1+R7^Sti)d3i8>yu<>6|8bOq5P15=!a3i3UdlkaWgC*wWf)2oJS_7p!!+OcCkY4VK!T`LD6f`h{wWjNL=|hnDiU5u z3HQNpFBdsC5DBqUvwC=VSnj6FgHTY3!FWWTQW0zfOMigL9p5XG083l%{-Jg7Nc=Bz z$wO6gwvP=2;ejop&LevSvXSvdm6k3#IEef`Ej-!`wxw@c_`{x_R`=kDfsYWOP-2Sw zm)N?hGq7YE_GDXoMnKW8LM;OBAHZ9ncT@i;+DIcwa${5JnV=vs&=7Ne0^1l|92j9l_G zQR_Av8njI^*hE>8tymBiS?S75QI4`8CI?(PGQ_yv0c~1nmUP*C(GJYOfs!)EiI&NH zjad~ZJd_lIYOTdw5mKXVP;kD#;G9Ir)GNpiF@K8d*g23uQ$M1>3uW#1lY5FlCK;4; z>I26?SoGXZLX(S+wrlyKY;28)g2>2y|3)JB@%pP0L*6(oB;v%;xn#*%e z@s^pQ2PwLttr!z%A{;TEF{1#xJI`vn{|J$}11UNv#qDN_PNY~(+Xfh+R?|UDx#4y- zQov-1L8l2S1DhvLDMorJ)E7NUC~i9u^q2%e%-y!t{WGvHHv@#@fJ8?#&F3+;{S4aF zh6J>O*0!P!|F+yu|H?t`5<2@6kUr$93SvH}HqyplBaB@!(zL9nOb*)E5Ya)ASg7cu z;FE^Eqs`b5lL}?bVTYFoztcq`)4ccN7@;)p`xXVhA~k*c6|Qfhh2M&_YW#yLOADX% zs%hchCq)mg66!WmcYc*7{2nRfaL`4Gmu(>x)yGRdctS&@###OA{xJL}*I$atx10 zr<$wFY;8jsE8FRKj`Jhq=6jXmncWXfS-mTC2l+b|A_d@ce1Hb zn-Qk8#E6J;NPpZz5%;$waSZw!$n8P4(~ym;;T{Sqmk6UAX}#P-P$dJ7wP{PDTs`($gLpj0u2=ND70PFca?(qssdv=Ox|-gIIj|0UnS8hf$>; zLHiFV8m1gIkI~eGvegqz+4nkO?|$`SERh{3r4r%^H1&#_qC75>bP8YA4$_d=My|dxMw_wB z;6L{y^ChNg4B#Sl0ubNJw&`u70NSS2;XhMutF_!V0chp^9Nj6QT&Ylk{hg~TEf#at z(on>J*)#`nfe~Z!cC+n`D0+~!pUcdrk}V8n)YZo-yCQ%M!Kd7jMp3o@hM#T6Q9;PLh z_>lX{^fr@>jagYX8ljW}xj@~5i1MCIq^Om5PhzZAUOQxzP+sCG>DDl$7cn|;R#K#n zdBtR)XwSLnA7sXONDU&Ho&PJ!Wl9(9fYM1ZN>eSAAQNpyMw6a6UJXA6DKxn*Bh|_) z;ZfLW!v<J8c~1MMS2YV=W49#kKbaMOd4 z8_b&-O6Lj(=!j8Z9GHOV`TY6tK6 z;H@MMq=}IJ@KFIe&dQoc<5=7nV$RMj{?&arDqt_4P8|KS_B7EL5NgC&W9ko-5Az-l z^1L?9lJApNj7PSY3<)Gty$vfIk}^P87QjR2D!K3*@CHLGYatp z<-^|JAmvAvh!NzpQu!IFWZi}m2q)9*Qd;?t+iq(dNFl#dq%r zL24p2AN1Q1iLbi@3i&swL@q?NEVB<_DCZMg@*y8yHq^4Bbv>hq$H;i}SARwoF22CPU2yXzBQ++Kol!85D z1;m?m)Cq1}h+Ni)aVNJIoX?b{OdWL!x&KKqk5QusC}yFGA$$qA3qC?ED6~hkFx* zg-8gB{+H9yol2psMyy@HQrTZkQG?C6sFOA(joL1zmP}E-$(wr>B!^MQ`X(%v9=KYxf>Smip=+Ob$T)>mM; zLP%oFf*{p4=>BSg$kU(;5i_uF9JC0KIXajm(vp%mHIW1@Dxy_bLgF;OlSeGMgtD;! zs$jeTk6n0QP+Rsg^GHM3a`C`-&QEDwST50Ai_~(7hWkGyYu)1HWg0Fg=D%t#&Zc}& z3}tMuK}`S?^%#P}2Oz=cN)cP?dwC5jkVpf^dE+T=f9my#z?+*>4! zbwB)Z@Bs5AX_o$k=tP)ou&D=&O19QK#j%UbPxR2%Tw$t0j36za>AJ6dTuAn*#Q7A-N3a+}A51(P z{i$m)O~48W#5)0%VG2l#*W^TKTH4{*JQLw3dDxD5>OkGbzivk}N1qPt=MS(9dOZ5a^A(i`{ zsAFOgcpY*>>+y(KhMrOs@`X2MBcD-^5k%-D$UZ06!lOu17HP#u>JNTy-SJ+vH#+=2tIZ8RHE;v|}gQ zu>*R&8j`{~GTw(KE<)xD{`FX+Cb)v65#kMt?hQEm!C)yl;PM6iBiB*_L8Ao4#l5{h z5|K&{T#5@RWFNobS^Okvv~F3TrV+Y=umk`$(#TUg(oSP1#)+YC!61+1z5S{GC@ zV$4N^9LB0Cjb*1HT}hw(o7QlJ?&eVT3E)_*l*Ri_wjqdvoOxP!!;6|vuN}Zaf64Df(*v%rKb+9aA{Sbt;{_LchlKT?i zW%nVdBRk#LOksx`#+XOpQD{NtP?CB5X|qL@yUG5NX10T+pE4;m&cgyRsqQD46v0^_ z*(>2+0UkIaHi)MZw%YAN}kLyBFrBB3h3n4}83Ip_(p>=5fsO=xq~d%2rZFCC?^2Ikh5M3d1H1m!fq1hLbS)xyCU9#Qbz`{1UzkO>s!wXeO2_;vFy?D4Pee zJaB`}jn*aKIu`Eb9u^Bu46Gduc-e$LZ<3DqYCC zm&mEd7Nm0%kS|tCySShjJDMwth@5ZE?3mPK?jqm3XTj0l@ z1`AzQP4zKz%9*jAGpDRkG`ej0NUW9WlkqZ(^~rwXNOU*|hdO<~Fck<8I8o0qoWG}` z29!PTdz8q&C{L3w759O3Q)ZL^V-_)L1=a`ag)dDpxSCf1CgOjfWw4O@b4ogb_~#@M zqmi=7t)PRb6n5v48xuz@>dSvn)K(Dx9EE~&F_VfID@ZJo?qvLq-bV#R+y*Lx-rzm7NN;xARa(eiQqX&A*HFYLy?VHi}*+T1S5OfLINLTxn#*l|8th#mP905stms z>q5+Ejw!H-8Obp%i7_p0;DsX{_#yXn_QJ3o8%skOOH0R7my5IW%APYEe;z3F_tu$o z4{THz!!DT`{Eirr<4J>QXOeBiBFJAbAvgppQ0N2D!)VQbhMTbHQB7mG#?jN+2uyjo zoES@q@PiDHM|gus4Vl~6g}~Nf=miF^m}y~t&S!q$c}V^)5n*Kpd!-q?959)|KITt2 zDyumu-T+BriUQO+{hrWaBcVd=(m(wI=VSo4BiCwA0E-h({nY70%U<2w>;vqImGjqtq|{rb{(RrFjMsTSk%o zLK9vg8tP<88V1%MC^57o713e*?vi?THJv16 z4MZVWQjrT$zkGlQ38F9l7Pe2nMshJC;})VikwO~7f5B8qbEmeel zlJN#A*N?8>he!i1io9~{ULkFuVCo#o+2;wQQlB+P@zH|uej3w->p5h$k`aVdP#Ot` zEKtN;J~BM9xhokC3eyuUTlZ;)dN6B^y~1kSumQiWP#flPdVU0%e+02NtTC_Z8?_V*S*JhrFXvN3%|`9-(Ax zBBsqk zSk$kfbg&$3F))1KR6cgYMWiqu{bF1ZHWG1^9A#&rFmz4!L2^ae2u6%%l&#uI*(mf* zY{>*ldyuzJHAdQs&xACAs&3qqq#I)}MtJzsNmIz$bpmtkD1K*laHDokI1a6J>2Gpey@B=R(Pqk@+_ zh-w*mTOpDGhrpGhk#fv3`Wfn^1Ul$fIIzDta3 zAisPhyY!LVrB#M3nx*1hEEUctIo}!{Kh?kIi zBMH^}E42+{Qe)~+PsK_$tzU{j$cq79m1;>>kUxL}%x3wt)EUYhnLN2hwl(a6=56$Z zmbAy_s11jbS~9(0z0(s4IZ0?CoMH;CC}1&0j9Fihq!mL@uT>(3o8fp~a5mFEL`GhU z;laDiEhU!1J9lezGLed1%Uo_^MICRh;bQz)X_*6i;*?<9JtRxo_ACzbu*jKY>kEeK^M~uRhwIS^<$AZq1Mzec ze6By8&s1LHN6f;8goYJn#yYjAj@-L4l`LZ1b|<`*YTAO9GP;3)Q2^xL8w=_&RDkxT zj}_|zsAI&qj1vlg<@R$VlFqW!Va(W&Nczh!K|W|i-(c)~iRt|*?}+y=*i^!r(Ha^a zw5Y1qpp{Rd#t3vG)4N70^mwd|#UsI%(J*xJSlXHvn&N9Sd!9;bVVc7PO1BA;yqHQq zgQeTV(KRyl)?Gj+j592b$QR%@lE6-4-hL9^=z~ei)3JIAD}uv^c%PJaYp}BsGj)1x zLmBsXmk>WnHn;D`pCy`uOcyT~UrX z2OWZ$hIufTm*{daB~>ZAz+fBR5e{W6ni9wSR?MPWuuJB@9E&O|&qEweqMhOiPMJ58 z(xsI1Ln-N6+Fl2d#dpvn??F6hPM>iRWeldw;)hDi?|YGeP=>k-Qj^7>&x~UPMm-g# z`~r~KTVvzHVy4{34@G$`pY{r6d~-XqakOINHNo>AOrA5TW6^7832h;zyFiof?9~a< z4P_j!bD43z;N~2Yn|$uMwBr*$_ahw`3);!b{iRm!d$*}_#W@3NSc9j~81gsplnvDA zFCjtlx1GUKLp%=s9J{HArL&G7BpoNcf*j2Foxp!>;w%VyeUN$|68-7qd3WP=M@dO)S9E%5wsJ()vVeuz4h<}>Klo~kP2;X28 zu8;T-yoUip9mUF_G^?S~4?W^&8Dg=$$BPku((vV?&?RP}D9N!l2UUigPg~8ZwEz#& zaFCts4s*6*k!?nNwh1EJ&~2P;HfK}JsXaSo&2iXIoc+`+9L0q)s(;F@8)y4O%y~93 zJFtpvtCUWmMTqj-rzfMl-X>-TluwPL+)WB3#}nZRwv&a3yIC0HId?PY)4rtkxc@Vs zn28;i7Qak0s)9W7sC2Z>0ty@72L*Za4ub#piChzDnvU-9cp?v!07G_}JxE*8arTKGK%IPIZyq(jMrg!V`jeh4NncB~=sqF%Sn}K>Tv{2HXh2 z`1yiQu6W4nmCOx)GE@oSRb> zVkzBA6qSG@#*_a-Q1sf_kyPRZlb9t(0UrrnBaq`4y-eF%rc5SEaVydfRKBs z#^k@i3bt<2T(Ma0bY=%(R5lB|B(sY3npND2x|$~^oUFy4IziH`hy-7A8Nb zT;0|%q(#0SWK%%IpY*sGuVhI!+=@<`;GHfpg0M$T}5yM!uN z=;lV5#t*Zd=Zng{w~{MYiaHMW(#0%QG=M<)z2+GQc`iX7)~DWMj#lu|njlNuo@wa$?i{=!hsg6A7r$G4m$Mq>Pf{o?GM?AL7jy#Fb?TYaDO^*Kig&{6E*gzm2%SC z6L7G)SIih_)g>RDtPg{CZ=m##fnp53v_2m(o~8}_P{s{xvk4-_?+YRgFB;%iPryru zI{MUPfqri-a8kGHB?@l~<3WN;XXid;FMg<6ubnCcS0w~@J08?Q#(grKrTiX0p!)rk zEGYhP$Oim|q2=>BBo;OcD2=Da*P%cZPU|HQ74huNRBjB{>0d*pK|JCY_$mJIjoANG z+7rsSWfGN7Ek{+ReOM>j16S~mD-@hfQ=G+hDcdP6QNfu9lxy+JMFF_?TC;sGhLr8I zU5oXI?Tx-*!B|}SGx@pyBgw9r#=?4(AEsnWNJ^oMy?#NDyiz>a^l(;I%RaVXtO;hT25_adB+Z~?+)2v<-(+2lmgqbw~2%Gi_= zSudH=Gq4|X14d60t(lhI4Mza281R-2T#JwqAj{a-=JgKL&<{Ecg35x$v>Et^-^a?^ zG?gp8jvvqvC)-TNx=bS9x}-nTlQtbIhrE7V+#%E@w&#kPl%OW=E)?92bwAXESCUPx zXsn=sm#tqPIw`gyN}*+B{mfKk{U}hTS-&j7*m%j9w0;XkYg~IXx5ijJL~Hzr#Hfc+ zi9KxnP!t?=W&QfdtUx25E?`M?@dJ|ZvLp~gtkq}IbGW`@xV~(--V3X58hf@GvA3#} z9WYGO6l+T;hipsQP@}dy!~H3n!_!6K6J+7Cw%3ZSAp`-w9wYMmJv?@K;Rw$j@%CK!KE-+X?3zKQ9sCO80JCihmObcV=ey{y@#oPe@R7%FI1v5Wb?Y18xTa|cQ9AFky5 zh|!#R!W9iPB%N`RnVPv}#{{RBtz#YrOt~(mY&+2kjVr-iW!+TP(!2|QPFgx8fQNDI z&tRn!&gVfE-}c6QSL!KfU~QXLz4^m0dhyr@wJ1vmYiRt4asQquftHm%G&<=gwG$f? zFX;$vt3p3;-VbG9q2Au($?VOc%1Z7H+W;3MOM$1&ok)#c}nhh(zTKx8qj0C1TOUvObt!A?xo7O+f zDMM*WTS$om~0YqK;X-%+M_+k*HmA6%`EJV`HEXg+d zCl`1PqEKKwU(&ugUrHV~?fMv_Wbn+YkbDNoZO5w$d(iIzK9geGcVKlPL&3=Ld(m|- zwtPIxQR;+^ZBcx*I>9c13kdGFNhl*0lV1ID!8?)CDt-I*Pt5zSOEKit!!8JlzjZHv0zX z0$Q>Uu13E|2pHFNg07lcaAs|-W%F`m(cb>C$fY(`dlh3Un5i*UNEB-=Cl5H1&Fc^a z3km(AFSqk}RfYfKI3XGm0Nayg1XAJ%%o&rl)x=Iwq;1@gP8UbdWYN5*V?-5w$YrS@ zlAx`KinThmM5Z~0QnkeN6i-Y~VUf>70sSQAH_dVp$K^uU+yF0#LMclsys=av0lc%4 zt@7T^dFkLOH_)pb6y94vUDfkBKr)({>QzfQUry4a!BKAy>jOz&_3mrO#@Z?_Kh<*q z>WQJMsU1qxF08t+O|O7XsI&ug5Y5odprh>mn}{A5FV+A%ND^BpJ+3H5qhdYvI{fYM zZBSR@U4KoKZN8~Z5GIU34vGM~2qe6%$1#z_Lm7ly`;e^oQu$Xk=BA36!>Z0>v#w;wqD(K!_Fui`2E3>zm1g2^P0Nf^Db+OR+exsW8BV z=VR%Wg-F5_f;^0_z?5Swky7uBvmncfn(&7Xp$<>-U$%w#kvgDStsAY@g@wmX@W$^1 z7X^w{E5blY`xrYV1>>C5t=3Vi#EKM(MAh@u8VZdM~8v|CCq~f885-@mKKv z7GsNnVa1Pb`%^j0@Va##E-l4m-D7 zhBDscNH1EMg9}hkn)$^IM^lNo(DGau3$hbgx{V8EevzByY$Ays4b?=th8}5TAGkjmjcUZ5t5iP z%4Ry|S#!-dgTz>cD~{e& zox`}8X^AmZQtOgI2VJ)=CKNocp;kc|J2n12aaO$kWH?t3jc)y6wGxvIaY^$=$L{>fJNiWCYHK!{UUnyk$}ITpGj}v zK!VjM(_&Y+XC#f0r`7lShC7?-J7k(hE_hkL`PT)=w$rS%10sl1#0xFl=#fLKP+&`WdI!=YuYg8SireP7-tkbFZos3t#?%5`WpF6ej|V1lef$XZ5*S<|Qbvq_tQ{VX@SlbN1xIAXXcSLYH?krXzwiSu zg0DzdKSQe=_~{9)aBRmz=;cd&Oi);!*j#756G@6>${;i02?~~i%pj&dIA6_lB8EZs zM;=5Et|C@Fp%6#5ZpxB&;ToErNX|p6oWzLW;J36;uTHV!)|W6dq-waBe6B%yZ+FZy zRG;XVs2}K%Sg0{Z!7mS>X9ytFhWGl26;U|WHic1oA;LsC6Aph9+pW*#OF#RMSh)lN z7OfeHmS!h>1hH+>y!;@2gAH}8oyp8*eA7TY=N$+BhI^l3_aUZa{x_Aph^r~xZ{uuF>KAmU8`ruwFUvceRxDIlg!gehJ8#d?xNAJNT* zRItiH9aqf)m8DA@F+O}2iD9Iq*JNw|UwDes^b_&*Sld98;s`Izx(XnnCOnIcb=1k# z<~tBMV-+v8P?*Lej1ZQo>kUL&u)P>99yfBRoAH)y<1PQddV|&PseXQ}>f=YK7Z2E= z9)5(v1VYRCK}}e|^Pg2Bk2sLp2Y&*8!;D(oH=bMka(4> ze$a*WgH$FtB|+u_os4-3GKa%-8BU6zzuig2=<6#hC@;zLA6P0|7iQVTEwK<}9JY!Q z@gFc7N1ni8X(Z!5YJ0Ra`I9D{$3UkLW+5d1*h~`-9w!iop@%EbO~B37%tlIma&E39 zZdww#A;`E12N5MVbSYRbmd|nZU{T=j#M(LShdzV;lg+||fymSUxKo0!wM`-jJ zBOF#GTGJj7E#Ci}VkDC_uX)zKhP#5#Uu9mCUpin878-r~(b44%lkzGI`JaF0Eq}Xm zW~mH6b+yu#FHy9XNpG`y7Ql{oLx+Ci%?*AJT3j(S`iG_?*qX zCCMCVp&MVG%(b8ERIdG8r%L+co?EiEJ~v%HzMeH%EZU55GNpix@@zq_^@#%ROn3Ip z1BEnf3&QHH&Ufe0B)0a?xBf)+Jk|IuBIyD~TfRFbp>l?r{0=!!ffFj9kzN)WePg-6 z)F%P8?<}fRiGa^vkr#Nc^#${kLfjdPDhDnW2aC|K1fy7Enp+W>6S+6Ze7h*Chl}}T zdbp5B;1RnIGRB3Dd7+APAC*eGsqfq%+Fkga>j`3OO30?tD+le3-dW~=vl`iCXPGyC zUoP*-vy-cHRPH4St*zqdJcA_cab&B?*!7Qi1#Fkv2$lW% zh6U}sp0tfe5v@p3Lhq8?%66?%M%70;>RSu=#p+UCuGTK>G<7L^0m$M7+g$49eb<79 zzb^;Ibba<7b{T_H_~)*nJa0Po!0I)93BlQG`UVG=9;i|> zC@Q4X#HKblHBc4Wu3B{PfvLD;r&dAl>nUU1Dv2?c`uRU)#>=H9 zKeui-s^dkjA!E*7j{dO<9X*oq5i4B4NrCphJ-*SUF>L($hSEe)5Up3$L>BmjNP{^@6s=NY~ zVwKpnXzZ+jvuu}ARn+CvKq}#M)m}30QHs7bUT%fhb#remBJ$e1*%8{YAEE}9h?pQY zMyrvo4qrLX!QqD9>8g%jwi~^hEUJq;^-Ut5ZhW-Zi5Av&OY{~*hf*+d-^9{=x2wB7 zo3|Lrgx&2&{`wo9O} zu|~^|)f6qNI;vDVdg3^&CG;z02!cEYmw+YTb(5W@*I$+zg}))k+6X*HTYH$RqzH^H z54_wyrBo3o6sf>EN!vX7#RJcn$E-+3>*xn{KRsJBq z#UcKHi>M;66aCa{E$QHH8<0qkl>^&XpQ2PnUnegVuCUXPf?fq~- z2;;e?sg^WPsnnLKX#rs<{+Y`y!x_-rSrA(*1*OWwYa;%p`Ik>^@Fwqhpkh>`5JQMqW zEk7dW9V=&VVw?VCDAR93qyIeAnUfDV#b~wU+fqe-&(=t3%dkDeO8Js928NNRZWt$P zhwdQuN@DhN&UL2nb7g@kd95YgCc=(&t(J5n)drN}3nl$9+8j-eKH}HO)NEe52Tjqq zRdp;9>&sUAa(A7Yxp3(kCEf8e34vBqrvInXCd|7TL`av~ZlTl}TC1>SQafgg-l}67 z?{~J^U0&qnWzA_@)V$xe-~ef=9>zqN`o1vutF@8U3f))RYoq8PZ>$xt?DlDS*0F!8 z*!OX_y;S==$nJpIK27Z3S=Rwc|Dl|@)$La**QK&n4UK;5U$NT9X%O8$(kLqL?z(n9 z%Aeal5&m2%TfDjyflMXS*0Q)88yTcvWUB6Dl4^6FG+PI+$NmaZMj&mtL7 zB}*0d3>~~dKXH*e<|f8!R&e$vnhd+H92r}!D0RW#P|l6HZ~s6pt=~)f(LHkUN?_d^ zau8y0VEtl>)C(cPuQR(f4?$q$B~pEGr9yE+XGhUK(nRCwRfL-IMJ{bxCGVDQwNF9T zHo5$^x|GFByIfw+rPjGaE*GdvY*5ol3f40pEodOvspq1-`Y1Nb1tzewmd?7?o*6_% zhJ7twKDpCjV%l$|I`%Ddg|O&yKdBx2mB}%)uVTLlclt9DJv{AUq%)~^Vy9n)39INg zlqTjh`&9hMNgGkd&qzD4hxf)>&r*bHLU;U*Y&~mHu?C4uijKz+oqXl1BYLBs=~C#z z=a({TTW|$dk!illsfOu%rMfsZ|F7vg?&b@LadOr5ymSR?ccSSkF{fTc>)FO^ElQ=d zCLoVVB5OkR-$KjxcI?8~UVA5ewiKpjurg&+R);9>P_%=!vfa8-kh0h+1c^Xvg*3pbTvx{iBv09!pv$6y6z=IhWCF0;j zulzJ%RC#)8+(&!$22a6iO68A9D5^^ajuZ3^JMdm~J}c!%q_Dln?oYNzcS`vC7zJAb zMvA2<>Mu%=y|tngQQ=M68s}s7ZJ%9nW@6eZsx)0q(^EQJc}{SOm>G-aBHOWt^dxF; zEp^meZmczqQdON8c-xd}lrPi1-Qf>lJ?tcn=9Dy`IioFT*+w$iO_HWtJ=WT3f|5PJ zS6;U=?>5$c)uz;2qg_23{7v}Nr&ZQYsqcozr9;qP z)ouYnSzR+*ujwEslNMgmEHm~mB=Pq#4!`;LXT2lA+w^5eg57;an@0P%V3*w4r=+Nl zHFU~GB`Qu|oA`(mw?Y9OZ-q0$N^wU5i04jcE)EFc#K3j4?8uo z`;_Go@>DH`8(F6b1Fm<9CDz>0=W}*sqLU+fr8U_-gValh5Bw5G8{ng2zIU;X!&xn8 ze_bJ}uUl4lh8!`hfUL({21&;JHnMZeh83x=$i=-ZK@qNlEt2d(PZEBE#~F6QC`x`< zH%b>f{*f^g7L)XekT+$;-yrdf!sRSstiF7P66eHr$?Mo4x(-U}r?><=2EE5UBpVV# z!mlo%6e;4B9v%zs4nKIA<4aOSTQ?P(WgEm&BAx2eaC*b#_3ZvZ43Aw5A3ez8z6ySi zP?Xz-qK%BYu)D*b{7&j7fm#P^c4SVsxr2&x;<$cNcDxuv5E2#n-RK1 zG?q|b&!2v1787Y@=VfQsd2#i&HoodY4pBdr^SDt*jM{}!J7dgoJH%|8{!6TYB)Z@F zMZdE}Z81_jo=D@N3myjE2$;Q_j4c#ygwFYJ>zsy4-1MPdaKbJnMGw@ofD zSC@V++vPGtm6yaNQ{-Mw{^c}$!hPo#R@@(4i`i4xM#LA(cO0*>c3mdOIPG$_i^c6< z(<20<9!?)qgRvxxXj|4*>hCmN;=oZ%ZP3XOg&kGYQ?cn^bThikbbX8PF9FY80)6~X zacA|blIIFzh09*)&1*Pad7u>?!w1e2o8CQN+E8W+vK6SLfA%r6#ve&XWY#!qp&)Ls zJN%@4jM_$5b&ciWqN3f~FkVbM>c!OE2m90v`9(QM6=?XWPr=4MSxGm9)Z@kV>R^C+ zyR15bCEB!omt|vi_xkK^zC^yJ@0-Vc`!vFwT=JF(>$$wHPqjpH`_At0FSwK^$m^d_ zC9T&I#Vy;b#1-9?t0bfSU6JX(;ER12U7j8u?)T&MLq1a=8SzQq&!vtew^{FkQA%9iCVUW1`U4ni*CJkl3CnepO<2?0W@*X!^G1oY; z8r&-sHfyJ{lf3#?*V1`M)sHy{kiB-lEXBx0^6G$kq$}4-^yBlys?IA$e@~qb+$LSa zwat4NBl-xyF&oLIy}bQWgJQ&{vE)#z?1+(AyvKfRuHM&kVGk1yumL=}z47mcDFA;Q^MiCeE7lG=z7N(XB|b>m^OGqhWSb%Ucwk67e3 zxt#tQGsTz%D+>&GOX0N=?^O0<zYcXqlaN7)t>Q^!G4aUv{s>bkBX79Q-ZeY$PL@h zkx!0vo&ApW)RQPz!hJ|E>U$PPrQG`RU_lAfKR7JmJ%%>=anWo`6V*5>ew{&P9_~68 z-ox&;rQ{4l$%sKi&+B@nA^xf&p`LH)_?;%XY(KI4hLPh2DZqU;7ANIKWDk%O8hyu~ z{ZSqz4f|wk*oXNu}{ayX>r@d1lH$Q=Q{IMThq|!>?rxv^7!I)3%X{mK|roz6a#AA8WC1zU9lZx^%wQ4cTg&*~Z^F0p zC`cJVzls)*Rkt@i>fFwRwr}4d3uGx+oj-GKr^_h_efugS^-+&GsSAzU>X!f{_4>wE zn2Fspti(i{N?PVI{)GTR8|yqu~Y8=^^VB(J;$yA>K;KQDk1;6lE&wed>$Z4N`k{FophsS*}YZ18=!u(t>MKsc^K00(^dhFl%e1>G~^GPL+yTY%m)O9oSZrO`@v%j4wk)(RU6s!nQXMS|1LtP-@8~~>brod)GE_2JAG)Q5*V6~ zJF;keC%pAxBRR=5uNB;?`m0qHp9t@fJ8o5U$Xxl9lJzL(T;_-SayDf{4ckhx8VxOV1M>mO> zci+(~14r;QPAcAX2`3d-Dl<(zbB{BlxyA@XDqp~QIvKe>p7^nyrzDo zTtkIAq9+g2)puf)!>Q+Os&13zmE(Fw89nA&`#54Pt6o1si|0eSUN6p4rg|K6hi|$- zn~J29<;yASC5f0U)TjpsYsUDS@bC3QcVUL9VZ*7&Ej?O>^|B_M^=|u4s6JJvWi*um zfQv$*Xhi*t@r-HQgKa~ zz(;SgudNUxHI7tpQM7_?6C90pnBMYDzcT_hsBIApq#hyYn*JvIZFV-SW|kq(zWunG z7+5)Utsgo{Qbycr8hGnF18?20Zb=oCNvJelGy2}Y_z^ecE(HUoHp)PeQ=7QH6k~4l zf>W~rbDOQIC1eVso@z3Zsu=p&P*ua|+n>h1{g>Fc531XvpZY{quSLO^&Sj*!cAGhK znXD>nbr#)!R0oJ?#og>A#AwA2*j2J_OV_p=_ip*Jh!&D%+#|#7Jtfx4p2vFyU z+2=&IP*9(G2dH-hb&FH?0CkU`ij}oSzkE>DwoSp8wzJfJKs(pToZp(W%F48qF5ArH zy%D9FRlnzblWYH545zLxq3ZG%T((QrkJ|M1M@S!l-NU6) zzXlodbiw&TL9C|>GEj)y1+a7*mTo0a8_wQpO~HTiDdWjU4~XR`>NHW#`cCAk^X0Sr zI1y@url!o)N%l-tx7$U|OH8sK_TSy(LMFcG8zoweUA8jk6;AV7+slD*XPCbDb&IbuvK?jsEO6 ze&r)-n37RToffp#<@ROV(`eMh@LB7$V1h24PPjmXblIl`cS*m)_l%XSHSZ%;uf5K7 z_vzHCUTUb%64plS+mZACdQCqIN6Yw{_dKT_kzHk#uDNp@`tE~WcnjZW&(v$ybOjsb z2MYpgUX&|e&GmuMy8o~ioQLpAvJ9Zle<$@FCP8DhvEuD-cvwukA5n^`cvtmroNL2nt}BjmDVh2mGX)x z+^h;vs}q)QF7Zx_OQ6W>=tXE$OCEbEa|J@#s6WH11JyP1KR|x{g-UrEVskt%aEs`> zMHL};p6};Z5?+#j#6C|6v3{L0F3(5Y9NQ-;Em%U_YV&M}$XES<(8gQ@@SR$f&zhgv zclDCqG4ngOO40VK0}MlbB5QSf{m*yc>(r$ZjA9j(534oemk`lYj~BNGtgv&K7Ba%l zZ_n2)zGSkxO(cr^C6G(B9#x`vM1!r+dMJW|58NdQtbm%PKC5q~pPH^R+6vuCG4_`{ zbz5+?)5%ofW8H zFJf(ve^6|r7qNeq+A3Gcm5PyJs$?*KI4#AMpo8dQvfCo<>ih?_v+vo}DP!_)-_z~3 zJN(N#oubR7Xsbqd?~*=ikJmDc5K1GTvj+yATbiM#51pd+UNMs~IeAuHdz@PuOvs3F zZt42f3{es1md3j3zDNye7dH6ar@gX4_Vt3zx0M$}1)IfFwd?&(xl7Do^Ty3o&u!Jl ziR#jB&{xiNgH6o`D%eyg__AQLiyFraHh+6a6`EyFI$xyLdXr0|>22nnj zc4ug-w$*Wh%>$}wojFeVdAh~JsvQUZ?9lImN{=cjE+W|cLxz7HnZ)bwRAZ11HmlDT zN_WxLNQI8aKca)pTeR?iV3Vwa+`wRS-jjwV%xoz)MzHzE1h>cAzImpoqJzzCs1X@# zIwXS`Y<}iS&^7sxTG>Iww(o4LX5X`e&EZY%Jv-PG-sTkDFNTf|HZdm{9;bs?j;raM zo?rc+4r!c#dwjJ+8oyNTs9&c*Yx@ZTU+s{_+mbQXA&o2FSJ5F?fwPy#WQRd{^ted^ zQx^mA4r#1Zu_(qNje7_NY{~rX_o|G83SvZ{h(j8)YbC6@2N4$OK$m27v<5oDmmbnc z_?~K9)j1;$Y23~uMkaNNKBO^?R<-@!Hc+X=MBTkkK{?zb;*iElN{Kq8(L_Np z4r%O`rv+NjyVQivGECYa;*f^DKJu&ek*qIb?*`r_b1}6Qq8@;;@K(=0A68Ra*&$JT zo%ZeJEbar5JA(K8ZNRO&2Hsk&Zpj)ZYVYW#_ml@-uK*9!Te+^aH7scr>dmVy~n+hWSj;JTR$5NbmioCzRtG0oQuXHW{V)fPkGQpwTRP~4#j3v@qhIum<_bds$p>T{hWe_KCiR8tx*kD+IftVgK3$H`~*6DuxEfO96bqo^NqgwN7vb>Cu)1B`c?6-xrHR3?1 zu2`KYpMIK9dhcf`l{|2#-W^f)Tdzv)l5{;%1)0QYd;AX%Z4P`>57nw#BsrZ@?BHYD z@C~wA_joKzqV};)B305Kh z;XyT1?!Kc>UMN>H0Yj$$7DGO&T6Xkb#A8EKPvsUX?BD(hK#k+6s^#x5Nw$|M(-+=? zC%FzCP@5lF>Xqv9J!~Qa7o2xK@F%$%kWl@www*B9OlU_%<=>Kbx6}iDkcl#^HQbXr z_O86OQAyaNTuGOkWPGNTxwkvZFLGk-q9|UU_qIL~Ow|`c)ttsI1(y*)^2}#Yr>;@t z7M(R+{Hu7vdfj3#U?pjJ>+;hZ;BD_wOXM$9{x0Dz6OHtyoHa|+*42Ajy|RhG5j*)|FFt1_ zsh=k6WmA~PmT1I=7u|%j)+CV6^M}bVfAJ|a{~Lkza-@Z4({G2Llpc$LoTpq)3yKQQ z^SlWs8qm65#>qJ`k;-O=-ws^%Zah2NYJ>f_b-Q#bHo6BHFNbYbZN z`5(+zTi5ASS2@8+l*Dnom;IO`{Qa>g*YFzerWYkDPgPBaHIn&R1uOkW^304H$rd~g zqAN8TFB2v8u|3tA15Q55GY$0%Pd%dY{BkLOT7^p zRs@n^t6qk!h8LT~zzsibRIssLK}dFLiV-EQlfDqzs4heLy>y|egEBMx=dJj1ijpu`DV>7p{Gm@K_+X#1unn-u9D6&A)C_Mq8)L-5s8%%9nE^#+XG| z6*cS#KS7z)8rz(^=jyv^f*9JU!5XYoL!JdM50%uZ)X>!BTCoHFg<`Ld5yfPO${tt( zN|Lm5rCOFE z5dGVem1?%=;aXFBD*u9Jl~yD^c#0&>eoS=ARZ1**jC$!kfvHO@4W3jo_;m_Wovl;7 zqdIG7>U=B78kJwg&{02ro!bvA-m2>N!ar3b^|o1S~=_M8AcMj6;_bs zz!gfAHqvM}k+#%aEkv0Y-9Afp%F%6?A`(Vv398n=a#J`x>Y;x)xtv-)LprNES<-}- zh4^t3J%x&lK@xK*e#5n-42^#0MKP(|l9z)FOvxcJN!`TkIwlX-K?iU`Sd1?k-lHE; zb`kYD3GBlbTLCvH_anY&C~-eEBJQiV!>H5HMDX3=$*QKWpfCoKp;Q&p>-xnz|c3?B*gClhPlvTU`?%HW!ZH#l>GbNKm z+dqW!mWlq((9$IpRS$$TJr!EUCFiY1A~)Hwk|FbR^*Bq({6ap)`YM5H;V20*3bLlr zwaL=8;gVfL`D`!1W+@%Hdz(_7iJyHwL0REub$4)t#ozwivG`N;2C0R7xnZD}A+?(P zvFBIfKNchNRc8!MLLugC>fK`-+ap(xs(EB+=l2P}X*8JRVH!731D*DuJj+N{2sL`megTJAA@ur}|r!kCN1AM`w~_CEul*54RH6LLc*cl&>mI zd!49CBmXA6TW(6?-9$KVkA0V9uKkSlin63kdl4~#-ek@E(JS3?FLeq+s%d>2RKDY! zYsKyFO8InPtMij5`dhb{rlyDQBKP=$mr{&!s*hXk_OK22mW-el`@Uku01@Ucw5!U` zGaT4%6e!9YRZ>@W>t>-*2O6{^tUchqe(s+ltU-(ktDN@&bw~7*^Jcs*!u_^jk1n}g zTuHVVKvIy3iiH+nnCy;u4aoV2B={wXqrJ=VS1heddq}#97+o#QlmdJ0TUNY%_pfdo z5xeT-5x?dt0+``Ae(!hMOw?1S0F>y{qyiyXK1O_@H=@7kyyAzEzvc2*OD(rfZb~`V z=a#a2K*}UXZw&J)bnM<8gAt24Z<|v+T&#lID|@jS=M|e9%~HOa58p0&8$N8F%vDQ5 ztgKtDL}n?Gw;tq{t&0SVOxNM`$(Yd(iNml+QLaWr*siWSx$ctwy-Pi9wnKmB z$jkGRNZb>rQ_=igvatmwn+jdxWr>?%ol@xN|M`{u!PN}wM)ZFS!r8S-{ zPT@X~RBfX@v)AZ85x#1FL)`uK6y2E`_@xhCL(1z&x6(}QzMA=H0>zG!Xfi#!EtqN5 zhlIS_oV)7FQXKIKW&g%9C)@YNccywtLk%O|4qwlM9cy!8jLZd8R{UZSD_%MGjE1twOjvO{_Zyl?-W`(!p+`E!tnazM8<33 zGm-=;cz3v7K5FyFoT2qdqW}D^%BO0?Wk`A#oNd~aCT+;FzFLidYL@;T3@9m zxV#fSP4YS|=yxK68Vco*E$cHa;OR{>5~emkoGqj zm5d3h?NtMN(s!lr8-3221KPbw=_|g-?w*ch1N}+fn=4ZQ`I#TpLMk-2i3+xdi1V;9 z3QdwMwTGLgE~x%rR6;tU5@R*;?r@`;4T$fA$tsluCFJPt`<52pNsR3D*@Kh;xQ5L!?AUV(qo|St)yVjz9A;l@1C;e!}E;P)||~4Td9jvo*xZx7N(HOY3R#j z#d+{z-BZp{(Tk>(2a)1e%40Jm6>=O~q&sr-X=U1-oz$O6gPAeyQA4`!#;O-PuLBmD zJVi*BRfHkmop&Zj*2C><(WAljl;mg^(Nfoa6(+iG5Bw%Vuhj5ib`tG*SF{FW=mgF$ zx}B;DRS`AjH@d~xufLo{wZl6nW3_edRA2R_r+H*-e8W5QezB>uvisS;tjUXtzJDaY zejmt9LrE67a;f-&zVtomWAvrT!v$3Vo8)7}ZgafI`7>!59XVf+k4EH-^t7m+vya5F z+vClFjPif&(dxOb<#pT5lz!EBB&8l7aLwJ}JLFljcw9txkf(HZ=W&#@*JdIoq6eg_ z;N|v!U)a$#q6a*S%z+*n>75b1tdCx1>&j=o-HJk6b9h-QPcu2YHecp{GqnKQ|6a!&hX1v#w~JH; zKmVVm|2<7v+W-DKSSrIPqGE=g&#)sEK8c-A@xPxaRFyc9J{0MHs%6_SyZjB-R*dpV zwG&6BcZXN^ibOS(H(e%$5~S=$Bi6SXu5y#yL=t;`Vm$zg=}4XQtAUP`Ew+sEV&$vi zEiyM%6+K3)p%%sJ_L^6dEb7yRZoKep)jU**W=**j+@cWhoLg(HO zE}qx$`Mic-=S=t$(uM_I`Pbm^pM9d?{{;P$-?Q`UAL5ydg#J<8fi zpL?79{<%K+U;ZZ5tg4<=Ub(!ed{SA(^75MEl1VEoD_546OscA`3|20ySuv@ox}>6L zRj|6OVr5#X%EUi&0@-se^{*%@D=#UY;V-Kw3zij?7u;M_UQ^;f{X+l3B{?}W{G?+Q z;mh)$mgFxjDKD?QrLwxbIIU_~+VbVxmp{>qXVi{X8=>AGWyYR+V^Ua++H}nkoI{6Jsz)9_O1qZTKl= zm1!%htCpvg)E3=XRbH~nNIUyDCFV-8Uar(GchKVrg9ABNE*q*^i6?OcR?`M%v1w8x z%N$YdmO6e#b>)o{q{UK$rDdxos5Xl&3q{kc`rE?5h10aVWZLeMSyq8TDvHXdOrK|c zT2K-!DlQ5ZU0D_^oh8mRyJ%I(yoHO?3noupQgK5?cDs1z_j1Od~s+v@Wmrhzm~68|_7Az;P~+jnNnxPiDvi6_wQ`#S{JGD{q+Kv#$IXUg#$^ z1xvpe$^R!DCyS+%O*YdD4^ z_f2vmNSZYuOtMD<-_0e2WhJz=%1sO?FBdE7?p=^pc>~t7{=Q9G%V3u8g_7vVuTgvplGD zQE`RYM_KXLtDp9}njm41y78xaK^mH*PLPg&OYzMMvBkx<+O}@a&6pcS>7Uva+lqb;5)RzKhjV33v6=_*$Ob@>1?sY>yjD zf~A$k1*Jt5#pNZ{1rmd`-lta;RTtfuhU}ZUk4C|g+TghttrBmrXJ=$q<8Xo0lNv|` z1uIvi&QX3dOInFwScPo~iV}e)DEFxjmJ}EG@FV?!{HI$*&{+nEuP#|$Qg*ZC@cEWh zl+;$y1#s(<>S`RjtimtjfvN#*@1p}$72R51Syb$sTUM;vQR0^$#mlNoOcNn(;GYgl z{+lbw8$E{1u{yc5+hR4uae|04f|##DI540pnDtzBdUe&zC|xvY`Wo^R=z zP557ytkw9+Inj*`x7R1&e3QP=i45%ZtB&!OTfcdz4pJtR&#B zV!+2u>A^-*{G0SsKKA9B83kKjAk*6gB{vqVsF=4PVlH~VHPW0*DOs$1t( zRMi9*2bu8P7%6}19B1KrxvX0q=~nrf#`<`UUW4l-ns){TtNoq+JNdkb;FUdqR~=9X z_}B(=YNkKv@?80uQHnF;a&(W%sxG7Q#~T=8WslbX-_^gZ{-#Gy8B473B05Itz%*52 zlnzYlqY;>*>i2a6W_10$2DzBFk(*KFN5|KAywoioFBOi*ixr~zDPDohs{(A|O|d3G z1*`!}{$I|5a+Xb|2J!!*>}&h4xJ>lKCZ?dM{I-8cetW_cGoO7kD!*;t0gh{@kH*Ep z^ClN8D7tl7iM2YftS(^xkIjdI6*U#hW#??3F2kN!&d-e*vz?Hmr;{-zo&zRAq~xC0 zOvu$#_R#Dzqa4k-DjE1NTeQth)9+p^VpFPNrO%qd_fau8jff4 zGyJC`{XKl%df-U^u#$hM{~YPhWQX?$;9BskPe=z|40eKF zfQP|Re>u`W<_w>2Iye(71DAqp!Oh?X@GzLtd!#=l#pipJ7qjPpd%$vVwi+e@jl;k zhsg&X0&~GB|2ooN1;km*bIIG z`e|3+$o~E;@HnsqJOgY8r-41-)u8WW^alOln_w3B30Mdwp3vW42L`|v@IJ5|+yeH1 zhd|#c*p06R_`xhN3%my`1fK=#z;>_&>;`+lO?)|F#2D<(_X9G(-++1GpTHp42R4Bt z`EJ1ua3Z)DTm&8hmw}^B_4(?-4DcZ^58MII08r%!EgNMLwF!?m>GY0#EXM_1*E?5h8fX!gmseEf2 zd=l&ep9TBCZZO%8-Nuq1oCxNFSAex(G1v^Q2HU`g!7i{3>;rd$$*22#d%;ZbAeavh zKaKogD%cEWf^FaxU>A4~*ax{QdpiUf7OBY;2v-r zn9SFeJHhc_FPH%)or9l)>EPpFE?7Mddx9IlCh$pc2iOko1^dB6;H78K9usLtFavx7 z%ma6TLGUxM2~6bcmpj00a4(n#9s)z)C?2bC1~b5C!8~x?c;u05lhb^@qtC*g;94*r{2o{fz6myiU0@sd8Q2AWGnM?{3^18~w*<@ttH6A41K0&V z1NMQx0F!y%@p~{6JZb{z!0})$SOzwO+rh1~eZCXV?(eUfLtFscz^rp<7w}UsaW4Kg zk+=hH2g|{ZbIA{W3bujCX_ODX2-dH}-zE`XZY17=ZRnFJNO{+RU0@a12Tn^z&&kvm z%mRl_rayzDz&dao*aFS~+rcVuKUfbYPGNijQ@~+U`updCcY@{M{on?0C%6s#7~BK; z&LggYY2XN+sTYG2!JEMxupX3mLVYWP{NQciHgG4{34RXtf@7!RhkOb6dN3W_2j+tZ z!CEk58ukHe!JS|S*bNRpzrX)5=m*E}wy`{LCRh$G1s?}jgFC>@;H%(Hup8_KKLHPe zqcX`qje3G}!I!{dFmEP$gDb#oU=z3p9Cso024{jJc){K>a3YwPMgIZEfmL88*a!x| zR&WK_3D$wV;OtqnS0?$vOmO^c>J8R{wcr-88O)zUd&_;W3%n2P12==o(|x{U=aL^x z0rSDD!CJY_CO?>YG4%%T1G~W%@G#f`j+sH6xdgj`cY;g7$HCR$v;h7BegU?Fi{>#7 zfH&vRUKilMU^>_i=7R5nRp5tUBX}5W1xGBP-e4Bk3vLFJW)i=_bg&!D1!r*bsR|6r z2`KP!uodh8J3%=a)eF{LM*a)&zg*%5I3COcYr$IZQLq_YdO3Q7s~4d+*bMqEBF=z* za1WRTehL_;OEy-E;y`!a=~$64;TP_v+xtp57vWOU^7?< zJ`2`?2f-Hb2-ps$71G||eDE-MViEnD_>>CH1uMW}uo+wn9$JQ-!DE+WXK+54MBKU_ zOa~jmTyPuM3?>v)f8x|w(3j2p67++`U>0~ESO{(b>%iB+7H~h<4jx-V{lNL4?_%Ja5WePH-W=0A+CTE!BH#G3rq*Az#!NJ-Vg2oQ%mVb z;54ugECrJT_%)ab?gtCO8D-c7ECjcL)nEr00>hwupF3%u&-VhD33l9oJ;8o(EjYcr zzkdsO3AhVf0`3QwgNgHz2d01{ZbV;jJXj8H2Aja`;12M*3iJi*!9MUwF!@saqmpvL zi@|&_AFKuM0h_^XU>o=**aaq3ksllbCg;$f!A!6m%m?oUYr!_K8QcrDfxTcCm~|6= z1TF-}ETF%EGr^7EQt*f1YOovJ3=XX(?toVZsW%t|6Bp7BU<$Y$oD24V#o){u>?S<8 z72E}OfbWB0F!g5I`7+7}Q^8s=06q$qg3p8X;P1e#V9G7z2j_!faOCZ@S1#p%>0k$# z53ak5a=~VB3-~O!3p@<&2glW+_vOR^Fa^8^oC|(_H|+(EzlUVb!)K~_z<`md>Y&d?gYERMeFDni?JK%2V1}_uoo-@hu=%T08_vg z@FK7s%m;hGM$nhXJO=cGuY*}&4_F9}{Wkf*8DI-o3ATe9!5**`^erKtfGOaZdg={+ z2$q6JH&AbIA-EO12kZbF!7#WV9B~DD-bcR#Q@|YXBCs6H0XKlpf!n}c;2!YA^~6gs z1sriD{SurAt_5?z$G~#%d2j=`7u*IO0r!AAHjp3u6daLHoC%R190%rrSztMM9k>Ck z1-F5Zf_uQc`^gXP0!Lg$|9pV_;Bqh*ydSIrlN;$L;1sY8lwS$z0)Ge|244clT3+0z3@%fMbg2|KLn;%e00 zyWm>z$KV!lC%6mj0{4Rl!NldPUpC`!;8S1@_$pWq{u0~(z6Wjt_dSNcf&0Ne@KZ3k z*ylT`g}4sR2J^vXU@f=`YzB9NZQz?=7x*FA2Ob8KOMJemKOjFi7t9AYfpy^HU<w}N@*IxzhpqJaJ^)j}VO#Jw zFb^yR>%gsG@e||&uXvJtU^zIfl=cNv!Oy_}nDrF-z!hLUxan#96nq!#1XG^DPr*ZA zQW^809}}0stnKt~aNK{;zrhT!5ln6+KREm+tr^XYe90@dn04Fa^9GoD1Ft7K8VJYr%)XE#P)=7x*f;AKV8fmScY~ z1w8pV@`LaH96tfS{XFvraQ;j9Cs+q|gR5V`UN>UbSFsm3<2CFBUIx~K72sB|9_#?0 z1;gNH;Fc=v{0rhE_($;I9qgaHPJFzR^&L2@g8m1lf)9cLunjB)4}taI*xkqnXMi1G zFW3v_b;Ptf#b6$| z7OVshg4@9nHxa)&X)ka#mVDMLGZS{Y}jL2w&5q6Yr}CxU%o4w$}={NVNA1~B;t!e$+zGSzhnLZ_JPG< z+I#o~SPgCkw}KtuyI>gn0323}9l=!ay5Hj$U=>&e-Ul{&;|TQUEo5n5BxTmyc+)pGr{-4eDEMx z3w{AMgEK!MKX@P54Nm-T{FVNh1*U)xfdQ}+EComI$L?SuxDC7y+yl0O>GbE+KOrBK zzfl@|gKk^o8&sP#=#&vh4Qm{9RFd2uBiyf!^q*s;5s00hy1}XRzdX|4K7@;7lP*3s zdH!)n-!iPu_pOsJIQzVmad!T>d}w}`X9IG>`jfm%`TzC4BmE=g-mGJj?oF6;%+LiW z#HH}7`M(YRIMCteyZmNuUyZ(}nf%o*zmxk{!Ot-H8kg_p{z~MlI@;x5=JJQ(uYo_o z%)ij(#|)xv;ms)>&{37^onfz@ozZAY2ev-*w@A9kR?|~OvJM}Mc`OWb6!k=jJ zm%IE<_|@=Ye<%N4F5eB`0zb>-SG)XS_*daiHu)tkKPG{>2mECwpP(CP4EJWjAA~>N z0Jb$?zh} zvCow*FSiHXmYbt`%2AKpc(>noitaD;DL84DL+JNBauOd~=E}$k4c?HrX2{?lB`9H% zE|>rB;rUn>nD~&9_L2>Q*CZzFk%Xd0)nL{iJU3%H;>t@XR&s=wx6IrQ?^UN(_%e8} zKGg}o6#gVrex6(BUid5G@JWf(1%AAlzsSv>4lnt=`fM)z#qejE`3v3rRq#1+@;Aa? z0Dp{`Kj7wXg-?YaZSuJ;-w8i9j{IKuW8uB@OCr{dg3mJL-|os!htGib>hrnqdGO=R z{MWkqtKh|cXPCSZQySr~hM#8gH@W#+;j7@YO+Fz@B@qAVgx?6C7s2bGCwwpb8}MhE zywN^MLzyqZ$BH?A@?_#ayWmgZbK>p-*N3lgb<9J?PSTuZma)v`gYY85%g37F-;BfW zfbWE7%HfuuQ0>@YFMKM`puPA*@OAJjBJyh|7aNT_ig646Xp_I#)jtFNS@;Piue-47 z<9YBq{LaYEi_(cW$4n8LyXUL-N30I~iB^W-G zIh^%7X}#tS`S88)UU8-t{xkS=%5v&;gIn)r_#u0|<+s5X5(B*Ec3tp2$fruK{MoMj zK6r`a633kKjTn|p=TC?CoBTC8e+u{HCm!pO{}7)Ozqs0!A+`#+=}Jl0N4i^?YbE|6 zGTq?HK`NoNb3NtFXRdv&Sst>MlfuuvR^;TvXY)DnNkfhi`}ZK@Hqv;-m4ong9%YCQ zBSx?X34a!!9h(?&dm{WMc(1uf4tza)EMN5_vK(H@XKC-s7kjPH_L4M>q}fB7a~WqG z9Y{0yjKM0Aq}f55eVs@87huzfG;_2)B~2G;e5^^XjZU-JwfSMv%wYW>FLH6@3{F-F zq>WSXk<7hE`v1u1#A#Q#Y4n`#*P@W5%OTyTq}zd<#4$#?`7-w#{DcS;`<4?B@7#B! z{~|s+<=v|5F8l`g&2ji`@Xy10#kD=~Ps2|!<=?2~`?+@zekXjVSzoQ=E4Geu&akxW zNdM`kjHRxQ>G0RX$Ld#Ni+p@+5xnXbr{%l#jOrJ4q;i$n}M-=hp^mlXJXc&~mj7rqeQt6vnuFM{{# z7i+EZ!jE}{wpYKHi615W(drl1T;bY0 zs$Ud~zmZP$i&;jxsD81Q@&f*i;rc%kChluyu{VR8q)_S>9`|lSCe-9hgRA=@3el>woq=zXPock zvlBCW~gUnDem_?U8VaQc(C@_(^g2D)?*Qy=>eFKQ9j73ZDr-%e0ZPr_%|4Rh<02@PRn_ zWuvexPX2WGe0Z-tom}{v;^eP_FNBY^e)m(SM))h>e?>oX{9VV3UG^BYgET|p?ECD6 z|68B8jSs;?c((=*0@bUJ=4#CU5*r{gzd{_TbEdEEsd)6QRn{oI& zc-gm$)z77m1TFbqd=q?9ocufB6F)f8zr@r(K^sWq?}eWZPc>uO?-2YooJE(kj*l7p zf}WsR|DA68 z?S+2>ey+(I`@)CdYmdb7e-ytHo>1x9$Jn>efUkmo-Q*KqQ3}W$a4CjA5&J&Q=fuW^ zt_(dt*dz(Xj;oQ=NVfn`*=QO$}wV22mBYv@v>zYei-?^_+dEniSS;1CKY}}ocsa!li{bD`c=95m%^vR zd&R_h_;K)FKDQNq6#UOj`3cXe0>qa(;GcoNz~pb%<@>qUixa#KFXLw7sf^zC^B`mF z96>X0e#5WL7K}VWVp|ElBv*s z_}M0Zhg;W7_@N2jI_AS4CjWV6{t7pLEqoIBWA#laUo-y82(v!&;HM5u;dS!dL-1V z1{3+I@M%N)J)bKD;8Wpa&8ht4FSYVNp1_6O_prs_<^-pV4W!vNtlx89vJL)ec&`|> z2fhW~D@GoKZ-fV29gKbN5e)eE!^iRoX^RXDQ4jwrpA(1E`;2-dw7I^Whn#WW;A|D? zoHW+nq1ZBL@w-eu;bq4TP4KUie^CVQuA_Fq_rafI^41=j$lnW}IGnRLCZF&hj{HOL z&G3M$pYdFMlwb2+u{Z<%KJt6@s}b+iKS6Iqsrtje4eu4-n&5ZAd-eSt@V|q9 z1M#l>U8;UizP~}wc&aVE;{s)COE>|#>uBM$Ab6LF%y0>yw_Ne55EQe ze#&xnY;fA37JlS0-uav1Pli9k%x^s>M0H;q{8;!Vlb6_XpDIF)N8O~kpEO>6b{Kxj zv7AvcWmud16Sb9FJ!bL@d%2tV57jdjyO__^?2`$Qu!b_TrHm^BeT z0Ke3fpP&~Gs{Ziu9Z{xQu71X|_j33<;bX-}$-lwMf1Q~>K?f+|x52+k{^=%foTu0W z-wp2-;}61r9H;yd1i4;#uXV{p_%GmN`LrLM^6;n9k@^ejiK%m38zksMF;a&rWb7hM zEE|Xn@q77x?B#q;49_-X=moUM*nx~b4;fHC@%tn2FNqBKf}icTdi|j$jUwkTiJML! z4i4hNPBZvq6(oco!{FXDs^4=RI}^SU-mATr!rvE%Uk$$&K9(({{LNpIf2Wn-tNd>G zJLAYdY~_#DAHHhzW7|Kt&9MTOvv0puJPb@Lg8PDWPspQq9 z@v3V*L?Qg71Oz&5akiQqh%L6lS0#JMLp9a>uxC(kvY79d8fAXTf{<&lm=` z8St_6lzPmBkC%Vxm*ih<<&WimB7ZY{dK~?B!k-QA6%V`N=fcMtZ)81x7+!vPG-B?} zeJMM60&N7xGRd{C^?X?TAq%5i4F49N6YDQ>(}+L3qT5pB6e8zi4;_TBgYSmFn9oi- zTKfaSx4U;oIRyz+V&X2bXI<5M2+V>k*zetmJdzfeYPobUaiuQz=W{buh;7 z?GF>-PlTUIT1VGg+`8t#Pl5NESC(76mp^TQ&m_N>&3E9hk5Z49r5@)Q^$?r?)YW4z zaz-F$iK(ZxKj`P)A@~#je5C(+lNTA*IViE2AKzF?nxF7FaW6HtW0ItM%I&LJOu|1T zUBs9zX{>SIPyS-k_`}|5#P;>1*-ksgsynLqTKQ)NGESEGv&hir()$O85;qK4GgQxR zMV5T$KlLN;^GWh9fGO~?+Cl0*2A|4=e}d16LyWSdUXQqTp2;NfL=T-skEQU(!&97V zKVzM;8h#8s!;s4xXVEspkAsi39uxUHt^DK6{Kh^?H~d)gv-EZ48~fact^Bxy%NzT! zW0**dCqEW&dBfjl!q1MQ-%|LQaro8n)8g=(;nU&0>bDbq3cQznyWuZ_k5zwZ=R`7! zezo#>(hRqb($2ro5{0piE8W*Xx;Xa@W=_$el@m$z!{$cvL-?7kYmll&EYPW%Mqsn=y`NwOU)u}u8_cG4XqvFs!xoxK z{4FtyT9|EZ_*^}5+DLbjSr2Or5jm~Mc^1A#*2?mys?j#2Y)a8?Ixd~H{+#EgYX}~OT8Q&3f%IW z;6H>PY4XPNrycNJ@Lu}uwd8y8hu{yA-%I~dYyf-=k7v628T%L+@ChlgV~o@<5B@Ou zr<(bVJ>MYw$T<0%;77#acfb#Ym!@{?XFMy~3!e-ht3Qi=hu}wf@P7C)2u^~}<#XZ_ z8EzQ~`hklGMadzx_iku*F63^-HU(e^n z9~p9_z3$fWPsYd1q$?%ei&9?5NVm|L>pv}}itXAd^B-y6v9bsLAbhNGMe_Ryav#Eb z*~Sl_G|9Vdv*1sJ_v(j*@aZ1;#U}MQm4F42-tbG7!pD{Ce_XT_` z{rvDV;kUvs;B$nZ&T-qgkTma-Ce}DFGV0(v;opdsp&y4TKiNVWc}JbsKEW>d+u`R# z$q-YG;og4uN8uUeT|JHUZQ_N@t>I(!e?M7L;9KDH%>2?9j2IFiO($u*Y*`Aw4?dPH zMaOz8zZbt1{!I@ZC4UEe8+^o`R)XHl5Izi_kP*9%!VkmAdda_t&rVw!XLnQK$HmDX zfKP(=%3lgUJ5K(3_;mPF%<`?Zzv#CW{v3EO`*gsMhd;^8Z>^tH{o(!aUULw6Pu$t? z&zboXexe*%@~6VL!z0GEkI@$c@bANW>0b)}JNOgK{Kj|9>*3#qKh@-oy{fJ7d*H{K zys_r$fPWL-v;OeA;Jy5FSeDN3S%3J#sXUV~%TLe?Pq9w`z7;-T^7IiomgwhRDSQ|F zl~KIqVyd5SAkER!Vy_uwY}^KaB7B1>!`?Hv-HkbWNhj}~^zxNM@YNo?AK9a3F;>IJ z(>0SckCDc!z4PH8hWBdETKI?Hy~f67_#eW1)u9dkQFyQMy$ik(K2}VV_UePb(}NdV z`|%gC!3l$ymsPUyZp=dle?!m9L{8Rh#_;p|J--`M2wwp2RgXIOtK#r2@baEeFFUux z=fWS2E{={DyS~r^e*t`&$(Omjk3nM|yw@1-hcAMUrN1AU;`dA8)&5&0|Jrsk_TP$; zaUE&KnK~Hz)NA1jEg7-$Z-HL{f3}(5*r(nFUj^?qKJJIFfoCP*>Syd1$UAQDg+I;Y zjq^Y$@ay1X*+6_?F8p0__+t3m;PE22{AF$%tcAZjPW~*^6z=W8mp8%x zh|h_C;f~z~GDbh@IH7c$0=jM1B35R3=P>Zbj?u- z54mOKllIOyW!1vh#^IactKq%keH(lgyl4N1Uj|P%c6G%bVm8(P;qQi@Z}JJ*ssh3% zUrfA(_v&|<@LS{{4oT-(9o+Tsnf-!9R~P6w|%^APYVKKirg~yOGLY2tNg0 zWH~WI9~o189ef(Rm!G%5p9CMP9wM_H{wR1aKkb1Z6equr0MLsayxPeRe-M6@slRpR zPV5-Kk9y#L%;&^!GlH10_lIsgEJaR996jpc7ssi`R(NR#FFSR>Pxp|Yif+B=c^3RX z6VUUYL{(c)`&~XC>$5dt(@~f59m5N}ZJq(YKMtP<|1SJl$a2at#=9W=Z{bBRhhOg6 zstNuBc)!UT=ZAM#{P8BAI82;Hf`Pag?!Q+;$of7mUUfOvJ{C@azOx`$0vJ3v)-A5w*-FQB+AHI|P`_23b ze^4Dpqul|ECfB|2TXK{ECab&lS&wUkZP9M1H+dDe{ZqH^EObd1HTiE&P-4 z5&hNBe+zskd@TD*f7yc{?}JYtOkEZ*64?Dko=;fs%@92fBIo^C-sf3H@WAg2_{&W_ zEk~666X7S$?(csmf`8MoQx1GL{B5im9UTVOsKuh>FNdEtx4-|tBJ%HX@^63-!+#LL z|K8!Z!9ShtJ?Gs6zZu@Eoe#nnUhLh@BdGY4OJcXPADt$`r^3s*1*d-W)xm?^^>8j} zMh1A#WJDd*BLFqtSHa%{KiTB1wV1SJBYYG5Qzq}uOVkQO(zWB$C(P4l`xEa)yo;croU&{}l0q?aA$%3B(?=@Bw!l%I>XO?g5o7TaP zjl;LV9~*~nhd)C7yyW-5e**8d@8(;~SR04;!|#j3XTiT2hcASG5#Fo4>+#9A;a`)! z`yL~z*>|6lr+n-`W4l(;UBAFu<9=?Wld-~D<4U?N(j6e3lGkITlUQKMlXmYzuX`_# zJ%5&Yi66h&46o)(rd~1TOLN&6FVEv$sN{3>PxzJ7Z;Rnmmh|_37{UM1;n%`{3_sfB zb6p?a0>9}M@9%T(f`6I(UgO(-_?O_l=E#Xl7=Pf;Hp@5mS5n|#g=ZVZt)KCI>$&ig z^1a93V))EB{95?g@MoIxjdPG&-~;d%n7lqtqx$$R_+of3{rAIHz^ndl` zFI*4*9G??U8tv9md~2KA4im4yZ%9{c>XA_3v||qZ%&WX(K{?s-*E><~y@-`#qLwK2sCQdfwSo2XyvjZ82Nki3LyGl96^X)Fuq!&az^COLH{i^r} zKL`F;Q-*cMQ|jZ#Po}`H;dA1TM@E)oJom}EitpHw&MUSQ!q>;)>)`K!kLB~CXAAsV zc(1u{JA5O2tmh1>{i#O?ewozcv*RP{VLV?N#^kkwbP+Z+_JdO4eTClj48VUu{^2BZ z#sFgFj2l}PVF#H7ckJaA7 z54(nUn#AE#;fKQC6(QgKURwZu1-#cBz7)O@9#3-XZ}@9H{5^5_t?)tknP&c5+_=|a z$@f|VhT$J3zZXAjDeElwlTG=?S&LNoN8|7T_-6Q6^PDlrEQNnMPX2m$Dc`gG;djDM zH}x}OLI?al`0XYyF~K@pGlu&INmE$l-3BABWjYKW%Lab(PlV5b?={QNW5<4J2`M9& zG|9`n?OX*v4nEenA^98OQ{iLHXZ`T4mi#SzcKVUj^I_K)_L8O<8L{diWgLQkFb+TJ zI?nsY;WOaxg+JBQ!HOjkbC%+3YvI+i!|xswp{M=q&`&z~O`NLbdQ3@-N+-`LB#rp} z2GUI9bK)vPma*5n3w<6X&0NwrHj&LPE~UQv;a|06I6O9!WtZ@Y1VSHOGuQ4_rUrlME=9q{FG_`UE~!_PMD zXFWUgbMFxRYIwGVBkXIrvf6L(<10`8f9!n;d|g$w_et8cWhw=k$AC~7OYTjY0T4Rf z(zIzClTb#vO_Q58G!vOA?<5D^eTQ2`NA5qO9Qi17W_ zUjKFPIs2ZQHf{Re`@Zj;AN1t@&pK=Gv-jF-uf6u#dxOT+)gjQN)}Fk&n$ikexh;Nv zNYYw}=iA_U#IBV7DrEbd1)3v3Q>Z*|#PfxCJ~fqC;(4L(kve%5G`E4K zkd7Y*!|@J0FQi-c!Slbt_g5Rv1AVlThgo>O9sG6}J?F}bJ`90o;QtQLtUwyLVZc9r z!bQc?#_w?9sMPq<3r0^Hzt8z4v&NUL95ZWt_2NZu;g<^!PkrM z6R&O3xK&$l9)E21WKrKk#ldTm2|SbkH$C{EyNZG@7ai=7&FYdXM+ILjzOZP+U*2JF zq*7M$@1o$ePh!<;QOV0i*t1DLXsBnKR33CHHpt3lar1KgJ-g&n!HGG{m5AW;N{$S= z6yG+5`x8Ya&x{GaF{b3rF~MKQ?Cw5e%Q+=C6a{T1tBQg<$oCVoK>HuXCHI#Ezb`KN zPD$|gsFJ^y1fLsS^6Qe|iP2L(C2qpDwz=+sc&s^a>*IN_xNzr z(9O&UvXl{BSJO zNfoyTXXxKGM|~BHE-x;*V@&X%l+DUf#V?HsR*x$A`Iz7}shq1um#i8ad}DOUM`MDw zMt`FSKYls}Di_Iak7S=L7TLR}IQVwaz)i)$pIE-*EDe6gOuPXxc%i81Ir-W*iZ*?( zDEPb(hrdIZj&B8csx--~gi_w$v1rTvOZtkwP_*f#MZpb%+Do9HIOQPNIYmdUD1m%# z|Jvx_V#)Qbqe>nr34Svw{iTxNs*-swyTZM6FFb57`NEiBS;;?2f}a(2zE~1`cGQK% zKPw4t5CN9-_9)t6_mcgJ>PxOJ3Nj^MC<^eM&{Ls=!RhdZlB>rAoh2*B1m7*%9>=E@ zm0UhHc&BK|XU7I_71#Z3Oz`xmk{^r-9vEHn{FvbR(It-pDG{3Qj#+{H=YQ(RFkScZ z*s`wV@}eMJa#m4rt9%>MuUk;^0*dCaZ;uNuE?#`ixZr!EN^m~M??;tfJT~}fRLQ@` z1TT&*d2eiRR!PZoV}lz?N**2?d{9yX%1g$SoI5V~!5I1b-7!yV4T0r;`;|OW984?u z=BVIPCD)D$K3#Ios9<@?ABux(igv@F4;9URyEynAL{c)ac}y!rf4sW%ilT297yYDo)1Mayzs-rFleZH}GDRzjO3p3{ zE)7+?%3^_Ml9&Iz{yT1pa?3fz@Z~7yrUd^kWYD0sXz_@!Ajc@cEjGJ>7#B zc(-zTb|1x`++68*aX|@)DLz<#AAgA6=N+nddvDpk`reu!EAkiKCop}ZTS&V48h!s< z-cR^sl-~>cDZkZx{%hW=e`K8WzKZ;w*-YOrWxgL@qt9Rdhu;6f_h#L%zwO^!_Q}zBD@AlprzPHnM`n-wvw(0u2dWPP2O6lF+o5kMQ#D{p+Ii_G=2$-HZ9!?Q8Z#?{D(E9{9Ze-t?U4^W*tme}V5>P5S*V zjlO5UO243gy?>$J=bdj)^nMBXUVDN5w(t7ZCHi}ZRZ)8Tbpq41?>h8yd!qLjPLHy3h^69{a5I@;X9CSCpVb~{~_*} zmGbqs?G3%p_;d94taVH;`d04OKGeH8B>u1Jb)@s(u3yLZreM%6*9#u~8shS7EdIBA z6bpdsUD6ki)8FIRPZaN?zZcqbH?fQPKKngIpRcgr$LQ}T?Ds1;p{Wj7ki08GR zi=zC>LcisS*+0g|?)4!$!4|@^Y1jIc;|?arEXVb&&mJ#dE4<&=^LIV#$@2VyM^_s9 z9!GO=?)&8T6z}&6@AviI?={}<7rfuWB_4nN-iPIq&8J6K3WsC(TIl`0-urE|FTk-T zmyJ)1i+_IuAz^YEUgaiia=&MIzel-AyxjA@R7Bq&J6V5YR^D9?pQ?968n|n(Q#GX> z`MbJQ?HkN8xT}4)Vt|@(bH~iHj^|$5wXy$Jdg|q4Z z>m&Uhz>f4o{+`A6KjLr8*PHx(e4{dYkH4QG-~U^0M|OCf@Jh{XyQJ;r$if z-{F1CXP7?k6M3)XeJ1Y~r=cdbj6aEb#p0GmG2{M@*l7aOplXGK<=qyGpAjl}{== zaPq$TN0edAuTkg?s*CdR5cs!1}!? zp9#Sf_J>h?tKePs-%)()VAZ#@exvxuf^)XXuYgfF;mi8hDE+qCel?137c69d8^yN| z;`H(;^j=pTv}c&q{XHr`@6LWR{BRUbG<%bB9>sSK7M92H*(FTo{+6#F9sH+jBjJZ) zZxo~aU+~I*Jn_;q!_+~r2XXTY+tVuiQ55VP+)e+mmG(@B=a*Y2`K#n1SU+m#062HX5Pa}RAar@poiC^X6eCw>ocE1&a-|B^U| zNx=_^yTfykgzAt!>#>ZAn!>#>Z>*0q$9;6*zPu%2fG4aP% zM9ULFSdRV)5C0AEr#*aU6u9tz*29k?{=A1@O8f;6|0VI4J$yS1bcO$`9)1+@*F5~o z#NYJrCyBr9;bSnc7yj>h_!QzFc=#akKm;C_$-`~LM|=3I#K(DfIUER*?&cnT2Js0V z{&V8*dicMIFI=hl!7^cYrC`t$!Csm|y9mYWu1<$f2-cjV^gYB)e}4Y~1!{>uM*33H z+w{@CaL7ph*L+_297X!`iBBQkM*Lq!&wO?e?|^|N`pV|pO+Wtz_)z+J3c_CH(ti@8?np0@Js*5;uKodi6k0ubQ5m!F-yW zn7uU1%fIQ{S`RlpHrvBZkInIL(_?iWZhD}exaonvp`4{2mk_sd6EPFKhq&ec2IBo5 z{v+bcJU%ZHU*X}V&(HDrm_A?S(VHH=%A+?ue65F@9=_hgO%LBl9NBZ1>EW+=xar}W zJlyo~%^q%g_!bX0eR~`6YDxO!-1P0;9&Y+}jfb1QeZa#_-#+Z& zrf(nfaMQO>c)01?r#;;C?Xw2xES65v|{-({r&%k{P3LejtXuHrTi@I&H{KdLxJyzY9E_?dH* zf%|+skxi&1-Oul*xat2h@KJ&$d0$wZX?ZQ{4=s`y;epN@GE;dA@L3LHrM zCgQz6RbVRd9|Dgn&#{;&KvwgvD&WHZwF5L=dv_sl`#b#7rKC?jq-Z4{ev|m?+bf@g zi2sB5*jp69Pj`I+f-ULxd|c@#67MJ8%kqI);;x5?AOA1?ZRK2p3KBk#jZr=(4_^fy zSMQIIe$Cy=M@L~;pNWYRm!D@9-(PRRLBuCaRQ{Ik3Bb2PzgEg|Wf|!&Cw=dUN^k9Y zOLUaNzb+Ha=TzX5Pm5Fe1o?E6zW-GP?7OZbK6_{7WBLCB@pE>G@;?}YE$Lc3#1is9 zmbk@_JxhEGd|+I?pATI4+p|j8vlU;daIkpq zcs`#6F8Q>$ChITmCH`f$Bg@b3s0g9|^-0R#@^&_G(GO>xtqESqbZ;j8gm$Hec)M#e zC=lUeal6*V1Uzb|m%^Dy;^1LAfKCwm&w2r*F56mCMo|bUQys);#^-9_mKI6f?HS;be~Wvv@_(QBl0BhFah1A% zgJ7o$YAikLRv?k?)pYD1de~4UJoEFrzyX0s_ z;p6v@rxSm(C(7po;&&w#H@Tftt$Z%}w(_<7oDbZkdx6qJEZwz+^vmwh-*v=yL`Ny| zV{y+f5zJHu zHBE8ft~(mIjI%60VKn(K1}^er@u1fdA3I(7oW^oC`K$#Vrw@NY`se?q4A9NF>z~A5 z^7>^t^Fs1pv6a@>d8EG(xX9Hx>=$6hxa%3xzq(lIO;7HeQa(?!obM`D`fG^$cFUu{ zg}=q=n%@4{Oy%SILz;xWOxRk@~9H(3R zT?Jh7If3N>_2sVTNncI*v39g$Z9MI^Itqy@x54{+mO#f;*+2c2_SIz!NOz zM@WD4fC9#6`+B86nDkc8hZEoWD&=z^`L_d?a(IX1&|QiDo%p8ICzhY4PbvL}UspoY zw+{o4laqguzTwwO{|Nbiqe1xOUk?F~{}Pc$EQ$-b(BS5e-q9L@zU?Pbcvn(jWNzr*3sx3pJH&n!4n`7D$PHC)!etS0_R z+97D>?kZlO?ZVbU?m&EJ;F6!aNN@Fi3UOQST1)zCfX9{RYVu!5zm4VdIpVgi)Y5&I z{4X1&`8S@QhQgHg`vSk$%3%<=exAw1=Nzr&Y;pV-6Mq4? zw2ON=Phoogj}9kM=yu>SnxCDXQqc6_QN(TCtkuiO#BF_65BtF{8~wkP&(%z0=VO)s z`|l}W`MHMpX?tk78U8x)-8gPKhPc`@e_$}!FE?o{6*k#<*?^M<^SRLl+fg1 z8u6z%Zjyb<<@(t|rN87B_cO419NVnz;!dvPoS=_`bAZeD+PdzSiGOyH;yv`6Wr%-3 z{0iE!cM$(Wi_+iDe(GT2?+~v$p~xX7Zyl{lzZ=`{0O_|yLUH9V1-Rt%E#~Jlq<@CE ztrv%Sch}p*KXbCCYxPyz7SI1$hv)kb?*%UDj^11OKrOiIn#J*awpya}A3msbmhOSX zeZT1A#22%_n@IkX+T-~z0xtQPc#`G^X0y9~M*PAL^tbWZ>qM>ht33bVqr`1Jp~=G= zz=gl>2itKe+Hdhr*|>Km8%zZ5>?PW1}_88lxxf+uMI6{xtn^3DQsPl5&Rs>PiJt#G8S;anq%m?!Lq? zB)zR;-jevez~y_BtVioFYPuD_k$U(@($@ob{4b2w<5i^pGTXbA!^@6-yWnB3{qEYM z{5NMqEG7Thz~kD{l@1>tEaUecNcta)>i@%uAJV7wW$U`(W_Q<8;F4}X<=@hMl=yA* zi(0+xiH=_A-!F;g^Yg?np#3(U{C@{r>dV$MP9Xjk>0hV)WA$|c6q@k2{WEGwpBhv= z`H=!9|5p*WeM{aV{naNc{ksnTD#P|J<0!_p>J5Bl2-K9Vc@%@OeVEzq1jQH{UXoA)* zE+g*8X?&CTo8MQ)R*!!sKIYeoZ^v|ZJ6-d$>R$?Is}F)N5clVO9wmP4uay1)^4atZ z<#Wal6tHy9C;q$LH2-^({_n(>Fuvsx;@|lU%jZc2tX^at+8*eqs=e{`TfmKmEZl9k z70PGYdy1M|brJXdnKu*fU|hig`dYBZXT`qVDF~SE4#bZIE_%S1|I>+&{<9M9NcwL9 zm;Th&g`1xFE$PS96gf)kkM=oJ`TO(!3xEqBTjy_lzC!wy`zjx+$1Oe=Up}qCCI6%D z(F~%QyX#WoP0asY$}aeE0X|!urF@?D#)+RJ?#Ib|iTIr_X?j+7cL5hYX8VMg9{V%t zkN!yMx6)g1=-E;)`BxWk`7Yb%;+M?-rNm#OeMNI5n6gsoUuC_crrmWpaof+y^yD4D zEzjZ9UvT*NU~{A+*WP*y>OZgiU%FcXtFMcI$MN|+=}+YMT01)A9OZNCtIEgZYANyY z?0-#P-9y}ud-*N!xO5-IJkZub{`$C&e?imzF8c**M@xu*K>x7uyoC6LX)XBOSPu6R ze}MV7@_Ze*lV{J4efnI*tLZ2wa9O5_9&arY{P5f=PFSGalK-`ZLn17M-ub>@1m;4_l?vF>xS1J8v ze^5e`!=s76w7=H-c=GuxaoZQk@;UKh<#QALik8oFiTnPgZxDa_XUf>x{%?r;_Qo5; z{dxJaOEle&CTc#dz2630>_FR(;sECVdD0(1g;7oXfJ>F$_M0drUJrb0{vE#E3|!>a zkGFi1xF4@F7J@4DPqUm)AhS;s-?KBC|3`_Bc~1!sCH?M~D<9k6PR>%4>u%!5aUR*~ zYtt*@^S=(&lA8!FJ0xu zo4rT+?LMvLunXz8y;{@VXSD){6JG^fzUwu}kz9xAEx3pDw^5$0{9ght>E2SRJ@`JP zFS$nf@5J`L7xDSTeY@)yz~kg_&uf*>&bKIoj~O50ckiX&HH-L-#BCozKzQuLQ z$M=g~K>St4VeUlwUlCt8Nxye8@v`fckL@S;3h~#7|BmCJ?T8htk?JLSB;P(!a&nd(YApaS}FC~7$lL{P2{C(geKeN0zmhHc){EypPzjr^< zKMh>;p6xfaJMn)47rFfqdO|KvvjscfsC*tKFjXH1M-Z>1U)1E`L*l+4Zx^(4srO&A zUQGU*fSZhwwYzl{z+VC``M;j?Bc*(4%uUMw%;y!b`l=${@o&XV9?m0Pm(cRrlze^- zT*|?Z$9SLgzQ6Rvn>F3%y*U3*qP@xYUb%vGh_A0t1DEe@ z`jgV{uAd!TPkaH(c^7>gjJi$vk6)v}eZ=Ph7e2)qWw0;t6CFK&gl?-z|2W4%`|;Vt zZ<3GK9#0~^8|@Ypm%IKzypH;?hxmEuZzMmr{ZN6a#J@@0_k&&bZKc2aM9sg+_ItqX zZ?bT=Ezo}m{|l!m{h@r=Nc;oHi(IA$&LM95#Qt0#2QLu!=bbk}zbpK2tB9F{3H6Yjs8%4zvOc-)Q?;y=gq+5^r6Jr z3%>fZN^kc0*`RlN*z=!%n|y4aVw2~mn6B@C`@qpF@9@7<@6dcc&xU3Bycc+!T>XOd zzQ6Hx;&1&4{)gSga-%*p{ctkzgZaHC zC%+_a`zrr}{4e?s<>Tw6Zvc-g|JOjU&-m;IKdl}={$rsZA59diOKmw;`Ptz`$m5;@p})| z?>&h8?*kr}&k6W`N%#2om2hv;Hxu89^Tnozzd-ziXOz&s>n`GpST9S-XKSZV0`BMEWX^n1YGiY3++0SlhJ7ZB0qkAx)1SrU)Arjc($W}3!iJB zRUBr3yDlW|&m;eZcq`JEt5R>l?l823kL@RK`KbVIWk^zYoA2=Pfj|B|iTKKMl-l0? z68W#(OyzbmnY}^W_rGoPgwEsp>n}=yOFn0N@jT}NmvTGdCS`2?mOqmIE41G}!E~$8 z@rnMNa*5{WOyc(d7yb*-zU8v~e?_Co_7?(($a6)ewB5l<0+3GG;}ZS@u$N8HX~F#4N`pF#a& z_5Kd=S)b7FwK&yJ|5DQ}qduHK{-+Z^0CtmHmd`n$i_8CY#GhurznQ)kZ1$^ofAxXD zh0jl4Qo?OWe;jbB_vW(|FgK3n*5X#-~8W7X!`jI;1Vyl z0Sjqj{h^jrToWv>s$XpKBwKI3{0NSekGpIa|Q6t{-pV| zb9-1E!RS{N-<0$Irhn4FMK9U;7+W&`7m)tKZz=$_%S@e)wFZA zBAz6^>9-Zwk@!)>{q?gei2LKILta<@fAIV>7Z87$_Qt{F|0MA`=4X52a;}i*;WFxB z%g+{XD1Sfh;xOPsZ|8kjy?+|G$eW#~!s(pgX5i9Juctnoz;e5n{QYs|ABg*Y=55}L zZ!e30TiNoH-0jK&^iKd6dD~^FW@KN!RQ{j(T?@}pd@}J4;6m^F_iiKp>)A?w80j~C zOX*uV9z2%#?Zk^&{-)=jB7O$rEfVcMtt?{3T#PyHF1Ca<{ybyJf(!DZ?}9$ z`TKFIrvewbvU7I!Ape_*+c`iz#2+OeJAcLUv)MnDzaQ^$2=U_YD+ALT?Zm6Ur+6Fr ze}lLmS9Tw9J6G%!t)5`VcQsw#ZaIzk*&iw6>&U+p`c&j?9`&L1i}*qw46QG~V zXh)GexB>JcCw7j<1U{(5xJC58o!4UJa3pZy|7-erK0*3>fyb4@xFV&u^ZbnF5aJ0> zk6l3AUx)Q4;=Z3bh4+o8eUsdO4qWoN#PjRUg`Y@pe?EE@@!i-U8p!Ms;=Vs&XS4_5 zW9R<8MfzRQKBXUA&HcB>5uXIy(f>dJtC#DDm;FR>)04j^emCuH%g;^d4}{O-C#rnf zw{JQ&z8roJT9{mPfap5O`6 zuY6qbgY*`>OnfKw4|3V}Zn>%Q--ZsANAz)UCh>XH+XoQ;0rBHWxE1kV0vCC<^Sn&& zz3p&F_r?0XQ%GOEnWj6YUGYtcpF`Z=cjy&ADdq44aSUy&6e<$wy$xlVaNxym1eae3^)7=?{tCYhU#^G2wTnSwA^DXL=O42_> zyn^l8*9JrT_X4TF%#y{umgF!pC2yb_H=e53`i? z_W`%O5puWZNdMGChml-rAQ^n13>T6Fz7A0ET40?ReC=z;wIvL+}-=c z&*)Y@yORI3?c(!uNdf#3;F3=}f7bNOhXv@Hw^#bxVHe1Cl-`1G6W@t`8!PAcN_4zq z=kb=3elp}+(mfM)kX+X9p9x&_u$`}Xx;_p@?O5dcW#9k2C2-+WM!mNi=?^9D?{9My zaFJ&_htj@xIdDnW&TpGVK0hI!y~?zlO%EIj1up4U!yhBp@p=m`C4M69DEqGM5dSUo z{`%Q=;_t!`KmH6@0!`AO#iuZ+oJ?cTO zYE34PxE#TsVE<+9F}bJWyV74|e6ApVTRK{go4WZd#CveSlp%ka2X+0m7Y{QDxTNdH z5j{iP&bKx>zX$O~LhsM>?gV)f{JNy($I5vbaeqDL4~Tz~a%o&P#lUkfH+K11j~Q?I~} z>F2zPxW8}GUx>edpwgTFt#x1JW9Ncz%ly>ur}(+F6O8^c;9}nf97mLr{!!pkk9IDu z*&DBskH1gI=>3)d-LRYFvU)k1_$xOnV{1DLiEmY@^d|q06Zie@PQ=J9%=%1{t$im$&EP#Ilxa7x=NBtG?^ZS** z^%tG!Cxre(=Ci3-Q`tVDxbM$DfcU-dE1l_$4&u8&56NZq{upt8-_$M9ZYAAgS?^}& z4-milZsl+F`yJw!v7D_Rf1S8LzcasF`LAO8Jx;R~oI(7?r3zTTe;e^q_RD4m{tmdv z)oEvIe#Yu8*tSCPtIknid*Vj`m+!i1l=7!p8GM8IEA$`kP5Q@(+xha=PVbx?U++%? z7ykY}&wnEB?<-r3@)deNuKPHLGZUfP0O_}3Ia~ey2l3}w@1_smCho5ntF2P|#Lhjn z@9hOH`FZ*~nyC31u5#_Er&J)S>iz9E>|c>Ca{T zT0ZNE`{R_Sh;Ln|e9T_@H2P7I=Wq2XZhY=1?#Gq=iTJy)o8+?gHCQX{WqfeO=QaNa z>Mi&Ra5w(CNa;(7KL}jX_16o(L)_mtd%M~3?eR+B!pGlN;S9*1;Lm@k2_DIGzee1b zha!}V(Ci=^**Nm0`$zbZig2I%rfc?9Nu%=j_iZ>1xU{cT zU(xS6jFs~x();>+_on##^Z}RhziqLmYwi6K)mM_B{V)S5%=f6s*YAZzJKg&;`cNEdokTRiTm*nza@U{`%1Vc>Gwc? zAocRNC+AJXAHg_MF3bOe#LxV?GBEtmW0lY8+bX@ue{~5GzxtM(L8RC^3*O;8&O?=Z+lzuMx9CW<$@z*1N3AnQdJb%cKNPp}1l!4iM zFB13n6FUn1w6yCrXK1=+pDzP0<$T8L%I75J=NjU3cTjq>TaG(H+udJ&q=YAs{%632 zkH25aCh+?RelOd*wTsUfzKim=`g)$Y|6Lyt_v0nn7b^d2;75_m?95L#EAF3@(oNjo z*Y`Wb{kW!=h#&iue&|=I2>KT(|EqS^bm!~i;CkSqm;C**){wr8e$EEczXROW%el&D zG4bY>czv}3xRmFbBBeJyuyd>8{yzVQ68}k3=}itl3taMf%2k@6jYGdf`ooK(^#1}b zex5sNua0Iu4~O4M@-yWb1$HBT0`OA)9lmt}mvoE2sHnx`{hWMu`h=!y?R4`t<=@JF z!Q>=ET*i@d)hN5*DdM~RKmq&SD(H8~=gP+wKZx{mh_CKZKIVUWoVXu<_y+OYcT)N* z$me{Fdxif_+ePzJ(H>uqjSh!?TcZq4B%eEg3!isyR>0cbp7=w`?QgV`f1$|)_mTdx zyOiGS=f)G2&pihzp_SXi#2cue?Rz&zzb@&Xmx$6YCcc37u+_^G#BW6Vlk3wIh?)-N z6%EiW0)xf2H ztoQoIX43ESRi#fd@y`R7bf4W+^Lae+?-BRU>uJRJN9g^1Uw=pZbNeVCE9a(Vn$PF2 zSH`#N<6s4F;WKJ?1*S9IeU~dto%z|>Ot@Z`On&KPlvEN zgI}Jm{1?qpdeeKwuva8qe?IE~;L>lFUaItFXEp&BIT^o36TFY6~dANZO0 za%%uC>Ath8^0)T;Jn`EQFD%zVvy{kRl z+}qo{Je}$4?_D0W^)`2A(yarXoy+k`=vNw){Sne7nU0R`le>F6S|{}^n$*$~q>pXv zuS?YQv}al}C%5-y(kTT|gFSgLTm2vOZ zOYyeEmRRo9@`SwFkm<=ZL%L_SXF6J^Y8@j3jqRso*780IW`0+uyKQcB-_o^_mM^t* z)`7ZaY18ta%sLPzDwfXc?yqldS(<5G7xLuN+OEOoj`kdJvdSbeooj~aWX7R&$%T6k&>1^(E<+`?H+S)syYS`l1 zp(>iunBA*u$zpj~_Uoti^`SA($n>@Jw)cqcn-3nT!BmAP27K#UI3=p5wzh`eu7%FT z+tN^s<2o>@h%yN!Ujdzh@9J-Far(0zm3Rt%b$6wkyIS$>svhNcS$lhsKB8{^w5fG? zWnfXdHjSD}l;x_oJdqApWnRgpQ$db+(&FBpmaJY5t2t4_nPn|Yn!6TfTrQehTT}H5 zB>9LsOeE83sLf7fy#PgWaz3YYUwao6WvV`(A5?9QUtzjrRSehG_P(Cx{+1;%d_`@C z`1+I;QV==ikxVX~*4`!hskgVgcSfeaxxJ%rP9|Pm)s+(B^ZyTQkug1+%}-3<`cj)w<r?auqUrb9ST4B5wurIP_ZubE!fVpVnIPIXN*m)4!y<)n2Y`&2;v3_h-6V zme*wlA<%h1!OX7*t3qEixoWt%ihickNp<=?XaA1-qYpuS+jEd3r}X#spLQmUp!@Wcqs0CNmAr z)~k)MN|doz5)&b%*{CR-4Svpsu2V3 z!IG$K;D8@v98uDJsd|)TS-LtaJz}^u_E)ua_nzF`+gjT&XKti@W-Cp~ryW%>Q?rzn zg?Y$NqFhUFdN*opSwGWAB*O-03KCS7jyCty{HAonJP1K$Z>F;wBYJ!vTokaqYa5S9 zrz-l9V`rv-B#~|!fJY+T4ja3+t}~IE4Y0!O|JIB+E265!vR>hYEtN`5Pq^Z0?62u; zUJCbtlyJj|i&9qFk`tJZt(g`$G{nM|Qtzp4N~cgmE-xa4wM}I?AT=MKKfkduPen#Q zetJ@by)2K)vWNnNU}xo>8MVrvw!A;1dOh+WTg%m=bmn!>@2Rb8uS}(2K1j2j-;=6e z_ajN@Xyj7iUSd{KZYfX2FIku>|FOw)sH>TmgXzv{8gn}7~Hc^Q-0WG3U zBGkOfyD}%EfzgkHwv{Lw=xWD+Hl%ZgTO#P9QmLA(hpM)*Dm}ZQzR|&h^-bv+J@Zi( z(r?aj{UMu6qC6u52Z)#(IZT@j&rw39Qfp>%Bb-K=8HCU-)8br8Boav!8pcwp2WngJ z5eW>!;K%E2Ztw4_ZAmpYqX=3>ddid|>T0J=Kl)k4UB$WLm`i={^IWu;Fb-`Y%bl5_kKyuyyIF&O}yqqMxd1 zK|@Z9cc!*MytcDbslf)of~4Cznir!-(YBYGH|NNX!BiRC-1;$IQCEr5oZr)!>1v&e z5@}wXG35$&>8V}I(_&oJNI%;GzfxaqJ<7jEdI5C%ZQam^P3g6}!xD+6=0zPDv?}PWC(g;x+&xsqpONtIBYR!cG#DFsniUUyh!zgEOzPmVe-Oj*XmrS&I{xUIx%^= z&LE(De`+8zkV#b2Zk-BWBwTe%V9#Xb8r`n-5HgMte|t_gts7L`r#6uENSTvFGA8qz ztP{%X;=DE$(+ahJo1UmeUk-k*z(O*UsLC5?S;0hQs>VdBAI-BYjX_FQ#Q5!5tIOF! z`68Hd?6IYX?M%Ra9>}6_Bsz4Mz=pX_a`g>$N^kWaI(Vzg25MbMykGk&{+eq z%DT!a>u?8*&yKWc*Us@tgVL_G zOO1$Q#L6tk*ur$zMrmJScxStPXU^2l7Nd~ORPtF55z940v3OkD%w}KP2TkT_1MMB? zniA#ikEyP%d+BJ8N>`F%q5V@sre#pY!ZY_g3(wxt)}0fkoU+>(#iXUwvmEVUDn@PT zsbYP((n0|hC?B-tsc9(HY*(BW4Hy&Ry@e!7!w}yEltXnJt%ur~gQ2l0x)$kQ1|cf6 zz?v3#MKV&&l+9aeVyNaV&)LHaWjJWlcix%#JzB?7Thlwb`!W%=;MYG&G{4A(&^^fn z`XI<~XAjIVnRQEdh%YRaOp32N|A8=frb3=jTNhPGLCb&(wW@=ojnv;I(H?u-7cc4W z?6&zS-yF@!QThC?#w7#&t=%VgVZ@)pyl?%SK@pg20Va}8@6p9T>jV-M);Kn3({ZJ| zS~$gusTj^Ss~WBE@2#3U&@c9Y8zB$hfOA9W$&RJed7fnZ_M_x2QBAiChj}tbWk#x> z?*#m%&J?OcFKnh+R10}Y7$>N_jch6A_=^W1(g8<0Xmv8$^Ev(}YUw4a=6AVbbc)GM zsi8{3_FboxFAcM-0GTq)Yl5zzLz8VLBHp+@S)Ezdlj(&cs;eK-7R}-ug*8bpS7Zd_ z%rOiFsi%>(kk4YyFr60Vc}|N8I4y7ja*XW84&IOp$X+6ysIk#vXk-_oe*T|Rv2at0 z(mW~M-@F+9PZV5ZKiw*2so8lp=WyIAVoVLouOj`V%RsUwXEnpU-irVmIIVg!h~$yE z@I}(mW_$OX>jhS1Lu1rKAc7EW=gGu0iSt08d!)>FO2;dj!|TB!wikLSxM)M812?=A z$8n5DS8T|#bPe23^gB7aa&1}WM?~jQo))i4e*Q*E!bZT>Hbsd}vc(OVBF-1ddR*_} zsfI+1YEVPg*I*GPov5A;e@#EaMwTzitc#TamyOqp%oD$Y3DO7-MXS*>hkOa)GVn(D zI?9BwBA5#k@Gg)8!|fIbRDWW!4G7KE)r8rh$?)3HQ>>0z8M)!V{$yn@+CXJX*vM(Hkn{^=}?|jAF+ZKodmVCYY4T`B0)?60K(#sv$$YVU9EP&4yXe z89kRpzlCJ`>qNy-?Y$X9m321vi%F9#4~=SFlbPDl-rSdIO|`G*nAVNg3s&sVp;F1p z!f{9;_e1t;3QXNf-&~`nJE~@gfst$XP#96a3?_eb^_(cn%{3&da(~yW(-)c!R#N^n zMzo%jlbuNe_d{Ngk^3x&U08@s+zU2Cm%SmQ!ID)n6mD54B)h%NO_e{PnH-bugtCng`+wX_RkJQqd-2W3U$$<3GyLx%G;WE^A5 z!de-VQ2I}p@q?IY&U&R?*JUVdGI7FTCeh}|bZS#358)P~fs>m^+YoyaZp;Sh3eAt1 zbA)i1?mK4Ds2k>#=LY|nNEN35=EpEY*4z&d;G%(ki4%`Z6N~eGsOeicXtUF|dHsxP zvV1oO(r9XAHe*D?DFSCE40~cF-yrAQiq5oIs##q-Qf+rAf6m769~JNs(nsVAboO(T zlU=KV$~F(R*fVZ~Tsfm#n~!vLc}**}|3!S0^CF;{mtOEKbj&=4$qNJb`( zMAK|6ySh<5Ue1x4wcK;#J4rg+!G_g5djFo~tOR!Cc`lNyR3tp_Rif;OO#eJg0>Gse znYxy`h|cE1S2zuZ6=wLmFta9;IdBPQI@4`kwZo1tnH(Emf}v*A`h|Jp4?i&vG8vmbwD&JXcaPYXfE}32w zi+YYMNRk$un`ThLT;Nl_Iw%$P`sPyA3gt3_OJWwe`fP{;>`KCTRtSr#&+ zepPRlCQ-@9_06(C6Y~wJlmy41)rUMXI=hY*6)qO5A@^K-3v13QnO1D>&7^2s z_(d17`D|bwiZja()f-N?;iB)r6=s@hcIh(KDZJQ?fzVB`#jIPbX|(FSB1eZ~!A+*4 zBG#f#Q@LUc7k5|+v;Av?AR-OrHDr{;;Dj&N~EyM znqPm}=ANuw_ zt1;c@!p{(WhaiC-2?NSDvyIWkVP)RjG$NPN^CV{2eTBq@=_k5SP74`x@iDeZp$<@pUf}^^%a{IuyEhXYz?lzEQ-%H8g@MyVb>A^ z2pDmoRcTCbY4~SWacpovuMXAnG+B7KB_Vg&1hYEQ(^SJ%eQs)@kUvKrhI3Gk9L&S_ zBNR}h0^Oe)73ltyET$}4!>`=fVW$Z0P;>sZ^P%rs+q=>Om_WhTTQ^te`-ccgLe^m% z<&Q8OZb297iOxl^xrgC07$O|f)edw9X1=))VQFT$3w46AA_~I=MaSrGbmFd2Xo!$s zZrM-uCz{+kEg7rGL?FH`wt(f)@MC~NiXz`|ooZA$&dL zWF5j~gxbQ=5p1Q?eKJ;cz=jtCaWF4vWrU`qVEl$=qr@68ujGdI%+vyA?8UTnF}_hO zVdJ|Ip>SzgriP55L%<#sxq>iPU%CZF5-pHPi3(A?L#T^rq(RkOtT2?R^>*<}SIa{i zRH3(#wT`t7^)nYmoY4?cI5@@XoU2~*bT@(pH8?RfAA*(0UnYrQ7@JBoJq#~tczUc1 znkw3Q{E=$iqB31j$`%(FZdIrgo;p;}?;v;K~QGUJpO2o~z$7=nEe~y}XgL?;9eXfm~ud=|*K>;t3W=TZAiJVL;_GMZI zda>|Y*0P`r%`PtDxL~-8*xS5VyQtlIVa{FS21VDf)cJNxe2ef9swUyH5RU7 z3mWVd#jgm>66D)H3AacX*~lA14AGA{;c$gWD+(3k6hyXg!+tlh)#tRZ?G3j`;h%_^ z<1J(qJVJ919@+{}vk1;b(*oyH4KQ0A%I>|_9z+P5rg*6>1T zYb*|#G6joWr%tO)Cnl9=iwJAj8XCLBC5owoP%eZZ?^D9l(U?V8TUcep4~NblBTr}Q z=fd;zlCbQX->7gYi0=npTFl2YbVXyXhO)EPYTJiwDqS;IIC%@0iHYNcB}?;lB2aLorN&e2fUcd(E*Q*Q#5NMQ0s?2CEu?nfLi(Vo9hFP@DWDHH9T}dN2be9LA-4UA?)w%UOqy?>VgEZ z&RKh?28b$6&$aYOBhyS$;eHCs-dj3*{7<%iTI24Axm%CLM?0I<94p=q4~V_U?eLIi zlnoUK#@K~y!}8o|L-n2iMed{#&}K66F7pEwX-w$LK0E6t=4ZF?*`e z#M;L3o=4X;G%YApw4u&$1WeAn&MoGnE2kki=*XUwTZNBCiNURGbRyfF=xzXO83^K) zydYmEpm0E`Xf`#%tB83SS#1K|SQvzzHPVaRmWUc*h0swB9ZanwlsIf@m>6W|xSiDm z_n(dsLOTepQ>0AL+1%a*S-_|oexHuGolzv@D^ZTHF6^Ju4VlCKCiDToxs>Pji1wIq z;UuQ^9A!*3n3p~OxrPW<%yWArVL?7CYNN%aCz1%l>c9qC@bh5NwCqshrciQA=_792 zh{+GP!A7h$E5oppDK0r3P!hz2OO^dhE}%MM&pcJWLZ{? z6_h3tvdt7Fu-!u5RavBQ$Ey}Fm0Q+J5DOnb42|+7^jD{-0%ZF^K?!8vdTnqK{K|l z>6cxJ%99o_?SE!gPbF*2-;%ffLBiPGc0PH&E__G=oBR}f6OjtCkQw#~)nwGP7^(5h z|Cl8vh4&oVc!oIUN3cE05b>}7kC%DG->RDj0i|cvj}7&zk=P+K=%VGl9s#d; zR)7Ao4vdAOc57&BT8yMIpom#9f*_%K7u=QIJprrDb?y(YAncZ$c3U&T6P`CD*f`?L zr73-~Zv&23Xhs}XcpoVkFmaor!SvBMUG1Lowpn96g!)MFv7`hqRNzx7P;^SY$ObXkj(VoIY8wK%y@8TkDxAwe`MX4=3CfEU8y*popzONR&}^9 zaltZIxQ_cV<|JzPYjoDZWHIw7?C*+-z;L$Wj@zmfdcljqE3ifST9b8Csk)skO^rw= z9r6hAtMaFH3aNW(p3&WOBGc%J^4h-afEBy4P`6@Cy;1!NuxZ6x#sGC0PE@9y3GIr? z;x8nOLxV8aX@%4}M6mk$CM$zO3@Q_qwuQ7EdF4t8igEbUqigZqmF4y`%GqMW4la>m zi0T~T_WKjXO?G=WFHqW*KsYoJLY0m39Dau`brtbm>B%2?1DmX&QPb3ozSC{p?+l)( zZ5Hm6ld?ob2C;PbHG~3e}&?yvdJVD_9&;#xSqi!Cc=L->i}=cfx7ZjFthHqr#BRZ%E(dn5)-F2I&&2~E!JHVm1? zNl&^ZV>tB9V$#-r${kvd^P;bBV4Cb&JsW-m)O_PKxS#d&--8d(nbs95o4VPQvl?%a*0FO02J2f~NbIrw7Z> z8OTx?o80PK-q(*{C^xy)9yJaUax9pPif~qQZp31vu3-*UvYt&-G1RA#xSp5=dD(M1 zkdf?u3zmn-%QlOJs=t)~>2Ua319X>!*G4P^ITdm?=G$=|B-$w( zif`muhY)AUC0kBXDHYrVtqsyV*^H4lVF7E)>D^ah#&pbqy{s zC;OpMomy*n#bAm78r_Q#yIn9oV`%lA%9@p&J_Cbj|$%PrrS1B`qXL$t~{8^lUJyipx4zfu20Nwwe4P#tiU~53vo;P(HAY;d3kKSCckq)<@P_iJRtk zJx{cC46|kviI50Dn}tsbThD0NkW+1gV_~D;W~)0j#91;fry>mW;q)CRS2;xe8Qx(# zVs}{c6qCc3yIfI+CkAy~il&T}3hoeA(Tp+&7qvTVs4-k4M%Jb;!O}PkpU?%#aX^wa z@4MqAlXfbGBf8xNh8MQMha4H`c-Z%%Cf2Tx;?K*<7RyG8AvR4cwvF#r_X;8=gdl~} zZ*5tj`(iYICk(?~>d9k`B^NnoiJonlwF8FVv8jtBZ>wjQQ*Y!woLKz=D{UYVAy>R7 z4>{paY0P5W(l4h`LTY{l7WRb?5wC>HKw>~E()bTDiP)9!es(spE?}+6pjd`n|~-%Xt#!ut=62AULyI-NgvK#B&@(%xk`S>EgG{QSPM>=#o885nTO^m5;{kr zJo1kDkeQ`*I_6^|IbyukS@FXHo6XH>)gep^=?aFgb1*^-1&f7ukP*9r$B$&w4=?+X z?G)EDO^GnVE?aUW5)OxmpQVcv4sVH`ImzQl3x=meWGnk&`JIKRN7(~7d@NsfH()wL z;fY+*-D;anYhh$-as)@R&@5B4X9go<4H~sCV}=nK;OjhV+)h^;XUW2P?a__mg?QUq zx9ED@ux=YNfFB<6+!R+~o6b8aEm64u>v}Pf4Y!$D&HU`HWay<-1QPJF z_8v;32DY0;XFx+iO&VEj zB`d3Szn{E*15uj3PK+5K6qq#9Daj#>;$%hcY+;6{duv|(vgb*(!`*2JPB*vL5PExW zr`v4P{(mk&%rux^gxN37n{Ta}ileO;cgZP6cKpEl?YqM*Il|HzZhDEyoqD1(2JP<5 zBY&!Wh#`l$4g9YvI72|~pEtrUXsOc85Sm3P$0iB!ZiP@;=2o7_p^1rV=WtOiU|y5; zJuh*I=!-~UM%rn3_b&~$WfKouM9G%)q5(PnQ#Q76A5$P;(_&NDX%AmX$>BlR;a<*! zal5OmrQ|l!2r##b)Ffv3Mvr)go#jyLoc>p6~0RKX|Fi?B%?C(Iqrv``(>tPFY@Y?xjf=f^7K4RH^{R^7U7on6VZpVjKd zjPpp$Ub__`*0pS`=}(-*WNp51!!r$w&nmQ0`-X>2x*ZZy-hdawRfp$q->%w=E}BG{ zbN{0mwlZdQNUwjQ8k-cLA8zSw??D)OpKN8If)*L}N4-E%3(Ll5SuL_b@c^Oe@#th( zUFT5iG;E^}bo!wXwyfDzV0(~kJIXimhltLMI*PJ9ytcUB{^J7E$$9N@h;7{0A)->+ z<@!#ChhuEQM@@y!)`;0uJzG$om!x1xr`%fG^8SIIj!YU+*qs?H36(k1+~Oe2oMMEZ zqU9bM{6xPkey`Z5Dvc2V9_bYRT(&akB3V3LrjBD-#_O!<;ZKt>;7RTCQ0HxWMju2y z(8;7svbSay4J_8VKAtDDo>_pUVU|+7;SW*q0uSNZlt{V%{!#AlAQsjarg~kdOi1}kVYuCAn=#sK@8>*6cALt^{*J!5UC6Lr6cd1jw<442jl$k6 zjIJE|WrBa%WLy9A-$&Ni^g?${|LvNQ<)NX}W+( z_B2SPvf&gUfSc7eUXq=AGmE=>vD@Ylt8=RI$VDVIP%dK7L`6JT_gMw)iL4bt+<^iA zcg%!ZP2~ykI&}7&egrvJK9NHH@&lhTS%{8pW>$w_hE{4E5dJ9mxtCrD8bYcE5tgYQ?%9EE1kG z=vIWNCF6H5lj}PMa8R$zsb>YZkekM}-t>m7R7AXQWiK`|=rc2KeEEh%{U^ z2B7HIB>>ptA48 zZH##{>AriryES;VwWB_|958DJq8!&J3ZxamB!jw8&~NG5Db={XWmb1LRG$o4`VndA zqGWU1DXeGG33sHLXQ|S{_w$msQ=fGQd3Mq|9*&cfUW^dax+qX*xpFH5QJ^IiGf_-wowYpxF! z)m<5l>dpmt=Jt`2z4IZ5>lp|#IW`a^Z;KW5tiYmrOTy99t{=(^3e9yy7149uYHIs7 zY=S7;reZ?AA$MW{gndaVT{$StKQ}e>U+9Kx8C>ML>d?fprXF5}JmiEj26VXzdeFRsJ<%xK*4r7!`4+;CQ<(ws_LdO@q3DR@f~Vlm0?*%NB7Cyy&bJ)tC?fRMk&!=(mME%QIWOm z;f=^Ig*ZP1P76rMCW)~dAZ~Pn%!`-eS*~bYT_;D^+vM6?$Oa1)bfhgcH`=B>5Rwhn z&z0D62fH;&d>#*#OCdBBr5m?80%2detO`!ZA%)1*`4H`Bq~=``WuYyOT>08IM|s*Z zvb|1nayEp%sas|Nr{nNvZ*#}^6>Zu%Wdm67jU)6eDA;w{uTnf%8*d-&3W;+G&0emj zWkXM7jF=P*1n>$rHsaH)ix};$6K+EkVvVQbhqsY=&b7KREL`Ir)qvhO!4%@K?D>%$ z@f6+-Id%Ze$rxW#6cmBPWH$!HrtA>HRu>ILhs4mWx!U&eP{Cab@e!GRXD%tRE-S{7 zBDSYEV!h-fc-`e(Ok;hf;Kpiu5>J~#I3N}Ul%=sQU`D#p9a*0BRAN3gZ+{`r*NMCp zuzV%LaJ{DHHioQYDzg!jQOkIQQtTQ%=?{IW$y&QZ?3s{A%;fZ!}`+YliZoA8|uTv;HCEX2o=qh?lpeNrCpAtEmJc9J`t^{n^*=HnHqpbRyhk*wznw%-5I~(xzx6 zuFW+}nXVjx-RUJl-3^?O^ZY*AX2RlHjSO7vv!g0GvTZ?9PNWs( z9et5#IgSf*XJNytlc2q{?rW}F^9>cBT?xgIH4j52E73-B0M3zeV37+wLNtiy0gHs8 z!H44yE+sEAl*`{0K{sKpY3OOu;Ao|bPHl@fq#UbkF^d--_YHz$ZV8e~pg&-##A;)> zB2x{J@fIc7D5^#x)LS~byE3|c&pc?@NDwy4Hf~`F)~UD^#9S)ui9nvy!9>Lk!(@yS zX|pVWjqd!-9^VSJp{u&WBRCs#6%44awjg9wwF+%sZHuTxMM@n38oQk7=~#|&L&yUF zNhr@3g%OSRi0tSp?R-7MWO6fvvcYbCdo$ZBG#K@_+=)twsbmZ@a7M7arr{?hE3o2+ zyKGSMSa_ku2n+=)a7v||POqDZMZGzB^M2-YQDMm`COW0%i#^AtIUHRVn*Z-6);fP^&vGDC+=An1DEgAGYA^^LOp7*YvTxE#j-3ho)nC#tL3s z2|2&1Gj3CjN5oDSV_1Nm2;o@}97Mb5XgpEfi2ZN7`c&AAc<`TBtX*KUBDD?#uHm2iPCk$+Nf-v}v4Z{6 zWaH^auP^ibFE(Qp)3v$zQR_|Qxh<0ty;@-PmCmVdj5*vwKA%*9V8Y=m0vVppY3VF9 zK$R%Fjkfg_w}4t}kI%trA$45fGWFY6O+pQqKq2(Hain3$Y?W# z6W$gjm{Tprgb6b+GhygBI~kucDAKE!sA^X=nQodpJ)N32BQ4fN)^V1L{#x6Je?20- zbO%h|N?7MbkRe5$id_PkFIMhzhF_Al9le}&ENjJ`75LwClB`IZUt+PQAM_?7fd)Ep zW=2#!4c< zCnsC$Iq_AKT?%NLaD!)P(b=Mkbmo5eUA44!%w2S;2Udd8-LYU*vUO`2m*M9{R&tGP zBqVQgTSxO^Jw+Af})Q0r5PM=E`!Nr0;oIcIQvoUU{)&|(u&C0Q}r-P zI_?n;x7AaW2ea#srllL}oD|@-eE;xziJ+Vdqu!GtN2eQ}8a$NQ&?;mfTh?Uvsfx6) zNxDZB>oYpQPgJ#ZclPwcGKcQOKA?jct|lB>4^%`KAv!T{k_!9p?^Zk`!5ME+A9-|i z9#xMq+Hr8h+~ZB@dU!k{sy*L3J|`q9@E3J;_jY1O6fN)>uGN9#U@I_+TA$fqHpnz5G~-Z=Wf5@ z!W=5#dH8x%ju+SUs#rYVt5OeRD(BmZh?d#6*i0ATwrYTbEF;F`rv@?unWq2K-L=Fvnq}qi zW(0x(As8NmN-$#Anb>*nx*pDSx~nQtQq?LUgxhicB(91dZ9A#T%mxsPVS`u$>-}z4GTthG{ z;Ogzz)_|tA5Pkv|BhedAJXy-6?HgqWhFY6@G^j12+IlH6h15BT5yCE*l@jcMa3MFg zUOnyfi@jcPdHVFKe`4B)$M@&dZiHz?{cbV6TZr(;6!7Bi%d&CvLC3$3%<^{C8TM7Xxh1X)!+QbPJR0u+BpkVZN9KfqsKQ zb2jDdu027>)l7RJ$rk23Es0SGxxATjD83v>+-x&~!7o8)3z3Eq!5>DkNiI|kh|5C1 zH&H-r-Gr(oWAKnub$^p)6wp zeF3FWtWe;Wgl4lbK6QHhM~?tNP2P+|(zD(SzRGwrh`#TUN=phYYFsImHpo1pl-(Iu zzSc(_BCSMzSZYG4A{HgL^NsPS`?z;9CiII)7Wm00G^)~lY3@=61jOquWC@AXn@T)r zY-G~Bd0U2L&(IJw*ndrInDKdm2J>`wLacG}Q}UjfKvXtJ<^-+NoLtF9LF*|)tVq_X z#U5mPWF|et`Jx891d)W=JeCUXvUulH?PYN6`Fa?ml3Ddv95aT^WaSE`tDUJRTlF;tEQK3Yk5{Q2*4J!X4WU}ZL@3$T zfwfX16QU&Bs&IpNX_N+4bO0ZI*(nC&`GmQ4Z&hy_)KY+5#oTWyHUM39sFlwSq!-!x zvvuwbvvd@m%}4Ip!?Mx{g<3P!OfoRq{)lei$Dng>Iy9>co%^W33C|kxf&| zdhy8K^3njMSehyDr=pw)lfI;Nq#NG^>Ah^^CQOf>P@5{|KhOFVKebXJW1b$4R;J&0 zDV55J^<72nYv#2e*uKN)Oq5LZgnQ6nf)2fRxt@NEI#sh6@HT`7`HPx ze^_^;6j95zsOyqN%?BsFTN`D?Pa>&4X>2K(6bdgr-?ye%y4ODv4}JdmF%D5CR1yk+ zm?tm@mqfpsf@&HS)FGahg5T>E7Z7m>@F~ zF=x(3vzLMh%k(NY&Om&f+SXA~FQl1c*N(DMd=gi-q3VE50IGodm>`3G*HP8RHE-BapeUCky8Zfdc-vT`*^OUOhq?V|=;fV!*`lhNKU)xEv$cna-QmLxW5zgal z%M?^g*bJ!DR{*iowY3wJeqTnWj8lyzo_%>7IGZL*;@61>6l4(jUEuEVaf(0N=*B*}BCtNMxwk%;HW>tZM;=;F=5`$T= zP$7zu!v-@!ok{GQO8Y>rOY7Yl=bX%)T&2l zYyb*7lbb;|7WlW!ch$4@y|3jZAq0KmLcut))kjOzw1KEo_}PQ2-X%iZjV%CNANMBH z0-P}Chr_Wn-T!L5E#WN*^iN#RSStGXhIpy`7sZn&&`XjSgATt~v%ckQQVOf2viB@js3 z9Jgj@7{ZTk>%4t_*&DH7t4N$TT5m=u#qUio0i-Zx0w}>=Bv$A+@e`Fu*6NJK-LxMR zY;(AGg6;wiYlX-F0jg11@}x89oTFXV&^GSFwABR0xl3t59pa0!)s_%9nQCj>HcZ1f zFN?XL(Ltekz%@3X^v=gzYIWSbDEb}fUi!voyZ+!ME9o8G?X5%kjmAc6aMgELVn0_O z$NS1t)b?JMwTtW6sa2ApBs+{qHW`i{fT{|uF1~00)FD%imVpJMS1f}DTAoSBq! z04g1{fKFrBjel2Rh^Nui28!T_D1w~2Ciz^IgrA{N6KDHyJe&?6a6>?6o~rd~H^rO@ zYg%%Uomg~QUE(z>`JhYkv$1Kvno2e0vv#YI?^YsBAN*NRgFSji&5R}LV89xcj258T zI7l;w{5g4Zqhy=S=Aqj8Y?kqr`8OFpYHVb~G8SFG5i}VCC|L2{xs}n25~{~c(}3~= zW+%@_!xMwdY#Z{t7WbMLFUPpW&}gi=EHTBI)e)*gK~h`paqs*B0B{I~Tpg+vd20Q` z_Mt|*++#1YSQk{9rerfQy#m}tbB$640S&fz*@Ngj*S80{uud>HsLb z9?cLA52=?lt$S{@HAdU< z@$hxb#88hXh+fw1SH+F&hY|o0?%WauQB~k_VvA&{Xqk}8`Y?kQ#8%TBnj+d~gTA=^ z635;sGYN_6S0KG4F%U=Zl7M9cOn6AS?it2K5nS=8tb?P5OsE?I5=mrRB;baH7jWnC z7>$gf!iv+PqH|LtVhe`J`Se0AjYrPHjo{@Yfe%;$GlGxk(R(MOB0>=w4d|S_>u6hs zVL?KD)a2PgJdl3K6^*mxNQ%ZEwvV5<{F;hJ6FQ<89j&ND$HHW#x&A|iG5F({OSoELjxw^=R{E8EUQr!|rp3ATDb!Sr;+m$z)^49nCN48op;0#yCp5Wp z2;^IxTC?=j30>bP@3y2Bo+17zsOIrVjc3tRfr$WJYIza*6= z00?ZmED#@M+}xaIv;Fv_L7pug@{7K!=C%e;w3zseYR0kFfqarn3ZI|m8Zy`xYOs~G zf|XSfu^ZE!l4AM6l9+((A|^FxJ$lx?v;+&MQ=o@O&sdN3&nBbpr3F$VP;)jSZ->|o z-n%6)?Q4k*B0ad8hC0G#sFA&hO8|JW`)bSI*@PO@q8V!g}+MQ%C=ib;rUJPiu1qV+VPECwu6%#q@)rE&{q13noG^bEdWZI=WakDJkl8(VR<2$w z6uNqrX`bJPYbjwxRcJ^&EI~5)7ZpmLT=P@)0Wg~>y+AZPiQu7K@fsPs`$vFnGx!-Z zi!~)Z!Tcyk)@-zPWy&@KuI3DG0(pQ?vqGOxZop%7hd?GfQ0qMF0qS&9!zOufz1B`NLAm9oXqweUiJb_E_I zsn>YizXLn9(|<<&3FOczz}XnIwGAjlm@DmkS%ok1v1BBFmf`V-tIO3a1{oJ(a0Efb z(bb@JxY1;8-2g~Mq{smKUnmIc@XuC;bm=5F(}cV^@@ z%g`3|3jUHv@N&|BRT9EZkHskkS+|)bcs$jG{PYSBbIimE;1A-LoD|6DzRlquSzJPGa3UK)CbK48^(=JtGI^mp8;lyRrRKcay)(i~=LE(0NHGW>GN^Ze z9ed1t!3dYa?h*1~aHqVv3Bm$~eYi3xg0u{t7^H*TSxviWgDfa!-r>jwsHWXkf~qYc zl_lTNc(%2z25ecPRAJsvv(fk8MIEgL9pd10%0b?NscQ^6F9HrYTt33OUJe zTd>M)hBEWp?s`V2kmN*;3)s(#;b}GrM*N%128C8s91PKL_|sq24vlxoz1`}gl7nN+P#ROPdpD2bXCuh zKWa1?1bZ+dV&;kZMN8fjNTw0aas*Ho;{CkEjWTODSDUMwypU%LO3OtDnPn1uo;aNk zVdhDJMZ`EJti%AsJ!wAIN%9PRBzqyTGoIvyJWc}*Lb{`-q%Z0&*Nr)2P)_^&&6_q# zMJB@mIF+V1?d!Gd>a!Q@$1pd+w~C^$gHh{nn*&0_(IGp08MvRowL`d{iN87zj$8_q zf>J9sie|w4fh{<1@Er385hAM<&^}||Bx^Q)Z1xU)!;X4cr>J&yAJv}FomYOy7;`5L z-GRDOTBsheAM6lDh12T-H7P%ym#5r4e$^W>c#jgeXsed1C~8UhNwPF~twCv7CupJi zCTqwd7K*=Q;mp$O&QBnf-)cN{YZRxFa^b2Q##}72a^jRgYCVwDATY#Q+W{mjEP|gv z%>2WqT!JLKL-1MG8y?)en`5)+kESLfJ*-9Pqb&7+=f4g3CgK|> z0yVM{=JWyCjVmoNWFL>p5uOeYM*EL@>$r@k$Z+Au4fi9YqJBzE$_3F=cLNSTR)y_{ z1mQV);awD$knQ`F>A2l6MY51W9T#^dj3)huKLpBh zF*HBtTuB;knSX8PlE27haC<5gaPY$ovcDBEr(LBb)Vf1T>2O8GgARb~w4hU+K)LRU zEsweZ3IcX|$S9~J3a4tlS&D(%>vX5X@l6#1Zp%;sXPEinn!!ZC^1AGydjCF^?jIH4 zj7A)gv;vko#|P+_GF(CY@n+P@gl!C8mh&kH+D@m?XeW{Wu!D!`4?|P4>?}r&xoDN( zb$Oe4dH4C8=;xQ$Es9?PLT(a};UnECVxZHOLo4ZK4f!{j7ujFcflO z7Di=k3lG1n4R3rS2`y88T8ux5rg@T9#Oo$WS`n}OqZO~uj&ogtN$>hMs%9GyAJeN7 z%K?8&8D5r1&8dDh2Rv+~==)hvIy|X>QF^VR$RQ%7N|6L>mBp~5y6aI;3n|PT&qmsL zXQ(l$NIN|4yH283AEZ`OPXEB-g?4oN;se7mF0-;DHXf=1s0F|=5bp(MrLo42#)RHt zo*`W|Z;tuOM_#I~s**?%maJn+f{lDvh%_E6;H7TItV-PB$E@ILm zgqUo=1+pBC23bu(47S{wtw*=g-Y2!}8PsM!ESka(b94b!ENjHslla(Tv0+L1NWMPJ z%%E9ivJdIORvMR^o^csrvLa^+(?g+ga46wQ`khyW^t|kyK|~gBy2S{Z3sof@7#Yh$ zvf-AJ7&>+Lg0*}oi4b4SgmGEKGcG#g;`AY|h%Y@2EJY9pTD|hfQ*?%`4g^VD%+#5x z88nAR$l_Jp*f2maV~;r`zSiaNYU^M(?;$%+9`E5Es?ip4s@(-zNxUrc;jIbfYFHN1 z&T@F|UF*)^fEIQDNG2W)L^$2WI-mdqmSnkgusp6?*L#SNoQAm2l~V9BwNEwLs^uy_ zS5D!VAHNkucg%A~gqSe+5uSh3Iq6+Dnt;k)_iv*+-+zW)Hb4VQg&W$hUk(T8nTVdd zc5hetFoDq;BCr5yWF&G%rrXD`L3VSs7ZZyEJGRk$Hgt3Z!c@r*dC}`_F6DZ|btYN3 zgORvsSvF*VKab|YL^GSy1gV#MIhv4g??K>jb4tAzAu(RzdpJlCzWDJu}la+ zu<@7nDLMPAu0WmG%?sFXq>Ke3)H>?-gKcT@26$L^_Kg+%<;phBdIN@z`?DVGz#Ne$ z$#!@fRxqmN#c0C+uH^E6Y3?T7mfmJ4!fu6)}+eq_pG@dMojeqnhA=r*b* zrRN&8_XMP9+qhgf%UT=ZS$uodoi5MUd!NhTs4p8~#{^FtF7QQE%q;ZP6Cyum4J;;0 z9H~~=u2h<&8lq}-VYXs%DzeQvE*YKUjyU5!P~{OXJM9p)P)2q$Na5}Y&__9zuh$d;8&cSVA2%a4J?v*DgZ)Ht!R^?WetoE6l8 zOd|Ji4i}K}&PiX;(jUAA0idxTXHSv1`-)bWR&dFNzZ?FXlInUxPX55Fs=x zj@?;Ov`u5t7E6?43h-Anh1R3+-PsumMI~lgS#uGfNX`9g@j)wmD8(1+Y zQAvZGdO^a-v&E^{BtbKx;<&CQZ(IgP;}MJbGgn##iD-eRp_w}z30IC+jyBGh;p+p|<%nTq?8Mrm*B zYBm$cb|XZON0W^k-R^;f2W-ukQeWR0OihTxn63dey%=J=>40@W6d#ZPP_|D{SYW3d z4G>jwFxn7hu!#3#D@)eOgz|k6rLk5ih~n7X<9<8g<}VSSHm5rY-{ z7n*iMA2&8RRj%SId;};)|LFJuD_NLj!KJdaecp%SmWR&^zicr#A(_YL#UWM+#071AeXsjR14ENTo>6$btempHc{^E*YAzXy#1z>$GH%n%) z(e$bOSYUC5((R%AUFRnlAi9d8nk>ytR_m;t*gl4@g8Z^oB2wf9^TN6>xf)(r!v>F5 zi#1GjfuI#bABhui^PZMnVoCXgVlcw>7A1Y>#8cLR%#{btwKt=yanZh(#+-2hgulxJ zyEjuL9m58*=5A6XeR_F#eJrXp7Gloi-K_=7xpO!jqn-8@fk8Lh4%tZxUQ(c}S7wG2 z+w0BPnZ!p_5djHMAn`nqh)gLinrmEF@?i(v!vG1psot_QCe(g40a7cEEwg2P^RR5Norrs(8Uja3;j&2C8~@8c2J$0a_0<<(~1>T zegJwAxP!5Lk~ls%#*DQQNO$_IY>~YU8o^k?vGlQ*9CT|y&{ZNktmy7a(4fyM)SC5p zGMY<(c{vLbX%P>Sf{j|)8Qziyo+hC4;>5DB3^~?ENQK7!(My9>08qhXZjPs*!Yl0= zSso_m1}>2OejZ}cN3S>VvT?x7yO zU9rqAh}@S7?Lf)_$GlB9ls)nstF%kI^m|K+5s|oYp&ycjr~=^-G<*zj7^eI`VsJJR zmPZJey|!WHt&{<8fhjseJ5xNmw^YqSiMG3hdd}^Z_{F*;I2BLAO}%KD+h(E+MhEN$W$3?esIK#nTLi*Rj3@rb~aS5 zUa-}iWqB5s`18*ctntH(YbKutTt_*~VyB8iI=jDHjE97u+#gupQe#D`H*GI6gBD0` zEesQ>_IubQsaQpmr3DD6Eu#z@J?3!1koOcN#6HYRC?* zO0uLTDF)aal%)5irZKPLuo*DLUeRa{WAYRo8mV*ewKPr7J+HZno_PnZtWIwF)6NNA zr(=1&(4Q!YJ|3;C0y9#q-hZ(F4)|ityYs=->It=sf2Vi4vP$nRI+Kf))zg~+jwi3v zv3!FTrW0Ucf;Vk^H!dzaG{F2cx}2`80uGG-@#E_G5I;~;%9T|H39pWa#2LG?T3ocx z#^@~DzBt7}^c{}g?Y2#EAnpTIIDD{nhmz%T4E>poLubb!`AR$eUKitsQ#vs|;nSeO z(8?<4uKPd(tSsfvuj42`f`311j<#cd(AVFH&O*QI|M_ja`6>L<@z2Z;`g+g*W&Hf( z(fbD8`{So(yuN-d`u%wPBYgkgpMO5o^M7J~(AO`U0Y71m^V8Asp5pz_;Gd5FtDlr# z(AV$%vb?8{>E3nxSLEZB5AphA_^0E){Z;uwU;lm6{Gxe@=kNFN`RCsC|K73uqP~9L z4AAS>^XTg<{QCcTC&3b-dpH zADi(H%mLq>$PfDZZ8Lzz|0@2)#xXL`@ead_WhsWCx86+ z%y@nMXT5MU;>*$NccSs%{X_W$ebwtV!|e6z=YJ86|64O&U&sHWBjr`kub=*9H2!Pf zqPtmH(bq5WJNI9F|9_3IXoNn$cg=Wx{fA$3W9g@R;oFtJ!+U@HXMZl|*VpgpgEr&h z^Z!#c{?GnK#_Q{6MR-D;H~sWqqw(MVCAkxQ{d-*)WCeu+-!iXq zoO}Gv{io;G*Z;&Nl`is%{Pn$CS)20l3VModjdfoc*S1_KAW#?~Q#=o~Nfj|KyM4^WVe^t#!R`-4?Vz_1fh(&Hw)>M}6`K bdM5cie7Cal3nk;9Y{^RhooGPxcIE#7vdv

+#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { + Status SayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + std::string prefix("Hello "); + + // Get the client's initial metadata + std::cout << "Client metadata: " << std::endl; + const std::multimap metadata = context->client_metadata(); + for (auto iter = metadata.begin(); iter != metadata.end(); ++iter) { + std::cout << "Header key: " << iter->first << " , value: " << iter->second << std::endl; + } + + context->AddInitialMetadata("custom-server-metadata", "initial metadata value"); + context->AddTrailingMetadata("custom-trailing-metadata", "trailing metadata value"); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} diff --git a/examples/cpp/metadata/greeter_server.o b/examples/cpp/metadata/greeter_server.o new file mode 100644 index 0000000000000000000000000000000000000000..dc197b2d14cb36605b595aec47dfbde9cb1df81b GIT binary patch literal 112144 zcmdVD3t$z+^*_Gh@`#EO-}sIZEh=CVUcqO0T)lw+k$~d!a!D>El2?-(2r7yKN`zEe zrKQzcY|&CnEwjRbgXsuG~*J2-vt+pswv9&hs7xj0}%sIPfcV}|%4T<0Xf0fMa zXU>^(X6DSy+1a@}H%7}Z?30t@@Rj47?|65NI?kGyhn6b1)OjT5CyH}D++*qn3h$%v zeh9xy@r@LIkHQBi{62-7DEtA04^sSx5N@XULlFK5{{5KlABONJ6n_N5pTfT_bpI%X zKco21A$*MDk3;wb#h-+5E5)CJ@M(%a1K~D`|ANA2DSQsX=PCXIgukTtuONJp;=hLQ zC5pcc;dc1<8@hi5!rxN-RS5rw;;%vYJBq&!;qNK_2MGU2@jpTM2F2fma3{szg7D82 z{|kg~Q~VtW|4Q+{LAZP<$eUlPDgA@Is1T1R)L+@V`?A zeVcPPFA!u#Og{qXO*gl&ZIdlY|w!XH5RApDyZYk%iw5IV6{{otKROqwJ+&xZ~bW1tdC-=qMdsOJ(btK-A&om-ugDcyH+{v(S0hC zw<`K}&eIrehv+_{T(&2V^4Zn?*=L`v*g9zK*5zAMhf}WYuf^J*+w~<#*?p)FS_{w% zN{!0cO?%LaV;#{qkyvTlG3!mZ-yG{0t!`adl0=t!pS3gA(F!>! z5}XnpFU?1{lxSjFX|2bKjhJ!ATAjZtjZV;tb)1KHTIcqsmCEhU#@c`9B2@bV?9f?q zkyho!mOVWa$ls1tpMEwbnvmQD&$fBHMjKto<2Z{k8AlG@ats$L^yQ;FGdD zqA^*Agn4z$fGad6WZbk3Tks0cCfb+mi?z4zRn>s*h@;y&2Ic}u?X8{5mh8)EExu_< z=VvhcwVoc671?nla&X&o4Qk6+qceH}*`7rE-n9WN$u-+flnOSw_bPN?0#_e#Kfk%D zYIsX3k!o!jUY$%OYU^5t&#i56@($5Nkm-#OTM8jw7{^Q9V?@KBeOC0wa0mbO1*|mx zq`Z6xQLV$^-{BOGK#1vxa~z@$>Vx-qnd5m*ELm6AnD0!it4%hf^6Np<>O?AWc0ME| zs*}z63zCcBCVyD|!bDwb5~8&YwW-=folB|{oT}EARAc?{mSpq7Wb<&&$4NCq$!iSC`+=m_p5Jt2Md%mj@1Z?DLUt#aegS%LSt(tM;@1BT}6Otu$; zKCQCH0IabhSKn6ThN#=u2~BIXrML+mjEa zfDBr9LcWl}7 z#Iwh;JuxWq7AP_d^3e}iXJ8OR)ieIvXJZ|+J^<>ivG(7@+JEozbj;ccgpijv(5rzJ z=y+lh654m{K2r~`ZaR;Wo*H75T(&I+L*!?l*0MbhpQvG~l&Rpcx2U|r&YBcYhn z`pt40g2h!G#U0!IRgqyDXwV7D=X(}W17%zX@VY^dILo&VTCoi*6>pz)a$?U#xmJJz zyG3-@pk*6~Al5NE9|>ctVuPW;yJGFzV>w%)f5o2K*+&PFSkCjYj*5J3KAxduzy)p6 z5#25-5X^9EtYhkSfY*!urfc0g`m8BMH}9A ztQY_-#!AFG)~ef%6+2a8z^@I^8l6jaggpOp)e0?_#wIi`a)jN+a1o{`jU~W_ovI04LSwc|xy+rgPgwnUj88u{zA}mMTqG zT;Q)e_vT&cQ7;i!nSt>CVn|E{a1nbkjB*P4pC5 zeo4Qb{hhY+f0*lhxzGH&a-APX`aL|rc{9@Q%LAOxBK9;c{=XG?MKFB%n zKRM2=eISa(RTt$3^e5yTc_ySR_-f7%`{ewh&w(%ZasK3yesJJ_4;RqYt_T(%8e&u~8g ze*@g=K~OKs_wWj=T9^DO|Kp{;3rI$<2OMHC5DJ$AMCf&}@&5XU<^UemB<|Q4Ymao* zQdoL(Nl0~VJy0z$lae>+PeIi6w$L-$tDLT z_{0TSoDRLvd-5)H%~CttUY~@1KfXfx_t5ca(7-lxR|U9iH~=hLveQXT0Wn}>vOQ$Q z`BSkH!q%l)FuHU1gKkOLO5mZ=(Ejio#RAE)h+fnIU@fna%X(PI`oMBxzWC9T58aW3j}Kmk-x5gk*ZBBRfjwL?DtVFF&Ukya0j8Bc&i zUus>T8fKyMQQwYc%S&$cUg+17z(uA@D!!II0ZN0#mOE#DJ^<_<%+ zV3Q&$&{kLn?ig7vv<$zCUgEdU)2+bvhOz+PBd|7^QkZ(T_#bZaZi z-l!X{bgF|nC9Ef|k}H*1B^w1h6dFAS7%gM4@`u!*8H|fuhnTdgbSSJy zsL(+$4e6ziSal4)qP=E=!ep-p&T)k%1ekoWn z+rhJ-GMR>NJ+>VOtRUYmk1vuo6^srm1oKd##Xey0#GyKU59q>A=xQ{|gQ@@-I4n?^ zSHUYWYfZUT1Lkrlux*c>6Mf!qIFK^X_ts3;AaHt(sH+c(+&O6Bc`%Wx%2Y3bWyfhp zlk*!3PQ3w0wgNnZsOAD;;8VR!>!~58-NU@ndhEQmNFfNO8qpost&_n}Wzf{%0r-5N zz!S|I%x?CR*}7RqJE$Jrt6z+Jy0ZgA3n8Wb9+NG+aX#FyxM|fASqR^>_(^?q4p}34cQ-;1}zk- z16&ss;*bYfxLgolwq(0AX!$Bw2e2!FmIRzIII0(VYQD%+A>@TJNrf;Qs`ao!?_PtR zC}_KTq|2o|TFk|*@=W@ITldShvQJ_kX?T!^JC&EB9~!_erjp&d=H>NXTM7KK{de5w`HiXD#Lx|WJqm1aDnej~u4uTW z)f<=>3f%!qd7QF0hDKO=h1VOIS-eyFi(gN=C~MDFa`RJe^fDerbtKSAZ~k0 z*;BBd#EcFlw2oWQ1mTqy(%=bPTJzLVbjG(+SYgjTSqjv;Tddd$RRO(4_c`TU$vX8- z1j@;B=K^1!!=4LmmPwxzZ>grmkdj0n`d`|DD+Z`YJp4!=;%i_&= zLtQm>2Xk#h`;*Fi@`d@N4vMwAHi7o%%Akq??xQ1iTH=pZ}8F|LmaNt z@eik0d+C2f94=e>KAr5GiXrpQ@%WFYmp13f^o3sfxs*O!rq_7sS5msIeAiR@p_0Gc zS(SC8kr$Op^2D@}SXyraeI0{p`=z|LDi z0_wr--Ue}>9@rNebiJXR3d+Y+o_t7eqk10~%qOMuK$<%#k4qsgb?GC<-YrBkGC)%c z*`OXfDBU*pbW*z7j?CpP^U5)}KW6MWrgW^2QmW5o5D(SIVlSULl#gu=Sehn%J*Aua zG?sHKrJo6Lx31=S@^@1D2{L`QPRDX^yU&Gqs2oIxa)u7T3}6=l{^9!SGec#B=`l*T zm9vJ@50v~-PtTQl$nc@I$X9f zXDFqc#vE0CN;laHrq`rNUrFg|BfML`*Sht)kQ+k;%eUi(+i_&f7 z%RK-YyC^@UpNm8+f00+eF-kvOrVC%BCQbTEO1IVTMoPEY*Yj!8cTswg)UVFdKUW#1 z-B%k*={Ea|QM#>uYtp2zq;wn?-TI|55!-iT8vf@geVF8*@0D*CrB9dXeI~p1k*hjR z7v=9FJs} zX)>MWedNy@hzam3F8srGuB*w(2dI$JH^_7>=Qq4^&LkR}t)|kX-e>J6>^dAE0 ztEs*4x1Yg!j>J75Z&Mffpqv*e-Byo#((n&d1+b3+!zf*4!|f=1rt&oWb!pO9r%B&L z>85&A<)?I;etRh0*7pah^S6>j>Aly0k^J!#Shst2|%+CNQtd7AV(N>|Om_CsSUmTxtspCZe5wO9X} zDE$jEeXdT&e)KA}@4XQB^&>q;tVK$c^AY7^>+eUX3N-uv$UlnGZFVp-O?ryb&w#vK zI}__ZcT&2|7kHS`ZFcr5rQ7W2qcr?S;14U|vgJRD(kCDhx1)Ochv#O1W>Wf8nT~U$ zHf6Q0vXt5&U0bcEywo}!%bKp+9A#~#bl-Cc$`a3tZxfBJKKs%l;CQL;^`49&lx`~z z+C+?KY;!~nrQ61ym6Tp4b?7rmDUlD@MoL#d0N{G4&^jWE?aG0KzRriAnbIT9-6j}* zGkcE(|CR+`Z^5y3{TDVxj^p8|A72sY+Z=U69E)=VPLDB89PmCu|C5LV*C!C?d(}q) zTTi&M0f?)<2jNSES3!u^L>)MvLYU)t$Gr}@ywG;~s-bov z7uUu0w=nK?$R%@e{mqJd9hyR&!9q;Lc~sna(TMYN??%KT&g0_Fi$N_q~Z zd$upUjW|yc>IH8SeIY??pYTHvWw)aO_(^>A<#hw4(-3c}U8 z5g?5JnDBW-$M_!!pC7;v0zo)#)C6$6jW{n5>JK8$ulxYql~6u)l*0Nq6W$cSHxZr+ z;Cl$i@e(i2XJ|jI=k*$P@oK`C2Jrg{Umn2!M)=AAKD58ie{}$FBz#Q({|@1I2Jqhz zzAk_t3hR7W&pfknxh^7neSm%m;Tr<@ql9k^;C*v-{yZXb{?iHH9H3uMIFDpZk7N<& z*F^0PBF@WxfbJsd3t!=+i1SJq1SI0TYQbN#;5#h%>lXYE7W_{Z{7nn~mIeQd1%Jna z|ILEGYr)^M;JYpO`xg8I3;v-6|Az(t$bx@t!85gT3YO zFz8E-I1vlp*Mj%A-~%jpt_45Pf)BLdhgk4I7Cg^_A7;Uiu;52o@WB@RSPOo<1wX-p zpJc&Lw%`R8{1gj*ss%sIf)BOeXIOCja$Wd}IKwUYSr)v|f)`ovkrsTk1;?-Ag|CQH zV!_Y0;OAKI^DOuU7JR$~pJ>6O7W^U$j!!+|E8^f6`odSlnQFnOS@7u={9+4UX~Ab% zaC~YAUl9kt2pGO1&Se(-atnT?1;5II$1V6A3qIF^S6lFT7JR-1$ET<86>+Yy;P?f@ z@D*_yEO?^@Z?fR{<-_n5aZ(n%)q*dy;B6NCS_^)?1z%#pZ?xbyS@2~Re1!$S#e%Q2 z;I~fia1}g;I~_F{K{kaia7Yy$M6+_PY8rj^l#xSPlhYv;MXC;SH!_DMTW14 z^9>7rw*|*9N`|k9v)+Q^mnOp(tp8Z>`z`oJ3;sX|e+iyDa2@O`@SKfTnGT#!3I7A( zYCVzCVEreQ4<^Anj|Jas!5<3Y#~pw<$)_K@hj(rYhljbqRjF`z2n$?|3Rf%BzLZ-P zPA>pN$|nlX6Nrw+)PfMN4tmL7Q~2>7K(QYyT)k2CrS(+{NNU%D4TbhQ$l#P!iR+LZz}w>5dNCNPY>ZG2P0G%!dn%tKHlR?`<24a^I>=s zRZTKIgnvWfl_5M=HPs~{e2T)=YQ8V6L*bYCFuZwJ;mHs_Q#E-_2!BxFcZBfW3SS$- zk5=y~c$LAQ4C|aBJ4Xt54)PPyT?Bfh>4N7Y6AWm$zaU}6fyEWW6>-A-2+1N&xF2a8 z1_Q$taa5-Xr9|9SRDV*$QO4^B;V$B?qWY5}jxr)YsOZD}8i^u$H->>;HJSmZmrH?^ zh~C{5Krw%MK@>=dxVyvs2@yw*nqFGOIm){cv50fDxbvbB-zu`ikMV9qETVUk3q(gF zj@oT$z{BGh5=ETwIHvLNIHvLNIHvJ@3_@4L36F0`6mi1io5sWAo5sWAo5oMYAaq5X z@VJLW5$6jbT8$62;Nfvn)1P6XKhuH_v*5!m_y`MrmIW`g;6)a^*n*F=;G-;fcwRul zh~7aH;)yt8Lzt#7vEbt@_}Lcx91DJ~1rN_(NEm@LDNI*H?}`p3MV!(QhCsv_Z^0*6 z@QD_Dk_C@i@Cz;YMHW0}!OJZ8WD7pUf|pzHsTO>i1)pxgD=hfM7JP;U5Bn!b7;$D= z=x15*us@^o3Hvh|pKZw}?B{6u%PsU*Snw+?_*EACY6~8>;Bzc^!h+AW;8hm9+JcAu zJtT}c^DOl9EqK^J)cMp}=&!Nh3oLk@1+TZ@4Hmr7f;U<4FIw=eziy%bh6TSX zgpWMb0dIS~iyua@a{$kCQ7>|_qTk>G>;Ye=@cTmeeG0$d#ZRT!R)ueLarVsqY@z=| z;oo!V*)u*C6fO|^mlz+b@CRJ_GbmPR!5bC+eU~1@sjEZbn_Qfql)k6%AGr8WDfTPC zP4)JQqW_^w&*lA4;Sag^BNRLAaK|~hkGGzdOZW)DP5GY#c!BdLHy<7`ms{v}S@41* z%=w>X!H==zb3V`)h<#Z+LtmqCE~Vq}NPV*<|E(7K9SVQcE$?v@n|371eKUmPPs|I% z{wt=B9EJGLL-f-W{+5f6qu3@3{l69dxJzF^vEz@%{GW93T@;Hd{4XwkDaCG3_&Y8> zl46|-f6B%A34F+4%>Nk|=Mj0G!k=|d9c|Am`B z_oK6pMY+$pIGDYh<#984;L%^S1vt2$!u2muU-5!ihZW= z-7d~EYXT~&K$d`{H%X31QYw; zR7ipI0o{4{Eeik8#o0c$EBqrDhiuh#)Jd4nKV1Awid_M?slA@E;6w8}qdqJPDuKb>OtS?FH?{A9;_Z!(nV{|tD6*zd&oe5&wQiHg3-0C&?*M*6?GIL{X= z6&|L4UE!~}^k7cvItVJZzzO3AAArA^yxZNG`ftgAexn6H;1qK{r53yv z@B-(*q_t-!-&J_0i}Sejwk03jq+cN3PjNjT4>*>0Q6HTZ*U!m{{&hEh#%lpL)x$yy z{SylRgPYF<6w3hzqrlnc;s;XfVugR=;yfPyMB#sOah^9n1>B@h6b1wneh1(MYB#vf zs)Ta{$zdh+YO)^4GmY|c>AV!yuDT7xi0;Ul;a7|K}`MS5``b=(qBjPcPTtP-hQHR zZ=Y2e(Jz7lr@%SH&4rtXnR|_bS}muT@0lI`J&b-`lUn^j9m~ z+pooT__V^qb~v~Y^Eug-%k_MR!V5z9!Jt5aO`|MD-w@;7jXS>3^{a38#amAR= zS)u$}74GfJdXUQdzQVozSDeok;2;$^MQ%QOiT?Oeh==X!s|xq_WpTUrAC2_h{;NTh zPfX$7{;LgyzoGE6UAe5!*<&ytZ~qnJw};g> z_GNKCD-=G|&1X90^N_;NaBjO+PTg?szWYN;eQm0~{LelwmUX8ISbdelw5N@TV+zpQt&X zi!As`3;vn~KjA`i{%2Y677Kop1^+VO1&+5LkL$nhMTpn9^>!NdivGbv{))oA z{dipe(_)xUxPLvW@CG*@mV0s;(l>_iI)yj6IIyd$&t#+z_m?Xb?(N^3L-hYqxVL|g z?V)uF=F{rt&-h-2d;9meT<4b~y|;gl@oy>oS~nlY`%guBZ~q?m>uVJ5?cY0v^n6L- z-u^vs=hQWJ8s>A8oBzFp|3=~7{yiR-u7ZKI!14C)aXqh9_$_Wetmm5wUm3zjRG95> zG~fl!Z7w~yXX;w3aBp89&-;g7jPze}=~BrB&e7t>qjKk;l z0QdIw!7!q(-z$8rn-5g4x+*J?-rLuAFX4YvxVNwG2*RT?&Gm3K;00p8AN$XDDcsxd z=hnk4GyOD$uMg?@l)}CJf#XS^_bvD_m*8{mMmL|qL|+VefjW&^1Kh8tDcsvP$n(@S zfSbn2FIn)P0)8@_j!EL&9WC1}^#8Qr2SEkq_2FE+a4_QDts5(};O7CJ?^21#eEpfn zxIS5TL{*g&zq~S4UNo+$Hd&QiRNIpDj=qJY%gc*O;_>;Znr1k^H=d|U)hNWO|q@3CebiI8Ba7o#?{r)ic4y119Zisn;PqCs}@Ir z3@d140!}urN~9W_^oorUTgcPNk7speL5-LnoH#TVjKs0R> z9_(CF+W=qQY)I6V7Z)#>P}`7bUL0+1Zfu^U4|<-GR7z;t^5W48rY73Px29@lHZDju zl-JHnrfTbxmC33WRCU^z`HhWGKP64gjj6`Dt@FyqEr9Gt7S|`*x=ycc=pud0sIK`T z-Ns*3xS+Lb4T!=nLsZb%1ygGq^kLGMB%51m8yhZcY%Z^z+l-ZFD!}R#pg?8qwaGO6P{QdA$;Nq86DYfM!nsum=xGa)ZtP}ZOhytWdTj~t~cVp6iDs=2laI)_j~rvseiqlzx9 ztxHaCN`b|-#4)S~yPMiro%G*W)z3HsYZ=C7ra_v56ql%~;F3&K_M-nyOEWxM5D)MtChc)YDz30IdXv-PA0U@gGu$$=31B`VcyfX<;ezcNw9~Hf=Rn2 zl}OcA#c@inP1Mz13wMnT%B`qQwxpU{!D)f}Li86dDxW@Kd^xbR&W)GFfN+4m7rs5i{z@5BEid@ycXfvMN>7k}9hlh0v(F zWJ^n#N=_&!S~QX~jn~2_yvr&};^lLTqR~lI43Jt64o+=-qRA)~gavX9=+UED>G~*9 zb!hqmIafXuz8D&?8l4%3)&!dysp<=afMl<^8(<~?gsjG7QN{77tbyJzKd+Qp50e^T%upn4*2*@c z(`Uw~&(u8$iZse?>8i%ohE!RmE!rF9(FQtRS2*;*)`r?Iw!#CDYl3661!DIc#SahF z&`VR$7En;ve7uLBqLB^BMRE6GBHKoUe(&Y_`HmsFGA43mjP*tu7@P6ID82bX78Ouc zZd1k4YU9wKl6v@c6S#+q0k_*jViEO2l!axer1tDy2hz1LhH3$xgL%GKkX#Ip&hioGse1)g0hjx$~6wK=7$>eQXkQsZc!&=F@~vZsR{M&e~t z460X-0pptie4%dJv*xWUNKXr0j%bFVq%vMMGY*4^a{tpado5v_e`q*sSX5sDP5?O% z(=WWR62{`0<0q6yxi7eO>lrjo*Kv3#uB~sa2cu6*nP>}8hCGpC?TJ8h1(QnRQ^6%^ zNv5n66N_waOmSCkOi@>f#ZjM+<8zLR+_Whn=VBDjR1^3DP)|E*$~h+z42lYHN!(!IDBFEX35N z7RMJBsxb-Ya<09~RMwMsk!kX-Ox1y(01at$9A;pL)ILTdI2p-AJ(+YR47pGMn-bs? zR*sI(#A!#5rr9bxiHt<~FZyOy!=hSPpPP|vX{}ddv~JCkO63R7NY1;kxv{=$xodq!LpTO(WrHNDPl=B3%5a17c0cGmB}K#967x z?%?kC1K60_23WmU&wwN)3Qq?xXqY@Qn6kmW#@T2QHDPB+2 zp^Fz>ME0s=)cEFPLqd1|id1t^VP!Hktx5)U&cbmm9l+s)%Vu;(<>++aDjL(A#4K+?JyuT1xK4`-FLE1l!f5rNo5mE1#{x&RzA3d>Tf_J|d`Gmn43=S%)fr|nW?pR@ zJkrDKA8=n<;;?)L6EDnpu*SkUbZr{NMbWkIaz1-d zFqPFLVS#^9V{=_~QE?38Gm`M=*OD65kf=|xa>|GC(H0VIQ{CdCBJjwdW3{v-=7ULe zM-L4AlFGzlRngH38iD=88jcITX7M#4 zFu~(jk!Y%JI!sV%aDn+@4u%w1vB1}g%D)S{ci@4BJi96wGr((uY!u%p@P6w|uAzxn zKj^?ynKF|`aB(Xx1ShvrKm5Rx;eNM+&sFb%{DgB~xj#?74N3F|N9%cGzjA7FpPBaK zLA*)24@G`cEGijaU5$exEKjn}0m^r0G@yx6yWjyS<3P$xSb(g9p|eNCRHk70*g9+5 z)mKKT9zvjnO5(KGBAxc)=~GmHGd*#`NEI4W$I{W1YPA<0Er@33C8i9pE0}Qa5w53} zl3fQl+Z9XK3GXRQybLp4)b@1GltX&aY~d4HYwPe8iA*aVT?XE1RckZsNWk|ha&2C< ztj~HWhoUiHz2&tn@ahW8x1zB*)!iNfYqWA*9~J}*?+9Qo2%3pelhHF^aRLvo*4fR3#bTPz^77KzqHm0i%8PE5_b{)D32SZZhe}X{O$x(&`hn4QeK_EihO| zgTSi}wk}*c@g8)uU5yB2s*MchAlT89N}#t5b0#eLz#|N=nDQGKm{N;ISJ&c;Lv+jI z$|Z*xU$40W2P{{*Jg}uFIlr-aao5?64bkHSq}Fh;m0{=5{%8d=*qCP62h~^)Tdb?Aj8_~+2v^0guA)a;||Zg;dr~s^~yR7E-Z`H+TK}WLm}|WqXm`_p)Unr zMZgO$-2u9OqgZTNZ~;S|*Vw!$(G1UodQ_CJlyGeXR{#vp@|EzqR6opvc#%t2D?j*# zwTm2~C~l4*v^UHFUJXozoe;P_6o=>41ndAPj`J#!b&&`ZqeUX9iY(v1@?Z~j7_V%C zJ_+w^;gKHS>7{vf3&SS9wx~;D)2kV?cj^TEMHs8yXH$M*XR-%w+#cF>0izs9)^AMl zajX|akHtD{Y;>Pu{{Jkast6;$p)>uF!dDiYC<=}dMk(BaE!3jt}7Ey zw6;li29$@bPxD}FllEhK!M*8K{{&V5;?1@5Yf_*8#*eWex-L2I|3ES{+0=M-b7Pa* z4$!q*v)|oaIJ;xwu(1e!lK}HCyd8(l|6T9M842!+ughUq@$E89H}q72e^ChjMR6S6 zCDU%&Z}*PeJtv!YX+@Z_0Hr6OLkM^*x{we1HaqAcm2G-#vOora=!O%DS}D9 zcfAYrlc(ZNVDDXghP(Z)SE|dK(R`aywPU8;BVonh zfU50r{5YTePDdy%Tu>90@H;2mG8=~t!0cV{Ymjbj-BPY(Z<-eRbEql2!3wvo<@rc? zw=?ux-u+q($EWhHoD6`-?T)?_Vrdpfol5uENbfwB> z&%}MuqZL>-c~TSZ{EE_3){M$=`ppP#nCg~4qMlGf&O|pe^NqCKa1*R69?;~4^o(m* zH|muRjZc|sbA99D45qkVQK1M_XlhOUABo4tbT_K?&g2G<({b2S+GUUI9m(jk!2?Ar z?&*Rq=Qf|Wxe>k4Za53x0|qeLcgTV}4nrFJ6v2HMG0kb|d=r>mEOVY-PclxFX)}cp z(q1L|H$LLfk2@jwDbB6;9`sy%M&(V*de<*Zo4RV!?;9@anSH~(W4}J92%QXa&%o$< zqfUL|&?A;BZk8!qFSo(SJ&xBO*u%r0LpLYqChG7V$6SlCfzv(1-BLWp{V_rJJtlk< zfDJHXrMuLSf)_&YgJyI`ya!bHEfx08v3hFl-jcX>{PeyB(Pw(#mk~N=a`C#UoLaQo zuMPex2kj;HlFfZC3-jIaMPbH>#w}Lsx~RR>3*j{tJnq*ww)E<1C_W*Jjs4d7v6luL zbOY6b%I8x~_h$)Rlyg6J&fp}Cj)ZFw0Utw*4&8X-@Xe?o1y<5msppUDR`4(^z^EE`yOE z8eKR8T10mR>}x$IrUgpvwi0bv1{G)I*Qe&dhscf?Ek;C@BVNw&ln!LkmR6~0%pXhTCQSYBZqKTk#*py2&R;1Q#IZecVkx)r}n@>^_qJv>09?^nK@ z+|^Q_?RT@g)2}P4>+qNF>dQDi=gE}#+!!+B9`uyPxdw$U*<^TtE7QAwagB@pGc+Id z%@H}@gDL5?Pvhqg(roV=`+qU>lU3Tx((NQ6!^~vZR^NFLw(43~b~er*yXe{R(6gfY ziYdxSdp3V*MPtBD1q-k!lyUkONUt1 zU`_Dwsvq*_;)g-;V~8|RbkTtfzl;uiucP-y0jM~9JPY@KXuUKl2lf{GRPNbY4%i&% zjQ)gjD5SNe(-#-$d0t6F>n&B!EHnKw1P6Z;KB-W<1;#Ym6D)s$8T=6!Z5Et)3H(k| zeON0ow{~F>epa@nHeOYiXlYR!h~TZryheO0HM7zr2@}eEzw`{sp*LD3wT&%mN*;wj z#nZo7idVNZ#^D>Z)pbcMC3IpRk^a4mTD*Y8r#AdvENo8HAHr4N`cV&H^l9CJ6ykTF zSHkyu_kE_XpAp^{Li{Q*<1Y}7pZe_&|0dCwgMULf(!V6=`Q#PEHwpY*qQ`vR6nH1$ zNdH%X^T`v4|4rce5XTGgT>>9QIOhMhz$Xa$cLjchz~2)%f4QE^JA>%>JN$^hEa>?Q z>8Q_kfiERK#PMs(T%Y_UZmfSiGl+5i@-@=GB5?lVGs@j9@TVb;7vg&aj(OsR`MfXi zKMDH33moeNFQosz!2c_7*^d2CAY4d~r`fUoM-YyItpA|`mwKKn@{xK@74%Zis|CH( zvsU0zpIb#f?+87ABycPP>;F@c&vJ+}{)C`kA@E-aT;}s4;n=>n2>MqEM_Sa4^M_k? zVRd7FEr2Iq4U;Yg2PA!oc;;NKDWF@$42vcI1y=)W!KM+y91 zf%A9TQSSEyK8NTre`)`X0+;Q`=L#Xcw71(W^y>vK>Ax>IeS%LGs zhWR`va9OTx0_Sraf^y+FDs>_L3qjB40wDf`z-7PtmB7!|*{E?+_Aj<8%m?Swhlx)1 zYdN2C{a}4cJFh1`&gbWJpAxv7rxp{A`N(-{8R5bC=u3iL&PU%Q9OXVP%KIaMzbNph z1pZrr|4!hq3jE&!{~v+(hd5qb-e2om=U{=$@*YNbu)ISA{c8|sJ3LF^_X~WCz_Go4 zPjb&EJeYrlpqKgc2|B31%%A;=VEyw6D44&je?CD3^ZA|7lTXM%dTDQHGk9^my`yi{ zScFlem-dEz4XbvCB5_?Bz;WK z%X+w+a15{=`JAn}f?n$1AaI$_l0ZIZQu)z0z$;jv-xm1mq8=U;xGdMt1TM?tzfCv>&kMPq2>kZ~KRlw;SIzcRzD3}dTJmoY zxGdLVfy;SzmB6K*-x9dY=Rtu>`lkgh>3=J5N&mLMCH+4IF6sMXMZ$%Fq(4&NlKynU zvDsw3ooAts30&3>`x}^y&jQ>ZkAr)>F#k6I=Xq4ln{Nqv&IjqS?{hwkWBwlsoc&Cs z|486PaE}+_{}MR+pP0|T1uo~)PJy#uf%*JL;B(;~FU0>LaGp0Ye^dP+JwE#c%Z2zS z0zVDz@k0DlflGh;CjviNQEPf+;{1mR{2oDHDsV{;$6culje^byG30&Gqi3LAf;If~} z^2+(;JV7tV!}A3W$LgsIAm;*sR|~vU;4K0lFYucMK0)Bpt|nRVs0F{!f?p(XSr7Qk z!u@4}&cH0Vg5x{Yh3!%%=%qdUQ}m0anq2vrlLh@(1U^OJ_X)gQ;13BL*JfGI z=L9}Y;QV}ydQKPk+k(DA;ClsrvB3W&@EHRCMBtSI&!u`oxzewbPRSI0%+tmV>_9okL9nf&QNE}ZsHQ{qa{Yd(R1)nQ$*^X5L|AMH`YJtoA zrM*czPYQb3U!+~ZvDfMXQfHo^mv$@jm-F3xK`-^GvEa29{2GC?TpR}$2wdhb`|rtG zeKqgb3Hl)d|Eg#&IX=jGm>}roICHVUrQEo{>xJA}!cl)|x7Q1L>37{E=%wAZ3tZam zodTD3n@>2X;xq_-m-X2!aBeSv99f@od}|T(nb@b)U)pC%v zH(77k`FK2(n z0%zMme7(Tg2S$9Wz>h_MuAKtsHDOFTh$<0-?-C8-`2y#@hB&Sj;DrJAalFT89K0~# zy$yJeb3I-daGT&g&K-DRkdG0%)(HGm1|i%maQ3k=dAq>b7eaimzRs$zf|BG1dg)rr?ejke72x}QQ%0Ab0J=P1b&%@)Zc;B z$&rkoc`;#_z^_o0`p;;Aqg?hoXA1mEL7x)%RRUikaLk9>V4c9P7W9t^oP9h@{-eO> z2>N{jPYC?@{`v;XJ6GW63cO0-QGuhL6DX}(;MIbDxxkYG-yraL0^cU^`2v4i;57p8 zJ3!x{{_JBQa1_c=_(ia0tO+h6F5J6V)AN%^Sd6zHwnA}0lHokIPc-X zq&)&}Vqypf(!_@4`l7&x3A|b04qm$j0v{&u zn+0Aj@MQw86Zmq0uNL?Ufo~G{Edqa0;I|5VkHA+7eBeR)2K8?j_%MOrCh&5BuM&8Z zz*h@=jlequzFFX368NhEzg^%T34D#fk01vU_5ZTKM+y8Z0-r7LI|SY)@H+**PT*?= zzD3|)75EN;e@)<>0$(TaoP+fZ>W||OkBRvL|GJ<*UEoN+n$ji-{2PLPs=$$+>#j!N z{4N05Rto%XkU=h1@@>c3gwg#v#_;1vS@k-(b-{$qi!5%|Lb-z@N-2z3kCkDz$*m)Gl4e={O1B+Bk;!rzFFXp3w*o4pAh)#0!KUK zy66=6lY)NmVfqHkwN>CH0)I;2vjzUNz}p1=jKJ3ke4D_x2>cfU-y!g41>Py}=LA0Z zaD9XNKQHhSfxjT|*#iHiz^@nhuLQnA;8>sADQ$zmUljD)1paG*?-KY+0?$1{-=O|4 z3w)@+Stcfz3;Y#9UnlV23VgM|QN~yB4_uo9xV!!^qGfS?Dlyj?0Y~=fu!duBBtT*W z9!}|uz>l^#Bj&cWI0_gMzg(ZiJfgW#Cn;Kt!XdtOfVy<}?G5)wdES>B0v~URXGZUS z1PSO}?LZk65=GG;#igo5z7GHDd13of1 zoY(`=@U;l7Kb#Zi5boWI5) zZ{KNu)|`nsIHHFp^Q=F}RvaIXzkH9^)WSK4;ZYNeZNJWi+iwL;hrk8uuzMd#4VM*v zKh58=HO@QyD|?z{u<_!R>g)VPE$T3H_>PeNCN$4W_^Ab>AU$7&ou(*qLYcJ)_4Nw; zRG0eDN1)jIKS_4y81|qNMcp`Tizf}Jt=>MtoJCEupCjHI2XF^#sWaU3GKamQ~g7_YoJP6Bs z%nQ#V)^zgWtjO9XiK~i%)48 zCg-lcnh9CbS2GQHu`-4{)v;4ueAp9Q2+r3x8265|vR|ifhMHtQ&(jR%*Bdr1%*MAY zp=Vb(*@;^dXR6*%06&pM$6valdSBA#U`qPiU+#IB{>JR3%Iv~%;nAT7J$v?Le3gk) z=l%^vzU&~k{XVV9U-dYJ;?b6^Nj#~Ns)IjF3W>oFq2d!sGAcr31I7|0z zO1~P&n7tl!Or<}oZcNhIomlCXws$(F_y8|diaW@7YyRFK)H@1zU*WaM57?xuV-NNw z~lHX z(_a>0c)fqxreAdSr+KQAWwl2Mr!omc*sl{j16uW(ciQd4JY_*Wmq>lu*j*Ut`g~uk zIH))40XzOGm?Dg#=SHJ$ol=7>8?@pPDYnemhE_<7|Sz}MBgBIxvPef6ZrE?tf+ zj*SdfNe_N9JG=8AO|9J%=gFuYIB=efn}07gKv(Obz0u&jq?66j-sz50bnB?sY}9wC zV$k+_qndE+NqfFxZZ_?E@3dQhWdGMAuTqoCqGD^#nzizIS@G{a8F-1)&Gta|gb7$0PYp$m>OkzQdBd z!}5X>dt>|xxLQV!&wb1Lc^qlS7A4-!DHq8tytiW3)hjyhV7t$w7GY;h_s_WdTolCP zGxzgQI&PU>d*NHDj|%Q$34opc-WhGYrEz?6HW*y!;U{5<5{44%=Mcdj8q7t8KcFg&5iUns~TaCBX_4#7*8 zX}5+Hbsk&GeiodB{|{JM^XwUhriQ@zkm?{We^vGDknb6u zI!3QIMM=Z!>O?)i4!tx7n8sr^jx-}N`%Ll?ya#4OdBk3@3cBcUhAr>j33b7IdT$tk zx-*@x7gQi!LFni@KU>dQe83Dr@!%nQTDtgI=?M6dN1_gPT+h73^t+e9Xl)`fY%?{I z;jwyQ@p#Ogi5y7P4`ER=^8tA}uUa_tE}m#^PArz0Pr4LR=Z%QR=eM=Ro082fjSY#q z+SKCs!a`?6Rbzd9vH^aB+t8Rwj<{&rtl=%GMAZV~Pu9feH7Dwm@H5Hg#?~hNW8eMw z`@%W!y>473aq}j)ULv>q|I?HvX7_AHN^Ud>q>ND-8Vjol)lF(8iCy<;IIX zo1ygoBiu6|hc^Cd#qBt<{CI8|^Koe7uQTxfDGT{21OFRY@bfopr2cr$8SBlVP5*qC+W7gK0J8peX2FlPj+f+r3+`Dihc@}U6t|!M(JadUk%1r2e`C2E z+T=SxitlwHu?DmemrlE`8c%k4<&wCemuX8 z`8c%kk23J%xk=2&p^d-Pz>nuBF&~FE{&EBVpP@aOk3$>(Y~q*w7rz6_d>q>NYYg)L zl7)OeuT0ke+gb20HOPM_3;xvx{=a6yk8>?vQvZJf#`VUbt^PI``2Pm^F&~FE{>=t{ z98;K&LmNMy<%pNm|6RCeJ`QdCXzO@M{`cUX`8c%kziQw|otTe98~;uN|L!d0?;(CU z{%p-cKAug5m*mHDBw23`ZTjycep!EeAV22g(8ixj-=UHGzs*Aa5e9y26PC-NO@2P{ z%kty-i_FKNjen>?KAum=d>q>NM;Z8E%Ywhuz>nwKv0M&q^6|_Iykz~q5BJQ+p^bmG zfq!=v^6}gJc**)ln`F5h+T`Q6>x2Awt{U@kXyeCkqvIvZkLRf|ABQ&nr3U$bhy0k2 zLmU4}gZxjkkbkE^KA!u-ayhigzuO=mzpKuC9NPFd8sy_gc$tqw8$W-)ShhcYPoDWW zwDE5t`Lg}`WWm49z~46ue*Vs~l>b2%?f*xTFUybT%yGFnw3YvD13!+b%*UaPe-H6X z{SU~3ztg~fU>5v+BiQ@={SUvr&3bca(?8F^kLPYMABQ&n;|=_IS?~`v@E@85KYw3a zw*O&S@Skgte|Q%Bd_Jjcf1Fdf-Z-??-%OG(^~dwSn2$pn|CI**qqE?zHk5yG7W_>H z`DbRq&)++j^*1aF{^bV!@f(27~^1 z&LQ)0Xye~((EqqB`1$+s(*8coqWoJ8`k$DE{1*-U=u>jJIkc6ZzjH6^{~uZC|F)t2 z{+R{;9)tb`S?J$skdJFRTy73+q^COv$LmU4P z13#WK$$T8z_zMmE_)Nik9NPHLHSptE6wJq=ji1j=mi33{EHNL4HvXAJAo)jT!9T~q zKRgTmI^vi8e?%7iDFc6T7W~&6^#4~D_P^4=kLOYn?1r}bztg~9k_G>I;+OUJaTfY- zH1Oj&mYM3m*`Pn3bC)UqV+Q$nE@r0u+YIvYnL1Pc?FRYdv*6!hkUt>{{Tfw93Q<>PswneyimzqH?27W{(^{4=xQ&o}6g=VxZB zKcC|w%a7-2X3Ae;kdNnXX39UwP<}jbGgJO@13#Y2nJGV?OC!sFMHc*X4CTjjH8Yi8 zXVCxZEcp5S9BF@e9%rWVuQ%vFCky_S2L41A{C67o=Vrmb-cWyd4riw2-)N9uody5H z27WxhGgJ9n4g7eXXQuow8u;;i&rJDu5Wlpank@Kt8sy`7p_$6xW8lYgMKk5^H1Ok^ zY^MBu`-jJWJQp-m{ygHB^@ryYX39Unv1 zW~%=h13#X3nJNF>#D9eDhHC%Qf3nbjvq3(d=b5Se$B19{-Wc*B4}(<9)5ag958f96FJk=zorHv$a2AA_=U%85Uy z|57?{i|dQ&gZCFff~o%VakCs;T+dkl--dhUXZ$k2P{m;RSCahGAx&O^;;1vrO#BaJ z$d709nD~EB{HIFc5D(Tfo++ftA4n)Ml>dI94VEAGl$qr7gBNV?^j!fl&H!LG@t;eM z`*0t3SpPFD{MQiw8EN=&pO8uZox~s9n;O)=$-;j>@gJW?{?{!0PZPg9BMP$$%Kr-R zo7%6!(0+KnR|6Kq~`C z+af6c+ay0&e^(AtZ0`Bh`Yzmlzp?0FNBlTH$}6bg$DVLLq@^!<9i}g`JW~EyQFZ4 z2j&0PB0om*=MX>I&yx@j%E$LCCixH2M1Laja}bn20QgPyztK?srwsBZTI9b-^4nQ3 zg+ck}TjXyg`D=&|%m0i){^J(;m(awMZvN>H&&j6xt0Bg8^UqQX|8n9_=f7PC{HFS^ z*r^L%D9VrL>IK{XC5!y8lKgb-|AIySQj#zG{|g5B{lQN+)!)M;AN@ml1=~Ld_)X|P{?Gz#~!T(r<*^=0>7#J z+YRzxGssVo{9w6CNd6wJhWj^QPR=Te{zItX>GZ$FqW>;~{`g1@@OZ$7rAb+1l z{tl9V1`DPzDF5FU`Rho&Y=7*M!SbI2>l9EmA^*G2v05NK#*lPP>)t@*ehYt|g+Hi& z0X%1$qxNtcUbs4iT}(r{9gioQ~Na; z^#6xJ|G!w|521ncgf#Nsu*hF&kdOP{g7z~CI*6(M#*_TH0r^NPud{&PRQ~lOe-06& z{eBGbp#0Sq`5Q=ny7BW?i+t5tKweD9?=;AN)gpf%$xqjRUbe`OVP}O)_MiX4eX#t4 z;W^n<|3}e-*MTY*?@zG)8!Y_!#2TLI0O5@{gi{2h7`dVOiyMEELdG{vjFiFS76#6aS4; z7{r71*9`oo^6#bcw-GCi!{qYeqT#A7+sM9gF-v^x&UP{yi4?Lk;qeFvuSS>kOv$ z8%FY}8r)h4_P+yx-&FomgZ!fm@~^hYpG@-8&A*pf_@2B`)$rp|6<@bwckpE{wEmpzu6-Hmn1)(|FFa& zf4xEeNe20QEb{y0>-q|gUszZ2s)r70s=p)hHB~zPe^~fWBmQ*j5AOrNss6W6`Q`j^ zilO{%@SJVZe~v}}p#A*S!rx5%!*n&ce^Hja-U5D;{<{qNpJvd10d#Pa{`cf-DbuAe zhzIqb2mB`aga57><@`6)Ape^d`G3#X{OQJ@Pb~boCuhcw&zUCu=aBwj9_m8>+D8C5&T*x-0|DTCJ zUHv~`;onF6d%55g2Ib!e{HF5ff1nw*5+9bo2>u1hT0vytRPl09(&fiEYuP*|> zN&ZffFWY~lLH>sp`A40irKEfRv&SO8(;$DeLH^m`AehR3F3BGx3k&gJ{oiWgFDL#D zY4~pjepCJBQNv67EiveS3d~a`{r8gmboO_fh5x`ITJd!JD}djm{}$3;w*NT>{ok_4 zA7YV@WtG<-E%LV;#RALU04^7|B+%l}J~KPHX*Pb~7EC;5d!{zV4)t1a>!8u-%rFSi1} zsr;P=`DF(Ahr&1kaA^D=M)HIGA8F+^5co~Cy)|8s!fRQ~mb_OCR^-)512;1_hor<;F=fSxA(k0t(e_OsT)KaBWmF>`SR z?Pm?}o65h1%8zq4UO4_-3jc!sR}ADJNpSu3t3wr=lTQD~Ec_dZKVAR*De#;0--|C> z;FA6Ka)bV*AjhQt(;4dj6AS;V8S1|o=uGDqsvMSh7v{#=9nMHcym8Om=4epC4?4DzcD^53(_ zpG@+D{Ri7xUdNtkuD>gZKVAE;v+!R-{4|WZB7^ep0De>XYYgQ_Un-Y!;(mD`I0%?$ zaQs+9@<+ImbtEXiAMl&xFEz-&#vuQCi~J`@emeVGWRbtlAivHa|5J{=nZ_1lzv~8W_tIZ2xniU*I)I{q_C? zpy|ylN;#j5R`um@SEhXB>7Oi>O%Xu z(IEdT7WvnZ{Ci!=IuexMVUfRu!{@9V`@(+Y@6|XTmaQ_D77X!bk{2TwR zS!DT_8RWlUkw1at2j^eN!gmcEW!Arf_|x_O0l;t4e+TI=`~NKl{Sy}X*JLRFN{jrx z2Kg%u@_%lTzntXLFyPi%u>Kyg$j|N6EVBH!8RVZf+Fbt+lKkNNqoDkgf!|dB`6OT3 z&uWAGjTZTTBl+p%zg&Sq`;P#>N&gDcpZT%>-EPqT9*g|*!7soo zo&FzK_{%foA34@s{>zDff>y)*8!Z0_;5U_jouT}9n96UFe>cgW>Pps;p!}~}dz=)nCOEdQy{!64g^ z{jMkeOI=PK3G(Lyze)eW|JC$!h#&12e~TW}zuqGM-y|QBeHZE~uNsT|Hj*#<|J?@p zf49gl1iuom@j7t-2Fw4hMgB&E{Cf=YPd(dQ|IH*no&Dwmzp4IrkbF6QtT)L24#|%M z3bvKx4|PkfBiw!r-(!)V|G%1I4iRGe#r|cfogI-w#eUXkdNor1mzc;quW1N|0N`!>xnCX`T70?;5W7Z zPLdxZLahId2Kh0PAN>7T1<5~>1yPt6xNiV{oMR#ZyoUIL`tm)8wXA=Df9O69aQRXH z?;G^Lk@OGNUsD?SEbdyCA86Q8gZv*Drl8c@o&Y=o^Wl4^2sa6|Nj6)z7byl literal 0 HcmV?d00001 diff --git a/examples/cpp/metadata/helloworld.grpc.pb.cc b/examples/cpp/metadata/helloworld.grpc.pb.cc new file mode 100644 index 00000000000..4255687148b --- /dev/null +++ b/examples/cpp/metadata/helloworld.grpc.pb.cc @@ -0,0 +1,70 @@ +// Generated by the gRPC C++ plugin. +// If you make any local change, they will be lost. +// source: helloworld.proto + +#include "helloworld.pb.h" +#include "helloworld.grpc.pb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +namespace helloworld { + +static const char* Greeter_method_names[] = { + "/helloworld.Greeter/SayHello", +}; + +std::unique_ptr< Greeter::Stub> Greeter::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) { + (void)options; + std::unique_ptr< Greeter::Stub> stub(new Greeter::Stub(channel)); + return stub; +} + +Greeter::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel) + : channel_(channel), rpcmethod_SayHello_(Greeter_method_names[0], ::grpc::internal::RpcMethod::NORMAL_RPC, channel) + {} + +::grpc::Status Greeter::Stub::SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) { + return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_SayHello_, context, request, response); +} + +void Greeter::Stub::experimental_async::SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response, std::function f) { + return ::grpc::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_SayHello_, context, request, response, std::move(f)); +} + +::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::AsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return ::grpc::internal::ClientAsyncResponseReaderFactory< ::helloworld::HelloReply>::Create(channel_.get(), cq, rpcmethod_SayHello_, context, request, true); +} + +::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::PrepareAsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return ::grpc::internal::ClientAsyncResponseReaderFactory< ::helloworld::HelloReply>::Create(channel_.get(), cq, rpcmethod_SayHello_, context, request, false); +} + +Greeter::Service::Service() { + AddMethod(new ::grpc::internal::RpcServiceMethod( + Greeter_method_names[0], + ::grpc::internal::RpcMethod::NORMAL_RPC, + new ::grpc::internal::RpcMethodHandler< Greeter::Service, ::helloworld::HelloRequest, ::helloworld::HelloReply>( + std::mem_fn(&Greeter::Service::SayHello), this))); +} + +Greeter::Service::~Service() { +} + +::grpc::Status Greeter::Service::SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) { + (void) context; + (void) request; + (void) response; + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); +} + + +} // namespace helloworld + diff --git a/examples/cpp/metadata/helloworld.grpc.pb.h b/examples/cpp/metadata/helloworld.grpc.pb.h new file mode 100644 index 00000000000..73cc75e0a62 --- /dev/null +++ b/examples/cpp/metadata/helloworld.grpc.pb.h @@ -0,0 +1,197 @@ +// Generated by the gRPC C++ plugin. +// If you make any local change, they will be lost. +// 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. +// +#ifndef GRPC_helloworld_2eproto__INCLUDED +#define GRPC_helloworld_2eproto__INCLUDED + +#include "helloworld.pb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc { +class CompletionQueue; +class Channel; +class ServerCompletionQueue; +class ServerContext; +} // namespace grpc + +namespace helloworld { + +// The greeting service definition. +class Greeter final { + public: + static constexpr char const* service_full_name() { + return "helloworld.Greeter"; + } + class StubInterface { + public: + virtual ~StubInterface() {} + // Sends a greeting + virtual ::grpc::Status SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) = 0; + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>> AsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>>(AsyncSayHelloRaw(context, request, cq)); + } + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>> PrepareAsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>>(PrepareAsyncSayHelloRaw(context, request, cq)); + } + class experimental_async_interface { + public: + virtual ~experimental_async_interface() {} + // Sends a greeting + virtual void SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response, std::function) = 0; + }; + virtual class experimental_async_interface* experimental_async() { return nullptr; } + private: + virtual ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>* AsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>* PrepareAsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) = 0; + }; + class Stub final : public StubInterface { + public: + Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); + ::grpc::Status SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) override; + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>> AsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>>(AsyncSayHelloRaw(context, request, cq)); + } + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>> PrepareAsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>>(PrepareAsyncSayHelloRaw(context, request, cq)); + } + class experimental_async final : + public StubInterface::experimental_async_interface { + public: + void SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response, std::function) override; + private: + friend class Stub; + explicit experimental_async(Stub* stub): stub_(stub) { } + Stub* stub() { return stub_; } + Stub* stub_; + }; + class experimental_async_interface* experimental_async() override { return &async_stub_; } + + private: + std::shared_ptr< ::grpc::ChannelInterface> channel_; + class experimental_async async_stub_{this}; + ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* AsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* PrepareAsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) override; + const ::grpc::internal::RpcMethod rpcmethod_SayHello_; + }; + static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); + + class Service : public ::grpc::Service { + public: + Service(); + virtual ~Service(); + // Sends a greeting + virtual ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response); + }; + template + class WithAsyncMethod_SayHello : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithAsyncMethod_SayHello() { + ::grpc::Service::MarkMethodAsync(0); + } + ~WithAsyncMethod_SayHello() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestSayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); + } + }; + typedef WithAsyncMethod_SayHello AsyncService; + template + class WithGenericMethod_SayHello : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithGenericMethod_SayHello() { + ::grpc::Service::MarkMethodGeneric(0); + } + ~WithGenericMethod_SayHello() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; + template + class WithRawMethod_SayHello : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithRawMethod_SayHello() { + ::grpc::Service::MarkMethodRaw(0); + } + ~WithRawMethod_SayHello() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestSayHello(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); + } + }; + template + class WithStreamedUnaryMethod_SayHello : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithStreamedUnaryMethod_SayHello() { + ::grpc::Service::MarkMethodStreamed(0, + new ::grpc::internal::StreamedUnaryHandler< ::helloworld::HelloRequest, ::helloworld::HelloReply>(std::bind(&WithStreamedUnaryMethod_SayHello::StreamedSayHello, this, std::placeholders::_1, std::placeholders::_2))); + } + ~WithStreamedUnaryMethod_SayHello() override { + BaseClassMustBeDerivedFromService(this); + } + // disable regular version of this method + ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + // replace default version of method with streamed unary + virtual ::grpc::Status StreamedSayHello(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::helloworld::HelloRequest,::helloworld::HelloReply>* server_unary_streamer) = 0; + }; + typedef WithStreamedUnaryMethod_SayHello StreamedUnaryService; + typedef Service SplitStreamedService; + typedef WithStreamedUnaryMethod_SayHello StreamedService; +}; + +} // namespace helloworld + + +#endif // GRPC_helloworld_2eproto__INCLUDED diff --git a/examples/cpp/metadata/helloworld.grpc.pb.o b/examples/cpp/metadata/helloworld.grpc.pb.o new file mode 100644 index 0000000000000000000000000000000000000000..234283660c2185112bf5a40874899672b328aa80 GIT binary patch literal 398496 zcmeFa3wTu36*hd5ArKWMUaF|Hjutg|fq*wa)F4C$4H&^FUPB-QL}L;|f_Oop0cDJ% zse@eKuL}K| z&g#RAs@O>8F=kR?VU-AiUpfBLN5#JZ_-GndUFM)2xcZ)o41$|lgSA_lm^i|=1 z2>K&@U&FUuu-8G~5dKZjxA6TjzCRJ{r$ReGe}?bR<@s&Uckq1|-(TSS9=@bgC+IJQ ze;@Q$!fylpweTMZ{ZMEZ=tubeMxMJtx8wU;e1C`U@A0LydqDpn{2xL8B>WDce+K;v zzJJBHSFpc<{vF?c;QO&){}lQ!(4E42G2}sC6y?C$t>&eBmzuohkfmBQD8)(Kw^dX?}EpbLa=1Z@(2q0p;A7YTn2=(WOM2YS8mi$QM?{zlLx z!Y>8=g7D3t%YHpbrWEbV*WvqJ!5#zsp74)@J|X;i(C_2B0pBMDdkXYv;hzD0R`};YpBKIj^abHJ z3VjiDlkhKrZpL>DzFP%*8T1u=e}M0+g8dNmN5a1b+AjR-Lf;VjrqH)Qe=Ph@Kz}NH z2k6g)|2gQ}!oMT*U7^1a`W|Sf@V^xLKIpH6-v;_?;Xe@iA!wKI9|`>pXt(g&L4Pa! z??8Vqd=Ka!g#RPxpM>85`e)()0{U0sdqMvu{NF+UA^gXn{}ldTpgV>4Fh!@aAO|#8 z_!#H_;qyQT3O@)mU-;dG?hd+#@Pk436n-zzA;K4c?k)U2LiYvTPx#LW-5>M-;fD%6 z5cDA74;DHM^s~Z$4)hS=b_?tj)7Jdb2O88rZ zwt(I$d>ZsN;cpk(3i?Ii?+|(?=t|*Nf!-zj-Jq+5zX$YQ;qMcAKj@c)|FY1pfUXh# z0no1s|25DDg?|Y2>%u<_x>opa2>mALw}gKL^xMLJN9d!V>xBO<=wrfvPw3-9pAfoU z==VW42>+zer$C<;{u!aqf<7nw^FrG|Ul4wy&=-Yn0)0vN%|f>b-3t1$@UMXWK=@aM z{!r+TKwlHSUFhqeZwUXU(6>N;Ec{P|{uH!B_@4>=xzM*k-x2;@p}zoqPxwyIUkd*| z=&yv|2KsB^KLGtu_%6_og#Qg_xA5CRe=Gd&Kz}cM59lB8{Ug4A5^M+PpN0Pm=wI>e z#rJQ5{T=il!ha0^3x6Bv?ZUST{i4u2gx)E1rO;JE z?-F{q(A7fk5qdA^eZt=l`X%AN4Ehz}*ML4C{8vH0Cj5h-4+;Nu(1(RzEA$&ezX|#+ z;U5wDZP4!s|ESP)px+h#F`?fBeO&k_gsunuzVI7_J_-7i@J|bU2J~6spA-5#Xq)ga z2;B(!qVSu9z682i_$@-Wg1#*LE1*9R{#Btr1pSfluL*4jeO>rBg#H-xC-{~pQonwR zoN9t<9b|c1Q{Gd=4OzeO(icgbNGFpWvLP4rMt0bqO)yKP1P1_K> ztHn!|e9TNiOUbsJjl`zFe(Z;&v?<{hpgTA~Z^}=od3%9m-!*;b&YjEKhOBB^*4DVM zD3kh0BDJOK0!X^|4nYe6y==61k{F^UF*2IOrGQ#rezBEIF!8(@iRSHbsM3{4HFYLZ z5;7o-~n=-z)yYLk_frV!HLWQ#=erufAZFS*p@ zL%9s~bKz7ZX!xZbdaBHE@b=sKy%n-Y6o=aM3DB0Pf{0k%wnnyji=DD$G@LCnWnGQC!RmC-1LDWlz_|v zduO&xKn0~OO&caYvp15P_$(z_n)+pFsvB*-H1(TA3N`VXZE}g!3yIX5up4UcM>et2 zbh7RFBE&OR=8lDAHEIB>Ya=b?6;7SZP7L)Dyua0S6g4mM(XS2P;dNIcg)mZ z5P$)BP&#fr)!b_#LztW`Kb}On%mfpuw^)b7d}X+!eL!`E27<(>k>4 zwP@FC(5_d*QopxJCer1~FMf`qJx^`B>p{5N zOJAhe{s+ei9?%;>mVnZSc>3@&F$Sh&u)qF`WBE(`sHO!CqiX8rRMw2DuANiURFxbx zudZ%hO>$IyLtSIt?54S+u1qdiP&qGIQB&QR966sN;WH^wGU@F2+{)^jWYze1;ezUG zlOy62P65|g*;qZNVov3P#tDR0G@e>mwCJR{<}+f%__#;Ql;Zdy1#!@M4fS)5r8rFs zj;%^IBE1F2&aSS7#C)>phbZ;+qpGj0uNgI`t|~b%Sv!i7fr7IeDjTk09p_cdtEsM! zA8|zduzAzVCdEY-udQp0SJzfIR#(BD4jB?q@uKB+L`Ai3K!H=&q-ErBMO3f9G9ZH?F!X&YN49K2rjr+z+@NO zPe}i(8_?1lp#Py{5h>NNr=E|xswy1eF=)#aZ>(#qtf}CZP8sfEe&}yCWF6S%$}8(? zkr#P$eCp~KRD6PlLBYLI^OH3-bywFl)KrZ;vmu#;@}p){UXviyTbP{FSl2Lqe8p6% z7a(&gs%sY{8yZc1)9T{Vzft9lO%1ils`%WxhImsgdJ-VC+65GJSIbpXokU%8Z1{kh z8nUA4-W4P3u7LIA^U2b)=0a+7u8JReO1!qIrl!7e*V||1f@^B$gw-;NEU2!9v!gm5 zIU`wHHP!gKLMiwNU+3AC3*gljG&UeS8*@%wEuNa@G_o%2R~AwO`DEoY?XIa2ZVzR{ zhkL*LB~uWm@XCPHe_k8w-!g>{IVIfhJXQwX=#%lPB!-4$A;mrF7*66Szkk@AoP<>yO_+Y_`0*G^su#>JoQ{-? z9wtXW;rPW@Lyh?K_$l$gU5p>kPGWkpzUG=sZI&Ur%lT7v$w)a>>e-ZR#J`!dQDc|$ zM{ye($>QiZpP;DG`s>@wO64tRtQtR_2Z6@^vp*SwnI9bWQBzkt4-R($27EMA^kAnd z{zLk48|z=QOL?CI(`wAhn|d%u?isS4C+REvod!o1Y)w#T>}fbHhc`rICXbDaRC!Nm z-+@A6!q1^7MXUpctS=s(u~slT^d`1&!n_FBQk+i@%(s;HBvNIp-e%T41Ykw1uDU zY`1HpmtPFp2#n{nfyfh#!;>&-8POby3$TaQc#z2s4=qh-22*?K(gKX}+Rk>g4`><6 z4OD znaNOzXcda27kAMvo^0bFsjimtZJbnB!X(uZPKw|{go9E2-KXx)1zSt`R@?9v3GHFP zB7=`Zm7SG$u6H@8+k;xX468^V79~)Re%qn)+M2ZM?I1MiriGT?+Tuwy1RB`*E!-o` z>b@t@!rO01tt>y%4s8GCj!d!8pJfG(*3LR0meo^oMx(Ut$w!Lw{gP9yqUNyqNE=}$ zcktNC8n|c1x;cNAuzx-Zg_Z&@#IFEPA+M z&<5(M-KUr+vdJjO5ZER(w$r3?jrQzs!N7IL1=sLuYT0reM z(XuC{=kHzO0I3lAB}`@PtRK3wzF=p4{>~!mT5r&9s&p^g8%!!(BWANiHX>l2yf~+X z#HJ!2a=NB>x^0hK1-dgC7-3*wG9`7H-NGIs9IniUOPB3tVun&F;A*0gA%DpFwnR?5 zNz3lB4Mo8_P}S|FEr(|oeio}d6p6OmHZ>*nlKY75GCX#arat0bvn@N{q(@k0C~sV4 zwlU*g(1gX4vG<^H&$y3>^*gyXs3oBlQYhHWWQo2|V8=e&_tVVt0220Knn z%PaS4?KojAMx}7ZM7Ef-scu_=Jv&&7X1)f2)(lziEo&RHY%@23k~KISh@;$XnKKoF zoI{=z_CygGIl@}jy`!h4aqN+%4RXJ1lsH`;2aJ7e3Ccl)Z*D8_aXw5y>};aVNc;n2 z3eC;&h@Y09?ne(&Mq5g{P#E+q=*Pahq-#iXf+UP2;6PBf*pSa5_mg;`GuMzuEIX-{hYp`{F`tpuX#|xea^wKTP zf*j*?mnND^x^h1H`agH>gr*2-nqT+v<|x5$gYNW>n{!~_(3!$oj7oGqhEDyN5_IPF zoV=e5^u9GPuV5hBDHxZToDGjz~wmlV3yK?(_ddd-#xZxxW^9GFPPNO z@u23SQdB#giS)2sblq0x_z-X_Vy#Z3aD+D_ACKrwbc8kuy3ZJj(8$)h%tZXtWH1Rn ze@3B`LlK_GhH~J(^3Q*9U-A8Ua}OHZkY!t`xGj+hDb4OmX+oqp=WxlNJb;a6rZTB5 z6EP9%#{j#QF0zNd{^%7XsuY@69KqqB%tV59>*nGCp5Mwt(oED}=>@&Jho=>|5&|_c zR^=G43EYf55+r2TtuxW#p?=f4RQV$iZy+&KFNa7=`6H>a0jQ{cPgCj4Go8Ryf$}y) zT<5kkt_Ng-O&XpQ*ftd;`pJ%0eK$Dd?7RnZyt#SsXX}F<3|K=h$)GS)3SQHf4U0re4SroG)k;nkvbY7{koG3NrEC}ok{#ZiW6NN@ zpUhEh8Jb2%=ljiVW#qef)i9;NE*mICvEARZJ6 zo~g5Tm~P&c;-1<8dle>HE(I-F6CMWEm=aE!iLq`LBCazd#iaRouBU|1$P2A$X!gNZ za(K&xQk^MzB6VozHgeBd;IXBN_^) z#~%99E{vY*ocgdW2CZa95mISG3)+hL*;qUmx1#nF!4;z{)-L8<@@4lM)1e*P{;+E% zALyIB7!{P=)uy=<^h(!&{=B12&v7obxnD`o)QtPCBkR>n3wCERXkzSfWHfSp28lRn z)0tcmwqB?u(h1Dc?VVJZ)U!jebDKy#Q9z_+IX}r^!m^KeN-r4sz~ylc>?CO;6jC$Z zH%MSCo^cw{joRfP7|x3@Z(Z5OM?O4`^VHke@T0GjF6olztx?TkkFO4=j^=4qDWd&P z^N=pX03XsK2vsgaoOMN_%PO~}E z<*l$xF`Bv~X9hz{bn||s;$>>gThjtH2(0zNdC0+2F z+Q!4iYjz=S9_5O$JA#E$kMu@=znsmyv%Yv|{n(xLMLX-!31!dR*R+^*I$ED|rA-T) zGBoJaruO7a%x`4Il-<>I+0wC5cPu!_^9@y+`c?Pg{ar_tdz#XQZRhQF9P$PYk zj{9vQ=8&Cs1Ts%Lq($@DH&jO+krh+K7I44$aQf%(k{YzDu`6l}rH(~vpf2b@Jlq={ zt8zVxwKFW7p=q?NW4ZTEMF$G66m9K&^1RLc2Wm83yy(VU_BkkzqKHrOb%Goh;tw~? z*Z6hzD40l~>``6WAT8*$)C>7)!e$h`^GQyCF2R3@vpnvZNSP*HG#L{=%RfSJ0Cx+v zc~gOPjC&mdJ!PP_wuxK@Iw+*2PafavDH(WyabT7NadYryn zc*G~!**fYf!&~{1T~65@Y0PZ0m0R$$^UZ8>mYGeOr;KL3+@Ppm!}*&+_L1+#SSjt* z*pAV%oYR#@uF{P-{iqRQrgV@0S+;A@qjj0-=z5NoT!hVOQe_A zqpZ)-q{-2fiYbR^atOtIx`Gujr zKgx*BsY&5KxgT|B1mqJkbu&F)PA7WV3z0K1OTgR6p>T|r;v$+x%LR?Hv2sBpT{bR@ zxVYHAc`=rj6Lt%6#MT7=@(_**cP+&=6f|C zjpUL9=?y4VyG&y#dZ!FNx`4ym-OzePx#Y(XO7S1a;=30 zmYGO4x4~L8!^G+;2t`+bs5He1HpN2S6c_8J2<4Y){_-x)v8%VdE3WiQ9?Ck_QuakXql%fwsPA=K8STEeXEQP~QRTFdCP4>YYS$-la zKYgVh%D&TRQz@pwlUKHHbVEF z2tT4^TlYikyRA)ReUY%c@zgy=;Ae{M!FkA73>Y04+}l&-ucoGMMRs_y9!t7DLDcX& zS`da87vQ$0%IMNb2e#+LrI&PUE{;>TYqu$&AiCiuW-(lr-J(tk*5dJA;d9{Oi1|(t znT6c~atoHmnMxCF~AEo|rn5HN3-{8Ew`bU{tHAmEysP)wt((y>9CnWVfg@>S#e! zZm1pXI=O9Nx&_nH1~Zj)$g-Qb0_fMKP57Qsm}oh_D3O|&NTkk14?ANlo{RB36VJ0K zo-_hVF=2f#JNISZwIf1D$V{&FsDoPhBbUl^rX}%DQWa zq3bFrEL0qF2L8~DF?vuMXD{kKMa#rQ^Wx5-i6N7)U&*`HQ`eXV6rBE|Br{Nwl6A;< z19lrx65hY|wW8639?IAscAzif0Hhr4j{Kn?iu@rx%^Be&){lGK>Sh`)4l#1IZpDwYRb80$skd z3hEM#L+X-_@u)6OF4@+HgS;+lX(O|WnWoOz3AO|qNSJP$7E0Or?J255Vq80|ec?e{ zn(#d%fo55TW?6`4S%l}Ac%Fr4lJi1=y5)4l<{{M{90F`>^(k^b*<= zr0IaW55VougiIB5j|?uBF_Z=ZQO45AqJ1}SPA$b?(jL9pBRU$exUMx!aVRq*1c`ig% zc~^V4N`iZi0x%OfEE8bJIpug;W=`HmGJQkj-Dc!1^3o#DpO|+ZzkP{PMUn11Jm;XJ zCgDY9IcIE%<-D1TO{zb|O7IG}%>#@UMhS#I>I*q}4-E32&e=OX2-ik7L#4)duPT7o$s0GF?J#G@E(*E3<#_$C@h^kcK5vWqyRIGEY!t4C7feCezrP zz^;aUO%~l(l#WC5G7c1aJ+M(*(0;EhMwT32}f5msA0lq4KZ{_kS;n-?J5k;oS{lkV=zj*wYz(3)UOIDs+90_x%+@(W*<1iNN*ah5hJFsb){J>|Dvzn5lh zqf&0PM|&?IOP`kpO_zdJP%hRosqz(x)YK)VspX5Xm0g-j(@{rh3!iu-TAn2k-ERpj zxB_KhD^5+lFeQbeiebozWK6}7^5!$wkfEqcH<3Ql25hZufFajm!+$Mw<2PHCrl#6j zgoE&_th8n7YMdXUCa122itC`_22}KGupCw0pc31jsI`}_bk-k0I@%| zT%?$5a%$^}<&A72T8-HKS>(J1T0vpoaI5*=J@lj^(e40W--N!j*F0>ncAAd2|Hl8xMXIwEZ5yvi-!F1r8z9y)_xnH=NNXP?c?r44mQx%>lc)Gu`H4 z{4Ij|EsbN!j83kv+X)`_SNa-`$WPGX+V^o;=Y@{WO=Q)Mu&T1UBkc=}D(tlpGFT2$ z*?4cMtgtVAL>*->$m-F79@vhYK&7Aa8rFHly#wriatQpm2VUKVqs>@19@I*6RYP0f zp3B;rj^M4>$Y_I#@*64Y#cT%KZcB5%&QJ;LD>te1<`OsBnx74VXP)*Dgt;slrBT># zrUkZ9(M%U_oufOGCP;H{4z4vqnW-F^J36WXeG`L`y(EKJgR{pvAc!^8jpdB^`Jueg zpFNwmor(BfzPQjIAyEcwIdQ$0k(ba*9)$dKHY(yA{oj!|b2E6{iDgdrMC={fN;B$QM0;vTP&YNf|G?R--!$iv(;`gd0? z(ReiUv;LR`c;?hC@j@?tc_#Bjbf*HXms*aIM^pZNmH6u;@CYV{-2?N-)vW_~yk@*iDzDXH@sVA0x-YZ?m5$P<51 z_=P}IQ+lA&3us8@m(lK%7y)5V9F4+bW(G-ZgSeEW!K zsEClQFOvS1p$!_Bv_OnSdB!&E{by1domOZX4Z>1#JKwa*hP~5&+T(_1H9?7NhvCBK z`x-j+VlAJo&Nv+@a)uv|<|pC)&Gh=y$T>KP^=vQwygv0r50h10OwyeoSjcrSNw*W&vfP9;)v#qbHb?0{@OfL74**B=j4jLa z!GXaGA(qoGM3_ylqL7L7a*uwS9JEU$$a%sKnY$>7^s{jUDV2~dtVE*4sMNv=V(Ek5 zLvT9M8stYNEvrb?L^{pF<`)Vb2VgZ%uZoi*jt2G@Dz;^XN+=h?_!lT2{f3rGEz8L) zwlY!}%nXoTv6jj#n(=O``c>-LE;i;9olI7B zFiE$Azz1z*l5Qgqt(*zDjAEW?uQGAWMez>ICpx@7ezI^fH&3$y4z6uGiK1-i$j|mr zo-`?GVJ*`&aA&p`W%>In%PFq4=TmKLyU-R3L3U0;GlD&X89@itJtinLpA4ll z1#Tg2t|zxNVca*ppfvsMS?DHx?e>IHd1^^i8-iSI=tY87bH*)H)Y7jWrmY%hl@6TBe}ex)f>|)-103;1}fh7PX<>4BgO6H&GAe ztvml;5b(wwmW-H<+FfFTLNk}h8D&U{s5F61`1+aW!qBr6|C7yY{Fz_2{PI72`s76y zVNSmqE6-M}Z&#$Ynwum5qyhLj10vVB8dZ&;v?!Viz64nLP+S}-)bCa`4jGOzJGR#5WjKEvD=%Fs~8v~WQJ(3&o|MMMh?x>^!i zo6$N$ZdcW@b|>I3l;j@4jOqZx3!ExK74VZhm*Kf~?Tv{e;cd$a?cdEZ9|Z-ml*eQIhO{>jD$97U`PCramB z>uet6^+St)dhudgAf>$kq~$oCl8&jVKTJ(!?gY?C*1ReFpG2r+XjA@O?Us^Pu{YT` z27hiGi1Vhsy035U&22orxi{8$Nq0T6g8D&L^26a&Zg+WDL?v*n6ze_#O|qTC$iANM z?Py=Gdw(lB*H4~o$d~v6L;jb{UTk}T&S*`=_WGaffYGeU^@zr+$y>xi_J-%+Mu7QB zyNB}vx=0){8y#?>rrqOfe-cjSMZJf@m$Y|(FM>P(%hOg@m)k&Tu4XQ(`-QRVcfLQ+ zLo=Xp8?j04_r5r9V(=u-X#gb{Ui_-`SJcI}NpTTP{+&)hZVZw4vUWnt9w(GN+YW{r zm>c^c?%Od6kP}c;gfvTMJJK)FF2;$xkLTatjmCHta#|q;!}}&7krs(d7`)udzP!Z1 z=9dzEWa*5aREw|`d?@Yp`uo;o*e(oBfc-^lW`b-^n35It>pU}5s5o3w>pjr`{gbG` zi_lN*Xz8)}`Fyx>GYN&`*~8hxq+x&#yd1v{{du#!z-Z&&503V)kjEmo6l6W(MLK4p z9)y;D2OY=IPfr40>W0lctb)pEn!AzezAdQJ}wFR|R$5m#ub=!?UGe(p4`z`7rlAfJ+aynE@+b^OaDG2YlS>y0? zq2J<+d~C*ZamKT|q@(m^`SOs?usd}RsNc%V%iwVxO+@K&%MzZs;4v^t5%*^60=Y-~ z+MYZNF7g=wSE|MB14%UKp1Tc#CNI9H|aE9fr=gn3} zP7eBz$2R%&^^>q=k@V*K&szQX6=JH3Dn;t24J>_v`uXIoO3AgXp7Y==%N9v~OE@<_ zzrb-**G|tYMliT~Tz`}5N?~7FkUVZ>!9D^FhxU$JkdARALF38vxtpJ--&30L755^S zzf2b)Vu_X+$kHr?oMe5s$c{&vqivS*!bWLL_DT~vm#mMXOPh7JROYSm8-hn#ytLUz zGh%HG9$|x~c7(us=A)_fFHD1TQ5sEY0!#lEv5)qtw@D-Uzh}QlbLyj|ao?0-D{cmT za`@Kn^uJ27PO~F3x>$d2ljOCRUn6}aV6zlcNNY3hjrhOE1vRcqj)ybcxeWv^MQOt~peOS;DxmD6<+L5+` zH7$M?gz8=ChFO^ zoPn3M<621S@76d&)|Y%}b|mP<^z9aIwbuoMzU6M}QBwW%H8E|-Pfffa*hovDWE)Vo z>o7ZC8@|(vYqC-lvvamOc%+@PHNhhdK8S3~8QOIt>(H(n?N(jjY^Md+60twUA=1eX z*%_Z$@hL_kbKCZ-?ZZ$$-K0_%CadLY^6b3gxFoq zn!FP}zJve6Kqp>%x&lK^x*R7tG!prp9(R#CbNGe)-9JR@jkHm#wJ)=MUw*ET(bt`R z(N|~Uq0x9onAd zG(MxcZQ00C8)uCjnM1=e-;amfi1WJ?-5R>Y)@}jUu4Cs<(VoIq_FqpZ_r>}Bic((W z=kzwerUI`+M(seOYv*mv@b>*y-)tD$cza`derfs`_y}~xmVKJv&q*wQgN#Uz)AQ+- z$-L7Ff^+Py90urRoa9G&Q*510u~cpcO1+e}#1W{?N=-7DBKP3tUuo)h!2SQe6m0gZ zmJLem%oMp*$*#+Y;LR>nD|U9$Z~qDsrbg6n`bbW%oJ?*?nAKQ<^D+PN4glHCh*C%GzHG*X(E(Q%kq^ z()gZwmM&7^QWoEwO0DYUBknZcEWoWPJn@^O`3ja*JXP{eOUXNURYP;{0Yh#+1jmE) zhin z9;Vag$bb1*luq7l=g(#n=~Vkz7VHo{1mp9?~+6Vj*Up#XLt5%eeQ?r^| zBbXw8R8Qt9e<#uM1ZRdzImkNoI%b^(u)cK)#u|}V^71W&iOb{n5DTQp) z&lLbPk4P?4Q`<8$qIc?Il)~NSP=@YZ0;#2?o2ZSuzXl3Bl<<=siJcK4;qaMbuj{^o zxl6_l7{x~$H?v_3y#O^`!#l4lYFw2E94DHhtSL^bHBpz zZshDbZ51cRy@;8jyQAY9lt+Td`$R7#e-}iT)^Bc_`*3OMeO@(~yUVl>W!~{=ogc=A z&`byRwTRtk4>@F>Uj#)6&bP9T9d^cx2=*L_wZ@2S9X{=pKwB(q0u}v}BU9$MUyb~m zsBjAXmN$+T8#IZ+a9YkBJVnzZDC+pHObbVp3=JA)Uf1ImjT%Fcpx;hx8_JBqvkPk1 z{e>j?f7d5uiRdnC=1#Iyf25pjFzd$2c!uBg;`XD*|FwMo)3wo0IWn&i^aMP9sHr;X z%!XvLG1+j^jAX;Y>N&}hGo~Fsuc3a-B?{&Gd0;*SykCs zS;D0{DUeT1E?7`GFUh!#H$6FLVPEk`F7c*>tUo$zF4kqV$!k(gb+Wc`MzXeQQcc|g z$#0A+qg17q6iWxT$SD8l6Q|eDK@sQIRV6BGt7?)BVZ9=)V%m%`nf1+3SpOiuOfFRF zNa~rPqt996A3vk9X?FHDmYISnKkAFEI&r}@wR5H?7u46)E=W#KR#s(}KcikUQ!~$> zsvTz}8R-Z8$TP%VM*U{A@6pnJKT$i>+8Q;|vD6Ny)tys6rL_7u^z&&mPO1QVe88R% zuqT4;tATzhJND-f5@Ac_&JRD^r@rlH`#JT-zWO=IL;j(!zAQfHKk7TQI_t~)YywmM zFtY*Z%o5-DrCp7G z;=H=Lc{Rzg^`yY;rnzIP>qd{eDA`aqsjmK-DYf-YjWZe>l9gBXksfXIXdltZ+3SlC`=5|4~1XQIP)pYesOXPk&OB zDULjw^7`|O(Z_`bSG~+Oq0IQ~V9f+&SDJUG{~tXzqoU5MoChUjHAWi|SXs&OG_A7C zRupy(+=E$y3(aOiCOkGfT$~-gFgrXe8{E<=H>a=xfqgM~Sxg?;iT2F$f>(iJ4=uHU zV7fPqjadE-g>2tsUSP0iFZBOy=^YEaLxMut`x|5e{De#up}blwlvxv@+?ohw&mxMH zmVae~V%zJ{wBJni#b<8(8wD(kxmIP9Ezz=MEo>6(eHHk1&9|1Z>sSvHl;B_06b~hu zXjw$tkD#~#W?szz9yxN=_eNfjWzVVX-VbS$`HOI8mn5=o&$g!$Uh!w9_KEj8$R70j z@&r0PjxsjzZ>FDE$G^`G9a&&Un^E^FLuz>;?N_G_k-X`p*y-i#=v+X4O&;7;hoF@Y z3}m}U!bwbQ&|i*hj1KrAq2!pNx8RB{xHVvt!0(gN%ZoUF{0=eLaYL>KH9EKg6Wr=4 z$)hguCiAg}jU` z6hdWViwBmRl%OA&rB|`N(`i<<`2}o+2AR^^+iVR4JD|=>$K3qW>)MU_QnQ?3`Ybd@ z96VarAf<(^RvFs_$=VX4l}Y6zq7=pPq!#fTNFVJ5(ao8g3EYi~!E~hI)`~sma8t1u z7eth?n46w^9I|v1b&zboaa+2$hqlui53#>?o5yB~{Mya>9>*7;*%k4%oF+eVL-xoC zc#h4*MYtUR49gtI$kC0n^$!P04SF#(`9i1i z47`Z79hU%$4ydvs`JtTnIXv-ipvdL0G9)GdRep zgZ!gsBQb+yv>;~mw2hU+t|&xJ`=z6cj8u5r_}RIe5-#0ne)8!T@}qlvRoHBupTKPC z)+Hu##MaGSaD38JjDl-yHe~)j6bx5E&^F`#2uQy>;xzdh+Ahs@B!*kH|270;w(za& zU7Fgkfx=UpKHCx|Fl3%ilrU0<+T4ah^UYZFz`%!cBA*)mgmW1xuB|hFE>m3ZpH_aV zTJ*bimO3x?4d!;CvP5=xem1y;XJU}-QpL8Rr2oBhR+L+7LnwO|(I>2DDt)A$m(ZMF z=B#wqIv-tjH5MqXu<2@^nc_c#Ec+E1&ioj?!1@SsiE9krYTW+yCJw!tfq(Ap2jw5f zg|3%kQdhEu-}e|aerKwXqLb9t6>xtgNSnxNJU9U|bLhrh4E$z3s%7_Q9RWP~P;+yY zZd|q6;9H9GQ4YMApANU_WxTex7r_{4w@sb6`qhCLU1E?%{`Wz22P=IRjiMd9^l#W{ zC56D*{*gDQ9hwW9n|AbO73Y7ZMtdSTWxGNNT(^vUyLN}IJ*d#&=3#rH1#bgOhkuZs zcHc(#5~OW5DjlJxogYzB{o%qKEaTjw&2~f0EEvo`h2H>6uS1*-Xzc5pA-(mZ+sSfv zXxhbpw}^C}qpb%gp06%+_5Xij7s7bmsA+mPpC3YIa2dheIUL^;=6@n@TT20tb~MUa zRf%_2WK{WCR%~Pa@X-~T`3aM(%Q1-Y572n&O=)de(ni|jWBYaH1>aBki!-y%m65>i zTu{!u3NBj|y8D3{GDK+ z`JfOw#JOkQe8X~;b@69~ ziI!EYHI}rjd?4@_(2775fotR?kGqt?Wv|am8Bn5(_~xZNbfeD7a0M)qHz7}9Wqspw z^v7@PEz8-sxMLTNVI1@|$du*S5TVz_fTUNI(fYh4&A80ZENT{S8D_SxpUX5SDHmD%>K_;@!XF831=rpHNotQf=peA zlK;qQ8qo@q6|pUCdaJnLrUg0<6$LgHG2uRXgq5YmuG=i_A~w|GgI{!*)v;^1?!)_Y zqBcp_z7}(fV=-6DkniO_g?~~@eb$cG(Obi~tDX2S`|ZpBoQ>@j|8q7pZllk+o#B7Z z#vNY&JDp9|35Gr8u>Zgy>n}|HchUcU7ybW#c+sEyTpyo|^H+P}BirSStf^$g&$xeM zll#Q?N8~<-xqU~m<-S+u9UOD<<^;NfV=mq>+uy|-rz9Erf6@y>PDyK&K}*b1v1Ou$A!(TCC!L$+qZjR%kH4WKh1dob|uUqQh2BNQ=J+7e`t64 zKXRZD*>vdp7DO8=-0nR2CkJ*%IcsCc0%o)i+rJ`?H%nB8W;7l*x?*bOHM5fyO|`h} zR8iMZF}s?%xlOfm=)%+#lZU-neO6i4J8k}zBXgZP%f;)+MO=ggwu?7$&zv-Ae7taS za&~oPZTzH>$BisH_Jk3Jp@Qru1u41)Y~ zU*H6W5r$9BwPmGTbA#@q$AfMC4aWn0>GM^52M}Y+aOSPC<^j2PQ9_i?0NSy}=UDn< z!^{u#94_*`T=|qhKDi%xmB{h`aD()xoA_}+uM&>WiTH-}yei0Jt)!vV^;VJ7?|}U> zGzRgzM1F=V&z;Bt$WCQq>xJM$I+QfWa%+Ngim**ep91=0ZFP1aFB7?D%ldxgts-Zi zXwxqX(qGq4{C1I_;ObW&#P1RL-mbhfkQZ>_^*&uB^6$Ixb06abs4bO={A5?Y(4-#+ zwn6G)BKVMe*PbeT=Q?kcBhDDT=vWF^!*7Uf0+XL_SwYg z#{pd;^8ILRwQ_1}yXW{iERispjn{}=)3HtDg~-Cs!x;-YMShzr&rSLHdwY-oeuDm3 z9i8}bk$>KmU&hhBIIv=ouXN?)TW&F7sGU?v7_FTx6ZuRxja)O4JqFlzsi)6p`ku3B z9v3@3cVzs=kzVedlq2Q$mZUeaS<&km7m?P|Zl6j7f894~TSJ6M~Y6QqBh$Tk1a zC~|FGuu|mOnDw~GFCisu{<&sh!sQpa<|B8AJe!ZC`1|ci347jU^v6%%I4F`IFLG_J zd7j9Rb>lnp=|+)j`L7iDQEq%^-SW7|v$g3s;tZ4W(Y4o*f6Tp>D~Za`+lLO6#wEGalP!9sjJsvpf_&~y(*rOJ3R9FQqYz zC$*ke@7jXKueoNfL}7|0%#Yo+OJRNxjB!;GM)SAJM6R{32SuJuPb$Zze&TQIC;k9d z4F7x&Y58?3?T^wQE^>Xo4)v4D#!I= z%jdy|%0V`NBGBU!NvGURC)aFd#3>z-U+&5&4QKsk>+QP;6Upo0pucaGv_fMxr6p@4 z%5Qr=VaWCcJZZ^ZcA6tD65Ab=>3`0?EtVc|YhLp}GrOgBF|P2 zWan*?*F)eVWxp>-XHy?KlOEedel&Pr4`-b+fG5|Umu(GA@rR2%+j@-TlSO`*o4&J; zQYCV2J-JNe+4>fx|Debxxam9XeUr#F{kHWZAHbU*o~OkhE^@7WlSQuCw@T#M%1`zD zs?^US@R53U_G%vKL(e$k?kDA>_7qB|GH5G3lEwuH|W@PM#gEmPkpeEE7J2$0`J$C znO3r`6Cxk)%AGyi`6Acqaz#J#wf)Gq_8}*m6p3x`1s|zvr_B|x@jWlw*h}dwl60D~ zrE^8lc4taDJXG4cmN`$H(h>Qi;C*{i{X7(;aleGo#*b%2uI;0}Bl7FqJaVb_&D`o^ zkyE*R9V&wShf&4jldTLSnjmsbzf1a&UoUb^|NBKgmXxqIboMcx5jj`Al{@Ey?}+>a zH@>sy`*A<F^Q?h}`YoXu?Y6F*AvukS-1hkTpVPZ{`7o6R)` zPLxKQq@nezPLXS4tH;LI_j=#pC$5aZG_t0R;h#Yu*M3Nk>|v* z1g*3v$XZE9tLv@($h$ON$S(o!ms9qf;(!t&Ki8F0e>TTX z+#YHqjMg4+6}eW%M?^lw%_DcR-=ALa=;LCM8EzH1=4&1i z`Dt!^)EP}Ps0^=){61Iiugh{Z^@VnTq*fK(F^% z{m7T}A&(>dH6p(Yyl-#P^;V-R>99${aItKiIP0%%B0t7WV_pz{02LUYbLfwa@0>vo z7rEw_Cif$+>PNn;ANhkK*X9A6M6Qjq+xkg=055#?aelbSPj&5cO<=#tBG>Y-61nF0 zmx)~K+YgF7oBiX^X_LsOy82NYnH1>QC1H3vVCz`UbSaH|&fN1}&P>A`hjRZuM#6AX zHVxUU;r=i3Nf~L7skr}({5V(ctZ#1>dA9x^N1R7Qex4hj%IWx!b_v78>gcY2MV`%; zq+`L6l(^m&ibS4GM~Yu2^3a}Et~tCRd3`_eTSY#dl(70cXU^;TiQnE&{GNW|7tp|m zkJgrpM6TJdOyt@)S18*ORpjeQ3BUZ`<%Uf1bt2dLV!OyS{d+{tTWdD`X+b|J zV8!(LaFNJ)Dq`b1cNfY;u9jcqTKjAjxmtda*N5z57M^6Ec9ADsIr<1)TZ{wi5%~of za%p1R&-dfSg6CyhGmtAiUgRk^4ZCM>U0};gB%Ib(uJ1!0N80y`yf0nbB#c(yog&ZX z_sCuzZ`ygDHa5mZu9cx!Z-k!yBNh&iul6I~ zE^@7n4Cczw+rTj*A5TWI<(EA^YO5>7zTW^JsskFMzY^4SV?X(<6!~6mKC%itgxpxP7b@r2&S;**Rj`KptGutG#%#Ob=7P;F0MV@WVLUp!8 z}xi>^gGV+F;sB9eH4rQL<(ff=iCvTCGu?cC7-cGpj>toMg2hl;0!!Fh8>G<+ek&kfGaPE85h+LcB z-74}>eK}_-kBD4bJHFaa{@eSBKbR-qo_DsZf39(YRL{qVoTu8h{Bwi;QY!LLdw0$! zYDB&*l>U310HuGc$p09U|JIj3BJ$6;^0FZRS4Do2E6+6tf|UMtk@J+u>hJ7N4`#!A zo~HjXBF|=j>MtwBzD2Q&{zB&ypQn=ovrpbA=}d6-bndgP6#2QXTpA*k<8hI{7Lvc> zr~j77uf>|tZ||`tUMy1l9U^}{6#rE}{(j?0;Cb)UA8V)FcYXQsBHzcA%h@)if1b#- zdTtcCR?jO%o~@qaNdIw>)4c^>KlIgDELabBNSIax@xz!S03PpqMV_rMQ(X={nId}L z!}Q16Aefi%3WLI}5L<2nKfn!3zT+u28Rs`&(!0qGBZp07vlSxO_O;fET-$frD)NKf z^qsTjE|Cv$<<7oo{sa=}cR&mKkth0*&lmZ=l!>*cv+uT|ANksTJ)Y7XO{#gGCRE?}db^9t#Aw@kR=6?PBq1 zg2yw`p*#GPPGLqmcL*-q1PEh34+_ry0+7YOFF4gReJuX6;4)?Q%bN#(Lix(n!^bIZ z%sT|JqMw*|sDdA+;Pw~#;k07j5lZ+YBY3gs`M4xu?Y~6u4T9V9eoOEtGw`1Y{!|8@ ziv-CIPiNqx1%D<3r^lE#BBH0kk5cfX75o?lKUTr1bwxih^Q)MMAm)u$!XKyLCn)%d z3VxD;k5llI6?}q%pQ7NWDR{AhPgL+p3SOe%XDT@T1B>V<=AEVBXDfKAf|K`%eq!D^ z3VyDF&roo>=&rh;Fn;1?A8O{3-=spx{jkzEHuhR`5j%evN`(tKiow_+kaW zLBVfS@TCggtl-NP{ALATq2MV6zeT}Y6g;iqw=4J;75q*GU#Z}$6#Q-lU#;NxDENH} z{v`$fih@6&;QST}>A?Ysd0$h))2uA|iFpqx_}3NuVFh2S;NMX2Zz=e<75q^J|E_|6 zPr;v1aGIS)KQZq~1%Fz>pH*=F-v*HkVqTjPexriFsNgRt_!b4m@#qSY3o{`RLg4>mc4ZjB#V!Y1E2!Fodb|!Aa zKOlHfMtCw-%=>|$#&-5^%=@8&zoy`?EBKoV{$mCIse*SX_|FymZ3TZwT@uc27y(Z|*!@iDI}65imyQSfdB|E+@mPQiN={ErI0L&5*7;D1%{ zzbW`X6#SnG{x1cGNwa)nUao@2B6xf^(;t_hztYF<8xbG#Xm=v|iFtz*d^ZK(UBUNI z@I4iLh=T7O!RK?i0vyfK|HQm~BjHIH^Y&Bl{T1A{azANiuz#q8AEw}+Q}DQgAEw~L z75s1oKT^R*DELtdevE>TRB$>0i+*C>7zICG!B151lN5ZMf}gD5rzrSo3O-T6CnlJ*1f&pL#?1Z_Il=5}pJx?+pciQ^DU-@SiAnhl2lH!QWBvcNP2>3jUsg|5Cx< zSMY5L{(*vjsNf$d_-_<^yMq5t!Fv?^j|#p+!T+M*y$b$!1^-yV|E1ue<*?s!V_uHC zOm^^?g6AptAO+t|!FN~i!3w^Yg4?%(`>Hb&^Y&4~@2lXSQSkj0e5isSsNe@H_%H?k zoPx&{{4fO{uHZ)~c%g!iQ1GJ^{1^p4R>4OpIGw^rKQZq(1wTQ-Pg3x43VyPJpQ7NW zDfmPMpQPX=3Vx=7Pf_r*6}(izrz-d~1-Eb057$l1o34aEPr=Vu@R;42iIPG_Q@nAf7g5Rg$_bd3975pm-{(ypi zO~D^h@P`%r8w&nS1%E`rzoX!fD)@I5{Cf)ixPm{S;OiCq`wIS~fGU)DiFun9e2ao_Rq$67{8a`2p@RQN!P^!5bp?M@!QWEwpD6fG75rxk z{&NL?TfyH|@Lwo+r-Hw);M)}Z0|oC=@ZTu-b_M^Pg7+x+9~FFug8xOqdlmfe3jVQz z)2)E$2a7?R=0`s`r&I6&3O-Q5^A&t|1s|;7dntHDKf_(%mGrQo9#e2ju0uiz&r_(=*r zR>8+B_{j=>ih|Rvo9HLz6)X5e1)rqglNJ071wT{4rzrSY3SO$*?Fm67lyht>g*pT;I-q-2#j;O+cOXK!8Y1ajFX21oqQnKE@Qso1?@9Ps z5`Jzd{K821X?P(3>C-9qOlm^m7e&I8IOfr7pi?rH{D?F$4y7_aw=>RvLXvMV#BTrz;m97cXB;)+1 zjgagD#z%%QdZ=TZ-)s?*H8XC1l^Te?&A7Z6C4jxHjLXXr9Q<#LpXMNjJ&a9%dIUd* z@iQX$V#d#k;NM|;(gYkKh@cH}_j`aoAH|?_}z@Jh~QfpPet(e7{4WgSFr18iQo@2{>2F1$@m=+{Im4p z1Mi*)o@D&K2>uM?_eb#E`3IF>ir`l={^bbX&iGd&_}>`+dIT>$kf5~@d@bXTMDR%m z5%gFD|A6uDMese?Wj`LlA7}i92);YJ@|Pm`7Z~3h!M8KMC4!&-S%O}V;5RV-;|Si) z_)jDF9~ke5;0J$>pr1wX$&CLzf~OdNJA&8q3nJc$;01Alei6aPGyYx#|1;yijNqs9 zQ1^ZWA8{B#zlz|mGrlc?pZ9r!K8WD&F}^*5&lyh8jtIVi@xMgy6AmZnZxQ@f#y^hW z1CAi*pAq~*#{Ji0`0`&dPH*oGe@;A-o<9@8XEDBi1iyvx10wiUg_O=`BlvTSe=dSQ zG=jqOe_AER|4coK*in)2Ut@es1n*`1xCmawQ}g6}($!e0`>s~E3{;EyprD}w)y@%a&a;wVbLCW7C` z_*D`7H;mI;S;C)5Mf7}q1Ygbg;t2jW<4Yp=sL_$56PN zBlzQtuZZ9U$5HrH1izT^TO#-d#&3(@!;hzQS|j*{jNci-zr^?(5&Q>?zZt=6PN4L+ zMQ}o6-cR$0W`1zrFB9TtoChg*Ou+{zc-Cy8&p;*oAO+7?aM@JMkjA{-GZ6C_v;Rar zLmKl2XCO8_FNPwrn0X6t7MvFWS#X}DXTkT5U%wNy&oqoH zEI1F^S#Tblv*0|~X2E&z%!2bEnFZ%TG7HXwUKX4Ow=6ghN?C9ol(OJFXk@{85XgeF zQ_q64lg@&(GtPpubIpRYQ_O<1Q_O;&7{LgLng1FYk;S~R5zK@ir{Loi{A2~6px~z{ z_^Aqhnt~TA_(TOiUBM?Q_+$kyQSdVq{7eN;DEJfwKTE;SR`5~A8Oyk5btQt$=^U!dTP3f`pP3l;oo1z)7# z*C_b43Vxk}U$5Yc75oMTzfr-LDELwZ|AK-yEBG=6U#{RcDfrC_zCyuM3Vw@%wu-Q75p9rzgNNUQ}Fv0{7VY{Wd;9= zg0E5V2Ne9P3jQ?(e^9|6Qt+=U_`?dmR>8la;NMj6Zz=dA3jS>c|Biw`s^IGs{JRSN zn1X*#!5>%fClq|Wf`4DZHz@d%3jUOWKds=;DEPAq{+xn8ui$M8{(^#URPYxSe3OE| zq~Mzse2ao_Rq&S;{1pZNfr7uP;6GIGA1U~23f`{ZuPgW)3jU^ozopH(|3kq)R`7o+ z_`ei0kf)^9CT=e7oqp4%FHsFMDH3Vx7+AFSZ?-yfo% zSeEl*qfhj_*x=FgVuQz(^bb|=!xa4U3O-!H4_ELb6#Pg9FI4am3VxJ=AFbfWDEP4o zK2pJ>=kmt>MN0V53LZVjH|a#r@eO{wlFkVVexia$?*o|h$135+DfoB=KUu*iDEKJ~ zeyW0>rr^a2K2gD=_Z*BJCMn@3D|m^5pP}GqDtJP{rzrSY3VybNmnwMlUWc(m^j?R- z&r#ATQ}F0L5R=YyCHxEpKTpBS6+C*+#N>N{5`LzFU#Q^G`zj{=i$YcQo-jc_&f!lui(`Rez}5Qq2SSbKE`fWD&cDtyiURE z6+C*6$mH9ggkPZGjSAkR;L&?ZCf}=-@QW1u8U?>r!LL*B==~_8PxOA2!EaE~xlzHF zDELwZ|AK-yEBG=6U#{RcDfrC_zCyuM3Vw@%wu-Q75p9r|3B=V2Yg(`@yCx|Lp5N!EF04ttW$SrZf7i8wuB@w5W@K+ zoh4y4PAAz0LJ7_E-U$$T$Mg;cOn}fkgic5Tfe?C0DF2y#JNtgG?CDNA87H6reZZ2w zH*a>f&GvogS@`)Deu0Jm-oh`m@QW<`VhjI+gP zW8v3Y_;nV3y@lUk;Wt|NA`8FC!f&?lTP*xm3%||6Z@2I}Ec{Ljzsth!w(xr_{9X&c z&%*Dw@CPh>v4uZq;SX8(!xp~8!XL5lKU(;s7XFxpKW^cFvhXJ?{7DOc%EF(v@MkRi zSqp#8!k@SB7cBfm3xCPNU$*d9Ec{gqf6c=GY~in4_!}1friH&{;cr{`I~M+~g}-Ov zf3fiQE&Q(*{x=K%yM=#X;U8M~KP>zs3;)={|7qc$Sopsz{8J16%)&pn@GmUTaCz&MU;nxm`SmP(eG8Yj zXSw=+Q67mD!uz8)(_a-SzNyi(p5~Q`%UiYd`_<{Y3B=cN)tcXCDfumpp3(Z7vn}#3 zEBO&dUcwz-!FCoJE;|F_#KXe9)WTo3=-IrI^~>A8B9Tk9ol}U9Sl+!iU{%cs3M)HM`txfv;QrkICareE$YiWME;@cT{;foaC-tdjI{GTlR zeZ}Q1X!^bH^vsVIKKxf~=MF~yaIODWijOs%9#@~4#KY2gp+)`z#iK^g6s_kgi=L7l z*`A>M35u5(J$+gazrQ}rp2D42Pf-34#ohNH%d@{%yu#?0{Q9Hf;{yC&itlLn2HKvL zcII&1_aKX&LJQwj@tuvHGOcGH;$oXd>PNyNf3V`a8a?akht5-cyx~%R?^1k%;df~H z*NKOP`<{}YWaKH?)n~a~IKDB%Culy5c$l6_i~MxOry4y}Jk)1D3qL^dX-0k`@GBLsG4fNj{F4^`nc}+}`N>*- z_3<2TkdIWn!N}KW`SFUo?|q)Ac|!5MjJ()?nBsdIUZUkMQrvy-v-qF;6#uo6r)ENZ zK3DuVhD$kIj|xU%WIw~jzf~w6H+&PVr^Uk0R(!UR7yXYao-lkXt>**9n+!it^T+dprW6j499|8ApO1<90B7dmj2N*rlpShZNm_3V>e2G@2_7q6hrj);8IZmg#?z+X_j-0(vE;4b743M1}&e8acU;a;Tp0>dS~&sz9$)7Vb;ecumhJ=YSKuryLX zK34L-HTnzmmsQhQ&mo2{(R`uehZpw{GV+@yiag~L?r1-*s{JJwZT=)IpDXqU+@#BoV_~*kFKi+Whw>Mh&n~I-ktjfHeBR86hFuCky`$I3x8bkbB+8NT7LBItp9w&rCc>C{(Hms(((%wzsT^Bx+dSK zxcmOc`C9%P#l^cs%t_QTO29&R|G1Q&2E{Kk`h_2$_~nKV)A}z`+ss&=WwqwT-x^%3vX21eJ}aGTF+gIyYICWKd^BF>krCzD}JpBSN!~$#79InSxKvn zNdDesk$+3^>x~}q^DFGZ;ofNYep=z)itlRtt;jF3$gjL7>$%D3k@3!^#79Ji8#@cM z{;^7alF`4Z=BHWoT&egiM*lCh{Jo0Dj2>z()o06DY)??WRPo!49*I|#;&&Lnoz`=d z;#Effd73Xz1-lU5+b;EPB=HfEVS)HgBEF7(7JoEY^z ztBNl+oT`=jd`)~rWW9i$>+j9+3d%rWFO5n0FBKVI`oE%GlY{!~EE3cu!XgSSOO zARd;#ODytVDgHu0&uDTKg^?hirT9xmUhG+@_$!8szj{n@_r2$`GWRX<5s|e5>9)~t zINYH8Zi>Hd^v~1j++yL!DE^j_7dx+1{2jx`>ffGG{5`{^UVo*y`#$uv4tEoBP=yiq zedq^hzO&+gH+l**pQHE(hOef})j7mRMAkIvK;1?4xx*s=q2eDIJ*`@PwK&@o7diqlqb{TZi!o=$v3#C;Ei*!ieM{wKwkH+m$Ui<>yy6$~G%^*0d@tM3OW`IU_P zrds}N3%^hCRgC--T7KJR4%dCJ^jezFSG?ND7i<0p#ohO|OZ&A#lJx}jcPYNQ(IfG_ zLh&^WpQ82uRq>gIi#?;}uzvTw@W0met6p*Ueb${?&&7(n@3W@vg!(+aMucwv*?IzL66<&V?y4`}(}^k8A6&e%Cx^SO!-GhE8mSr-1F;u{+IowS|}sN&On zZ-Cb+9+baA@!>{(OReW?#m5*f`8BqU^#|n-ReTd8FY&t7!ar1eGb1nMaFhL6e~?cn z9+sYG5g!q8-@`Iq+kd;#3%)!Se3=%}>_+TjDG~M~6UeUw!tc0$dnz z-+TTGDd$~|{1Tu1lf(-n1;$QE|LX2={v>e@w{S%#yiK(JPl=C+xbN%PM%%MKHGGAU zxY7SB%`a9wY4~}XPfD?To8i5he@r|q+;w^!zSByMpyY3a8gS7l6eXJ+wA7&|@Hu9si{2vtWGhF=eDC%exM%?$gi=9^~?!M1m z_;&Nd)9u&93nT7(-X&g(6%UTPS6vXUr^dp6PrNYVzAwH~$LnLo4>j@HMDyJbWclE@ z@+!sM_sExN`5zUZVD!*%Ons^;!D-&faM6F6;ztGe4~idScvS1z>0s6q)PJ1f!SU%o z6+h1C*;MP9^;^~x9EaYm_(?`y+RchXSl)f_{B~N;C5oS5qJ+CN!iQ)Td zzQXTVkNbZ4-8COWJgmO&V&OBDo?!d_2gTj@)JysKLh(I}J(6EFN3cCXey!r}``;ha zPfkCQ+^{C>la*YSE;@x_MUr++*3DAx0k;ZomUQQUnGds_SdeU4`NXN>$< zt^X3me`9!s<~tw5^6q=sMgB3xgYr!aSw3O(NIAJp@x}oEN%5utuRWIaGza*FiU-@H z3CFSg^G1GcZU1tVfHeL!TRm<;x0?WT_`1zVwoXGrD!*9@h^^=&l7{0OQ zV=cTv@nF081Mv|N_kDTNF1Mb{`rY@=OL_QM@wp~k$@kq)VfnWL{8q)^HvBAY=kBMn z{JVx1YJR5T?-@Qu^R-W7`S%U4(R@e6-S^9jKRHG5zZ-esuPgpxfbVrW>v!KTFY=El z{;`plc43<{SpIOsrJf$5_$P)-J$*@W_r3F?fA=$4&*w&7_zj9LG+gwIrUWdEd>!Bi zDIS#nLh&z+{4P4(=AO-Zg8u&{#lJQ360h2GSU%{_?^fJ>uf6n_HaVB&-S^r{yv|qr zN27m+wrA9NEbqS8Ui|+JiZ8dK7K=Qte;Gj)gvPUmZ>9M{#ohPXPtrVk0n4vqt8ZPnO@xpNbUq!qya-NB=q{C&3uVwTIA9)eWUl5Q# zRPl8J@^34Cp^@KG+qufctS89FDt@t%FV^x0D89bYFXNQqe_%Zu8eXU6-&TC%06+hd z@N~GBcwuByBQNRvgW|#VuI5sf-^|EM`M*T*tBn1UZeJ_Dg^?HDc^T`u#>iJ``%kv; zMT%c%9FIKY`^<{Rq<~lu3|kw`BkrGey7nR_Ww)qV1MJ}Ygm5N zijqFJ>tFh=Wj@+)@k=i&zK!9M4%=SG^4l7|zSeWF;`bYSq@B7#@$HPf_>-p<5B6t{ zy`J@tG4fkz{RiE^{9&VC+S$j5kBF?ilEh2WZP<*qto@OT#7oPg6YDKivE-maj1Kv$URn zD?ZNf?KHpRZkFHC@MAS!cn|ZP4HtiM2k{Y+0+XJ@wS39FEWc|&{z=6r7%ui)av#f2 zGF-}e-~G&k{jPs29y9V%o)3P2<=-&*wVt-;8^zxY@B{>u~(_Pf4QyxPc%pN~DndV>9~hZLU?kS}_eCJ=#OrRw8v?xi5ta}3mu^sePa`k+wZb1+elNq<(BXC|9_*(rQG9PBzk`;a z@F?r~wc%2a?o|9YhKv0rkFk8*aH*#!Djw`dZS*+HCyacd4)=G8HyJK^J|w=5mcbvZ z{E7868+oZmzg2vW;alm4)_j8HTMdtD{s+bPH(c7UO`l}>cEcsUXDHqo;Ojrd^6MEc z<*ion4Fddn#fJy@Pl^Zo8+A{!{%#{L zea^7(`xOtiry&zR@G;v*nA-4>Vlz>t@9dGF1F1J2KeEMA8xp`Up~xSqX;7eKc(A^_t$47$Z25QA zbGy+a_O~j2hv8!9!-@y%#n=y6&s|1d^c<{supGXm_}xZc@^S2ktmj_Chw1oUN<7S8 z-K*q-<#6ObSkHY%&-Gf*Ly8B>;rbu3`~yZ_?2jwH*lQ;tv}=67K7YFELzpY|Qy5>;I$SB7ckG!Sb;3CoKPHK)zA&VEW&y_+v(1`UxBS zi}n1;@NIN@9-;VChOevnhl)RKc$MZ2pR%4O4KL9AF2$cUT;etSGnNmga|`jX@~}k7 zKWFqvx!U-1*7Jhl;ve=^JQ&~G6o1jkkJEOJ{DSqoY`EBYk>alyUZ>^1Q2aH+rJPiK z$$ElzUZ{A`&UY36v(Y2zJnbvi6Abr4#osjYV&^Jfv;6CZOS`b2;%^x){e%Y;58A)M zH>@Wp->3LHM$b&04zE~v<+rToJtM!TmcLx__YIF~zT9^#|2M<8)x28qpq{%F|G>y^ zspU8PH|q)NPbnVMf1lz(J)8W8$I&BK(rP0M<(KbSf5PzhHUCcWCc~+isn36YVELrs z8)*LbA6fslh7Z?#^`DrJ4)9*$g^^E9e5KsJtN7=JOMiGqWI2-WGe+L- zYQ zQhb`>V%yP*&oErtsY?~FHC*H$R(wOlD|O_WXhYG6NWI~b&MU0N>9)V&(ym>mc)Q_J zzhY~%y!*cUSGE3c6?flvPu(;1xpf_uf70lYeA#DRwr3B+#r{sk_X_aS6#up1lFs)i zzMtWu=Y8VxyEaAr_{Dl0ZlRH%ufIH2@dpeS{cF<%SD2o0#79K7GV)T+x1@tPBO(tO zF3;8|{z!n&Q~Zhmzf$pQ0{kPzuMhBzHsEmY4e-f|Z)13ij_-|%Z*RD?BhM?ogW=LY z|6K8?;k#-*WgBw1rG{Us`5THaGF;LjvJuPQ65yj0zdgXGDt=dhw<}&@xTJsG@bLVa zPkcn=S4MuSwsVQ%I~!i4`L~LXH(bhp;l`|IlHrrJ{QinhF~Q z(UHtgGkk3=zn|i#2l(-dpAq19Dt=~w|5fp`3}0XCA3lo1Jv+dsD}GLZAENlV0e+L> z=NT^fGI}f4e}Un$61hn6VEXSqn&mGv@>gp+A5{Ee!$nWk*5UbbfrUR#yfAW!(NnJV z@3IZ^%M6!s_oKu|M6NP?jF$gK@#_p9ulbJKviyyPOFyJV@tX}V(DKJCep`UwsQ8@$ z{(|E71o$_K-*33|w?}Qq_B?3#?{v7=DE_SBQg?RUp5>PqF7fSB{87V4X+38v{*2)g z?h?hHH~dsBzxSBsA_e+)&yUt*dwbWsu2g&T4lSwfrX9K)cW7#g#P_LBS4YQnwOVZA~_b;<9+$uPNTs*4fgY zjMWD9kqxdsyIgTah}Pz|p6*1tsWn7zanz&NCrQamY1r1)*4f5M%BfwFpqywTQ&RCn zs>OljZ7rQ$siZFnSaox9PNKIx9j8a;#=E=P+nN@{SggFItBWF9*`4Z2cQy9TsUA1C ztutLx+>w}{`TMrc4BwZRW`3T&w>=*%n%kS%0xe;};KV4R_$5;+b~<^Y>C}RFx(iWJ zqPeTvNrJGbS5mOaRA-{Sy0~KQjJD3HR9us(J(H=Pwyw@8U8(A}##AB|o^0@JdDyeH zoV-n;Dds*}66HthlHJKfI@vs>E!o~Y!O3GXpuX+EWIxYS!qjvoyXMSD^vvx~v}CS? zlZEuSxeW`tlUWExOXtq)O4lZu<|do75ig!w)!CP5Z*zr9*{iroQd~TDVp}JtdMeeG znw(50+S+@jC&M$Lx};Pk+T>(UQ>v|-YKBVoI2-T$Goxx|Xu@Ri`Jyt#k@icv$_|Sr(mbh5K)L3Of^3UmNijURw2Ta3yo za<$4EP34oSOG@S{cQUbe4mCBiQf<^&%t*|4{;W=RQU`}?_&zheF042@i5luga*4Cr z(yjIBM7p=9A<@#@9;@xEFOJ8e)SsxWi#0Ut9iOtt%t;MZH8bOJZl0n=ZeOdqxM;Uj zGD#uEJ5&P4I};tr9tf|vY*Kq$vNJuQXF+FEU9zW}>SVG`wO~~qRnelU+=V0W-@YIg zbId5Un^8)AhaNJTx=-BqXd`ERApOaNvD^`e;28)l8*jh%;~VE$>5Zaqr^|8 zIX7Z`Lli`G94C2|lTcLX63vNpf--uDf}@(++15k7Nh(OSGwb8!PVveR;BM756DL$t zmi9KrtKz;=R-wyS#mwZq`gCt&tZsUJI$G4znn)#^?x~2=V4$jrLW1c%; zL@f)YZ}5p5&sjdvCHgN$%An87)@cS{F-C^o$a6 zSmYRLy6cmj{`wpKK(xYrU`Dd1C(&Yxq{=T>vuXfpx*h+_`X{w_x#ia(Ys3+EuNMu1hxc`J7I;(ZyQ5V+%i)N&UFG?k1<@R2kL8RkVT_cRp0D^xB?LJm^ZO z>V^0bQzA_yqa}_FQ)!Ujo=kai))guzyXupvJ}T>8lZ)c6UB-CwHbrrtVmC$=T9GFW z1$x4dR_;c_6+JLy57LtCq^BB9EW!l58p?cyH}kioyl#3)F%Obxjzvm+`~WWYG%Z0M zqOmuf?BVeJBYXC|Vg6NOnXSAS7$RR>B>uamH;vw1dFremkPsZdR{^~)r$a*)b8Cmr z#m&5EP~NW3>BWWVbLM@57C29cM(m?W>lrQKHqbPUIfxclCg*o2Q*9m8k4v=26Wo=f zUYBlT^QK5LJk0n~wmlkR2d5ELe=b<{>B>2}C9ay%=d?1~K~rNWW_o>tr5DUv$2oSkHxwKN9AoA5Kdq_f28RRy&HM&3H$pmla)_MjKQr^We>O3l8=SfX_7nR%jX=>k9 zzpz*jI>=G=5LC=F5HaPZKIi@yCH@4SCX2VW(R`gmPxT8Wqno;VJJVH}b9BHDdUGMy z-s7aQs@m4RSgavlUlFGwRbq0px3i6s3;Nw|Yv*keV;onR;B8J)PbgW%LrW^8Ra8Vt zIS&w=sv9jDyjnM<%KMT{G|g7UB{qZJK;s;0aS2&WJ?i>$Wx4e3hb#y;7Ma``Wp0fn zPr|&8@}Hrx3(XI|lbp!Y^EBAlgQq;XCs;*Iyl?#OtxCa~YSXCR)lZ1mPoiSirz#?w=*<~lSCI;Z>e2XwxR`tTs@|LnILr{w7|c!z z%j=TeX0etcpgKZ_1#>d2%Jk=nOfFgZY*w2{`k>aDYNGof>cPaEAngY3&9X z6PkW1Ay-)%_xRX8m`jD}y^>P<9J`FtG8J61HKf_dSHaCx$n5h(125D$7F=I6W%?|q zdSnZdi>z`>GrMZKtE$^dsH-uPnsxfM)cv*0{k5EaH6spHEC;w?K|KmJaqaCFap-Z= zTQ6nLWT{6DaWz*I=rJwD9-Hc!QPKR_`)2GYV$xlqu}~vTv?r5sUT5Q7F4W4Gb|>0W zRnwi$8BU1D^l*n7wKQ!ul1DpvEt-1>j-M(nG2f{DNnxsUAAZJUz(T$xL*QlUUYet> znpT^+YiS)jsKH!GoO*UnS6UW7Ob=;jdO~jhhkIb+!FZUKkG>ucicCFpH+My85Ka4- zI%pEi(n%?7#+20arTdGU3jGftKS zACQ*|>&@m^wj^Pcr`)NEKKQ2vUQJlAMI#Ux|u=;Cys~d|{JD{Fl8rco8 z4-V>m?Lc5gz}o(hR+#TC>FA>E)_HD5d8(FMOlmsy^wQv)W-hMcrL!&$_Hx@_QLsPh zDF$STw-`mk(!IZ8DSd2RGTq+AfHT?F9n8j9d(>k-L$h(t*%wSMF;X{uUO&6q9t^6# zT<$l01DQSOWemsd(yBq3sT&?YlvM!=iK#zp^6D{ooyb`xs%Z#xf%{Fw5J#;BWL!w= zXoAHIT1a_KgR^fbSjEFy{$M)v7uGZijQ01%D5%NZ_P_>J;GEPlDdqDJAq`D18oJ!6 zP9eqWn(EXp#Ljsg zwe0kp+iAZuxfZI~v}u6kKLPE*#jt-7}(*&ORkx20&OncDZ~G-_FCm{iOYfthx?W~HXs^ovu;re1YG zDc;VB5m)v zo_my~BzUaiYMPH+&{j=H<zu-Q3ZXcsK* znhQl4S0Ko-Q+C_7Zb3!Cqnq5W$TPP<|eE3^! zgm$;CDo?3o^kZ0E^=X7+I8UHa)ImKvwVSRi(90*>(TG&4Q}E46`E`d z+v5N*Y&x8lOr$IpkDE;Mzio7qUDx42T&br*kN4QVF0G%J=%y(zr+!H#aFeQRPd;I6 z37qOuG99Ob?^IG^wb6358M%>KUd>E>!01#q$rIsu5G@t~-fm?JIpjPHXOY*5xX}nZ zKf}3|gM3pTr;=k&Fr6wJDH(hQyREg?y9xI@HqAXHL>LxKx0}Q#M%6L78Hw)V=x)h$ z@VvLjAJayS4!X#ots~Jb$I;+qRE+oYrAyn%<5$tIYCowg8}nC$VzJUW)DMf*nF*Rf zD|EdNcY+48blu5k&%_`;RYn!jaoPh^*qwHs&)w@N7tqu}=IE`+Y>ukg)D(1L6A_+? zC5e=$$b0t=6&G`TYfd)yw#1#**=b+~;hA%fBKPK{Z>H;k-%5Shm5y(qeL@sYE>c;~18(EJT-AJJzFq3vgj6cAfYSmi zRqpA@>j0+K(Q3Nd9-udC@KKI+SbE zT?WIJrDAS*6L#bVogdjGP?PC1Q4EK2Z;a#IoU^P$9F*(!hB89k-A=)BdMe)2rJlZ# z_baTy-ZQD#Khh4#^Jtmh`*V#qLo}&lf?*oI!cn zgl4)?BUW3XI;UOTweGp?Y_frFH{n|XSc7{o)jTK*_MBBRwT5LlqhM%>2+^2L3_>2u zY`L?6IC!u+)Owq6XbddEQGLe-CzU$G4PL+`ljYfLQo!%ISZf?04SPds%S%cGZZpK+6n^n$Pp6w^=?Ax*}xtHOA@C>v+z*m(7ZVd?C zrEK?AAsVtuExT3yB$!U-!1V>;Ro*5Yo>UfTT7*&;>u_AGW!!|5-}OZ14GTV(wQEt<)DnO`!W#6P-=1 zvK>U9oft6U0O*7CXP z*F`ZzzvXJBOz9K;h%JG_rNx_OZBd3K3J*c*XZ9iJL<;Plp+XcMM6`4Qoz+7;sK0ck zx|XMQdS9*DE~Td%gM#Hf>aJ3B8X-axsg2m9JEm0GOe(FPOMX6cXyZ7wC-F5swgB~A zT_L%nHUNg^kMoQrf3(7o{ORZNFC1-pt{c;rgL(WurkVcUnnTX_l0!O!f~o3=m1EL} zi~UAA@&vS=@3`i$xLBXGW~TKCcH&N0p^>#d z2fobo=$%xIw}dJRNRPcoH`&!M~SoxXmi3#z2O@Lgb`yoO9j(ZMS8N&T6^E#Tm9 z<)Z~*K6*wc95UV)7^~qce9Kcwbxw`81*;uf$*P8UtTfFRjn?O zj(iz3U20v|+Zn4ZbrxwnmoM^sk#nW2zFbpXdDxY58@m2N;4(A#RP@a?SPBpC2;_^! zeYuCZOgR+)^o><@=)8tH zHRhkX2~**7tU35#ijtaaB}4Ob1*Y2a>SQ?2MwzL_Y;Ie0(%0Ndm>+{wo*9GkqSJM+ zIYv-CZoX0*^m*oct!0u*29;ow!dX6~k}$`IAdRvMMdA`xzExZ5*zTLzw#KxdEj=LgwH<`!7`m79Ic8JZ88Z`%fZI&05HNMP1+7}OJd=IJZZ>~zrnl;=e2FWJvoO=;kj>*OXGpNW2qDAUSvz2j)qJ1 zyQ$TgpDRr#QSTLOBBQgtT$h))oV73gjt6f=4#YjA4hNeOYI40P;SL(Izc&{%%5R2r zr!&b&&nTlz7G*Khe2@_ol)?)5RTy+_#KSzk;XOgm1KxA&J#p}}nBX}c`78 z6l)b2NJjFj1cG%W=h0hn*oL^=?V-5M;P=tewU+M5&HY@(Vbt5+WOJr(=*J(1deuSm*zPZdr7OGA?nW5Mm_ z%SKL8YzOj?q|qql5uMfJ7mB2uxkD}x{%vQzDQe%Ixmc`;EY0hmA=?C{JO8{i zF~k?_x*-i&WT3PSab(C@sEQqL=yvbNR3(QSBYH1$I@PtHDnD2Gs-1x3;MrSIJ41&6 zX&59k@k1O>Nl~s2nJQXv^Ik~(p}G-^xpQi)vtOr>y<+qW)Yj07&%8vcxvDO38D>x= z-=Rjg-h{2r@fk~JdCqBdqUE$yqu)laUyrFyW#%Du)LoOYac&bu_iekI66HO(k+ND6 zpe}cym^R=`_=c~_D z1&Dc)GB&BIn0!=!Z$9%0EcF+C6uU3_a3_$LYAQwhOC{*0^s@?)sfR)nc&3Nq(Wr`< ze^x$|ChCENYRWi~pGl$BG;F23r7J^M49%mS3AD^haYct);VftWxgqynNJtYS6B9kj zct@g>UZc%#dKq}pEDNo`w8ZFjPE>)3c`I0GJ`C$b@kH-@SSzBCX=mY_L_2ljc+JSASRHJr%m2%nRa5R+uu(a)G~dxI+dcC63ND!|Tk4T93r$143gqfnuUTAb z;YtT=DWohfem6Vw+I-b7zn@$k!5I3W^>%LV1mu4SO0Peufnf$G5?o!Oc>7mU)qFNJ z>b&NXizAt?JqffRL-vX~T!^Vq3o+Egp*;hhMHnz7bd@3>t7aT5ti#}|JXH_Yd6g$M zxI?#8Lvwxcrq*QBT)OSAlO|G~OWKDpMBLxwrg2AGo|aVYNviIG56Mb;gA282(X!?? zzCfFuSKj)h_63t~pm!(KHK?Pq z>{*6-skWk7uk$M#`t%B|Ui?cX)2*qldD(Ulvv-@=z0KI2%U&hF@+CJ%?Dpt9i<%+R z8@x5Qt%=?sly2>6wsw3&cHodj{dTLfk7BUH*q^P^7wcC}_hER%<8SBuJBEVx!logb zZ{@{j8p^rvxFL6x9+&J)H1d06=Tz<0lOm@}gFjkXuAQ>ub_>TRq?(Cda6>sbzWx0;i#`-u`=3j+ee(c!6w)qA}4P4f-l18WZF7)!u0Ik>!x&HQvR9A+&vx-FEsa#P&(? z`WcSx#gyI3zt9HeW;1_JyA9gg`RFSRon`-vFE$yLS7>*RS^Z&u5UhP+6VUzbSqL4_ z=B_AgFqXZo=x&M3740SvC+51LogG023 z?0+sBWP&c-SA+MDM&S>ix8 zn$pep2e9vNaK$^PeSfCw@IP1bX(f?gsc}F& zooI={tBguY?FaSg>|$yTU0v%d|DKME-k2bb@nF@tP2ONNg;(`_xw#2HsKn**ZhZOhnz1k@rfv%*1hMJ44G(G($T>zN(pH3zvD! z!1YoM8)tUabkiH+OK9R_CQa?qug-hp)vskPb>17F-9Td*u(bcmu?!fQRq0+9?8M?Z zzzy`Yfj19(_@z}Hpb`C-3Tdmj1T*$*P%O1`3tO&H?6Uw1TeLOr^Pd zQN?|;&V+v9i|Td{w!*e%BGeS-B6&` zMG~}ysZni{(hGLWYUFq)CLdPs?&1ifc>NjHF4%Zphx&O-NmF~(G(J&C%c8U(OYcIZ z#(Q!@Q+p*XQK?tTHCI?>d` zZ$0KMhU0jD87ZC96^qq1#ChqXVNi!E25~CNDLCP#;{N(vk01@^oQEU|uaqpKC7Sn0 zH??>1t5dNgQ@K_<^8Z`wDc>2Sw+DD5*1zw8nIG@sT|Z~U26X}?MzaN!=FV<-s#!me z5lu2%H8lI!>7A+ZR9j1Hnx^io`@DxHXxghnd#C373?Y*fcK5dXFCC(dP>$akie2@b z+|Dk7jN8E}D?GPO$)!|I;rHybSNjI()IF8d!ELnXEA_1<0CrRjV52=>Ye08(>3d{` zc&9zZgWG$Pd+wnN)fLDxCIj7R?~iKETkX}p!jLPODAkJe28MVWb#oGQ>nTr>Mfe&lVsl{ z`{2RvAEcdZ^x@l)CODg;vZ-^yop>3l-E^*Z>}Ne5B3SXb$_zd}p>Ie4PyRFP@^w0g zL%-3ylCC_B_t4g1XU&q5e8~2+yO&sUV8=3(9%^Y2dDrLQOPktBO`hHfMz^)JOIvTNrqd3pMJXn8ynDO( z9#Y!RO-2Ns&4*pQML$MYJn@k}XL~p8+??QCe@5*b_XMC$44HR!_jr>X>hOn3j=Z~= zJhbdVmqvNx-;u045(8`8;YJ8|o+FF*8mXNM=HZ++4)=ct#5kvb>US{JPU&wuZ~q!q zGeRlk_A{+pD|rufcoOqHAzAh@2c%t}xd<(Yc7+)lx$H`yfB#I#i%+HV>%V{vTBvB8o&RHqpnM=LGQdKv7DXtCrS9`d3!RL|GVh`Q% z+0)yeruQ69)7Jtxr%Y;Sf}d{hte=)?k!LW8nx};mGq;w<`$l{-qn24&9&!4=>Thz? ze+fMFk!jpWr@cCR+uLRJu!`*}kDt$F7>d^BExlSuzNcIpgxotWhw zG3QieTTgeFJ_O7~!!t=z-9eL(A)RD@KhigKOJhH2sp#RN_|zmFb93I+(NQFC-7>AT z@3O6!nrDLNeHIlBVp>!-iv;627_D4DS}BS&{x5fiGl70RzvU+|)aWl2r}475bI@B2Ms<^)GREG;Y;IvlsKjp3po|*8|P+k zI+a{e%uT&n)=+*fFOg7_d-{$9`zs4L!G?O3z@6EpiF8%WmWs!5XIAOb65aX^&3vV* zM3kdW9u02*CSs~xS+^W`}CgtIr%adc0Jx-~{!y4sLRw55A| zhnu{I`}$($5n48xKC`@~tE;6wS=pWHN_WwXh!t|4P94B3nz$gHoY>2E_rz-XRixC{ zl^YV4>QFh;ZP|4BvblhPvbDsFpw)&1r?2N8XY6l$Pq$GHYDXBqyMXr<$QDi-ZP0BZ z#wNOVlI}F7rCfR^T@CdyYiRcYzl_5f?oEdt(g60*cyDCjk*OJO@-kTqzXLbZK(rzt z&Rd3*X_Td;$JUE|Ca72l9$K%IBB9ocl51CH0?p?q~RWL)L? zg@KK$2KhXA5wnNO=b#1}HBjx`77L|t$i@UR{!j(0pK)ril~T^%wHx-e1+QQ6Wo=NI ztu3HJBppp$)f%wA(92k`$`4s$yWL1V2TM~a?maka8GR}A^5}wXrwi+B9SG^@scdBr z?tG^vZ-%V*$4m7wS{s*p&?d*-tJw3@{gX{rS0rOQ@avA5X`RH2laaff##m* ztX#0Y7etdtQO_h)c0MYDLeiGWb=seFI*5aK*7Yws?N!Z>mhYDAq+VB(biMec@pM^C zE%%_DzLHwEOT|1#7JP4R@LjTyYd>rzx{U$!6gXkSb@`cfqIZpuGT#OwT1wCkEab~P2Hxy! zGvnCACz)Nyd5au(o}Dd2+%GN?r{{}o9^=#9?QEM<5yGBGRz)^g;v5$kQfjlRWOje1 zU8}BO)BPj2XjBi~s;L)WTxPseL)SjZRM#Zhc2=LJb)gQvT8Hj*XzMC2k}qm{)7`yk z{dL|O8R(1m+j9=4rsKukhSb-d400A!H!bz)trls3Aigbv%(sSSFu+S)#~G~#PK|K~EdVoDodDBKgP9oLfT zZc>+K*H)-sySi)DPBU*m>VGZ;%JpS~JXK1SIc%g>q3`YInh>b(QTF=Ijs8>h%PKP~ zQSTu2uHS{cmXv!f-jpAjfMhXyse~1}t$b+W6)mdk?bI2Mf_{t*xh34T*RU zfUKMkUbCFo9!#v&Yuvf52{>0@YqJcT#c+$Qtv9p`7&*Z1%rap4VEZG>Kooo(3U9;e zE6`M(^`X80){71MuMhwIaU5WE`tOhUU~A)le+qq$)$N@=e6MdsE4HUt22O zn`n0$zp!pvw4^@W+h`8|a(%P(8-0?+Aw5VshDQBdK18hbDDM=u%*|b4|6-JNc_~_^ z7RM*Fx6zbtb6sK{-Ne+_1`WC=1n%NEoo$LpNEp#^vV>LD=~=;&?m@I{QWsrIl;k6{ zyZ0vP&0H8%{hq$@RK8rXK9Z<-zu_MkVtclXvDK)Ln$#6k!wedd~)W)rR9BX~CCYGM{K{>x=R|Ks{}A z9VxvHQN7;XxmuP5>-lixjATcAPG?nrJFgwLVaA&?Y3+vEDdj6^n@Ku3pKgJ4W@o%p zV$ODL&pSMv*wEto&wHb9NK(;G@V*X9S`CrkTxKrc2rXlo8Y@me|DuTu+u)jwjC#Xf zT9QdGys5}L#TyMNVZI!*z5OjLykhMgoENTesJb)2!u3AILo@NI(yc!86trVaSZ~vL zgC$r?IoaMubC45w0+JR-x@m71Es}5#uHTgON7&cnl1$GwbJPweTLSZ!*xSnP)fu6M z%&#Uaqfv%CcKyk4kFP%&?g~Q6=e;MB>295&a3{8`a$>nB6;Zdf;n#JCHZ@M2$-|I~ z>z}p6+h*G>&-g}KI@iLq`y{g%lj%z188PXt$4&tX88O*6{fX1@sDlAmeQpCVF)nlf zCSTeHVEwp*Ol^i*zR^eOu#G^MkoN(YIP-vFsHC25n?HiS1*g!;ZSA%Nl!e?G#u{lu zS!G*SkGc?|lvfU%-AVE0p00SST96DAa>h(*8iLM{&2LMykav8NqkFD&mKbWfoil}l zQ&u*ixtTS2R-yw24#~>vfEEs8GpFy--WMYm=BxqHZo;4G()jim%`4D}96AD{_lo}(Au}bUx%3j^R_WkFq&=MW=$=<^nvWZVcVIW6tqfxrfS0B_(IzcJ+s6r?^?BGxXfO8zV~E}NDNH^E;GHt zXer;p)TK@>_+S5NDuU0&NGAP^Lx`-*#^C~uOft8XC`@CE?1gENk-adDHnJBcn?svq zUn}pkJl99a{#+lSSY&u48@G-Xw=Xt0r|z^RmHH?lG!KEpgt`mvZ3aBGUM&$AFT$HP zqB%4#L*py*F!w3vhP(z!J51_@2;@sZ&*i{NfxiZPJ>VY!Umy4yD{!owc%lAc;N>8{3-EP-*I4*In)~B*I>=+V zcLA>i{ht9x`Hfhywjbqp2EGK+c{1>wNxzhnUf{bxxW@tC75F)t^A9Zl*Mt0ckiXj^ zzXas5yuAYaVX*%_;7qq&GfTMgNa7?$|HRtqaT@tT7LH^@aT>cx7|0nQf;HYP==IpmW0r?)#|1aPq zratWc*w4#nOZ^M$9tG)ejOJ|r*1*rO@CP(!J==gh+s7Z)LpZV%|3RM$=Z8w0F(AL2 z<|3cgf7gKgFF`&5da7iELGl8$I^)RmkzM+M$Z{eF* z_;3qHJ26}=pL>HnQ?wo~=lcNP$fAD>3*XejrCj;bAy@fa({mKqlYn?(xcdXQl~1gv zSgxA2eoi+mpIyMQd`f=#<+lNO)H7CdPB$_$ansd1GfWHYG+o_+R-%H{qeO6%u z>BD*!fSyf(W4y-bewshrO5hl7EpYU23E(K-4jjwFLBLV|Xy7P6TE)tV*TE34H8khw z9ZFpKhr@s$2J!`(b9}MivN^~f3G!n={wUzhAdh}V{4?8w{Cbe*zLS*O`+y$<{6*jk zfqww}Sm2vOdDsj1RNyFo2ym3gaoKU8XR(&&bi;Ib9`s;*U$gMxx*YNkQg6y_4{)@n zOvjhQ#d14YbI~K|RSojkpKJm7BOqRffIRvi>{np8Nc+foFyAi$Jy?Ht0{_5cMu`{B zJ52=sTadpI_zA$ffuEx}+k^Ra6>zMl_X9^e-vj-m-i%wn0(tZ^D{{iqhkqOd_N=41 z-=58Yqdg-*59aT77T#vz-4=eW=6-wbweaVFqn&>Rj_Le0aFkyi+IN)S066-|Qk9xc zdfo%+iS7RV#Mjhv=qDcl`2zht#~0iEZ8c|e?*#c-z#js>Ht*C*TD-T)+Jz!Jel;9`!s!T+*iqZ6&{sisJHT`FRooIi9h0A;n+w*6z=L(R= z_}-*Br*jd==Q_`@E9gf%r61xiZ?{_H@3C+h_pu%_Gm_TzK52hxWe(^2~45_G3S%6ViDc#24c= z-op0;j^X~s$KTN5%6OLl{0oGO!jA>cc5bHo$2d-BzPIM* zf;{TK*utL&J_q9U1@ONC|50-;&$jxA>45z-vBjr%i+223x(&;=B$|vgI&cg4t@P{oN=gl~O#h!OSp1IVEU+QwoKhPd&H~d`Y zRs4Jcqyy@~aS+R~fJMu>SQy&%VI1f7JvW^KpL*$NtqY(0@6|V|#rYaNPH@ zSaZK0!}K2x`q7_YKMKbM8-x5v2p4$`aEvduN64|gzA*MA;WDoVj^%tNa7>?C;HaPX(uAc$orTu}7kfBf4I!NE+ynSl+J2Uw z1zg%e=6eC(UCXncy@59Zp9;J~bJm0XB8=}oAdl(4FL0FK4>s=XDV9_t_8s}pd z$QOVf97jmKWBG27M?a5#rWW)dmvID_hXX*5lpp3P;8-5gz%iXsKlV%KfqW9|nGgH` z;C;Y{21U3z!w6K13wmcC-CEd z9|0WO5vh0ne8Kh+*I#hH`gqVk3iO{uT>8%#uaiL@?Y|H5QT&GAo{d5Osh|hf(@z0D z0pw2uj{YCp!B&tz9pn!Neg<$!H!fFa0>2RCQ9t^Dvp^pG+u6V|ojHuNwBCBqkK8Z+ znwGFf z{{S5OKUV-pd#(h&8R)_G4(t0>Adl&PHSjG!4^@lE=3EizgYDflAityYwVDsS7C5#e z*8xYreLe8QK@ZxGzCdFda&Hy1{~{Y0yvh#JAjWSJNU!);Jh4`=es~&`r&Nu-N5%?CG=r_4{-GJkHsGe)+eBud{*^ zKmMBI+pOcek&j=b`7eQE`JV|K_j@#I&W~ffdVpiRjsZQW|9s%6|3=`Lo_B+OY>%*A z!0|Zxc^n^YhwR}$N#DMqrfrWpSJK1 zf#bM!WvF)r6tK*1YzQ3vQWQAq*$p_3-(`KD%NyFcFUTX8^?jB{{bztY+IbW34Isas z1dj6n=x5Nceh>0kzcz+?gym-p@QoncO5j*N_Xdvs7Wbu}2I+qy$fLi#5;*$XJAk9V zeH1wQ+t-0_2=;#p9R2VLQ14y?`Hg|!4ECenz;qZ7@*_Zgx~2Zg`ZJsL3kbIx^kDwt zxeu(5$ALWBbD@P_ZLtUEC0-|cr2m8ckhg%3hI*H;e#qO94h332y9MkIqdo6sVGoWI zZT+9WWD#y5#P`o2zb){;fjvh6|2xQ^3H$@#IM0Ul_g;|4`itX1%=cG89{tbT7XB4* zDz=gDwIBZ8$GOkPpS8fBV7)5<{vpH*$B&rK)gX`g{u|)`06ndmvw2wl*H>0K{U|o^ zjny20?IXr(v`@aj^;~REasCkJEk6c3$AbQU0^bGrk-%pFKLYr^z<&pPF7U&F9}WBy z;5d)*FW@nd{}lM1z&`_?1dj2-a{f8Up9k_^0LS#S^-sP6`CR)aV<6mbLC*x>X9CA` z{suVC_kIoh7|?_BjX0kA4&+CJ{J(*Z1diu|aU6%d3gm04KudoH!~GugBmWUN&Nu!9 z9OajzJrQC0m$&d0EPN#kUm5rg5U*8%WBpwXING^7aGa;bc{W_9!~PYPhczsEegPcI z)mp%-wf*du)&{;8#0%wHEc_7QRgf=d07pGn07pCTwD3)V`UV}-W?JV|S zeL;J+2YGBquwR7oV?Z9;_g?~^2j5V}TzA@!lKCFpMlJ{9;} z;7QK>iBI$CE)G+uyT+WBYpva9jJ^2ln82uo&v^ zT(D;k;0FSq1^hDLdjh`?IL;d{v2f|PaQc&)$Qk?(ecp9`sC7n0Pins0a?TelzaKG~ zU)lsX_uYh#0FL%-W8pJ_<9gP9z-NPgxsR9asRw=<$bSR;TFtpU%!hojozr{_^q~EC z?=IRY>vXIi*YV~46G`W-sLb(4_Cc}y>0oC$3(|*w;5t6;Yr^&GSz2Dj3-rtZJ$Qcb zK;W33CjrOwlykJKAItgm5H8xY7&xw{%l-lW8tr)xeRcFDBLym z-=l%=NL=bQmbd%B?_v38dqloK>tR2J{acLJ@4+5Sw;doIFkTmeyy)k6m4Q6QYjxrh zuR?7P`?2LAUT8mun~VJygFR^f!(b2EzXUkiUkn_};hMm)9996Y)bZkU7zZ5F`41L5 zF9D8rUJ4xTybL(nc{y;j^9taYFSzb6dN^PHLiS7gOT3uldN=yve}FvZBgaehY(>xW zhxJ?q9Mk7&uoLrj&T%uiL?%@t|Msu4jby-vRPy|0kdy?f)0> z0?_{{aJ2t(;AsCBz|sCMfuo&wf}I#H<|BrS9K%J9;UdRy?}BhKeO>`OF@0VIj(YC4 z=y?I;QO}FOQO~^=J@)}eJ@*60bbA0errToRm~IaOM|&Ouj_Jeq2g(QSc>*}GK@OWBOou$VSie7Cl%#v(fW{ zMGv+|+30!Eq6gbe)MLx{mq1T8`HuO8`HuO5`TjEK$9#VUIOhASz%k!n1D;L1{tWWj z#4FeGjO7#Kh2JcgSuzx{X6kL5gH_1BgTA3(U64mSA@E%LT<@(+;5a)Rx0HsO8*dbZXN@VM_R z>W9d95cd_I2Ye5ZzXo_a@J~s<=)rxw7lHhFAioIsEx>Vp`)&)zdATz|56-`x3p@#W zt_FS>@Xx^h^MPLo^0x!O0eG(K9krn63kX;019>i0H%h1V+za>}V9)P>p9cI) z;I{+64)|@r@%}?zbCdkV_laP7egk^G2Rnbk2}2+Lf$53o!Z1Cjg8U^AZZq(kf%gHw z75MSM@qFufz_Hw3tvT1DAHe=QK_2atb73t1Bgo^qFx3Aqi+(&8hWh0^sb7EL3KSrH zm={5Oah-y2WG8(-Wm^`e4+qa&&fOF-q>pf3cm7aP&VI z?g1dr{7W6~aln6qa&kFvJfFB2IF|FRfwO+;L*x1v+Vd-)yrhGyPx;fK4di+9OY$At z>ldLsoC)%HUh)p$c>eJv;25vZfMfcs3H}7rXEboMryMxigMJe2=>d7P2h$n*E!h8A zLbA{|EamSii7;k^ns`LAdjQ zuMGTT;Hv& z57w7)ATRw=_LF#DO*QD}KAQM}Ujsh^`2N6g-d=*!}%j15YIqF-deaHPgDa~0P#~qTt%yIvW)Gy|^5A6(#p38xw zo@;=kp4)(9|7V!yoSs`ix{U&U3gmAo@UwwW27WPc-0z3uDct{g0?4EOHKDv=Is651 z>=$7^Vz{I}va`;|dTl4CGv;F_*pK=6Tad?mJOMbS|2d!s{q{u`{s?f~Z}t}Ok0E`& z0sa|qyiWuD1Mc5L|A6PdQO`cmzHbZqvE3gD`~)q}>A4o<%S)gK(-ZgC;kf1pkViY$ zJ@?3eb7IkwkRS(rY|vAs?z>hN_S zzpy=R1pOz0Jlc7#=3LIv&j0ssKdI0E`!^>Y{@=ej>G1#l%}IxB{M)+VmnMM!DF(kZ z7x*5)4+K67_+`NV|D1y3|LY-r{{NhUQ$GLO&nf6)uJ)PO)*siS`sM#{ch)Aqevb0P za+Kd7NBIqNl;0>v`QbUrZ)}mbt>JdRIuoqxL={6?!b zl>3=D|9KE_od3lBB+h?c3Gz4&y}`n9KIcrZ2j@R+>%W(QJobBW{_}JQ7w11^zJlY6 z^Pe|?JlcP!g=?I#o^Ap8m5uzC7J0VyKpIowhs#xz(m_52`WKefLrq1-14s3sp z)Qo=|27Dy&i-C^hF5 zRV&EL+8^_Uz@rTGN5=d7wXCV}S2C_=E^ANBp9DQJ_r?5U;Ig*Jd`%eV%Gi*(yl0#r zlQlc$r64b3TjmYGrHn971D82c=4Sxkk%9i)3VbJl^z%jFI|Kg`xU3EF*TZ<=OCPph z*4p^*QsCnm=uZRi2?FV78u&!uzXd)C_&LBQ1HTh^4EU?SrvU#J_-?=pbQ$J&O$9z4 zxXd~8*Rz3(?`7TwT;?{J9|>IM*qO6W<`0J}Yqk9M65ul#=+FDWYXs8I6}6vZJ+jA! zza9nL_!8oif!DF1{xk!ZIavPcNZ<`3Og}FJz6bCn!1o0HKJZz<`7T8Mu>E_f-<*He z)J~cC-oVEIm$eE0x(xWfAm0G|H^9@t_XBg&}VA-2B<4KHx_Jmo;(z z`ZD12L4FDF1;F12E@OQDdc`#yA+}%o0!&5$mp&fz$-rf;gn27)S@UAP5cr`C^yezz zhY6&gHvvB!_^ZHw2mD*$M*ttbrt=5K>qy|0z>fmH7x1Hj&j)@C@N0zV%3@LxE8u>B_huLOP~@V$Va1bja5lYyTD{1o7K0zVb_tH4hK{w{Fo^Yho= z13v@gH(Sg3gX483@U4KK1$;d4vw_bBeh%<9;O7Eg2weKM{Pk79&j9T zUv+Kg502L&;M)Md3HVgtHv?}4ehcu0z;6Y974X}D-vs=2;LifT1Ndve?*#rO@VkHy zTgUl><9j#oQsDOhZvcKT@HFuIfS&>Ue&DwPUkv;{;12?S1NcM0{|fwJ;E{EmKR8}X zfENIN1o&j&e+1qN{88WwfjAafPVn|3E-=)=lsF;KM8yr;7e--#!z`q6lHt^xYoIlu>cYs#{=kJcwc1{4!cIsjrnGO71 z&~q4Y)-#R&q0ePLF7IK#9ysgYTuD<|0?sPttl)g{sgEzweAoug_bmIK^Q-!|6gYoZ zsK-$|1LttJ*U!ub&hm2a{b4>nM~`PN_Ho{8!k?>wv;Jv{(%DJif6g}^@qeiiV40DlblN5DS-{xR@XH*)@9`~L}i8{nS+ zp9=h6z*~WT3Vb2(&w!r_oYP;%REvOr4)V_e{{r}Hz*$eb{_acQUxNIw;m#i%->-mg z4xIIL>+dRoe+}{zfU|sBf4492Z$SQF;NJqj82ER<7X$w{@OOa!2Y6&-=MRq8_rO;J z&UVh%-)#f@2at~fXZbVqch$gu1o=IHv-~;wyKdk=f&3}JBie`Y*NcG5U1ZGf0?zs` zU`U@=fy+DAnZFC1<*#SRpG}+}oIWc+xT^tYdFfk>0lp&0R|A)KqOs<7;IdbN`3b;R z0X^3Nm%CnB{z>4gf&9n7R|ozTaJK(BRzja)n>s%^zH5MdDR9{<&XPL=XFbwZ?F;-D zpyy!V^3D;~b20F>L4GlCIs3!%?*LyHpcbd4j{h>_*mf20xtsoDR6lw8tY%Dfd6&uF9!Ld0)^H5X9@6H;BtnJCA)!_f&3}J z<;)1nF9I%mN}1mUobyZS%&WjFLI1bF#{pk%1U*b2t}m=-ivF$u_^&{ITi`5Tr@yNP zz9Y!D1K$bw3BY#-ejV^#fIkU*SKuE59}j%ZLNbm%9Ipw$HvrD|pRB(t1wIkvYk^M& z-VI#NLUMSg0GG66z6iLyQ;+$xz^8)#Z-G|<-)tm5<-}_m@U4JzyspvTO$I(4 z_+!9l0sp`9&IP`T>e~PDS!z*H(Z+YG)JBV#6JEh*fCLkH#Uv^!^&}(*5(!C64j6o* zMN3<%*rG+H7A;z|sHswo*4k82(Ne{V79ZDgz0^{rmRf4LUT^Pz?b&P2S+nQ2GqWL4 z+W&k$y-+b3z`~8@i%_7{tS4-K`@5}11_W$|f{CpAa@9|dWm5J~R#rX{)e5wdv zAj183fvM}P5aIqaT~+uR5uOy+*&@PgM0o$>luFxQE5Zvz_%sn-A;RlKc&iAn7vYOU zcuItKityT!g1Z_!T02u?W9Xgs&3eSBdcTBK&F*zD-eWpC`iSi|}P4{5lc7T7+LO!Z(TVZ;0?cc|vA)GIxOp zA0)!RDZ)!c__suOy$Jud2%j&)7mD!ZBK$id{C*Lx+Ltc=ZLJ8uL7cxug!^r*@_hfn z>aVVU7K!r*i}0I7_yiIDT@l_S!oMfN7mD!3B7CI?zgdK@72&st@K;5+itk4LZL0|X zzBqrtiC(n4c5R6WFA(9kitq{%ewzqy72&sw@I@kgsR-{B;Xe@J>qPh+B7Ca||DgyU zFeGdLG7(-N!tWH}6(amD5q`c1SAN^XzjcW4ABppqi16hiyi0`NEy6d6@Own~o+oAP z|FH-kB*IsS@DdSzuL!Rf;eH=VU3tC;|A{z%xd>k=!dHv%`$hOB5&nP(-?JcV|AQiY zkO=P-;Uyycry{&wgg+$0=Zo-%Mfh?NzDk6z7U4e=;hRMGBO-jyMArUCMfe~Q?$;UW z%n}j)m^i;)gg-9A=Zo;4i}2+l{0R}hT7>^Xgl`hzPm1t83$ynBQiKl@;oTyq!ut=++W(vgA1uPxi0}y_{CN@HB*I@1 z;R{9huSNJu5x!Q0uNC3H5#g_ja8*BS=ij!8@E67T1BYef^^yo5Cc@W=@M;nMvItL$ z@ZXB?D@C}nXP|0u=~yPhUlHebi}3X#e4_||RfPKwE>V|#O@!wS_b^_2@jDS-EW$U4 z@EQ^Rx(J^q!ru_#%S8B_BD`CKza_#qitzss;r@eBl>Kju@VpUO`+qOOj~C&}pQp1w z%S5=}mZ~c>i17au*I6LK-x1*}MEHM+@HHabZ*$c3H;eE;i1Yi8RKMze$h#uEK!pEM zgjb00%_6*2g#Sr|FB0K@7U7*D`~wlbPK0k2;af%cUq$$UqOASfM0kM+|GNmU5aB9G z5_@ZXs|ZhUTB%`);EB7CGcze0o; ziSYA9xXN#1__q!bK1!UwM1-Fr!n;Jce=oDLXM+eoL!7@|gpU^CxhE@?&R4!I>i@zX(^? z8MKEArFl*fK3iO8s|fe+{a5D?I9>hKez;VeUm(I&aOOUdA?CXoL zTU)BBc1Swak^qx20-lC5oz2>FSnrZPS>!=~VlK##xQ&(#FON zYf`MM6eh;DG`G*5m8vgoPB*rtCZ^ikYiFcN$>xkBRD5GyY;0j^#iXi4GBN6cR9nl~ zme#q#-qMIG7Bx1fQ*F()O{1z?%A3KJ<{;#G*7Fl^oqXH>nb8RB~dnwyuu6qg>-B)cELAD5DHZj+@(6g;FH9ggqYObRqL^VA9-Qhy!8^_6~>b5bnr_C9_*8MQhVu;j+efWMzu3*WU9TT= zZ7r?v@|b@mKi6g*GyL4zrbbH=O3Nt!rqW4jw#nh86^Rk5o=r}pG~lpo<_V=w5uK=Y zqJ;>Zl_>O2OSYyxSNTSVPaT=HzoNx!VJQz(=%VhTs+*(S6H1n_mx`uQ41Bx7Nu6zQ zxW0)|Q(J2$zL?H|VOFMFpql!0t!l<6*0vTV&P=7pG&a|^%`H_GbV;ZNwVJe}7YsNW zUu0-)n=R819oy8HYEDx>OB``7MzqOt+BZ=-B{a{oW&kY zPH(E6;dO#~a(K~Ls<)d`s?T%w?9}X3b?uDkR6?SHP?q!Zc-Dy{$2B%J`N=!Ft*v&h zYRS??vt~D?8)wzFmhVVErD|ldDm|=;+T(KiT1vea`fqD(V_W%n^%Dh^mR8KFtQtcN zW*~7Bh3BVDlg6N=4(S=4fwF7o%Zz zPj$t}Y{ujfS!9Mxgf)(qgDV6rwxmu%8>_2imG#FqwU|S?U=2khY_H%Mk_44~Rjp^P zp(;8jD2lPu1%eUoA&CkL{UmCelWJ2I_dIOO<`0W7F`_CJyws;uWvF3mlDiFXG#Y6- z^7;DNnW~!ut88akVidTRnzKnJg6)2UZ|sI4_c)sw%Q>92bSYBNa?F#a zkY?Dt0-3!Obc}MAQwB1xiaZp~K#ZVPeX?cf8_KCBDCouLPOV?cd%g}%%wej6NEB40 z+NQU(&6?cWu6$RJOcePQN1CSe=*QZ+6lE>{8oINSiHLWRVRdvRSr?*{3hOQjpOP4= zD;4f2C%n0XU`r{gSiid)&=e*@jcAhE+(=eop}m{zM>g0hjH+y{qyASzOT9N9t5ega zBPpzUZmaT8I74K-)T2^$eQEqj6Vs`BH3*~LZ;~>0Lv3?&swtZUJrfc`wPj_s&Gk*G zw&;$#aeicd#0ulgY4`gwECGTg$Uu63$fcTubb!!x9|R zMcIMR2S$WWjB5dTt#bU(Z0}bOIFpyC5ofYCO_ONTX4BG055t5|q+(w(Mm&aBG|jG? zY2*oA~n#Fc`A6I&WiQy?uY z@E49I&rWAny5d=kwed{0Xg!<#qzNq`k%O@=F>G{GQ_H38qnjFOSp+1N9=?yPP|JII zVzx3>TklQJdVMi58%ue^Uee=U0p!)NG^#k;6!9(|PJWvchE1YbuF{H%@pCF@F*9&= zZnMLdjA-|ku|j3S#uzcCwr=J*t)*hM)OPBys+o;}6Rk#!Qd6yCTV^+V{e^(x;fs6I zL~1@hl;CO!H(rwWe2rKJxFov9fdXZVT}hlo*H`ruJ)GvYi-RNtDWk96L&_uy8d9pT zwzM_Xk36$2m7-oMbtKcXr)7FeAjWZ2;mF5O6&9sBT2pO}vuI|3CS7aW=Qh_Ry=i;Z zb>1;cBCZ*z|RSq#5q|rc&D8QD`or(q!~>UjHv2H)oP}DSrf6S_;xM7EDEOl%Dsa0h7VV z4pC{Ing?RR&KsHAQ_~U^)n1|dEo-d!s#RgNRl&Zr6lL=$8k*Lnl5Mk_)ta%N0!9-P z%a&0p$s6k`=}HyDboVn*Y}Ft#&=>X6zopG=&tk!bDvUok$m|(vYN2s*xS=p&gEGBQ zyMcm6L&(BpQVt?LL%}$5!lY5jhmh69tu)4x8Rc`zI=^hKIA0SnJ!dYY*kE8GePN zCQ(KvE2q)szEmnn>v?Up>6W(a8lX-)RU@fw8fyPcDaE<8v{~(o3R}3Nmun4oB+0O0 znW9;z`kLiEmqD2Jj@QuTI8<16ewB52Hra<8$xc5}5G8xN+6QQkbw3sKh`P*Hra)i% zQ-Kew3+Ktgp_x2cN2|+elr!B6c4^g!Ox9If=K^u9O7|tSwH2jopAu1#a^1!_wy?aS zVNPi&Rd!TMjISDMdQBC0Y8bOEC~qAt=ZYgdA=_gio-nPTRQ)T(6+*%6=0>Xg^>nXS z0cLta#!POhsy^yd(`#vO1Z^RqE=sE0tGFme)J{{BDp1{>=mi3-hepgv)#-}0M?`p9 z6~$vH5+l8BGut|HB>t>dp zRars#n=0ZtC9RXIDWhlF{9&_N=A_Ci1D%@C=%#eC+9^MxEu~IY4W+lkF;!ljEFG3s zOC6J`2!-mLp2kaF*GiQ*(~w|?Dh4>zF*VB0h_SV4Z>m+TVR_Cl;+h>qP|j0MnnNC% zT&;G|`aKCl;Sv0iM`5Yxe8(uBf}Usgd7QaGjZXnS#24R>r#5g&R8y2J>Lp1 zd0fQEAk|Iev)Vu|FaQSktcv<4^1)FO~)De%FZ2r*NFDI%8H8C|S zIlZ}jVjy+=>A}pXY+SI)Av=cBK8nDCvNuShb@0$2jlu%nDIHs0=oL_n_HGm@uPRAS zn3kZ*m%ap3rYb#RmbNi$1YJ68gseuw)(kVOnMA#TP;{xn$$EzJI@RG-XJ+d<`jsYF zF0E~=FOL|_mQpoYiQ5I@a>J0RLj%|KGNc*3o~}pLvTkVL^~MJh*zikFmyIwp;O#&< z_YieqYM>Gc6jw9LNm3}qC`ZD~K%G1zu5>1a1uUgb6peVZDNacv)mYWs zd41qu#?INpOsHa_*PPC_0Cz~wcjm13EK|!VJE-gIR>>Hjx znGzbg^bO9RUoo^DF8mJX!(gn;y)ojYw9t((YKA6QR8?>PEYWsS!$< ziPR;{+#a&i*BegPtF5nB-CVMx)w|`+Z&lQ!K{n&4a^-mITy_Jxo*FT8mf9rk=PaH~ zQJbXg^CzE$HQ76)0?z)doCEWv>L*(>=8hzs8j$vwb6xWSb>k;e2BR6Ew%K)Qnv0;S z*qe(ms$vzBzLL3lhWO$<*a)og^Ci%2$lJ$|EpH@0z+g_a2k%Tz>f0aP3;^+-?S z_L$};667DAVF}!zrIN&qaL-LZ#50!`fB#+1~wJJi%zDUEgFsld|*mmdf9u zdOv_Mn!-@-232gF_9Ap0dy~=A#OknibrWe1fmM74K!Abn#!~^ zec?>uesNJ51#Guo38atx-0=1a~5Hfy>MTL?qZUk;GT+LQvLhI zI4Ym@&ZIwe`Mmj<9iE7%3QSGv7?oHsaeBwp5td!Y)K}|a!yiQutr?pJhL;N57f^Q6 zm-Ltj?Mov<+1WGoL?6GS>_wobIsD*UYhbRi`O;GFFDjYDa< zW)gM#>FcoU*WuZ(Bj_vIlGkIl+!ai=czFklJgqKxkBSSfj49tGGph&Q4WZWcR&(KQ zXDT4Qbz8L>esxAYSej<@*4Xs?%BQ#(=q>tD&E+lo34@FW$j zPt2~?1S;Fms!4d!a5!2tjJHlyT9}~WUvo=ZKWHwQY5Qn(u(WiVS{l!|m8PiuZ6iBw zE3HyED~$~;QFG-E~4nRu_<0jMUqtU(Fh0{o_GI0qFCJ*%j%V`5_f)@XD0Zz8itv_^QK}&c~kmyi;sw=>% zt6G{ZzJ0d*S(R*SoY6qr*FAsuJFnHMpjY{3>W@A$fY!9>Svu1{GrpRN;QhWvaTSY( zUi%i@biQM&%~YLDOwv7XskY=aS}v{kylyUe(XzB9G4vFX-z=#asvX%YpSlF@l@BbF z_F9Z-hA}xaHCH|OPL(&1zXEQjv-BFhE^7gwtK}Ff6tui=^cHr+32J~A%OY``&4?te z63~N&X_1?@0MWztdR{kI%PC@}%TKnx-Po<-71Px*W40p;uj(;vBI_rCRMP@U1UtRcl1FtH9g4Tj}kLG29xxTog0L z-u4W=NjzidqUULiFe=roURpu&pin#;+mpKE z)zmoCyFH5Pg~9}ddf7A6?QEorm8&~rNmb!INndCrNe2H>}<;XnSL5=86B4$ z#b+X2F>YF5!iXvn+N}&{B;w4RnRk!+PI1EYnbXGDokl+ar;SNgO@L0DLw*wJJUKWc z6US3(N4YHiSx-e>yU*N18~SZ|O6~Oz=c%#Ds)^D)nY%v>cl2<_1NGM|JGT4*2fmY} z=S?F{LnSoR8FBeu7$zCj7C`+A&y-@^9A+tYhdro>{2!DKS?R6A5u54ZFnc ztUGyO{p7hxEq-d5gI21z#8h(VcHO!;(^Qwq@4^Lh+`nDsp?N*^JoQWH#Zoiq$xXp3 zStrEKZa=VXjN0kzS{7q7IkLABYnNH%k1Xj%j2(-luGegvDt2s<-)8a-u9zoA(qpIE z(rROn_iQ?PRhl`zQN8Ye-L*)1=AyG`#DjiQQyrh-HiNn*nv|xQGqnqQRFd9kLVdlG>bj;P8k2YnvGr+sVn}PX zH<3PTdV6bKQ>Ld^oh+T+>IqsWSCtukTGdkpug@!23j?Fn{4rgBdJE0hRVU4=*QS(< z$Dif~2W;c6TGG_bq;*X#>S0vUk(3X;<>r5bBBqwqc`_pyM~50D*b@qlS@5W%cQ!zj zavw_$|EQ>B7A1S}uHwL|Cs^M#>Y~0ef?n36?%Ad32>Xhl-``ZVVc>RYe|=jgPhcI^ zo9x$Xv2r0+OgiqsLaDlsh3?=D-m(|-lI|;trQYG*KQ1@xugPqI78;f8`bL# zIUc$rkaP^=f$k-P;j?PtFXiQL*}D_3AtL(%E$o9q$=Vy)7f zy$-Kest#~rl5dps*66(lr;$_q$?x7-ckrG~=q+Q0r}D^v$UGii&+H+ak5~Cz)s68p zy7EKs+|t(5qv6P=K3jwf@^8&sTWDFZVO$eH}a!e?JK2) zXw`1&^-j!UtE~lrcZZrKhpJgPbpPze z-*gW_c3#@cMP5IhUW3^(o!-g16E{BW%*_N;+$%%#9%>lHQzzw><3Gi_M$Bm()dx^3 z%ib&w-Jai0Pkp5aZ=S`Q`1H!#WSSJ98}F;mGAb?-?_ya1O%wISsM#2>Mvt2*``I5D zp!`O_$j0?pROtow}p zqSOTlj(F%21<5jcff7ITi}t`qjVZlB0jPDuChp9BS~aq7AiHReYJ^d|2xRsP5^DY3 z)fZ=}`BUpCczAXc46<0Cb&7yvMb7RsY+!s?p}W!?Z7*F#i$VY2`O%T;Fqe8wfcXex z)dcVuw0Fk&9xB|s1VswvSBE}cHp`9=nJQVt-) z4b{%q4r*!+&yyLAV6T_*50mnZ0YS6 zB4?V7v$q6MnyoTJ3Bb!1qv(;)jdah}W!}A=)orzn>GmG?9nC4tNN5pn{3P>DnIrw} zJ>HX2rgR~G6(%T4b)u>K_OR?DQKdW2`D zM^DcNOwCXaTJNc^KQeT>+JvBN&0e&CX2f@5+(6zL(MCI&TW0aAO|m9>%SwKeN+}!c zo5!kv%pSl0JcM8~6})iFPQNIvYT0nds;l6>IP)bdRAmW@dS8{*8^GvrkWL*H(htNX0`p6!-}w}TW?b_IO|&oip((7$=(&_3%psCzg{ zX|~zFlcPjE1ihEjmTIA1%9G)AcgU8wklNcudOH!lr9cn+{5%sX`6{p5FJWZzup{(D z%7`;l&D5Bxx5s-es(PIS-6tj9q^#fgS{gtZ54-msGLvmvcC2}wBn!n3RQ0Mrn_CS+ zKEnxN6meKvX6p;OTO=}1?PMP`Jm9ZNH`9ESiVqb{+smoKc@))6-oSyLB169!0|J`Y zGK-*bMlV{R-&N-4ZeUF>vg*N&Yt)X8%{=nE*Bq<*JbK;Ae@3kzLxl*;s>RBS;Uv{{ zgIjjAj1r7|4_L7(p~%Zv#tc>I)Fq#Go~8*||D`IumgYTm&}kJDbYJu&^*yZYtYB_1hok1aIVvAL+>F)3#94|D)^ZpYklVZ)@?0A)RXX=h9objKG(?E#+@Gi-DqlY z{9p4fHh=xy5_{BZ&TK~J5@eBrwyxLTuH;+q*XW-H6U?lBD%k98R~Cn(wDRsJO%w%Q z5nrp`p=Wx|Neo=zrr+_n_;y=-;HAV4-sI$8I*^%m@LIq_J7Zc&q{D()(5R+%fg93% z=k}Ct|Gsw+qS$9!mz}*M(|UDODCzm7>Dkk~yZENlt9ExrTL|hE+VjJY#h-S~=#@MPXx0V$=nxwwAH9RkXahb#}TcO>YjFg)U%r01}~>e8w@h=*+g( zx(SWb+SH3^>4B0n=y^ghbiG~<_})_edQjC@p}RTLv)jEJPvrxo^;4sVs|QFAr#ZVx z)SaZS-czIF*xggdAe-AWu`?&HfoG5kyu1P#hovp_K(&;5%<0*)Q?pambn`W)(o`ONv*zX6a+&3>pRfW## z>b^t5T#edDS&<1lqfU)|ef^Y|pcBx=Gv~o8?@WghrN9n$b!|0h&n0LV>5_`n{a5Tk zgA&_Y_3|$B^bM3%d%YFfrDAI@?Y%KlFtdDbToYPstVg)8O zGfwEO&O%?jWvr(r+4iuk(!{WFjr4FTdb)0_@EyEtVwCDYnhWswv6?%G7(wky zV|##0lC7hSkrv75Hb z_@H<4FjZ&#EN;ggNV|+5;uQhMvRb68>&dO95xsxM>kc1XU#~7IyVK#ZMIv(#UHseb z5(&C(+rPCyzj!uqcb)xK0i(gEou}eC+qx#nv{r$86GHE1-KqQ7)Z6K3!I*BcRc{&z zy(ZJ>zz!W-o33kUY@RW0c5|Itkmb&B`2}8AS?xFs^p=A+Eru+gM4JYUTP?hxz$;jH ztWWOs$OHFnWcLi>&R}m<*S*lm4&NSOG%bGqkNJ3?fIq3XpXmqn^oaW2^2aVyWhI8G zr? zLU+jVJb$1SGOF!BO&h++Ja#h}Y;XK>*BjMbltOUJMlg%*sIIqK$6n|y#N5i^7pAz4SWjNtfosKB zIw`bt6?(Fy2Tcs3Z1+?<+!G0$>qt-=HRBTaTt|Z1{~4FS=Q6XOL_RSfA$m|N%ATJps4ZnUw_eurg=LtoKui9q^@O_dT)Ks5PG+2YRH+B&N-1D zj#@X9^{IyBbhXZ#Gh{|v%k0*iojrDYBPZtoaFJpT>&KsO?v;~sH2vF?|L=d=^kqPw z=b*0u`Y$=?r?9?1e=7TrbT`_1o#si>>mvD6CL!!fc=vk z^u<75;h>+udYON}>EOSqfd4HAeFN)d{yEpd{#Kwr&q3b-?4RPGpAY!oc8LE%z+dQ~ zU&4Bse&2D>uK@g7hxo4o`e_dOZr026uXE6^0s49e{W_peIp{Zl_)mAxZvy-o4*D%X z-{7F%2J|;LO{ZX`k%J)+XU>t-+|u&^ba`b=L7wN4*Er`m-Tn2gMJz7W&U}{LB9g%A9m1p0{ton zeHYOG%t7A`^p7~`*8u&a4*GRKf2%|O-N1TT|J~-G-^6;^f4kj5za8+GI_UT00xIqQ zfrEYk>!tm7IOqof{#u9hD**Z*I`B_reXedsz5cW6lW}n7(^h{~1O1&2`X<)P`r|GK z{S~a2>Gzg{{}!-b)<17J=obP0j~wh@%6gf9mOJP>0sn3X{S$zHkAr?4>!ttx)?O2R-g`)gkTQ*FnDl=pS^je-rCv z`B8HkT&-n3ZSAirtLl*HcZh@iDzB?U#{Y{B`hIk-sUPT|SLd4gLml*aK>t$*{|yHE zhaB`pK>x6Vz69u3Ip`~Z{$~#QsX+gTgT4XiA9c{DfnLqY#m)coSTFN`Ifcd5F97^D zDid+_i-Eq~LB9;xuiBKj{1t#d$3ede=pS?Ne>c!S?x0@_^z$9;-vIR2JLoq7{Wl!+ zTUjsj-vS5ycEJCZgMQD?h3n66I_L)g{m&iJ?+B!K;O7JV6At`gK>rH|eKF8K>7btg z^uKh_PXT&Wr^YS+^+5j{2miOSUgqBe9rzu9uhvB3+CLxga~=2#0sk-u{Sv@G+(Ew# z@PFkH|CNA0)PcVW@Sk$vcLV(}2mV^1AK{?i0Q9O)6*vEE0{W*N;=dK>Pj}#d!g^VL zu5r-s$wH~W)U0o{dS;V=b+znA6DkmcK&#f#N+y}8|c63pkE90-*V7z0Qxr^{J)9yGW|Ys;BNu? ze>mv30sT!5`cFXozw4my_XS=5%J_fJK|g@?vi?jvi0{wqD*xvy3KXBluf&LB${XC$5+rj>YK>vFO{Su&G z?qL6NpufjK-wE_TcF;co^lD8pZuwoqdRc#LbnxFgz`xId{}#~y#6iCq=vO-Ew*meA z4tjs%h4kM84*Gsv@yh!5K?nUnpzn0h=K=l04*J1B|1$@D5$mP@4xu^uxcRpj@E>#F zPXPQcI`FFj|8WO?4dCZG@EZXC=MMZd;Qzuwe+A(Gr$ha*0O)_^z+VjX?>O+60sVhD z=vM;0x+g1c{_O(#R~+KMn)R~$tas3_1^QPV^y`8BzjM%U1pL<>^qW~P$FF~I@c$>k z{&yYp{q_ydAOF!oKM?5ufCy4+5Iq07N z`ppjIe+|&@?$G|P2l_o6^c#WxPY(8PVZBWM_Z;-w0KcDu{W<%E>)+2i==%fxJ`Va^ zpnu;X{)2#iUk82x>!ttqbI=z7zS>h5xBpTC^anWTD}eq$2mMr_KgdDf0Q3VL^l6|! z*g-!J=(jlJpM^kwxC4I)(Er(izZ~d~ao~3X{Z}0HPq1F*f3+tyZvI^j_{Tfw*8%+r z4*Iu%{;Ll9%|JicLBEal(tjs9=syAclN|K@_7B(JYEN+7^cx8DA2{USJl4zj|HVO{ z5BMiL*gp*DPjS!}1N+r8J>vSW4Dioz;8z2_+LIlZKNavtJLnsLevE@Y4fKC?@ZUV3 zALqbd$a{XS0KeRUzY6I8=D_a;`tc6@wLm|?LB9d$w>j9q ziS;u5|L&mQ0{9gU_HPIJN(cR(eB-0Ezsf=1pY=QqecF^Yn{W%W$LBRfV9rS~N z{yYc$Frfd)A^lGU`U@TSC9IeJpX#8m0Q`#_^iu%;9}e-a2mD$GeiPuUdvfBoUmbuy z-9bMO@Mk#a7XrR|CRbeh7X$rF2mVrEf0KiL1>nze(02lTi-W!k*#F-S{#y<7Z4Uf( z!2a0|`VBze?x5cY>`y!Bw*dYe2mLm{|JcF*{zLI)`}02z`hNUSeOdoq;b8wj)=U1C z4*DYi{}TuM^8x>V9rOi2f31W4MZo^+9P}lCukI;~TYpUe{C_&ce+tn5pM$<0=+!d~ z(4Xd@UkUU#IOw}rFV_$Ebcp|2z~9G# zzX9;~a^PiHY#zr7vo&t<)=f8TN74+8qP9rOi2|E7cfRG|Mq zhx@n7fPN1Lel^g4R&~F2L^-O}e?SIZe zy8e{$f7wCbkM*+t{Jw*JAmIPjL4O3`t7j_2jekDizv7@T0Q@^0^rr&;dIx<8;NR<@ zuK@g49rRNG|9%I3J>b9Lpl<^FpE~F}0RJrq{XD?`frEY_;Qxn%elg%b?4Vx;_-{Mt zR{;Jh2mLC*|Gk6$3BdoEgMJO*Z*Vd0 z_vDVdY=6`o2;{aG*DpT`~axq$x%2YnvkKjEMs4D?Sq=!<~;n;rDUfd90EegfeC z$w6NY_^TcCHGuz~gT4XqpK;Kq0snmm{S|<}*g?Ml=x=t=F9!DC;-Fs&_#ZmxR{;Iz z9LDdfSkE8c`dvQ<{Tjf(-NF9#K)=F4zY*w{JLtCn{oM}w?LdEzgMQD0!~19MbI=a} z`ky%Hk6^uQKUO;E2Lb*A4*CM1f6zgHDzLxPL0X~G5+s_K1|Eq(3D$s9t&^G}6 z-yHO5p#RuGKM&|X?@)g%1o}@L_)AzX^Y8yT=$8S#dYE(E^j`t=yE*7Pfqr)feHYO0 z;h^sZdi6}axba^D^m{qz*8%VB| z{S?4I$ie;^z<ff6f=f z?Z;XNet*^zGE;vZ>A)Wd_`h`E=K;NXrgGf)4+i%C%0WL2@c-zbF9!Uh9Q;=X_=h{_ zs{#LL2mMsQ|0-C2%%j|)UKLGCi-Dto^*0(n&=#J+aX9@?rD<^>G$&_@+AKrIW@4&C zwciJmn4;hv{(Fs%qyH(sK3o5${{G|0?05N%Uu&HS8cg5RHEnwHeDnVa(yA~sUO7im zARYd5;Pn4;a`OBy{5gs~m40vI0u}lCgd_Mo|HI@@qaTpIiS@h;>dU=zGykD4trq=N ztmkd$8HvfC&wA5;i&)<;qtsu_|6fhPDE*7oWECBLI;-?Q5~TkvbPkID66UM?ArHgN zIXBUd9^d$33g90N_-~OO@t3;*0b3BQWejV$dmB!O|Q$L8r$o^Kgzl`{fQZ+ z{$gNq{$R1cLrr$jA@ko?fc+{@Dw|Axn)!Sio_8(v$K;=3(O(-=Kh2_F#CooVt^8{( z`W37nkx}X|ru}!Z-b}x@S+DY@Jk0b{&s0VJdx!PD|NU#2e6^<-=|5(@s$b<{>iv5< zij5x@arzgqSmoc7=$wB1f8VadD4QVuu&?S9$4NMSH!wK|lOC1dZop3f{#6$KWz3%w z!Jlj4Z)JWB>s9=R0{%wko9Vxm`MixhV}+UilPL1Ye>tjQro+^m{_C*l2e3Y>{I`=H z`M+WxiWnV!I;;4P1o2;K;h!Fp|6>ck0q{ow{+kwl6Z3f*%8QHoWBTtO7X7s`?LV6Q zg3_;(^}{n{{l(-TMtU+K$1H#IK>SYw@h`UU-(@~;qs>@h^6M@7?W~V#zi+VU_u-89 zXoigA@4r*ZjQHm$S zN9n&2@Jj*zpUgMwpVNkDu)4N9%=qW;jq~pq)}JiJ^xd@oSkfc=2Yf--AJTti!2Zz| z{uRvUZeYd=ldsDsY%~89bNp*qujx6`*)`?InuYW-tYhV7clkzOMH}m%Ru@~2KEVKc#0T@I$@ib> zVES(z;GYfnXEWc-|NmruRQ|ulV*l=(aVJOE@86SU+Mm-uod2tV{c2ApO210xkBQ*> zdjd>;0pOnt_-alP@fR~cD*yf6qQ8&zLnG{0bBc)nHtVDM?_(|ck60hoe?Oh{DF4^6 z|78E?Lg2rvEd0T0VuX&U_E){<2gUz%*6*h;lle;~1df+1`U$K*EO2(X{@#n;vw-;1 zW7@CYlY;aetp9QZ{}j?A|91fY*8=}HS@?G_|FQ`F3=4k|^J`eI>hC(h{}%Jj`X{$g z3kMi{^Bl>h0#e)XOYlzvl~f3vQ}to&Cj{Jed&Z~z;u z{MP{ZNA9EfrvLuT9p^(cWc|hTUo-2?`G>u^;79de@381|Ssyiix|Q@O{}$}8<1g!v zCJ_HGd;$A^9P__p#Gl=n2`#ti*R$UApQ%^RiAVOA0sC8k{a0D|A29#8jHUXE$)9WC z*D#-}ac}vCfTR3( zI`gC2zjG}5ikSNETlCXd-xd*n^_&o7|9aLR5~0sM0PEjlJvT#{tB?x=$3dh=`F{h* zf8PfFKik63J6&U*575HpUp*%R@%tU5%U?I^Rr-Gi@cUB&Bmcd}{DJC6ahUP{9O)5% z4f6|FtN1qpewBs)&oi{JQn1xmlRwGA-wyaU0sf5^enqhcN9CVqE&A!K&)1j9{59=Y z_lY9^-@y7CGD`i$)E`TFzApWx~{3AwdUX=YSE&3AH9~)u+A1wL?)-R6G zZ?wd}nBy<=->o426X`w$YugfpJF|^Cvcejk1hJwSWiC(4pU!96&&*4 z7S>buB5;`cnHK#gtREUshy8!IMPG2H7EX=OFC#rFfB9bw*MIkt@n--1b2LGS;=hpj zheq&sCq3d91O86{f24(f5A%Qg-r&;(50RKV2Ut{5) zP^Q5=jLcX;mk1nBTligo|5L!Y$_i_g&^krT-qJ zNBJ)|SLc73{yzi!d<(ye`6oog|5yvZjQRAlcc}XRQNVAp@ZVv6RR8B<3%`c>-GcuZ z;NNcHx0Y+6+FvIRxVkSPBic9ypCY-ucgH~se|(xd!4Ky3`7qsIHI_pf#X{#nd7 z{Wp{OQU1HyVt*^^qx^T7#r{^dU;6K9VE+mW{}$#y$?^9;O#l7J!e7Sx4Z?rV0RCT? zZ~Cu#ycU}MA2a`*NfUG^{in13XhUGyKZf)u{W}iV>7U1XResh0`xjaG*H6&)AMQJj zKTZCxE&97yPwojErv6!r{Y#F}_EYil4rRZ3e|)BgXm*uUl&oquXruhLJwKh3m%KU&~XHktN6#r&x9 zU&?y3{6EY3sPbP-dgT9np7@jHU%h|Gw7=ED-@<%<{?B)#>A#s4{uJiR^jGiyG5L2{ z_*2i*#8-_3H~BxX@H+*qx>_E`7-~g_g|R)n`Pn8j~V|43%?V@U%mgpnr=CA=`fsI${{izy1*{FX zzdyF{2OOvKugpK{CR3CDo`s)(fd)sFzx-pc|4(N9NrwHq8UH_)^vHk3Y<~@(uj+sG z{CU&>^M4(nh0|}5h2O<|Isc%Zzh=h& zbI0QL@9YaT*v$W?|F2`c+5XkAJ}Uj6v*_DcKQ1EvPmvy_|Dvz#;VH{lul%pJq?_?S zU=YrKUCckh;G6O9PkO}Pz16(?5&Qw9S8*yf_+5a12;iqJ{4LCe>32#DOHodKLJz`G1I@0`G*H$AFe<5AwBYc z&Itsg!_TLx{!mj|CV#wzKZ*J0MDWL1__@rN?e9^5Kg+^j9y9(87JeCse;(j(xA41T z^8aSx*8sj6(wY7r_Z6J}Z!$k>|H2H5e(z~I;V63s4zv7BBR$GL9l(Cor8Dh++QJ{q z{KEqDaQ=PL!e0dVs!1^UhvZ}bjbr{X5&V=z-@tmBUI`q#2mVLvOQc8sTLJ7>L8kqk z7XJ0jH`{NM{}T(p8}J7M{x%E0llf8g|6eTp4S+uc@J~G+r{5OlN9CW9q(}bW3it(p z|EPt(cb!h?DE>nhe!s60j1F1<76Se-O5ok-JhT4Ki^)HU^eFy$fIkfI@3ZhvX8ti= zEV6&h{Fg@+6taIR>&^Ph)E`bKAp47e{Ud?>H(B@#m>*Ss7h3ogfIkZG_ZW=he-HCJ zvaa*KneqRph2Ow@U$5HlQvm;53;(Ek4UWpcXOkZJeau^@Z|e`fl2PBk7U<%1$I> z>5%>J3BdlRE&P3^d-9wp`}ZXPihnNaoAqTff6e&!BR#UegY93$N>%Z0ds|LCEZ|Fs4U-q!#c|IIm!^oXB-62a(Lp)cdze|jO{A2bZ}FK*Prk*xPW%>1(- z=@EY&^JV`18sI->;or&plYKCMn(<#{;co`~B;ZdNj^qC(^P}po@`OAr< zNBnN)%ltP3@UOM-*D!xJ+wXsv`Tt4_e*^Pn{nH5ei6R{T(`Ra8)cV1l7JUWlAM_39 zPt*RTq(}a%NQBd`3D`e?7T8ew1bQ`wxr$W7bFIpARkeF97ym3hclB6zso2v$W%)_}7pg`EMEE&jtL0 zXo3u--z4To<=_2CkN91He>vcP-NJ8TK2;Ba!z@2nS@`P!|4P9B4-0=e^A8Kq!{uj# zg})i_uLk^yr(yp;$$V;_1BV&^GSVae=L{tn9kTph1NaYE_}gN}|6U8ffcdii{5s$t za5|3vemwAs@_&EQqxhEr{&j%gYT@TIpSt&f!}R~-7X1aRj~c)H%wm5Huzvxt|Fko( z|K`Nx7m*(MuLJPE1^5qH_}^uIMZkOE@^in1zlixV|1JdlV~TP7-(miK5&Zis`mL-# z!O*L^QXY2~WB+vn|J?}e&l`>HKdePlj+8L^ZsxzkNsrQR1K{5T_}5zaBbjgd&y4>j zi@ucg)V&BCrvCS&NA_<8>Ax7*fB6{fzpI!Z)qc()J>uu7#RfWL{dEiAzi;8MV7_{0 zp*)QL=Dcg+7ct-8m!SGzO8|e_SRDUPF45Ge`tx?uqxg4>AQ&Ao{ON8M6Lj@^82ByO}TRzh!{` zXAA#Y=1+~_Z?^EaGGDGA+y(f9N^$zX&HS??_(zj|PddlX=l^P0R97j zf2W0iSX#&TIQ^0NYsP=6g}(ssI{{xk=R&oq=KNJL^P~EoFI)Is%$ND^A;90~Ow6Ck z{HXeOFVds*UkCWB0RI9D{|e?u<^OXm{LRd-;gnPP{}I5SKou17|FbdE|4h=O_?M~0 zdOBqO?*jbODT0WDlxI%NKP0`Si{3&;O$=6_pbGk;Bf1?f@z^O#@5N)`Vn0smVT{>5{(@E1B7R{nJs z{ygSyV7=mZ1OE8&IR0O`QX>z{ko6apSLCtOqCc7Shsu-byXn90lOFkRirQ>IhfKex zf&JSo{A%V?_6Qs%|1TDPEAwkut^D^4;J-To`|l3sN7di|NqQ9jbJ{rA5C{IwSTlB+fUB+ftnhha|6a~A%967ByQ7OMRB65t)3N!l;d(YE?sPX@xN~|Bq`ZM%pGJj3}(WFP|*UJ8r`DZ=w z-&PC1iut!^$oh-Pf8WAi#{5OBSLyc};IFB|@&ADN4@B^vCOwLOf!eG@hvciapdVk) zuUGG>#{8w%=o7!q=ldUK{<)L%h~Lfp8WyVfzXA9K=V1OJ+glZ+b_%CJHY-!reOQWFrTW&z+w9D0MaA=8s^LPYZKs?S@_>&e$@DT zg+;$Irv673`v<7aestt=>{a>sBe4I!E&OL=@~=4``+s9h{S~A~{?7;YzlZF%@IPjL z5y#*EFw=jVg4Dh!B{wXxUiTK^j zKRiGWk6%WR9>u>4@IM0l+b#UJm>)I&c#DO<4)C`F{+GUnR-k_!rjV_z(Jq2AktAlfTuXFJwJ+?*oVFzxPRx{I`Vdm-&AmVE;F#Vf(LVepLN4 zpY({o5%{k^;2%(j`74qW%{QUs`b_@Sm3*St?TP*wmXYJvon=C&A0Drf7 z9RH2XH}j8~{^b_^2duw1kb5*s29=PW%nGgF<+J@V{~Saon)S~|7XFk4ni6IIMJXKr z>8z*Wec&+Te?IAv{jI?MLxBBXosRikG3{Sq(LWp0{;!iB+1~~1KNQ%1)(mWa?l

IMzq?ziuKuvOi~hIR763?B8bLk7j;U`TvWBp9}a$0sf^8*nd-*e`p~0h1>r& z(xdnn0Dd0eue9*zF#q@n{*NvEGUm(n^BBPYPYZt;^B;-ezh&WfFu$Ais{b+w@Ly@f z{y+CyS{OC{c#-tT|3wpY{*&=P4)8}&1*z&3bNsWI`BC}*yB2*X>ks1i`yXcevDKnq z&HAYR=li5b@o(Vx%l7945dWiQ;`qPA{G)us`O~!jaN1{${FlQMmr>>C5Yi+2=K=dq z1opRE_=hpy?7x`yH(U5iK>j%i@PBRL7c)Pq{5)&nuVH>S`(2fv1mORI_W2_Jf5iOO zi1h0sJ@Ws8iMssM2>wvOZ*9i>=?k^6EP_9i^oYNi`Lg^D2mEyw{sYXX>CwPp_8)$2 z;pa}$@%Qal{vQeWT`f5NdwoY^PYBTUxiaWs(xdp-Fki-h6yVRJ1V-s!zj~9`XB44)-5U1N>Vo{Pi*UH(B_3fPV(y zpWKGy{{i!(^51aMqxcswU*^BjfPZ*9=9k`}6V7bE%=~`{=@EY(i2qo?|JcH>VSZHm z^>+(@3E-Ck{x@i!49b63GJkL;=j$(K{I4ZFihn2bW%)Z3@cYlk{Ck;i=6{p_InpEk zMiBpUz`w!5U(I}T{mv|ZFI)7lv3@_pf2RJ}IXM2CV(OP#^dGYRAj4rM|NEpz{@c#} zYhb;qza|0y?RP1*fA2*);$Mk~|K~}M_%&yT`=1qn-(umP$o#1MbFqcLi21VrR|)uA zE&MZM^53`cR{(xB;9p7&j7lQ2|2>WQX8mQRe;etM|GNSIT)_XWg?|v|LvLi~oD$L_`!@jl&jUv(Ld|6iCNm47FZ z9>qVeGTi=u4e(#L@b|e%8y?mFUvJ?T0e%wjPrn?;zkvD282&f&?MnaJDBu{-wphCCE)+U!oSGEH{;)B;co!^s{y}cK8}9}^N-^E=YN>_ z=M2)*Wkc(4TLJ$Xz`w!5zlHe+`e6PvB=MCgA(dNM0ye?RrGE;?lYWj>wQ z&kN1&E7<=!?7u%U|13V=|1j;}hxCYF#C%!*T@Uz87JlK)niw_ym|@{p0R95NUv1$} zV*Vk1#QD?AKl@*g{a4R=v;GSCkMziY4Z!|y1N-M%_*cc`r!D+>fd3u9|Eq<+g!xh9 zw}x+E|1D?zu@U~SBR%rp5@7!#VE<+d|2gJI)&J)$!1lk&dNco;>0e2DWPc~H|9imx zUt0KEnIDz^9=Gt<0RGK@e(uXpR)eC74Y|^bvhLP3z%=_AG7|r#iDOu{g?><-9&oizkIg8jP(&$NHOMZcQ$QRBC(NssJr1^)jbu>W9MXF~RW#QgIj{5OE~h`#{%?@qwK z#KNEWeGQJve@zztIuQRK0sh+-{*0LX*Dd_bfPXjOUqtIH$p6m=4{Bu6(k^ghf z3zxqi1O7u6{vFIeBqII)+oE3;(|_A6_U8io?*sNHZ@~V0k@+JG`<1WdaRKR({|W$q zCE&kh;qSRbQ_T9ym$+|C{OGkMzj@-N65k0{=H#_>*JW|ExuS5$mJsuU}d0-vI1?9N2#x%@ZL1 zUB>)@M*5ri_il^+2G-wi=uQ7GBR%r}Rs9&t1+f1t8Yd$APq|GCqw>$47JWJE zqw>#E(j)sfP6@Xk-N636sGp4NuV;Q#`MJQNZ;2WI`z-n^S+CytC=WCJ?j}8o|8|al zfp&v8f3zCJ{}k#cq4;c}PR^zl! z*MRt+Pwgy<|IeA9FP%@{P5Y}!kN8uVpDXw;0RC?*{7uZyGx(RGJ_V0Oz79J3x zzt^HanDym`-i-fp(xdpda{T4^<3$kv!>FD@_Fu&OsQP2RMc>5wsQUYA(j)u3K>EE5 z?Ek%mzkvCN82&TU??fu+DE@b_ew3j%{hv>IWdAyl|JMWi@3ioL7t{aww`2R?WqqY# zzZw5yNssK$`I;`jHLO?V_jkblYc2euA8KJ#{r$E@U&8vR@>97K$NyZ`508ldMAD=9 z*Kqu0{q-h@|AQ9(x0xSRevYMj2IaroSbs)@{YQ}=*}n+b|2DAyMhpK9=1+>?f6Kz} zX1=U{HUj?tSorzNH2B;I{zn#mzl*~8_Z`4*r*eY)e--l+5&UM-BmXxrU*?}pfd7Vt z-^u*rBlxdc_)C~C+rM`Kzkt#i#s3ZFA05H}D(O-DI{|+);4fkR9%jXKrv?`p{C>v& zzh~jEVg4dMU)5jl0sbw^bo@l_cv?-{Fj$ueoajN zTGAta7vO&Y_|?SOjchdMj~6iCZ2!z;noQ>*er}D9zbyY-0sq$){!`39j{WC3x=(*HElqxdgkehnM0^4~VVzk&It{|8XGI-<(|H!b|FApRc# z{)-m=$;^-P|MM1pUad}l>HqD3zu%9r|7)0E?0F&k$1H!JCq43i1@l+1RQdm7z#nJf zFJpdG{WIFa-_Cql|9k@YcQW5h{|(F^pN+crZFl4UOD+5b)AsPrtl{%j{Qn8~TP^%S z6t0f1>W|D{lmEVjznS?m{d33$KmGi6>5Sz#{VSLs<^PjOPtgjkzvtHN;n^(xzdPXn z)52d6lmFiq{tCd~6YxK|8^^ypCjTF#NAWMJ*YU66lvC-yH{f4z59V)YelhF)4?q3< z|DQv8#9zYv4n9%w`vLwf7Jd==RUP^IBlFkf-(=wrNa^^?{I?I_Z?*7im|vD5>n|q% zeG9*s`Q5Bn@$V1#U-~ij{|e?8v)=zO`A3i*`9Ej6j{ge5-w*JoSooV`@~bTT70j3E zKLGG=wea)r)`sW#5$8`c{);XAycs(FWvo;FKM?R=wD8Mf@}IZx8vuVG;O|Wdv>VxI z_CFh#A65VDMtYR~oy?c@-ywkiq=mmMX8a$s@QWM5{?7&c_bmKw=I2MG{~s*;1mxp|GSu9Bl6!7fPbNdpGWnII-=r#u7#i57_R@00{mMn{4(a} zYBMr_`(?iAFE?5EWy~+*^HurF1N@`!)BfMx=vdS+->*M>Y@YvxKUc8cEI%7qzrZ-( zwEst>N9nhS?ccz9W&g3j{@Z_Iv7hP%b-bfLGJo?j-}ILoR^t3uwnG0N<^OMz9@*b; zak%^)2khUQ7N}JH6Y@XvXBhV88UMeE^``&V#I%1d>5=`N!2aWb{SR2|-^hG({$hY( z|JxS(b0}Y{Bg+4;TkPKs>>mv5|H1><|EgY6hq?Z2+F!(a)BnXW?H@{dYw8t!uB^%y`l~? zznT9366ulsMYFX11^P1H`ezZa|7zx&_0K%!m$Bae$n(GO=LU=YYgivueqXWJ-@x|! zd{zIS0_;EZVeJ2n%=hE(n{C>E0qf23JAmpHbwv699MU8IcLM*P4(z|lVt*dSc9A*?-K>aQ&0VdNaOe z{c|Mgk^h&m{eJmV<@YRL|3%C<>z`ugoAY0JUaYczZnN0m%KH55sopo!{+liKuLJ&{ z2<%^Nv40u!4>kCvKR>Y8-yPHcf3n!0+Y+w-D}eonKZ48eI_5|9f67>Imfx+cUtq-F z^#54Wqx@6G_RIFS3fTX#h2KH_3U!$NHu-+H)%FP5&*k z=uP`ak{d~33Cu6hm(j-1Uz7j1gl=_RQ&m}#|KOL8c?Y|P(|D~rf|DVkNFoJ&s=@Gx^iZK6b zz(0O9=5M8XSshXBU*0oVzcex3T{~u0zWdC+x|FyvW4hw%E)hp^)q(3r$&Gc)x z@VlNmV`Qu_<6lL3=ii7_`hf2cU-0YU&I2%{}$k{eGbQeOt;2fAE1ZZpXW%A z;@^3-=F9eHA>enc!TdGMKRtrqPI|=8pQrh<|8)c4zh&X?{VNSVDuTb^d2Ih6)*l|B zzxf5MFJ}Gz5&AV2eMLSwf$m%;RZ=&xD-UO;*j{}uDK;VW3F_;&#Q8y5a7s#nz!75`T) z{EF)|U&enK;Lmyy$G?Eer8-9FkIY}w{|%%^@n7&w&6nwa7vTTd!k^CksQdpmTlmYE z?~mV<|Ca;)H8j9baWd!M8pyBe7@$8gfBR*==`UB19>ss%LLGlu|K9`nPcq+}|Cz`9 z!3HnS`2R;1eK+fu8t0q(AFadjuOYvxBP#xPkRHW9=R4u}-v{EqjrpPYGr!ogBKs#V z`_=naN&_U6e%&$cFD5;*zW~^OKd}EQ=9~6!WPZM3uWA3I7W?~Ax~e0}{|{O0uL1UV z0{b^x?9XF2LafV@&(cV7*!Y=1{$$j;Q>9 zGU-wN$-5z3|2zTgpKGx{kNL-IGctekGT-!@z{_jWif;yu7zn=8S|4V@Xp91zD@+!7JkNHvUUlr?3 z`zvDFKZ*3n{x!hNh^I5;aIN$7lc3JG-&h~e+ zUge)P!2Zi$)BZR4Q>k81$GiF?^Vj6hAwBY6*NwXTb+c0OUjY2meuw#Es9dPyVEvK# zYw|x}y_x<~SRa*t|3rFZf5)P5{qY-Me?BFU>VKH^-#q3=)gRMXZ`$7()BdlK9@)PF z*uM_gzvt`N{%+>ql<~a&l4tz?9@6heVcJ{SAE!{gpboRX^Z)OE-bs4Tetml8?*_I% zmqS$kc?H=2DBExPuO@=;gC6qvM#kC-_^$%~>&!3kFUX$_%skibG w=02@|e2cV41O4aeXEX08#pYMFzIkvk#=-yP + +#include +#include +#include +#include +#include +#include +#include +#include +// This is a temporary google only hack +#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS +#include "third_party/protobuf/version.h" +#endif +// @@protoc_insertion_point(includes) + +namespace helloworld { +class HelloRequestDefaultTypeInternal { + public: + ::google::protobuf::internal::ExplicitlyConstructed + _instance; +} _HelloRequest_default_instance_; +class HelloReplyDefaultTypeInternal { + public: + ::google::protobuf::internal::ExplicitlyConstructed + _instance; +} _HelloReply_default_instance_; +} // namespace helloworld +namespace protobuf_helloworld_2eproto { +static void InitDefaultsHelloRequest() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + + { + void* ptr = &::helloworld::_HelloRequest_default_instance_; + new (ptr) ::helloworld::HelloRequest(); + ::google::protobuf::internal::OnShutdownDestroyMessage(ptr); + } + ::helloworld::HelloRequest::InitAsDefaultInstance(); +} + +::google::protobuf::internal::SCCInfo<0> scc_info_HelloRequest = + {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsHelloRequest}, {}}; + +static void InitDefaultsHelloReply() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + + { + void* ptr = &::helloworld::_HelloReply_default_instance_; + new (ptr) ::helloworld::HelloReply(); + ::google::protobuf::internal::OnShutdownDestroyMessage(ptr); + } + ::helloworld::HelloReply::InitAsDefaultInstance(); +} + +::google::protobuf::internal::SCCInfo<0> scc_info_HelloReply = + {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsHelloReply}, {}}; + +void InitDefaults() { + ::google::protobuf::internal::InitSCC(&scc_info_HelloRequest.base); + ::google::protobuf::internal::InitSCC(&scc_info_HelloReply.base); +} + +::google::protobuf::Metadata file_level_metadata[2]; + +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloRequest, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloRequest, name_), + ~0u, // no _has_bits_ + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloReply, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloReply, message_), +}; +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, sizeof(::helloworld::HelloRequest)}, + { 6, -1, sizeof(::helloworld::HelloReply)}, +}; + +static ::google::protobuf::Message const * const file_default_instances[] = { + reinterpret_cast(&::helloworld::_HelloRequest_default_instance_), + reinterpret_cast(&::helloworld::_HelloReply_default_instance_), +}; + +void protobuf_AssignDescriptors() { + AddDescriptors(); + AssignDescriptors( + "helloworld.proto", schemas, file_default_instances, TableStruct::offsets, + file_level_metadata, NULL, NULL); +} + +void protobuf_AssignDescriptorsOnce() { + static ::google::protobuf::internal::once_flag once; + ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); +} + +void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD; +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 2); +} + +void AddDescriptorsImpl() { + InitDefaults(); + static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + "\n\020helloworld.proto\022\nhelloworld\"\034\n\014HelloR" + "equest\022\014\n\004name\030\001 \001(\t\"\035\n\nHelloReply\022\017\n\007me" + "ssage\030\001 \001(\t2I\n\007Greeter\022>\n\010SayHello\022\030.hel" + "loworld.HelloRequest\032\026.helloworld.HelloR" + "eply\"\000B6\n\033io.grpc.examples.helloworldB\017H" + "elloWorldProtoP\001\242\002\003HLWb\006proto3" + }; + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + descriptor, 230); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "helloworld.proto", &protobuf_RegisterTypes); +} + +void AddDescriptors() { + static ::google::protobuf::internal::once_flag once; + ::google::protobuf::internal::call_once(once, AddDescriptorsImpl); +} +// Force AddDescriptors() to be called at dynamic initialization time. +struct StaticDescriptorInitializer { + StaticDescriptorInitializer() { + AddDescriptors(); + } +} static_descriptor_initializer; +} // namespace protobuf_helloworld_2eproto +namespace helloworld { + +// =================================================================== + +void HelloRequest::InitAsDefaultInstance() { +} +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int HelloRequest::kNameFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +HelloRequest::HelloRequest() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + ::google::protobuf::internal::InitSCC( + &protobuf_helloworld_2eproto::scc_info_HelloRequest.base); + SharedCtor(); + // @@protoc_insertion_point(constructor:helloworld.HelloRequest) +} +HelloRequest::HelloRequest(const HelloRequest& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + _internal_metadata_.MergeFrom(from._internal_metadata_); + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (from.name().size() > 0) { + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + // @@protoc_insertion_point(copy_constructor:helloworld.HelloRequest) +} + +void HelloRequest::SharedCtor() { + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +HelloRequest::~HelloRequest() { + // @@protoc_insertion_point(destructor:helloworld.HelloRequest) + SharedDtor(); +} + +void HelloRequest::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +void HelloRequest::SetCachedSize(int size) const { + _cached_size_.Set(size); +} +const ::google::protobuf::Descriptor* HelloRequest::descriptor() { + ::protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); + return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; +} + +const HelloRequest& HelloRequest::default_instance() { + ::google::protobuf::internal::InitSCC(&protobuf_helloworld_2eproto::scc_info_HelloRequest.base); + return *internal_default_instance(); +} + + +void HelloRequest::Clear() { +// @@protoc_insertion_point(message_clear_start:helloworld.HelloRequest) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + _internal_metadata_.Clear(); +} + +bool HelloRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:helloworld.HelloRequest) + for (;;) { + ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // string name = 1; + case 1: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->name().data(), static_cast(this->name().length()), + ::google::protobuf::internal::WireFormatLite::PARSE, + "helloworld.HelloRequest.name")); + } else { + goto handle_unusual; + } + break; + } + + default: { + handle_unusual: + if (tag == 0) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:helloworld.HelloRequest) + return true; +failure: + // @@protoc_insertion_point(parse_failure:helloworld.HelloRequest) + return false; +#undef DO_ +} + +void HelloRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:helloworld.HelloRequest) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->name().data(), static_cast(this->name().length()), + ::google::protobuf::internal::WireFormatLite::SERIALIZE, + "helloworld.HelloRequest.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } + // @@protoc_insertion_point(serialize_end:helloworld.HelloRequest) +} + +::google::protobuf::uint8* HelloRequest::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { + (void)deterministic; // Unused + // @@protoc_insertion_point(serialize_to_array_start:helloworld.HelloRequest) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->name().data(), static_cast(this->name().length()), + ::google::protobuf::internal::WireFormatLite::SERIALIZE, + "helloworld.HelloRequest.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } + // @@protoc_insertion_point(serialize_to_array_end:helloworld.HelloRequest) + return target; +} + +size_t HelloRequest::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:helloworld.HelloRequest) + size_t total_size = 0; + + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } + // string name = 1; + if (this->name().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); + SetCachedSize(cached_size); + return total_size; +} + +void HelloRequest::MergeFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:helloworld.HelloRequest) + GOOGLE_DCHECK_NE(&from, this); + const HelloRequest* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:helloworld.HelloRequest) + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:helloworld.HelloRequest) + MergeFrom(*source); + } +} + +void HelloRequest::MergeFrom(const HelloRequest& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:helloworld.HelloRequest) + GOOGLE_DCHECK_NE(&from, this); + _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from.name().size() > 0) { + + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } +} + +void HelloRequest::CopyFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:helloworld.HelloRequest) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void HelloRequest::CopyFrom(const HelloRequest& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:helloworld.HelloRequest) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool HelloRequest::IsInitialized() const { + return true; +} + +void HelloRequest::Swap(HelloRequest* other) { + if (other == this) return; + InternalSwap(other); +} +void HelloRequest::InternalSwap(HelloRequest* other) { + using std::swap; + name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); + _internal_metadata_.Swap(&other->_internal_metadata_); +} + +::google::protobuf::Metadata HelloRequest::GetMetadata() const { + protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); + return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages]; +} + + +// =================================================================== + +void HelloReply::InitAsDefaultInstance() { +} +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int HelloReply::kMessageFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +HelloReply::HelloReply() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + ::google::protobuf::internal::InitSCC( + &protobuf_helloworld_2eproto::scc_info_HelloReply.base); + SharedCtor(); + // @@protoc_insertion_point(constructor:helloworld.HelloReply) +} +HelloReply::HelloReply(const HelloReply& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + _internal_metadata_.MergeFrom(from._internal_metadata_); + message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (from.message().size() > 0) { + message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_); + } + // @@protoc_insertion_point(copy_constructor:helloworld.HelloReply) +} + +void HelloReply::SharedCtor() { + message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +HelloReply::~HelloReply() { + // @@protoc_insertion_point(destructor:helloworld.HelloReply) + SharedDtor(); +} + +void HelloReply::SharedDtor() { + message_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +void HelloReply::SetCachedSize(int size) const { + _cached_size_.Set(size); +} +const ::google::protobuf::Descriptor* HelloReply::descriptor() { + ::protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); + return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; +} + +const HelloReply& HelloReply::default_instance() { + ::google::protobuf::internal::InitSCC(&protobuf_helloworld_2eproto::scc_info_HelloReply.base); + return *internal_default_instance(); +} + + +void HelloReply::Clear() { +// @@protoc_insertion_point(message_clear_start:helloworld.HelloReply) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + _internal_metadata_.Clear(); +} + +bool HelloReply::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:helloworld.HelloReply) + for (;;) { + ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // string message = 1; + case 1: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_message())); + DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->message().data(), static_cast(this->message().length()), + ::google::protobuf::internal::WireFormatLite::PARSE, + "helloworld.HelloReply.message")); + } else { + goto handle_unusual; + } + break; + } + + default: { + handle_unusual: + if (tag == 0) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:helloworld.HelloReply) + return true; +failure: + // @@protoc_insertion_point(parse_failure:helloworld.HelloReply) + return false; +#undef DO_ +} + +void HelloReply::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:helloworld.HelloReply) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // string message = 1; + if (this->message().size() > 0) { + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->message().data(), static_cast(this->message().length()), + ::google::protobuf::internal::WireFormatLite::SERIALIZE, + "helloworld.HelloReply.message"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->message(), output); + } + + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } + // @@protoc_insertion_point(serialize_end:helloworld.HelloReply) +} + +::google::protobuf::uint8* HelloReply::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { + (void)deterministic; // Unused + // @@protoc_insertion_point(serialize_to_array_start:helloworld.HelloReply) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // string message = 1; + if (this->message().size() > 0) { + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->message().data(), static_cast(this->message().length()), + ::google::protobuf::internal::WireFormatLite::SERIALIZE, + "helloworld.HelloReply.message"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->message(), target); + } + + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } + // @@protoc_insertion_point(serialize_to_array_end:helloworld.HelloReply) + return target; +} + +size_t HelloReply::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:helloworld.HelloReply) + size_t total_size = 0; + + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } + // string message = 1; + if (this->message().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->message()); + } + + int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); + SetCachedSize(cached_size); + return total_size; +} + +void HelloReply::MergeFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:helloworld.HelloReply) + GOOGLE_DCHECK_NE(&from, this); + const HelloReply* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:helloworld.HelloReply) + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:helloworld.HelloReply) + MergeFrom(*source); + } +} + +void HelloReply::MergeFrom(const HelloReply& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:helloworld.HelloReply) + GOOGLE_DCHECK_NE(&from, this); + _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from.message().size() > 0) { + + message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_); + } +} + +void HelloReply::CopyFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:helloworld.HelloReply) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void HelloReply::CopyFrom(const HelloReply& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:helloworld.HelloReply) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool HelloReply::IsInitialized() const { + return true; +} + +void HelloReply::Swap(HelloReply* other) { + if (other == this) return; + InternalSwap(other); +} +void HelloReply::InternalSwap(HelloReply* other) { + using std::swap; + message_.Swap(&other->message_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); + _internal_metadata_.Swap(&other->_internal_metadata_); +} + +::google::protobuf::Metadata HelloReply::GetMetadata() const { + protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); + return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages]; +} + + +// @@protoc_insertion_point(namespace_scope) +} // namespace helloworld +namespace google { +namespace protobuf { +template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::helloworld::HelloRequest* Arena::CreateMaybeMessage< ::helloworld::HelloRequest >(Arena* arena) { + return Arena::CreateInternal< ::helloworld::HelloRequest >(arena); +} +template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::helloworld::HelloReply* Arena::CreateMaybeMessage< ::helloworld::HelloReply >(Arena* arena) { + return Arena::CreateInternal< ::helloworld::HelloReply >(arena); +} +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/examples/cpp/metadata/helloworld.pb.h b/examples/cpp/metadata/helloworld.pb.h new file mode 100644 index 00000000000..57f6817e310 --- /dev/null +++ b/examples/cpp/metadata/helloworld.pb.h @@ -0,0 +1,419 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto + +#ifndef PROTOBUF_INCLUDED_helloworld_2eproto +#define PROTOBUF_INCLUDED_helloworld_2eproto + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3006001 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: export +#include // IWYU pragma: export +#include +// @@protoc_insertion_point(includes) +#define PROTOBUF_INTERNAL_EXPORT_protobuf_helloworld_2eproto + +namespace protobuf_helloworld_2eproto { +// Internal implementation detail -- do not use these members. +struct TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[2]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; + static const ::google::protobuf::uint32 offsets[]; +}; +void AddDescriptors(); +} // namespace protobuf_helloworld_2eproto +namespace helloworld { +class HelloReply; +class HelloReplyDefaultTypeInternal; +extern HelloReplyDefaultTypeInternal _HelloReply_default_instance_; +class HelloRequest; +class HelloRequestDefaultTypeInternal; +extern HelloRequestDefaultTypeInternal _HelloRequest_default_instance_; +} // namespace helloworld +namespace google { +namespace protobuf { +template<> ::helloworld::HelloReply* Arena::CreateMaybeMessage<::helloworld::HelloReply>(Arena*); +template<> ::helloworld::HelloRequest* Arena::CreateMaybeMessage<::helloworld::HelloRequest>(Arena*); +} // namespace protobuf +} // namespace google +namespace helloworld { + +// =================================================================== + +class HelloRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:helloworld.HelloRequest) */ { + public: + HelloRequest(); + virtual ~HelloRequest(); + + HelloRequest(const HelloRequest& from); + + inline HelloRequest& operator=(const HelloRequest& from) { + CopyFrom(from); + return *this; + } + #if LANG_CXX11 + HelloRequest(HelloRequest&& from) noexcept + : HelloRequest() { + *this = ::std::move(from); + } + + inline HelloRequest& operator=(HelloRequest&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif + static const ::google::protobuf::Descriptor* descriptor(); + static const HelloRequest& default_instance(); + + static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY + static inline const HelloRequest* internal_default_instance() { + return reinterpret_cast( + &_HelloRequest_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + void Swap(HelloRequest* other); + friend void swap(HelloRequest& a, HelloRequest& b) { + a.Swap(&b); + } + + // implements Message ---------------------------------------------- + + inline HelloRequest* New() const final { + return CreateMaybeMessage(NULL); + } + + HelloRequest* New(::google::protobuf::Arena* arena) const final { + return CreateMaybeMessage(arena); + } + void CopyFrom(const ::google::protobuf::Message& from) final; + void MergeFrom(const ::google::protobuf::Message& from) final; + void CopyFrom(const HelloRequest& from); + void MergeFrom(const HelloRequest& from); + void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) final; + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const final; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(HelloRequest* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return NULL; + } + inline void* MaybeArenaPtr() const { + return NULL; + } + public: + + ::google::protobuf::Metadata GetMetadata() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + #if LANG_CXX11 + void set_name(::std::string&& value); + #endif + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // @@protoc_insertion_point(class_scope:helloworld.HelloRequest) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::internal::ArenaStringPtr name_; + mutable ::google::protobuf::internal::CachedSize _cached_size_; + friend struct ::protobuf_helloworld_2eproto::TableStruct; +}; +// ------------------------------------------------------------------- + +class HelloReply : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:helloworld.HelloReply) */ { + public: + HelloReply(); + virtual ~HelloReply(); + + HelloReply(const HelloReply& from); + + inline HelloReply& operator=(const HelloReply& from) { + CopyFrom(from); + return *this; + } + #if LANG_CXX11 + HelloReply(HelloReply&& from) noexcept + : HelloReply() { + *this = ::std::move(from); + } + + inline HelloReply& operator=(HelloReply&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif + static const ::google::protobuf::Descriptor* descriptor(); + static const HelloReply& default_instance(); + + static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY + static inline const HelloReply* internal_default_instance() { + return reinterpret_cast( + &_HelloReply_default_instance_); + } + static constexpr int kIndexInFileMessages = + 1; + + void Swap(HelloReply* other); + friend void swap(HelloReply& a, HelloReply& b) { + a.Swap(&b); + } + + // implements Message ---------------------------------------------- + + inline HelloReply* New() const final { + return CreateMaybeMessage(NULL); + } + + HelloReply* New(::google::protobuf::Arena* arena) const final { + return CreateMaybeMessage(arena); + } + void CopyFrom(const ::google::protobuf::Message& from) final; + void MergeFrom(const ::google::protobuf::Message& from) final; + void CopyFrom(const HelloReply& from); + void MergeFrom(const HelloReply& from); + void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) final; + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const final; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(HelloReply* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return NULL; + } + inline void* MaybeArenaPtr() const { + return NULL; + } + public: + + ::google::protobuf::Metadata GetMetadata() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // string message = 1; + void clear_message(); + static const int kMessageFieldNumber = 1; + const ::std::string& message() const; + void set_message(const ::std::string& value); + #if LANG_CXX11 + void set_message(::std::string&& value); + #endif + void set_message(const char* value); + void set_message(const char* value, size_t size); + ::std::string* mutable_message(); + ::std::string* release_message(); + void set_allocated_message(::std::string* message); + + // @@protoc_insertion_point(class_scope:helloworld.HelloReply) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::internal::ArenaStringPtr message_; + mutable ::google::protobuf::internal::CachedSize _cached_size_; + friend struct ::protobuf_helloworld_2eproto::TableStruct; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// HelloRequest + +// string name = 1; +inline void HelloRequest::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& HelloRequest::name() const { + // @@protoc_insertion_point(field_get:helloworld.HelloRequest.name) + return name_.GetNoArena(); +} +inline void HelloRequest::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:helloworld.HelloRequest.name) +} +#if LANG_CXX11 +inline void HelloRequest::set_name(::std::string&& value) { + + name_.SetNoArena( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + // @@protoc_insertion_point(field_set_rvalue:helloworld.HelloRequest.name) +} +#endif +inline void HelloRequest::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:helloworld.HelloRequest.name) +} +inline void HelloRequest::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:helloworld.HelloRequest.name) +} +inline ::std::string* HelloRequest::mutable_name() { + + // @@protoc_insertion_point(field_mutable:helloworld.HelloRequest.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* HelloRequest::release_name() { + // @@protoc_insertion_point(field_release:helloworld.HelloRequest.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void HelloRequest::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:helloworld.HelloRequest.name) +} + +// ------------------------------------------------------------------- + +// HelloReply + +// string message = 1; +inline void HelloReply::clear_message() { + message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& HelloReply::message() const { + // @@protoc_insertion_point(field_get:helloworld.HelloReply.message) + return message_.GetNoArena(); +} +inline void HelloReply::set_message(const ::std::string& value) { + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:helloworld.HelloReply.message) +} +#if LANG_CXX11 +inline void HelloReply::set_message(::std::string&& value) { + + message_.SetNoArena( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + // @@protoc_insertion_point(field_set_rvalue:helloworld.HelloReply.message) +} +#endif +inline void HelloReply::set_message(const char* value) { + GOOGLE_DCHECK(value != NULL); + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:helloworld.HelloReply.message) +} +inline void HelloReply::set_message(const char* value, size_t size) { + + message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:helloworld.HelloReply.message) +} +inline ::std::string* HelloReply::mutable_message() { + + // @@protoc_insertion_point(field_mutable:helloworld.HelloReply.message) + return message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* HelloReply::release_message() { + // @@protoc_insertion_point(field_release:helloworld.HelloReply.message) + + return message_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void HelloReply::set_allocated_message(::std::string* message) { + if (message != NULL) { + + } else { + + } + message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message); + // @@protoc_insertion_point(field_set_allocated:helloworld.HelloReply.message) +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace helloworld + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_INCLUDED_helloworld_2eproto diff --git a/examples/cpp/metadata/helloworld.pb.o b/examples/cpp/metadata/helloworld.pb.o new file mode 100644 index 0000000000000000000000000000000000000000..85671e8aaa3b10080aba2cde1b103fe994eaa612 GIT binary patch literal 111592 zcmeIb3!GI|*+0IA1B#?FDk$$CG-Pc}cubX3y(}t9kcqWv1mwCaHK|OEFI|H;%!F67uWS-)@nVvazrCe9Z z^;WsArt58T|30~{p=-a~zhACv<$60^*U9}Ibp3$bub1ncbp4>*e@Lzy=z5pj-%ZyK z%l$^Wenjp+D%X$6^&Yx@oc@18p6{jWCi;J$Jb#j|pOX8{a{V-2KO^^_rRx^Czn`xE zMgKoX{~r+S^KyMqu3wPrR=R#s?!P40FUxfsUB4pt57G5ux!+FLugd)+bp4v#KT6lH z%l%_?eO&Gb==y}*KS|eb$o&qwepBwBlIzoS-AVtyCC}fc>v!b-8M=N~?!QOZ@5}ul zU4J0=KcwrAt4FPAoqWy>pr>PPuKsJ`#;h3MY%s9*FV$sCAt3#U0;^_ztZ(@ za{qU_9+dlk$n_Pva-pYx9#?`Pav!1VP`MvQ*CXWqNV*P}`=jVOLhj!r*Q4cn3|)_v z`;l}lmHXr9dc549AlFfJeY4!3NY|6(el%TAmitradaB%?M%UBj{tUUEDc3T(j*MWv*rFAxxR(2ZO1kbF>$!-MT6NWht$)Q{DwRQT5PvABRK=_s7|tD2;82cRH89$w zKf@ppweLLkizcR`sf&DuF7OkVLa=Kt)uAm^hc*#CU4_@TjUcvd3z?B+8-syuOth|P zI1z7R;`;tMd+YmSd+2!&U3b%!@+vk+SNiX*+EcRXV9Cf0Tw$*hnw@mrNi+j=r96*q zrz`yrXh%LYKn;Pe<;Q7avA6%peZzGz?SGOYNV8w{>5&YZTPo2{nVL!XCO^F<-A4NC z5Z4omdTkxGI8WC1f6vG;j#uvSg`pz@$FHaQKNmeuu9FgBv5u+zd@|)$+AFfjHp_cXczO1ZT*ED)nNwUkMymfIMt347|-ay6h!-SGO_Cr5s8K+58++?(kb>YC`^fG+Dq$7W4l;bh-foEKc>1kv1-+d=iaky_}bX!+Sqg5M{egR>bBT`HL-{5*Uh2-vCUAh zU*G`{G2J}!HXe40e5!*b`ZjFomViiE%2kogq;gZDP5=Agn88&CZytHCq%Pg}bZqdI z%LCay;&2SQC4Q_~<{??SP1~?t!(j2l`|CM?MtWy6Qm5tpg)h z^R#4bY`<|bH9D(#21L*$BSx-Xqn$#zFBPJnlSPHVZ$BiXxuqJpn#a%-59FFnHNRPC zz3%zcxTXJ>Mgk8{M-(2)ot+OOs857MPh3TpzEM+M)v@8lTo+md9jj0H#0$!?x_07f!Ha5 zL~))Pavn=WgT@E@j#l#a4HM($kimXw;-;q_y*Zb?*?)k#%PnhS+X`{%LS<#h;jhl6 zTe4hA^$nas)tsuj>BYebx!jt1o!v@C`)(!M*k0;~gFcoT_9j(SpN{dAl{-j_fM3EGTTHVK$W9?n~k})1KDNu7gEXjLGA~&df z&1@E-bly79dp6Nf*>m@-*@;NE3D0)AZYN$U@$}y``XC>hTQ2=XY(^$e?&ARw0`y46 z`aX4*M(N1)vd~(!W+biX8#8?ALvv>N8#8>%1on*?zTfG*F~fgjhVQ*G!yljyO?PlP zI<%eP4h?}fX81IivCI|{7 ztsCt-UE?#hn%Ba?0uDvnwyhj%-doeYiS_%c=x$=b)bXM#C(H_LkA6C;rdj!rq?l3p-M+iH-}~J6k(? z+maV9Or;ifBrojhPNh@xdly`o=uUPfdeYtPoeRe;QcUz`N_}j~^s)ts_KsxRMP==s z?dkSJM|^3bqc>SL=F+m6a~c~jDkHj~^uMm`%+j(&$&QZHvQ&3R+qkaz<62t@=fHLi zm#eX{GzV^Y%IM|@q2qfL&xRAE!idsv%<&@vr2MoIN7u7qvy<=YP4=XZKYGN_&cu@B z=#sLMu}77kK4OH#c6BU2e&mQFmn3_75(_1|vSGxLS9B+n>16lumyHu)C{uT(U2*q^l#@1GJMzDlu2H_nJ6$O(mZk5~**z zdj1hAm&WUTmJYS!I7P-EnfW&MEepC+OU~sS8=GF#-gB!U`UqSUov?VLljwm)W2(-JoF>#;+t4xCB0OAZ}bzbba1WZ$nS!k`?-n;iljW&JDm(?)<* zJ4>X#^~Vm8as7i&?1}J(hK48h9??G_`Z$$lpUc`(+U8QfvA%>AQrb%?p~`MfHzTVC z$bdZu1zokj%=Z!Ri(-nkbzS_njz`Ra|z?sI;mydV#M?eGljuW%&u(a!#-> zJ=5x7KT?0M9(&M^mD<>zG`|QX!$$LdOp-18G39C&SFtPwX;&$uS9D^CQGxcZ}SS)%V|Z@PEy###LYEd#|^te%y&8UQ}UiskxL@z?TpsXuV7ZQULJ!`N(W)xh#q$nymRWB&!4Fz z&KV$xmY@7rCG@zHD7MppWh>op&5R;Awq@#?PoJTgHxb3AObQ+)ZRFQiG*a5=^kS1BEO7Ai4cIM9Ba#<*OEr>n%GGP&*qWze?;}6UODX+|N=&9v42`kgN2O^E5%8Pb zHLFwfcjc$~Z^mFt-d5fA*^e(X9WO1kl&_BjS& z$2Io2Ct0{sLOm)j5<8iH&e&^#NJ3)k7`M|v&v}l zjUMWUs7LPaCBM(vL;Vi#+j~|LKwUF&QO-~&PQ4e2r;;Rb#<7Z@a2krJZk8n+Qo9j_ zkhrPOP#qeP_ysZ0Uus%^<2Q2+?JywweUW+$P~v+__om!wQaWM>pN{b_WoX0U%a8G( z+fR;i!dfq|olD>D{@z{0NTn=xaBXZCZQ^-4#y`Lz_5+#h`}OXggZ-r=A3P8eA`%YJ z8#bO1kQ+03*|q~~>6ObN8a;Wmp<2cuyi1l;>k<>l1gAVzpE*G>L}uK>Kair$j8e3* zbOlnW68beR5KYBy^#E-bg7QnkGe(2D2hS=!#s;I!@2z=^00|ka&)5NN((s?vD}}03pYbQ5j!v?4@)6&!B$e%3<@ptIpxse%A8|M^XIw!#0$7^Masd$V9nj$T{ zTrS3PHzdvDpo!N%Fe2DAd{5ADhq||)!AzA32<_q*^qlDpmSc+8Kc zpaY^;+Hs-bVJT&UnbXNGI-tcJaK~$6V{qMY)rbeVNWZEKZ5K@Q?mV)^WV8CYBNeC2 z>9wMfu3oJOgD*3BUw>T$+e#7c_K%JU+9;hFH1rFs!m)YqV}a1LUuUKNbIybHGL|Cq z_wr!lboDbu(>G<#R^+EQzLBq;tjq%EKbiW;iVmugj$SD`V3MuM8x8lA_2P<=5Aox{ zHBCcJar^hnJ1o1zOzxal?fGBnhqK?V$#&y@`o)d<)eUc1<=v>VKUFUFks25NHO6`T z!!1?#1H=sUVCy2SY4lPvOpMg<1shb?d_1ku0Yd3F1S__Cz2`s9YtyRT<+kzZh-yur zo-$mws;0i|e&O@n%If;P^{Lnw_+8K!XbQ5GW+fy%Ad2jK z2~y-zZWA1Eah|;q{vYtb%xe8Qu*SR&tZDD07hau-j>_5wxtozpC)yI}#MSNTMU(ht z;p9Y5vSDU(MLarTPUqsz)UwWL?a7X|=43iHvpE{CoZ#e)#cHRdI@5{v&SZD25ckb& zPEU--Tl@N=(P-uTL{EEbT)(PpXl+hMqpgb)-SKpHqCMTy&>Cw_(4SaNxig~`!K<%m zg?jHcJ4x@pa&iThX7X1Gzk0c7mvF_DDHoNEotm8Ap6D!_IBxv7iVG&3t8ZB9C=p$9 z<7}^_ue9XUqmLZEo@P0x5zhZP9M69y9b0f65oWe-{W8$w2;;&_# z!kPTX#9tG{-^4ftnqvj=y+Qmvj8jlH8va>9{G&SBJAtnzer6E=oW!4n@z)3Oha~=T zjK496=kK*}xRC!C`8Ndd{QVOSXY(Hu9}nWMmG~1e{_R2hO%gv9<8Kb)?~(XP7=Kd` z|ER>Dg7I^L_~#^k7RC?J8FU(9ha~mwwG_X+qi z8rMZ`AG&H-CN@49(x&8ae3Qhx z($ppKt~#||;!j5TEkT;M=7}Ga__rW`BH%wD@vb^ssuJ&c=OF*QfWJcGUHnZFufEP= z{8JzBcS*eZy_1P=3gXx2k-t^qUG@!1d>z{V?m+$liFeic(qYW#dFA}a*mqsPUm@{l zVLY@cO%h*?@$U-wyCgn_@k8nq0hgck65o;$uNys%-zxFvU_9i{pv2qSoHF96k^HCi zrp$7FRbb;N-uOb{t^CLMV15u^CGoB@){-YaE%D1x{*Z3p2OILlZng13_^2Z}!t-45RTBReCNlnkI@Tib=V5#@(4UrgR~^|P@uQKy zIpE(W@n>NCJA(LKdE#G|cvl@BrKX#n=d!O#;$8N&NW9Cwbe{MP67RBaTOR&h5`RAW zhx#Qh!dyOH&ci?IC}yNpWBz0ESNO*gbd!{y+vr|3Cx)g$_bWrV1Ee_CHBV%nMEAa| z**czO?JPpp10u^do?=;}Bwx4DeTH3R`;e>0l@5V2bWmiu#tx%LkPr&4cBV$+E11Zn ze{qoRxf1V^-zV{|vE4?AS4lGRCkOJkOFXw@zJ6%Kc1wI2#=leZpG{aDXAp%C)Bh}A ztqbTD3EgrUD~0JIsS-uV`CP9W8_&Cdg&KRw@2x~pM$lG~6QlbKInegsE;3y0$^$uc zuno^h{9EbXw*lJi{SxmQdmMcLennuO*8?q`e) zqKTXpQAA9W78?GhUk1$-?N6rJC^XlFX_^C{KPoi*O+{Z$WV9mSJU&~>z^~{&!{>TT z_hUAQ=^BM@8_CI_yOPI#kx#Qg_V4+sLG->Hn8!4#M|l>`(mz?k$m-HrO@T87xUCW*j+Dnikw{a zVzbC_)r%cDba1}>R^natVyMax_dNG(iFehDsS=;7UMv!tT=n91p~+P*whB$Ida+Ar zT=n7-DFgZHMVrv&s~1yCxv;tGMO&WuTP0qZZR!=QBW#vS))Su@%I>C+>ny4_*gn+l{YBieata!qXm-TQ3@x0%wHG0m+7&}_*=quPI=QRW#x z!hCvvp7^6x$KZLh(bge)!AG@!5^w8sIUS7>KZyLC)~AB@r%PyD6EGg8GQp8?SnE@A@R2Pdl~UGN&Jtf9{J^6_fb1cAC=CdV?&oD7AP%i)kny#@1DN;#=~>rzL(4${(T^f!IGABwm?m z{4Z-n%wh{%+=hC8e#I6S@ou!iUc|e}fv<4j@5#csIVtf1ob50n;@xa+Gp-SDWyZ64 zhe>V6- zg45Ee3I_j%;Hrzte$#$boNg z;CDOljSl>y4*X*d{2mAX2?u_!1HaFKf6{?(cHp0O;GcEi_dD>CTQj*;tga1@)Yr&bl^K2 z_)`x2X$Sr-2mWmb{)_|vo&z6r;6HTWyBzql4t%!*|Cs}S&Vm2Zfj{rSf91e`+c>e=W z!EMC*NALi55$~Vyq;I#2e3N5F{>xGyO^QbYXT#2VI@uxOo#4PnIdDF0Cp$#E(GHwX z;mHmW?=%O_t3cTy;+^ThO|ED1L_Gf4X?BQsXE|^_J`4Yx!p*EQi2jbkV*wy{#~jHw)3Wdeg$rt?-U4oPmgUO;$c?+zJyt4c;w*`cn(a@=dRv8BP6cCLm7{ z^`)5XDC&Q+K|&%Ks}TVS^~=En+(o<*@D$ueJb8H*Kky(JslRsM$2xF%kraxJ z_^UIS5!AnD0`e5mJ4mzQsNc`R7>M}0QZu6?9<~ZWT*Nyuc!0Zzev=J|zNK+O7RErt z%dYPl&#vzpS1Y7^n-OSSk@0LEBA!~YHIM!^;+^5&;|+~B@X^1IcxC=Q-bB1H_~_r$ zIK;ol8ybh;qkkXqcTW0{x{2uBAekUN(fA|_V<4h;kY&ZuxFrkI^yfP8>~>YtXSb^w zKi?sTS5vb?#LI4nnJS`p{$?@II429!^k$VXGdkk05{B{Yc3#WLZs#>VAya@nMZ9VU zKGA{KIPh8revt#e*nwZ-z%O;+mpSmu9eAAspX9(NJMbwEe5wP_?q`{h#%~V#?0#0$ z*E{GN9Qc(Ee7XZ~bl@`_cy_M&}aAin*Qw$`q>V=*@3q>a5GxWjHdBnCLm7{ z?`j90Jw9Q=h`%b4$wuRiOhBF@-a8$5_IQQ~Bi?lm`s*Ed+=0(?;0Xsl-+{L}@HPjY zbl?jd_(BK1$bq*z@EaWXVh8RTH!g9|cRKKt1MhO+?{eVX4!p;KryY2&17GUE`E6i! zhC>B$;vWew^-;K?A#6Fk9~>o7l?uPrCp06% zxWZTaxEZPRDEuEjev;gMz(M~hg}=|IH$BQ96u!pCFO<76G^8%~-tXgQ%Uz4Y*ZQ~_ zao()(+kM>h9NP%D`Qar+e}_+RdaN6cX1(|LIR9pa!ygsCUO&)ZGZLLgL-}&=P9HZd z^)7|q>*KrSZq~7Od)5(N?tRFoKThrj6~4j8&B%cFx|Mr(`?%>@w-atnuLJ)dC1;~A z=R&#bCLuOCTL~=pKI+qxc`E#`!awHYX5_tu5;A5;us$$cDEbMv$$#2`|IL9<)KpUQR zq_>gi%e_w;@%r~q^z@X%H~Y9r?_U)DX&RUz9(|%q~4UtXGV}zH(d)RW}97hGxM&Chrx%a3q-?Z~v75Oco1)+0%Q60W!a@I%13#Ch^yS`Dz8oqBD$I7^?^gKJ zK0PHzh0O~8wvWG6?tb8){|Di=bXCw&Lb>;hFUOSIxWa??HM51{f-{-^ds*~pg$M6t zOuzGY2mNJbEN9S{vrO*pQh4w_!j#){$1r{HK7#ktaClVVKhzKO*T^}A3X(0ovj{Ku zcKP&XBzmX9pY?I-c2)R=L(Yj*@XFP%KQ-OCLSId|P465BeXqiQCfxEHGJ3kpfqzBe z&-wHwzkaOnU;6lYau=ZiNxApDkDGR5{xIIJxWdQF|0^G->aRkp!h`o~CV!t& z_-}lADmE%asDhMxzsthMEBp^WZrY!P3g7GF#?DQIvz=uUW3GdW{*OMrvGXqq58n3~ zJ6p(6X^i=#*xRf%~X6Jhd zXZg#7-uU4w4*G)*eE9`z&nu!W_%6fO9QeNo=X{wb9O7>8vT=;leoL`usKloTFNb{v zrr-IT!h`qngF=7Sg?9S5!h?MXWkP?u1OF=FwsQV+!pFe-&D|pBkkCIThEpnSXc0VWtC53qE3)riU)?p<3`~ z1efaP%@_Qaf}bSx8wCHG;9Y`0BKU$MG@yPrM7L*Da=rxnJsO36sltQ(9tQtD;iW=@ zmp6@PIl(>j}5n|Af%j9j)orZ=>k;fP=nqqLzRCF`E8Y`r_S5c)1tsCoz6INVrY!Wi?t( z-LYB#|CWkFhu|-d)X$gci?>zqN)cx8UkKhMxUhN0)N1)F1*hy*VS?aa5?uW@ieeTJ zE|5^_%V&iCy~pe4F%r9raBfdpLhZ>B7iqoWe&;QOkAeLRyG2e+=pP%U0aNc%f=@j` zIjr@{}wVh%5F@jeLy{Xre1iwviQ?FBkKPb4k$@_@l z1A?1+{Vlx0`{MJjg zoI08xa4_Ze2Exl>zmqAq-xvCF8OWIO`A@;0m4SdMhnLa~*Sk?=O1%CpEZr^=e74}G zeBLeie8Elmd{poaf}8TWPw=*K5=z08!;`3kX1%uwZgyz(5IzR>pN!UQ-Uhw-BgAYwr&V&mKR-r!sx^{PEWczo10a`RP4{DsnmOLo;?>qwruqSf4QV z6K-qAwm9&Im7Hw<|5V}Gem?D?U>gMD|$3D*e?EI-&U zXZ$~(aGU%z;YKDZzQuumT*(ji-AVK0{Z!%E{(R?^cKLTW@b5eDlcw9{T<5^=bl{IW z@ZS+W2KL>p5N9l)26hbWubUwFy@cERwo}mu`|C_O`GdlPeRRfe!)Ms#lrcU8b41@? z;GmB=@Y#fyWsC6^I&eJDNuR$Jzot3e7_IGUPqrqPwf7|Bt*K7>bY5?3+KXRvO=Gks z9$%PV)SXPU#S^XR_NB>q*V0&JMK+r5CI&mbil_=$Qk|{IruL?3OP9tdiu99`_7tBU zrXQo@6Lc6?Ya*TMjwiYoYOuO}VP~p4Ne?q?NmOSqf9|ibG8&J!B^M-mJJNAtSsd?5 zb+otAXZnaN{LR9~+QszM!ts?$5`DSj+dFf_S6Aicr+62Cv|@2@ZVQCM*TH#HLFr3& ztJH~mqUrAC@pKBIibPwgOS{09bpLaWjg=D@&uH(gr~FKIUzP0cX-{=dOLaH4&+krj z+ua7d)iz#r6j`g)V*%^@@qad3+Sjnzs9vwQ<0#` ztXT7yIKIM9{iL2As?1Z9J+0mCT~x_?W|558(pVKY43yS9lA<+}+S-7-fey+eZmuXs zVgW*`GKGNpDr!?GU1|D=sGMlnej`1lI^&7XHcGp09{IVVz1@pn(Ku`Jq()-togZ(A zQ%>QxL&rzsn3Y+ciz}x$r>m*4ThiXz&>ovIAx1*8Td!zzhCX(%u|1t6B9*b>CN6_$ zs*5Q6Iaa5%FriDLU(a)V)0LDo@yB2%sBgns>+nQLq01f?i#`#hD0Pw7q_^g(SI9IkX#q4|}5jO{VWCN2?oC3oEB}q*C28Q=Qi&yHl|nm^h;;tJF;y=_C2N zg^SbInUmbi`Ek(nMeR*rWqT?*aZ0K!**2>;-PN0JPSbdFNoB>=-P9Cbm7pVOX;jye zn$+E$SRT8fX_3unyNqb1X6LFpzEYC~ zr>iAZ6I;S|O%IFL?P0AN4b`Voi(^gGo71&v8kA7)vmlj=DLQdhr)o`up_Gj~tTC{z zN^z4r=}_OMboay=z3IgKjwA^=oDXW}Yu=rDqg7KVL(|Cy8BSz$6o+Svtq8dFSI_C} zNi0axm&s-Pb(kI~PHP3}n@OdXK9zo$`erxR=5BnVp&YJ^W_tS7spsSt|KasSb8PnX z<|<`)R&8+SQNf!q?RqFA6qE$5fNOz}}zj~d;J9=tVd5AlN z;tFQ%l#XPgyCoG{(v|*?SU#bZ4Ja~yD=T#^o}E}GEgCH;&>;mGrKRu!SKH9@DjS2T zSC8vXE*M9P6@7j2E}Cnn=)8pX^z!)9iro28L0zjE3PpLR1M{-9#$#aauZkbz+y&X`TV3}Y0{lWA!?%4X6jB7TGYVV z>I=WI9A8OtD+GkRIs^Lgp1+`|kZ+%!ulq(MjQH!}VdzZ|ovwGANuwXNy z6|8hv4{MNY^N4>^vbT}=wY{=y0Xk+&t znWvqI3a46^FP6KqYF20SqTX~H9Tz5ZCm9OUP&Rk#=ufr^W*8snn%&zO<8jXPrLpGm z)*(jLDQ41%X7^a(WpigI876dglwraNYKCUd@GLu>J!@EMbi5KfEz!|2pWbs7D88zB zS)wb}M1_PZ3@xPg&|^artphHlv1_WkA=^JRQ45ZPwRJWa}bi9G)1rz9XaZfzm+eMTe?TeEQEyPZXm{CI2gu#D@-A=+9 znkUC8Hdrqj$*aUh{*Q;JYsj0JRE@0luTHC*ISMT4t|{K{;|~Vl+B6H6z)*FgdL|wS?xq?o0@e z+p-#xT9l*fdsgKx#H5K+Q#snNLL@}1+ho&+c?E5EP*xHOWi+oE-4i84VeJe}q^spO z@va8nk9SP3{CL-V$Ph$%U@$wmpo7|CdSk7jLBKFMlV6DDVOxr4H@suGfmPpGTaX3v!f}iU_x7%gIW0t)(=!mkc*xtL2BYS zGj&yace*!0TM@WL%kUE%Aez_1$XHoxb`Q{2j;tKflfF#jK+|iNA0V`l+yHWALlJoa ztOeu*QoHgY(>)o5y{a>@Bx%-YvNJ7%mR^`jo;Go{FIX;Hxnk|@vfzuwD6>MDHpxvW_ojX)=Os=mcl27%K6MI;tE>YD zn{s;8kfiwK9eyoL)6xku+81`K%~{QA6C0VqF%@ys0TOV7>O5-92s_rKDWX-e&fX<~ zB|bi}nO5f7TayswyU5I?a%OD)t!^yOS*L4TX#y7Ky>Jaz&ZapL-^CYnBo@x*9kUdc zPVJIiCppcitn>@Y?Bv4s9(otXt9*y+@tihCtBneJm7uj~F9&W{%MCdVwr}jS=~YvG z**(~lN_Ft&NqrtUy|=g`NymoMb^_XFs`fH0wJvl-t7PyojrKLuR+wN^Z&DJL(@N_D zhqscHzb(kUTTRx_b2=}#1Q|!>mQX9Z9^3qVl)(l_K8QWsh-dbY)r)6Re~PQYww&{u zf*dnw*Qhw)tu@(gD)nn}=zM;??rD~37@V~_V^^T#g@~WP3}VSUcYhsBQrtB8a<8I! z5xsnDn?hB=GJwswoc-0gu%VUw7;UAh7EgC4Xd7iiE3bdH#$weS>IHxsWkbOLgQ*WGVXVHcgHLi-uRxP*Gis0p9ZS&&xF4YC-l|yT8 z&=yViB2?yVDx=-0tfGOL-oVYxeNaXDrCr!O`+F(X3WiCY{;3=fZ?W_%;*R!25AEY< zKfG~(O7~$|20pH=^xc5#=z3UJK|^9h`8`iQtvOsi-tTCAogvqomwNNy&X)GBhA8?EGbxcu&{F-3)0%~##IjTTi+NiCtxz2<$qD#AVfyF;5-bB~5H zmP)emDOJ#%#_qmsx1P39aZr<&;aV0~~_SI-31 zmB>P|Z)lUu?A(1&MvC)}4r->Px|W+2>2MbLT66mtWr)IDWn+9p55Jhy4MvnWBN=uGr+-pe&ES*Ga7n?~Azeo#28&1mLc=Y}1;>1@^uveVWa zgK%s}b0^8A4JBBcV$c@N+YkeBj%FCB9F4F$!?T;va37>!7Zv@o>PpEdTASoWI@KA_ z9^(wZW%k!O`)22k;2Z*-JAVsK5_mRNNP>|5HAoJMGl`)ImDyB2KiB?nnt%HH!+~e^ z4Y`=2z(f<>;Kzbd+m8iNY))Hpip~CoAnKGq}k!X(GfNw6j%AHH?T)pBI=!;2gBs)pLmr5P`9$P(-o!oGre zPrOY}{o<`O_v1Ddo25!yvy?@V-NJ-O!fi!X*Z+DK;h-MNn@8#?!#?@<*^ql}$k`K9 zPyf0%GW^a@{hEi@EQ7a$c?wx<=JYuoOJng?y(OhN&7axnT$-W{lZKNUc-~E^Q2L!! z4}C|67Im+j+QlomeltIwi>;oS9*zYSfeEZlz0c%S@D@xe+eM1xG*!f_;?w5LRI}eA z*_BVoqNPpLYA6A`Buo2D^$&Pb3mS?Os9a3jUnj(8(|<~i7Uw6@lLXVd*uLc|n!lbz zpHxaMi}x(2m$FOZ$?on{H@{{eR{Ej54XlG_ut z^Y%Yjb7avV`!`OeK~qZ>{8pIX5N2$L$?7%@3%?$e#TvZ~%|6nL)ENT8?S;=Dow6v| zsy^;Rzh=XYi)!r|Kc=E8ewHB_o7Toh{S`~c`lo&Q)3>H#YI{#B{UkDDy;CpVWN9`` zw4TtFXid(c1!sRblYX%krQ$=c783K@mqz)WOlt>iXjboFsBkPuacWwc|AVDL4503` z$X6hWF*AK!ReIVTNz9l7;iN%(AR{_^&PB~(d#Xo$jzWETNq0fDmHv%$I!`$8?#K3K)L~=*^cY z8OL;)FDWwqFwjq@dk&0ax~>vDoURU_{|d-?7vQ%5-Us-0z*hi{^mhRMb)f&K;B3!h zfZq@F?B}8K{6(OD9O!of{Ud;XAMmdM{w&~~B;VxwF92t~`{_T2-wDok4uG7$0{(Wu zOW5%gnEnaCj|Uv-&jK9j#{rJz@N&WV@+iok1~}`UNB=oY2mBjA9|!zNz!w9K{_GN* zWq%XsZvy(S0=@=t_UCC7$6+1Fc^c?90R0ZYKL$9KhfN@d%Yezp2Z8=6z`p`Gr=d+* z<9X&BERIJ1JP-6A0Xe@1oX-?7?c44t@_*H_l53pRl8|X2;?*$yw`w74?y$=G8>3th3q`?09AlNej@DBri1>hS1 zZvlKE;BmnD^m5~e#ehEuc#q(G;kL`rzaQvP{-*#>0{wQt(f>ODNB@6caK51bUjlm6 z`!B#TT_fTNxDfTNvlfd3TabP3L8@z-RH-);wbwEx3^^VhEp z{SLra0{#QQv0d5?IJQf_103to9|6aD^djJ!K<^1hus5|o(f%_4ZwC5n0KXgX1Ay~a znN51jjtu1Q0sLvek^Ucm{|e}j8Ls89|9=g5rQlp1egpU%z?TBv3-}iRe;?q>0N)Ha z)}sdmXM27N^p7~`p9FgDTaACd1@xRn=6sReK>vH7zw{^~q7ZIRW&-{ppr0=|+xZ8; zw*ft->rtS`_Th&P`kw(k`eCnw{s7RUAN~&X=!YXlsN||~1^VH5!PyUJ|G7Z_0;KmU zpzi@Z<-oTCj_vm2fMdJ;lmq{<;OzfDg5D$Fq|+6)f280{kN!W$L4N_zqyH~<&`$w+ z^#7GWkN$rL(4+s8K#%^v3Gf>sy`Kjh{r{8$A1MQja5+B_aP4#`{o4S)3FKc6_yWM20slGR zw*$`Q;nUhY?<0bio7yul{hr2-z+W#BC(a$H!$NM>5zl8ic7w{JW zZvh>2OQITx*Y7lcJkVS>Bp-acpUJ0puf?9e^_w#|3RRi zDF@?(^F0nY_WSPw{7#Vb0l;ybc{kuV&ir@?XS+B&0XWW^b^?Bg^h$H*{T6VXH@yrv z&YS)TIIg#Na-I?U0mrvT1O6{a?-;;w{C@%9IR38@oYRTr^E#l%^tJ(x>0JpprguHy znBHUL+@)~-o&-47>vI9edR+}TmfJ~y<9uoc;9J3Oa|92!106t*@>c_n?Z8I?NB@5Y zaP?dO19~2Zm~-PE0eT#tpDE{^ae8sQS^+rr z7gGgiJO2Rbx*O;*U7rAYoTqGa&_4?F=!b7R=zj?G=!c&IJ^EoU(4!w-270vrO>*uV zrx)jmHG;F>a9;3s2mVpO(a-k*j_vjq2mY|&Y!A*8UjTZv|Ia{={y$OLm>9{qm>(4#%q1AZfvw+{f0{@>!j{|q?#{~+M#|5qINv2xxY z`v>QValymoq0fQyIp-Y0^=>ENXwUZ@_)i39dvKok2cSoPz6kVK9)`)mR^jq+4B$6` z|HlBn0PqQb4<%uy-|Pe&=SO@VI|sHO=ZR}W^k#naA)v?k(We2&`O#MZ$N9w*ApaP! z^Le2EGo%f-_&i+4G64b|v@<2Z3`y{}z-){!|PLT61z;T?}2RM#1Zw}!y{PrFYob9|0Eo^{+tQ) zr+}Py06qG%9q7@Y%K?7~{P01*(Vrg&`RJc5fTKUZ3^>yN8srb9v|Xp&<^2KZc`t$K z@BRezje!3ZaFlaM@bgIS44@x+j#k99GXZ~--~@T!0Y8)i{%ydu6q?J@4ewJjL52fr z98w4Lrd~4XWq@BQjBL*pfL965^bLSl0Nx0Az2Gc|&ssKqJKsS+4(Q(w^wof4K8^*v z1?Z=MeC~fQk>@6$$Nsl9M4y)D#Xyh!?@GY2|NRi)*nfRRaQ54^VCPR9_)89a6!CHh z%c*wYQv_%KWBb6q<-qv$bZ_#7`(h4Z`R{k&+}0U-Y)^R2#NctdH}Zc1IJPJMBRJcG z?KAheMot3coFO>VV|y|V=&?PS1oW8RYk(fxlO)h%`+)m@upGYILH}{Uu{>-69Ob`F zCs+9&%WaL|oL(%qrhc(FrZ?pl%Q=?Y`5*_&Z8zX(=S_fP`MCpd^yhy8j&e--XZta| z13-`d{0`tqkL}nTC=VA3J^KOiM!;tRz3~In^IkzyK4rUs^8X^h&H5SBw*xM(D;51> z!VR4Z$M&`p>>u<4+LH!)8TP9B+XuKzUz9z)fY*wAwtq6<<$x~-+|aWyA-PN+kyUY<*@yCft&`AkM>** zINB2j9R0&>4hNRM5#*ykZvb4DTU2^KO1P;n@)|G;FIUpFAC`a|l>c$S%Y>foan+;y zfL>lJDZQTpT$WLD;x_|5*3&J3qx}B@9Ob)kl#le-j+t`K_Y zpvU%MCE(|P-unPY`Y!^0Hqd`n@Nhjvd)^H6h>r#w{W%tJ%-?eX9}o7N2RODrzW_hr zyav}9CW4%|ft<@BUA%^8{E709037Axyt`QW*#BaAM)_FY3ZZwEbCmN=@B`-i62P&X zJPiK14*dKBpsxV`3?Uj01bH~Wcr)Nppg$dOoL`vv5tlcdU+~8b(xse&{8MSwR8&hjn>9LG5XdnP^a5_jeP%oYc$p9|ZhphUkZG?N zzn}j|F!h(A&jDT|@eFkVUI+NQ0Ivs}*S$?>0{l3@=K@{__&mVPoSLCUfDZ@yF2LUe zcpu%0le7q_Dhh{1akfg z_*}q?EpN|*oGy^_-+=c4z8CP7fV;}ur-6Pw(C-6$BjB#`_7|YX^7bO&TR~2-u^gJ;))h*B1(aLE!}9AL@*9BO=x2H!Uxh<1IadOGA##}f zq;oPgu>3auBcV*LOl#(P4At=;3XB_H@$)?XLxFMrZ^BBsF}N8AYyw=id@5uB@X>P5 zmpyXNa?F~Bg2ZOVjcmrt054-eLLJ~^3`kcVBXM9k}j=oUes=sdryaMnlz@vb-0A2}r8gMhm;ph#3R{{Mtz$XB{ z3-D^dUk2RFO*ncK51=S;x@y#&{!;~bE#UaOMKiYK=rqt@0`waIH*;Z*-Uj$(K)(xc zGZ*9NmjSN>`cblg#r97EybAEifVTi%4|p1Iv$n?38vwr&=(hnr9q?U%Hv;}L;ARbw zqyGi?OrRePzrULWcn#o9fX@Z|?SS_IJ{$0jfSWNtM{ftb1?YDJJ_qoFfL{gpXlZ0Q zU#i|CpxS8W{^l0e}*#0=s*8n~b z@VS5|0Ph2QKHwVxZv}ii;BA2K20RJ)LBJOPJ{o?1w-E3ez&UNk*OLHm2l_U^ZvgyO zz*)}o61NU;mSg(wt$;IqQrhCd5YB7;9DWKo%PC`!!Xdy}4$o;hoHjyV`H}z67W|SB zzD)3IL-=O}zX|XjEmHlx2XH2RQs^HAJPq{E0p1JvA;4M0w?)n{neg)?r`NR6X9Lc0 z^Q9d(zY{d{Qz?!^V~GAaX*WAU_y}otdI4v>rY%?xIO}K<`mG^+so;Yle6!#OLijU+ zm&%I+md*cvDR@N)|C`_~A$)6 zmqYkw!AD6tOu8Nr{B*!MU8byG0yy(bJwYcp1~}8-qG7KMaHfB3l#aMHgzp#J{4S4a zSK!WxD3 zA^N4V;Jqz`?~wi9=680+o^n~}Js6^|J6+2!k$h%)_Rj_ldu4!gT)9j#@b`C2|4E^* z579p>laECqd{micSQEl$3%(_U&lh}W2;U$${w|O0Y%8Zf6pofj6l47VHo@NvINSe4 z`p=;TaHijUmV&)WfHVDfHSDzkzEm*2tO0x(;12-a2lyc1%K<+C_>F*gN{7%3R0{%h3M@xId_J0WQ8o)OIZrVSlzYFj_puZdNjevg`@a=$a1bjE(9|8Oz z;2#Biw6u$C&&L3-0sJ1o=K}t5!21AaSx=s=BR7U{e_d!?&+;Yd#C&fYodcw=i_Bej zvLi8$J|>s;#_<_G-njWaJ>IzPlz!ldaq(+9mo1?WfGRS2YU^lP+8ie$W@S3QBNm^a zIi2XF??qNFNiLzI?c%BKwj_N#v64P6i3lB*-qucsOn3WyS)UE8noNfjMXMWA3oEB} zq*C28Q=Qi&yHl|nM7fwpAIhsvq*HWONke;#J_p(EmS{izrm{jEwR2U1P9aK)M7euiN5K|Cupg!H-`Dc$qlqt zsZ)pb7cuED^NBO``LraDGNb5EFJ^p0+375&_GtB-&Yr}ABpo+2RUgcKn0AERS8(#_ zn2%(7W=i?wFjddyubKNv&&oJ=+AHWh7Ev91nlyK*bqlMKe0+6jIczsp(V?g5?$q-C zkosD6E__QWwxlcls%>ypd8hL$D|IQJomeLIDn+ePvKw;M$Sk~g)HaxNln=999)4cx zgVz1yo3V}`UMt~^TS&({C;M8HUFkS=V;xEAjI#O+r+=eWuY*N?_gR!FmC;O7UTt}Q zRepJ`jX6A*MCEK|{=o68YsBd!$eKOY_oyjZZPC>Iw#`V&q-3y)q47goUsiRy9}oU52Me&nd)$6$r} zJnXFK1T}W1G@4;^$ZL5A(SCMjiLQYYFn#HVdH7|%p}gCQ3hicZ)+RXxvW!@ z9qmiFfl)SuN9j360~J9NH=YV&;WZ17faVj4c`i~|ot(%`Ve^zJTneM{Xq0Xn=)>@n z6Fppk3X@S;HLJ6EQE$2}wX9QygmRJ~jbd`t=&aL63u#-!Czk5=wU90~OI;yNb6A~! zU|w$DWa%%!@=XQoUk)eRXY)A_zh(2lV;ejEGa{Cb+)tcoC_jw1E6Vx=O zGtof@crQrM885Wf&_hc^w89bY=`+vF%Q!Y+{LJLCqUp0wW;Q1^Wx70vUX}2m8D$gv zX_!0Fs^3>5shO#(+Pl-e2|flVQ)vb_oFH-d4g(@b-k_K?Oo|qw|^Q=vb%s*sE{6~fELOZgM*Q5^|XMwgvRUfu0(q`A59iBhn3MN zm`|u_OSUGK$LUa&cn_U2-$e&Z#j5EDBp%Suq`6`PpEYHG*ep6}dRB9Fs80>4m|dKX z@mV^mNXNvSI;Izy4z~`I$EqlEHtm+@BP#C8(a&^$R#vC$e6OXnrgf<5a|QL)&BrHPJS z>I>z-v)RPZ+!!hy?q#mm{rI@Yy7X0xk@H7ijhxIwM_-Mk@cE+|vSpFNLTHo?)0{r~WRwpRZiR?#CjtBrj+O^5%IFjN*Aa+U?qSY(k2 z$;~PY zq`rB`-|vv0xA<2Vf4znO;v)E)Ec}-i!Eb)+hW1}p1phqIFF!|7>3@*0Let-2v43(A z`qLKu{5`lr^{=$(pIQXJ+4GJ57P>s{{ag>fA71{^dA)d zQn_AFybVS04<}j<$j{&DEmZ$#;m7jJzrie&|7_vM`nRA6{_`#R`FnST>aVfze}Vi_ zC_lF~9OP#es{Pzb&xP{O6@E-Ve@CTI{&^OD{=QG4{EIC7{GF0Q`OP<9F#mgs;O8?X zIAHpFi{QW2!oRc#e*T6g2ef}#5&ZmZ%P>EGFSStrZMN{=SOou83qSj`Q2mcu`1zY< zh4SyT@bmX63+3Ns;a^zp`$Z}cg{EKq2$ATq{ryrA z{H6ROB?_2+{tj!Q`uUrHVScU?h4S+^)x!K=CZJG${>ELH|IQ-x*ID>C6v5Bm<`3(? zy9oZd7XA+x!QW=#-$n)%>Ob?{aqNG-QUw34q94mIe}}A4{kL1}-&6$uMhicGcdStT zn=Sm@rWVS-)xyu;^(vJAQQ=4beWnQh9TxqcErNg0!q49cEY$wzEd2aE!9w}>TKFF* zg8yaVNB@1k2>wGB{SOwwKU}_hf$irPir^n*;paZNQ2&)#_`g^L|M|j?{;Mm3zsjQj zp(5IkIt%~9MesLT__r6qKi9&~V}e5c-)7RSJyDD{d~Seq54}a z`uV%=h4No(;paI`q5N$^h~?IbosvTP^ze`{jl5Z@1{@?}r!4zr&)R&kHP+{}~HEpO054zxl2u zmcPe~sQ-IJ5%MRBsDJw{{QSNALhV0j;XhP_{-N?6H?;ppMevte`1#y`LhV0I__6%+ z_mB(aKii@|UWEM>7XAEvSoHIE>hV$uxWrq1T34aF?(|uX!IZDqgGn_8NzcdsP=C2ig zKH~(#i5KW6`7D?p6}JBhieW6wKUVnVGj>k?cM5+v{WZdG{A~n;pRb|_TmJ2p7icD* zIR9=TTElPfMWR1!f1T(z{lC#4PX8tce~a+TXUPn^@|FKUH@hADi-i9yB&PdNHhDiH zOr<{@ag?^yq?6OXnrOr6e~B=r45$Bg(SJF`VF;_?vzu)E&j|m8$V~TP{!572X8&l5 z{cDInY(KwKu<1V}`p?dz{}Bg&**MK8pBM9`ur3Tdr?cs=7XGP7O!wjR^O*#;^jBEY ze>?Gq(_cXXZTfE%{gd+O=Wq4f^w(ST-(k`JphN$oqW_dU`Y)u4Z?ped;h&X<|2*Qi z**{P0uMmDN|NOnZu>bCN=zoh8-0!Cxc%+`eK6^S|VgrvF$ec#nh>h9133iQne`1Csvj!ocPC9!vUnivA%X z!83irl`}Ye!_fHr?YP@TR-)8@oqqU|oQONe+OM=4XcaP`~+rMMH z)@u4MV}pn@k6t$kWGvi&JtzG94Ok3e`E&HkOoXif8kneG21-G}Xe$)P`1r5VHJ zFKqvLN7?Of7XEzWuXBjsX8+h@wI*!;K5enT&!K;T=s#J~Z!Tf~^*Hp;75ygv*ngk3 z=-=Ydzp_C6pK|E$vgp6xqJOtT|3^hXkMA*r)Bhuf{xuf=e~tu&%TI*9Q_eXRF24h! ze_6M2mhe(pOc4wse}J-1?qp;!9Q$*R(woIf4KaAiTG{hce^G3wvw!{|NhsZ z|9H_apQZJ!2>Y*rzE^Ma|5)MA=l{DM{58U#&;NH4zb*ZPmh^A4r2lQSz+$uideL9! zr(EBJ)BhIYx9Q(&DZl*wG3@`_9Qr>Y`t!{nZgJ=zJyMqxY`?Z!^dC(H%$ELNivIFE z=|7VAZRxMK=;!xe;q<@Hq2H_4iqFcU|Gf_VeWD-RPkw(A*8i+S|JkBnF1{7v{QrSN z|9Xplet!|xe;jpiHveBEietWJeG}GyH1XT~zr~_|z@mS;L;t;^za^w!m#P4q=FmT2 z$^R!U`aj^%{}<68uK!{E?|0}wV9~$BqJPk#fAmD1#uJ02s=KiNhf)J)%fE5L&+B6t z!u+o|>@O?TDaG>pGzkiqpYftUJpOAC{aiLMg#Fj!uz#lTzZIG3K5Ty{@!QH@jm7?N z6MxwL&pGrj75(|f51(=9Z?for#-jgs4*mBOsDF<`|00Y2?^*OuEVY-PCq@4<;=vI1 zKc9bM^Z!cGUoXr&ejKFxu>U{e(0@^lX3VF5gG2vLi~b*4^bes00$ct0lIUL`_M1yM z{r__4FFj6|bWHy)i~d;-{i9{!frb|uAzXj1Bz~L!=Zb!;zt39qf5xHzY|(#ihW70G zcb`Llm*}q$e$M~h7X3eP=$~1j{%0KeH(B)m%%cC0Lw}#>&sYEd?$AGI(f^!9e>qJM zZRPJ1qW?VcpSgs~-#Z=rJB6Qy2N@w;ey$>ZTlw*h*OXX(o+nA+`g@;4|Ffds@Eaq- z_TS^sKiZ=IR~G$0aOnS&=$B)3jQXtp;~9tk3XA^VSoEJvF9>Y;cl1SCWj_6*h~MV_ zdW-(wS@h3x=s!>NQ}>V&!v4R*!Cx!<`N~hf!~S^|`}bPx|Di+wG|`{0{CwA;zt5uo zj~4y>10!4hU0-1S{nMd;y+!|ii~ea2{Wle;e-iQA%Fh;y{y$mt-{{c)QPH2T{55=rN7mozfAOF`u}dxzghH${d$?`e?gn!|JAATAH9bh z_K&?p)0`BLs=KhBUkE?FhRFzZ!e5ht2EPX~FrSB{{BHocHd)gDPl^lY|4R=2D@8vI z4>Lme`M(|dS6cM{%c6e-O%QGE*Lu-U#XBQ}{WpyGZRKyPrTo2O(SNl=|7OvjZ~i&k zp?{}Ee+eZt?EgGkBmA=iQgs*R{{`{e{6A<(Kflrnr~hjw z+wHHsOe@Y;{~jWKoBq*n)|QfaDscJZC9Saj`cv%sXNvwo;WwAC|ECbYO@D>x?-NGW z&r_H>$OZ>L_!pZqJ+M<7jL;vSQalZDe&!NAJ6H8&9 z`s=Ch2b^Nj|Dr?x-wV|LM~D8E7X7DL^j~wj-TzbSwBh0QOQ%W_MVGrA{BJLif0u)Q zp72i!RH?gg{rNue+wy;pq#wtRWtQ|Ga_GOWK>IJD2{!vA-2ZJA{(SaNBz~Lyr6;je zItN<))#c|bi~UK5{y*1g#(eqr83(^7hRZUBSdl$`xzAyLo!F1<_ggIXf5)M}R`lny z|DrSP{;wB)8s27vaQXSEga3Nr{}I`YA|A0k* zl|_FUIhf$A_UmEMZ^l2y2&TnwD)HO=Km24(xkZS%{8!WeaQUC(&|fiCGv=$m2ORt{ z;g6!RbRV{VpTqvGVn3GOT8sUcoMrdlQqiBU{@(52zg76Dd&&r5`|l+Fp+r$PB!kS` zBlctYh|L=C_zfbg&don^;f7RLc^nas3{tr3$e=qzryvzupWO{cH|4^a`r~jZO z{dJb~m(dG$PE)x5E|HA~Vg2FspGy2T{iQtEqk#VB@8^a6{}G4&(+bqT!J&VwMgLTb z{;AZ!v!#)cV{1hJZk3AQkFnn%mlMA&{dJ<>e8+_AKYu^Z@EgDMI`o%L(;D*W?{eth z%7a}BsK4H#e~Ux^UeOE?W>Z9fcMHGqlM!S5 zXP&1Mzs>%YVt>65a`|hr*ngAg5BvXs=nvQbus^p5f7t#~QJl~IPZ7V({+$;4n=SS~ z>#)B<^oRS8u>C{n1v~dq5#vy~HVOam5N@8$^_8(=e~7NMjEtpV($D_C%3}YUNk3DD z{WrH>vHSH!KLz#2JeLx`&3|Jp`sZ5oPZa&8o*KFHM1R Date: Thu, 13 Dec 2018 17:05:39 -0800 Subject: [PATCH 0553/2143] Fix typo && remove unecessary except --- src/python/grpcio_tests/tests/status/_grpc_status_test.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) 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 5969338736f..519c372a960 100644 --- a/src/python/grpcio_tests/tests/status/_grpc_status_test.py +++ b/src/python/grpcio_tests/tests/status/_grpc_status_test.py @@ -54,7 +54,7 @@ def _error_details_unary_unary(request, servicer_context): details.Pack( error_details_pb2.DebugInfo( stack_entries=traceback.format_stack(), - detail='Intensionally invoked')) + detail='Intentionally invoked')) rich_status = status_pb2.Status( code=code_pb2.INTERNAL, message=_STATUS_DETAILS, @@ -118,10 +118,8 @@ class StatusTest(unittest.TestCase): self._channel.close() def test_status_ok(self): - try: - _, call = self._channel.unary_unary(_STATUS_OK).with_call(_REQUEST) - except grpc.RpcError as rpc_error: - self.fail(rpc_error) + _, call = self._channel.unary_unary(_STATUS_OK).with_call(_REQUEST) + # Succeed RPC doesn't have status status = rpc_status.from_call(call) self.assertIs(status, None) From b9cb2459ea4b2956547abf5fb516b553d85f1ae2 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 13 Dec 2018 17:18:38 -0800 Subject: [PATCH 0554/2143] Include LICENSE in artifact --- src/python/grpcio_status/MANIFEST.in | 1 + src/python/grpcio_status/setup.py | 19 +++++---- src/python/grpcio_status/status_commands.py | 39 +++++++++++++++++++ .../artifacts/build_artifact_python.sh | 2 +- 4 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 src/python/grpcio_status/status_commands.py diff --git a/src/python/grpcio_status/MANIFEST.in b/src/python/grpcio_status/MANIFEST.in index eca719a9c20..09b8ea721e8 100644 --- a/src/python/grpcio_status/MANIFEST.in +++ b/src/python/grpcio_status/MANIFEST.in @@ -1,3 +1,4 @@ include grpc_version.py recursive-include grpc_status *.py global-exclude *.pyc +include LICENSE diff --git a/src/python/grpcio_status/setup.py b/src/python/grpcio_status/setup.py index 0601498bc51..a59cdd0f0f5 100644 --- a/src/python/grpcio_status/setup.py +++ b/src/python/grpcio_status/setup.py @@ -63,12 +63,18 @@ INSTALL_REQUIRES = ( 'googleapis-common-protos>=1.5.5', ) -SETUP_REQUIRES = () -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, + } +except ImportError: + COMMAND_CLASS = { + # wire up commands to no-op not to break the external dependencies + 'preprocess': _NoOpCommand, + } setuptools.setup( name='grpcio-status', @@ -82,5 +88,4 @@ setuptools.setup( package_dir=PACKAGE_DIRECTORIES, packages=setuptools.find_packages('.'), install_requires=INSTALL_REQUIRES, - setup_requires=SETUP_REQUIRES, cmdclass=COMMAND_CLASS) 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/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index 18eb70c8574..e451ced338f 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -126,7 +126,7 @@ then # Build grpcio_status source distribution ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_status/setup.py \ - preprocess build_package_protos sdist + preprocess sdist cp -r src/python/grpcio_status/dist/* "$ARTIFACT_DIR" fi From 5a38d1956fb7007108a310e0280df58c9c824cec Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 14 Dec 2018 10:08:22 -0800 Subject: [PATCH 0555/2143] Make yapf happy --- tools/run_tests/python_utils/check_on_pr.py | 78 +++++++++++++-------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index 96418bf2d3a..935d59713ef 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -25,47 +25,57 @@ _GITHUB_API_PREFIX = 'https://api.github.com' _GITHUB_REPO = 'lidizheng/grpc' _GITHUB_APP_ID = 22288 _INSTALLATION_ID = 516307 -_GITHUB_APP_KEY = open(os.environ['HOME'] + '/.ssh/google-grpc-checker.2018-12-13.private-key.pem', 'r').read() +_GITHUB_APP_KEY = open( + os.environ['HOME'] + '/.ssh/google-grpc-checker.2018-12-13.private-key.pem', + 'r').read() _ACCESS_TOKEN_CACHE = None + def _jwt_token(): - return jwt.encode({ - 'iat': int(time.time()), - 'exp': int(time.time() + 60 * 10), # expire in 10 minutes - 'iss': _GITHUB_APP_ID, - }, _GITHUB_APP_KEY, algorithm='RS256') + return jwt.encode( + { + 'iat': int(time.time()), + 'exp': int(time.time() + 60 * 10), # expire in 10 minutes + 'iss': _GITHUB_APP_ID, + }, + _GITHUB_APP_KEY, + algorithm='RS256') + 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, + 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', - } - ) - _ACCESS_TOKEN_CACHE = {'token': resp.json()['token'], 'exp': time.time()+60} + }) + _ACCESS_TOKEN_CACHE = { + 'token': resp.json()['token'], + 'exp': time.time() + 60 + } return _ACCESS_TOKEN_CACHE['token'] + def _call(url, method='GET', json=None): if not url.startswith('https://'): url = _GITHUB_API_PREFIX + url - headers={ + headers = { 'Authorization': 'Bearer %s' % _access_token(), 'Accept': 'application/vnd.github.antiope-preview+json', } - return requests.request( - method=method, - url=url, - headers=headers, - json=json) + return requests.request(method=method, url=url, headers=headers, json=json) + def _latest_commit(): - resp = _call('/repos/%s/pulls/%s/commits' % (_GITHUB_REPO, os.environ['ghprbPullId'])) + resp = _call('/repos/%s/pulls/%s/commits' % (_GITHUB_REPO, + os.environ['ghprbPullId'])) return resp.json()[-1] + def check_on_pr(name, summary, success=True): """Create/Update a check on current pull request. @@ -84,15 +94,25 @@ def check_on_pr(name, summary, success=True): print('Missing ghprbPullId env var: not commenting') return commit = _latest_commit() - resp = _call('/repos/%s/check-runs' % _GITHUB_REPO, method='POST', json={ - 'name': name, - 'head_sha': commit['sha'], - 'status': 'completed', - 'completed_at': '%sZ' % datetime.datetime.utcnow().replace(microsecond=0).isoformat(), - 'conclusion': 'success' if success else 'failure', - 'output': { - 'title': name, - 'summary': summary, - } - }) - print('Result of Creating/Updating Check on PR:', json.dumps(resp.json(), indent=2)) + resp = _call( + '/repos/%s/check-runs' % _GITHUB_REPO, + method='POST', + json={ + 'name': + name, + 'head_sha': + commit['sha'], + 'status': + 'completed', + 'completed_at': + '%sZ' % + datetime.datetime.utcnow().replace(microsecond=0).isoformat(), + 'conclusion': + 'success' if success else 'failure', + 'output': { + 'title': name, + 'summary': summary, + } + }) + print('Result of Creating/Updating Check on PR:', + json.dumps(resp.json(), indent=2)) From 40b8ca97a1d89153711e0d965cd25de1099862f1 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 14 Dec 2018 10:10:57 -0800 Subject: [PATCH 0556/2143] Update docstring to make it more clear * Mark API as experimental * Rephrase the raise condition * Add more detail to the returned object --- src/python/grpcio_status/grpc_status/rpc_status.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/python/grpcio_status/grpc_status/rpc_status.py b/src/python/grpcio_status/grpc_status/rpc_status.py index 36c8eba37d5..e23a20968ec 100644 --- a/src/python/grpcio_status/grpc_status/rpc_status.py +++ b/src/python/grpcio_status/grpc_status/rpc_status.py @@ -45,6 +45,8 @@ def _code_to_grpc_status_code(code): def from_call(call): """Returns a google.rpc.status.Status message corresponding to a given grpc.Call. + This is an EXPERIMENTAL API. + Args: call: A grpc.Call instance. @@ -52,8 +54,8 @@ def from_call(call): A google.rpc.status.Status message representing the status of the RPC. Raises: - ValueError: If the status code, status message is inconsistent with the rich status - inside of the google.rpc.status.Status. + ValueError: If the gRPC call's code or details are inconsistent with the + status code and message inside of the google.rpc.status.Status. """ for key, value in call.trailing_metadata(): if key == _GRPC_DETAILS_METADATA_KEY: @@ -74,12 +76,14 @@ def from_call(call): def to_status(status): """Convert a google.rpc.status.Status message to grpc.Status. + This is an EXPERIMENTAL API. + Args: status: a google.rpc.status.Status message representing the non-OK status to terminate the RPC with and communicate it to the client. Returns: - A grpc.Status instance. + A grpc.Status instance representing the input google.rpc.status.Status message. """ return _Status( code=_code_to_grpc_status_code(status.code), From 5ec78a286d7be61aec929b133c031a7a1af262df Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Fri, 14 Dec 2018 10:36:51 -0800 Subject: [PATCH 0557/2143] Added support for fixed load benchmarks, all the rpcs access one requestor to the get the next issue time for the RPC --- test/cpp/qps/client_callback.cc | 35 ++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/test/cpp/qps/client_callback.cc b/test/cpp/qps/client_callback.cc index 00d5853a8e8..1880f46d43d 100644 --- a/test/cpp/qps/client_callback.cc +++ b/test/cpp/qps/client_callback.cc @@ -66,7 +66,10 @@ class CallbackClient config, BenchmarkStubCreator) { num_threads_ = NumThreads(config); rpcs_done_ = 0; - SetupLoadTest(config, num_threads_); + + // Don't divide the fixed load among threads as the user threads + // only bootstrap the RPCs + SetupLoadTest(config, 1); total_outstanding_rpcs_ = config.client_channels() * config.outstanding_rpcs_per_channel(); } @@ -87,6 +90,11 @@ class CallbackClient } } + gpr_timespec NextIssueTime() { + std::lock_guard l(next_issue_time_mu_); + return Client::NextIssueTime(0); + } + protected: size_t num_threads_; size_t total_outstanding_rpcs_; @@ -108,6 +116,8 @@ class CallbackClient } private: + std::mutex next_issue_time_mu_; // Used by next issue time + int NumThreads(const ClientConfig& config) { int num_threads = config.async_client_threads(); if (num_threads <= 0) { // Use dynamic sizing @@ -146,7 +156,7 @@ class CallbackUnaryClient final : public CallbackClient { bool ThreadFuncImpl(Thread* t, size_t thread_idx) override { for (size_t vector_idx = thread_idx; vector_idx < total_outstanding_rpcs_; vector_idx += num_threads_) { - ScheduleRpc(t, thread_idx, vector_idx); + ScheduleRpc(t, vector_idx); } return true; } @@ -154,26 +164,26 @@ class CallbackUnaryClient final : public CallbackClient { void InitThreadFuncImpl(size_t thread_idx) override { return; } private: - void ScheduleRpc(Thread* t, size_t thread_idx, size_t vector_idx) { + void ScheduleRpc(Thread* t, size_t vector_idx) { if (!closed_loop_) { - gpr_timespec next_issue_time = NextIssueTime(thread_idx); + gpr_timespec next_issue_time = NextIssueTime(); // Start an alarm callback to run the internal callback after // next_issue_time ctx_[vector_idx]->alarm_.experimental().Set( - next_issue_time, [this, t, thread_idx, vector_idx](bool ok) { - IssueUnaryCallbackRpc(t, thread_idx, vector_idx); + next_issue_time, [this, t, vector_idx](bool ok) { + IssueUnaryCallbackRpc(t, vector_idx); }); } else { - IssueUnaryCallbackRpc(t, thread_idx, vector_idx); + IssueUnaryCallbackRpc(t, vector_idx); } } - void IssueUnaryCallbackRpc(Thread* t, size_t thread_idx, size_t vector_idx) { + void IssueUnaryCallbackRpc(Thread* t, size_t vector_idx) { GPR_TIMER_SCOPE("CallbackUnaryClient::ThreadFunc", 0); double start = UsageTimer::Now(); ctx_[vector_idx]->stub_->experimental_async()->UnaryCall( (&ctx_[vector_idx]->context_), &request_, &ctx_[vector_idx]->response_, - [this, t, thread_idx, start, vector_idx](grpc::Status s) { + [this, t, start, vector_idx](grpc::Status s) { // Update Histogram with data from the callback run HistogramEntry entry; if (s.ok()) { @@ -190,7 +200,7 @@ class CallbackUnaryClient final : public CallbackClient { ctx_[vector_idx].reset( new CallbackClientRpcContext(ctx_[vector_idx]->stub_)); // Schedule a new RPC - ScheduleRpc(t, thread_idx, vector_idx); + ScheduleRpc(t, vector_idx); } }); } @@ -287,7 +297,7 @@ class CallbackStreamingPingPongReactor final if (client_->ThreadCompleted()) return; if (!client_->IsClosedLoop()) { - gpr_timespec next_issue_time = client_->NextIssueTime(thread_idx_); + gpr_timespec next_issue_time = client_->NextIssueTime(); // Start an alarm callback to run the internal callback after // next_issue_time ctx_->alarm_.experimental().Set(next_issue_time, @@ -298,11 +308,9 @@ class CallbackStreamingPingPongReactor final } void set_thread_ptr(void* ptr) { thread_ptr_ = ptr; } - void set_thread_idx(int thread_idx) { thread_idx_ = thread_idx; } CallbackStreamingPingPongClient* client_; std::unique_ptr ctx_; - int thread_idx_; // Needed to update histogram entries void* thread_ptr_; // Needed to update histogram entries double start_; // Track message start time int messages_issued_; // Messages issued by this stream @@ -323,7 +331,6 @@ class CallbackStreamingPingPongClientImpl final for (size_t vector_idx = thread_idx; vector_idx < total_outstanding_rpcs_; vector_idx += num_threads_) { reactor_[vector_idx]->set_thread_ptr(t); - reactor_[vector_idx]->set_thread_idx(thread_idx); reactor_[vector_idx]->ScheduleRpc(); } return true; From 8621bd47adb7dec1f16bbd616890fd3b0df3336e Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 14 Dec 2018 11:23:18 -0800 Subject: [PATCH 0558/2143] Assign noop to build_package_protos for backward compatibility --- src/python/grpcio_status/setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/python/grpcio_status/setup.py b/src/python/grpcio_status/setup.py index a59cdd0f0f5..983d3ea430b 100644 --- a/src/python/grpcio_status/setup.py +++ b/src/python/grpcio_status/setup.py @@ -69,11 +69,13 @@ try: 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( From ca4e55e6caae393e33784d51f1e9d2352608c4dc Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 14 Dec 2018 13:03:22 -0800 Subject: [PATCH 0559/2143] Benchmark to show that byte buffer copy is size-independent --- CMakeLists.txt | 49 ++++++++++++++ Makefile | 49 ++++++++++++++ build.yaml | 22 +++++++ test/cpp/microbenchmarks/BUILD | 7 ++ test/cpp/microbenchmarks/bm_byte_buffer.cc | 65 +++++++++++++++++++ .../generated/sources_and_headers.json | 22 +++++++ tools/run_tests/generated/tests.json | 22 +++++++ 7 files changed, 236 insertions(+) create mode 100644 test/cpp/microbenchmarks/bm_byte_buffer.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index fb233cc3601..e296eaee734 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -526,6 +526,9 @@ 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) +add_dependencies(buildtests_cxx bm_byte_buffer) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_call_create) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -11191,6 +11194,52 @@ target_link_libraries(bm_arena ) +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(bm_byte_buffer + test/cpp/microbenchmarks/bm_byte_buffer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bm_byte_buffer + 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_byte_buffer + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark + ${_gRPC_BENCHMARK_LIBRARIES} + grpc++_test_util_unsecure + grpc_test_util_unsecure + grpc++_unsecure + grpc_unsecure + gpr_test_util + gpr + grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index c4d8a0b95cb..9cc4aeecc4d 100644 --- a/Makefile +++ b/Makefile @@ -1135,6 +1135,7 @@ 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_arena: $(BINDIR)/$(CONFIG)/bm_arena +bm_byte_buffer: $(BINDIR)/$(CONFIG)/bm_byte_buffer bm_call_create: $(BINDIR)/$(CONFIG)/bm_call_create bm_channel: $(BINDIR)/$(CONFIG)/bm_channel bm_chttp2_hpack: $(BINDIR)/$(CONFIG)/bm_chttp2_hpack @@ -1641,6 +1642,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/backoff_test \ $(BINDIR)/$(CONFIG)/bdp_estimator_test \ $(BINDIR)/$(CONFIG)/bm_arena \ + $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ $(BINDIR)/$(CONFIG)/bm_channel \ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \ @@ -1825,6 +1827,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/backoff_test \ $(BINDIR)/$(CONFIG)/bdp_estimator_test \ $(BINDIR)/$(CONFIG)/bm_arena \ + $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ $(BINDIR)/$(CONFIG)/bm_channel \ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \ @@ -2259,6 +2262,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/bdp_estimator_test || ( echo test bdp_estimator_test 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" + $(Q) $(BINDIR)/$(CONFIG)/bm_byte_buffer || ( echo test bm_byte_buffer failed ; exit 1 ) $(E) "[RUN] Testing bm_call_create" $(Q) $(BINDIR)/$(CONFIG)/bm_call_create || ( echo test bm_call_create failed ; exit 1 ) $(E) "[RUN] Testing bm_channel" @@ -16084,6 +16089,50 @@ endif endif +BM_BYTE_BUFFER_SRC = \ + test/cpp/microbenchmarks/bm_byte_buffer.cc \ + +BM_BYTE_BUFFER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_BYTE_BUFFER_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_byte_buffer: 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_byte_buffer: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_byte_buffer: $(PROTOBUF_DEP) $(BM_BYTE_BUFFER_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_BYTE_BUFFER_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_byte_buffer + +endif + +endif + +$(BM_BYTE_BUFFER_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_byte_buffer.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + +deps_bm_byte_buffer: $(BM_BYTE_BUFFER_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_BYTE_BUFFER_OBJS:.o=.dep) +endif +endif + + BM_CALL_CREATE_SRC = \ test/cpp/microbenchmarks/bm_call_create.cc \ diff --git a/build.yaml b/build.yaml index 6e2ed16398e..5f4d554a467 100644 --- a/build.yaml +++ b/build.yaml @@ -4015,6 +4015,28 @@ targets: - linux - posix uses_polling: false +- name: bm_byte_buffer + build: test + language: c++ + src: + - test/cpp/microbenchmarks/bm_byte_buffer.cc + deps: + - grpc_benchmark + - benchmark + - grpc++_test_util_unsecure + - grpc_test_util_unsecure + - grpc++_unsecure + - grpc_unsecure + - gpr_test_util + - gpr + - grpc++_test_config + benchmark: true + defaults: benchmark + platforms: + - mac + - linux + - posix + uses_polling: false - name: bm_call_create build: test language: c++ diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 097e92f5836..93ed962a00d 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -61,6 +61,13 @@ grpc_cc_binary( deps = [":helpers"], ) +grpc_cc_binary( + name = "bm_byte_buffer", + testonly = 1, + srcs = ["bm_byte_buffer.cc"], + deps = [":helpers"], +) + grpc_cc_binary( name = "bm_channel", testonly = 1, diff --git a/test/cpp/microbenchmarks/bm_byte_buffer.cc b/test/cpp/microbenchmarks/bm_byte_buffer.cc new file mode 100644 index 00000000000..a359e6f6212 --- /dev/null +++ b/test/cpp/microbenchmarks/bm_byte_buffer.cc @@ -0,0 +1,65 @@ +/* + * + * 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 show that byte-buffer copy is size-independent */ + +#include + +#include +#include +#include +#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_ByteBuffer_Copy(benchmark::State& state) { + int num_slices = state.range(0); + size_t slice_size = state.range(1); + std::vector slices; + while (num_slices > 0) { + num_slices--; + std::unique_ptr buf(new char[slice_size]); + memset(buf.get(), 0, slice_size); + slices.emplace_back(buf.get(), slice_size); + } + grpc::ByteBuffer bb(slices.data(), num_slices); + while (state.KeepRunning()) { + grpc::ByteBuffer cc(bb); + } +} +BENCHMARK(BM_ByteBuffer_Copy)->Ranges({{1, 64}, {1, 1024 * 1024}}); + +} // 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 c87d7209e7d..38cdd49fc7f 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -2789,6 +2789,28 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "benchmark", + "gpr", + "gpr_test_util", + "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_byte_buffer", + "src": [ + "test/cpp/microbenchmarks/bm_byte_buffer.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 cc28e52ae21..bca2ef53878 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3363,6 +3363,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_byte_buffer", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": false + }, { "args": [], "benchmark": true, From 653160d8067e648c94c7ab095dc7fe4bbe1f3271 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Dec 2018 13:47:33 -0800 Subject: [PATCH 0560/2143] Make NSMutableDictionary annotation right --- src/objective-c/GRPCClient/GRPCCall.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index f36b814cec3..d4d16024fa0 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -370,11 +370,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (id)objectForKeyedSubscript:(id)key; -- (void)setObject:(id)obj forKeyedSubscript:(id)key; +- (nullable id)objectForKeyedSubscript:(nonnull id)key; +- (void)setObject:(nonnull id)obj forKeyedSubscript:(nonnull id)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(id)key; +- (void)removeObjectForKey:(nonnull id)key; @end #pragma clang diagnostic push From 4f91630d6b2ba9fbf0b75e2dbaa1932a739f2b17 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Dec 2018 13:46:53 -0800 Subject: [PATCH 0561/2143] CFStream use serial dispatch queue --- src/core/lib/iomgr/cfstream_handle.cc | 98 ++++++++++++--------------- src/core/lib/iomgr/cfstream_handle.h | 2 + 2 files changed, 46 insertions(+), 54 deletions(-) diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index 827fd24831e..bb402f96cf5 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -52,62 +52,53 @@ CFStreamHandle* CFStreamHandle::CreateStreamHandle( void CFStreamHandle::ReadCallback(CFReadStreamRef stream, CFStreamEventType type, void* client_callback_info) { + grpc_core::ExecCtx exec_ctx; CFStreamHandle* handle = static_cast(client_callback_info); - CFSTREAM_HANDLE_REF(handle, "read callback"); - dispatch_async( - dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - grpc_core::ExecCtx exec_ctx; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_DEBUG, "CFStream ReadCallback (%p, %p, %lu, %p)", handle, - stream, type, client_callback_info); - } - switch (type) { - case kCFStreamEventOpenCompleted: - handle->open_event_.SetReady(); - break; - case kCFStreamEventHasBytesAvailable: - case kCFStreamEventEndEncountered: - handle->read_event_.SetReady(); - break; - case kCFStreamEventErrorOccurred: - handle->open_event_.SetReady(); - handle->read_event_.SetReady(); - break; - default: - GPR_UNREACHABLE_CODE(return ); - } - CFSTREAM_HANDLE_UNREF(handle, "read callback"); - }); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_DEBUG, "CFStream ReadCallback (%p, %p, %lu, %p)", handle, + stream, type, client_callback_info); + } + switch (type) { + case kCFStreamEventOpenCompleted: + handle->open_event_.SetReady(); + break; + case kCFStreamEventHasBytesAvailable: + case kCFStreamEventEndEncountered: + handle->read_event_.SetReady(); + break; + case kCFStreamEventErrorOccurred: + handle->open_event_.SetReady(); + handle->read_event_.SetReady(); + break; + default: + GPR_UNREACHABLE_CODE(return ); + } } void CFStreamHandle::WriteCallback(CFWriteStreamRef stream, CFStreamEventType type, void* clientCallBackInfo) { + grpc_core::ExecCtx exec_ctx; CFStreamHandle* handle = static_cast(clientCallBackInfo); - CFSTREAM_HANDLE_REF(handle, "write callback"); - dispatch_async( - dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - grpc_core::ExecCtx exec_ctx; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_DEBUG, "CFStream WriteCallback (%p, %p, %lu, %p)", handle, - stream, type, clientCallBackInfo); - } - switch (type) { - case kCFStreamEventOpenCompleted: - handle->open_event_.SetReady(); - break; - case kCFStreamEventCanAcceptBytes: - case kCFStreamEventEndEncountered: - handle->write_event_.SetReady(); - break; - case kCFStreamEventErrorOccurred: - handle->open_event_.SetReady(); - handle->write_event_.SetReady(); - break; - default: - GPR_UNREACHABLE_CODE(return ); - } - CFSTREAM_HANDLE_UNREF(handle, "write callback"); - }); + printf("** CFStreamHandle::WriteCallback\n"); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_DEBUG, "CFStream WriteCallback (%p, %p, %lu, %p)", handle, + stream, type, clientCallBackInfo); + } + switch (type) { + case kCFStreamEventOpenCompleted: + handle->open_event_.SetReady(); + break; + case kCFStreamEventCanAcceptBytes: + case kCFStreamEventEndEncountered: + handle->write_event_.SetReady(); + break; + case kCFStreamEventErrorOccurred: + handle->open_event_.SetReady(); + handle->write_event_.SetReady(); + break; + default: + GPR_UNREACHABLE_CODE(return ); + } } CFStreamHandle::CFStreamHandle(CFReadStreamRef read_stream, @@ -116,6 +107,7 @@ CFStreamHandle::CFStreamHandle(CFReadStreamRef read_stream, open_event_.InitEvent(); read_event_.InitEvent(); write_event_.InitEvent(); + dispatch_queue_ = dispatch_queue_create(nullptr, DISPATCH_QUEUE_SERIAL); CFStreamClientContext ctx = {0, static_cast(this), CFStreamHandle::Retain, CFStreamHandle::Release, nil}; @@ -129,10 +121,8 @@ CFStreamHandle::CFStreamHandle(CFReadStreamRef read_stream, kCFStreamEventOpenCompleted | kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, CFStreamHandle::WriteCallback, &ctx); - CFReadStreamScheduleWithRunLoop(read_stream, CFRunLoopGetMain(), - kCFRunLoopCommonModes); - CFWriteStreamScheduleWithRunLoop(write_stream, CFRunLoopGetMain(), - kCFRunLoopCommonModes); + CFReadStreamSetDispatchQueue(read_stream, dispatch_queue_); + CFWriteStreamSetDispatchQueue(write_stream, dispatch_queue_); } CFStreamHandle::~CFStreamHandle() { diff --git a/src/core/lib/iomgr/cfstream_handle.h b/src/core/lib/iomgr/cfstream_handle.h index 4258e72431c..93ec5f044bb 100644 --- a/src/core/lib/iomgr/cfstream_handle.h +++ b/src/core/lib/iomgr/cfstream_handle.h @@ -62,6 +62,8 @@ class CFStreamHandle final { grpc_core::LockfreeEvent read_event_; grpc_core::LockfreeEvent write_event_; + dispatch_queue_t dispatch_queue_; + gpr_refcount refcount_; }; From b0b4c0d9c36d9b3185c5b792ca6e8954ff065e54 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 14 Dec 2018 13:52:25 -0800 Subject: [PATCH 0562/2143] Add API comments indicating that byte buffer copy is size-independent --- include/grpcpp/impl/codegen/byte_buffer.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/impl/codegen/byte_buffer.h b/include/grpcpp/impl/codegen/byte_buffer.h index 53ecb53371b..a77e36dfc50 100644 --- a/include/grpcpp/impl/codegen/byte_buffer.h +++ b/include/grpcpp/impl/codegen/byte_buffer.h @@ -93,7 +93,9 @@ class ByteBuffer final { } /// Constuct a byte buffer by referencing elements of existing buffer - /// \a buf. Wrapper of core function grpc_byte_buffer_copy + /// \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() { @@ -102,6 +104,9 @@ 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&); /// Dump (read) the buffer contents into \a slices. @@ -117,7 +122,9 @@ class ByteBuffer final { /// Make a duplicate copy of the internals of this byte /// buffer so that we have our own owned version of it. - /// bbuf.Duplicate(); is equivalent to bbuf=bbuf; but is actually readable + /// bbuf.Duplicate(); is equivalent to bbuf=bbuf; but is actually readable. + /// This is not a deep copy; it is a referencing and its performance + /// is size-independent. void Duplicate() { buffer_ = g_core_codegen_interface->grpc_byte_buffer_copy(buffer_); } From a744221a2c5b93d8bd90c266ffea68de34c44acd Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Fri, 14 Dec 2018 14:14:46 -0800 Subject: [PATCH 0563/2143] Editing appid and installation id Created these from the grpc-bot account. --- tools/run_tests/python_utils/check_on_pr.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index 935d59713ef..f756e4bdaa4 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -22,9 +22,9 @@ import requests import jwt _GITHUB_API_PREFIX = 'https://api.github.com' -_GITHUB_REPO = 'lidizheng/grpc' -_GITHUB_APP_ID = 22288 -_INSTALLATION_ID = 516307 +_GITHUB_REPO = 'grpc/grpc' +_GITHUB_APP_ID = 22338 +_INSTALLATION_ID = 519109 _GITHUB_APP_KEY = open( os.environ['HOME'] + '/.ssh/google-grpc-checker.2018-12-13.private-key.pem', 'r').read() From 580d43d03f20b0b92f4b7ae950225a1dcd3387a0 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 13 Dec 2018 16:55:08 -0800 Subject: [PATCH 0564/2143] Address reviewer comments and remove binary files --- examples/BUILD | 15 + examples/cpp/metadata/README.md | 5 +- examples/cpp/metadata/greeter_client | Bin 267800 -> 0 bytes examples/cpp/metadata/greeter_client.o | Bin 101304 -> 0 bytes examples/cpp/metadata/greeter_server | Bin 278392 -> 0 bytes examples/cpp/metadata/greeter_server.cc | 14 +- examples/cpp/metadata/greeter_server.o | Bin 112144 -> 0 bytes examples/cpp/metadata/helloworld.grpc.pb.cc | 70 --- examples/cpp/metadata/helloworld.grpc.pb.h | 197 ------ examples/cpp/metadata/helloworld.grpc.pb.o | Bin 398496 -> 0 bytes examples/cpp/metadata/helloworld.pb.cc | 638 -------------------- examples/cpp/metadata/helloworld.pb.h | 419 ------------- examples/cpp/metadata/helloworld.pb.o | Bin 111592 -> 0 bytes 13 files changed, 29 insertions(+), 1329 deletions(-) delete mode 100755 examples/cpp/metadata/greeter_client delete mode 100644 examples/cpp/metadata/greeter_client.o delete mode 100755 examples/cpp/metadata/greeter_server delete mode 100644 examples/cpp/metadata/greeter_server.o delete mode 100644 examples/cpp/metadata/helloworld.grpc.pb.cc delete mode 100644 examples/cpp/metadata/helloworld.grpc.pb.h delete mode 100644 examples/cpp/metadata/helloworld.grpc.pb.o delete mode 100644 examples/cpp/metadata/helloworld.pb.cc delete mode 100644 examples/cpp/metadata/helloworld.pb.h delete mode 100644 examples/cpp/metadata/helloworld.pb.o diff --git a/examples/BUILD b/examples/BUILD index 0f18cfa9ba7..22f2f0a4f1a 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -51,3 +51,18 @@ cc_binary( defines = ["BAZEL_BUILD"], deps = [":helloworld", "//:grpc++"], ) + +cc_binary( + name = "metadata_client", + srcs = ["cpp/metadata/greeter_client.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) + +cc_binary( + name = "metadata_server", + srcs = ["cpp/metadata/greeter_server.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) + diff --git a/examples/cpp/metadata/README.md b/examples/cpp/metadata/README.md index 7b33074ba1e..96ad3d19bdb 100644 --- a/examples/cpp/metadata/README.md +++ b/examples/cpp/metadata/README.md @@ -57,13 +57,10 @@ If things go smoothly, you will see in the client terminal: And in the server terminal: -"Header key: custom-bin , value: " +"Header key: custom-bin , value: 01234567" "Header key: custom-header , value: Custom Value" "Header key: user-agent , value: grpc-c++/1.16.0-dev grpc-c/6.0.0-dev (linux; chttp2; gao)" -Note that the value for custom-bin doesn't print nicely because it's a binary -value. You can indicate a binary value through appending "-bin" to the header key. - We did not add the user-agent metadata as a custom header. This shows how the gRPC framework adds some headers under the hood that may show up in the metadata map. diff --git a/examples/cpp/metadata/greeter_client b/examples/cpp/metadata/greeter_client deleted file mode 100755 index 929a51c3a5b426131d0573b2e5cd91da16f1ecf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 267800 zcmdqK3tXJV)jz(upcswd1;sn@igzF(5;c_=S2vnO3_+~vs+ZZB=Wu*{os zzdHSJf{|9w&b=k+Te7cunsUTux$;9)x$;94zIhfZu+KbA``9*q=jwd#^DN}?W1ht2 zr|A8rD*oR0yQ;D&1asb+yy8{KDYOit`XVk7F zU;V}7_vRe>(1lgcU%d6Q3gk85OFHB5O&!(olfvmOEk698zUsV|jMTAXeOr(B&Fh%w z+a;?r_0rC9W7DPu_8#XOGcJAfxUr)HXQnUooi$@+QOjPVd@VlT4QKW2>&rURzsu;9 zhbvZ$&KcX{E7)f=s>y1bcHCLrS!enVoN->x;TbKyu{Y=V&Pw%_kLzCH+daeQD;<4S zj_?9De2w@v<9ju}OYr>`zTd{zeDtu91-=j9`w+el4`E=vQW_+JE06e$g8`0@!@cb>l&*S@ohV|;_OZxe;e!hz5 zYxw>S-{0f=I==k8sUE(!@O&HJeth4>_mB9#kM9TgI{1Ew?^b+2!gtzp_jad#5LmJN zgi8;)@VCzt)~(s{)M4LP{b~0hi>DoW>4C@o@R!vO9sBvRD}S7p``EyBbANWpaZ9h+ z^W~>dv|Jp!Gk#HvG_iTb{Zvbynoy@`BS|c=OY@t2eAX^v!*8A3M|k z>ek_BH*Sb5?^rW&w?}G!pa+V}o@PVD~0iiI5) zXJ@rs^oO!odD@-IDT@|VXx{>#7%Cm!

LvYO3=Q>NReJDEDZ5Vo zc%SE<+UM!TQeTI>GtOqd?)9zTkkyR z*6!Ue`t3jVedN*)?g`)W;DWn)+xMGs&TDU8KY76|M_-dYexL55XZJrlIBxYji$@3F z`D@z^l~eYA`hu%F_I~8>_s@Iro4?uAeAu~{y_>ai_U#ovxUK)>yS6;_!(V0p^jFXP z^GDZQaYW-eZ+-aqD`%BWKK+14F1=*;+{f~7p1PtveB%jMec9Ogz|))F{MJ8~uYdc( z@BeLb_=d_$#x(A~{@s@Kvmd@7^qvySN&=+ezKfm+2 zr_kj|KQ(*#eA;Bk;aqoYV)z3vKqxZe^9+noB0Bdcq5lXBQX>4xV-v$qPr^^m$%*lo z?wJ^V7wmANdItea1V8!E#PE-HPYmDl#KiE56B5I(J3cYIDTy4;pXl=)K0^9F-&0BG zPXd0Tb_J5a4^0ApAPJu*?30-O)+BPyL(q|kpN?eoll05r9*OCcCDFqhlIY2oN${Ua zf`4=p`ApAA%+InU@Gp|+^KO7A8eg9$q4RzceQQdhw;8)7=5smd?3X~VK8La;>aUu- z#PCOw^l#II#Q6K>CWfDuM9z0-C&nL#pePZa%}Mm+)Fk>=m4u(EN#y?<1XYRZy*>&2 zl_dRMdt72VCnv$bKFN3=m!#ewCef2KlE6!n$YDzoIV=J^k^W3eBIo(z6Sw!!Bzkpl z5_^7o5{nP=7aw%e7&EiAk0MaOi5xVMh;9yexdZpV}nyd^|}%{`P40_-{q$X4I%x(R)vq^^0^ob zI+TO6x8kQj!>6Euq<>ej!tc}Y4`62qzxJ03fbdK{FN%E9eVvU8pZdqo?pkgOHT^GKx0mlAU&|4?Uld!u{#_J)|2_&H(DVxqQ}_!tKFp?kIuI|h-q(gz z`aunE1!IKIepdlF9{4#|w>R*yO24Y>eKCn%T?zdp|D9S7jXqD*^7+AE6depJ`P6Cp z4}7T7S84d2SXU!IUj2Dc>%Uij>M^dUPb~~C>A#`- z@#N78z7qXH{sUV6Mz5X$KZN&aJ;_q&zHy*Ky-nBsYxMS2>G%D7nR@-t$l*A26Y)DW zKQIgO`7P`%`8n_%mA*;C+eMz~zO3&k{Hccd@D}I~;q{(zy=;F)r~ig{ezu6eNb^q|CNe9)K5NNX!{WG@VQyru~H3(xscEP=wFVb za;+zZ+b@vIdT-R@(a^tC%c0jp|0CUB-=3=|e4y!1M7v1GJB}_g{jT}HUE|*?^r4>` zj&N5#*J8ku&e9DkZS-nbx2wg&&()&;2aVAG^Dy42Z~a=%rd@Amss8Qq(3ygcV7(jf zRrMPE{~7w7@Z*B2y~|X#??UiNJt@@or&Ggc!7dU1^|cD{vKI6OdR#2g`i9{npH|I( z`cV*+_1P;+(K%_XB4F0V58qwEo8DK*=vMh0qV0os99_1L;&Y+LF8%#L1z+PC*Kh5r z=s)|gqT8$K9}9-rF7No7q2Z@$JJzJ}i}iSE(c{Immu{VOyn243*5?9`-MAL?h(Gq{ zitvWf>Y0TOB|K|Dr`5wZW&+yYa*)B;xZE9fwR@uLv9de}Z~xA3BaydYG!~odtrV)2HdzYx#de z`@2EUIJ#@R!uRUWh1zapzpDrvKL38a!q2%vwRa!&@D)QpS?|0O1weK3c`QryZ@2D8 zB<1rf$bs_g-Cyw^(C|NNKjQQFk#i;}I)xf;{874=zgHiYAvmXeR%`hn+>*~$bOiOS z+v67+QxtxowzpXt|0|3~wrin|uZ$e_)%LdEBhNb^H?}L=GcG0y|NHr}wEZ#k57qI; z?ft4k6OUDEJvsCf1vhhz-|Kq2J@xvqZ&lw=*HkyJc|Lcma!>JZfpuR%$+s8rmi+Pw_;um^2!!0s;ez)Y^rEz zDl1c{i4iZJJ$XT0-GZ86fnlJax)$VWD{68lO=}3&RunfiRM##jYHG-xG+o%3Q46}@ zz+W`GIHxRMko-mG%`R>_rL3%S$&%dM+`M@ejn$Q?pG9X>7B}VQRxYe)C~In{sBUVU zQRy$Pz(0P!uk7O4=Xn{(&7Bo&Y^+!ioLSuz%*#0^*fgu+nt4H~r>IW2^DkyeZ^0Pn zr%Y>XtX@!iRZaG#UvqwQQ;bd`wsI%whMZkd ziQc&;Z^{gMY3EfIoxOPHx=@tNt1717@^a3qZmg_msIptx zm{`3=h$465^qOEr!`T%zHS;PeuS{Gjp>R)`6P(`=Y+RVQh^xm_MCWHLs;|k-pH@>- zR|$bktASz%tNe>7*AZh!jmF$l&aaiCx)AghA}ns2(sWIIu&laveqG|yMk=|v7<6-i zJG)|0@XUM}(_h1CZZ353?CRR;#)as&V*eZ&Hw zjyrl+ZeBy2&^&7PN1C@d?kDELgUT=uQj4coz%^GDS6>@!oLe`op`qd$f6>B(Ml#k_ z#q|}H!IH*c)y%ru1xjSaBNR0zkpH-PB^v(;C6rqLS3I|_siNl0YnpH~ABe z{Sm`CcXCy5enoRl6C8mKY&7%iHzyCX?q;UlsT9INDpr-QiJezd_-=WkBKo0c7A!ncjBQws`YgjfoR*QsEjk$~{HG*{_X5W1X7In4x(3bOu|L zHG=+JCJ`&qb$pGb{LdJMv+};id*n`3aRvTuq_3&2MxgvP(v3|bY8n}ZY#ZI9k9iYi z=&Kk;&B~M&@K^6#aK6(WmN!Y}s}sxW5u#xt6$?EQ8;dwglsnl3GmLW?xFmCzuCgZ* zlgZ4>oxU(wc_jnpX|+|hvP(Q=PiMESN3nQ6ufP-UgD}E9&NphC>-~!`8!B47ZDQW( zJGhLSzR!k}L?8tn_z#$m^J|M2HaAsa-Z-Zja}RKP-eSM97YX8ecNqSM!XYbwOVp2U z^|_PH^b^u&cXEWtMBBuZiG3^`$w-TnH`y92j8NzoOlY!`!$krbZwwWu+j%)f6%CC+ zT3fM!9tWFXqMt}4Y|)4%fxJm3a%c!vHjBwAt6}6(_BEPlO#@A6=WRp63Ul-6|K?UK zaHrT;Bw{w!f1D~cHPl@bTa`&Nll(Wh{waxllik6I{6At+toAKvsINT!cvk;9}ge))Lq-(K2BQsl99mT+$63aIYCp<6Dz+oO6ii5RP#Z47W&5dg5 zhcYLFg{zcoX_yECdi541Qhh~r!wg2a_#f%qoU-B|*8y@Hn`U5jhbT2zP?{mx6$0|-=9kUl zOe~0%`ruW~6*V)kDntw-`AOvzQ)?M!U05rsYmk!X&y_$rUh)5n`XF}_mIJv67n~Dp z#B>u2-;0Z6v~FvFO-!i$W<0~>#+foR+90LLWySSnm37TnrK&2!_Cs*S%-K`04^rDK zdlGqNGwUj^EUT}psjj@npXc|Zb7rC65Kut{WCEOI$SQ4D9X@$M*@Bwt`v3CrsizJ9 zwVE-x@~X0?3Oy}1{=#c2?IE0-C{qtXZO7(q9grzcS@;QvNXlCUwk6A|4ktg8xC)K=AC$(5#8 zRN0lTJtEy^DeKOC7zwo{(m~`ng^s_vQf48O@)%~71(#sSy?PM>gNhnh4CA27uA+x7 zlQ5^Qfoo|-hdgzhU!TZ>c>5$*T!@O|xN<%pD~$=-qQ>gTnsm&^(8U|`xdP$-6XP2$ zPY0JYnMGf(dEGWA9wG?k#2Ef(oZY1P)wNarIXYC-j3x@B5^9F+l;Z-iyh#htkqtro zBY`ITsU`6d!nNt>Xln!xgyw37gl^C!Vah9AGp3XD)Cj_MWMP}4I}hy@|^lg`bBIdtAWFq!JVm9!NWBLXF%eJB@l8<#uE_*T^~$K zU8N2^W}G{R%Xx6Vi*2uo4gFef8P~)@k0OvLE&%3P^(q1x5j!Oqz}u99cKIXd7|AkH zOE3nEVKZhSaqno$m}nxP9mqtrEHZszMQts1(syoRj_D72sS#%!5Pe856_-JU6irl6 zg<*=VibjbfN3=AVvMCOYVrWw_LIJmB{JqHkMe$+G7@`JPWhHDx(JAt?uD(bP4J2)x7%siE!G(>6g%PYh&gE(c>VQ|r z%$!s9ih0$Ga}laQ=__yu$340vN+9P4b*NO_ls6@|M50zwFn55_nO9N6gNpNtz?!>u zgNUXoC@Tb5Bb`$$)@8>PokyI`($GzSJkKk zIXg}VU3k9qpzt*h2M=q@aKf&Vdo0i?NDn7)>#i=V3Dz!XT38n3F*3Dbigi51q&11g z0wy=fhQVa0npB0dZbduMesskw%ye*ggXf=SfF*d&xeUt5_58Yqt8t#u4cNKTq8gNM z8Z-~5ip^?17^$g|8Q)ImA?Fct)>R1Xcn_c_V}pn%f&m~Yh!8_UNuSJu#kxveNBmIJ z1$IJ;N{bd5B}SEykHj97h&n~RGuoLuv8))qQ;$R2ms))SAp|Vuw3f!>5g-gU&-^b(#1Pt_VVQ*rYf!+fcAMi z&dKz=f0JCGM#_lnjINlu{!R?N$;v8;Flw)6WNw?R#%u6Oz#?U`5bBB5X~3!)%$XWq zu+grr@0?~r&u5i22Ai~b6qSf`v(>eg4MDE5@#JwL_p3O;8of5Nbqf$WSXOo?wA3|7 zML5?|R&`Bn#UjwGtZ3w>ql7PD#S^_Gve=b#5w_%)DQmwosygXkF^f|;)DS>5;mFk@ znRM;Ag3IIorK*H*?ipzYV2&DKd-UvJ;NKB@a{N4vD=(1R^lxYJtr)w zy&9{7W!x=V6lC;Ssiu+ebG4O=>d~Qy1G!B$zoNRv2PlSs)@_Jt2{x7&1s5qq1{#=+ z%kC3UNK3yAvk2#SePuy*4>INy=>x1Ilgmd&Ny>=S>8!`C*`Z( zrKNyRIw?2TH@&oU+L<%Ta!;BVpEJo$+P_cA%axaa^s8L*dyL#Nr``?XjdNq=_P||y zqj4J@{~M#T%#&rAw=4b~4csyKmmj?DrhhS4!AM(`BbLH6rC45-AQk>HX>)&}qM>fV z+f{Ig#}9KzSEW;h@-8~fdPeQQe~J?C;!FHr@|<}5ZQ*SzFP_TCRI;*!d-DL0R(y_k z=kZ#rFALwIqp!i6qp7|&yl=`6YuFdRO@8x%)p%2S7hi{)pW^!gUfN_nKNUkigt&M0 z-LA{L{NR-kdy4OuI$b6CV|{CNy6M=P@e1J>-*0sKD#;)1dl6}V%zcvPJ;VO%6ueX4 zGil(X?o#kI9{5R{6}-y>?=7V~aCe^v-l^$#d*S+hz8(*}Tf_T2@S)7Zg?_&WK6*D* zuj7Hw)bK$Me9dHqKjeXb_Y?*9?WO85a=1>vpPKH0uRcKGWqRO)n}khYmIr=dw}NMT z;Ds7q;DNVj`h{M2zTz|Bfp5_8A`ko~{k~(l2kz7Fvo7?&`!$_<4}6@K+Y%3a;S;J| zZ60`+=D))O-z8P?zuE&Y((q0X{Hw>uHf|^xVdj;i3e`pk8kn7&AlmY9=N%Oqr(F?@6)gLz|DOjogTP(55CI-H}?&! z^T5qL4c#8NxnHN(3)kbc&jUC2k@S1u<~{F058T|hG30@p`#gO5eP*MF<~`|D58T{; zlkS0=dnqzKaPuB{wg+zR@5%AN&HK{@9=LhGKPMyJJ`d^l_zOJn*KSdEpwI(9_*Mlk z^1#2;_XL!B;QKzL@XI}LbKlQG58T}6QSX62sq0@Z)Y*aK{6$*XZ>I7%haG${TziJxVf*W$OG@t_idDW;GG&??}3|pR@yvpUyI_u z!vi<+?DW9vHU1h8-1xzD9(aew@Aklr-u8On-5S5o12_8bc;LR}ivJ-G+{iywj~kS=2`%VHLc(2AU^}zd0zj)x?n*SCL-0hu~9+}sPb&I9k%_mlN_;HH23JaE&$ zjt6e~cgO=b_g$sx{xtG8`kCp08~x1oz>R(udf;7J4n-cgxj(7g12^}jE%dh zo~7l}=7F1g-Bx?xh5DYPH6FORCv2SuZthj;@xc2vojwoT-1Fpk;N~8|ArIW#|CFlz zgOPuWz85Op0}tqQmIrR`8_V&)&Hamo9=N#&vB(4O*Y}n=hsVz^OnS%zpT0~vvP{o? zm(OT;jt73^588bwA}6z71bv;UDi}`+O}Hz76lQ@DH=_yDWSg z-f!WTTKMZMd>h_p!H)rcx-R1+fg68Ix!L%c+WvUq*-79FlfaD~_0lQOB-Cg5Qw@-kAj6l?2|M1m2qj-k$_Mm;`S8fVW-74|w6m4|w6m-gx0dR==NX=|j3T z9&LEPj)zIdhPUXr%L_N_%3gR^5`43M>BaY1`eWBykOW?o1YT;%*`{OSdT+f&mKc#Q>jEchY|K4`(~EclQG zzsiDVTlWHAZo$p{w%lXYSD{L7zg`z5{6-7k+}};O9aorpr3u$dgi^}fk4g9k0#W~% zdx{Ca&w`tKy$Nr(;4PYe!u67qoA`J3%-j1;#p|HS-1HFEVzkHnO9`Nv2p8uN-g*}7wYqsTkt(B_(BVg zt6SYqy#?RXh2n3yS@1Lq-eSScm}YjH1>eiU@37#wg4g}5w&3Q@S7vrvaQp9&tg+y@ za@hTJS#Vq>>weZ*aB~MRGrKJ~u26M9Jr?{>7wYr%TJS6j-eR12PM!P71Hu@*ejf*)tWvn;r|Q_nKiz__w%}7Oc&7#bh6P_^!OyVZT^791g0HjS(=2$m1wYe* z_gL`h7QEMj`z?5%1wY$@_gnCDEVyIA0~UPHg3qwvLl*oz3+~hNV%pA`7ChC0&$8g@ z7JRk^&$Qs@TktFkUSz?uE%*f%Jja61vET(3yx4*lTJX6RJYc~~EO?OxztDo0TJVc3 zc)11trUhSU!7sMp^%ne63%|I%A-G@;0vtmZW=w@8)$tx z^(o(Q{*wR=AN4f;O*^a*znB)zqW#189JPUIh8)peN&kxJ(M)$s`WH+ybd7dN`ln1Y zl(>UjcB`nM^ZOi1thRRHhjs zM0+Kj$27y~Xt$(~W11m)v`f;5GtJN;+9~M+nP$ik?U3}|Ofyu7wn%y$(+m-!^^zXV zG(-Dnxun0i2Wf`%(IQEI$}~fVXrZJ(WSUD#(Hu#?%QQoXXqKd3XPTiyG+oj!G0l)6 z>XY=dOmhh+I`~hv|4F8^nC_SK2BsM@M0+LuE2inxqurAJ1=9=>qFs{yDboxMqMefd z5z`C_q8*aHnQ4Xs(H2SH$n-Hx*Gu|(rn8wYm-MwvAIo%+q#KxK2oNol^c74W&vcHY z=P`W((^-35l?>yBng`gNx1vZLveeu-(i>ZniB&oWIH9Uc6K z^gq*uO!rHA1JiWL(OyaaifOvyXt$()!8BcPv`f-IW%?|pJ0<-irs;~K9g@D8X}aKO zi==O4nyxomFX`)<4lrFV>1&yu!E}+N8<;+q=|V|g!8BcNG)L0&n5L_ZW=Z;Drs-m% z>5`tqG+k@dC+TyUrb~?uej)wOG+k-5U(%;CO&1#Nm2@7{be+*|Ngu~FU1qdP(uXrm zR~hY;^npy%MMgU$y*JZzjnNiKk7JrHFvW^I6(qkUBsUK(HhbPB{S2z?7jt=>4VxVETUn z9Gd>|mksyNKPm076+-{Ar)c$KX_SBGE+B^UU&o^)aO_toAK3iWm_TSSu-Q2yFltNS z#jlz&LGUU~a1RnpMz3Y+U%`g2`Q$+B)Q>yytAzaQ5on)!9OygaA#o>wf3~DN2fR^a zr-h9Dc33ftH1y=r{DK!v!+c_M55!Ljujx^X9 zXEy)_4ww=84T=z<83ksB9Ol0S9^ivBFPV1fw96F#HWxMVT#Qv*JjcHAa2xWF z^goA$hE!95;W2PL#m#z<*^kTtC?)}daRx8~A(4I)<<)-Kkm_F4Fb#c;*7W`it$7gU zTDQiijPok;H=?(|&D8G@>C?Xr4|k~I&in9`8$VE)=YmzI`N zshl7w6{_kwsG`7-r&6}iQU~fH>M$Pa0(qQ%E94=dba}LPr*5R+*xq^U5azXZXEJ?y zj&K{rU~p!^0~%5fpl=3_qg)g+R5RlI1uo7Y{4bP3%W0+(c;+P*U!@pBYcPg7fsbdz zxr+GVjLutxH-O078n6-LZHua(K;f-ZRktP(E<)Vt?<8^{RN_E+`;qRa661-!^7rD2 zudlU#RO`^Fv|Bk~FVi?Zc=iCN8&CAPe;uCq#&FZtcEb>;QNEW#jyOF09|%1;km~%B zA`3l<4Ad+`|1ra8xHR4QU&I}O&=!u&;Nkd5M$z6~*%x?jf(p3Q=O7o&L8(sCua_d5BJH1nW65#$5!Klh|%Q z8NEff>~^zs%aH08JR%O=E9x9lQja))V+V@)i#X3i0MKjELYIop`zf_n|GpWGSLz?H ztK^J-B}&WfkI6U-HGd|g!bO?w{?91n-#POT*O|JVN*SUl2SR z0h^Xi7Ch3)Bg+u}6#zlw%8fRExJu$KZshhY=?W(IkaifUe*eWqX&PzBY`3 z79h1i@%khFHQV!WZKQ$S{GN$!T3`-a83BXTj@G5nO@O- z-DMH~D;R?1-FHNeQo|mZjbB9LWfK7`jEH)K4#`Yhp;kDTgB2gcL_9)<5r^(Azq+EbUI+x~3%& zfA28D#SxgB`*#g-ps~CvJF2&}yCvlBBv6@F2zx4~9?O@$@fAq0Wt|CHb|+efFAAz5 z+YMD1nA~1MgVC=*?|(8p9P+QhuxfQifkfI5yW9M0Q4U{>Qib#i%AxD-Yxmz5@^4LB z>+fnE9JQi5ZRO9<>~{ZFaC0YICyma^TNUW^acL{tlu*$75$7PNhO!?mn&?uL&>c-n zmA3Lv7W(tY5W_YjQQDz2 zZ#Oa|+K0ii#I{=jjFxp6EnTq@ie$vuh>^_aVsw{lNGnmJXwU>Zl@kSqkSDK!H zEzMF&6XABKWKEm@5syf(6sHhzju^B=x_@}qFp2bcG@nC*y#7p# zFoYa0yoV{$7-oTTHF$gsaAf#95fo4PK*5)j_t2Ao{z-SsCTRPLKVbGJwjJ@6(!35* zxmX4>gWIK!ubC6J)nEWw(xHF-2%-K&0NG98PJob@Z{W}wp{H${SAyouP(Ml5lYHyb z<(OgVNP;a~zO_Rbe_|nnozSCPWmL^>Fu*q}dN@K6}tvU@=V-Bx}DRQoB^7B4kyy46PC{?+K0*C=t|>K{9m5 z6C8(N4QUaRC>(?2ZnAKL2%JIk4H%Q;SnQ-o_6J#vbab$#SVM_HhRArX836M}`ObHn zfq?8=Sa%GBU_MltxZv112)#8y^_DG)4UmrRuub^c5m^2-J4iasJE;eYL(s;-rU~*3 zyu1NV3$++jX<llxJ6>gGncSP}rvVBj?WP^|PFBTK&;R~m~6;`_AzB&6nDTu7l> zn);JzoFz5$6Rp`3Jpll8%|7U>n-pf%X6S|>DTwnwB7;>T){SL>ie#lq*2*Ou9PO*rgF&&>{8)4wnrsXz zpYdkV(#{p#%}1gs{lMwLvj@*^Jn@Z9^Ah-yDqUtBp6gJi3(qb**Wih7tgLNrsr^8X zIBjAoRX`+wumT_-%u34+z@m9lZFKII5u9?V%!xBD!$Vuqq%-{EVS!;guWyy<8fr21PX5(F+UNc|BD&^GvXgi_y_-{dD zJv00HL(voy5! zJt%y5eAyr3X83(*icRo8GQWxiDKgH;0nZiGcv~pjMn~wg1l(d)b5lq@)c=p(I^mlJ-ltiY$^87M&yA9?m zLHKZ`)1or$sar2<>V-ljjYI5M!kyut4(Exf+ZnJ`n7S3vWW{FqyZ7(t4F6?u3K3@- zO1i$uo#8*Kb06mT;1bh1itpOTrtYBJ#v!~fm6YTvvX7~;13EQ*K`KHRS+Y|3| zjJjBg=T#Gl2QpN9GF5x_VtdeYyR#wI4F6RLwj<8;w*WVhi95spwa)z?Fy)=$55n&L z>ofdGqd_^G@zE>RZ1+3RAA5#>(QAtLJE>PtqSy@oO^i%?HvXp4ybiYXX&KDPX88M{ zz1ug#4}qqhFy2J+|N0Dnx@z;^U$)wO3tHlt;g`Rvn!SeRN1APB_#c3I&kX;MVx#^~ zXZUxCz!@ap#n=fP$7cACK!HZi@JshmE!^@4OZnnv__ysr4497uGyGkUmuQCH2kGbz zdlNsC&Z#gV83c>}znsGyHqRR9Z9qUn+oNR-DKw<2fxzvfku8B_lZH zMwzc?wBupcN%diofXt%Bk)rLbOZ$Ayhit+m+~+K&$l#r^C!8iWvM&mg3I7E=YN%vm-M;gc{~jTw=YH>Vo5HYQk2)yd710jp&gKpoUn6fFLzp;Gj(C{$MN9ALgCl}LvXLptfXY8>IjSA-T@ zRq5G2HV{+?MZXR(2(%KCM`iI=sWJwNv4bP*nOnYIy3bj<+*0eu{7IJ1OZ=@DMC%z2NrB4&J zZcRXg+a!a{EQ(^Y6k%2LQVut%$5;@T1A(GIjO%UC=0dZkE9Q$kFa!H(%95vgCh(H5 zs!n(qDYTol7I#I+c-wZx`96wsicqMR(+Sd}gdbm>D4iXHw1VPN-w#EM)u&*}*RNw%lBZTH};M=|f zZE6DochK5a*5TilyZNtna+mPzPe{j*tIElIyV*$Ft5zAiS-@#|f`xqC*ihN+3R$V> z3*eJ(?+7A@qaJ6 z7JfXS*b`CeHrft;jVAm7LqWTPevXRePg6y0e<=q~i=gW0spihdkc+9^(oUajxpuAR z#Td}gzihEI^l#`cGa-Yo&)+jbWy1cEj5|)qa2`^0b0#qLgiJJNCNNZ&za*W^6$B`Z z9Dy5ro{izUK<2$*y;HQ>EEokV*jbYWTPZ!zyb~$L2gGTj3{V)a?Bu1Pg z+4UH`Ay}F)HY?=XDf_>K+uPj_rzLy>3g@}m8RM--Y&ac` zYqke)?%C7>UjnZhYKGiP`r$ix=IJ#w;1)Cn?iHobGjPOkSs)LMLEedoM~q;lym)pH zfPp84FXbc`5Pw98glPB0DGh3c8~9(l{+KjSqW(FSh&YJT;0WXV0r*G8C!g!CMr%g7 z(o!A~^-zEOLlOUHlsKIJMut5ob~1`dGyFsCCM1HFqxSWMnqNUdXc_YSuV8s3;vZDS z2Tk$8zp?mMbuwZol%Dp$U`zl)L{k{VgqgfUjHc`(QkJ|8wqx<-OGH3E97fe~1ot0M zb;LOu>Jy`B31v&5JtcaTvUi)GjUgGYjd6{SiD*1JIhI+mzK)TF%Hg0tYZrZ8sA`Wt z@i|g+#$yubWzvli7^8?mISLcb7?u)GsJT~*2!5G$Qm610?VyGv-;5Oo|FJ90mzt^x z02hK203y9&n||jMLffpi{(I_e_14>_09L(kU^tDaS1Z(xw3Um+(zG;GG2nL1{!(GY znevs}_s$el=^f{~@JY0V;f%7Xm?iV}e>h`WEZ0=ZH(#t)q`Ni>x(QXL)feXOfC`Qr znKWT3-B32$mIXq+8Z(@-e-q7DoPKc<<#YCiihAfNje>4OoX-$pdUDB!-e2b1Njf)X zWyNTOQ?_8r7avio`W_!i(W>u`k-1iV9gxw8`r_IoQflpn^de5@X9hbK71Ka*&$;>U zG-KjY+kpnJI3oU4^$Mj6w?XOn7^P_*N|1>)Bjcnej#sA%P6}P_wX)>>W<(T;v|%Ir zj0h>8x@FnAY#LIyaSrlc=Ff#78A566c8Vl7!(qcfzpf9BoIxNZ()x6^b*_2@tDx)`aVhNbH7gNc=ZvIfMuRoWK>xVf>dugGw^--Y%w=t$ffhpR|NdXLf$pt^M+w9Yl3X0zKequ6;V(>M&Q&^u;kq4%yV zTzfNOZ-tEWFBDaKVXBxS6puKUa}5yhRC$&Xn|L+{yhNN5EnPFoJDIIR^jy7#;s8#B z`Xl@7JkBbbM?V(lL)_W9$CurOqXLQLvj#{1R8DN9sm_2R__br zW6mw;VW7G)oN|){{OBYd4S;=zF7pt1NeLGA(F$1DaQ^d`E7v?3P1FbPT_z2!Bj2VN zwn6IxMeBM^>qER66i-V#drM@Zer7zgA|*w&ULm%V3McO$AYc*h(e@_*OIyq2P+QSh zqi!zsZPIJ}H`4R+b=3CorP-v5Y3=_?TeFd;=kz)>W}s+h8|2=CXA7p1OHfImT|W}X z8&rN2i8$?otCe3M6{6cv0u^MsV+u3tWvM0X*^?rihl*%G{Slp-}5 znh*LN$i&y*359%LD^V`8T9)4Fnt;9%V~Z#DBdxeoW2HPge}WGO0R{6hbct4a6%Al=YOjTcQ?S))0A^C* zS`vh-VTP;`=f~1t2tHFT66$DE*#8gaJj6~9F~@Ims4wjq-#}7#Kof?yo(MFJF9Q07^@NM7q;jxuBgFgT-JG;l4gCSrj|m{yve&q5RyyqCNCO@@J7$c2GcgDhx7_H z)x*jeytn~;Vw`Mo9ylBvo~lAf zu+yE%I`_Ipmy=UH5$E^hK`M_p{z)tdON4a?j3ymYyZjf}QVN7-_0Ckrx*zd4c!2rR zG)ulgIuRk;-rR#lrC#vXHzV}Pj8IP?^rFPCc;y``PD~{%`_y15Y64<&H>~wK)YOHV z)&Oq}%WOKG)VciDtF6Ifgz!u=LM_dU`mOo-%~Zutn87u+?b<;U%fA*sIHL2Ga|M|Z zsu8CgqJV{m>DGYrW3su9s$rdmF@^Tio&Aa$EMbs>)WzVXzjU1(m1&wtjK6I{d;p3Yj|sB=yT^nVNxyQ zub7PfI!%wpsUR>j^hdf?_ciuPA_zb?@o6E{$JXADm<|%pk@ezfm%DQkF)t89#swmV zA@Rv-(s2Vy8yn&^&h}jYR~wAEqLwTa8RHE;==B=tbtm+CH6(>~ z8gaTPjj(K3tlNmQ9|A040IpxqKVv-+6pf#uy12LZ4@ahvgVeGd7lytERPX?F)1n9b6=U~XeR z0b^tkl@6K^dc>R>9wCI4Qh9@FNQGM;#pptSLnuC!wzlv{Pd}L%keVP7DG(`CaUp+m z$1qfsPI#m+6LO@ zsXb$%n<&sc6q*9yC*b}@*JiAB<)!>k5t_F~?M*CSx`xCT^Np~s_1{D>DB>#*S=$pA zp(pL_iI0&WMmvS}lJ|s^@$<+KQhkpIDT1@n=w1!p4Di6AF(;l%ZfCMu<)}YlLt@^- z^bj|q^>keInpvS!{KJ$hC>>-&Uw)Vk(bAB*X#!nY$HgJ`I2fa1MvjOHiIHOY<#l$zPC#2C`KerH8>J^HCUVI{H}|2NduO&E zwc!$J_`~u*!^?%`Oc3p*KK&6IjDuGuc_bBD)C;!_MI{!A48M%rK1jvf85GlM@~xNO z;&cr90jDOWV*C`vK%QZspXN%YgU~=?L1wN-CtR%rG7R6bf%c4#E|$i8AP+Q#+nGX( z^50FA68oLne%8bc)nZ?Fr zKO3V49E8I`->*ysQXF)#*uYQ{*jC#YPYdu7E?#9o195EsfYO5>l7&SvjLo6M2 zDXNlIj*_n_X_h#+7$XbPGE`xorD82h@9eK%8tZ63K$pbnK4@hxN9I|y* zw$6G8StIbsxw&!EWt_F^f303f2efg)gTV z(#)#>Ch`B}GFaIE0a0_wzo0~%Mi$dsLHn~73FlE76GtoS!@o0Y3y6P!O2N6BNkyDj z*-%Y4gx}G-SW(39pfRd7Vx#>|T5Etgvd9;JvEag5Z(tNnO<;5XX!RHq7}Z0CRfE$H z>3j`pARR9;emzZP)$g!m48L9b*Pz1o9XVIUZ{~RKKXqVk5%P}jD zr|FcJ4zOC+1xbE=Q(*D4wqHK=Iom6r?6kG?dS5T{9jU%B+X!ge{n*-#*-y!z0__|W zP_0j)YtFUUbuz*^3BLzs;`pUADtga9MNq)R{WKh^IPA+gsOWYI3#nmxs*G6X;M#_W zGXRj$|Kjw^d`KTDRt>1TYqNz{d$v654mAZN7Xw2aJY;omWmOdo#eeVEt~(RbPM%m5-zAc zNV8+EvEi2$`AlrSaZ z6-hb;updN*mS9m;)}Okxo?Xq8grb3{1WPJM4Hbbw4e3_JQQY%M6fBGWdJZf zyb1$kd3GCQkHn27iS4&(Lvt=-_P@>+1N3Kk&;S+DPRXomM!E_6NfEv8-hmPq|3j!} z{{=!NhdRouf@d;O9&j;MV_P0%k{!|UnHilcZ`esuijgHbUF`%^s|1rss;Kh{)agzg zM5u1r7ocY&+h;r;%8o@F-8RKWgpsieai#8Qvn%xrAb}m$8h8tiDy$*$jG+89DiiDH z*eGUi8O|&}r$?}n*E@H+-ImQRc@gQ@46hu$hB4QSkqDd4aVNH2?9^$0mXa8-Sb#9` z`0pGa3F;BL@6Rk0HMRq20jSCP#+^gRmd-*QMNm3e4zU<($jSeFqSPRpif4u*^wX~;%}EP0S>spcV@&zO=pmXg?3&*+5KZzB$|2!A|R zEW#V|@K}VRq!vNzzh})NrjdiHcLxLE4v9TzE$kiIoDnucO+c=cw!58!UQ7*qt&Qav z5rKdPM0OOts^}W(lx|8gj`Z4AjO!si4H^$>W<4f;ya`;bEh`+g-jBg2@h7z}FtTZw zfrru!hv5#jWF|_Ks-RrMC8y&{ByvreEf0h&nJ{`{p)YgbDZ8xxFd73bDb4|vZfH;s zVzC0G3wdnHJ;RmABC9p0)jiwK}ddU zw`|6UAD1v2_eFrU=sn~m?B7J8w*16w!?@IhI@Hs!lEd{&l?WHX!JAq=c!dQ6IKb@I z&!x`rq|wRIEwZiMxzM~#f$-9f*c`RtAgZO%Yp>4=gu_`BS{SF8!Yd0!j1gzfpV$e8 zA*k0Xl_TA7j4U|2xcAY>YcV`~ySt?%QaJ7oi%ur6B($u8uwvBl<{B=>x6%W<;>!2c zKcp;qulcNQaT_lI9K z;rfE%`kdi<3_`u$ZSg>!jz`S3Tv54JQ!z1DSZUad%-En-!qR(Ju98KZU;h}^>G zg%!c!L%dHa(F}GrVy4b+E#5;cpvKUs#a5V&_Z4vb%EO<3WL6#^~gDmk_BebL5G;aK>YKE{DQsY$iern$C9f-U&DMHQa|YmU~KS?3)u| z>$YO2m%$svfwzY2wxS+)4mt!g4fEhGFY$6QBUN2{Xs`|M2!}K7$&F)v3uaL**d=Sa z9E&PvPDdV2qMaCMpStIn#7o !5#mb9)^`LbvddzX1=<=`(g?!SbwEa-r4*GN6ozk<#tA z9SgyF4_NO856_(;vf3gKSbntv>eCGp9;mOhdQ*R*aDSw6Te}ODMeGT*H^4Z~8l1^4 zXfNqje?o)&a~f0P;BccHPHgkPjrMc{40Tj1huW-$OWqEsqh-j&_MR+8G*QD(P?a9# zR*IT@>+={chBMCizG(OoJgDIyJH_8E#s2yYY1g0S;cDbWRV-B%tCC`dIkRVHtT_(* zZ2-E@ws6b~XMA&_^lqH(Q#ofO$T4+`YLeo43?6+xC~SHY6!gtINPhc| zdQGHxI)=l=Q>AN)0u7$BmrwcpEhh>A8WLB}>(%}6d z2>0Yf7VHWJMe`uXyv^6%;7g5Yy-P5}aVW;3kVll#Zla0PfE+jJRPqTc6C4lUJ=X`nI@r|v@Es? z>iDx1g{g*u8-n|B+$7+J;8y%C?XsnX$xo^@x3wG6VyuUmPYjDkYuK7XC5puq#q(1{ z6cKs2qPRqf;+gM?C=P@~#JaL@Tzy{gmpD?RV*+PPAS*Y!_nj1_ipY$eHP%Z-+k=RW ziiAP6W3XF4$A)|3yNO8jn)bFCInDpsQa0`riBVHNl!x261*&md+of?qv~jqX7qe8- zfk1tW+%pdPT!KEV&(Y(0E5vBc5C?8gVUMCS3qWFu|Gi}hpt+Pr)J!~h=e zy?&Y!T%!`)y?9V7#`wqOx*uI2ou>rNc(brzM2QK}Y^5nNE*~=A67ipH1KCLgN zl)@PY+{j0M5Dyt|QdHEkPb`>d0)i(9l1sg8XWEJzMBF^D-i+_r*@5;8a{{4hfk5a2 zjHj~;kS;{J6zOu7(_K!A0b^;IC>2vmvPCqdr(r+lh93xR^o+*kyWvQn7ehs*1K&c* z3DGk4wG|Z&)bIxngP^fsG3{*pBkyD7SLaJV%##QDAxmtgZv&=3P_Cu@nSr$FSUHsS z<5`_bU1EE#Xh|_z;_pJm>#**JmdHx7%N2bE6GdYE`Y`ga6;T2$qxEyKX#JQdwX9$7 zBw_3sdANGMNcBd0oAk!Pc&OemQZV&-B*qcO8hgb0p(+IE#`^WqtUx2nRE4Fw!jvMB z1ain)eI}p7_2t9$rNi|_u==jC7n>1#tIF5`$2Co{zJzkpZdtwgXmEbhx z5AtwZ`z_Vl|M`xz_Ch?^+KfjP@&g(483hg<`P4DG67nr-Oy!LiE+cvI>xLpFE(ovA#m>(pOHx zzLE;t3%M|vwu+;}(c78S2+C_UO**-vt5KaAJJUfs6TglW&X{sE)s(hryVhE+4;i}z zSHbzp4wgSNuDm^W(Db55CFe(ZbFdn5a76=M(v^p~*wP3IOmKSH>+|3+^}3j`?W7eR zUm3y`!P7)b^B1h7mQKA559i0x1BZo$$k=JQbZl$wkq@^;=F}AFiO5B>kcVx@_>$T9goi6p2M?LI0K6x zpqoB$k~&=D68iD)v=gK&0O8{)H0ARyz7apwvGjQT01pWyrH^|bDGi{4aasUo#n*Pq z8nu6DBNzl9I4^)Fy10?QfAA;HAWTWE}YTQ%18csJjC>Zq==txRA%@4 ztJ3N5rRS;AXR6Y7#!Bl>+YOsJO8jjQjfi_~3PJKR;@|m`>?2FZEm+%U5&cJiKE%{r z5W+o29#D%^S1r(z8L4LS#m%cFap%**8M6*|M~m5O zGqJDCtk}y~sa4iM9y}z#F%>)d8bNiQzI8Ft_1CHF__1Tgt&C3T_vO&UL{vZl+t4Ft zhl+x|V?_n@^7d$}2$5OYnr)0vsqjb0LWS{sNkj3M51&h(H}CowqhK&huPyHWsqc6GU81c z=`4}YFQqDxd=kqICoZlNfAJ9AuKas1$#Zt~w(}Z+@&_2>E@8V0bj{QPem8EdrKwcu~G@7SZ`&C!_jPBhb&k~=m@{k&l5}&zAbr5G*l3=C(8*Was=i~ z$R^apHLA*lc|$f`96d7vhKM3g)X>N8Ws1lMZADhB*Vz-9t`B9i)IlyhF+GJvJ{=YG zlk}@@y~vY#A#ADi8C5BZq#_ziRT98ED>Vd62c3{i*~OTVJbl$yjM(+BxT+i7eSVhnu>?c zg#<rd z8kt5hFMVftctaauA+>;xt#n>6N|3YPzJx!Owl=I7a{pr5aC6^qbMJ6-&oB>%OECN= z;^H+oDz)`z;?LTTudzFn(Jz-l4&k69Z-Bca5(TK^gL0(eSuoxY#$g7i<22Futt`ZG zpcH39QR)-ERpA!V=(2w*M&&jo#z9cg$6TZ`(AL$*4ew-mUT+g)Rb&iSrFl0z&E~14 zviosCJJy&=P5M5hm5T$aXxbV=STdaPhGZ6@mnFFn?c~fa&K*r7ai!%|Fc!2E+2(a} zHX@vH)Bz*n!jT?Qv-%s#C7ki>UQz@srK`Hd>_YzHW^N)MEFiPqqU<<+_TlQQ;^&p6 z_?c)H;?7bHAAJ~sy&#Ea#Ccnq>E3YmBw0emoJt7>4*SEZN1SH_4_cwi$B1|iH;H_Ef*|Y6|afml3$<1eEo4PaNjp$H4sYd zowGWUOkho^uKGQ!`9O)EH?aUC-Hm7?8X0lQa2mk<1M#yYTLwD10o1W0AbY#2)E;iB zW9?G7otq=XH4ml~Mu_qFsYaotZj5KB6)x}u6*G*q`oo!I$Bjo0KYXE*v6kPf)WPy2 zS)i{l<7KpL1ZKL$2}Vf#?SP%~6R8O`0ShJOp%XQUTz_^cB*%J^cYBQ#`a zeW4gh6a%IRdDE3&Lli0n@xLTv0IbH{N&maJI+AJDFfAn*(>flz&taYG+vR+8#wU%q z!@+3$pIAy3n*G3wI6ooNyj3R*hlz_Hv_*bUfoVO~VG#Cf@E;VIR;d@IsPJn@Wt_Bw z$1nQuzSD1@RAj9;5Z+@no~Q_~u!$4;_$v(h*h@>o!V<#doi)@B&nRNdk#b@IP}A?3 z(WxrOVvyfqw@TsDP?#s+gwIl1Cm}Llh|qpGxXwkdS(F(9y6o^jSuqs_ZIl2UPe?;J z9b~5DAcAP0lTMe+U;-z;j)ggXHn8~%XxVEDHZIn}yY`W`1CfjB>6!$3Tl*7RJaR=9 zno*PHj_+KP5(^dBecQK!eQY&%DvR^R(m8EkIskm(w^_RIR+ zzb-)A&ROXoL=ZP`G10czu(;7ULyZ9}d~(A;919p0`N-dip#f6+W%N0yR6Fl&5`l9^?3Usr4nvHbQ~ z+^0rLI-GI!Zf;bg8w=KPUk_F%bvl*lCF<1(sqH-{CV4b9t~c+XymkM5yJ3XK!2Rjz z@%4fB1Gq6Wp&dq^^q;18!bo~L=ekWvDCjlD%M;~?GyZqicwTs%3U#hEZP1#AMPRp0 zC*gN8UhTHGpqG_abMltWGu@#lhGalJDpnx0%8^vK9}i6A`s5MrC9r*^!i+e7Uq3t? zkv|Oq3ckq7v8bL_H?lGnzwiSug0D?Tg2Et*F^J1U7#Ru>Zd=1PYt9%0D5LaD zM2Jcu9R4QTtxp!{IQzF)xdZ_bt(%FSmLPl-*>>qk|Bs6UeUn@?VkZUi5vC0*MgZkP z=>=y27pFCSG&j}-hreuR_+l9!W9NYz$iG6H($=nQL5>my?hA5NpcEBL>K!a}^i zETGR^JxQAqJ9E`ogDh};8s_odv-L7Jm?y4`P3F@zBp#1WUEH4{& z&Yg?ox16^cQ-`^Dp`if8N7f0C++H8vk7FujNFLNT*ihg4*}`nbXfhVgpNz+F?_&}^ z#FVV;OEmu~o6UDX^o&)#)WS6V5j=!v>Usl7E4J@N&%}8Sb2HxZt+M4G zdcqO)d$eC3tNP>-?!^N(s7D^*ZUUj@@?aMhN~FC?l~D&$`w&myZpN&bM@ct!#Tr%}dz?0fVy<4Kp!L!dJQW+ANq*i18ATf{k* z9ER^N$1njmhbe9{lXG(=xoH{64MEOLIEbjZ;iX``SU$(qgEK>aBWusS%S@Lw#Ln({ z%pWjIqTfI^!08;b?W@>f+5-LqF@VVc(}zPRlr1>}Hc8OK{uVvVPlnBfU1$Np9u3Oj z$wR@wI77Cw#c!|`QY)fhSWqqRx{cZ<3m`>IvYP%+!zzO+fDJlRKIrXSH85OHH_)EVu5-l%^PZ4^o}2kR*Ypmp9 zE5^x?1U9o)ukQ7U0-j8A*UfX5+w$&| zG?nl7S54VF3f!jhDXC?3gYGC6nD8v1)}2L_N)hnsOY#Blbyg@}Da4brQ02%BaWK)? z)v%cQY4>SfMr2InJtXq&qO9&NZY$N@g=~R`tv-m;)t&OoQqFx;DD5V^S0vh9^2jn8 zvF{ZVO@&tu+8MdB%mHWBv&qUbU;MsGzLVz!Z<1c$yCtB#R2;d6*(zE8t*TlwF`~m! z-?&y4c)1jgEL9n+{$ZbhZBq-OvR+?1yP40EHnA1ah!iFCE{Uyd*C=UJeyCf0djdaC z-O9(+nuVRHZe=Y1S$trdTRpvRn_c_2*|o+>z&!0SC>rq%R>>JY<(?Vcn0%bP5q9nUfUHPn!2_tA++d7rOGTx)hRXk0%qXc1l*=J{>XfX+T`XyW$0;Dq6tSP z;F7H>jJ>X>jCHF7##rj-|CAZ8lAJteKdx8Di#$U{9lf0V1J!gKl86rz@xM5FY4JW9 zbY!`9$H>h^#z@Y=Bxm73Eq!}Fs9QDrO}{XE({d;$V7$_5v0tE9ua(*Us>~)EoRqY) zeJvl~a0lVyFO<9OH?q7ZBZebCcAhM7o;-r(WvL5?S2lk_DvgZQ^nqE&`R&G>>X8iF zDI=gsFPq=`4B{poDk6r~6;(cgO0r7qIy83IO0pc6Qd!jLQ$Q-!4VJv?CM!+* zUX&bloFvEEXn0Px*DzN~5*S-Hyu3PP4?MK5k{x%X(X)O@^GsU$hpOEjry|7WjQE9Y zGf54?(;sN2;gBQnsx3XfSX9$dGbF5Pla-_q>K2vjlnvctU)i&K^(jh~^c9j_Wju<1 ze@CXeEH%@P2GKpQtqDE|KIY%+Pr>p_9nXN2Sb^DQ#a_Xe+8unA}?;ejch1c?4d^( zRBeQGWH_E-mpSu2RUsIWCW&#fcDwhfazFK1_dY}Jr^^IW;@VTXEi^m!y_(VuPzz9s zUn1d?D04Kq_!C!W6ZH3TfB%n0wjGS$2cvl+X5OT>Go?dDJT}RXz`}I$)Mh1M7G8eU6mJ2Xf|CWUp;5 zk^2&vtJV$r_upK7jq-5|M3;{giemS#Y35S?yz&Y2=Mq`s)u|*&DwSTUO6yNVE6(Fa zOEs_3(;%Jw z{`2!$TSyaMYR&hehlt+Mf1$|uMaS0^5`phLND|TBAhcVtfhqwUpRmKY_9@JvP|-_A zGg1BYEG^F+Svd`H&x08lCG6ltC!hR^)I<-ByC|>D&>2`wsr(TEMRke5ae}U-Bkx4U zvqOGJ2*-<@p4JhmdLCum-$zN<7BE08MN)rNg524qu&Q~JvgVS}w{v#I9f@goR;lT1 znx4|)$#Wa0u#vH7F0x(wOHCs8_EblG<;I@lC{>mJy=F=^(wAZ1{*L!yee5KK=B5-@ z4>jXk(oT_#)}ttq=_O|@)=TFVQJYiBHLubFz=SJ ztF*dm@%xh}Rn%6=@1{qkVn~O?Kkjc(_l(x7TZqA+g^x7Li2YweejDTPn}2`SD-wK7 zUsfbo-KV#yca96T$&)vg6m|I+m9k!mic#0n9(LR9uy$(70%ym_`E}8#XL>m%OQI9s zbXLx`%I)duR#wio%k6O%@AN5}opSpgx4OY^l-th|urAh-o=R4$78uKE>R93j5C9aC*UI zUv_t#o?V2!_wq1Fd1WZtNUuw*{T&~_EqRlMS~u3L$eitPM-}I`sKWVl?K}FkQk5OQ`?MpT1`%6K-YqV`uhxarLz}UUeacs2|OFyjDky+J;eEql|G| z#B5uBEmlAh)oBRaGmk09CUiPCZEBgMHGDsztFz zkywtz+>PlxZIauo)NPR4X1N`&(o5!+A#x`t|8i?T=DGU|E8Y*TMXjmp!rB+xFI}&) zS6xO(KkaeO=p<(SniM7&^>F&A8k|MIu(D-drT&KM6npk!YJpC=DD0?OJ=HdSPBo*t zOwx~N{-we5hVUQ#TijW_$T>$2(ymT1%TO{R_6?HjY(bG9<#{%ZfP4W*frTfP!u@5}4_R7p$j zJlWszKitaJ^2WzhN*lFAam(gPaYZlWN{Q&aD>CVSc(D(o%kJThzX$R9z_%4hM10bE zZjxk!^`4mm6Ov}B-NU*%z2(0?gKXK~&{AWuzFS4B&GI;h6F@4r%KYa)C{G4u=`<$U zX$01gJE=VSTWGXL>fo7OWPc`3J(??N80VkiSsuNGkBnA|dFHq0Z2XBzjN?8eT`NED znT%B4$5cy2+8SY>?JUPd)G351d&r?U-bD1$2aGl)jzo z?)uMvhlh=rYn)gO?$j%~yQl0yRct6PB&l4w->CWl2LZCz9hRvWu?YS^j@r_ddnNjl znPOG<6QjQ;Pe*Q(s^Qt@9gGoq1mKj-MAKg0i2}GsSSo3xGQ0Mu{oPHKP%R00zX|Ck zSSCi)g1(O+TYrueh>x3Z1BEvz;dc>zbh8*kIveua%5`Mlt2)K7MPrGfX4zpqv3QRj z4I>JVb^B&Jb$G8CN^yHsdolPi(ZXqC?CpzLH zLyfM8>a1&BMGlEYZj;+dzhI;oHDP6e9$zWEUfMeq{S-M8Xp7NfWc7F=QgdtHSF?uq zI?6;-8BtP#VSPiSeZ6)+XpS#-@)nXkzED}X^9}C3{jJDuSV?t8yhL#Jk(Ab|DL$au zNLeXCTXp2-BwIyy=Sb&Ss}V)QeMm6!dp<{{y!^7Upz^DKa9Eo6DB9@lqN%nf-oW`> zBD1;cTKE7fr?!%l4JE@m4Lz>wl!Ex1Y61-E^m0jU*69R zc`r|oBCjq&o_p-%V`o@uADt<8?n$v9+mAi+Zfm{GPVwjZ?MNn&tbBSF7bn8B_R@mH z(ai|1sV3F8vlXNapg%?HJl^sh_i+Za^Y{*#AZsC6#^ZE31)(2bV?6HtT{rX+(!eL$127cl>+1OJzk+Gu(XVkngZq54v{EA@5;SiZbG$ zGmfa-4pcyHEqjpQY;DUCQL(9-FRAk-xPYp8ZkxYGc6GdVE7>h;`&dL>B__z`bEa7- zf;k&&q>_NF)$7-4xW?rAqwC(w%}#l`7S@tQ8~fDTn+!mdcJ^M@KJI&XDBq9$U1aUd zkamLKe{o``%6&O4n3Bfz0IqvTl9b_aN;h256sLB{y8-Gq+iHK-B%2|%KWP-;SiS@& z+UJ)`wDsz#y$qFGFVy-}2~nqkfWy?&mw3`hYm;NY37`+he?-FyQ7;5RH!e^yRXA?D zXp@inV--#nFWoA4ddd%j(vrtMoZTs$0tf*|4wMteHcohw1-ZIBvF+qvaEmRc2g zT8^9qtlO;YU00_QeF<+-1Ms_*q4yi)nnfi{;GF6of>-DLTxLvwhQmvNAhw-ZCt90b9 zi&f;`NaQ_4&LQ-^taMg(bUog|Iq4pCT#pKrRNjylk*A8tJGIEiw8;BJWT`Du+A-Gu zY}fzgpMrRCV6Ot#_3u*A2Q638CoCYk-K@&TkEAWsg(qJ}QQFnn`=H|Tn);1$4b}9~ zdaCcB;x%fzr}o=a-p0x&$MuLZax=v4kHlJbzMeyi=j(L7e#N*7J3oWDJHBzTHWfj~ z%F8JmC5V`;u3mQz_K5MVj^FD|cVUuLx8Y{wmP1;G{jnw-@owiy-G)>hmOe!~02U4; zhp%`1Ju-)PzpT>JnS6p;_2GlAD#~n!Y};Jq>e0h&+tgH8DZfTXc5Hp{JzK@K9W;E@ zCg=-)N-|8(P!yYyCeDsZ;kM38GBn!$UWE!s-H2RN0#0Ab*&|_$$3=}@JiRnw~ci6%Q z6)(6s>oK<3sY*hIAZk~Wo>aA=|BxMWB_!hYi}-&fhoQSgOh8Og3w zX6{%ftJ0pGMb@95rMRD!geax>KC4RhW2xFs;odDTi)bNP#^YyHza{>emt#CGcB)8S zUWxH|jpNN5)kqA+F4*~hP&uEYphv+rlT&5x|Mi<KV?6?@_Lox@PDxWMuCTUEX1dz0(_D2CH75+q9-5r40Y3i_|xuAkTIW`DJgBd^t{qxvf7%>-q_?rsfU zsqPunWp7vC>QK&qxn5i42`BwHC{Zhu*7^-p)of%7Y~{utOS~u&j1(?dPmjww8t*%V zYq@3}#F+*`OP->49c8t=-U)8+i}GtpEKJCUl$_e0jxq4t>O(p9?-|+#38|0L%0&4; z`6)v-XT^wJQGTe2$DDOw?UVfXB0G9_h^B$J;*4L<2=-`CRg>r*z8!0~I(Fap<@O(1 zCDGY;s$pKB@K)36hzxykd8v!E{B{oVd+NVG~w)xc9;I6Pv}oR{JL0Lg4q@D{dCGW47^ zUBPDg!GfH%Ka)GF`i7jk^*^*HoWpRPoVv~Gwobj}%v7#*oc6bGDIeRsM#64fFB08l z_ldVlJRN~zKXa_Qb)?=oj=|lTsumBr?`?5~z*+?~?rT(cfQss6RhhV@D_zvMYb=ds z&c@A3Yo@eHc||PQrV>!I6Q*w-@%na;K#_guMboIJJkC_+YJ{>-f3BSevTMZuI`Ln? zJ1n&u;&AL2cu92KqLPp&&v)}H2|t(r#M!?u#K!f?xa^O3FSmx@^{GWH=*Qi@17{%@A5LAOrfVq#(Bw8mjx#aC}CdmtR7L1$ifHTbitg53Qp1K{1mt zIC)0h`_2O4eyY46qOn=VV!q^I zq;i+2jm;~o$evfKjcMxEX>3lVh@8ge%r{kI^A!bO)Y$AL$59)bzkf?5pxTeH#$u__ z3Ze2fx?Y7fHXkC?x3M{g_+QZ2Y+R|*?%CK(79v_>Q+R<>yZ?`k&C+T~I!a@6_a>#2 zWml43Vz;{WPMtZM^tp8^LsONbj@#J0NC_EZoYiT%#4|>z$IV2pM6}!Jy&aP0o8=jl z(dd09-My$W0RsAxt@*9g^wGWFtR1x zD2>hOsNmFi$2Y6RHoCESQgW+Y#W7sR2qKt`&0F$-LryY;Qy=q~NOVV}lbtGZ=R9*7 zo8w!&XHH|Y^`ad1gI1Tssa)&g2rQA_} zPJz-6(g=LHLmID1#At^!x__-&hb{%~TAqDKV_YhEtedb5kY#MYLmDeoTNLGx#yvC! zEXh2q(`c~M=rP<0JESqSMw(UcAi`YT&?Vayt(J=Lg@-iaA5?{_DreXsjaS%)P>oI4 zA&q~xDjOVA5T%6-)9+F8xJ!olr|r(SFbBjF7lAZ*GMJekjCNjqaM=OFS`X=P`tDx zwiUt-X*lzvpqd}~?|t4SV==W9qBg*oc&jbZht$wkR!G!Zr}KCjllz?T6~TM{-s90- zJs+)Bk7RBYv37L&>#BqYD4>M(QZDsZ=1jHCYLN7Q+3$Quh6O5rJ=Tum-K_UmJ6ds% z%G9BV<-)f=iTe1h=#LMo$Ad0idQEu&%#l;W z9?^_Md=FGa^!F7({~RgedLG$UlYyR0plg4Y%R@FoRW-F2RlZ3bqr3W88iBXe_56>y zr&FKs-gwEk!>Ly$w@#-%5 z@RvcWqe#Nn$}Cm)+Nvt|=b>s@-N$@yU#aMRo~y6c7|9%pMa$Z@54T`K-M4R-r$sz< zI(tmAzvFjjyA7N+XNJ;MuU-91c9L`hRVe24#s~ulb!2$>$l`ual&jHgJkzG;`{iOc zE$uXscK2Q>Ut=S$_KxGV)m>}vI38C$?(RFf;46SYwg(5Nd|3<4|jp?Ms?P^=hYGk6l0+Mhk;mA5$5s|@qRu<{)?SqRf!m@bx5 z23F-VCCIIv!efeRJ92@+pAGL6r1G&fI*?f7CsKrZdCjcQtPpmRApg`a9>`B-ah;W{ zeq^kZ3VQqD#>fWt2HYaNfDAQ9~3?pLWsL!O8V z6g4d)*Su4qLwM`stTn48@BZue>QF2_#~Gh%-KrLfd40eC+8uU)oVtZU#KGjGpbO>I zniJP7hqqrk6t5v6C$5EFE~uITZPIS7;uppuLv`{Rjau`0RU)ZRjn*$`DopQ zD*$^>SN~ikru;SvdHb=RmGuw86JWIpAZd$@Q)s)f56kYdEY7beb)0)8IZ{8mbx4<; z`m)$et+pJIRAUTh1)znv&Dgk^+!9{d#QxPK>?=PB%o%>&a(%NvOr_5+mdfC1uy#;* zzW*#EL|xm@6W8>n@cP$o*T_O$?awwGmta3xqhNE5fO8IFe@C)36C1;yDutv|AzZzb z6=}W78Z)JJfqm=W1$ymU{~pkrtQXk&zdBT@sBY_iBH|#^ z75VGu@mZDU%}SH(uSxzNR1xNXjbKY8SlxtA?1^%Jom&;Tu1=G-iB)cg4pG7tfuQ;` ztkrYW5+<)J87$2W!DxLy~z^S14N6sT9~{zR2(U0tIx^JcN{O!=*X6QXX;VwI>0 z$?fdrvh&h^-FdRSTQ_04s9tx;V|(c@f|81w`8sZ~SV`K8lFWW4TyAG`4kFYeHFxWn z&qfoAS{rz@K@z-C?$zd!s`sCMCQ{j83zRem38;GJKdJmp=%-UZUs8Wm9)+cz>88$b zWWoSD_10pQdZV5>cDyA+k=pE?q`p&9|BKvvsn@uvfApf8`U-7bWi_I_ah0v%dR?_t zeVKPUbGq-Vrbb(tfR7b1C#G+@WYsTF_$uWS6TW$YD8P=(U|W9~Q*GAfR+8=_7TPtd ztiRWBn+hlPSmluCoXaHH0(Zo>I?a^F*V(4l^+V!LYgyFmoF zb$e2Zx^;4!e4)BkzJl6A>G?i9Rh&WD-cpXgzvCE@oLQVx)AMvPt>R_G{IwCpsgt7! z^5Na8(#ZO*zWD3m}0^#f&`W(lE}VcfhA zDD|E>UYzk&@0nwTKI6P+jwuGpSWvgWkBN0{o8P@x8eZ@GxN|yK_tidDzVb)G36>YRj8`oGE@d6|ily{pscs)A zThHpdIO-gDhh*;-45+)qRa>cS{7u)YS4ydS-_Gfo?nag7 zAxZNQQBxX=_c|I2B_-W8s~kb!!RQ31A z1hox~p@Pa#q77QS{XNN>jC|!^_^)EgA!XI>X-c*ux6MGlh zNCMIJ-P)sB$ZRnNNZ3nRwN`C^%DD?z_2d;6m*pH1-Ink(17+$%%Dcmo7#S<&)FU@>8&*(3@c%C8o%ODWxWI~ zwC%_fn1wkBE}~4M{P)MAB8J;M;|Kr(!U@=-N|8UDxu|-Q!;a($U1PF9w)TP|T}37z_9w+%99Hf$Olk1<8 z48MeK_<+o(rE8dgdG&nJ{t~q0Pu!cg%XCFCzBK7Rd4xP;B5A`_%d=7`&8^`LW=kLb z%R$*XG}Cz9ZhC&xrB^^`Tf@Fd*)xZ>ii40u5y$>+P1V_~%lt$Y9!jg2O6i0yu?I>^ zU*!AUn&Sf`l+=0btKz+_MM*s8(Vr!dU3G3xw$1D$Ms<6=Lw0vmeeoj2BS(L?CZ(Sj zeGdUU7Mvh^kuOPT^E$na_8X^u5hg`-08+x8_UpDP?fyJ=`kJ1nLpw$K zV2Nq3KB=~ylI2|z^Qro&=IAqi-W-S0(ieG)$`U*5OBzl+bNkky+h(aXI_VHuSyy_fmhNFa#87>ftxI?<43mV- z>?IH^u}-pYeBdvrybV8+%?YVEDuH_?6zN5`#7Vw33S%O2p*zxbr}&JT(XEpSi2J)q zZKz<^#HjC0O2O`XF^f?2Mv>Rbv_HR6(oL1*E!%_E z{G7T`PlNMj)_yv(_P4ns{zM;`l=IT(2_3zYMEk#lf@9xt;_DwKn2v<*f$ceKe-W26 z>G#zikxJ5a*H2kA<@za$rxg66e)(u8{NH~e%?|Pi!DWxXIEy~x3;rYo))DVoqwJ)w zC6>CE3;Q_>|CTlO-BIeFT#u<fAMeRIL;Cd15yj>f-&|e1GBluXpTzRQn~GE7f^n%QopWZNJ~mrf zcI$xteR|(iymDpX3Y#7`vrq5KtBQ+5#Z?0??UOXG@KzOgK+0$@fzhV)!C#5OAo(0? z>cl>0lva#hQB}EYba74LO_gQED~+&I`ztXE#Cmy>yS%tZ;}ddn7cA|iO6fvNc3Mpv zn8}Wo9NFfGD7Vz%%d0AG8X+Z?8Y(GWIYO0LbXh1m+Rnct44gAjyGw@SE*Yie7^J+g zY}}-o_SNj-P+?JFsBl4PsAP&b)6~M1#WUy3OD`BZVSf3I}2Crzs;4;7Y{7guGA8gu4_E-ENkR#P)}?AUQj3s;sdE6}bwbJ@Jm*s;q> z3abi2RfVOYl{1%R&nx7=Y!%PR!kn?`UTKX@x9vt=?NH(TIMc4Kod3u5&o+8NS!t-) zt$^Y6FLh<XoC4 zD5ui0m7|uHmOJK&+CC7avT{r*UOHx3MN#pJ;_@*f1_hT^6;|DTgr3inoHGU%f0-GZ$!JER#9D6RDQl`jNsB+L&ZT_+~vhp z!K&iIqGH~!{F3=pwXZSXNP89x4#;m^mlEVD^-S=yW-SQZO%f z=CtgB-0V4*=jWuZEGu1BT%erD3udXf64mr8is{l+UkM{5-}0#%`TO7Ke@hjfUWNW= zi$&~Qjk@$|%Bm=Jgry!jc?yOqLUcUJ)Bl6?=n<~mlD_yB;RaCAl_zxUI zf?H#}7G$*DA&hZ)18Y_BvQS0UGbAQ1nv4wk%y|Q%8QGF z%PXpa)#cPA9;t5W%iD2TS!pq4tzy##l$D7Ub@eV7U2!AUv;V$ix!Cd?b0KZn&C*+x zSC^GlhQ7Ri7OuRtd|9|!T9K8ED#}zDkDgatUNl>Gu&H*&N4PqhO}jGYvWjvV`s!sN zrHg7;7=4r${b%{p^`<&Rvq#?eQ?+0;nxu}9iht9}73fvP*oJ08`mbq)%Swui=5e<& zzhX*NRpG6vL8XdrajU5s83mz{m+I;?dTH^B((=?1BSu&=)KCd`4N~}8o>TIY?w2f& zn~Fmv6-5Olh2=$M#Z?8;25Y^~t}Lu7ylFJDSMeN;Ld7+qQJ1b1Z*WFuL{|N9f#j1M zNCpKfmZwfreltZ%iN>%J+tMgX3p7HxPgSV6sKCOH^ab(Hwv(W;^blWFysWr%mBg^D z`Q^nml~e)Ty11$e$1W`oN`IhoK-pVVfXc#K%PIL3Zi&vRk3Lzr1kvM z%~Ehx1#u($kZE=$mvWn@y14wp6_Y1dR2EkiQYV8&#dHnDsSBtbCIO=&?<gV)`H8o{~2ON^oL*H8udHOGuEy`< zCOG%yk-5H%oJh5;WaKog+POCo`5!xRZsjuS7maX^ZiB=1>QO3l=8Y>D8*Xp)$j97PST1`= zW4>d~R~&x)yioO0cRJ$gE*DyV?CsaUhwC3QNY7tYdJ{c4BXl(a?CGOX6eugnWo~GyEI*8`oPQfmJxBia3Fs$*)?!l`H zs2lj`26A(zFLZjI{EP_28F9I~M?_V(5%FVn4AG)T>i^%W-*$b|y{Gggc7GAsM(KuW zg0xY(VN#by!xWLf|Fpr3%%5K;7u7cMFe3fP_B9qSd5gtMhGX$!g-Cv!Uqj}X0T%Jb z*#n>g=77cje~yB3myRU|vHv3M>-ev@Oys~Os-TGYj(>kyme`@Jv*o4%8S}&yG@QBPDUAc_815e zl4pJ+Ax~3TLv#LQh#PIa@=MO2m+AEpd-BTEnOU3Kxp3#kRmS9%M3ejJl-ZW}Qu`~; z-byrm{-5ltpx%FPT{794R=qM*aZ`}Bw(4SQnYtNOqSqqrJH0xr#}h12>8ZZ6rptU? zuQ3E=V?mZWn0>J1Y{%92qntqK9w|rG>dROc_yR#rFi#YT$hv~wk+Rf|R!POm(Bui} z=@Z6UYU8O#VmIm4CfW4(Pu7>>&Pcd8=d0{q;+SbiPjokMy@!wC?g0;gMc|vCoai2y zVp;zH$Ae@3exmy*>HGxDINP!=K1Mk3T5uiM?;j_+8^Kht6`T!rf_H$)ta@(+^T6$3 zBbf2&iS9P=nSY+>w$8PzLtqdb&KJX{gSlW4cpJD5d=%UP?gsaQ2f)K%CcoR5G|aMY zIDVo#4Q%?Hbil80!Z!qtXJ@WK?&G?<_kgd)cXuBKlM*;;f1YK{0EdBBgVVtcU=g@5 z(A~WOybat5-UGIPgL`#%cY+PQySr0{Th_~92AITF>LPG7xEfppZUfhWd%!JVJNPts z96XEt=ivF|voGm_4{?5=1ngoveiQf=&ZX>Wpso43n?(R%516%~& z0Imin59;pT4lV+l!P~yl-F+0?%8}SKUOo8>m#3v2+( z!QJ4~;6d}PKTUH7<9$W?H7H}Kb z0X_vL4M8t36?_fM0pA5nz{DW&!Rg>ma2?nJJ`Q$(uYyUkyMH$E!E7)Gd=M-Fe-3T{ z4}v?vPVfMj!Wr$O;H6;Svn;C!Oat4&TrmIK?(Q=1d2kcB58MTIf(O9Cyn1#N%mVuk zrJTVuum;Qp>%lVcX>b#G0Ne$>10Dc7z@wmb9`UKaXMt&8CYTH6f@Rf)?mEb0$2v-kEL9|UgNsEo4_Kl9ef!KP9t9z5+Cfv!Id&F z4cr9&8q8ddzfGWhDWkmy%Sb<0ko2m+P2f6k7dVTvNe95A;4yIUMbu~Zpi;r{;6yMV zoCAiyb>LQT8`uQC3ATYlGP=9Fzz4wKSlW3o3v30KfG5B;;J`_=Yv5F{8LR;hf%kzH zpOxAM2Elogi4WcnE&*G?bzq;1@k4MNxEH(=JPdvW_T~J6m5F`9955H$1XhCWU_E%& zCEeYP;CQeVECD;gHDEID^*#%xgDqel_$F8hc7pX_{H4SPQ^8j7QLqbq15DxDY$a3C z8@vr%0`3IYfD@;YZ!iyR23LWHz?2!(AAUMuA~+1p1*e0Hz#{NAa2?nH?f|d8obm!! zfk(l~Ipq5y@(HGaO<*oqHk0y}=inyrJK!#`5j+5%GmH3O2G}=){sBw_Gk8fd7tGBi z-{5z^dT=+`2)2W*;0?2}8~6a2JPEsj>ENt6_zT$YO8f;}4mN=I&857+m%+o}K`?Q$ zWqkk+1OEk12b1TKZ!ie11M|ThU?aE}d=)$lc7ll)d-^=jdW!M|+Q%t(x5HJKz1RKCb;BIggco5tM9s_rQ1GC5vI3Bc?6CWG^hQO&{ zJ-8Tb1V^r*euJ4{7kCetLVL9f%m9;0u`_rMxC2}a?gj4z4}&|vMB1%pFcxES0G)_@1W2f$7Ur^(OS1!MFh&25tazz(>InFteO`1kM6?fvdp-;CNw=sOd?1A|~Am;=5HmVi|u^aZzpyTIqc1E72*`(AA4{Oqor4dOLOl9|aeIZQyF~6L1@t zxtekYmxAr!Ch$1;3^-&CegbBKAA^g)j5~-AE(W)O!|$fNz&!9U*ber+lJUlR(gk;c z3&DM04VZi{dV>?eCa@B01Gj)(V4n??S03dCW`d>QBCrNr4c-fG1OEry11_m0U9jJM zv{zS=E|?BJ1?GW22P?r=upV5#k$M4c01tw@!DC?JCj4_Q{U10U%mDMjxnKw^0~^2{ z;BN3m@F4g$cnmxS4xC55ts_1-2h0c8f+6q;umRi)?gj_kPrku)unYVbI3%BO*VoB6 zxD;FjZUI+=JHTyV7uXD*RZqPHGeB!TdV)c4377@G3N8WLz%}5=Z_r+X8DKMbA9x7d z3R+iN){ns;_!^i6c7RL30S^!#Yyr1}y}n6&@Eq_EI1#iK;KyJPtOB#ZP2dvn8E_3) z(m;H$4QvL3n~4wJ0wylRKfz(3dI*HXX04DjFJLU6=`_$yclZUt9^P2i(o zJGd7-4t@j>**tOVygg5ALqunDXJ+raz5F7QDxrI7gym;t^7E(BY_ z8t^E%6|^2DKKKLh5cmRUEyW&S5c~s}1^yLW0)F%u{swk|yTD$L)2@S~z@y;RVBclv z3#Nfz19QPvunc?`+ywp$+yy3opZMTR@F=(t>{~?t3XTV#1@plcFa&-MHh_J1(oTT6 z;6d;qunX)2hZIx)p1@zgTyPOs2CfDl2e*L-z&+rnU^_VEN&F2g0f#JSyaz44lwaK+VxV}b1)sOe4cU!KLu;R z@h?!$;9Rf?EC<`bJHamSelX<*#!X-b_%yf>d>O0(-vqaUAAwEa=U^K+dJplzPhP}N zZlszvGkyRU@5MjC2CyEi-;ce(k{0X*&UpoUfy=V0dv7O zz%uYCxCtEaHu1qU@Br8jc7g-np`Q^4)gw3wD7`;8%W6e!*0* z3!Dt5tfW4Jnc%;`Mc|NkDL*j%J?soF2V1}=!4B{cm=q#Bm2hRdGfEnOUa1q!7t^+&3^WG=lt1Rm>Fde)G z%mdegmEaz*9()yS1lzz?aPS|o8(0Dk#LrfPBzz;V0`5r$cUdpMv`%06K*9A0$XPNN1@TZ!5t`~n1{H5@d zOg`lCtKk>IPc`}MwFxx@5&7HTZ-e)<-yZn;;QN{JXL|D6;cMVUmTR8{9xspMZp+J6 zHKq5%b*qEc8M?mE&cI2zF^TYug>PdKMsGM8GnfvzY=~|jQI8N55u2g#?SHMH^R%F z*dUY7^Y~WyJ7dW2gfEBp(=VB}E(D)t%D>%{pAO#u?^oyZ;CI8HW5&PUi(d&Z_B+?) zjW(qo{(1O`CV#URzY)F_KHKEuvs3`_pH}#Pz~_hYy3rH96MjTujQsavOa&jU%?T1e z1OFKYe+JiycQLVY>crKaj`_$KLYVUjng13cs~4)7<|Z2q-S89P{p!d;_+juVX8d_x{A2K<-&rPqjmHn9gB~1%9}k}b@7D(8 z!}o^w(=P;n4Ey`(*8qPM-cP^X@E^tC55jlA`{{QKzAZ-lfhRHFfKM~+L%$?0EdDVb z{{0y7^Wnw6qQy@o{%ZX1;x|ro-^+F4WeYqXo~iqlc=&BvBN_6 zJoxjFCV!odKa6Kt6i^4Y`WDxT&&>B^h^^|pa3zFWh#t2x)=K3<~5G;L1_(?*yj%t@|~3^UKO`EkNL#Qfn*GfYB?3Ls@X3?JG0 z&WY|naGm(^JTEOhru(fZB;j%iH@BU7gPg>JMz~or_Dgt71d4sjXb|81{fX{Nxpwuw zRp(v!P4LHK@Vnp#zk9;BT{{5Z2Y#F>|0XRz$g`vHL*QG@{AwLva&(mQc`fgq=sw$& zvB=Xg9sX7LX!S~Lu@E17242;Rx8{2JlyWxe#Tvq$bI7h2d&0w+^OowlVA7I+dnCBM3KLhVqFV@-V z$Ep`Q3G=Dw7^7YsAdK~=*!7~5Fe5*RT`vYEv+nU{|9X*$A1&>$>&0nTd1V|?FN(z9 zKD6t_XL(+@h~%ev5s&U{viA~lQ-%`A`{pT;A7Q` zRKh&K*~Dn|Li)};e5?WfENKIVprjjX(Y_mC;Z19t?+p<_)hp)G5BN_gQmlW&F|1bmX#zA z>F~?o!^$K6a;2c~dGKG4!B@h+0PknxdiW<|@Qv_W;is53GS+lj;h&2UzY~6EjQFxp z_)3iU>F`bPerq~;@V|}`zY@L~KHB^}NS^B9pN0Po^~m*i-Cpc<`l#K6DUPx3a}a)B z4E`AWRCvGsU?9rn!28YN$HUKpr&;lIyu$O*eE7-mR5_0~*2O~b7r@t;eEdq+hZ^A5 z!2@1=V~t}s#I5jSO&%XzVf*Mo_*m;=$KYjM>`XKMLQnsJO#Z9kee(~0OAJ0AUe@iR z)pMyMAzQv5-vD13BmQpqBKnp2rvCBTKqCJj{DbghGphZL!N1VUe_e1O9d%#Qk2X&d z`QzbFhWA@H&4&-b`^|4d@Sn48JJQt8nBOY`?ZyO;E%@O+u`4aC%c{w_S`whqeT4R4fu(2{ev7YjIrJp zWFhr1VG!l<#ymI+z8&7LJzN6+Df|pGe*6^IRvXY^Nbm0MRieWvLkH>i$~;@_M9vL_ z^J{Zj;ID=EvtFc&Y!1e_>|i%mg6f!g&ekwBD_;+}D&46DH z@2BHJ_(kv+n(@oM_%-mA@X_ifl(m)rO5i7&@r`=f1b-*IpFg$P^8MP5F8Ia7$8Eg) z8GBzTbdC#S$j^YE1s`pFOUil)g7e^S<2vysO2R1vsnn!`>qlIpX)v zz;9;WmpCC@PQpgLCPG%M7UTp^@vlD}@B`re+J__-TP1#-sYm<5c1<SUfFFKpx9>b^H~d2Q3(WZT8k)#I2ww!h+vMYa=*m9^-vtkN`WgG`1B06PYm3Lj ze?)vgJ|Dgvz6$Yf{^Rw8Tjd{q^Z@_1qXB*xykFhl4L=$F6~ue;_p1CsSqJ&=F#JGs z4k5nQN6*1Uhc3b#Jk8(6@{Uojf&MzmJBP=K@7EVBgij>?{iNmTSnHNS4SW^6U;M4` zx51xl#<%wgQQc~SzZ1T}_gS;>+OQg!l8CP4F!-_+9YN z!!v#JbTQ6z9DtYi0tcDAF>g8wzXRTHov1IyZh-gev(n&q!Y?xA$Lj+HD*y0@;r-gk zGI)7kFcEjP0fjJ%JV(yOFWb zM+TH7e!m$0=OSZ?Aw$nU)Syx194GKG!VQh%#?duluxccPA42DT>fXm0Y5I--F< zB;4||ISa^j;xHpzyq+jXS|QSUk}#;`$tmC(P65`M0<7{`PiwKmQp*=kySKG(9CBneegVFZzP`tL^yF{7>X>gRhUF z-yZn;;3pB*Epy|1Sv&j=_-Or&%;%58%lpM)V{e{I+VT$ZlWs2VM_WyqOt>S?bJ26=W2eiin( z!Q@4TeLg{K7Q{F95avf*C(4Vbj?E<8_r1EB#UOmfUr%(0_1O}}o*M;;UqqNSF~W%L z<=yapK6ytKtC9a6LWcZOM`9mCpDXT9s7u@wSldgFZbjBXWNqL_9&im$Z{vK@G581I zqm_f?eFzb^!av4!;?Ed`n|XiOvvVec#8voSwDJ-?7Qx>PPja3NW1g}aelzdi5|!28*^9sWD;(ef|loJd5`uSTx_Jl?Z`_^+{6 zGi=o@Z(J0-cOdi=EsOHc3+L(N&IrI6E`y3aPlg8*!46Bw}Wu)gp+nG@h&5r(U!Fk zreCUU`vN13Vf(}AlS~-DwX(!?z6SswtsaZMY539S=T{${gmSd$Y6Tg3laHmLH_G=@YvljZ==%6h1i7mII+ny2K-L!aKx>a6T zHN*b~ezM6MYqp2r{{rt16L1`y6o%ig;Q@~9JjF8mKoUUYfPv*|#J{uq2N@%{84NHv-T@3)RI9)2l&v^GZ7fA~f46HNV$HQx|?RgCxz@MSUh-SErd zDN3)5jlH6S@HOz!>a*x~3_j$;2jPbxxDq~(>%{A6JRF~m*PGlTBZKC58)5wF)k66D z;Qjj68u$kIXnm8&-wOYY81kFo?}GOm`?tYwg^%U~%J1-jN8$6CVpb1i4$^U zrX_j=Da6-C`ImJTd`k>|3H;0Oeq-V_Hjg@<4%A2429@-;!yhF6B9ph*oPs=ShEE=? z*Gt?yNPX5vQq)}LFkvnw4B(|<_+uhNynJ{+e;x)e-wT>)#*d$_Dy--@9li!W+IUj< zBKSMuqm_m5>)cUwreKMYbN@)m51PS;iL5{65pbcn*r}wV&jO*Y_^ zTi`=77TCf7&#^5wNw`7JVN(dV6FKi+6n(C~7w*$Y&fY_lJRXJ*WcaW9CZhZ?;`_B_ z!{8zyll;rQ4Srq>z6*Ya499%bDmr8m=1Ic%%}*A= z?}EpJJsEOHiCc-k8omksN|QI7ybO&rA6?6j3IwD{JSyuZSZaImzwDt=f(HHe;OnGcKA=={o4KG@VzJd z*X<#hmURkzH2Vk9DHA>kezvKf`13TcjF%8*9ATpM^CDvnd^-FqkuvmlsPdB?gn5%N ze(MB#;opIu79m4SHH2q};ZMLb?D5LcnBOK|!r1!a==DEHlwt4|d_E9X7mPE;IfO|k zj9)uh0zVNxnk_}g4R(A#ekc4$9~~ur3w#QE*qT{ z__Ivjm~*wjkA(NlKm0IwKmSb1((!%s58q7uN;Ca)O+>WgEPF z>(Osa(*^&o4==V3;xA%@)8ZJHolg&Mj6)Jm(&I8I_pGV(;poZIyccGvR~Ad)UyPBD zHSo{H;J3r?hWE2`Gkhcb$!7X9yz~#jKMX(G(hoG58|*x8ePKWF7n;V#MD8-wr?7)X!ey z8^*H(`0}UlPjH?1eR5&=YW#P-vObEOn#=t2(KnlQ8Te>*M&@N{@Jrw&9XE~HUr)F{ zu`aNw*V^9k-}2I0NZ5B{q*Vjo7K7gk{|3BYd*1}#3h!J0;a`TQ8hg6Z-iq0z%(~$J z06)v*Lt^+(4SY%r z|Je%PFNXXkc=5l9rhSa_!ENwo!AG;Nv>9FS;@_{B@x3|wb5aq+4)RUXr(@`m1-}!% zk10o2BNcxM`~&bJ%WX6Ckuk-ufxjQ#&(F8R-wGcsA0o3Eeg(W=IURy8j1iv~nXEi` zzj_da&xIdo>TjR96FcVMM_KSc;5zX#v@qM=?|JQE33C1?h8`Q>e+=)JkDc&R4t{oO zfq&3Pek!_kqUYD({~eE>KW3Ed=;?gR=OcZ#Mr=Cp3f?iC=5O=y@Y7@P`S9c5&qtP< zjxi<*!B2u0y(wqLeMCH^t^ zMeu$;H87X`4|qSH7!N-K-mmS?htGs(i7707IgKUhhv4V?q%S_T4aLR2G8au8o8rmP z=T+3`PUP%CPC4OD=GwKRG4^YRzZTxlPRHSM;r-h1AuMbZ!u#1N6JEZ99<7fJqS7Mx zO87aZemW0RrL-l?8p1q8n5)e&GA}a9a|dA#5XP@9-wXdP{0LKqao*!Fde6g4#TGt|F9W9{yil?F|5tuMLZ@7b-=5 z5&Wm{V@%#ypI!&wYeqzUHT2&BpAJ9VjBn2mq`n-$kLA1j=?UZ|Fvzo^>`&O=%@93~ zBInYX{^wcbRrG7&uQJoI9Z}+^!OM5}Uk~G7b?uZ3pE-+nUYIkw^)aDZO%^478T^(j zy1RcJ7XN@7e-nI8Zg=a%`l|QoAK$DdHQUB;zg_~IsKWm9nWidV)H}DOTMaGeQU@KV{aq~Z_&uEf@gWm zlVPke2jLsw{pKNA@DITI^%YCt?}zVi$~V?c*TCNygWnEc9)oX&UmSx!1V0DfZ{3X- z#jU9^_#phm7KQg^?3s#gY5cb}DAKGyB9T_fRM&9~>c zPaEN+yzM!zgli+*74vO*Ta9prJSlhimiY$@qmQ3uToSyBx&*JrOQv2?#!J(Z~G z{`R5gW503hZ4vysMcv&WAlKvn;PUI>XI&q?-ifX|;6H8gf1i6V{7~Zi^>2sa&w}?G zTPDt@|AA+u;psQet3$)!li^32yuB_d`b~!)93%ZA_|xH8hVkSZ?`yAv&xD_D@-kTC zUgaPD=>q@s_rf>9OIX*w_8dce;wW`sH~h0)C;p9^Xtou*ymb092${Ns?>(Dx;tSkz zN`t=_KH54~kT|*U8{j+4_~M`MdTCS=Cby9D%4V2&z0fcE*NY7JpvfC!-$t9i*yKq= zrhdx*@#`JLzX3imB_glJ`CdNkX?;MrO##9k@8{V>zuRy}0C}QMkO}gv75=`JW%Iu6 zAN-6M@z>bAU;ORxQ;8pqm;APnkLlFCztSfqZZz^C_5FRXU+O^4Aml_FtBRatd}us; zjo9sGLynZ6y;l~5OJ7J`CLH2Cn@JdB?Kz(?O@z5HB8)7%icLfC2jHWPXM}HneGR<~ zhR-m0W8XLg-wXLz*^6(SFKvK7MtnbhH~jnXcbV~xcdQP=Pep#F$=~AD!DH}?;r-gf zfed69!uyraczD0~LDI~(^OWCe5c9l`PpI7RMH4u$C&ws=rV-Qg3o~W^Q9&56X6G# zX&7~74ScE(A0*Cp_`&d7%=luPltarM*KYZ26(@^TM2&;{AklY#(q>ie0_}gjqrEI z;9KF#;B!p*_JItsUnjii=V#yK#f;Zu@agay;QiL!^WZnZM_c<6U#r0vCH+UZPQ08E zj^k^(-fed3-B#qBQs%E`6MXL&d>ecmyx*9u3;tyINv55QHII}6#@+CK<(L6KAO^n> z-h!WM%D30=gFLH&KL?(r8P5h%uZ^=a+X$0On1N;(d+jyIvpw)x@Ui;hLxeev`2b65 zUOMs9RpTKttR;*+;RngJQx^6+)AC5_@vtSdaimi$52p4@{(Ah>eku1SWcLf!B~I;^ zx+##;Fa6$LIsG!$_MY7@tEykdlz!<``lU|o7bG0vr}j&-l8IV|oF&MK7diG{cXwRy z$_X0-*30pX#9HG6A0}FFCa|EL+ z?^!&a66E|5sIXQRSy$RNX@%J;%`oBg_IgeD*1E0rPt1n>}C@yd~&g!x=6pK4) z;+Wg523up%qVI(WniaUpy1`T1eLg2J-zwM72W5k;ae+5`Sx@x}boR22^ct$N(f^9T zBXQR9Kz*F`tS$Ha9Kya3A9y)ny%!(&QNTKu5I7RB)+Pqt4p^;;Q;r9$hF;;x^&854 z*;go_Mq9{No8#g?k0(=sqw!XKeBhmUYiEKN>EwpEsU30F=SEgeUKba?CC+-$e$;me zp+^U%Tl00SlWqyzY5mwH``jT4KW5*Zu_EyIIIBAFew=k*T;Pp3>sxW7xZYqFWxtC9 zYvQcDK!vs0kv)vYFE6mbD)TfFt6AL-pB~qDXyBT-ae?fFLP*N`4$n_@nC`e!u7WBG z++uCA1)eg72MbAIo&BKym5ip}i3@z_fg15$W%i^gfqbh}Un9T!;q&4Kk7RcE zr??sW6XJdok5~LXA-gHj+LuTmw9tR(IP#vjz$3k_7vfH>>unv0Yl{D@mvtgB(9z4< z5(vE2%X+w%JbA9SolbUqsdcBmp0wb52-+MUc(#|dPi%8zDZ6Rc0Ohh12;Gn z7xz2K?O)^id=_VYO#++w5L@;u;^FO5CAUgQiGO-r{|f>u<7(sjd^65^M4md42tPb) z4D;Z)1#1HM=U0y=THg?@pG*k665uBj3cek%wg%=Xbwzq`7-VUnwwF~C_(#C{RoqQ~ z2v~O~+#mm|fc1ztu%vf(T*}bE$hf?~LvdDdpf=7TpUjnwgpqXF+`vPJLAJ}$7ixAkdU$=$uJPvUd`(#txS5cp{?Yj0wpy_eOV82BYm0utt#UTe_5XIB3^ zLchE{`sW5V$5{n|b#c~{k~h*%ni!aAE!Nk0qre#h+xy_vE&m^T?*boJRqc;YA0Q%> zH$r(>0inEVX7UEazNT&3G>u6p50&X8nKYqECQc@4i--jgQ4zsMn^b;r|k6XF0l)y?eyI1rKKNuee8j0J8gb_?5^oM-Lh-! zzotJqb4TB3E!N#Q)bGBDLZ{|O6-$??sIkd z=YRiffq%BZKU?6RE%474DAxj8&(&|HT&?#xckBJ((^Lc5#P2uhv1hR@yc@lj4shO; z*i=angR7bMYwPs$#r1kWw?XgryUP#M-#veqA~Uz>eJ=0%32_1}x1m;le>?A&G=}NL z4pMqs`TeeZe(%2=KV?DPk2u88+o7g8+${&ujB7qp3={oc(+oU`2DrNP-M3E{Z0J-Q1(+V z?^m~LJ@kaC!SQ z#OHRfel1_HZ}h(B8}+?j{D6Kw;ezn@7xQ;l^X|XbR+c~G-fF_!axJv7GOZ8(?xd5H3PfzJDj{rozBR*$JHZ~)6sg=<`{+4gz1 ze%`?6Pjw4tSSzs4bM^a8_8Dt6ay@UKSGkYH|HLza%WtnC;x_--4=yF{^V1gMCH#3_ z<@YSqo9|huC*SiXt2ZmK#ryoQ_j#-L+3LMz8}-;$dl%Z1?Y+UCGgqHbc#kFex$qvn zRs+3nIltH*g3N;3OD=zWts?He#DAN-&(C|Gt=yjQ?a1YipSi@X+)&`N{KE7X``+%C z2FeMx362%Jwuf&UjE~ul+uNTvdG*@jecsB?L+mH3^Q=Jq1zY8Po_k^O{p9-%-sdge z=dIr7*oVTupXGg?>wVt9&r3Y{Fzcc)omJlFP2T6N-e>!@fB*eH@>WHE>H|lFKmWx0 zypiM3==>!SF2An}?!ely!m-)w^pD;7xqC=|c_2SuzNgATEZewi7VmBy5`W*y?`4fr zu3hvN`_pTG%gUdZQ$VVBQRJEy*qP-v@eizCyK5`!_Xd7GfOogf#lPh?&HkRH^)opv z=ljX!*4}Uzo|g;$Uw1w0YE{Hr+ZDHZOa6MfUavQtbFJ5_f7AEDCs*_}e!i(qzyBLQ zTfLs==Z9PM`+?!~165@8kV3-k;(9&%Ez^HlNS?k-XROzKHjg zy!Y@v%KL@9Z{+3muW68q`AB?vK@JChGcC4L%;awv-?<>C!}#lBCeOn7E-{mXVf^(mldoZX*Oc_loU%vCX8#Z>Gie zj;;Dq6uwVv&*`NdFb%Vj&7(ysGKcL~m_Nh#{;@5bSHt)lV^MN=8fK|YZ#pbk)crjz zb|4hiD12sYEBQS5qiL~&Vsj6VDt~aWnEPAaetPT=Zj1!K6un|9+J8^_UF|!G#}T~M z!{1EY{IpiS9)C?a!!%N$3fOO0sY;;7NPl;&%%YjGL|6g7CJ!6~55BA)9 z9ln2T)_&SPrZ4;nxV+bMe6Kg*vs^RqL&0B9`EY{5v7>>@drf(Z(lPqtUY>$zn=g3J zm9ugM|DuPVLHugs(@9^{a*Pb z@rQ|nth-Jn{vRHG7V$?s{2bzs61VrgmH6Wx{zu|--=j~o^3_n#q%v+KNk9XrExTi z{xNIkdqHhVZ2#D7`Vo!aY#iNkyFSmx(LB(X`uvFaO#M36NBqBuTl;*J_)d3dK^I4e zKW`)cR^mqg7sOkLFChKBU^vKgFC)H?xQ*Z4%8cJPd+%%G_b?B)@p}Yu>n|I>vpw9# z?{OY(lTc`;#Ae2-s28Dm-8JBFNMHJkhlrc}{M8l(nutHh@~hsb^gl!VXgFS^{xRaG z5|=aO1>bOvmhU0{s+A|+PrM%rmdL9)cPn7>`KQ1u$>$9pR{HusV({^Ekc9ZYV2*uza8e#FB~9)8rrO&(tC;U-TmC2sBW-{>#L4W=o;U>55_i&Tj4|=%C?T0!5}q=%c_-s<5dx1aWKliSaF zxXJC`dbr8k51po*WAb*NJyafA9FWOFDHSCTk3#t=u-&mbE!X3~-QFqvSor@yOf6FWBgciy z-$r~F;s@~;uiHz@zw2fNnu(`??+rT5=PR&Y$;Cd%@(0TVfeSTu*GuZ8pZNEP z-@I4}xYx&befd>M7{8nN;|D6fob;Dsy+q1CeXjz?6CWo2#rqVP zNBlzIQSJ69a8#+}nvR79p?~nv`ds_%@xblx;Ez_ZeCM|nt>c$x6F+ocrSn$e_YkkY zS^<1?*NenAy-CX-Nqim{Tk7*gwhz=8cgb1wf?xa>{cP>IGde=>zfM&;*6%~WqxyFv z%Rhgs(m70Tu^$oN^r!;I68|glxrZrzd+xDsl=j>+wu*LW70Y)5m*-mC$x*~F1upfx z`e_BMo?D2Y{YIs4^_h+dRLb9aK={4hN!;QadP)Di#4VodapH5pz)}5p18|}L>@8aG z?JWNX;uiM;vhLa+FD~UTAJF=If%r|t&;F?baz>|I&k%2ZOh4D@Ew(RSTpU|n#H9hTP#LxPX7M#WM&jF8m-!~tkbdGyO3*w`@PQoAZ z+zoqa%g-hLE|wqqvI6snKg#l_G0t)}@t0VB)>joUxpBy$`rM!WTyf*``NX$+e0w`_ zixXT+`cD9ldanb}AX0x@?}r$4R}#3i+t45Mv(@Jk;+#sGhrO->mq*Q;vZR+_f2aRQ-2Cvr9d5ub<+|$=L>SeVO$k-Ey8j@H2ewg}{aWZQWYl zJjl-xw>a0MS^iCLQ92gKCi=Hr8-PoHS^SFi*LB2WjI*=x`+eZ@+%J0b%S$Z(Fyjl1 z&cR?XDgWf5`oNR*u{hsMpSy*8ZsY4N;P&n;>Tah)a7jB1ZcvoXhja0ie(nXuzpuC0 zbPNP}?sMN$z}mTn__;SJ4s*|4S>VzR7AI_S=1VNU+s#^TUzYzB@zY*bU?K4(XmEM% z!-M+1ra#Deg@RkWYZJ@QgMlW`wRlE*?keC?-r{H9&+_LHAEo>;xqT(^zaFB`#pB%d zUE;^xsGrfi?)tOQ*(F?l7A6{b?z1;&Iiuf1{O;QnkLxY=apJ3Lluirr=ZW9@3>U~Yo9*g(he3^Wc>4KmVc#7>7PnEKX>KfzhzvD@&Dgg{?2MG{|1&n1&Yd> zF+W<|6RQwvz5-Fq`z0S(tm7qxP8_D-v27pWZ`19=YM1Qr-=J{$m=lCOZiXyNeddClZf9+{omxzCBWsq_T+ds{087s|BaU^ zozL*OKOk;#%KDXxQS`cjDt|h?t3aro0BK~3EGJY@h=CvP?jxWy#PgMF# zJbCpM;8M>O8-x3gGl;+EB&FX>J$xqd-w}V}4+`M*-PQPK z8Jnf+(MP^b>C9j|?8ow_5r2a6#GZQ%@e8S69mw*31TO8f)oY(OLa<2x+CCQR-@AzW z`rFPBP-4GWoWOL_-w(L-yTw^vLHwJ*qsIH&=IV2Idrk{N?7ORLuHxOhYkPi__{V@t z{ja5b#APydR3zJ03RPnoB&N#I zzxEM*-aUGY9koEq`||1m;8E@HJj*{#yY(Q_Sqeo(>RHA2#qf03M&R$ z;8FCaC$;>8lt0ElO~ik8u+k~;5AhpVAH#o7y!j{kKu%Y&V;3p?!#EFGe|-(O@I&l8 zrT-UOu%3rN@ssCTe6>AyIdGwW(gRxXY?jXue}?`ysBP{#kNCr$zVQI@ zN2tH;&+>mHzWP1|AYRytxX>S+ zru9FDw4Nd!qds8#wsJ)@{j-1z9ovtHW^vbzz=h8(o_jX&Cmg{;q{CLhjjRXUfx zMeB1U%Rfqdfb%uF+g(S#L(4x$-1y;x#BF~i*wS6s0FRP0cL101vVr~$tIyNKZ6D(S zq%*BepL_4$6fl~-#BE<=p5;GAd?EcFP{Z8yOW@Kz7Ds*=@x%6zdcyC-b+O-*Ki9QK z*MAFeY5%1UDFKr|&k?tMm)4%Uc4+w-ocFEWE+B6EhK4vFeU?)o(GW1ttvW%I&*E4BRfv>y%cCEh~8{8s&0?2p7-|ERzs;t5O~j^F;EfW7a# zfy?~Xy2JDhYH>3j3$mx$N>MXA{PZY@)O@##vZk#@S# zzY2I%eSX98zF+s0GnCE`zNych!I$_j@fP}XHWEMjom&1|KUCmj#NS2y9{N@GA^vgV zZ{xUYAindvqU*UBxU~Nq%2ng5)x@X0Ronkn^3Myz@3~qDTmK&SZXI`z)Bm$4pL+vv zp>O+(pC*3InTp>>{ctn!kEIlU`aT6tAijxs3&-gQ@upSL@0ABG&pn3x{C<|-HLbYq zLxxyz*KFWX{rFyom-^GLB%PW!PjSBo`?>4v&S*N%19$EGZ7pa0zFU{#zMt?0;-8`2 zZT+%)x0d()$?d?S>i;2@Kbv;qLe}#I;&;BJfYEQtXg|K>`PrT)Zu{JcWA$~h>N1t}L^~=<=l+F*orUl=?@-4un-JbQv*N0gCq?@(iESA3ocoaWOS)=cJ z?I*S1@hpEVaN$qeziaQ6cI8fG;e2i7Hxd7L>Pt2r{{me4 z#rDS;pT8libPhd6-|G#m&syS^PoatUnL}E>^Hl|mZ@*65@>smU^51xmmY@9{1&$~F zF!9&Y`rJ1WKP;!^eLN35s^9Nq`7`fP0$(JZU%T=%VzzIc(|K&)Vb*`E7PRqoG;!OP zZ12@X{65NogGfI|{ON?&-`e>}6zCw{FsjczhwWqSe=6~tSbxLU5Wn~ceV~n(yNUbj{!b8}b+bOu z`fLBS`rNw56yKlqSw?)zUlcfu_-5k%ddEw|Kk_3j$Zm+$uT%OrenWA4?rp?p9HjMs z3+c~VujMaiT*UW?|BU!KKUBc_W!l*oznFJsd+~v90&ZnU!rhhu7rx53-JqB|J%vu z&zGTd^0`W9I_2j~(z%JaACK_>@n^kp_iNxXFIYYblUMt{U+G`;suJFd^!tF@--O)l zb1ZN96n@P5Zy|nw=P%uFgVMMBJ|_3-fJgDwDu=^AbDn!#%=r0X(%GBsY5lSX%0n~>4Tt)nW|5U=CBK=p1&+VDwkgpM6b)nMn^{$TrH<`(z?)D9q zKkg+(Z5+KyeAAB=xAvL+A*J8?isIH^Yl+XGU-2;gI(9el2Pjt`Cf<0F(s_*fSc3R_ ziCey@V~O8I{Lv};zK0S&;=@Ykh@UI42k}#h`|Ii7CO(IL&gCqB(npkzZ;yP1_`RfW z{QMwrYZH=iw_`u5boQpbZ|!p@am(Xl^?#YT??;+>vC^6TfKoSEv6Q&4hnz|LzNfVO zovhU7iNE!5Z8wu|2YpQV6LD4_RQx!WUj|&p^<#|3XdwPMmbW|zvxwgXJgOb`zeMTy z@qY7&`*9tk#HVjn!e^5HgT&9Ef7r&$ABo4v|3|X?oR8~spXIu$y|4IT<-O`SpPt0> z&l9&iYjVbxTpzns%YXDW{X9c&v7Z8udf)hE(fD=1<+(pZ)TmtVC7s{9@-t%V*irVr zy`RwX{m5$}BYvObFfdG;E`2MsF#5Z221^Zb3 z72@}QT>;~hs!uDOl`kl6{j!qy%wH*PzW|r#?&8^l-(vZtlqW}!&d#4vI=&uw5%9fP zCV2Z#mS1+YqWc(~%azV=XKBALA^uL{mjBLZ?(#2M{#okD)}HSs{)iVxu?4vFyXDtP zlKxXH|9#qzjl>5(tMsqAR{@*fKL%Xrq|Z~liskQRdEdXf@N-J%QtC^!EPo|&%Xjw- z@zbx+@-t}v?oa#*;+yVQU?)=6 zE1i>tp$BX7NYEz~#9&KdylF%hklM zcv*3ipDz(VhwGlZlFs5U>U;Td3#)+(eczAT@+HN0^X%^Hh<}%Qpgs4ntF^qZKYW(B z<&Qg*_4x^Lf4wsHWu?=0qZYLJVlnYWe^%Vu|Kr3HT>rKD%(zDB%w+w|o?Q)G`q%RJ z8T}7AoRtgQ9w40yeyJeU!PxF!QTi9MolPDN0T=owe@n~XMOt?_JV2O#PPta;yheM< z_;W4sgg3tKA>MM-6i4A-Nv8&XNI#xKIW|Q6N#aj_Q-OKJUnB1O(|(0{C5mrf1}^mP zJV~E>66w7CtBN0oevoUS-eP&;mVfji;} z0GIK;!HWYqkL9nVKgamt72;VF$>sn5GPuUWs;!p;%=XY3cl-%I=f zmfwr?pC<0FYtOz#>$#QnT*C6F0T=qWc=1$Qi0}3nEokHYW#X29_diJI8yL4y@AYTk zLO=FxEok%L;hPn=Je_-xPAlPqKcGHi<6_OfDV^tUR03;B=X=BtyG;RW zpIvW_uIKDB_=Uj5uCaV<#-HB+F7M^b`B#bie%Jj_4=I27?OGq37rsgSnFkdA^fbM{ zNPOS>^|STYf%v`DXV!<54`=Duv9|#i`p+|dGI$dc^|Z zQT_OCmj90D*ZPqwKO<)OqQUm=>cPAs^;tzfp3(m{aX)T(_kY*&Kju7Te0~P;4L?@8 zM(3l%f7hVx@K!$eHsDe9-}O$Ve=+2fTyN1^?487ya>6`>_y>qz@`wU6iQhu}6W>)} z4e{MDfr{LlxkUk!KUKh`9ejV$2=VjT{zm^{;zzxvbWR}scY|)!dtCus=r<2&I~>mP zG4!|K!<iD!uWanAn-coh8;?@>CvoOkAv&ew?7{7r!ai9bsGCfcWm5`QDcztrai z>Ny7y?=X-9883r_X(ya^Cv=1HgqJ{CVvw#LxY_zL&*uJw`eYKB_pxth;sx zpGmv<>$!czKlME=SI6>K5r1H-0#=`I0Jk<|QFr^H!%OYH=ZSB=Kug&4HEbLTAu_i>*Ibr|L1{A`&{xxC18Grmr3Ul>P1J9{xZC$$h{4ed*>7X58zUt z3&Fo~Sv~iGJQe(zg<8+JejWP=@#nxtaxKzZ?3cv-xXRVv*Y%D)xz1wzc@=Pb7D>3< zlfdP<{hXKE_+{0Dig&Z!-a-6y;(LR??LbN$0gr{k|${^O+cTjJMo9nI#8(f`o$Ex*!&#{XX- zekbEYY`iq0y`-LJu|18>SAaWyJ69Wc9iMynkF>nMKK^mwQva%b4|650{x`DxEc$Q% zm2~K=T7nVQhCramqUM*?; zo+o~n=a2dw@guk%xhVIgC%@Kh^TTrJg^Zj_nXLFF#J>w%`X%P&A=%~0XnA#t!;v5FgQP!A@3#S$_ua&GE*nR`EJNqb z|3}|zHuKb>+1)i4xX`)&HvPOG@rQx$&A)@UBOouL@Rh)Yj-8M4G=H?>=Zc>|J~6(! z4!FpflQ_@r!Sau@{GA+#R?qgWO2^;dbT#pJQtw5}x@!vBUFvh|pY*fg3F7`b`}x47 zK8KyB<*lCIVfkyoM{*smx7Z(v`+n~up3>*~{>cr*ulu?ZFumnQ;(q+wPQO$--`uR_ zZ5#~}U$S6|`-0{~><;1&V7`@WFTKTnO8kVcDsUk27&=JW$KNk`H1P!WRcnVUiTn1; zX^`VW=irRi$Le_<@qLd{`~*Jt_r#xJd85DZ8KrX$>;FcU?*uM#b%=7+>i>S0_v03B zVtG54!TS9nmVc4+i#>PoueIOpJdAg1bz_$SmvOp*a&k}N*8-RK_3geN5cmD7uQ~eG z=*4^Uv&B9tqSzh+JZgO14qV#7&Y!5|kNyZ;>f`&ns{c#zT^DP`PiFbch<}Q9*%`!7 zd``Rog*OY+q$wuPKsZYj9|JdKE zyt4C@Ob)jIk7}PQfJ-}ENI%IO(wX+(if@IVNiLH!^~C*seEr0`AJXzi>MgdBxF6>^ z^>@lYEnm=rZ)W*9#P9i(0z<^xfJ;5?oD8eaCy4uT6!#Ffb6ZSqJWss$Yf89>^b@~V z`hHy2BI0&_)7jcRu}#E%J!IPRO6QxeDq)K0*jI=@+NA`neSS~;T*}GWtk3K}D4q15 z6)?T%Wa2MOQ92DQ|1siEa~ z(Ec_0*R%XA`rl@;{1%qq!U@gf&-284C4m?&3`2Jv_(!FGkLR!JCho_RuLZt0e;d5r z&+><}V7^xO)kI=c{Rt07dA0pmP zea!0f?meVF2gUZJe#PRk2T@-5$IfTilV7A?5`52?ox@@6vjMm~cZl=gQ7r#oz@yry z`eiL|=d4+o9^z?F?%hh<-HGfG zLE=Y}p{zYWPu%xczZZ<;`sEI#znag*x!A59wlY4%+F`+TeeTaFAL>|snD_~ltHv9@ zC;k!Yw{Kzjqjyp|{yv>Yi2o<|g?*0YKfkk<_xE8vN!-p6oW=4x!A~UZ-%3BsJBgnF z-0DWi-8xu)+Tq&2#wR}{egN7-u2%PdEY<+KPTI}RBYQLP9^k@1>v*n~&9ff>F7BL%*xk?R_sM{uIZN%?q1}`*HhI;MbG- zT#V<)W%K^O65qhMkp_KCY&WdSNckA&i$jPnA-et`UA^=u`+5&E@UCTDIY zep#o|dAoic`x9~B-=2nFSjLN;Pq|!w7P}X?JojtO3VeH-5^9G2B)Fe9<|^XHussjw za}PkjN_jhXct7IPu|OmE?VLBQ{1V`z?`@^NH;d)p4_w;c&h51McN6LO`5bN~{#(pf za#?%shILta?*3ORVdLk0iO-`xZ~S>aao=xzCviJ(*ZTM8z@|w&OP@Qn zSL*}w(_K4boJ)Otf1T`)75wewTbtJ|BEALkLoORHKPEmM`h{F(C!TPa(pkAs@k`ye zh#v-S?@q|wzF!7^mUJGb95DHLF7yMb=NvxQ&hwdlgyL6hRqDs{A#Wr8JI)I>9^Xe? z_)9M9um3~*BkUK`OBcLF=|6C*61Mh#KXHG3VJq=194}OZVtX8^bXqyTm>x0@xb)-o z=PCWy=`FU7`280s@J8a-kS17j5I>pxM#=QV(3( z+0XmBl=yLvC}C^Q3~@gW_D+Yh5`o*}EdPmaZGWS4=+XLIKW^t#;{JZ0>w(KWYv&-^ z`~H~ar{Aa#HT!fbkr?tNnH_ z=rKayU$;HW;rwynb}?}KZ2*ql;qX#B?&qX`0Oi|U{^+gHGot8h1TOX2Fh%Qc<9Fuq ziof953s)1LzEugIN&2r?d5)KZh_ArB67}4xfXj3JxYJ(|e;?(K(P@9H_LrTbevv&F zxX|h0{A=TPb(NO4^XaYp@_2N8^1y|T?}xvQ`13v5J~qD}g7=j2onAdZPyCm#`{mkQ ze-^u_TFbw1o8mT~{)G7XOD)7_uU0x7-m&|L`+9OyqtcnbM9Z6A@gw4X{Lf3oXG6Zq zW%A@hCq(nlRSrj7_Xk|@n9Vy60C)QT1xja@ejWQAaCt9(Kjxt)D(>gwJsG&YJ4v|P zT`ceKXTRnorE_SfKG(+4e-hvARi$!@5qq1K_xa&n#0LhIj_G^fBJSsl-sfbc^8nmiOiDp~>j?%{d(Q&X7KL zD(RdLT-w3Uqj)><=kM2o^I86<#QpqH@kL7K`K?;e#>D{f{i%TOPdb-d`TtR%o_IC- zPwMkI&YMlduOgmff7v*i0r@56H$9~VP0k-j++V*qkGSt|d5HK6v`3EMbEh^beSaPN zDB=%Ne>S^d4e{4JKD>(f%aos1|2>x~{hQf7hF?hh2HF=k)*dA8=jVUZGNrTRds^{o z*8gPUJ2z{;|10quiT6;?H~#z$aerUr>G-{yXFa?7eZU?6P|-Gh=}K1~S|kOP>9KdR z{Eg3PMc%{u{DS!V_SJgYy#Iye%KtO()PiTS{5~!E+#`FmytUgZ;(lI;D~SJ&kKCH{o>ULPm!uWSF6xY%uS+5GZwtJ3f9R@~;z!``8|A7|1|{38$Pi+*vc z-hV~>e)u`$TA^@kuQqKTKmSi0xb(}a$F*P^%dZA5atsQtL(H%Kh@-Cs+RZHmG&h*^A}qF64I$9{`CGze9-q=jB`a-B~R1SKz`Yvnls%-0cKCRq%T^YeCaL|AqK}AFI!`c9?O7 zmOr0#%-_{U{0`Vda#{Hsi2M7FKLv+?$eH^OREc_kK0fvn;IsI5@b(AbQcvGcek}OO z>6zqntIr^CDevcf{VH+4J=@={<@dcopPJ;u&nNEZ2Y!h7?X~*8HXogMrqY@5k`gd^ z_(kHrfBR+P{=T_`Qc7p!E#dauNZj{F{gSx&edW4QA0OMiO6mCe@P83M0Q0bP5Vff6vg;5p#ZFaG}hy}FbihP-*_1mH4$ zn?J8~60FZE;Eo?&r}ek>f{Tg!=Uf~Ixh&=Ve2@P|{2NDv+xhs6K6ke(^?|qO*Rj)q z3!UnN6j;FeOvU^pc<)@rpCbMp;(5*&rxO3%>ge(NJaD0N)gem9c9n%+bNR%!NvS7VGm0>G#gm@o4t-);^{G3F8=9uX-Kn+{*UsVEKkM(e3kY;PSqH{@Y&@fAZH#;H{ib_vqL1exBr5 zS1v!CAL;3t(-rH^dy{lhGVHzcQ&=UKiiq^Pj%N) zJ22Fr$!EIf)K|sh(S=eyeS>|ebS{@(pUMp8bL(S0x%5CL)jcvWupU1Nd`h8YK2)?f z)8C(6o6Yri&l&2R)72GAozb3ejyDeVWx6tJ`-U^AuI%7&J~z^p$5&@G#~V_q)%o6B zCf%J%cjfy=GpV7`WTL7RMaH#Mney(7n&MBggI$@{zSc#fqe*=}9@3YUy6VSxbsDwo zN~2j&`PB;6^{pPv<}&!u(g;$6BdM-+>zWgBG-ReHJ<^{~;U{ZSL)remuJuBbI@Zyj_tkR{UvoTz=Y?8Oo%=-HZA%{oV7lk5Pg4zOysi_&pkC z#b74evphY#W?Mz8*VuE$P`YtV$NHhn7z)N~*0f~vt?8~cneMR^PpoMg98LH46$>Zo zjT2MFVVFu}9NL_yX~F)tebe z54(2V)?<45`XOpK;`$&e(iqI{r`xDvbyeZ*=M4{IFfYsucjfwqME0!!jpS&uMg#-i zbsLo84fDFY1HW#9%*3x{pcut55UB|h2|T_AG6nCI@9T2%vk#qkHa=wsQ|ZBOyt|4= z`CQf47fUT}UNL`OGk!ACnQBU*r{Yz`?yZief?ZkCa;apjSa{Cr+)!6RE(gV&h~dn- zuHN+E>Wr&Jy1P5sx>6n=5{L0bDh07QfU1`%k*F=Dlp5|EgrH2emePZ$Ez&DrE>Ryr zwYzV4D4p->ji4)HJ3!YjStAWm6dsAhn)!W$BA;@(Y;IvDpYH1)UY3a#SIyNmPP`Nu z#0jXB40HW&c~eWI2pPjK=baY)%bKcfJab-K+q~1;o6bl^|Gv5|^7qZ@&P;zw|1V$b zG5oe{y%XDf?lx*(6JG?0uwqEY$8bvS1CZv+v)!5ShqBclGl8=2P(QXBY~w`|4X!Ed zO%^zQ(f`ZVz0z;WRhR4;^_*?guv(eSez~;WRgt%{b*%iWvb9vEihkBM>RB6Kp2_!S zyY0tK-I;-*Y(6vCwZ1ts3WhEL%2s|mNR@k|+WPU+<>Q;1Z&inEfa2uZC*P5El@b#{dOK-qWPG2)GA%v@etS5$y9&A4Na zh&M_Tihc!E08EtbPUq9;xJh~(M&4lGFlJ3KMr%uZs!rLZ!UHR6Aob*#`j*Vv_WVd^ zvTa#=K3+B4o6cprQ$zV&lk#f3ZUNMb!AyUXm^WNbBgu*o-n0PUp;d~uYQqjZY2U0Y z=qd5KHrn|xZA3N?CtJ~gRjGyo(}=#-p0Dr8=GLZj-A!%FmWPIAp|9FAxzRrKz#^?u zfdyJnpLn%=o5?N6qNCR3`HXlXsAnd@I8~|eC{M2FNVT<~@9T1zfh-JpydOLhP`R7h z7pIandDPfxCnyq6b&S9fk?MnL-PAk~Pc8*mV`_hQMtl@uiDFf+aXgkxCKtqAbG7Fi z2hwZcHINo=JF7Ektt~Zy*4Ultf*(T^YiaeNrjAq+J>=>lyw}uGRRoeN@cJv->q;bJ z_~jQQgvYB&N?8@rfZ*o>o3ox!Xd zYp3hn>eZRNHd(8ZEc_DuG1SGL)wu|bQPQe19bn{1^Hk?uC!n>qL)*0HYaQ6M zbm5RRO_KfA);@0{IK2*>4w0aY9vC#$gPFA$Hgw8h#Kfyc2K!*01_a1>-xKpqGTB&g zH#N1_rV3~MI(do%E1)HyA|Gf zB6I=A%jrQpBmps*g~KVEgUhHrpQuiW;4C1ifoykQPhUpdf7$`nHRZJsn_I%dBP^&E zRux{b3f40`kMeSEOvyX@QYfrx#jAB_ErCes&*YNH=FT{TQ9?;#>T4K)udr_*J=BCD zHeTLHw%4X0!1^=8!%g^8IL74JGWiNnGFjKviFshK@DhpC%1oE|GTm$76?S~=$gCvK zuEX8lEvPDb0x@0?h?spEyD*Sb;%aGX6Bq2#WOB3(upp_P{`6|h6FT;iEz3^nA5B)l zXRR;eHFdp+!WBd9nZfSmXp!{ljEPK;OU)ZxpAt=}QD)CBIEjXvTG9TEBHJ;U_hcdE zI#S#AZN=jq>CXNPMirdW_1T`D;Y?nARm(!J98hUxiiA!Gw^q0FEjl-et9-n6fx6f+ zX5KN98Og*OsMyVevktzjUd;RjUcm&_)(QELL4~0di9@>B-!@^WJW*{yWOwF0(%Q9d zSQo{0$zf1A-TYIDAZ(%YEjFzRLQR2o9UTIXu zicV7@b`0rb)lj}o9yAzFnc^MNH%%99kEifY6ojf&J2Zfaym0Wx8N zQI{82Zc>AoIGUD<`b08P&sNZ?wr6V*`E8;4VWvs2w^fw4Wx7VSw>^EwQ*rE9s-YHn z#N>c_%_|6m3nlpkt-?@QLDcjt_a~O5;Pm zr`W4Bo9Wnb_Wz0@ZB1#H1^wCKOlVyBEsZ`C&P1=lsas;M)zex_HV6E~DA^oX1WP27 zrUr!@zJdry#35e6N&`dCG-P!s)h|AqWFjFx+0rj64xV`Rioy2Yk$iV{?O@x;U=mAy zt;qtsxl(3wyZA8^A4tJQF9GfwR*km2<506Yh0h(mp0SrUkL@d3~^bwj~)Q4o>FY~ok zZJ~Jmib2;@^9n0_X!hWYKOk*Lu~(3=CNoO-Um7!t4LtiT(U4g;l*z%*Fqp?;dRly6 z&@br32n~RGT3-}Ls9L}_T{ceRw7SGNt$}e`KX!EZARhWa1SQp^JN(y6W%GZoF%iKEM9ukM@VzP6af!h zK(}=YzxV|s9Co4sRizr?W}tt;m8;f~W&R>4r`0L3vrFqYQ5-e_nxY9xXOoNI37O+# z6bn4&hB6oYl*>V}u+I z+Bz_BJdLsX zUoL~7p@DQ>RGLI}z$SA;W?p|^dN|Xa?AuO@%vqaofR);Ru4WZOR1$UN!%PCkbKz~u ztjx*W+^8BagmeX~#Ep9hjIdV$YkS3hj#m|Z%JKT*->vEfgrtL(RO+q{_j97wsWdR2 zOJYdeYk}>8Ol<64b{LMKCF{lF>+328QqUTL$(=KUu03Bj>YQ5>;}Z`0wM^S|B5d1k zz_M>o7ob?ky>KQb+vuAKPtE^8Qy(Ry*P|gFpfGjE8y3SXWB8u9OIBwFt>M6xBf|&= z(qKPT0_?l+%cCT?Ts(RC;<5;RNxmG2*Pb%CW)KFQ3zxtzYTDPPvHAf;wot3W=!zn2 zRoEtB7L|6aOI}_s6k2J)$SaU?3IpozHkHsI@vPDVe2tsX;;vJugf|1)B=M|)Ud7O zpP3AQP#NzUeLnusD7){Rfh0_L(670DUhbqljP5M}l(8KkaDe6om$agGTvOmC*k z1;Wk~SAK4FW>GFX;2f%;74%=QYi$v7M{KkOiLyg!{0lP}m(Xo7XgX5u(7VON0lS+X z6!K+g&<R8LeXTDM+e7WP{Ko@7+TLxpl(p&bt!N~ z+;e)xs}^VSE%1uN6Bb$@l`$P&GK5EXK6JIzKzb0%H?q2cc``GQ>KSYrcW6RwWM~4c z*RVkgjmfuY;lQrN^xP*A9?t!n&0(4jtRbyHgaXA^!DBT!t7&167^Jsbpz=pfoO(Ea5@l-xah6WT`~T(3KrEo4XOGE8y|4C7-B8H>;<;154Qba4VQp zh|+W;tPFcS7^^;Gh@pwFy*wkxrG&qDU`rL82tvykvJfT#urS6fyD+TQjD|- zj!e_0&40-7nutK0F>yO2UvQj3L0Kg0H1#R?pxPJ6Du)wfTE*~uz0K)TdeU1V4^G=< z1u;EXxkEh zMk`==q3#7yBeXrl3N~yi8lhn){8??|ix8{igb%)TaBgi3X*gwBvLILrt&pg;^-2r7 zVU$S|WC;`{QC`*YYItOG6r_lY<_k}b4hngD<5gHWvuGA|@OsNd@j8CpnwE`#SolaL zC2j+PB;Xp-MQV(wV6#{cMR>&+bp;>2TWpv3hI&~ROy@F5Y9xNsg*3&YhX5qT5^U-$ zCCDoB_1HoXJ$dK_RbY1I6lanoqzUS(mK#XHMhWstVTKG92=!TYqv_-(8-2f}1t@fC ztUvYZVHdFi1m?a8`DFS0% zz%CsK6J>Qxz&e3>6D$lXN*O_*giN_EqC%r+0%m(fZ(=;OtxmP7@|=L^`%F5gr6y-$ zz`m*FDFm3NT4aL_)J)waYmY>1p2aJ zh12OTGR;=?Sguhe;w1qHDJ&K0YnB}kz8REAoH96^?#Z;J*D@YJ9j-PuoM!I^;|@nG zs+mwS(t@hK#6N9wB#n1yI!}2yUxIuYtU)zu&;l(JaakIo<^I$VE%&EXF=@dEeltg! zJkpVsmav;vKpu7X4W>r09w4%aUZa8x`v;OFm4&Up>f!c;h`uVTQfTPN=8><)A9NyI z!eJ2%@zdF=4l8-sJY*w2V8D!qEf_cT1sowkv1J3)oAxV5Qf#YzoV%eAcoVPDHPj|< z5!P1X0;z0^*uHjg!!>9qL@lT|N#zz)Fd`@By&?F4svUbb}WtjjsSDoqOc(XM`iJHsI{4V1%Q$5GRf# z7}>Q5^?<%5({5=z!UQcaKv4;-FUTBa-k}|xrQ856DgqozMfE<3DH+>#!irKmqMTB) z(*zYkBmj1g7aPJNHB((^l5m5}iPwl2^Cyvl-1o(4{c>y)l2y|_@eVe~3bQG|sIhEU zYHDj;)EROLf=S^{5{+cJdM{I1#DO`-1Qt(Zkd^LqLY#vw4mFyk5#D4_1xXbiJ)XG* zletRwgmF1BDw4*6+ElG62Ex|P>&Cv=WNW=!Th0!(N=V$_aSXsI)9&`jZEI%!2hdE& zzwjaM_-Zf|7pMM3iR*FAiX>#JUpWtM8M|9&24#Wq?nQyaD-iSTLVJ>IAn!mhS2*+7B*-yrQsx3ktz6NQQ&75Xj%+nlt24EmcV3ZU-M;*P5#!4=T)1 zuG`&+q;nQc?uNcJTZs@8jdWQTN7ZW>BzhE4m}N z+*9(nf|C?`Uc1(%HU0}S7oqcW=VE`_y!lP3_?+rObMy~m@gys*BDhoowU7e7Kn}TV z;9cET+*`==f&Pz(d;^t{lCT5r#`7Od%XA3Kz3^&+TlUi6pM7e-} zEnd~`d{YatwMSVvyk!q5rv?ymW8rd5vXmEEK=-DK()DZnpu{0BLnjb91IIu1an#Fr zQr-@%Y7|Gvgv5@9%m=?W3eWN_>39vp=((tfA%;0?yratvt*o>-@P^q{RP%7V8F@ts8NOB1N0q<;0-XRANqIPOXf;@wXae3*IAQJ1RzY ze`e5sg7}>fv6atd*G~|$x|l3%G}O7J4XjFau%+@`GBLv>G{a!uY1hDz|H?WEY-g;a z1zY)!i3&k9rjHj`@*mBKF(EQaR&d2@T9d+Jq~xO5KK8|`aXWSm4XsbfUTbUt#ir-c z)-I=~D8;du!k%A0N~TJEU8V+V<)v8y%T!@aH2SHg#bpk`=38>dq($+@6Nn<|M>ZL_PO!gIGCatH64*A2SBu)<7_q&j@>WN9 zF2oUA*cb`1g^5$#7tMGi_Cl(-33yDkd5kkBl`)M~f=;6C-~{o`c-|pl4OoIMW=k^+ zj5}~^`*X@za)tJV#WIS>71wr@r?0ELm{ZoH?Cn&qYF=N z85!ura<~w$pzKm#;t!$Rnk_pi!n<99qDEv#stjs-L~%p5vT3~9<>;AU!@~_d2ykvw zLh1+K3MLk&Pws&@YfdN!zXJi8dzsJ zQV_32I=W7<4)T$fVd!$p#u7*`%x+7-p>2wZghYd48<^y}a~aoMZW1nhh395(k+YnS z6=ISjU2<(VIX5n>{q701mRtrHXDcxwlh0^o?@B1QdqF0bb-7L3U93&W`Yrc+Tc=g! zqi%6#5WD6iy_9a9!(5mOsih2i4hh+?iv_cCKp;cuDEDYt%ZrHCD=9B)qNRJd;)#`M zr0>W}W|r!N#mM^4D$XK}=J>JT)tJ(H zs|&d)Y)Qu!UR`yA!v`5gQ!WD-9FtrS{h^RbCaB^zQ zA*~R9XOyYL{>Trxq!U#LY8-akQCu=02uR7T=B&i%kPBat49hs<2dDX16sJ?0p^E+A zvJ*lY90D}6I)~}e1$w2Sxpg{ayt1lWRouFpNEGIZ;D$b|9l+X*+Cfxk^HPyc(<&jZ=kk{>3=Yf6_X75XS6w_vPRR=dsW@rO!5m#A9UH{6AcqT!yT8KaSZ zWi}zXHGk~HlCOPZBo&xM9YV{k4pnC)5*Vv+{29v2K}B^Tu(44l+V8`kil85*t#scZA2oi9JFK z#_{T=;eyqJ1Q8TaVAn}Co*~$l!^~s2G(0cRu8Jz4MHNVJf(8waX^+H?1WQ)1OyYI6 zd&>@2ajgXDGXAB*ZTP*aim6qKYSDNXb@5BtVIR^&HCb-h(hU0OxaPi~u;yN}C>+uO z<8@}o$qKQ{=H?j3mx+ZTUUcEaYdsf^Q~e=NgB)*b5Ki<(rL3WPQ*m+|+rqyrQpMvU znl*V=pea~>kM0d$+P1-U4S9IeY<;*o-j zr?~&fGSSi|Db0CbQ4tfDk#idjaW4YMSJHUK&J^`IbV1G-2w6Je7xmMZc6WQ?=2W2vZUggLLQ zK!XFKGyo}baes1JZZcY@Qg4)PIXNZ>Ic~6DqnOyqi^Fv-5R91vQ(?VBL&(sMQ6?Oe zcqr;PHv_SA-AF+R_v`SslCm=RbOI@EceZ=sr>M!h{N&n^#dPe_YC9b&tnLM;`Gjnb zk%G-x%c<=e*hB-IV{RVTRxe$oE~CGfS`20$i!>fXY;c&*BlL3J6kW1pWYMt56AA^r z4O^8XEZ{ml)~u;dLiya{y5Ev!wA)Dj-w=-Vw#eb44CQnMH=DYap#E#;Dhy~&n9v%8 zh>&pJ5S6w_w(6XMJ;**mCMt%y>9S5iDXWnbQ#G2Y(h4CaXwPfRELeS z8F{R2*;zqns@W_>LE_nlQTvI;=zkH$4UEe`QU?2??5kCeJ1?c8tYA*& z*4Dv{NO|24QgJ(QqP|i}ykN5x*sOvBBzm2)eB(Bn88k@?Vb(=~$mEGoZ-Y7gYKyr` zAyaUYh~{+*#-mv{&bH4+!su~6>FtdclNFeya0Q^}+vmeDLrh{`4yI(C5NwJKPB7Gv z`9M<6uYku(lI3gkLzs`nUe#6V<>{enoXw08wD8n9_~jgU;?}K8!3{T@m6+iC`qXF@ zgs<$;uvMMm^*9`QKv#A8!jrKa0xeO)(W=Kd&6i}chgHN-o(4AwIDfFW2dt2C9~GI5 zfJSsdY7LI_EEgysO;CAU#)rEk=XXyQ(?4Q1?BHB&yP`OSpF3*S_JIhS ziTFubf2?$0STBj#V^(T$IYUzv4HqyMl>SBGQpQV4L2WMS3E4OZ89Zr0f+f3%#_NT0 z9zJ9Uz+naM2*!c%C~}84A<>LzA7eWCMi|G9@K6Ya?!b=HHKaTmXuQ>~(VbI~l^vrG z-;+b$96ugEeyNgY;v!0uOLVZ_wHkG~U z)yOO!onGD26h&nz8s{RbRV85CVp#g;-ys=&#RKr77C1RhwzVi+LG5W+U=xBn z1XdN|x~iZw{FquOont(0V3J%pNbMBd-c*159twO_=&J!XT zCCO;;n6N^+QMyyn_PyC|%Q>r!5s}2T5WHIOD@M*-WnUwi3`|**<5`4UnJ0U=9Q)zb z?U-~(oC$G4xbX%FE^XuqQgP^o8ZtT+oh^pK`WQo);dUhhM&%$-ZQodUn`=NZrfWy07q_h_xr0jDfq{Q)X&37zpDpj zU!7%h-@XJt+!-7k3PAxAuN~0Sc(JF`9X#U&83eZGm)L)%iTZC=0hvCH=oF`djojKID_Z&QTGI^*mLpm&8#6KfOm)$ab3IaS1ob zA*dC{#4`DrHflw2IZi*Fx;@LeAw^LPYR6;CAzjBaebstFZnKGqBX9|R=vAL2>qXq8 zg)v`#;045a9r{Ldu-i$hlFDr&Ue~2+NP0d4So{tjZG*cln<7;F!z}!6 z$W>DMj3`?Rt6HOdT{x~;Y*(K7NgW`>xR4+&dx5(1WmEC?`mQu!43#{s{+%!f*VKv6Wgfl*neA zAwBrPnT5qo%JOE>TfIWMP-q?qI1JVHAA|k!4=^FeYlJ7VBY8Pg3a54_TLTfEzE!Er zPYMH39pO%OZ})f0E6QCShv$Vt3HI0_12*}(EPNt)iw>TC|lI4kUU zsxK)ntg3;A71*!XhZ8=N{lhGSTTh``w_{@PrmN_{{_unsY;V(Qww0f6J10BekSO%x zB-uu05mgA;+V<*3NF^*W)6rdW?6TO9<=?J+ULMF)r#J>yQ_9MVF0e#gl8Tz<-IY`U z1lO)QeS7;5yvvskck*@*^Bqxa#t@=Ec6n2X(hu@$(Ai?UXZ&u6*AzAV)@-&vQDe3x zi~yHK3KFXud!-~p-Kg8aqFRPOP1LsbkKl|`^jE6DxaFKHZuF*hWcMdl_3Ls-h>#uN z7S5uG#e63G7Ho*nz}1Nw@+0UE)^{omI&>~ozs-v8SKXHB>BoWhNNkF&WVP-jL8n+D z@nj)?AO`?mda}*K2AZGHVPO!u{aArD>pCo|YUVmP+y>wV3LFEb?;mh>C7op%3>5OF zQ&VFCAye4A0&|(~9bVt?mRr5lVjU^b!4u9`wqi(Hb2!46?U`j(fk0f5_soEH2FoIt zN1`N*XZsu*U?r}|hJ(sWcY=i_jQ1v{nMmvT>zz_Dd(%Mc>f2041X`u3zMNagq)&H$ zYk2pd3`Fh2R!xbp%{`@rasI|wFrHGnhfvp{3L6Pa;`WS-%B-40{P<~LA}Uil<1EDw z%NX_LGs4sbGr|O;TqWWs-PHwuzoetz{;-Z6Ib1y1){%0I{f}#rJ8tvz)wozs^vgjuzSzu%$z)9CV zihGJBA(-_8_7IpC3jy0U;ny={>$s+M^ z&hM_X@-loDD4DE75*=hMlw?Od)(l6Ii$^hPX9r$GcUi&TRgsBYpI2b<9nWZ?ydAF! zBrS3te@k3cBFI7sa}u?M5dV&>EJevep_e%^dV`z1SwIBf9Vh5r(6G)WTzVp#>_`s@ zj>z>H?&q9o@ zt6NBXtH`X-6^&k3j4wHO$SGZzSv}R)1mE9Li7%fF*B|v|J0f1|Oc&$@2P<^rfZ>9z zTzOR*O=K-q@Bs-EM{$lOr}m-x)O+}4W_X$@8=ahsRh z>B2d!jBkFdzBVo|N(YCRgfQJZ4cs4L1u>C`BSLO4jdd&Nn+TClWjoJ;p9OJFNaWpU zE-H%(p6C?d5`Q1zO%HABPsjmf^WEV#E?4_P?D+5N9}dMZQRWsSyYb#)KcqDEv}T|4 zkD3au49gm@%wS<{vAE0O6gg$b1%zOY-t&Hhf`i~MK)_(gAtH4Vv!m4Mr73?K3lXbY zF1)NL=5{p_Q)87TXrqjRqJ;!l;Iyy1)?qg;;>(h4VAHPBw<}%2x0%HGb44!>akfwZ zhfTU~t#Gs@2AA$FDyxV@WesewP*1d`@i((&>qJt1`82mVNPYh*aR3dw)IaBFA2K|N)}TiO>(ebLl9@Hl>hoZh>I+T?b;R7CmN8-%7SGj$B-WrV6=^U>5k3vBs~) zUc3P*F*~yPbiYhU!_9pIeR@qA_8@C&Q##n;Ab@I*tNSXIg1lu$5#%O^&tw-8$9JSVS0rH*Q-N~TtZ zSF{6+-v3 z@JuxbL^qavjqp)G$?8HJYWUqk>O#C4Drq3+tvb0UPX>Auif7u}dPKzh;#RLrq|5iV zR_fO1Dy=|G#)?c{!_0xN6dpDKV*#NXMW!^(PmbF@t4-Q&O1& zx4ltWnv63#tKGzodgLdQUDLswSi!{9&VtYrJlCZV0;|Fa;7Tm>^*lB-O3c z5@NQ75%U&4Sv}NDp+RUWZut^2KU#3L`EnxElpq1?t;&%{V$m^7%Zd;s`$3n@wN zu{6@bGGcXB?QrGH&ztbkS^G`D5c^(Wy9 za|MI_nLr>!QNP*F(1%8FgYGjj@ibloScWGY&x7i`(^J0T9j=#@npIp;E{WLUj=NA8 zP;F0tdbOVN2(@S!8NeiNz$VKQK947YM;2FOZ%qcr1&i60hy!&euohmb55$@zQK;~aeXE`=d5-%k znXJ{rT}KQ18s?|kn_aizXCY_G_VbJ!xuHB0l&Rry(;!nItgP+b-5`us(MsI$cabSP zSy=U!6d;8JMWF#VN0SqgTf&BRyuJ&&Idc%Q5T(feIGW+krOINVCcNRvaeard!{2|F z@z}yCSaNiB(eoQp>%zSr;q`@QdxxC99oT0EgT-@0dS1w70ak(N7|iAdkOjk{+GPY! z0PhRG6h(o^7T8KyJ;olQ;)<+45td!Tvq%sTyJpfxh8Yy>Hw`L~R|(p0s8zv!V;F)| zG?aOw%R4bq+QYY_@gwT9!N#lh9)lVCYswA5)06Ob0DY+9d%= z@J2^CzGP-EnZtnv6-Qkv2yjiQ8)||C3}#rF9}zw0vqn%y5+;BiFq*{-uqp2|ze&O?5P&$W)WMCdi#3f#P zp2g}m!Tv}Og2|jkG>M|Zd_G~(TPF8Tq({t*n_$;Ndz&PyMg7i^Rtvt0uv*}&UL=!C zNznNua!N&Qz*m<{D^o@ehq;OVl`L+J8Nfa!8KSPUOqsDM(Sh-X#c&Ze_jTqZx3>os&BHjb+pxuLrk#Vy5aVEmBs$) z&7>uha-BNV%JE_3d9~%4-rGZh>Am^MIlCtS>?Ugq@ zRM?=mOm^tOoCu3bJ+wWvMK9c3#b}74mvKAdOL++29rGcr@~GL zsE8B9J2sU40Ti55#%Ru#9t>?c35x;6wa`%dG%KOSc1Ne>@!7AeEFv3vsc=HxI!N!}%uC=XvJYgqZ=0ta`5aKPyP@1!^X*VH##?!sIuTBg zu&D78%y_BWT%E-G|KKoca_^dF&;J$B{Th?Jev5hpD9eTUr!MFj9itF7V!idu)+cKxH`PW|bo;H0QGSl24no{taBIR1DpCoRe- zZ^09hT~b?|jO>Paz<_fb*b8swHWau8wMw%&<{Zy*)4i3bhD!l7e#UY7e%T$g!RmHa zsus zXu=l=mgx$Cga%e4vL(H~Q=%QPNSMmzQk`xuc&d=EDb!n%1tF-@nG2{OVxf@iKm@c* zDcnaMnltnq<4K$|T!4=_D<%3t)wc1A9np`X%#x@Eb5m&4{%U_R*+zR;;-io^aKZ!} z&Thvxm7+5|Iz}X{H#w&S{8@oi=Ary>;nJpMMeMlpv@CgcsexX$y(>8Q&9(1|?TK26 zth8!48LO0KR&>Uch+n1i>eTA~z9Bc{N({8(v>#8d8^W&YzI;Cd3>YSl&AQv;X-gJz zO_$7lqN9y*8?a<{wIGz%MV-jnU5r73T`eKM*dnn!J(ymN!(+0A!@4FfNM-v&>&wrF zJlZI*wzr+rpeSDmVyIo-w>szc?X-9GW(Lym6nkn}>$0<)Xm2Rk_pMqYUXvUg87S5S zOWRJNi`$eC_$naY3oJBIBWyB8QKeB^c7(Yh6A1dL6zlAUS~$u_l!s6#bIE8ZG+jK7 z!+F#hkjWvs2C2x;h=@;ak~)TBk(s+r!K=~{!B%E2Upvs_$Du(Dx4NIYSuhRJr8(4w_1k73sl zyee|?RBdNwb>EmMiEyBW9eRbF@bb)=H< z=w$zzGd2@~ z&g8L~Uqv$IGCBocGTha$b0hOGRnT)ngD3E8$&n=6WAF#2lJiezaFs5v7uR^lR?2D|@}C5Ewwxue?NcamuHn31S!P^B zajU)V|0>cfF%>5~RfSUSVP!y_L*UlHPVJvP ztifSTd;&J$2SZHw?nV1+)Els2Uy_6~Ow!H(2o90yQTv&lOexvVydc%ST%%_FUbY1d zmzAb?P6h=*Xy}gLWfYja#+64WkPQXz8Ra1K_^(6}koJiTcC_>qB1$JDZdE00A%*dH z7yJu+zQe9HGb#KYE>6-_Mfs5^45mylz_Ad0rO72r1V_>ZWl7tGj25pq#uzhVvJ;yX zMuzj*fh7p<&g4{qbyI&tOhI8GlbU=(X;g?Tc1()n+hRh30U%-5+Wqd-b!;XW zg4Ye33WP6Q+@Nem49DGsLLLKYShpu(OL0tyzsVm*CMiW5gdd_9-I>(A4&gyi%*zT^ zMl*=>q8@Q89XR^LDSBb%2E~YInW)Kpve`kZE2|vbN}~*3>vC;0m02FC?4Lm57kBhS zZK}C5F2>^D&b;3UHyg4^WFLGOwUk5zP;*ca0Ua!h$0^G8xzZ*WIDk&1f`=UO+;6br8pOu_&9Z|H)MncipI4@ znBRUFPiA;EGohF~$2!QcoEirNmi+ac_F|wux4Q3gy0SlK#1cC3}RKODs^-( za{1>&m}3>uq;qfXzz9)ZI@~M~2;s9CFa@BA^$BmV0I>7gvkOgzrE9Wao^6qG6&KvV zJQSP?u}H`*Px>q>G`}q|QmuaS$YXpWZTPU>9yV)KoeQTRHOg{Y5RK~Q>CWxbQ=*Rp z=8GK>hVY^{I&KcO08JwRGSgk*YcK;5UkS37dQ`%$P+^Rp4ILjssSY9yLl!`52>J(* z8Y-#+O{Lx1Z`2yY6VBbm^{Q2Ey*AWM!JhY#XLVNjJ@TWOA3D( z7kd|1igMvnIh=P_vrmaN-g2Q9UT1+Pl~1epK@nw*jqtVRuVG%hF%z!1O-{PJe3u(F zQrm>afk(J78}YeMDanIwkE@sSaJ|!+fuz>SH)Yl?$b&2??m-bQ!Na%s&oxWg@;uzc z>S$>NPWSf+EJLka;(Ci}O(m;S#IT$hN zQKd0*e{Oh~A6M<*$(kXMBfUSmDpdklnVEJx2IezK3A4_95)X=0El9~8)xZX9#1ts? z$ML5ws(q#LkSnYg+a?iEZ~YECDQ`8~#M0h8VEvW>t%X_4mGwhZ>J{QU6nP!hIfqP^ zuzW3)#}q#Y#TK#y)dIrjffRDncu*0JG55QpZgWm#aJ+)=lh-u#&_KV*LLB}QQJhyB z1FcfLAiDmzy{qPd>I;d|9}?~W^oOlEQsNRMX+B39382Mj`&cxPnN^#^+ITVUyHW;I3aR?St=x}8`OH6^uSCPuVBI(p+O@&<*Q(+?7NCf}( zN_mE;NfT%O8edy=O!eGMNKdqR_I@Gl zS$?yeeD4JUlU%eaU4P% zxF5uWrG^fFx6>4DXm&0ut1W95@LaPL}UgBo519*I2n@hO>wd*yuwgV zbhHA(V>E_n%!ZH6-l41hP?63Uj2i0pI`i@m8DeXsRxHpp%16?ok_KxOLFW*j1j6%= z=fpzRci(FD8KfhTwIr}+LjdT}(B!d(*=v30Q)M4mAHK;Cq*dPq5$4o0a=r2Sw;Fcc zG6ifUg{|m@5ipxPoBc*BF6 z)J?zI?DR)xL5$|S5@Q9~`V@SjzHs8XxsNi}V4M6lpzVt(7YWorOPJ77Dt0upB}7jC zyS=SGJn!Q<;bo3F&b6YXhAFxNPBc`thy4L=3^tk1>y!U~hd*~IPt@uaP$@PWCxhlq zfN#6aHux0}0D}jBR4Rsq^VzJoV_MFcjX&u`OU1+BK;Jk;bPMQdhKG3pvB=wNWzfQr zIVw+l(RaC;iiu!Z}N1lB2*|PSNwi+H6%!gFzeE_#j5KF zSHWkn(?ks-L?R_33I738Rx1&ZfA~PaO+A@&@;}7g;|MtkFRoIgQNoM7%i%?yhVK2S zVl-KPN|J^rdz8B1ItV9OQD-nYXxSovh1Gj}%m7c%H&Bj|Qo8F4DT+YA{3GN{@Ab7d zLQkYO^p;Rnn32jW3pSeEbvnhkgi0LBwzx=SF2lcGql!pYS3*fy&b0!(mnf#WP%wJ8 zvdp2zA=M4$IcFoBID6<)3Z-4>bnEpt z+1+OZu4x{4scxRy&UfuQ|I{%^DIrvbCeX^^yMp50283dhzXp#7xw9~lMZo2oP;l1`kCX;ktXr) z)y)%*yUL1zqZoB0)01|P@i{~V5L-w3HX@>Awr$@=R>d@yVRnIbqRwj}zA*ks^)04X zhqZ))ZTWg2iY({J?I;%q>D9NoJn&|56S5wFYs+7==f_`|Rf-@um?4qMV9JG)o&;^U zzQMVJ6)Xi+c60JB1nCfS4iPySd^m7RKdSGyPAgUD%cq_5_+>ZusP@jlOg@yBZTGs( zJ*tFg#X*tQ?+YL&96}HkEFQ?uPY7;1A6H0eE!6uXNp9O#s(ZbRC0JO)_#sbwy+n*R z`}O+cEC(D1u4lG#2%m=@r@9ihyIqAq^k^E(7KSQnmo9x{phG1QDHOz6H#+PZM=t(g}86dtjo+?&_Fh=cI4hwFhBLr9I|gQEM;|D_WJu3$0A! zHzK9LFm16#;Fgg{-EA?_J)|~@0w_h6YT}V5Muhq)$Z}h7bOa<0dG;BdJ(TaE{Ss(H z8(?uZz%(B9qBkKO#Nu8-xbJgmz#4w{JPob94 zLlQv9#!jc>O&#`WXDIH&R+sRs-V&p;n8$UBPK+cbq_`cNZd%s*EkJ==3}ZCX<9u|* zm=BfoV?14ZS_Oivqe3kn!Ex_^SGi33#ny7+1FbBB1Nf+WufNw@%Lp>1l=|lD$u81M z*qCd*&zqYSp2=<%_uX42kqbMx3w*y^ga2+g8k{sn^F#W-%Bdr#Fo+0rW0G#5#V(#X zb4a|4&I%p6G8IfXUtUcErlan3#k{{b2i9w@BCG3MC^C|v$E(*5PPqUd&%dyV#|Waw zB?&uCK)=hmkLUSh;krz&!8{b_RCEO+3OPQ$A1_gICG3rCN(XhLDp&4xhxNlIm5329 zF|64s1ZHN&PN~>--v&LC3OpZ4J65tqAOcbA0ZE&>uJdSgh3v{MioHV^%KQulYmA(z zOj`og#7AM(aoO2ja84?%Wwj(q&QN+*HIVnn+S`XBX zWtLy)Yn~F}n_6@Lc|5UyW`z(48$7)+=D|U8(rs`$3AxUZRdeAN6 zNpUB;Yqq8DPE#c$afJLmf|UzG%#r2282&VfFR`x>twz#Fr{3xs3oHYM&LZtEC-a;U zLGo87@gI5K!i}4oRSYDb7a=e#%)?1k`Bi~PL($779V1mJ3$>o}fb($IDYlv{b!fWS z1?w_4`f8UgKmDjEyoxM_EW8>D)uhs2wGw(j;2f$~i?M<%HaBkUXou^mfXI3u+=Otc z;5lY26+~sv@$ejkxW>Z$kGjTxJA5IYnk7XR&9xP@nYed{$p9Qv1&;C6_n?gWBsqf z-9#1Mk_K5i>AbqkhUpu1@EHR~pn&lQmMbk#VaLN22Rb#n!dbdf9+Y5c7di7epc7l? zf~{RdhD}ifJvaNtEc0qQPw5ZAgQTcuUd%JKoI|eBk`WcOvmh%P9IC@je_50$tkgP5 z&78y03=NV{*B0ZtFm`!xUUD`)Dy*wz`9%qKt!g zoW{E0IG`ct^>4`mVG>|+dYU;MiWFO|Z0->!EjYgSbq4-xBQ@(QxcLgV6&5g2a%*tW(oClQ;~Id?r>v12xp}f3&3wSua&ZB zRa?X=n!i#SfVQh7`bN0o18*rlFg<3n6)sqOtp+Ok_kzk>lmaJGb-5{Rn|K z>LM80%8;T7Y0Z5;r9CKMOzLnN_w#!N{yeWo!%<@Kpk_r|wtbA8 z4&%pOd5|7ow4`CQkw5 z5d}=v!5AgzE3E4t%Pgr69@>lUK3fA)!kPSdMQ+;Im4gP>i>-0S{6&F+@vkAXldgn? ze1Zya=qi_E`5QcsJ;m$_RWn%hzvgzA~yG znRiFslk)yat9|fF>!4JocgOYNajAT8*2VE;I~vG0s1QXieD6&S-wm4WIyEqR{r0F- z2G9=wv0FasVTZWQN@a%Ml?OedqAQh~$F;)&3U}3x4{#8Dhod(dHIo*D`v7X34_2#F z7*CF&`*a*SI}XWLTJN+PXx|&riSY@a24wT4GT1GtELLguzwh7>pTX<1=1^;9N4MV% zPC>tQ|6azMFXE-`_souNm)sv?|C!)@1@GPVBhy~D-w%Etw!ek%|MT(3Jw5+pv!mN* zOoPvx<9sPN-d()^GG5yL$rt1Yy50V!yr+-p-nISn@^R@6Y(IyWw*Sy{m~Nk5Ha|3* zu>XF7&p&pq|ATG$p>F?S8tC=wd35_0e*Ryl{kuETUbj!=ZHca*u2Zkyd|dh|cBqT= zc-y=3jcy;C`_c1jd%gc(n)WxOS?OOr+0pGa(}3E48?UhaZ}1u2qUrY14=ZuNRiGkg8|`5%JzPfdH>{^BET zDO)|ie)>+({-7@pT({5a56w2b|38}c`uu)w+UxdrG{K#}C1;;@|AZHvQQLpx*K&T{ z-U%K+c>X^J?eD)M?RER^ef+@r(|*&B{)!#<{Fk1QE79$J9T=uTc>cfR^RM7VW1IdS zUwX-GzSr%)@daJKwtwHWf8Vr!@|?Dm z?UMhN8|&PpukODf*MI*7IsY};*!iL7)p7I~ZQS!ec~ROwc~KhPr-M3w+FrNMqOse) zv?T3IOVa*tvav_dcDns~(EjO5(*Eg7((p~&Qg-yZ_2cK!o{pvcckN|qzxJ}U|9~#e z`CD@KY4-(l{^j6vZJ)P(>0xOrXYvp5raAvLGoQbQum6IV-uLt7=QKa{+RaD2dHh6< d`es|tB;We)N~N#mwEyrq8R_5TgeXmBG|RNU$#qT&K1AwY0zSf0K>z?6XE`UuH`M6xw`!QfJ{0VRc4 zs%UYk#i}iBZA)9UxJTtjwY4p^v_ryKID)x^pwYL1vnK|d)bMKwWdygdk<^!2~ zzjL-Zv);M)&D93xIp6W_7(De@~-T?8B;Qx>5{wEM`r0Yi@ew40%3h^eoehlKr z;r|ox|4G80g7|6p{|x-^f&b{IXDNOT;^*mlGsOQx*IOX|8T@~N?q7uX=kWg*bpH~> zzohG5LHujF-U{(===x=de@oZfApRX){{iCdbo~m%uhR7&A%2anUx)Y&x_%Sl9d!LC zi2qF2Z$bPvUB5%|yAc0{u6IKGSGs-=;$3w8KE(e^*MEcf1G?T#@rM-u9pe8-*Lx`b z2;zUx^*<@zOYy%T{+O=+4e=**{U3<`OV|4##sa`Hz=}JFt|Jg1K-akt9|->sg8zAh z4Tkt&x;_NrL+Sc3h!3ahArR-&^$`$%hOUpKcqqk3QG7JS$I$gKh>xY~<0w8J;uGll zM2J62*C$aNrFb~R1$2Ef#3ShX6o^ly>(d~{<_rIv(^mOJesb@P+SOc z5nUHUJeICYARb58;~}0v*QF3or0cUOK8NCSAwG|;&xiPPbX^AVB)Xmq@f5nA3UQ3C zFQE8BisKZQQ#_60=@eH$JcF)hLVOWjS5o|Wif2JwMc1<-oy1oqJ z%jx_-cw5LEJ#sjSx4{bu+~+ z5PyNLTOn?v>lDQ8biEkjYv{Uz;w2DYOV`&?d_BZB!2d78{~HPW62zVGe@?vXoyQ?| z;wy9EuM=P1)1HeRoipUo=dOGnljB`C?CombvvSU!_{!Mc-9w(u@7iii$;n^s;yb(A z-v;uXE1j;`C+Z@9W$f*o=kT%%EWdivfC3TQ5Wmv5FWS7I7s&tF?@(_)YKQK+yG61%UCc zN6Ikjj%`5g=qtGXn|D3uZ*boe?;fX;Jd$pjG)8By>p2jrSh}{vyZ)d+ z90?)g1hXHsYR_VjtdqL7{}ty3@vi3~yKeq=MKs`Mk^ys0ySB49&F1E4*QpBd8AGD1 z7R80Mn>J(lUQU$~s!Z1npLDhF?Y!ZWoc7|IZrHmI#+UZfC1 z8rhz~*0u9N@V8gx<6Z5$q0aBV5~m2hFi6}jY;CC-)t0JGwYQC`O{S{r8`?(AuWxe3 zw70d6X=tvgZWvSFRMXI2n;e6rEiGf}8(SL2)HK&77bcs=)HKv5n^K9I=B8A#BQ?6t zsc))J)mJwp8bMZVb*ehinyg9IFHY7bw9@>;bquE72vut)IDBkc;CLFH%2-5 z-(*j7^TLMYn3mS&RP+4y1!JmPlTFoasn+_Yg5p>Cpv{uVn4nQMPVzbwhhH zI{duo%sCYmXGekd0Qg@PJt-fr(V3rt|3}hw1Y%4_oUh^1K|kU>2J>~kGo`&P)!Z1p z7!^7->Sk13vbr|e%6I5(7_*ckqwFoVG|GOAE@%ZYZOPWf$yP9!BN3Jm;vIP}kg+I(uAU;kY8_n&#Gq+K|zW$+ouYg-LYi{OY#)nuIQm zv(HY0w5d52g;J=m1)F8y!2oLR-j$BmR<}bi-@nx*X$TU8)0dcc`&wUYU0Wm#T4hljw<_oI+25YWB@K*vLh(9pGg z*O`_9!!tv4>z$k9(5LU)mouay_l_JVk-IF%`ECwObX2wTS0um4h>`qSAn(#@8> z&*OWyo=SRlfu@am{;vc7uLV2T4tdmB)-z=JW-K$f-QwiLe->jKfC4LFZ0C^92Zz)7`AuBhmbJ{Ni?`(Js=kt`Er*Rx(`<}oq z04ajgOXYiL1g`F7e@q>!2r28&M1fQLTQ$ygah%Ih39O8P8N+s!ly_|o@>O*0VC9g? z90G+htGs;D6{?*LoiOH}9OpV{Vcj{okL5TUbB?FRCZ=%rHd(hJ}v?1Z2>p=aDu2J4}<&Uq7B8NlxNp{aBay6ZUIWxB;EC%&DVOLY&K zH$J!Axr(|*terQ#zZ5E7yz8kIpQvY^r7F6k1EcQc8~%$Rbd}mv}O4pA&P8S{u)FFY+3#~M7dj*zX8#KTb92G(Lvy` zgx`L3+x-ZNgTz9W_?yS`L{o<{yv57#oLhiw9+Cw;bBAK??$(Kh+^PgOKT;^^b<0B; z#gr?T>msMruAhMctChKrs8a3j-k=KV4lLC2uHEsj|9a+XN)iP_)G}POV$(%mpdZ_0 zwZKlMJGPo>*&2kpwp4Weg}R8?3ZPoyD#TGh^k-c#0o3am-UBO3%s_jncU8~&Qu}() zzCJtc{au1WgP661_uhC=1SdnsDcsQf|_Z0{kz#8zO@B!0);a* zvMr!a&i1G>keOh$EJVzNuWkD}jKAV4sxEm)ReW8=_<`Nu(tXX5No1S+>rJZBz`BBN zA7l})B#1WTtL`jH*7;o%gR{$_8gQM%T-x7$yQKqMI^hMzRI_2fiPa!L>kf8)eb90L9qinhm;052ojnIr{|pOgD!#Mzf~-1>-fTck=+A3EYV$EnP{ z#A#6NeBV8%y>l1LV8}69G^Qk!}Rn@ zcpQ-IJJp=0YYwo(v=2L+=oXUq$rfu$~AGwBrE}R>)2guoOO*5?x zD0+BYv++{xHm*_tFFdz-y``rwswSj9f1+jDI?$${uU)U`Wd<}H{G*pe74gqhUBjAf zt4}o3r31b#_vvoIOIN zWuI^_0T09hU!sc69`Km1ww^htT$tqDb-rH)HoPFFvM{4_M?b9aIGdFS&UJCYW)4hp zv9Wo?E5+aiQxklaT?tw1o&i~ly-?l-a{lF+#y-dg{klA%*Lxbq9(PLFxi<$^q~H;A zhVmV_SwC2U{ch)@0@qbs*2D8#^4fkA3a04N!>K2tm7!)Y1_Y zZRc|!$#q1KS26fXgr(Y3e9uZsWoOSYHjeH=r`ywkN%~sk&hxB+&QRMsZ`kd?11hey zc*1&bE!>N3SDi0*xU34MLB889;Qy@}@~t*?;gXx=!>$f$j{lizSx@_^&?#d@g6c=P z?!wBsRm?G=svItb?K(iwi{8=gztHpHmeTotVIN!MFn=qx1Ga~Cu{-Tc58Zmm=P4XqhM^Ybkua{q;G&ey{Q-|vCvfI`+S0po|0YPfvN#xJaj0kdbndQ z5JD}2TBDzxRh{*6xLcHfG0)!0kIq}yoJ}wb*ig|0&l8L)K!KOtiLp(oQpyhy zYWwgRX(hf(jQv3rN=4V7{WSmxk2Q8VC{SA=?R&%X9STHG3F=ucqnTKD7Jhxbz7x&DA@Fj2!w z+%=;I{JYgj&84;tFqbw?xS)2(^(MXEcpM}E9p)TkrjKpi^^*{CKX?P2hZ8yJ4PQOs zw*_jB1uOX7SnnmZyKd~&sJ(g|*p0)=#OKs&livLr&bu%kx~(IW>F2~=Nck!Vq`-oq zcsu7#pglWz`O10a{)Ph07t6EZ(Rd?7dl^Qm{^nocpFw{@Sj*p=-d?a>hwLsUC}T z6?Y#Du+nUKrVQq%xUx=nbabHI}c`K%wZ|KB1RZ8&!)R zs)7a!#8!;yC%LN9=?W6;u-w83I@ZmXdN#4vF29lfyHGv#dIx-+G~{de%#o{|fs^59 zcO1x0(`I4I9_hAh_2}l62Ch!2nz%*0-hr9WA@MG^6nszYs^+Md%JA$H(QPfzci5le zu>keTzz+3v+bRo`mrKFo^vVv9GSk@<3~8>+R6%5vktlkZ;$8tH3Dw%KL-4!{s6pS8)Kc3K@WR! z9wa@rl4elCwPQ1-kCEwDd;D)xdVx&8Qm01&I{=o{F{qAK+VF-aVgH*-CP3ZFV=M z`^pUb{RI$!{P{{ae0L7lZay#d@=-|X$IA5CUV0^^pDNRI5k zoCoO`Z1yarbdx>Ezb*}bPa6Imy`*D4)>D1>0P2@7AMwsevI`kk+fZurFAI?j;mtI2Yr^<9u$7fTzFAsxeDFG-yMd`M2aSf%PBIQ%v zL;j7FexgjD>)E%B(hrvDF)w`&rK2o2f1=+XiUT}^QvAdDZ}a#|DBae_%%*f(ACjVU zn}64&N#986H%j{kUF-UH8>L_8OV-Md{_Jgyj#K>e|1C(rxu?W194Bly0&w3M%(d`VXakY=;kdWjst(9{V^@O6j&b zGMCbAb)+Lr`r0(gep==EX&KR+E@^7L^am;3G=IZ9Zl-ioSz;SsMP-e@$qSA>k->V5ivk^d z7@@*=`0Jy?$q`_vtMD*I;+%yMm%FHUm6UF>1^HVj-R95Lly2)AH&FUisb4&^Y^8L} zgKHo7y8*I*`gc>h%|8B}hb_HO8D?%5D8G`@ZTV|SlfF8Q{0)?@BKE%+o42NszdH?o zzM5FV?;)lCaAE=Xs{AS4=ATMRx7pW{CVe%f$EE&3QDboxQvJFgu6=Dt_gi-$CFY}p~p}XePyn|@Ur5-WY(2G0p`(T+a`rfE&$ncwDnND-vC}3rjZd&6&7F)o_*#n#p z_nFco&I%LkM4T^M@Rb&Pl?Cq(;rcgY9**{Lh&Z?Mr5j`akRx#HA21}~{~%%iNeb1^ zJ&5zYs@IUVj_6fAgzI7OAH#F-AL&1@?r04Ru6Glz=C*Ln@`i!INPjocPoWrpFOB%? zbg#w@xW?ZN=Qy6|RX8d--R|n+$gm5llmj7GA*AYF-`H1lK0XfIOdI(o1l~&aV7te_`T7;%ClF4N^Dn|r4B)2$Bj)$B z0lbp%lLGjSghvB7+7NLb!6+0W&QC+w!z2gyt-t`cD!fZL{_Y9`<55`0LOXHK3W?7n zyfA>@OE~UVA?ddhUK+rUgEb+Pe{KN3oba*$elOv;SA~@S7U9_MO8gjDb3ysIKZV4n z6VB_qoZsbyjL;t=-^Qf?n@!* z@jBu>rm*0jh}sb+h$8({VGxjr+ASxX6mgyngNpt+3%=QcZ?WJnSnwAu_%AH@OBVcB z7JRD(f7ya>v*5qC;D4~-uUPOuT5z5{_>&{fn|^@qBF>*I_*)kI9Si=h1>b4G-?QNF zTkyYG@ZA>tLks?Q3%ad5Y#aELgES@0ni9Dhp`4iN`eg2Ex<47K1#S#aFVDI6jWkIMeEh;y8U{&)+{ zqjgXYkIF$jYLPSCf}d=`PqE;qS#aE4DjXsX?lu(;5eIjl3Wta@%7Txv;5_R4Wknp^ zu__!Q4$lVsX%Po^vI>WY!?Of`TEscqLVu10=UGKi&iNMlG7FBoWQ9Y-;aP}3E#lzr zS>X_IF0|l0Yw`0$9NcXy93l?xz7-A;2Y2HNhlo4-@ux)`+^H)ZBJNvne_F)BUA)2} z;^3}c;Sh0n7UfTiIJnzaI7A$tUHQ`@&Se&Qo^=K3ud>kdY%EBRJBNis#Hq31NejNv zg5yqO;Sh0f=do~zIJgs8I7A%Wl`I@0PO}AXvEaB05e^Y2Wx;V*vv7zw9TpsSJPU`2 zb6p6Z4D(xDC&`EBBn;&`Qhy`P^&xsph^SrD1R-3ulAKFPj#?KZl8Cd^A_sR|3x|la z+=Aa6!fyt>jsp)jf$)IB;h`iDo>n+KGz7w{3O_u6I?mq|eryOoRxL>IYL=HgU*WjY z>kmIx_=$cH?%q+(S3qtr#g`XV4ho}XT5h46cg`X0_ z+Z29U2!B%HBSZK{3O^%+k3I~cGeh_yg^vp1KT$ZYI{L$Z6n?HBguAO%5q>U&uT=Q7 z5WYjTETvZ|it_t6PtHLzk^ztW= z5^+}p{Rt6=ULN>i@DDBehj3g)4+of6he1Fh`pd{rTEsazgdq@djtIN|^RqTiZ_5+eHRIRk!D2ty#^L@ju@f7A5g{!QcI{!QcI{!QcI z{!QbjViXDyC*1ELQN#)Ndm2AIBtzrj{!ruL{!rs*S>%NKNlic6LO;fW7h3Ql3tnu& z$6D|b3qH<*tGD-|w1_hygdqUWDHeR91wY$@pJTzp;|mf-obxR7=Uedbc%?satj_Fe~}QLn=JGd7JP;U50B$W7;!GL&{taU&s*?W z7QD)W&$i%mEcnG1{1OX3*MeVa!7sDmms{{FEclfc{3;6`o<|{J#F=NIueRXxEqILu zueIPw3%5AEO@&GUu?mz zvEUsRe2E3W)`DMW!LPUAH(2m5TJZ350TRMlA*6OFxdT?gZSV_v;q=O$z^-D~D%z+bsBQg|Bt#;Z}vi!GQ(NT`qnCU7exu zyIuUJbX5Vk$<8W8f3Hi=Gn-b0-{<0w($(#N4M!|)T`4=wVaRC504%HbB6d!*T( zdJF!51>a!7@3z?U4A2)i_q+CRkH1Ud54bqbfcIJOBZs1#hg^Do(kNBEdJQYA96H0_Qs}&LeI);HGkHRP^6->7#V@fWp7;;yklC=4h0^!Ns@J z)op;AOy8I3$oaK}{$qtdK~(fT zA>5sE9O`|_#aVt6;KRi_@JOO~)Iz^c;m^2o_z5FQmDf9T@S%vG2M4ZOhlqlfx&veB@~;=kKnZQo8C;`0Fmte*Tfd z|LNj9F8ovBdqa3Rbi4)5zg+xAx_VRLe{yl|Cx@Mm^#6A8>*(rAg}>$E=hD^P3jdFb zLvg6^wuOE;C@OH?b?Lz^D%2}{pNq5n-zz*^-=eV8Sm5MPZSwk`l)}C5Tex3(QQ?DK zde(cuSt!T*UWMsDuW;{s6`o-{s_-GM9OyPx_*miI_bObDSHT3nz}e&Gi^u)v75iHgGoc9Sz3)sIU#;+5*FWWC&yN5%wTs^~ExeE8bhhcv{sBrIl82<9<(D5jT?`V$?kadf~z3-qnUpW(y z-un)U@mhs@-^sAv9SZlplVSQ3p<)+^@1U5z)q?*_;of&Ohf{u!oQQJ9hy2s6aPNDY zsYJh5;oSg;MR=D?l4&x)BBPtNz=P-Vs!oBZv z*gwafhxFd}IgH<-aPRvZmh+*)z3+3_Kj)v1a=h$=r#@8s^``!tPNrgQM z_r7Qy05`RZw-vqj9n>X6KYTjM3FB7*KHORC%4eA?0OxBGp`v>f zz4yHn)4XM&A6$X*z3--Y92~1~@B1k3Kd%FvWlFubBR)tX`g)y(ev<|NAHWO5cUC+; zer%y14FypkzQ1DoYXFai&2gNCdW)}wKKX8RO^uVdtSVJeG_j=~PP)6MzAfn;bp}b7 zRTPyb5(`sxt#IgDqPivpXW=DU7RQPU!)U4%7|isLFmobsG_@ycIyw|hvZJQ1x@loD zQQZWBYinbb7uVMZ>53DHYB+xmj$*S=6pu?Jf|3$#a9~_RGFBOu2R3-}>~zHw3{q?B z+ghqqHFXBL#YH~30ZMQ$_^`eiPwxw45E*Ne3#!{2QVBStZc(D8xuL#hNesxaP{vln z)@(IkaciQwb)g2w*Dq{pZcP$JA#f*K6)z!0sn#WlRI`K%t81HEv;rWSS%N1amZ}Zd znyMQrii;Obu5YStT@q_;ZEl^a4^f<+R7PmpisEsLW>j}fYERY8ZeEmZs;FO(Ou=?; zRmqw*G}Ubt+kV zL4C5Jc9O0RU_e#s$!s@oQ&BOSYl^<+RjanbB0Ey)ZBi%J&F zY)(~H*DOlbWC&q5%VK8!vEz;W71i^T4GI0%ZgmE{R=bPS>P=&LNznyx@aRP?DX4L6 z35*+|-pzo+Q~ftq^D`D;&BKJuEJ%});!@=b&dC&2U-VzA?Y;5X%%$pS(v!x*vAU8m z=d>ziB1Kjkd*`xRsVkLPR~kFV70pPd>Y8hrxx6;n*wUOzHq|VtNG^s79RjSz?}sQ` zj>b*M)+&EC)sR>*cI+b6olI_D0E6l!t@W@0DvW#jwj$XC(;#f&B`|2?k;5=6p#ypA zuZ6qjCN-6*P3m)E@xBmeAQx6#G zbmwg|y_Be?K$c(|TR0-RE!G#~P4ZmxEk?MO_Cc{L!&PSTmFIYv2*ZTEsHmt|o`_st z111*1{Jk}SCoiYk%4=d()$k_* z4X~SYc~x=3*OdCDY1$30fTDu7YwLTInO?mpnvj?^A1YBYnZVu_A9c#Pkf(<`yO_!h zxVREB3iX0mn{Y+~6*Q@x5=sE8^y>cTRvn&hjI7K2a(_-Ym=kM-GG4#jKC;dszC%Up+xJrU|W@+^Hey*H=n zhGn$K(6UtBgtpatITsmr{-&~Tx~8!b1}GXFFS_7@DroAnCrz%1DYs5nBQlL;MTJRx zG=+tU+N2)U{K;c=G9BMOd7SF8G+|XL+a7F65jMS&uocD4i?mE-nr{d$?rrE+@@(UJ zaSX?Gm<2Q>Ez^P`MPVHI6|*<;`%F@7Doy)JCXSn*TnJCjYJLz-9h+>bwWUp{X>M$R zVLgTumBwUaO=Al-IpvXtRBUEdLh4aeZgLyc>gHL~gEY?6OGd-=XEdx1b#x?PpZKC#4639AQ{#-1C7_CU`Z=*wfV@%2q@$yU{kla?5arBI%xaRz!? zm?EH~s1=N*sbVusP&-n^B^M@BRms-H$<}gMx`R0%`$agUxMU&pORczSTAN&$Y?22X zSOt%B1(D4CDi>s| zv$zN*!PPLaXo82JrkZ5m)T<_LYfx6JtE)sOow4Obh2VEG*EdSoB@|XPL)o;oRWD3J zAB1zXQb5#`F80f6!8#*ucwWGs9;$?$ya+^J0FRVybubfx9L|JUK#{OO^(uCDK}j76 z46>lHwgE@lUKAHk0KdcCT%EDAsm z4xJ~|ZI*yGOt+d}TomhQfsU&_)v#m=EH|ZE+iO5Q%!{+G9kJNhg^(eYX*pFcDvsk> zC$o|;k#0+swk1=Ers~EdRHgkA<})EJ47<%@YMQlxY%d;J+`{??lWbTa!&lYnF$t=3;3)~_jG+gl8d$1= zhaZ~bKz{o?l`mNU4?du3oSvaqrTVb?LC%Am!NYBX>B-NOCwk}`uPZ?_PT?+qXV@xQ zltVyG08Q18`$Jp1FsA$FCrkmpHulh_CFC?~n%-d1UlRF&)!5~kER6Nu@0(dXEhf9& zPQFjM&s2(MOL*9FW%Qm)LB=yPLys>V)wiyLYm#Yn;51c-i^s!5U9zUVHEDR=p{CPZ z)zuRqzd6~z&NVzx!s?N+{P(X94!nxsy04a2_$KQ|i-1sFe9+m!CqL?87#Ex1F)>v% zj+e9f4GHv*MdNDg@y#NQ+z8)&)!;*&t1eZIA0zG0xL9mjjoS}Fu$VprKXHQdBypjN zC)L?5xcQ3{XBFP0BKuJvq|NZYo>OHPTdZDSX>awuELLn;76UsLG`C(;-3rgby7|f1 z8MuN43k9j7@vX_mX81S{)>3s1Q!jo>R5epWxhn-mLF-F2d{@+qM0gY8N(7|?@}gxN zI8m?SCE!85x&iaSYkAhCJTQ!w^1u~YJ_)&!^WvYXe@SEaDyDX(ZOj7_WTrMH7D z1^Y&>Y}k5I?JW(-1oWnOD0%r@n4DLo#woCT+SC?&*Bhgmj#o-W{V^=4DTA*Ymn#Im z1)bjC1?Wy4yBw>w`?vwJPkcSnrxm;87w}nDul)^7dBIdWu?T+V zVsjKWEpU?l6wEM`;d}~AgpU&FW1)T=Qv37S6N;gb9v}@*@NNz1$C+Cxc(%2EVO`2L zd<@(~X#%KjNG|w4(Cq7C2ByZMUtvDmj-UFN8#mQi7-Ym3jp?UjSdVoj2C=4@Kspid z6l<9&=%U^~p|Bid&t~6R+XU!E@mmFcJR68+;Ok(5&o0nIYuD(t7)wUg=c7ga_4(*P zWYRa4#KjDn)DF<_;!}su5prz^ooMj0UKoOIa3VjY^1K*-dfJ+tU)_M;G0nG?L1AK6 z6}|!j=`hX32Zy?31AM5cCZWB}L8k$SWfBTAOniw}l$fn1qH2)=XQ9)o#wTF@NuLn9 zlii|Ece3m1-S0^@eo>RvEPMKZJ`8!oLN6WXz;)U*81|~W4{tZs+i>u=+rGWoo*EGP zv#S)cU@@h>Ez#88&;Sq5>gUAe@bV)zzfyfu3HAUj{BXSa8knyxgda<(ue9j}arP4& zT+FFaubpDE8r6r**~`FQU%f7J*6U4>S@_BOehS7F2>dO4 zvtAunQd{BIgHR<%2RxHW4Q>VQ$H}NFvX*xE)DM3>U>PEG1_wet{K8)^Hq8X}u+B!m z=jVAx(Rdf)7lrtXlkhm!+YAg>2H&ww$!omsB-F$%Xuc}lu!X(~Mzj~>TP)0&5uZ8(*V1KmD>AG>MuL$~WI4bpxMO3x=ak!i4 z7IHZ(6HbFC<#PQs4UUD2)%Z6X`U3F-V1Jor-S4R16r0M!FE^{Y!pkoG+ps;?H&#wp zZLNRhOV^JF*W)ud{PazADzU{d{rB8Hy?-^A!j3?&Z4>N$gV}=C1e0C;h%q0xr^4A4 z^(}hVVf{I4;5TT#pR>B}s|}03YC$IOrH*8tZT?gs{KE}38E%0u?GlUYTT}3v3*;v= z=H7qifU8RC*CXnO`_=R77Z;(EY8tBB+SJQcSo>Jetf;DtT~FB5%VuXpncgn^VyM2k zP4%iJ`0FD50eGUetvLZZL)11TagYlV=@(MUU+`62hu%ZWI))qHdFd}ZEI+DIFVakG zYJo00Me5ZUeDA*W>9su|&u*)6eyptm0D+GQe z?SzM0%^e8;$I_m2ydxmeKP~8aM_9yP75G<#oW}%ykHEJH{M&@1oRtFqiNIG0{29X0 zysZNNg`k)DdR@?CzNS#V-VyXNUmprw>OGwJFnSzl*q=uU9OakO{RskpUeFIG9P_(b z;Nu1UWr0rmXLq3 zz=2E!aE)rGbc@@;tAMg`w@9`};x`DK_q9ZNJk^uwPts!4$(^{nB;&;b?-cm4grgkU zUSK4ej=lx+(ufz)l{oR5dwuMyz%Mts0_QRQkqa3tn zBi+OH(<&hS*9ASxVfy!pu99M;zfaK57x*^>-YW2Q0>571_Y3@1fy?&zU4ctEj|g1W zw;q9iQ^@~?z$N`bgkydm6!bj4BmR)UWw|^caM(Ux1*E@A;9SoUzgOUgXmZtWd(>*MhpB2AqTcsRsrRIOW+q1j&hz9cv9d`2|Oim**|v?j`Fb`H2@EWuj)wk zw{kwSPT*1w*ISmuI~zYG=%t+31&(ttZr9u{F<-L({I{T&{qwAxwEta!OZz_(xb)8fXb8!X^hXko z(X+tI`6?6i&k6h@L62p~^j8TS>j{oA807p=&P%Tr^5wkrdLiddA^*z)NBJlV!)*fp zqM*ND;Qu4=9|?Smz;p+uK2aOsDW1TOtBM&Qy9=L=l=Ax?PE4^@N*{V-q1!DlY6C)Wsi zIo_=l^tekp)2|V@^xIuR&WnP6ouEhmoI?ItFX*M8pB41i2sv8?y_`?JN_fx@?+AKX zA3hYgY>)pDxa>EEpd%r0`Hm#}k0Bf**>9XIaM`Ylg&gdo*q@UG{m%tnDRAtIm_8x! zmju38;4)ud7Pz$ME`dw>?+aYgZx*xqqDMJz3w*x7agBxTX(SxwNWTpi^zRD#vji@m zTgwD4>8A@^(#z+gzX?QU%i;5E0P;OY zOcwO(E%xLJIZ>j=_9CCBWVswD=%xJ!30(FAc>9N z(x?C;9DLSbIa2R1Az%7`ub}61R!|Pk?OD!DEndwljurSkflI%&2>dgG{)+-XLg4oZ z{5XO0b1OhTd!`C{S&o+pT=oyLK1e%n5%jVjxJ%%;HqL(7L^#&}69xXJpg%_7(*K{e z;3rw|sKDj8BmFPih0GVPlYt00$J(>MN!VE+aOsDW1uomQ#AUul2zuG?;oO=1Hd*M! zd37zMVc_)#^yjI9UY6qnxMZ;p&G|IFYA3s;HL}xM*=@X;6D@inF4=R z;AaW^ZGn#x_-=uZ7WhX3A0zPp2)t0>d60Jum|rI+NhAmDoG#=` zIr4c#)@M0?C=+rdz3urWkLaO_I5SW=g($^{&lEW8MSKJPp}@}_LHbfk58_fUuO%XB z)Iv|NgK{dto_qqNoX-n8Goha)=;b_oF5o;5FCalk`Y@566eBGy2`HpY;F!i?9$g@Y|9QM$8o(#g{kj0o{X$Ow=l7#K0{Go@ zuQCMJtoL=oqm&oKk78Pg%LIP3z~>2^pD{6csld5!M|_>Yc@B(tkHC*ZfWi)eAI~7h zXdp%0SKxhA;M@igFBAA@5umV0;J1)2Oj;^%E)&GN1Rh0z!g_%ZXAt5S1YRKUodV~v z5|icnFt=I6&!T#VZ2XLXc!j`mO_M`|z)Ki}c$L8USs0Ta7C1lSApVHJ`5hVJ+XT*i z1>$=I{y79F48?{80qrlt3koFypUoh|vjsj!;3 z@^*n=E$H_Oe38J19i(qCuMGk(6*#X+V)9&p^RpY`9RhDgfWlgV^D{UmZ4&qwm>A;i z0_SfJFnO=Q+XVeE8aUDZl)y^`-Y)RD0$(if4uM}I@U;T(5cnp6FA?~5fnO`|y#nX4 z2$P2m)4+_D+KFX%1MBw)l zhS6++e_h}yf!`8w9>h;6D=h9)bT@;6v%b3hn=iz)J+aQQ)%${)oV@6gbwy21>hL;ExLWdjD?ZAoLQdcHFn4j$2Q9bdr)pVg!BKplljga^Aju6EoYCJ zC~e1(jb2y-TNHHEB;llVr~nN~ED9~$%Hk_F?ZXTX<}z5t=W*c=RSe1A`A>$UxiY2~ zr*!#wvOoPQ6aHQgx$+CJ9tu=6K<8a~H8Km;7a9(a+RuFS^BG#kx|?y%`r8;^tFT&; z;h|H02g_e$`A@Rw^Jz|gMR1fJZ1My9>@~MG)E0^JOu`2{`57f2@8%fzNuAo)F?%lj zZCTb_z5gh0|13!(Q`w2bC3c`0xWo97}}zdE=oB(=}gkoVSyJw-yo`>=hDwwA_z$UJQR;GP-N$0KdH;-O0i z_Fx;oL-wn)6g$w!^8&oqGf-O%dZz>ga}nAYv$yTA@Dv!|;R&Ai-95Gp9cgddUV%v3 z_R1iux6V1^6KR4u9+2II`f@l;(7?VPH`8}{hQnh*LQT`00XV`Xq_=;!mJf;VW4|0c zj>RwE^wgua88M8-cG~a*9}XzlY?a0*zWA-{hhd2he+kJQh&IP#6&%eG($~jcE%3CF z_0E~N=eN5JRoc^GxZ}eeZg?l+e%$#i{jTc+Y=F1PE>u%Dhu*G;13mnCJFxrf$-ubV zx4XA7x4zm1jV`m31Vkb2->&KQt=Ro;5j%7B=>#CZ)PZq!nj?E$pQ)}byS?u-If}@Y zKQOt29sTs_+ z*0;)ud$iKoEt4vH$cA9wHj*P3=PrgQb|dvbe6ngo>7 zQGTE5=_Y0qKIMZ>+?qZxy_feShK;e;);cf-h-c9ZEa=1V2D4@BhUu=8i<2Kd6`j~+dkeGK9|FPc8hg$@Z0`?S;`^&I%Io)2A%Y$aYS`bojd#|8Iv^sX zrvHW%@4x~)w*fvX_AQ*yuVE=YH5guNDI-TxR4kFZPcy^{$XH=>S^@H<@46-)LGSXLxo6{n!EXk$sX3J# zec{YGquNr{HH(NpS(jMQTHTn0PdQtg+grpBV)pZLXR+hZPjY+`%IGeSV%(z>_w6`< z?m4#c#|`|8v*52Je)<`p+A|;bCuO}H+w}8q$))|cUoZ1*d&{ANSVAApQS4xMx0&ZT!m&{J+nFe>L&T`tye@_}3Zu9|w%>=GbOG`U->0|8}@% zK8|htPa61N$%6j{1OKa8@NYBl|1k@G-uFo6ANxekH^;X8<6guVB>(Gh&wL!)_;F8C z43Z!Bfn+|8ZTz^mR)`+}=HuALk9)TU`QOZfpU=~h_T%|Dte0b({*ea#JF?J^dpu&0 z`u_y?te0b({xag1{l`OD*dI6O|8o}l@k}cW(*C#Lp6%w?X8$|`Kb}v)d>q^O8w~t- z{sHrGY~$}R@Ndb2e;M&h|Kon?te0b({#6EkY}3rgv5kL?!G7FNo%uMn@vk%J$2QG; z9NYNU8}#FTl+4Gmjeny-KkjSDd>q^OpEU5}evHh=v5kMT!Tz0D@NYHnH zJ6n+#A_`@f-!#%dt&ApMxX$KgojsVT1j+A3N*i*rtD@f&VXA^KoqBf1mhe`@{1Tn2%!{{~iN>UKaeH z80^P$8(1&LHvM@-AnPBVzrcJP+xUkPfy_Ui1HpV8+xSl)0;wO*d0;+{ZTuq*{P;}4 zd>q^OOAP$DUpDh`Y~wF8@Z-4w%*U~fzrw&jGzt(SM{2{P;}AdO5b~UuxjT^B3 zIJWU`BLZ1}@jM6Sa@ozBLkLPMIAICQSO$Pn%L4Uw}9NYLe8~E|OY3AeD#=q6T|NSiZUo-IIIUB5( zW1Ie+#4qa)o^!!`9NYMJ8}#FO8_dVCjsFvaempmW`8c-m^SUzhzi zp0B`qIgWx%fYn*J5V>Il@i)~@_!Ce5DTz78_53K0tx&+ zj|El`f6)Fo6&(AE>4WzdLW0Tv`9Iej>}T}EQ-AV2OYuj~&bj5OH)RiF*p|6{;R_TNhSk8(BZi+~#ER~G&UGqnF77XFuse_R^< zA40k*|7C{!-vPA2{2v3EH|0N%_6a{DjsA%i{$k=kA`SnQ7XGQke?l65d{1t&e;)D6 zJ*`nxu>5WWW|RNs8vKX*!w3EMBa8lHXrJzmSNr{oyxBLH&QU z=$}RUc?jS#De|j@x))7 zhJPIJoBX%>7n+g#DfHj{00r&;f<^yQ(my7kKafoa-*cMuuP6Po{2nmqUv1I9f%F%o z(ZAB7f4d?74;l3LSoFV4`gf+$|Aa;VZqh%G_|gBk?|;z$_@2vD{*TkZad{g3A6WEP zzN8sDg#Pas^q0WEY0`f*bzD*6=LppK!WiH;mH!K*U)I0x0cSA(?H2vxN&iJYZQ=f_ z#iD-)>6i8I`v(0VSoGga`qTB_=RxL8{##3o+tb)z3j8Mj<^NJMMo~BftUntd4*KtD z(jV-9T4>_M{#Qca4~gSjrxNDbCi_$KqiA%Pji$kp5$Z zZoCZYKgXhfy+J>oR}s{|*rNY%8n{kPqyGyQ{XGW%KVi`Sutk3f=}(vcZ(H>5Hsl}A z(+K9@Imlf8Gc(Npzb*RneytrR>pz~)5!8Q?MSqI)(=eok!QWu{f6cF~+q5ZI$5}i~Zw?e--p^G6c)-af|&s$bLSD4efss z1Od4UT&^d=b2i!(wEsD3c(aL~qoDn(h(9=gJ^DD!k*@yT0{kZbZ^w^yA+VijKMv_Z z`~PauKc4ibtAB4>^zSz4$1WwP|Fnb6^>0>&`7Z!|Q~vX|WA6R=-wO9Z{T&wltr_OO z&7wbQ(EqYQ|936=Z_QBuLl*s|2L0O%`d=db!FKU5>0bdnGN7+zc*|mc300hQ_2&(X z{gnp$u}THYZ~P(V`g0K}#`Q57g6*#e_)Ybvj`Yj%=M@kX)W6K4|5no9A(g{*(9bto z^sgoT%#ZE&j|TnQE&30ng^x?p=>M%ne?Ddw!aVg?&!6%8@nHT>fDRgc8tlKWBK>2D zpQB*@j{$y@|654E^#7X%{r6k+-$we+V8s*%_1|mJzmD_|BR=&1pA7onvFLx2^q-qX z{|<}(O$PmM8T5~Ybt;qp_mcj@)98QD!hhh2n(@>${NDh6Q~7N**#EA<{(oBZpGEr9 z)!)Bc^zS77ak3xFZ>K?j1vtp$zh$JKx0J-$(jS zaW(6Up#HC0^v4bQ-#6&rXVJfz^i$+o5!C;&MgKg5{=XUYPak6T|DQ-P3=h75WhKM? z7XDqtPtCw(3G(OXoAu|>gKMeFsV{>0KLq$q<=V|O(O*XT=`q%|BB=lO z7XDeppYHklHx~O>8|?qcVE;+5PGf36Eu#SHmhu<)-U{u_PT!{hJs zz;7zQ^^|`({{9PO112K_mZ(V+j|vFINZ)e6(;-(k_e)}TLP&>w^6T$BG#ApPZ(Z;pcbF9Uv)|2L5S zdBlk0XRbm27cBZ0L^Wf&`9p(6fBtKlU)KMF4En!r(Z4D~{cA1y%SgYh|AP(s-?Hfc zG3ifN{%=_H&o$^j#GwD2qs-<166yb;cBA_@SpMUI-&FoBq`!wavHTA+=>MKY|MkN) zW4iI@TNeF=uWNqk{~-qbA6xX_P5Mj8evX3q|Hz_0ZqR>(L4WPhX8*rT`k{OE1rXs2 z?^yWX&X7NOj9LFbEd0Uz|JK5vSD?*2%V(|DC81vdzp4JrBmc?vdo*M|*niH20!E(% zpC3y||3y+6TnFv10)CVJ)uca8{8)d78T5bIqJJ6bPuG6mv+&=SA^$rT`?nkF-|+_f z%Z@esZxiYNK^p&^1N>+-vKf?|AuQ}dq|CdH+#-RO}R~fDXev|&WZ)z&29x9;z zlMVXcwdlXsqCe>WKUws*81$cF&_C@2bN(MC{U?(B90m2qfZvq=6$bsM8T3D7(Z7xK zr>lQQfPo-3RR7-1kbkL#e=qUh$r-0OnE&g5-<1D#l>ZLm!}34VkpDAbfHm2FD=i$H zo<{$vz;Dt&Y=>r)^>36x|7{lin@E2_8vTE<@V`p@!S)mM-=8h^7aHs@G}wRsNoN1; zA^k_9b43X1p9uUW|HXG`raI!s@+&sz|B*$1-f5bDywHu8LH+ogWzxUlPnuDVza<9! z=S0okEHy|^2a@ug7dFg1?K$kB>m~? z-wfb4>7Q%Rf4)Kg2NwOG9jP;(uKeG#=wCtlW%-vG^f$mf0pL*oUz(x*g}`sh|2l*I z$p-x&SoF`zQ2%=t{hJK>ryBG(k1*%If%FIKKl)0B-4^~YX2{GSvSSi~e~A z{TCbb9|kXIP5IxHq5eGJH|4*>pntAG|0;|Amr4K0Y0Cc=i~iLH{g)Z^|J$PfAEcj# zVb_Xa{riVS|9a9d$A8?@Fpng0y=Xqu?ElY#TnzW?$o(7Ce>L!%{J)*_^Yb^>zpD)T zhrk3A;L!N{4CznT{u37dUlM=1_H!BVo9ut#ZJlNI6WU*Gu>V<${=a0X|4EDf9R~e1 z2K^&Pnf;do<${6C&^PcGeJ#Vuz;DX`UW5LmLI3R*{b!Q?iBcI{2ld}-(Vzd0W|Z}J zp+WyqFhHWr;QC=L=}%XG+ARF78S-zo@Gm9)$$|U_+s`w=Z}NW`$a}?zZiVrI`*Z*b2 zPtyRGD^N|HJm5FkUuv-bdV~ElEc$<7@qbW%+@inEp#O^o{oTNieRRalp}yEo`q|%{ z%=a9xVEs%$@mkW)<%H$8)S&-9%73u_>`0@Z)!oJV1CH5X(2x7iv)yc059#N6#&UO( z{^0sKh){v!7m1(wIL?J}#T1y2)7~KdfcZ`y@z47VQ|g%QXY>`|SM`qpieI4omto;T zK>y?Z^~}%tM|*<0k-n}B{{mmBj=O-+)PD_zM_{pYfdy2?UikfQuVVa3w_JGYMgVXh>qR!Jt1R7_eEl zt0_vwciO5=t&jM^fC7sk8*SD2PJPDrT|+gswx-sS|M#4kxjTFJE&^>o|Nj50%ia0T z%$YN1&YU^(xRa&sq8TGcjBu#WD92A66zWy%3k2*?PgOsv8+~WXc?d6&oF&UkCYPQxkx)HVJDgTiJ!fL>X*F|C zsj04QYCfeof8r?di#*mja*PWv3k z9?p)`OFPDlPMhl4Z;WHqnDmijMvwGNOJCqPt8j(4W#18w7Kh`8vw9A2IH$Sy7@6`! z z4aXvUoAJE{-)r%`4&N4h)n^%gTrUHycrM5H1{rRX&l~0Q=Xl9ZBz2)-{;Kz{y+=S%YUD|o(!?;H5ODY3WYvrj(%B%kl% z`5wOS{qs-&a4D_1)4dzq@Af#5>bm&kS5Q`!{EM z9(v@G6PGOB=k?9mM_)XtCF_|%_x<00J>}x5%eMLM3EgtvpU-`D{eJuOyj)he=jZQ) zuF6p~oKDy7{5h;>ckY`DeWH{x=_1uUm1% z`}@0|ndW|T+whAU)8b@I!buX}n)+o-%t51shK3D5rC^U5iQKf1cP|NEh#zN^X( zyD4SQiC^#k(&oKxemZ5tJ*=&j+sFZ|;_4|wv@&mRcg^632gdV>cRp8eMQ*H4^(%W;dd#_b>WzIf0K z-aMbB?+I`W*$K6b8{c~|8xZ|^_tzO9>Y zdpzsckH7G*I~HGYbmQ3{eEIAfXO&Mp^WY~hy<~6KGkGhgEDwfmJo&008ap1@vhn?E z|G8}KhZp?f?-N5eR9!Nv@u0OIx2&D{#Q7PAPFc1seeKJe^M3pD6(d(4=JiF-ef7}q z*L-(g$4jK5wx61P9gh8MVop8D9)ARe2w4(7FO0HJ|8NregHHSOPr_i?@iTF>J-+Qk zd;AoaJ-%cgd;C7wX}fX<0ovhz-rFAEaH>7NZxZ}3FpzfiPd&vR_a~9Vv^B>00#`rRVv`Mx&o`)v|Bt4^~oH)Ah*+=cW9+R(4gwNL+K zlJ?qnf_?f^lgMYkB>i{H9`nFE zBzF6JaOh0n(&6}JlKxeZB>i1U?BRXK*w^>UByz4v(!P_S5Jx%oaeVx&U>5Ere+KYl zJS<%IaY9=ZekqI|rLU(66+Xv_hhrFYD1G)xB7LU9k$}=4GAMur62JU-frn+eBA3H) zI^<7uT278HcMkf|c$%%>3s>7fB!$kT_OZt6)Q@OdAozo}C|2iCLhmc+!>S&oD z=%-5jK*?t_O&0N4DjtrHz$ca4b(5fTsKk%R7W7>U1U^UN!?1hAf7?-le!j$?hd_uQ z|AivGn#X<)yGQsrkBWq8GW}0Z5am`}C(@JN)2CU=IaSgxU=;Iq*)Ct5Dbg28{5GT~ z`Zo*+K(*Ia$eHk(PX!Kh!Jjp#Ak{Zp%K2c4p9jV$eT#+9{o&_OebbK-^;PX&j($gS z?vQd$7i>BD_YmpBM~n0xNq@?Ck-pv1E;UY3?gOI)0a?7`XtX2obHwL@0QEQeJT2>+ z`BxEsQ3QD~g8sbk1RZok{=6sYU-y*=UnTJr&>?=T`gVqF z7pq=Xp+VCfhd4a4zLJdNLDrvihw~P}IJ!B1-i1C8{fA^bo;Fh8E6^?^|12qgrB|oP zdM%K8;uOgpS4+L>wdnJp>_)t&T0viuahwOa?dRCr(L;-G+NX%+lkTXO{X*%2K9 zWqK6HpL?NK++G$w=SjPlFLBk64nq4Unobl(HR6(bh7XI*2cJez}uL=u4SFrvc znxOyFowB_wa{Cl=Cb_j+=uAdK5dSwl%*8rP{f7Vv|E5~-uk85+;FIV$rTys;*&M~N zOO*b>bpm)@WOMw5?csrrGO2Iq{`^@a`OnS+W7_9HsSn%t6a>_|{84)g`e#K&Vl*p% zn&dcDFZuLIycK##{8;KbS9L$va8LGcr1A3JHjRytcbtA5_Dgc~XScxZr?5s9kz2{?dyWK#Bf6qXqqIC7nAl9#Q&C*^a8euaR=Neo!P- z<(}@c=ks!ze$;xAUhzK__Ll5MSFX@cs6BtypoihF0 z14O;@r-*tfIUGD*$TMt_=iacxBxf zuCKv2zq--yYnWX;y{4|#H@k994dTk@FRZIAZ}e9-_{+;hQu~A#&zv~Fu5NyfFJCc` zUtJ4wwUsrl+^G$|+R74tLv`(ZufM^SJDu4mtOZ?g;P%ce$u7_1L~if7GfVuF%FC;o zn_Vtf&Ya4|>ME2^SqrO5{4Q73g35++e?w)pzp=2&T~djE+-^tt#WT;fGT?F*`x+Z7 z=lhDP{l1*+vwi;J%EfbhT#mPnxpOa~oYssn&L>T6Y^blyJss+AC zV&aoZd<~1Lt9)A2jw_X2R5xE1H{Io?(({27`4;(VP<&POkL13vy1_T2u3=%Ne{#u{ z)%7!~eKm7M6XsOcxh77po9mlfSXCue`c;UY&hzB^8$ooo+VL&a7PMo0i9Y`bSuGxuA|XtE6nYysrzkp>vt+LTqNJb?= z&0%U>^C_-?SK}Y;#-Ej^vx}*tDP@IR+6BoF@gNo)yuB`+e*ll zkD+*WoxieX+G4-2v8Z}swcl;q_Y=CaYvNqryvn8;KL!Hn$l2;>(h=R2cVPpJ8U`Ym zjJdNauZA%bb|;}z#I;vWp4ncr>y)b?oelP#l9p(1?~^8nPF@e4rsE5CCN@! zjOeb9T{D8A_&4CufUf4X58lLHJ5Ebo_{={O=fsvvPi9^l(iOeg*z*q_L*D z8jkXhNH;c#sA(iGWXH)Z`j|6;yT0&Y#H>tM0eAK8Ip@3GU^%%wU!7214;Kv+shI0w zZ!F?0k!zxIX2{Pa$0gZtX)3#&m{eqrYx)9T)s^HhPpzG+D?9sB`gC^3dKB~bbMh_z zJ_y6zqxnW{Q@wj3W<%aZJ0@nGzJtrS>HAC!l5nJ;1OEl{ab9i7f+qi5%o}GlVeSEL z&t2pe_QJ-mH@o3~$sN)hIJ_(@#jBnv;46PqdXkX+Or&K$2*2awck>g*+4* z7nEzVo85&S8mkW#r`tK%-pYnXA6Z+rftCT*W}n)TV*TwX@d2wm?@NjeoN%=bKaPE9{t!wI5BD{0()BW2-VrW|IGbp?|Xd*rYeG z-S`im6svvn8|tf0I*Hf%s7ARIc1-}qMZN}_ZTOn~u6%TOIg>TjZ}-%uB%jAzF2xkq zbp+(3SY}=QY*xys2=;A|aKDlAPO(MK8Dy>~ml`DMXfk zHUw8xJ*T0vVKJ%ud|xee5z7#MQ>~3sRWWh&8C$C6*%dHGz`o%v#!&qx=U^u{?5BYkV{* zJ-^A<v313Du!qgVlTCW+tT7+nhQP zH3)i2`K&ouPxoQbMzn7>EFUI2-6>@YXLvB}Ic`?ljeb_bdUDZ@sQ-~ERNVt0<)jm9ZPyTQ4G3h-o{n^c;to6PC;P0N*2Ejr|Dhf`vFfUFf2CYDP$P|1?s~UQXp~q3Bt%Iy zQG-cBJZJrpfiNdF5X#=KHj{L&bWEs+LbUN#_2>Vf70HJ(!!|&bz32-QR0-v^7@yf% zkU_K>>>aru<_M%bq-jmnHQ4!dO@xP3M7y80v_o0f;OB*bU0(|!^Vo>}N%Yowe*@g1 zauN;c{Oy_C=}}!WpWpfhkp< zOZipgx|Fk*Sl7Vqks#+C46W9*E*@Kj6HMD1^ROHotBY0LFdGqj?PU6~b4%+)<*LH5 zYzk2Wf*78qb1zj_EznyTQr&=@NvrQ~%Gkme{9>NvSckHtmHY2F54rQIYv;OWNe5jr zW9OE}BxR|HYXVCLOC8V$bY?ksiytR+Zz#?K&dHq*MQQNiAD#!mkuFr*Q;fL*=051+FFG?oj30IDM4w$aGD(UkTo->Qqbm8?Z(%luD>Zql2 z12r+9&kGWmRAS~L_iP#v39ZEs^S_yQNWXaF6=@80rsy=7mI@0pm&eLpqjcuDt z2TRQG)F5unoXj`0W$S;)qxYUG%>cQL=!-{`K;ELaPotQm(#hi!dWvGEpnfOK0XUDA?5RGD(9mcQ(w;JdEB|8 z+(}+KlQyks-aKCeEyVd6CevQjbeh;`(-fDUj+Z|{%g&vNMLeEp>TY8aDp2~}+r!(%s)?HAmd_}i zDJo|tSkcx=DkmaU11BnqXy1v`;Nz9ni{*G3e65Sbg=S+CD_@toI`%h1v9bqKx-0}bE+4);1WRTD{0h^|&;!qQx_mo~ui9ctuIVqH@O_)Z&Zq2Ezp@XG!Xx?b9Z}Gg5S5dIqJgbBa z)UI&jZ6|}sjB^^w^c`5qBCZd)RoYVM)~~a=5owJ8tZ832q(Z6Wz%?q zb9B3U&Na7@P6WW6Webcg%ev;piQ>;eQ#4lphg!guQ$Cely9L#-+ZYSIRoddY-s(B7 z^72Is?aGB>RF>Ccak_j_b%P(vfmHonuRRrhu37rr8gYPX*Xf`M&tr9BzUE*qR$Gn} zkyW%O2AzWRaALad>hc<2?R@_NEJ5JdpV;8WS|_xz#;!YI!jh~fO@yj(QOIi+v>WwD zQxs!Tg2Og+Uab%;Vep+z{xfksudd;0oIf>vYg%~{70Oc;nuAl|YF`A5)YQ<#Xm|9G zTz)>A%mjA51<;bQPDCfT0T3yO5M4q@pO^)Ubyc#A_^u{1?1mJD7A;gtj3OZ)c3(&$ z;?(=@XeSn^O3*s>IAo6%AoTw#G!U#PiFnr~l-qc9Wj%CCTD@Ji6w_U#AB)^>){j_a z>ur@+oT5+8CJza0>_G|YHgz{^<#Le*SK_c7%%C`Vyz8RLtD?iwtS`HxyLo&HS7aBX zi5!D>os;P~c0x`r#-yV#bW&KP-BA@a>g>jNGEtZ~7DnyWG*i&+U*lq|h%OZN53VPh zum-Hw!8VG%3WINUoZVA%beiJwMxS5WT2_g;F}u1JudLAO9UVKj8_NYJ*c6dAyKX*Q z8O>zxMr)YX&5J`#<#QL;RxSk1s>(*%3ubo;tXRA$JM&*P8*WryxfnWjM^$tG9UD8D zx*8lhKhE1N&~b&8=>%r!7TcpmVVu#e3qrL5&)lUOuS#cL$F}JWH*@i$QW` zT3UNG77fd3Q*NP;BCEt?7DHui)xvr-BfL@Cjhu%C1_w|mzSL+4s2RKb3w;YkLh@Cx zCcv9~NJ6ya`%epTblXwxqeel*9JsfQw7dwYcCO>>>C?+6oSN-8yQpy5^zxijb8y!W z|1K*7o_ngx<(OVpHg#HIx$D#k@iDo2Q2%{u4&Dc(k9>Vk1aRZwDEW(SKcsis@Y)*g zMI4DQ{ikBplX6qsp7?hp(vHHv4h{)iP$#M)2gQptDm~>CTu^@crNRi{Ll}JoCHh5_ z_GDa-6TeeAmN*hQ1+7tz5jOwP{g2816Qv|ikvt}z;*QeoC@!9gT_{;@!mV)txTas` ziu)>^2z!rPj5mr?9oObjtcc$ezv(?&C%#RGRPRMC-)hFAb@8&QdJng9=r#yeu;Bd?Z?@olS%SY73;xlJE!7n{S;2joxrhGrS%YrwbAo%IF;Ni_eK4A;~rNnzIc)FBlp9Qaw z^!qKice3Equ;4dJe9(elF5h=`jE`^M{u5=`f_F(e=@$GQiDz2y{7s_1Sr)uq@}F(N z-`ZR7pKrmPvKZ55cO)a;D=2Wc)JDPCh-mn9+v!cTJS>-6m+^Q_-u)HTkv_)Mf$J>&p%7xJr?{B zx4`=>xJT+qzXg9VL!>t>__q=twBRR8`a>2xeTJapknd9~`!n)vfu~z=^WGv0uI?pq zT5xrrPL>5%_p@YMaCM(Tz6DqJ$P`#`bq|8qf~$Kd$}G6LzoWu}t9zR2Ex5YxrrCn4 zdum!NxO&gO-GZxoSXNtbb_5&AP^!LOINL*6T*^zFV1sc*-|+sQt8Pei5#f8aJ@Pn;Hf zo5Zs%_#fpx6!{kXQ;8Q?aCOg=$AYVSWV{x9VmF<{r!Tl1?wBV|JofcfRZ!U@?USk?+S_Z%@$m>Z;J(gWTi;oX2CPt z1>Rx7FPHW0wBV|JyDa#bs|1~}1@D*lQuSJJbzfV*1@DmexD8qGu*5UvJtwN&d*%4( zwctY%ueabW(r;XtU&){a zSN9@0q(83Ypzb*;u;5wpev<_jT-~45VZqhCU_BPRARz2>uLbXy^!qJ%Sf(Ge;Hq4Q z^s^NIL+TzD3$E^eaawS7Pgb@Cua|TREO?8=y%t>EDS}eHIpLPqb^r6FoS4e)kEVzHCx5YJJGcf3{|?>L3gC$xnh8B*7OX z!JCudElKdsBzUIQUOJ!7BzRU5JUaTuL+ z_&yrmtl?=I-lE~EuTylJhVQGTZ`W{jmo7!G*6<81eTRnQN@DZVso}UX+x&ECc&3S> zpK7?eGo7Nt8h*HzzDL7xHL&^V)$k)t6n0O;$7^`Mh6@c7k%opJt)(B-@MAQ5NW+iS zaEB|Vx5sICs)ir0;prN#?rx^&Obs{h+6L~_@KZE8SsH$-hG%Q|X&Rod;n^BqpyBeU z4aa&kJV#6K)$j=#UZ&x>8eXB{c^bYz!zXHZy@pTH@MaC4tl=#he!7OYY4{l$-mc+i zYWQjmpQ7O%8vYXv@6_<0YIv817if65hELV-u!c|9@E#36OT&9L+^yk#8a_kA`!)P* z4L3BrP{Ri`{2UD*((rRN+#%=JWIKyAJXOPsH9TFzXKHw+hM%Y5P7U{Jc$S8rui@Dm zK1;*%HM~T_3p9MThI=%;RKvX*eu0LUY50X2UZLS-8oofoFVgUO4ZlRgn>GAW4R6u# z%Qd`B!^<_iUBl;S_-YNW((n!qpR3`W8t&8ZE)8Fx;oTZut>Iw}ze2-%H2g{p@73@c z4e!(Nt2De{!y7c*(C|hL_q1+H^#oJKJvrXtSrPV+9PahBZb{wj7|uHi(D1Rx;NP?( z3-F7=T*GMpFh0i~LSb@UqP-m6kHX}#M8g~&L*Y>r?&9!B3X|&+?cnhDPasS#OSGNC z-%yxbm1qlxzoamAvuHhsKc+CbCeaEGze8biNupj3zeZtlMWO{9ev!iDf<&`9{2YbH zQrOAibrdF7B%03Q$0L#w1vZ0P?%heXg!DLP?%hdXa$Ea zrZ7zbPAIT5>4lD4u#3}h&niYB8AE2 zhz|aX>VFi4ofPip@F5f?*CX1?;r%E~&OtQH;V~2@S0mcR;gJ+37bDui;qMY$yJDUaQGSulZy~-=Wqjs$u)?!aQF%elS>e-=kOc~)6_Rw!QqQ3 zOs+xH%i&oRCYK;uz~OT!Os+sQo5Ry6OfEpw$>Gx}OhbP(ox?d4rXfG-;P8nQrlCGM z_)l(s3KvkgpTmbxn1=RfFNgP|@H7gCIXs5KG{i@{I6RWVG_*%MIQ;!%2-A=rZRhYe z6sDm(+QQ*4DNI9nw4TEsQ`ke{3J$+R;X(>~Is6)h&!KPuhhL;H4c*af4nId>8nUBK z4zHsy4b{p47!!Zf5tD>!^Hg=r{_ zdO19c!WUDxfWzNBJl-*{9bx{s{#+P%^>R<(V^8a+gWlOip_GgNffc>bxKD=YG3CoY zIUK_o+mYwnv?I|u(B zX`a?82O$GE13zOu!6{dCjdvL1&_ad>|7=Y;9O*_7J1xZ6UpIp!>O;vdi_Sv|`n7HZ zqEPhqhqx|HDeEY0+M4Gs+f30I6w^I{C8%=Kpz%lKSrJZK6iSS z5o0SX#Xw3oQVhSqIj5FRon3*9WIKHqt-F>F8CEW-Cc0;O;95`ud6j zpKo-cVB^+fz)oPZXT`hzR8QbT<0y=yD5j6fNP|r>_5v_)aADwiWT6C2$WRn8DE`;r z0b_RNB~ve*dYRx~=i<_ME}n#LgNwuMxY)BGGey zA0BQO*^SRIvTpcXM4k>-jT9;=l($Y0O(W=Wu&#)P@}3tlPZ6a8QCvHzC{plKC|h8O zfresr7zcHMJc>FX4~EkD(Hc(OK!T(C&Y=dOxYlqch0nyO25wJ4w=#+`Vk%OPplt?D zB)N#hP|b+(R}6_N!5^R$Qci~nfoEQ#@l}RC)QLXSf%JGrjH@VpD5L9M<_!?>)(JLZ zyloZb6Ue-Eh~hduAus$?cLyc*1WFBbp?-w>sVm`$wsQC4iLaxze?;rhh_qX&!(JxS z^x)ZpG+{i^=I(Ah@r|WTTN8#+6TN(2kvL-f9s>6So*PIteorC`JckIB%w7K(#b~H3 z-S`9i6i;9)^-SMU_(_bSzI#$z;CU}pz@$D4v8WDmt>RppICZc97Uwxn;ANtbf(Rve z77r1*hKNZ)&SG{@>4@@IBltL!w#m zh!`{+qs$>8^@#CzYCtxB5#wbD0D8?@Xi|}Jzb37fzo(({LjB`)l{mWv{+^WEC&@Sq zG=0mYLf*`v`&$z7+r}LDfvRkyio0ma6|m*fe21o7_8@e58B!U)0-Ksn=0h?)5%)Ik z3#1do#@HAekO9@ON7Q(ybPR(K>0!ih!uurQ=A$X7k5YY`QC=JRKnoJJK=Jw`?)R3W z@QAxlve54dQa8Y(Ak{PZxwMsGsf){Jq5p{(3{ChyEOZ?yDZD&<-DMH?8$`^K=spT> zKxS6H1K`8AE_v^|t5bvS`zE{JYuK}!qA+X`18wf7J)u&3-SdRO-ONsVEwz^@x84>OVjR^wevSe+`YqaFB4L3>fbX! z9gXsfyd!#B!z}@K2Z6%0LfBI`OtI^1>Fw?+}qODxVu^hM=TGgt@sV9 z9dvI4H}_)bB%`z9Rso$kCT&HV5DHp9VjK$95cZ=*5?z8EvZ2XRrLFivOaAf+lpOu- zTd+swmx**s)BzMD-)DbuIM{Cqd_ZZh`DS=nC%Bx-kFLT$?E@p)TbFEe_?I#zwxH1P z-LZ(bvqgJuAWh_s821PuSiB8L3z@Ho(F^`GPMY>d`OzQHOWTF!?L`c+_Mx*h>vqe7 z-qMZU(iQ8W2u6$z=*jfF0L^6@(khh5u^lqD=dV&)jNT~G*B}>2>*+yAixgi-tB5Gc z{1u#%>~NQ`!5b-^ar@UYi4Yj{k-E7YZnU8T!%VtyEzCZC#PuzNuQcX}h?!iNpd<#W zfTamEic)y&a_)nSy;S!jV0#C~8slNB22zYe$Ycde!7z_TFM(GwJsw?}Wh70w+kw)~ zHusYjkzUDzLc|y~sEKqwbBV%=Wo#3K#|p?Iog~qvB)rhLxnIYL^dCxI$Ulx#l1R~s zXjl^>{c1e5BQTQu&WQCGWUvuyow2uw`1i#cA)_$XcoE$ZV%lBQTIlm0yU37s6A%(pvv86?>kHT?(eigv*>ml;btn-GKYs zU@48t-9k*oWRTZRLl1+?v2g%Xq)`+F z$`^shXMiKZ-2tcggg*=XD&jrx9MCUhvn++CEq@oYKep`=<7P?`bhi_gi@7tCbGyWF zG|_}@wTR*dz5mZ}^(O$NW&(E%LSl}ABMJjsbed;?W>KJ@NEQ(J)-4s7VM$MdYPf70 zO|CtG^$W<^2|PuslA@Zy74+M4#tMpQD)xj{)Z@q6^F^Ki@TFE~A8I1&%!yF#9QYNV7zxZ00OKHJb(U@=V+q(rN@&v8M*Ll#AI*D3|`7U$STiJ+F`Btv&B&T#gX9E#Q&FIr0%#f^}TY_Oa0v)!|73pEfonsrhS7KfmXgZ}aS3%tDdH}Dca zxp&dzeuSL5nI0~d1dwOYbB22;miwN>+;7I^#$p1GeNumHsaY2nQb;XT`N=d+lbZU8 z+U$dtfP{<*kQKLxQj2s?;Ia-hHB`T}y(r*oL!GIE0^@r_OMY{rtgGEX<2-N*xtCqIA(sZKqwZf;5Ykr+D6rcyXW41@%L zcreQ~I~a@XNwv|qpL=l1Lp&$Wco+|9MU&3(Pl5%8?Ob^?PuEaNIv0jMzX2Kp;YW-X z>OW%Ao=M@0os?zD{JSwLx{`E)xr-RKGyHuiu}lyJ?{bEJI`vj<=18-fGT8V|eTIKC zr4MEN{U+uOQN$ZhVNKpX73CAiyluezgcJS0F~fg>$44?=FR;ncXZU|ojM5Y_dJqYM zXZWqycI34olnj1k48ko41YBdV~;6f)H6GM zM0*o@#*fVK&y8{S8P@2M&G5@Z+$=*onBgBFctDbfu?+%Hvux91+05`OQ2Ast{KsH9 zq})b8Znm7+&G1_?V`Ur5wvlZ}S$&r_!@u(m=<>ZtWn@ECKQ_ZZF~-KTVpX#T`j?7s z-VcfQn!+OEy;Yap=y56ti{*=Lt$_#Z%HEi?R2KH7;H z{x{UscRa&ikFDDs&G1{H8p8Q$Q6n01Xw%^M8U9309x)F1OrPO9C3?iCQ25Ze^FEH7 z;jjKUZeE@CUzy=Q%@$3Y;Xf;YxEcOe;7_aCe_)1x+`%Nih~YpUn#jPd=NNX;4k zQ!@4z2ro9nzgMDnlkh_0Uj8snqz4ftDbglRNg~B49~0?V8XR|JhCdDF*hZ{%#t9`AJqa`yfcGyH~h+xjdpE)o%Xed5O)r7oJ{S=EI7 zfecZfOi`bGsXpig|D?9jX83QivmG&x{s6f0Ow1Yn(=zsMFlC+L55n&L`!oF9k)RyP zc>i5(wtF>r)Mxl-zb|;dnRtg1#b)?-L)-P)_`^c;+Nq{nxHBi4;ctF_XJ_~qfu@`= zUQXoy{TcprQRnD8TAf=_6Uz+W`<|%wYBE1uZ8gJx0F7mt;Xgr%lFf_yp}Ie+MCe`r z-VFaf7C1S{_mS@ej$fLAk$us(fTL)P1n%Cg z?pNSpx?e#{z}qOr*44%q-^LLlZvoa-k*JG(2wDaS5OO*(m5Pf z+*UemZzW1+R7^Sti)d3i8>yu<>6|8bOq5P15=!a3i3UdlkaWgC*wWf)2oJS_7p!!+OcCkY4VK!T`LD6f`h{wWjNL=|hnDiU5u z3HQNpFBdsC5DBqUvwC=VSnj6FgHTY3!FWWTQW0zfOMigL9p5XG083l%{-Jg7Nc=Bz z$wO6gwvP=2;ejop&LevSvXSvdm6k3#IEef`Ej-!`wxw@c_`{x_R`=kDfsYWOP-2Sw zm)N?hGq7YE_GDXoMnKW8LM;OBAHZ9ncT@i;+DIcwa${5JnV=vs&=7Ne0^1l|92j9l_G zQR_Av8njI^*hE>8tymBiS?S75QI4`8CI?(PGQ_yv0c~1nmUP*C(GJYOfs!)EiI&NH zjad~ZJd_lIYOTdw5mKXVP;kD#;G9Ir)GNpiF@K8d*g23uQ$M1>3uW#1lY5FlCK;4; z>I26?SoGXZLX(S+wrlyKY;28)g2>2y|3)JB@%pP0L*6(oB;v%;xn#*%e z@s^pQ2PwLttr!z%A{;TEF{1#xJI`vn{|J$}11UNv#qDN_PNY~(+Xfh+R?|UDx#4y- zQov-1L8l2S1DhvLDMorJ)E7NUC~i9u^q2%e%-y!t{WGvHHv@#@fJ8?#&F3+;{S4aF zh6J>O*0!P!|F+yu|H?t`5<2@6kUr$93SvH}HqyplBaB@!(zL9nOb*)E5Ya)ASg7cu z;FE^Eqs`b5lL}?bVTYFoztcq`)4ccN7@;)p`xXVhA~k*c6|Qfhh2M&_YW#yLOADX% zs%hchCq)mg66!WmcYc*7{2nRfaL`4Gmu(>x)yGRdctS&@###OA{xJL}*I$atx10 zr<$wFY;8jsE8FRKj`Jhq=6jXmncWXfS-mTC2l+b|A_d@ce1Hb zn-Qk8#E6J;NPpZz5%;$waSZw!$n8P4(~ym;;T{Sqmk6UAX}#P-P$dJ7wP{PDTs`($gLpj0u2=ND70PFca?(qssdv=Ox|-gIIj|0UnS8hf$>; zLHiFV8m1gIkI~eGvegqz+4nkO?|$`SERh{3r4r%^H1&#_qC75>bP8YA4$_d=My|dxMw_wB z;6L{y^ChNg4B#Sl0ubNJw&`u70NSS2;XhMutF_!V0chp^9Nj6QT&Ylk{hg~TEf#at z(on>J*)#`nfe~Z!cC+n`D0+~!pUcdrk}V8n)YZo-yCQ%M!Kd7jMp3o@hM#T6Q9;PLh z_>lX{^fr@>jagYX8ljW}xj@~5i1MCIq^Om5PhzZAUOQxzP+sCG>DDl$7cn|;R#K#n zdBtR)XwSLnA7sXONDU&Ho&PJ!Wl9(9fYM1ZN>eSAAQNpyMw6a6UJXA6DKxn*Bh|_) z;ZfLW!v<J8c~1MMS2YV=W49#kKbaMOd4 z8_b&-O6Lj(=!j8Z9GHOV`TY6tK6 z;H@MMq=}IJ@KFIe&dQoc<5=7nV$RMj{?&arDqt_4P8|KS_B7EL5NgC&W9ko-5Az-l z^1L?9lJApNj7PSY3<)Gty$vfIk}^P87QjR2D!K3*@CHLGYatp z<-^|JAmvAvh!NzpQu!IFWZi}m2q)9*Qd;?t+iq(dNFl#dq%r zL24p2AN1Q1iLbi@3i&swL@q?NEVB<_DCZMg@*y8yHq^4Bbv>hq$H;i}SARwoF22CPU2yXzBQ++Kol!85D z1;m?m)Cq1}h+Ni)aVNJIoX?b{OdWL!x&KKqk5QusC}yFGA$$qA3qC?ED6~hkFx* zg-8gB{+H9yol2psMyy@HQrTZkQG?C6sFOA(joL1zmP}E-$(wr>B!^MQ`X(%v9=KYxf>Smip=+Ob$T)>mM; zLP%oFf*{p4=>BSg$kU(;5i_uF9JC0KIXajm(vp%mHIW1@Dxy_bLgF;OlSeGMgtD;! zs$jeTk6n0QP+Rsg^GHM3a`C`-&QEDwST50Ai_~(7hWkGyYu)1HWg0Fg=D%t#&Zc}& z3}tMuK}`S?^%#P}2Oz=cN)cP?dwC5jkVpf^dE+T=f9my#z?+*>4! zbwB)Z@Bs5AX_o$k=tP)ou&D=&O19QK#j%UbPxR2%Tw$t0j36za>AJ6dTuAn*#Q7A-N3a+}A51(P z{i$m)O~48W#5)0%VG2l#*W^TKTH4{*JQLw3dDxD5>OkGbzivk}N1qPt=MS(9dOZ5a^A(i`{ zsAFOgcpY*>>+y(KhMrOs@`X2MBcD-^5k%-D$UZ06!lOu17HP#u>JNTy-SJ+vH#+=2tIZ8RHE;v|}gQ zu>*R&8j`{~GTw(KE<)xD{`FX+Cb)v65#kMt?hQEm!C)yl;PM6iBiB*_L8Ao4#l5{h z5|K&{T#5@RWFNobS^Okvv~F3TrV+Y=umk`$(#TUg(oSP1#)+YC!61+1z5S{GC@ zV$4N^9LB0Cjb*1HT}hw(o7QlJ?&eVT3E)_*l*Ri_wjqdvoOxP!!;6|vuN}Zaf64Df(*v%rKb+9aA{Sbt;{_LchlKT?i zW%nVdBRk#LOksx`#+XOpQD{NtP?CB5X|qL@yUG5NX10T+pE4;m&cgyRsqQD46v0^_ z*(>2+0UkIaHi)MZw%YAN}kLyBFrBB3h3n4}83Ip_(p>=5fsO=xq~d%2rZFCC?^2Ikh5M3d1H1m!fq1hLbS)xyCU9#Qbz`{1UzkO>s!wXeO2_;vFy?D4Pee zJaB`}jn*aKIu`Eb9u^Bu46Gduc-e$LZ<3DqYCC zm&mEd7Nm0%kS|tCySShjJDMwth@5ZE?3mPK?jqm3XTj0l@ z1`AzQP4zKz%9*jAGpDRkG`ej0NUW9WlkqZ(^~rwXNOU*|hdO<~Fck<8I8o0qoWG}` z29!PTdz8q&C{L3w759O3Q)ZL^V-_)L1=a`ag)dDpxSCf1CgOjfWw4O@b4ogb_~#@M zqmi=7t)PRb6n5v48xuz@>dSvn)K(Dx9EE~&F_VfID@ZJo?qvLq-bV#R+y*Lx-rzm7NN;xARa(eiQqX&A*HFYLy?VHi}*+T1S5OfLINLTxn#*l|8th#mP905stms z>q5+Ejw!H-8Obp%i7_p0;DsX{_#yXn_QJ3o8%skOOH0R7my5IW%APYEe;z3F_tu$o z4{THz!!DT`{Eirr<4J>QXOeBiBFJAbAvgppQ0N2D!)VQbhMTbHQB7mG#?jN+2uyjo zoES@q@PiDHM|gus4Vl~6g}~Nf=miF^m}y~t&S!q$c}V^)5n*Kpd!-q?959)|KITt2 zDyumu-T+BriUQO+{hrWaBcVd=(m(wI=VSo4BiCwA0E-h({nY70%U<2w>;vqImGjqtq|{rb{(RrFjMsTSk%o zLK9vg8tP<88V1%MC^57o713e*?vi?THJv16 z4MZVWQjrT$zkGlQ38F9l7Pe2nMshJC;})VikwO~7f5B8qbEmeel zlJN#A*N?8>he!i1io9~{ULkFuVCo#o+2;wQQlB+P@zH|uej3w->p5h$k`aVdP#Ot` zEKtN;J~BM9xhokC3eyuUTlZ;)dN6B^y~1kSumQiWP#flPdVU0%e+02NtTC_Z8?_V*S*JhrFXvN3%|`9-(Ax zBBsqk zSk$kfbg&$3F))1KR6cgYMWiqu{bF1ZHWG1^9A#&rFmz4!L2^ae2u6%%l&#uI*(mf* zY{>*ldyuzJHAdQs&xACAs&3qqq#I)}MtJzsNmIz$bpmtkD1K*laHDokI1a6J>2Gpey@B=R(Pqk@+_ zh-w*mTOpDGhrpGhk#fv3`Wfn^1Ul$fIIzDta3 zAisPhyY!LVrB#M3nx*1hEEUctIo}!{Kh?kIi zBMH^}E42+{Qe)~+PsK_$tzU{j$cq79m1;>>kUxL}%x3wt)EUYhnLN2hwl(a6=56$Z zmbAy_s11jbS~9(0z0(s4IZ0?CoMH;CC}1&0j9Fihq!mL@uT>(3o8fp~a5mFEL`GhU z;laDiEhU!1J9lezGLed1%Uo_^MICRh;bQz)X_*6i;*?<9JtRxo_ACzbu*jKY>kEeK^M~uRhwIS^<$AZq1Mzec ze6By8&s1LHN6f;8goYJn#yYjAj@-L4l`LZ1b|<`*YTAO9GP;3)Q2^xL8w=_&RDkxT zj}_|zsAI&qj1vlg<@R$VlFqW!Va(W&Nczh!K|W|i-(c)~iRt|*?}+y=*i^!r(Ha^a zw5Y1qpp{Rd#t3vG)4N70^mwd|#UsI%(J*xJSlXHvn&N9Sd!9;bVVc7PO1BA;yqHQq zgQeTV(KRyl)?Gj+j592b$QR%@lE6-4-hL9^=z~ei)3JIAD}uv^c%PJaYp}BsGj)1x zLmBsXmk>WnHn;D`pCy`uOcyT~UrX z2OWZ$hIufTm*{daB~>ZAz+fBR5e{W6ni9wSR?MPWuuJB@9E&O|&qEweqMhOiPMJ58 z(xsI1Ln-N6+Fl2d#dpvn??F6hPM>iRWeldw;)hDi?|YGeP=>k-Qj^7>&x~UPMm-g# z`~r~KTVvzHVy4{34@G$`pY{r6d~-XqakOINHNo>AOrA5TW6^7832h;zyFiof?9~a< z4P_j!bD43z;N~2Yn|$uMwBr*$_ahw`3);!b{iRm!d$*}_#W@3NSc9j~81gsplnvDA zFCjtlx1GUKLp%=s9J{HArL&G7BpoNcf*j2Foxp!>;w%VyeUN$|68-7qd3WP=M@dO)S9E%5wsJ()vVeuz4h<}>Klo~kP2;X28 zu8;T-yoUip9mUF_G^?S~4?W^&8Dg=$$BPku((vV?&?RP}D9N!l2UUigPg~8ZwEz#& zaFCts4s*6*k!?nNwh1EJ&~2P;HfK}JsXaSo&2iXIoc+`+9L0q)s(;F@8)y4O%y~93 zJFtpvtCUWmMTqj-rzfMl-X>-TluwPL+)WB3#}nZRwv&a3yIC0HId?PY)4rtkxc@Vs zn28;i7Qak0s)9W7sC2Z>0ty@72L*Za4ub#piChzDnvU-9cp?v!07G_}JxE*8arTKGK%IPIZyq(jMrg!V`jeh4NncB~=sqF%Sn}K>Tv{2HXh2 z`1yiQu6W4nmCOx)GE@oSRb> zVkzBA6qSG@#*_a-Q1sf_kyPRZlb9t(0UrrnBaq`4y-eF%rc5SEaVydfRKBs z#^k@i3bt<2T(Ma0bY=%(R5lB|B(sY3npND2x|$~^oUFy4IziH`hy-7A8Nb zT;0|%q(#0SWK%%IpY*sGuVhI!+=@<`;GHfpg0M$T}5yM!uN z=;lV5#t*Zd=Zng{w~{MYiaHMW(#0%QG=M<)z2+GQc`iX7)~DWMj#lu|njlNuo@wa$?i{=!hsg6A7r$G4m$Mq>Pf{o?GM?AL7jy#Fb?TYaDO^*Kig&{6E*gzm2%SC z6L7G)SIih_)g>RDtPg{CZ=m##fnp53v_2m(o~8}_P{s{xvk4-_?+YRgFB;%iPryru zI{MUPfqri-a8kGHB?@l~<3WN;XXid;FMg<6ubnCcS0w~@J08?Q#(grKrTiX0p!)rk zEGYhP$Oim|q2=>BBo;OcD2=Da*P%cZPU|HQ74huNRBjB{>0d*pK|JCY_$mJIjoANG z+7rsSWfGN7Ek{+ReOM>j16S~mD-@hfQ=G+hDcdP6QNfu9lxy+JMFF_?TC;sGhLr8I zU5oXI?Tx-*!B|}SGx@pyBgw9r#=?4(AEsnWNJ^oMy?#NDyiz>a^l(;I%RaVXtO;hT25_adB+Z~?+)2v<-(+2lmgqbw~2%Gi_= zSudH=Gq4|X14d60t(lhI4Mza281R-2T#JwqAj{a-=JgKL&<{Ecg35x$v>Et^-^a?^ zG?gp8jvvqvC)-TNx=bS9x}-nTlQtbIhrE7V+#%E@w&#kPl%OW=E)?92bwAXESCUPx zXsn=sm#tqPIw`gyN}*+B{mfKk{U}hTS-&j7*m%j9w0;XkYg~IXx5ijJL~Hzr#Hfc+ zi9KxnP!t?=W&QfdtUx25E?`M?@dJ|ZvLp~gtkq}IbGW`@xV~(--V3X58hf@GvA3#} z9WYGO6l+T;hipsQP@}dy!~H3n!_!6K6J+7Cw%3ZSAp`-w9wYMmJv?@K;Rw$j@%CK!KE-+X?3zKQ9sCO80JCihmObcV=ey{y@#oPe@R7%FI1v5Wb?Y18xTa|cQ9AFky5 zh|!#R!W9iPB%N`RnVPv}#{{RBtz#YrOt~(mY&+2kjVr-iW!+TP(!2|QPFgx8fQNDI z&tRn!&gVfE-}c6QSL!KfU~QXLz4^m0dhyr@wJ1vmYiRt4asQquftHm%G&<=gwG$f? zFX;$vt3p3;-VbG9q2Au($?VOc%1Z7H+W;3MOM$1&ok)#c}nhh(zTKx8qj0C1TOUvObt!A?xo7O+f zDMM*WTS$om~0YqK;X-%+M_+k*HmA6%`EJV`HEXg+d zCl`1PqEKKwU(&ugUrHV~?fMv_Wbn+YkbDNoZO5w$d(iIzK9geGcVKlPL&3=Ld(m|- zwtPIxQR;+^ZBcx*I>9c13kdGFNhl*0lV1ID!8?)CDt-I*Pt5zSOEKit!!8JlzjZHv0zX z0$Q>Uu13E|2pHFNg07lcaAs|-W%F`m(cb>C$fY(`dlh3Un5i*UNEB-=Cl5H1&Fc^a z3km(AFSqk}RfYfKI3XGm0Nayg1XAJ%%o&rl)x=Iwq;1@gP8UbdWYN5*V?-5w$YrS@ zlAx`KinThmM5Z~0QnkeN6i-Y~VUf>70sSQAH_dVp$K^uU+yF0#LMclsys=av0lc%4 zt@7T^dFkLOH_)pb6y94vUDfkBKr)({>QzfQUry4a!BKAy>jOz&_3mrO#@Z?_Kh<*q z>WQJMsU1qxF08t+O|O7XsI&ug5Y5odprh>mn}{A5FV+A%ND^BpJ+3H5qhdYvI{fYM zZBSR@U4KoKZN8~Z5GIU34vGM~2qe6%$1#z_Lm7ly`;e^oQu$Xk=BA36!>Z0>v#w;wqD(K!_Fui`2E3>zm1g2^P0Nf^Db+OR+exsW8BV z=VR%Wg-F5_f;^0_z?5Swky7uBvmncfn(&7Xp$<>-U$%w#kvgDStsAY@g@wmX@W$^1 z7X^w{E5blY`xrYV1>>C5t=3Vi#EKM(MAh@u8VZdM~8v|CCq~f885-@mKKv z7GsNnVa1Pb`%^j0@Va##E-l4m-D7 zhBDscNH1EMg9}hkn)$^IM^lNo(DGau3$hbgx{V8EevzByY$Ays4b?=th8}5TAGkjmjcUZ5t5iP z%4Ry|S#!-dgTz>cD~{e& zox`}8X^AmZQtOgI2VJ)=CKNocp;kc|J2n12aaO$kWH?t3jc)y6wGxvIaY^$=$L{>fJNiWCYHK!{UUnyk$}ITpGj}v zK!VjM(_&Y+XC#f0r`7lShC7?-J7k(hE_hkL`PT)=w$rS%10sl1#0xFl=#fLKP+&`WdI!=YuYg8SireP7-tkbFZos3t#?%5`WpF6ej|V1lef$XZ5*S<|Qbvq_tQ{VX@SlbN1xIAXXcSLYH?krXzwiSu zg0DzdKSQe=_~{9)aBRmz=;cd&Oi);!*j#756G@6>${;i02?~~i%pj&dIA6_lB8EZs zM;=5Et|C@Fp%6#5ZpxB&;ToErNX|p6oWzLW;J36;uTHV!)|W6dq-waBe6B%yZ+FZy zRG;XVs2}K%Sg0{Z!7mS>X9ytFhWGl26;U|WHic1oA;LsC6Aph9+pW*#OF#RMSh)lN z7OfeHmS!h>1hH+>y!;@2gAH}8oyp8*eA7TY=N$+BhI^l3_aUZa{x_Aph^r~xZ{uuF>KAmU8`ruwFUvceRxDIlg!gehJ8#d?xNAJNT* zRItiH9aqf)m8DA@F+O}2iD9Iq*JNw|UwDes^b_&*Sld98;s`Izx(XnnCOnIcb=1k# z<~tBMV-+v8P?*Lej1ZQo>kUL&u)P>99yfBRoAH)y<1PQddV|&PseXQ}>f=YK7Z2E= z9)5(v1VYRCK}}e|^Pg2Bk2sLp2Y&*8!;D(oH=bMka(4> ze$a*WgH$FtB|+u_os4-3GKa%-8BU6zzuig2=<6#hC@;zLA6P0|7iQVTEwK<}9JY!Q z@gFc7N1ni8X(Z!5YJ0Ra`I9D{$3UkLW+5d1*h~`-9w!iop@%EbO~B37%tlIma&E39 zZdww#A;`E12N5MVbSYRbmd|nZU{T=j#M(LShdzV;lg+||fymSUxKo0!wM`-jJ zBOF#GTGJj7E#Ci}VkDC_uX)zKhP#5#Uu9mCUpin878-r~(b44%lkzGI`JaF0Eq}Xm zW~mH6b+yu#FHy9XNpG`y7Ql{oLx+Ci%?*AJT3j(S`iG_?*qX zCCMCVp&MVG%(b8ERIdG8r%L+co?EiEJ~v%HzMeH%EZU55GNpix@@zq_^@#%ROn3Ip z1BEnf3&QHH&Ufe0B)0a?xBf)+Jk|IuBIyD~TfRFbp>l?r{0=!!ffFj9kzN)WePg-6 z)F%P8?<}fRiGa^vkr#Nc^#${kLfjdPDhDnW2aC|K1fy7Enp+W>6S+6Ze7h*Chl}}T zdbp5B;1RnIGRB3Dd7+APAC*eGsqfq%+Fkga>j`3OO30?tD+le3-dW~=vl`iCXPGyC zUoP*-vy-cHRPH4St*zqdJcA_cab&B?*!7Qi1#Fkv2$lW% zh6U}sp0tfe5v@p3Lhq8?%66?%M%70;>RSu=#p+UCuGTK>G<7L^0m$M7+g$49eb<79 zzb^;Ibba<7b{T_H_~)*nJa0Po!0I)93BlQG`UVG=9;i|> zC@Q4X#HKblHBc4Wu3B{PfvLD;r&dAl>nUU1Dv2?c`uRU)#>=H9 zKeui-s^dkjA!E*7j{dO<9X*oq5i4B4NrCphJ-*SUF>L($hSEe)5Up3$L>BmjNP{^@6s=NY~ zVwKpnXzZ+jvuu}ARn+CvKq}#M)m}30QHs7bUT%fhb#remBJ$e1*%8{YAEE}9h?pQY zMyrvo4qrLX!QqD9>8g%jwi~^hEUJq;^-Ut5ZhW-Zi5Av&OY{~*hf*+d-^9{=x2wB7 zo3|Lrgx&2&{`wo9O} zu|~^|)f6qNI;vDVdg3^&CG;z02!cEYmw+YTb(5W@*I$+zg}))k+6X*HTYH$RqzH^H z54_wyrBo3o6sf>EN!vX7#RJcn$E-+3>*xn{KRsJBq z#UcKHi>M;66aCa{E$QHH8<0qkl>^&XpQ2PnUnegVuCUXPf?fq~- z2;;e?sg^WPsnnLKX#rs<{+Y`y!x_-rSrA(*1*OWwYa;%p`Ik>^@Fwqhpkh>`5JQMqW zEk7dW9V=&VVw?VCDAR93qyIeAnUfDV#b~wU+fqe-&(=t3%dkDeO8Js928NNRZWt$P zhwdQuN@DhN&UL2nb7g@kd95YgCc=(&t(J5n)drN}3nl$9+8j-eKH}HO)NEe52Tjqq zRdp;9>&sUAa(A7Yxp3(kCEf8e34vBqrvInXCd|7TL`av~ZlTl}TC1>SQafgg-l}67 z?{~J^U0&qnWzA_@)V$xe-~ef=9>zqN`o1vutF@8U3f))RYoq8PZ>$xt?DlDS*0F!8 z*!OX_y;S==$nJpIK27Z3S=Rwc|Dl|@)$La**QK&n4UK;5U$NT9X%O8$(kLqL?z(n9 z%Aeal5&m2%TfDjyflMXS*0Q)88yTcvWUB6Dl4^6FG+PI+$NmaZMj&mtL7 zB}*0d3>~~dKXH*e<|f8!R&e$vnhd+H92r}!D0RW#P|l6HZ~s6pt=~)f(LHkUN?_d^ zau8y0VEtl>)C(cPuQR(f4?$q$B~pEGr9yE+XGhUK(nRCwRfL-IMJ{bxCGVDQwNF9T zHo5$^x|GFByIfw+rPjGaE*GdvY*5ol3f40pEodOvspq1-`Y1Nb1tzewmd?7?o*6_% zhJ7twKDpCjV%l$|I`%Ddg|O&yKdBx2mB}%)uVTLlclt9DJv{AUq%)~^Vy9n)39INg zlqTjh`&9hMNgGkd&qzD4hxf)>&r*bHLU;U*Y&~mHu?C4uijKz+oqXl1BYLBs=~C#z z=a({TTW|$dk!illsfOu%rMfsZ|F7vg?&b@LadOr5ymSR?ccSSkF{fTc>)FO^ElQ=d zCLoVVB5OkR-$KjxcI?8~UVA5ewiKpjurg&+R);9>P_%=!vfa8-kh0h+1c^Xvg*3pbTvx{iBv09!pv$6y6z=IhWCF0;j zulzJ%RC#)8+(&!$22a6iO68A9D5^^ajuZ3^JMdm~J}c!%q_Dln?oYNzcS`vC7zJAb zMvA2<>Mu%=y|tngQQ=M68s}s7ZJ%9nW@6eZsx)0q(^EQJc}{SOm>G-aBHOWt^dxF; zEp^meZmczqQdON8c-xd}lrPi1-Qf>lJ?tcn=9Dy`IioFT*+w$iO_HWtJ=WT3f|5PJ zS6;U=?>5$c)uz;2qg_23{7v}Nr&ZQYsqcozr9;qP z)ouYnSzR+*ujwEslNMgmEHm~mB=Pq#4!`;LXT2lA+w^5eg57;an@0P%V3*w4r=+Nl zHFU~GB`Qu|oA`(mw?Y9OZ-q0$N^wU5i04jcE)EFc#K3j4?8uo z`;_Go@>DH`8(F6b1Fm<9CDz>0=W}*sqLU+fr8U_-gValh5Bw5G8{ng2zIU;X!&xn8 ze_bJ}uUl4lh8!`hfUL({21&;JHnMZeh83x=$i=-ZK@qNlEt2d(PZEBE#~F6QC`x`< zH%b>f{*f^g7L)XekT+$;-yrdf!sRSstiF7P66eHr$?Mo4x(-U}r?><=2EE5UBpVV# z!mlo%6e;4B9v%zs4nKIA<4aOSTQ?P(WgEm&BAx2eaC*b#_3ZvZ43Aw5A3ez8z6ySi zP?Xz-qK%BYu)D*b{7&j7fm#P^c4SVsxr2&x;<$cNcDxuv5E2#n-RK1 zG?q|b&!2v1787Y@=VfQsd2#i&HoodY4pBdr^SDt*jM{}!J7dgoJH%|8{!6TYB)Z@F zMZdE}Z81_jo=D@N3myjE2$;Q_j4c#ygwFYJ>zsy4-1MPdaKbJnMGw@ofD zSC@V++vPGtm6yaNQ{-Mw{^c}$!hPo#R@@(4i`i4xM#LA(cO0*>c3mdOIPG$_i^c6< z(<20<9!?)qgRvxxXj|4*>hCmN;=oZ%ZP3XOg&kGYQ?cn^bThikbbX8PF9FY80)6~X zacA|blIIFzh09*)&1*Pad7u>?!w1e2o8CQN+E8W+vK6SLfA%r6#ve&XWY#!qp&)Ls zJN%@4jM_$5b&ciWqN3f~FkVbM>c!OE2m90v`9(QM6=?XWPr=4MSxGm9)Z@kV>R^C+ zyR15bCEB!omt|vi_xkK^zC^yJ@0-Vc`!vFwT=JF(>$$wHPqjpH`_At0FSwK^$m^d_ zC9T&I#Vy;b#1-9?t0bfSU6JX(;ER12U7j8u?)T&MLq1a=8SzQq&!vtew^{FkQA%9iCVUW1`U4ni*CJkl3CnepO<2?0W@*X!^G1oY; z8r&-sHfyJ{lf3#?*V1`M)sHy{kiB-lEXBx0^6G$kq$}4-^yBlys?IA$e@~qb+$LSa zwat4NBl-xyF&oLIy}bQWgJQ&{vE)#z?1+(AyvKfRuHM&kVGk1yumL=}z47mcDFA;Q^MiCeE7lG=z7N(XB|b>m^OGqhWSb%Ucwk67e3 zxt#tQGsTz%D+>&GOX0N=?^O0<zYcXqlaN7)t>Q^!G4aUv{s>bkBX79Q-ZeY$PL@h zkx!0vo&ApW)RQPz!hJ|E>U$PPrQG`RU_lAfKR7JmJ%%>=anWo`6V*5>ew{&P9_~68 z-ox&;rQ{4l$%sKi&+B@nA^xf&p`LH)_?;%XY(KI4hLPh2DZqU;7ANIKWDk%O8hyu~ z{ZSqz4f|wk*oXNu}{ayX>r@d1lH$Q=Q{IMThq|!>?rxv^7!I)3%X{mK|roz6a#AA8WC1zU9lZx^%wQ4cTg&*~Z^F0p zC`cJVzls)*Rkt@i>fFwRwr}4d3uGx+oj-GKr^_h_efugS^-+&GsSAzU>X!f{_4>wE zn2Fspti(i{N?PVI{)GTR8|yqu~Y8=^^VB(J;$yA>K;KQDk1;6lE&wed>$Z4N`k{FophsS*}YZ18=!u(t>MKsc^K00(^dhFl%e1>G~^GPL+yTY%m)O9oSZrO`@v%j4wk)(RU6s!nQXMS|1LtP-@8~~>brod)GE_2JAG)Q5*V6~ zJF;keC%pAxBRR=5uNB;?`m0qHp9t@fJ8o5U$Xxl9lJzL(T;_-SayDf{4ckhx8VxOV1M>mO> zci+(~14r;QPAcAX2`3d-Dl<(zbB{BlxyA@XDqp~QIvKe>p7^nyrzDo zTtkIAq9+g2)puf)!>Q+Os&13zmE(Fw89nA&`#54Pt6o1si|0eSUN6p4rg|K6hi|$- zn~J29<;yASC5f0U)TjpsYsUDS@bC3QcVUL9VZ*7&Ej?O>^|B_M^=|u4s6JJvWi*um zfQv$*Xhi*t@r-HQgKa~ zz(;SgudNUxHI7tpQM7_?6C90pnBMYDzcT_hsBIApq#hyYn*JvIZFV-SW|kq(zWunG z7+5)Utsgo{Qbycr8hGnF18?20Zb=oCNvJelGy2}Y_z^ecE(HUoHp)PeQ=7QH6k~4l zf>W~rbDOQIC1eVso@z3Zsu=p&P*ua|+n>h1{g>Fc531XvpZY{quSLO^&Sj*!cAGhK znXD>nbr#)!R0oJ?#og>A#AwA2*j2J_OV_p=_ip*Jh!&D%+#|#7Jtfx4p2vFyU z+2=&IP*9(G2dH-hb&FH?0CkU`ij}oSzkE>DwoSp8wzJfJKs(pToZp(W%F48qF5ArH zy%D9FRlnzblWYH545zLxq3ZG%T((QrkJ|M1M@S!l-NU6) zzXlodbiw&TL9C|>GEj)y1+a7*mTo0a8_wQpO~HTiDdWjU4~XR`>NHW#`cCAk^X0Sr zI1y@url!o)N%l-tx7$U|OH8sK_TSy(LMFcG8zoweUA8jk6;AV7+slD*XPCbDb&IbuvK?jsEO6 ze&r)-n37RToffp#<@ROV(`eMh@LB7$V1h24PPjmXblIl`cS*m)_l%XSHSZ%;uf5K7 z_vzHCUTUb%64plS+mZACdQCqIN6Yw{_dKT_kzHk#uDNp@`tE~WcnjZW&(v$ybOjsb z2MYpgUX&|e&GmuMy8o~ioQLpAvJ9Zle<$@FCP8DhvEuD-cvwukA5n^`cvtmroNL2nt}BjmDVh2mGX)x z+^h;vs}q)QF7Zx_OQ6W>=tXE$OCEbEa|J@#s6WH11JyP1KR|x{g-UrEVskt%aEs`> zMHL};p6};Z5?+#j#6C|6v3{L0F3(5Y9NQ-;Em%U_YV&M}$XES<(8gQ@@SR$f&zhgv zclDCqG4ngOO40VK0}MlbB5QSf{m*yc>(r$ZjA9j(534oemk`lYj~BNGtgv&K7Ba%l zZ_n2)zGSkxO(cr^C6G(B9#x`vM1!r+dMJW|58NdQtbm%PKC5q~pPH^R+6vuCG4_`{ zbz5+?)5%ofW8H zFJf(ve^6|r7qNeq+A3Gcm5PyJs$?*KI4#AMpo8dQvfCo<>ih?_v+vo}DP!_)-_z~3 zJN(N#oubR7Xsbqd?~*=ikJmDc5K1GTvj+yATbiM#51pd+UNMs~IeAuHdz@PuOvs3F zZt42f3{es1md3j3zDNye7dH6ar@gX4_Vt3zx0M$}1)IfFwd?&(xl7Do^Ty3o&u!Jl ziR#jB&{xiNgH6o`D%eyg__AQLiyFraHh+6a6`EyFI$xyLdXr0|>22nnj zc4ug-w$*Wh%>$}wojFeVdAh~JsvQUZ?9lImN{=cjE+W|cLxz7HnZ)bwRAZ11HmlDT zN_WxLNQI8aKca)pTeR?iV3Vwa+`wRS-jjwV%xoz)MzHzE1h>cAzImpoqJzzCs1X@# zIwXS`Y<}iS&^7sxTG>Iww(o4LX5X`e&EZY%Jv-PG-sTkDFNTf|HZdm{9;bs?j;raM zo?rc+4r!c#dwjJ+8oyNTs9&c*Yx@ZTU+s{_+mbQXA&o2FSJ5F?fwPy#WQRd{^ted^ zQx^mA4r#1Zu_(qNje7_NY{~rX_o|G83SvZ{h(j8)YbC6@2N4$OK$m27v<5oDmmbnc z_?~K9)j1;$Y23~uMkaNNKBO^?R<-@!Hc+X=MBTkkK{?zb;*iElN{Kq8(L_Np z4r%O`rv+NjyVQivGECYa;*f^DKJu&ek*qIb?*`r_b1}6Qq8@;;@K(=0A68Ra*&$JT zo%ZeJEbar5JA(K8ZNRO&2Hsk&Zpj)ZYVYW#_ml@-uK*9!Te+^aH7scr>dmVy~n+hWSj;JTR$5NbmioCzRtG0oQuXHW{V)fPkGQpwTRP~4#j3v@qhIum<_bds$p>T{hWe_KCiR8tx*kD+IftVgK3$H`~*6DuxEfO96bqo^NqgwN7vb>Cu)1B`c?6-xrHR3?1 zu2`KYpMIK9dhcf`l{|2#-W^f)Tdzv)l5{;%1)0QYd;AX%Z4P`>57nw#BsrZ@?BHYD z@C~wA_joKzqV};)B305Kh z;XyT1?!Kc>UMN>H0Yj$$7DGO&T6Xkb#A8EKPvsUX?BD(hK#k+6s^#x5Nw$|M(-+=? zC%FzCP@5lF>Xqv9J!~Qa7o2xK@F%$%kWl@www*B9OlU_%<=>Kbx6}iDkcl#^HQbXr z_O86OQAyaNTuGOkWPGNTxwkvZFLGk-q9|UU_qIL~Ow|`c)ttsI1(y*)^2}#Yr>;@t z7M(R+{Hu7vdfj3#U?pjJ>+;hZ;BD_wOXM$9{x0Dz6OHtyoHa|+*42Ajy|RhG5j*)|FFt1_ zsh=k6WmA~PmT1I=7u|%j)+CV6^M}bVfAJ|a{~Lkza-@Z4({G2Llpc$LoTpq)3yKQQ z^SlWs8qm65#>qJ`k;-O=-ws^%Zah2NYJ>f_b-Q#bHo6BHFNbYbZN z`5(+zTi5ASS2@8+l*Dnom;IO`{Qa>g*YFzerWYkDPgPBaHIn&R1uOkW^304H$rd~g zqAN8TFB2v8u|3tA15Q55GY$0%Pd%dY{BkLOT7^p zRs@n^t6qk!h8LT~zzsibRIssLK}dFLiV-EQlfDqzs4heLy>y|egEBMx=dJj1ijpu`DV>7p{Gm@K_+X#1unn-u9D6&A)C_Mq8)L-5s8%%9nE^#+XG| z6*cS#KS7z)8rz(^=jyv^f*9JU!5XYoL!JdM50%uZ)X>!BTCoHFg<`Ld5yfPO${tt( zN|Lm5rCOFE z5dGVem1?%=;aXFBD*u9Jl~yD^c#0&>eoS=ARZ1**jC$!kfvHO@4W3jo_;m_Wovl;7 zqdIG7>U=B78kJwg&{02ro!bvA-m2>N!ar3b^|o1S~=_M8AcMj6;_bs zz!gfAHqvM}k+#%aEkv0Y-9Afp%F%6?A`(Vv398n=a#J`x>Y;x)xtv-)LprNES<-}- zh4^t3J%x&lK@xK*e#5n-42^#0MKP(|l9z)FOvxcJN!`TkIwlX-K?iU`Sd1?k-lHE; zb`kYD3GBlbTLCvH_anY&C~-eEBJQiV!>H5HMDX3=$*QKWpfCoKp;Q&p>-xnz|c3?B*gClhPlvTU`?%HW!ZH#l>GbNKm z+dqW!mWlq((9$IpRS$$TJr!EUCFiY1A~)Hwk|FbR^*Bq({6ap)`YM5H;V20*3bLlr zwaL=8;gVfL`D`!1W+@%Hdz(_7iJyHwL0REub$4)t#ozwivG`N;2C0R7xnZD}A+?(P zvFBIfKNchNRc8!MLLugC>fK`-+ap(xs(EB+=l2P}X*8JRVH!731D*DuJj+N{2sL`megTJAA@ur}|r!kCN1AM`w~_CEul*54RH6LLc*cl&>mI zd!49CBmXA6TW(6?-9$KVkA0V9uKkSlin63kdl4~#-ek@E(JS3?FLeq+s%d>2RKDY! zYsKyFO8InPtMij5`dhb{rlyDQBKP=$mr{&!s*hXk_OK22mW-el`@Uku01@Ucw5!U` zGaT4%6e!9YRZ>@W>t>-*2O6{^tUchqe(s+ltU-(ktDN@&bw~7*^Jcs*!u_^jk1n}g zTuHVVKvIy3iiH+nnCy;u4aoV2B={wXqrJ=VS1heddq}#97+o#QlmdJ0TUNY%_pfdo z5xeT-5x?dt0+``Ae(!hMOw?1S0F>y{qyiyXK1O_@H=@7kyyAzEzvc2*OD(rfZb~`V z=a#a2K*}UXZw&J)bnM<8gAt24Z<|v+T&#lID|@jS=M|e9%~HOa58p0&8$N8F%vDQ5 ztgKtDL}n?Gw;tq{t&0SVOxNM`$(Yd(iNml+QLaWr*siWSx$ctwy-Pi9wnKmB z$jkGRNZb>rQ_=igvatmwn+jdxWr>?%ol@xN|M`{u!PN}wM)ZFS!r8S-{ zPT@X~RBfX@v)AZ85x#1FL)`uK6y2E`_@xhCL(1z&x6(}QzMA=H0>zG!Xfi#!EtqN5 zhlIS_oV)7FQXKIKW&g%9C)@YNccywtLk%O|4qwlM9cy!8jLZd8R{UZSD_%MGjE1twOjvO{_Zyl?-W`(!p+`E!tnazM8<33 zGm-=;cz3v7K5FyFoT2qdqW}D^%BO0?Wk`A#oNd~aCT+;FzFLidYL@;T3@9m zxV#fSP4YS|=yxK68Vco*E$cHa;OR{>5~emkoGqj zm5d3h?NtMN(s!lr8-3221KPbw=_|g-?w*ch1N}+fn=4ZQ`I#TpLMk-2i3+xdi1V;9 z3QdwMwTGLgE~x%rR6;tU5@R*;?r@`;4T$fA$tsluCFJPt`<52pNsR3D*@Kh;xQ5L!?AUV(qo|St)yVjz9A;l@1C;e!}E;P)||~4Td9jvo*xZx7N(HOY3R#j z#d+{z-BZp{(Tk>(2a)1e%40Jm6>=O~q&sr-X=U1-oz$O6gPAeyQA4`!#;O-PuLBmD zJVi*BRfHkmop&Zj*2C><(WAljl;mg^(Nfoa6(+iG5Bw%Vuhj5ib`tG*SF{FW=mgF$ zx}B;DRS`AjH@d~xufLo{wZl6nW3_edRA2R_r+H*-e8W5QezB>uvisS;tjUXtzJDaY zejmt9LrE67a;f-&zVtomWAvrT!v$3Vo8)7}ZgafI`7>!59XVf+k4EH-^t7m+vya5F z+vClFjPif&(dxOb<#pT5lz!EBB&8l7aLwJ}JLFljcw9txkf(HZ=W&#@*JdIoq6eg_ z;N|v!U)a$#q6a*S%z+*n>75b1tdCx1>&j=o-HJk6b9h-QPcu2YHecp{GqnKQ|6a!&hX1v#w~JH; zKmVVm|2<7v+W-DKSSrIPqGE=g&#)sEK8c-A@xPxaRFyc9J{0MHs%6_SyZjB-R*dpV zwG&6BcZXN^ibOS(H(e%$5~S=$Bi6SXu5y#yL=t;`Vm$zg=}4XQtAUP`Ew+sEV&$vi zEiyM%6+K3)p%%sJ_L^6dEb7yRZoKep)jU**W=**j+@cWhoLg(HO zE}qx$`Mic-=S=t$(uM_I`Pbm^pM9d?{{;P$-?Q`UAL5ydg#J<8fi zpL?79{<%K+U;ZZ5tg4<=Ub(!ed{SA(^75MEl1VEoD_546OscA`3|20ySuv@ox}>6L zRj|6OVr5#X%EUi&0@-se^{*%@D=#UY;V-Kw3zij?7u;M_UQ^;f{X+l3B{?}W{G?+Q z;mh)$mgFxjDKD?QrLwxbIIU_~+VbVxmp{>qXVi{X8=>AGWyYR+V^Ua++H}nkoI{6Jsz)9_O1qZTKl= zm1!%htCpvg)E3=XRbH~nNIUyDCFV-8Uar(GchKVrg9ABNE*q*^i6?OcR?`M%v1w8x z%N$YdmO6e#b>)o{q{UK$rDdxos5Xl&3q{kc`rE?5h10aVWZLeMSyq8TDvHXdOrK|c zT2K-!DlQ5ZU0D_^oh8mRyJ%I(yoHO?3noupQgK5?cDs1z_j1Od~s+v@Wmrhzm~68|_7Az;P~+jnNnxPiDvi6_wQ`#S{JGD{q+Kv#$IXUg#$^ z1xvpe$^R!DCyS+%O*YdD4^ z_f2vmNSZYuOtMD<-_0e2WhJz=%1sO?FBdE7?p=^pc>~t7{=Q9G%V3u8g_7vVuTgvplGD zQE`RYM_KXLtDp9}njm41y78xaK^mH*PLPg&OYzMMvBkx<+O}@a&6pcS>7Uva+lqb;5)RzKhjV33v6=_*$Ob@>1?sY>yjD zf~A$k1*Jt5#pNZ{1rmd`-lta;RTtfuhU}ZUk4C|g+TghttrBmrXJ=$q<8Xo0lNv|` z1uIvi&QX3dOInFwScPo~iV}e)DEFxjmJ}EG@FV?!{HI$*&{+nEuP#|$Qg*ZC@cEWh zl+;$y1#s(<>S`RjtimtjfvN#*@1p}$72R51Syb$sTUM;vQR0^$#mlNoOcNn(;GYgl z{+lbw8$E{1u{yc5+hR4uae|04f|##DI540pnDtzBdUe&zC|xvY`Wo^R=z zP557ytkw9+Inj*`x7R1&e3QP=i45%ZtB&!OTfcdz4pJtR&#B zV!+2u>A^-*{G0SsKKA9B83kKjAk*6gB{vqVsF=4PVlH~VHPW0*DOs$1t( zRMi9*2bu8P7%6}19B1KrxvX0q=~nrf#`<`UUW4l-ns){TtNoq+JNdkb;FUdqR~=9X z_}B(=YNkKv@?80uQHnF;a&(W%sxG7Q#~T=8WslbX-_^gZ{-#Gy8B473B05Itz%*52 zlnzYlqY;>*>i2a6W_10$2DzBFk(*KFN5|KAywoioFBOi*ixr~zDPDohs{(A|O|d3G z1*`!}{$I|5a+Xb|2J!!*>}&h4xJ>lKCZ?dM{I-8cetW_cGoO7kD!*;t0gh{@kH*Ep z^ClN8D7tl7iM2YftS(^xkIjdI6*U#hW#??3F2kN!&d-e*vz?Hmr;{-zo&zRAq~xC0 zOvu$#_R#Dzqa4k-DjE1NTeQth)9+p^VpFPNrO%qd_fau8jff4 zGyJC`{XKl%df-U^u#$hM{~YPhWQX?$;9BskPe=z|40eKF zfQP|Re>u`W<_w>2Iye(71DAqp!Oh?X@GzLtd!#=l#pipJ7qjPpd%$vVwi+e@jl;k zhsg&X0&~GB|2ooN1;km*bIIG z`e|3+$o~E;@HnsqJOgY8r-41-)u8WW^alOln_w3B30Mdwp3vW42L`|v@IJ5|+yeH1 zhd|#c*p06R_`xhN3%my`1fK=#z;>_&>;`+lO?)|F#2D<(_X9G(-++1GpTHp42R4Bt z`EJ1ua3Z)DTm&8hmw}^B_4(?-4DcZ^58MII08r%!EgNMLwF!?m>GY0#EXM_1*E?5h8fX!gmseEf2 zd=l&ep9TBCZZO%8-Nuq1oCxNFSAex(G1v^Q2HU`g!7i{3>;rd$$*22#d%;ZbAeavh zKaKogD%cEWf^FaxU>A4~*ax{QdpiUf7OBY;2v-r zn9SFeJHhc_FPH%)or9l)>EPpFE?7Mddx9IlCh$pc2iOko1^dB6;H78K9usLtFavx7 z%ma6TLGUxM2~6bcmpj00a4(n#9s)z)C?2bC1~b5C!8~x?c;u05lhb^@qtC*g;94*r{2o{fz6myiU0@sd8Q2AWGnM?{3^18~w*<@ttH6A41K0&V z1NMQx0F!y%@p~{6JZb{z!0})$SOzwO+rh1~eZCXV?(eUfLtFscz^rp<7w}UsaW4Kg zk+=hH2g|{ZbIA{W3bujCX_ODX2-dH}-zE`XZY17=ZRnFJNO{+RU0@a12Tn^z&&kvm z%mRl_rayzDz&dao*aFS~+rcVuKUfbYPGNijQ@~+U`updCcY@{M{on?0C%6s#7~BK; z&LggYY2XN+sTYG2!JEMxupX3mLVYWP{NQciHgG4{34RXtf@7!RhkOb6dN3W_2j+tZ z!CEk58ukHe!JS|S*bNRpzrX)5=m*E}wy`{LCRh$G1s?}jgFC>@;H%(Hup8_KKLHPe zqcX`qje3G}!I!{dFmEP$gDb#oU=z3p9Cso024{jJc){K>a3YwPMgIZEfmL88*a!x| zR&WK_3D$wV;OtqnS0?$vOmO^c>J8R{wcr-88O)zUd&_;W3%n2P12==o(|x{U=aL^x z0rSDD!CJY_CO?>YG4%%T1G~W%@G#f`j+sH6xdgj`cY;g7$HCR$v;h7BegU?Fi{>#7 zfH&vRUKilMU^>_i=7R5nRp5tUBX}5W1xGBP-e4Bk3vLFJW)i=_bg&!D1!r*bsR|6r z2`KP!uodh8J3%=a)eF{LM*a)&zg*%5I3COcYr$IZQLq_YdO3Q7s~4d+*bMqEBF=z* za1WRTehL_;OEy-E;y`!a=~$64;TP_v+xtp57vWOU^7?< zJ`2`?2f-Hb2-ps$71G||eDE-MViEnD_>>CH1uMW}uo+wn9$JQ-!DE+WXK+54MBKU_ zOa~jmTyPuM3?>v)f8x|w(3j2p67++`U>0~ESO{(b>%iB+7H~h<4jx-V{lNL4?_%Ja5WePH-W=0A+CTE!BH#G3rq*Az#!NJ-Vg2oQ%mVb z;54ugECrJT_%)ab?gtCO8D-c7ECjcL)nEr00>hwupF3%u&-VhD33l9oJ;8o(EjYcr zzkdsO3AhVf0`3QwgNgHz2d01{ZbV;jJXj8H2Aja`;12M*3iJi*!9MUwF!@saqmpvL zi@|&_AFKuM0h_^XU>o=**aaq3ksllbCg;$f!A!6m%m?oUYr!_K8QcrDfxTcCm~|6= z1TF-}ETF%EGr^7EQt*f1YOovJ3=XX(?toVZsW%t|6Bp7BU<$Y$oD24V#o){u>?S<8 z72E}OfbWB0F!g5I`7+7}Q^8s=06q$qg3p8X;P1e#V9G7z2j_!faOCZ@S1#p%>0k$# z53ak5a=~VB3-~O!3p@<&2glW+_vOR^Fa^8^oC|(_H|+(EzlUVb!)K~_z<`md>Y&d?gYERMeFDni?JK%2V1}_uoo-@hu=%T08_vg z@FK7s%m;hGM$nhXJO=cGuY*}&4_F9}{Wkf*8DI-o3ATe9!5**`^erKtfGOaZdg={+ z2$q6JH&AbIA-EO12kZbF!7#WV9B~DD-bcR#Q@|YXBCs6H0XKlpf!n}c;2!YA^~6gs z1sriD{SurAt_5?z$G~#%d2j=`7u*IO0r!AAHjp3u6daLHoC%R190%rrSztMM9k>Ck z1-F5Zf_uQc`^gXP0!Lg$|9pV_;Bqh*ydSIrlN;$L;1sY8lwS$z0)Ge|244clT3+0z3@%fMbg2|KLn;%e00 zyWm>z$KV!lC%6mj0{4Rl!NldPUpC`!;8S1@_$pWq{u0~(z6Wjt_dSNcf&0Ne@KZ3k z*ylT`g}4sR2J^vXU@f=`YzB9NZQz?=7x*FA2Ob8KOMJemKOjFi7t9AYfpy^HU<w}N@*IxzhpqJaJ^)j}VO#Jw zFb^yR>%gsG@e||&uXvJtU^zIfl=cNv!Oy_}nDrF-z!hLUxan#96nq!#1XG^DPr*ZA zQW^809}}0stnKt~aNK{;zrhT!5ln6+KREm+tr^XYe90@dn04Fa^9GoD1Ft7K8VJYr%)XE#P)=7x*f;AKV8fmScY~ z1w8pV@`LaH96tfS{XFvraQ;j9Cs+q|gR5V`UN>UbSFsm3<2CFBUIx~K72sB|9_#?0 z1;gNH;Fc=v{0rhE_($;I9qgaHPJFzR^&L2@g8m1lf)9cLunjB)4}taI*xkqnXMi1G zFW3v_b;Ptf#b6$| z7OVshg4@9nHxa)&X)ka#mVDMLGZS{Y}jL2w&5q6Yr}CxU%o4w$}={NVNA1~B;t!e$+zGSzhnLZ_JPG< z+I#o~SPgCkw}KtuyI>gn0323}9l=!ay5Hj$U=>&e-Ul{&;|TQUEo5n5BxTmyc+)pGr{-4eDEMx z3w{AMgEK!MKX@P54Nm-T{FVNh1*U)xfdQ}+EComI$L?SuxDC7y+yl0O>GbE+KOrBK zzfl@|gKk^o8&sP#=#&vh4Qm{9RFd2uBiyf!^q*s;5s00hy1}XRzdX|4K7@;7lP*3s zdH!)n-!iPu_pOsJIQzVmad!T>d}w}`X9IG>`jfm%`TzC4BmE=g-mGJj?oF6;%+LiW z#HH}7`M(YRIMCteyZmNuUyZ(}nf%o*zmxk{!Ot-H8kg_p{z~MlI@;x5=JJQ(uYo_o z%)ij(#|)xv;ms)>&{37^onfz@ozZAY2ev-*w@A9kR?|~OvJM}Mc`OWb6!k=jJ zm%IE<_|@=Ye<%N4F5eB`0zb>-SG)XS_*daiHu)tkKPG{>2mECwpP(CP4EJWjAA~>N z0Jb$?zh} zvCow*FSiHXmYbt`%2AKpc(>noitaD;DL84DL+JNBauOd~=E}$k4c?HrX2{?lB`9H% zE|>rB;rUn>nD~&9_L2>Q*CZzFk%Xd0)nL{iJU3%H;>t@XR&s=wx6IrQ?^UN(_%e8} zKGg}o6#gVrex6(BUid5G@JWf(1%AAlzsSv>4lnt=`fM)z#qejE`3v3rRq#1+@;Aa? z0Dp{`Kj7wXg-?YaZSuJ;-w8i9j{IKuW8uB@OCr{dg3mJL-|os!htGib>hrnqdGO=R z{MWkqtKh|cXPCSZQySr~hM#8gH@W#+;j7@YO+Fz@B@qAVgx?6C7s2bGCwwpb8}MhE zywN^MLzyqZ$BH?A@?_#ayWmgZbK>p-*N3lgb<9J?PSTuZma)v`gYY85%g37F-;BfW zfbWE7%HfuuQ0>@YFMKM`puPA*@OAJjBJyh|7aNT_ig646Xp_I#)jtFNS@;Piue-47 z<9YBq{LaYEi_(cW$4n8LyXUL-N30I~iB^W-G zIh^%7X}#tS`S88)UU8-t{xkS=%5v&;gIn)r_#u0|<+s5X5(B*Ec3tp2$fruK{MoMj zK6r`a633kKjTn|p=TC?CoBTC8e+u{HCm!pO{}7)Ozqs0!A+`#+=}Jl0N4i^?YbE|6 zGTq?HK`NoNb3NtFXRdv&Sst>MlfuuvR^;TvXY)DnNkfhi`}ZK@Hqv;-m4ong9%YCQ zBSx?X34a!!9h(?&dm{WMc(1uf4tza)EMN5_vK(H@XKC-s7kjPH_L4M>q}fB7a~WqG z9Y{0yjKM0Aq}f55eVs@87huzfG;_2)B~2G;e5^^XjZU-JwfSMv%wYW>FLH6@3{F-F zq>WSXk<7hE`v1u1#A#Q#Y4n`#*P@W5%OTyTq}zd<#4$#?`7-w#{DcS;`<4?B@7#B! z{~|s+<=v|5F8l`g&2ji`@Xy10#kD=~Ps2|!<=?2~`?+@zekXjVSzoQ=E4Geu&akxW zNdM`kjHRxQ>G0RX$Ld#Ni+p@+5xnXbr{%l#jOrJ4q;i$n}M-=hp^mlXJXc&~mj7rqeQt6vnuFM{{# z7i+EZ!jE}{wpYKHi615W(drl1T;bY0 zs$Ud~zmZP$i&;jxsD81Q@&f*i;rc%kChluyu{VR8q)_S>9`|lSCe-9hgRA=@3el>woq=zXPock zvlBCW~gUnDem_?U8VaQc(C@_(^g2D)?*Qy=>eFKQ9j73ZDr-%e0ZPr_%|4Rh<02@PRn_ zWuvexPX2WGe0Z-tom}{v;^eP_FNBY^e)m(SM))h>e?>oX{9VV3UG^BYgET|p?ECD6 z|68B8jSs;?c((=*0@bUJ=4#CU5*r{gzd{_TbEdEEsd)6QRn{oI& zc-gm$)z77m1TFbqd=q?9ocufB6F)f8zr@r(K^sWq?}eWZPc>uO?-2YooJE(kj*l7p zf}WsR|DA68 z?S+2>ey+(I`@)CdYmdb7e-ytHo>1x9$Jn>efUkmo-Q*KqQ3}W$a4CjA5&J&Q=fuW^ zt_(dt*dz(Xj;oQ=NVfn`*=QO$}wV22mBYv@v>zYei-?^_+dEniSS;1CKY}}ocsa!li{bD`c=95m%^vR zd&R_h_;K)FKDQNq6#UOj`3cXe0>qa(;GcoNz~pb%<@>qUixa#KFXLw7sf^zC^B`mF z96>X0e#5WL7K}VWVp|ElBv*s z_}M0Zhg;W7_@N2jI_AS4CjWV6{t7pLEqoIBWA#laUo-y82(v!&;HM5u;dS!dL-1V z1{3+I@M%N)J)bKD;8Wpa&8ht4FSYVNp1_6O_prs_<^-pV4W!vNtlx89vJL)ec&`|> z2fhW~D@GoKZ-fV29gKbN5e)eE!^iRoX^RXDQ4jwrpA(1E`;2-dw7I^Whn#WW;A|D? zoHW+nq1ZBL@w-eu;bq4TP4KUie^CVQuA_Fq_rafI^41=j$lnW}IGnRLCZF&hj{HOL z&G3M$pYdFMlwb2+u{Z<%KJt6@s}b+iKS6Iqsrtje4eu4-n&5ZAd-eSt@V|q9 z1M#l>U8;UizP~}wc&aVE;{s)COE>|#>uBM$Ab6LF%y0>yw_Ne55EQe ze#&xnY;fA37JlS0-uav1Pli9k%x^s>M0H;q{8;!Vlb6_XpDIF)N8O~kpEO>6b{Kxj zv7AvcWmud16Sb9FJ!bL@d%2tV57jdjyO__^?2`$Qu!b_TrHm^BeT z0Ke3fpP&~Gs{Ziu9Z{xQu71X|_j33<;bX-}$-lwMf1Q~>K?f+|x52+k{^=%foTu0W z-wp2-;}61r9H;yd1i4;#uXV{p_%GmN`LrLM^6;n9k@^ejiK%m38zksMF;a&rWb7hM zEE|Xn@q77x?B#q;49_-X=moUM*nx~b4;fHC@%tn2FNqBKf}icTdi|j$jUwkTiJML! z4i4hNPBZvq6(oco!{FXDs^4=RI}^SU-mATr!rvE%Uk$$&K9(({{LNpIf2Wn-tNd>G zJLAYdY~_#DAHHhzW7|Kt&9MTOvv0puJPb@Lg8PDWPspQq9 z@v3V*L?Qg71Oz&5akiQqh%L6lS0#JMLp9a>uxC(kvY79d8fAXTf{<&lm=` z8St_6lzPmBkC%Vxm*ih<<&WimB7ZY{dK~?B!k-QA6%V`N=fcMtZ)81x7+!vPG-B?} zeJMM60&N7xGRd{C^?X?TAq%5i4F49N6YDQ>(}+L3qT5pB6e8zi4;_TBgYSmFn9oi- zTKfaSx4U;oIRyz+V&X2bXI<5M2+V>k*zetmJdzfeYPobUaiuQz=W{buh;7 z?GF>-PlTUIT1VGg+`8t#Pl5NESC(76mp^TQ&m_N>&3E9hk5Z49r5@)Q^$?r?)YW4z zaz-F$iK(ZxKj`P)A@~#je5C(+lNTA*IViE2AKzF?nxF7FaW6HtW0ItM%I&LJOu|1T zUBs9zX{>SIPyS-k_`}|5#P;>1*-ksgsynLqTKQ)NGESEGv&hir()$O85;qK4GgQxR zMV5T$KlLN;^GWh9fGO~?+Cl0*2A|4=e}d16LyWSdUXQqTp2;NfL=T-skEQU(!&97V zKVzM;8h#8s!;s4xXVEspkAsi39uxUHt^DK6{Kh^?H~d)gv-EZ48~fact^Bxy%NzT! zW0**dCqEW&dBfjl!q1MQ-%|LQaro8n)8g=(;nU&0>bDbq3cQznyWuZ_k5zwZ=R`7! zezo#>(hRqb($2ro5{0piE8W*Xx;Xa@W=_$el@m$z!{$cvL-?7kYmll&EYPW%Mqsn=y`NwOU)u}u8_cG4XqvFs!xoxK z{4FtyT9|EZ_*^}5+DLbjSr2Or5jm~Mc^1A#*2?mys?j#2Y)a8?Ixd~H{+#EgYX}~OT8Q&3f%IW z;6H>PY4XPNrycNJ@Lu}uwd8y8hu{yA-%I~dYyf-=k7v628T%L+@ChlgV~o@<5B@Ou zr<(bVJ>MYw$T<0%;77#acfb#Ym!@{?XFMy~3!e-ht3Qi=hu}wf@P7C)2u^~}<#XZ_ z8EzQ~`hklGMadzx_iku*F63^-HU(e^n z9~p9_z3$fWPsYd1q$?%ei&9?5NVm|L>pv}}itXAd^B-y6v9bsLAbhNGMe_Ryav#Eb z*~Sl_G|9Vdv*1sJ_v(j*@aZ1;#U}MQm4F42-tbG7!pD{Ce_XT_` z{rvDV;kUvs;B$nZ&T-qgkTma-Ce}DFGV0(v;opdsp&y4TKiNVWc}JbsKEW>d+u`R# z$q-YG;og4uN8uUeT|JHUZQ_N@t>I(!e?M7L;9KDH%>2?9j2IFiO($u*Y*`Aw4?dPH zMaOz8zZbt1{!I@ZC4UEe8+^o`R)XHl5Izi_kP*9%!VkmAdda_t&rVw!XLnQK$HmDX zfKP(=%3lgUJ5K(3_;mPF%<`?Zzv#CW{v3EO`*gsMhd;^8Z>^tH{o(!aUULw6Pu$t? z&zboXexe*%@~6VL!z0GEkI@$c@bANW>0b)}JNOgK{Kj|9>*3#qKh@-oy{fJ7d*H{K zys_r$fPWL-v;OeA;Jy5FSeDN3S%3J#sXUV~%TLe?Pq9w`z7;-T^7IiomgwhRDSQ|F zl~KIqVyd5SAkER!Vy_uwY}^KaB7B1>!`?Hv-HkbWNhj}~^zxNM@YNo?AK9a3F;>IJ z(>0SckCDc!z4PH8hWBdETKI?Hy~f67_#eW1)u9dkQFyQMy$ik(K2}VV_UePb(}NdV z`|%gC!3l$ymsPUyZp=dle?!m9L{8Rh#_;p|J--`M2wwp2RgXIOtK#r2@baEeFFUux z=fWS2E{={DyS~r^e*t`&$(Omjk3nM|yw@1-hcAMUrN1AU;`dA8)&5&0|Jrsk_TP$; zaUE&KnK~Hz)NA1jEg7-$Z-HL{f3}(5*r(nFUj^?qKJJIFfoCP*>Syd1$UAQDg+I;Y zjq^Y$@ay1X*+6_?F8p0__+t3m;PE22{AF$%tcAZjPW~*^6z=W8mp8%x zh|h_C;f~z~GDbh@IH7c$0=jM1B35R3=P>Zbj?u- z54mOKllIOyW!1vh#^IactKq%keH(lgyl4N1Uj|P%c6G%bVm8(P;qQi@Z}JJ*ssh3% zUrfA(_v&|<@LS{{4oT-(9o+Tsnf-!9R~P6w|%^APYVKKirg~yOGLY2tNg0 zWH~WI9~o189ef(Rm!G%5p9CMP9wM_H{wR1aKkb1Z6equr0MLsayxPeRe-M6@slRpR zPV5-Kk9y#L%;&^!GlH10_lIsgEJaR996jpc7ssi`R(NR#FFSR>Pxp|Yif+B=c^3RX z6VUUYL{(c)`&~XC>$5dt(@~f59m5N}ZJq(YKMtP<|1SJl$a2at#=9W=Z{bBRhhOg6 zstNuBc)!UT=ZAM#{P8BAI82;Hf`Pag?!Q+;$of7mUUfOvJ{C@azOx`$0vJ3v)-A5w*-FQB+AHI|P`_23b ze^4Dpqul|ECfB|2TXK{ECab&lS&wUkZP9M1H+dDe{ZqH^EObd1HTiE&P-4 z5&hNBe+zskd@TD*f7yc{?}JYtOkEZ*64?Dko=;fs%@92fBIo^C-sf3H@WAg2_{&W_ zEk~666X7S$?(csmf`8MoQx1GL{B5im9UTVOsKuh>FNdEtx4-|tBJ%HX@^63-!+#LL z|K8!Z!9ShtJ?Gs6zZu@Eoe#nnUhLh@BdGY4OJcXPADt$`r^3s*1*d-W)xm?^^>8j} zMh1A#WJDd*BLFqtSHa%{KiTB1wV1SJBYYG5Qzq}uOVkQO(zWB$C(P4l`xEa)yo;croU&{}l0q?aA$%3B(?=@Bw!l%I>XO?g5o7TaP zjl;LV9~*~nhd)C7yyW-5e**8d@8(;~SR04;!|#j3XTiT2hcASG5#Fo4>+#9A;a`)! z`yL~z*>|6lr+n-`W4l(;UBAFu<9=?Wld-~D<4U?N(j6e3lGkITlUQKMlXmYzuX`_# zJ%5&Yi66h&46o)(rd~1TOLN&6FVEv$sN{3>PxzJ7Z;Rnmmh|_37{UM1;n%`{3_sfB zb6p?a0>9}M@9%T(f`6I(UgO(-_?O_l=E#Xl7=Pf;Hp@5mS5n|#g=ZVZt)KCI>$&ig z^1a93V))EB{95?g@MoIxjdPG&-~;d%n7lqtqx$$R_+of3{rAIHz^ndl` zFI*4*9G??U8tv9md~2KA4im4yZ%9{c>XA_3v||qZ%&WX(K{?s-*E><~y@-`#qLwK2sCQdfwSo2XyvjZ82Nki3LyGl96^X)Fuq!&az^COLH{i^r} zKL`F;Q-*cMQ|jZ#Po}`H;dA1TM@E)oJom}EitpHw&MUSQ!q>;)>)`K!kLB~CXAAsV zc(1u{JA5O2tmh1>{i#O?ewozcv*RP{VLV?N#^kkwbP+Z+_JdO4eTClj48VUu{^2BZ z#sFgFj2l}PVF#H7ckJaA7 z54(nUn#AE#;fKQC6(QgKURwZu1-#cBz7)O@9#3-XZ}@9H{5^5_t?)tknP&c5+_=|a z$@f|VhT$J3zZXAjDeElwlTG=?S&LNoN8|7T_-6Q6^PDlrEQNnMPX2m$Dc`gG;djDM zH}x}OLI?al`0XYyF~K@pGlu&INmE$l-3BABWjYKW%Lab(PlV5b?={QNW5<4J2`M9& zG|9`n?OX*v4nEenA^98OQ{iLHXZ`T4mi#SzcKVUj^I_K)_L8O<8L{diWgLQkFb+TJ zI?nsY;WOaxg+JBQ!HOjkbC%+3YvI+i!|xswp{M=q&`&z~O`NLbdQ3@-N+-`LB#rp} z2GUI9bK)vPma*5n3w<6X&0NwrHj&LPE~UQv;a|06I6O9!WtZ@Y1VSHOGuQ4_rUrlME=9q{FG_`UE~!_PMD zXFWUgbMFxRYIwGVBkXIrvf6L(<10`8f9!n;d|g$w_et8cWhw=k$AC~7OYTjY0T4Rf z(zIzClTb#vO_Q58G!vOA?<5D^eTQ2`NA5qO9Qi17W_ zUjKFPIs2ZQHf{Re`@Zj;AN1t@&pK=Gv-jF-uf6u#dxOT+)gjQN)}Fk&n$ikexh;Nv zNYYw}=iA_U#IBV7DrEbd1)3v3Q>Z*|#PfxCJ~fqC;(4L(kve%5G`E4K zkd7Y*!|@J0FQi-c!Slbt_g5Rv1AVlThgo>O9sG6}J?F}bJ`90o;QtQLtUwyLVZc9r z!bQc?#_w?9sMPq<3r0^Hzt8z4v&NUL95ZWt_2NZu;g<^!PkrM z6R&O3xK&$l9)E21WKrKk#ldTm2|SbkH$C{EyNZG@7ai=7&FYdXM+ILjzOZP+U*2JF zq*7M$@1o$ePh!<;QOV0i*t1DLXsBnKR33CHHpt3lar1KgJ-g&n!HGG{m5AW;N{$S= z6yG+5`x8Ya&x{GaF{b3rF~MKQ?Cw5e%Q+=C6a{T1tBQg<$oCVoK>HuXCHI#Ezb`KN zPD$|gsFJ^y1fLsS^6Qe|iP2L(C2qpDwz=+sc&s^a>*IN_xNzr z(9O&UvXl{BSJO zNfoyTXXxKGM|~BHE-x;*V@&X%l+DUf#V?HsR*x$A`Iz7}shq1um#i8ad}DOUM`MDw zMt`FSKYls}Di_Iak7S=L7TLR}IQVwaz)i)$pIE-*EDe6gOuPXxc%i81Ir-W*iZ*?( zDEPb(hrdIZj&B8csx--~gi_w$v1rTvOZtkwP_*f#MZpb%+Do9HIOQPNIYmdUD1m%# z|Jvx_V#)Qbqe>nr34Svw{iTxNs*-swyTZM6FFb57`NEiBS;;?2f}a(2zE~1`cGQK% zKPw4t5CN9-_9)t6_mcgJ>PxOJ3Nj^MC<^eM&{Ls=!RhdZlB>rAoh2*B1m7*%9>=E@ zm0UhHc&BK|XU7I_71#Z3Oz`xmk{^r-9vEHn{FvbR(It-pDG{3Qj#+{H=YQ(RFkScZ z*s`wV@}eMJa#m4rt9%>MuUk;^0*dCaZ;uNuE?#`ixZr!EN^m~M??;tfJT~}fRLQ@` z1TT&*d2eiRR!PZoV}lz?N**2?d{9yX%1g$SoI5V~!5I1b-7!yV4T0r;`;|OW984?u z=BVIPCD)D$K3#Ios9<@?ABux(igv@F4;9URyEynAL{c)ac}y!rf4sW%ilT297yYDo)1Mayzs-rFleZH}GDRzjO3p3{ zE)7+?%3^_Ml9&Iz{yT1pa?3fz@Z~7yrUd^kWYD0sXz_@!Ajc@cEjGJ>7#B zc(-zTb|1x`++68*aX|@)DLz<#AAgA6=N+nddvDpk`reu!EAkiKCop}ZTS&V48h!s< z-cR^sl-~>cDZkZx{%hW=e`K8WzKZ;w*-YOrWxgL@qt9Rdhu;6f_h#L%zwO^!_Q}zBD@AlprzPHnM`n-wvw(0u2dWPP2O6lF+o5kMQ#D{p+Ii_G=2$-HZ9!?Q8Z#?{D(E9{9Ze-t?U4^W*tme}V5>P5S*V zjlO5UO243gy?>$J=bdj)^nMBXUVDN5w(t7ZCHi}ZRZ)8Tbpq41?>h8yd!qLjPLHy3h^69{a5I@;X9CSCpVb~{~_*} zmGbqs?G3%p_;d94taVH;`d04OKGeH8B>u1Jb)@s(u3yLZreM%6*9#u~8shS7EdIBA z6bpdsUD6ki)8FIRPZaN?zZcqbH?fQPKKngIpRcgr$LQ}T?Ds1;p{Wj7ki08GR zi=zC>LcisS*+0g|?)4!$!4|@^Y1jIc;|?arEXVb&&mJ#dE4<&=^LIV#$@2VyM^_s9 z9!GO=?)&8T6z}&6@AviI?={}<7rfuWB_4nN-iPIq&8J6K3WsC(TIl`0-urE|FTk-T zmyJ)1i+_IuAz^YEUgaiia=&MIzel-AyxjA@R7Bq&J6V5YR^D9?pQ?968n|n(Q#GX> z`MbJQ?HkN8xT}4)Vt|@(bH~iHj^|$5wXy$Jdg|q4Z z>m&Uhz>f4o{+`A6KjLr8*PHx(e4{dYkH4QG-~U^0M|OCf@Jh{XyQJ;r$if z-{F1CXP7?k6M3)XeJ1Y~r=cdbj6aEb#p0GmG2{M@*l7aOplXGK<=qyGpAjl}{== zaPq$TN0edAuTkg?s*CdR5cs!1}!? zp9#Sf_J>h?tKePs-%)()VAZ#@exvxuf^)XXuYgfF;mi8hDE+qCel?137c69d8^yN| z;`H(;^j=pTv}c&q{XHr`@6LWR{BRUbG<%bB9>sSK7M92H*(FTo{+6#F9sH+jBjJZ) zZxo~aU+~I*Jn_;q!_+~r2XXTY+tVuiQ55VP+)e+mmG(@B=a*Y2`K#n1SU+m#062HX5Pa}RAar@poiC^X6eCw>ocE1&a-|B^U| zNx=_^yTfykgzAt!>#>ZAn!>#>Z>*0q$9;6*zPu%2fG4aP% zM9ULFSdRV)5C0AEr#*aU6u9tz*29k?{=A1@O8f;6|0VI4J$yS1bcO$`9)1+@*F5~o z#NYJrCyBr9;bSnc7yj>h_!QzFc=#akKm;C_$-`~LM|=3I#K(DfIUER*?&cnT2Js0V z{&V8*dicMIFI=hl!7^cYrC`t$!Csm|y9mYWu1<$f2-cjV^gYB)e}4Y~1!{>uM*33H z+w{@CaL7ph*L+_297X!`iBBQkM*Lq!&wO?e?|^|N`pV|pO+Wtz_)z+J3c_CH(ti@8?np0@Js*5;uKodi6k0ubQ5m!F-yW zn7uU1%fIQ{S`RlpHrvBZkInIL(_?iWZhD}exaonvp`4{2mk_sd6EPFKhq&ec2IBo5 z{v+bcJU%ZHU*X}V&(HDrm_A?S(VHH=%A+?ue65F@9=_hgO%LBl9NBZ1>EW+=xar}W zJlyo~%^q%g_!bX0eR~`6YDxO!-1P0;9&Y+}jfb1QeZa#_-#+Z& zrf(nfaMQO>c)01?r#;;C?Xw2xES65v|{-({r&%k{P3LejtXuHrTi@I&H{KdLxJyzY9E_?dH* zf%|+skxi&1-Oul*xat2h@KJ&$d0$wZX?ZQ{4=s`y;epN@GE;dA@L3LHrM zCgQz6RbVRd9|Dgn&#{;&KvwgvD&WHZwF5L=dv_sl`#b#7rKC?jq-Z4{ev|m?+bf@g zi2sB5*jp69Pj`I+f-ULxd|c@#67MJ8%kqI);;x5?AOA1?ZRK2p3KBk#jZr=(4_^fy zSMQIIe$Cy=M@L~;pNWYRm!D@9-(PRRLBuCaRQ{Ik3Bb2PzgEg|Wf|!&Cw=dUN^k9Y zOLUaNzb+Ha=TzX5Pm5Fe1o?E6zW-GP?7OZbK6_{7WBLCB@pE>G@;?}YE$Lc3#1is9 zmbk@_JxhEGd|+I?pATI4+p|j8vlU;daIkpq zcs`#6F8Q>$ChITmCH`f$Bg@b3s0g9|^-0R#@^&_G(GO>xtqESqbZ;j8gm$Hec)M#e zC=lUeal6*V1Uzb|m%^Dy;^1LAfKCwm&w2r*F56mCMo|bUQys);#^-9_mKI6f?HS;be~Wvv@_(QBl0BhFah1A% zgJ7o$YAikLRv?k?)pYD1de~4UJoEFrzyX0s_ z;p6v@rxSm(C(7po;&&w#H@Tftt$Z%}w(_<7oDbZkdx6qJEZwz+^vmwh-*v=yL`Ny| zV{y+f5zJHu zHBE8ft~(mIjI%60VKn(K1}^er@u1fdA3I(7oW^oC`K$#Vrw@NY`se?q4A9NF>z~A5 z^7>^t^Fs1pv6a@>d8EG(xX9Hx>=$6hxa%3xzq(lIO;7HeQa(?!obM`D`fG^$cFUu{ zg}=q=n%@4{Oy%SILz;xWOxRk@~9H(3R zT?Jh7If3N>_2sVTNncI*v39g$Z9MI^Itqy@x54{+mO#f;*+2c2_SIz!NOz zM@WD4fC9#6`+B86nDkc8hZEoWD&=z^`L_d?a(IX1&|QiDo%p8ICzhY4PbvL}UspoY zw+{o4laqguzTwwO{|Nbiqe1xOUk?F~{}Pc$EQ$-b(BS5e-q9L@zU?Pbcvn(jWNzr*3sx3pJH&n!4n`7D$PHC)!etS0_R z+97D>?kZlO?ZVbU?m&EJ;F6!aNN@Fi3UOQST1)zCfX9{RYVu!5zm4VdIpVgi)Y5&I z{4X1&`8S@QhQgHg`vSk$%3%<=exAw1=Nzr&Y;pV-6Mq4? zw2ON=Phoogj}9kM=yu>SnxCDXQqc6_QN(TCtkuiO#BF_65BtF{8~wkP&(%z0=VO)s z`|l}W`MHMpX?tk78U8x)-8gPKhPc`@e_$}!FE?o{6*k#<*?^M<^SRLl+fg1 z8u6z%Zjyb<<@(t|rN87B_cO419NVnz;!dvPoS=_`bAZeD+PdzSiGOyH;yv`6Wr%-3 z{0iE!cM$(Wi_+iDe(GT2?+~v$p~xX7Zyl{lzZ=`{0O_|yLUH9V1-Rt%E#~Jlq<@CE ztrv%Sch}p*KXbCCYxPyz7SI1$hv)kb?*%UDj^11OKrOiIn#J*awpya}A3msbmhOSX zeZT1A#22%_n@IkX+T-~z0xtQPc#`G^X0y9~M*PAL^tbWZ>qM>ht33bVqr`1Jp~=G= zz=gl>2itKe+Hdhr*|>Km8%zZ5>?PW1}_88lxxf+uMI6{xtn^3DQsPl5&Rs>PiJt#G8S;anq%m?!Lq? zB)zR;-jevez~y_BtVioFYPuD_k$U(@($@ob{4b2w<5i^pGTXbA!^@6-yWnB3{qEYM z{5NMqEG7Thz~kD{l@1>tEaUecNcta)>i@%uAJV7wW$U`(W_Q<8;F4}X<=@hMl=yA* zi(0+xiH=_A-!F;g^Yg?np#3(U{C@{r>dV$MP9Xjk>0hV)WA$|c6q@k2{WEGwpBhv= z`H=!9|5p*WeM{aV{naNc{ksnTD#P|J<0!_p>J5Bl2-K9Vc@%@OeVEzq1jQH{UXoA)* zE+g*8X?&CTo8MQ)R*!!sKIYeoZ^v|ZJ6-d$>R$?Is}F)N5clVO9wmP4uay1)^4atZ z<#Wal6tHy9C;q$LH2-^({_n(>Fuvsx;@|lU%jZc2tX^at+8*eqs=e{`TfmKmEZl9k z70PGYdy1M|brJXdnKu*fU|hig`dYBZXT`qVDF~SE4#bZIE_%S1|I>+&{<9M9NcwL9 zm;Th&g`1xFE$PS96gf)kkM=oJ`TO(!3xEqBTjy_lzC!wy`zjx+$1Oe=Up}qCCI6%D z(F~%QyX#WoP0asY$}aeE0X|!urF@?D#)+RJ?#Ib|iTIr_X?j+7cL5hYX8VMg9{V%t zkN!yMx6)g1=-E;)`BxWk`7Yb%;+M?-rNm#OeMNI5n6gsoUuC_crrmWpaof+y^yD4D zEzjZ9UvT*NU~{A+*WP*y>OZgiU%FcXtFMcI$MN|+=}+YMT01)A9OZNCtIEgZYANyY z?0-#P-9y}ud-*N!xO5-IJkZub{`$C&e?imzF8c**M@xu*K>x7uyoC6LX)XBOSPu6R ze}MV7@_Ze*lV{J4efnI*tLZ2wa9O5_9&arY{P5f=PFSGalK-`ZLn17M-ub>@1m;4_l?vF>xS1J8v ze^5e`!=s76w7=H-c=GuxaoZQk@;UKh<#QALik8oFiTnPgZxDa_XUf>x{%?r;_Qo5; z{dxJaOEle&CTc#dz2630>_FR(;sECVdD0(1g;7oXfJ>F$_M0drUJrb0{vE#E3|!>a zkGFi1xF4@F7J@4DPqUm)AhS;s-?KBC|3`_Bc~1!sCH?M~D<9k6PR>%4>u%!5aUR*~ zYtt*@^S=(&lA8!FJ0xu zo4rT+?LMvLunXz8y;{@VXSD){6JG^fzUwu}kz9xAEx3pDw^5$0{9ght>E2SRJ@`JP zFS$nf@5J`L7xDSTeY@)yz~kg_&uf*>&bKIoj~O50ckiX&HH-L-#BCozKzQuLQ z$M=g~K>St4VeUlwUlCt8Nxye8@v`fckL@S;3h~#7|BmCJ?T8htk?JLSB;P(!a&nd(YApaS}FC~7$lL{P2{C(geKeN0zmhHc){EypPzjr^< zKMh>;p6xfaJMn)47rFfqdO|KvvjscfsC*tKFjXH1M-Z>1U)1E`L*l+4Zx^(4srO&A zUQGU*fSZhwwYzl{z+VC``M;j?Bc*(4%uUMw%;y!b`l=${@o&XV9?m0Pm(cRrlze^- zT*|?Z$9SLgzQ6Rvn>F3%y*U3*qP@xYUb%vGh_A0t1DEe@ z`jgV{uAd!TPkaH(c^7>gjJi$vk6)v}eZ=Ph7e2)qWw0;t6CFK&gl?-z|2W4%`|;Vt zZ<3GK9#0~^8|@Ypm%IKzypH;?hxmEuZzMmr{ZN6a#J@@0_k&&bZKc2aM9sg+_ItqX zZ?bT=Ezo}m{|l!m{h@r=Nc;oHi(IA$&LM95#Qt0#2QLu!=bbk}zbpK2tB9F{3H6Yjs8%4zvOc-)Q?;y=gq+5^r6Jr z3%>fZN^kc0*`RlN*z=!%n|y4aVw2~mn6B@C`@qpF@9@7<@6dcc&xU3Bycc+!T>XOd zzQ6Hx;&1&4{)gSga-%*p{ctkzgZaHC zC%+_a`zrr}{4e?s<>Tw6Zvc-g|JOjU&-m;IKdl}={$rsZA59diOKmw;`Ptz`$m5;@p})| z?>&h8?*kr}&k6W`N%#2om2hv;Hxu89^Tnozzd-ziXOz&s>n`GpST9S-XKSZV0`BMEWX^n1YGiY3++0SlhJ7ZB0qkAx)1SrU)Arjc($W}3!iJB zRUBr3yDlW|&m;eZcq`JEt5R>l?l823kL@RK`KbVIWk^zYoA2=Pfj|B|iTKKMl-l0? z68W#(OyzbmnY}^W_rGoPgwEsp>n}=yOFn0N@jT}NmvTGdCS`2?mOqmIE41G}!E~$8 z@rnMNa*5{WOyc(d7yb*-zU8v~e?_Co_7?(($a6)ewB5l<0+3GG;}ZS@u$N8HX~F#4N`pF#a& z_5Kd=S)b7FwK&yJ|5DQ}qduHK{-+Z^0CtmHmd`n$i_8CY#GhurznQ)kZ1$^ofAxXD zh0jl4Qo?OWe;jbB_vW(|FgK3n*5X#-~8W7X!`jI;1Vyl z0Sjqj{h^jrToWv>s$XpKBwKI3{0NSekGpIa|Q6t{-pV| zb9-1E!RS{N-<0$Irhn4FMK9U;7+W&`7m)tKZz=$_%S@e)wFZA zBAz6^>9-Zwk@!)>{q?gei2LKILta<@fAIV>7Z87$_Qt{F|0MA`=4X52a;}i*;WFxB z%g+{XD1Sfh;xOPsZ|8kjy?+|G$eW#~!s(pgX5i9Juctnoz;e5n{QYs|ABg*Y=55}L zZ!e30TiNoH-0jK&^iKd6dD~^FW@KN!RQ{j(T?@}pd@}J4;6m^F_iiKp>)A?w80j~C zOX*uV9z2%#?Zk^&{-)=jB7O$rEfVcMtt?{3T#PyHF1Ca<{ybyJf(!DZ?}9$ z`TKFIrvewbvU7I!Ape_*+c`iz#2+OeJAcLUv)MnDzaQ^$2=U_YD+ALT?Zm6Ur+6Fr ze}lLmS9Tw9J6G%!t)5`VcQsw#ZaIzk*&iw6>&U+p`c&j?9`&L1i}*qw46QG~V zXh)GexB>JcCw7j<1U{(5xJC58o!4UJa3pZy|7-erK0*3>fyb4@xFV&u^ZbnF5aJ0> zk6l3AUx)Q4;=Z3bh4+o8eUsdO4qWoN#PjRUg`Y@pe?EE@@!i-U8p!Ms;=Vs&XS4_5 zW9R<8MfzRQKBXUA&HcB>5uXIy(f>dJtC#DDm;FR>)04j^emCuH%g;^d4}{O-C#rnf zw{JQ&z8roJT9{mPfap5O`6 zuY6qbgY*`>OnfKw4|3V}Zn>%Q--ZsANAz)UCh>XH+XoQ;0rBHWxE1kV0vCC<^Sn&& zz3p&F_r?0XQ%GOEnWj6YUGYtcpF`Z=cjy&ADdq44aSUy&6e<$wy$xlVaNxym1eae3^)7=?{tCYhU#^G2wTnSwA^DXL=O42_> zyn^l8*9JrT_X4TF%#y{umgF!pC2yb_H=e53`i? z_W`%O5puWZNdMGChml-rAQ^n13>T6Fz7A0ET40?ReC=z;wIvL+}-=c z&*)Y@yORI3?c(!uNdf#3;F3=}f7bNOhXv@Hw^#bxVHe1Cl-`1G6W@t`8!PAcN_4zq z=kb=3elp}+(mfM)kX+X9p9x&_u$`}Xx;_p@?O5dcW#9k2C2-+WM!mNi=?^9D?{9My zaFJ&_htj@xIdDnW&TpGVK0hI!y~?zlO%EIj1up4U!yhBp@p=m`C4M69DEqGM5dSUo z{`%Q=;_t!`KmH6@0!`AO#iuZ+oJ?cTO zYE34PxE#TsVE<+9F}bJWyV74|e6ApVTRK{go4WZd#CveSlp%ka2X+0m7Y{QDxTNdH z5j{iP&bKx>zX$O~LhsM>?gV)f{JNy($I5vbaeqDL4~Tz~a%o&P#lUkfH+K11j~Q?I~} z>F2zPxW8}GUx>edpwgTFt#x1JW9Ncz%ly>ur}(+F6O8^c;9}nf97mLr{!!pkk9IDu z*&DBskH1gI=>3)d-LRYFvU)k1_$xOnV{1DLiEmY@^d|q06Zie@PQ=J9%=%1{t$im$&EP#Ilxa7x=NBtG?^ZS** z^%tG!Cxre(=Ci3-Q`tVDxbM$DfcU-dE1l_$4&u8&56NZq{upt8-_$M9ZYAAgS?^}& z4-milZsl+F`yJw!v7D_Rf1S8LzcasF`LAO8Jx;R~oI(7?r3zTTe;e^q_RD4m{tmdv z)oEvIe#Yu8*tSCPtIknid*Vj`m+!i1l=7!p8GM8IEA$`kP5Q@(+xha=PVbx?U++%? z7ykY}&wnEB?<-r3@)deNuKPHLGZUfP0O_}3Ia~ey2l3}w@1_smCho5ntF2P|#Lhjn z@9hOH`FZ*~nyC31u5#_Er&J)S>iz9E>|c>Ca{T zT0ZNE`{R_Sh;Ln|e9T_@H2P7I=Wq2XZhY=1?#Gq=iTJy)o8+?gHCQX{WqfeO=QaNa z>Mi&Ra5w(CNa;(7KL}jX_16o(L)_mtd%M~3?eR+B!pGlN;S9*1;Lm@k2_DIGzee1b zha!}V(Ci=^**Nm0`$zbZig2I%rfc?9Nu%=j_iZ>1xU{cT zU(xS6jFs~x();>+_on##^Z}RhziqLmYwi6K)mM_B{V)S5%=f6s*YAZzJKg&;`cNEdokTRiTm*nza@U{`%1Vc>Gwc? zAocRNC+AJXAHg_MF3bOe#LxV?GBEtmW0lY8+bX@ue{~5GzxtM(L8RC^3*O;8&O?=Z+lzuMx9CW<$@z*1N3AnQdJb%cKNPp}1l!4iM zFB13n6FUn1w6yCrXK1=+pDzP0<$T8L%I75J=NjU3cTjq>TaG(H+udJ&q=YAs{%632 zkH25aCh+?RelOd*wTsUfzKim=`g)$Y|6Lyt_v0nn7b^d2;75_m?95L#EAF3@(oNjo z*Y`Wb{kW!=h#&iue&|=I2>KT(|EqS^bm!~i;CkSqm;C**){wr8e$EEczXROW%el&D zG4bY>czv}3xRmFbBBeJyuyd>8{yzVQ68}k3=}itl3taMf%2k@6jYGdf`ooK(^#1}b zex5sNua0Iu4~O4M@-yWb1$HBT0`OA)9lmt}mvoE2sHnx`{hWMu`h=!y?R4`t<=@JF z!Q>=ET*i@d)hN5*DdM~RKmq&SD(H8~=gP+wKZx{mh_CKZKIVUWoVXu<_y+OYcT)N* z$me{Fdxif_+ePzJ(H>uqjSh!?TcZq4B%eEg3!isyR>0cbp7=w`?QgV`f1$|)_mTdx zyOiGS=f)G2&pihzp_SXi#2cue?Rz&zzb@&Xmx$6YCcc37u+_^G#BW6Vlk3wIh?)-N z6%EiW0)xf2H ztoQoIX43ESRi#fd@y`R7bf4W+^Lae+?-BRU>uJRJN9g^1Uw=pZbNeVCE9a(Vn$PF2 zSH`#N<6s4F;WKJ?1*S9IeU~dto%z|>Ot@Z`On&KPlvEN zgI}Jm{1?qpdeeKwuva8qe?IE~;L>lFUaItFXEp&BIT^o36TFY6~dANZO0 za%%uC>Ath8^0)T;Jn`EQFD%zVvy{kRl z+}qo{Je}$4?_D0W^)`2A(yarXoy+k`=vNw){Sne7nU0R`le>F6S|{}^n$*$~q>pXv zuS?YQv}al}C%5-y(kTT|gFSgLTm2vOZ zOYyeEmRRo9@`SwFkm<=ZL%L_SXF6J^Y8@j3jqRso*780IW`0+uyKQcB-_o^_mM^t* z)`7ZaY18ta%sLPzDwfXc?yqldS(<5G7xLuN+OEOoj`kdJvdSbeooj~aWX7R&$%T6k&>1^(E<+`?H+S)syYS`l1 zp(>iunBA*u$zpj~_Uoti^`SA($n>@Jw)cqcn-3nT!BmAP27K#UI3=p5wzh`eu7%FT z+tN^s<2o>@h%yN!Ujdzh@9J-Far(0zm3Rt%b$6wkyIS$>svhNcS$lhsKB8{^w5fG? zWnfXdHjSD}l;x_oJdqApWnRgpQ$db+(&FBpmaJY5t2t4_nPn|Yn!6TfTrQehTT}H5 zB>9LsOeE83sLf7fy#PgWaz3YYUwao6WvV`(A5?9QUtzjrRSehG_P(Cx{+1;%d_`@C z`1+I;QV==ikxVX~*4`!hskgVgcSfeaxxJ%rP9|Pm)s+(B^ZyTQkug1+%}-3<`cj)w<r?auqUrb9ST4B5wurIP_ZubE!fVpVnIPIXN*m)4!y<)n2Y`&2;v3_h-6V zme*wlA<%h1!OX7*t3qEixoWt%ihickNp<=?XaA1-qYpuS+jEd3r}X#spLQmUp!@Wcqs0CNmAr z)~k)MN|doz5)&b%*{CR-4Svpsu2V3 z!IG$K;D8@v98uDJsd|)TS-LtaJz}^u_E)ua_nzF`+gjT&XKti@W-Cp~ryW%>Q?rzn zg?Y$NqFhUFdN*opSwGWAB*O-03KCS7jyCty{HAonJP1K$Z>F;wBYJ!vTokaqYa5S9 zrz-l9V`rv-B#~|!fJY+T4ja3+t}~IE4Y0!O|JIB+E265!vR>hYEtN`5Pq^Z0?62u; zUJCbtlyJj|i&9qFk`tJZt(g`$G{nM|Qtzp4N~cgmE-xa4wM}I?AT=MKKfkduPen#Q zetJ@by)2K)vWNnNU}xo>8MVrvw!A;1dOh+WTg%m=bmn!>@2Rb8uS}(2K1j2j-;=6e z_ajN@Xyj7iUSd{KZYfX2FIku>|FOw)sH>TmgXzv{8gn}7~Hc^Q-0WG3U zBGkOfyD}%EfzgkHwv{Lw=xWD+Hl%ZgTO#P9QmLA(hpM)*Dm}ZQzR|&h^-bv+J@Zi( z(r?aj{UMu6qC6u52Z)#(IZT@j&rw39Qfp>%Bb-K=8HCU-)8br8Boav!8pcwp2WngJ z5eW>!;K%E2Ztw4_ZAmpYqX=3>ddid|>T0J=Kl)k4UB$WLm`i={^IWu;Fb-`Y%bl5_kKyuyyIF&O}yqqMxd1 zK|@Z9cc!*MytcDbslf)of~4Cznir!-(YBYGH|NNX!BiRC-1;$IQCEr5oZr)!>1v&e z5@}wXG35$&>8V}I(_&oJNI%;GzfxaqJ<7jEdI5C%ZQam^P3g6}!xD+6=0zPDv?}PWC(g;x+&xsqpONtIBYR!cG#DFsniUUyh!zgEOzPmVe-Oj*XmrS&I{xUIx%^= z&LE(De`+8zkV#b2Zk-BWBwTe%V9#Xb8r`n-5HgMte|t_gts7L`r#6uENSTvFGA8qz ztP{%X;=DE$(+ahJo1UmeUk-k*z(O*UsLC5?S;0hQs>VdBAI-BYjX_FQ#Q5!5tIOF! z`68Hd?6IYX?M%Ra9>}6_Bsz4Mz=pX_a`g>$N^kWaI(Vzg25MbMykGk&{+eq z%DT!a>u?8*&yKWc*Us@tgVL_G zOO1$Q#L6tk*ur$zMrmJScxStPXU^2l7Nd~ORPtF55z940v3OkD%w}KP2TkT_1MMB? zniA#ikEyP%d+BJ8N>`F%q5V@sre#pY!ZY_g3(wxt)}0fkoU+>(#iXUwvmEVUDn@PT zsbYP((n0|hC?B-tsc9(HY*(BW4Hy&Ry@e!7!w}yEltXnJt%ur~gQ2l0x)$kQ1|cf6 zz?v3#MKV&&l+9aeVyNaV&)LHaWjJWlcix%#JzB?7Thlwb`!W%=;MYG&G{4A(&^^fn z`XI<~XAjIVnRQEdh%YRaOp32N|A8=frb3=jTNhPGLCb&(wW@=ojnv;I(H?u-7cc4W z?6&zS-yF@!QThC?#w7#&t=%VgVZ@)pyl?%SK@pg20Va}8@6p9T>jV-M);Kn3({ZJ| zS~$gusTj^Ss~WBE@2#3U&@c9Y8zB$hfOA9W$&RJed7fnZ_M_x2QBAiChj}tbWk#x> z?*#m%&J?OcFKnh+R10}Y7$>N_jch6A_=^W1(g8<0Xmv8$^Ev(}YUw4a=6AVbbc)GM zsi8{3_FboxFAcM-0GTq)Yl5zzLz8VLBHp+@S)Ezdlj(&cs;eK-7R}-ug*8bpS7Zd_ z%rOiFsi%>(kk4YyFr60Vc}|N8I4y7ja*XW84&IOp$X+6ysIk#vXk-_oe*T|Rv2at0 z(mW~M-@F+9PZV5ZKiw*2so8lp=WyIAVoVLouOj`V%RsUwXEnpU-irVmIIVg!h~$yE z@I}(mW_$OX>jhS1Lu1rKAc7EW=gGu0iSt08d!)>FO2;dj!|TB!wikLSxM)M812?=A z$8n5DS8T|#bPe23^gB7aa&1}WM?~jQo))i4e*Q*E!bZT>Hbsd}vc(OVBF-1ddR*_} zsfI+1YEVPg*I*GPov5A;e@#EaMwTzitc#TamyOqp%oD$Y3DO7-MXS*>hkOa)GVn(D zI?9BwBA5#k@Gg)8!|fIbRDWW!4G7KE)r8rh$?)3HQ>>0z8M)!V{$yn@+CXJX*vM(Hkn{^=}?|jAF+ZKodmVCYY4T`B0)?60K(#sv$$YVU9EP&4yXe z89kRpzlCJ`>qNy-?Y$X9m321vi%F9#4~=SFlbPDl-rSdIO|`G*nAVNg3s&sVp;F1p z!f{9;_e1t;3QXNf-&~`nJE~@gfst$XP#96a3?_eb^_(cn%{3&da(~yW(-)c!R#N^n zMzo%jlbuNe_d{Ngk^3x&U08@s+zU2Cm%SmQ!ID)n6mD54B)h%NO_e{PnH-bugtCng`+wX_RkJQqd-2W3U$$<3GyLx%G;WE^A5 z!de-VQ2I}p@q?IY&U&R?*JUVdGI7FTCeh}|bZS#358)P~fs>m^+YoyaZp;Sh3eAt1 zbA)i1?mK4Ds2k>#=LY|nNEN35=EpEY*4z&d;G%(ki4%`Z6N~eGsOeicXtUF|dHsxP zvV1oO(r9XAHe*D?DFSCE40~cF-yrAQiq5oIs##q-Qf+rAf6m769~JNs(nsVAboO(T zlU=KV$~F(R*fVZ~Tsfm#n~!vLc}**}|3!S0^CF;{mtOEKbj&=4$qNJb`( zMAK|6ySh<5Ue1x4wcK;#J4rg+!G_g5djFo~tOR!Cc`lNyR3tp_Rif;OO#eJg0>Gse znYxy`h|cE1S2zuZ6=wLmFta9;IdBPQI@4`kwZo1tnH(Emf}v*A`h|Jp4?i&vG8vmbwD&JXcaPYXfE}32w zi+YYMNRk$un`ThLT;Nl_Iw%$P`sPyA3gt3_OJWwe`fP{;>`KCTRtSr#&+ zepPRlCQ-@9_06(C6Y~wJlmy41)rUMXI=hY*6)qO5A@^K-3v13QnO1D>&7^2s z_(d17`D|bwiZja()f-N?;iB)r6=s@hcIh(KDZJQ?fzVB`#jIPbX|(FSB1eZ~!A+*4 zBG#f#Q@LUc7k5|+v;Av?AR-OrHDr{;;Dj&N~EyM znqPm}=ANuw_ zt1;c@!p{(WhaiC-2?NSDvyIWkVP)RjG$NPN^CV{2eTBq@=_k5SP74`x@iDeZp$<@pUf}^^%a{IuyEhXYz?lzEQ-%H8g@MyVb>A^ z2pDmoRcTCbY4~SWacpovuMXAnG+B7KB_Vg&1hYEQ(^SJ%eQs)@kUvKrhI3Gk9L&S_ zBNR}h0^Oe)73ltyET$}4!>`=fVW$Z0P;>sZ^P%rs+q=>Om_WhTTQ^te`-ccgLe^m% z<&Q8OZb297iOxl^xrgC07$O|f)edw9X1=))VQFT$3w46AA_~I=MaSrGbmFd2Xo!$s zZrM-uCz{+kEg7rGL?FH`wt(f)@MC~NiXz`|ooZA$&dL zWF5j~gxbQ=5p1Q?eKJ;cz=jtCaWF4vWrU`qVEl$=qr@68ujGdI%+vyA?8UTnF}_hO zVdJ|Ip>SzgriP55L%<#sxq>iPU%CZF5-pHPi3(A?L#T^rq(RkOtT2?R^>*<}SIa{i zRH3(#wT`t7^)nYmoY4?cI5@@XoU2~*bT@(pH8?RfAA*(0UnYrQ7@JBoJq#~tczUc1 znkw3Q{E=$iqB31j$`%(FZdIrgo;p;}?;v;K~QGUJpO2o~z$7=nEe~y}XgL?;9eXfm~ud=|*K>;t3W=TZAiJVL;_GMZI zda>|Y*0P`r%`PtDxL~-8*xS5VyQtlIVa{FS21VDf)cJNxe2ef9swUyH5RU7 z3mWVd#jgm>66D)H3AacX*~lA14AGA{;c$gWD+(3k6hyXg!+tlh)#tRZ?G3j`;h%_^ z<1J(qJVJ919@+{}vk1;b(*oyH4KQ0A%I>|_9z+P5rg*6>1T zYb*|#G6joWr%tO)Cnl9=iwJAj8XCLBC5owoP%eZZ?^D9l(U?V8TUcep4~NblBTr}Q z=fd;zlCbQX->7gYi0=npTFl2YbVXyXhO)EPYTJiwDqS;IIC%@0iHYNcB}?;lB2aLorN&e2fUcd(E*Q*Q#5NMQ0s?2CEu?nfLi(Vo9hFP@DWDHH9T}dN2be9LA-4UA?)w%UOqy?>VgEZ z&RKh?28b$6&$aYOBhyS$;eHCs-dj3*{7<%iTI24Axm%CLM?0I<94p=q4~V_U?eLIi zlnoUK#@K~y!}8o|L-n2iMed{#&}K66F7pEwX-w$LK0E6t=4ZF?*`e z#M;L3o=4X;G%YApw4u&$1WeAn&MoGnE2kki=*XUwTZNBCiNURGbRyfF=xzXO83^K) zydYmEpm0E`Xf`#%tB83SS#1K|SQvzzHPVaRmWUc*h0swB9ZanwlsIf@m>6W|xSiDm z_n(dsLOTepQ>0AL+1%a*S-_|oexHuGolzv@D^ZTHF6^Ju4VlCKCiDToxs>Pji1wIq z;UuQ^9A!*3n3p~OxrPW<%yWArVL?7CYNN%aCz1%l>c9qC@bh5NwCqshrciQA=_792 zh{+GP!A7h$E5oppDK0r3P!hz2OO^dhE}%MM&pcJWLZ{? z6_h3tvdt7Fu-!u5RavBQ$Ey}Fm0Q+J5DOnb42|+7^jD{-0%ZF^K?!8vdTnqK{K|l z>6cxJ%99o_?SE!gPbF*2-;%ffLBiPGc0PH&E__G=oBR}f6OjtCkQw#~)nwGP7^(5h z|Cl8vh4&oVc!oIUN3cE05b>}7kC%DG->RDj0i|cvj}7&zk=P+K=%VGl9s#d; zR)7Ao4vdAOc57&BT8yMIpom#9f*_%K7u=QIJprrDb?y(YAncZ$c3U&T6P`CD*f`?L zr73-~Zv&23Xhs}XcpoVkFmaor!SvBMUG1Lowpn96g!)MFv7`hqRNzx7P;^SY$ObXkj(VoIY8wK%y@8TkDxAwe`MX4=3CfEU8y*popzONR&}^9 zaltZIxQ_cV<|JzPYjoDZWHIw7?C*+-z;L$Wj@zmfdcljqE3ifST9b8Csk)skO^rw= z9r6hAtMaFH3aNW(p3&WOBGc%J^4h-afEBy4P`6@Cy;1!NuxZ6x#sGC0PE@9y3GIr? z;x8nOLxV8aX@%4}M6mk$CM$zO3@Q_qwuQ7EdF4t8igEbUqigZqmF4y`%GqMW4la>m zi0T~T_WKjXO?G=WFHqW*KsYoJLY0m39Dau`brtbm>B%2?1DmX&QPb3ozSC{p?+l)( zZ5Hm6ld?ob2C;PbHG~3e}&?yvdJVD_9&;#xSqi!Cc=L->i}=cfx7ZjFthHqr#BRZ%E(dn5)-F2I&&2~E!JHVm1? zNl&^ZV>tB9V$#-r${kvd^P;bBV4Cb&JsW-m)O_PKxS#d&--8d(nbs95o4VPQvl?%a*0FO02J2f~NbIrw7Z> z8OTx?o80PK-q(*{C^xy)9yJaUax9pPif~qQZp31vu3-*UvYt&-G1RA#xSp5=dD(M1 zkdf?u3zmn-%QlOJs=t)~>2Ua319X>!*G4P^ITdm?=G$=|B-$w( zif`muhY)AUC0kBXDHYrVtqsyV*^H4lVF7E)>D^ah#&pbqy{s zC;OpMomy*n#bAm78r_Q#yIn9oV`%lA%9@p&J_Cbj|$%PrrS1B`qXL$t~{8^lUJyipx4zfu20Nwwe4P#tiU~53vo;P(HAY;d3kKSCckq)<@P_iJRtk zJx{cC46|kviI50Dn}tsbThD0NkW+1gV_~D;W~)0j#91;fry>mW;q)CRS2;xe8Qx(# zVs}{c6qCc3yIfI+CkAy~il&T}3hoeA(Tp+&7qvTVs4-k4M%Jb;!O}PkpU?%#aX^wa z@4MqAlXfbGBf8xNh8MQMha4H`c-Z%%Cf2Tx;?K*<7RyG8AvR4cwvF#r_X;8=gdl~} zZ*5tj`(iYICk(?~>d9k`B^NnoiJonlwF8FVv8jtBZ>wjQQ*Y!woLKz=D{UYVAy>R7 z4>{paY0P5W(l4h`LTY{l7WRb?5wC>HKw>~E()bTDiP)9!es(spE?}+6pjd`n|~-%Xt#!ut=62AULyI-NgvK#B&@(%xk`S>EgG{QSPM>=#o885nTO^m5;{kr zJo1kDkeQ`*I_6^|IbyukS@FXHo6XH>)gep^=?aFgb1*^-1&f7ukP*9r$B$&w4=?+X z?G)EDO^GnVE?aUW5)OxmpQVcv4sVH`ImzQl3x=meWGnk&`JIKRN7(~7d@NsfH()wL z;fY+*-D;anYhh$-as)@R&@5B4X9go<4H~sCV}=nK;OjhV+)h^;XUW2P?a__mg?QUq zx9ED@ux=YNfFB<6+!R+~o6b8aEm64u>v}Pf4Y!$D&HU`HWay<-1QPJF z_8v;32DY0;XFx+iO&VEj zB`d3Szn{E*15uj3PK+5K6qq#9Daj#>;$%hcY+;6{duv|(vgb*(!`*2JPB*vL5PExW zr`v4P{(mk&%rux^gxN37n{Ta}ileO;cgZP6cKpEl?YqM*Il|HzZhDEyoqD1(2JP<5 zBY&!Wh#`l$4g9YvI72|~pEtrUXsOc85Sm3P$0iB!ZiP@;=2o7_p^1rV=WtOiU|y5; zJuh*I=!-~UM%rn3_b&~$WfKouM9G%)q5(PnQ#Q76A5$P;(_&NDX%AmX$>BlR;a<*! zal5OmrQ|l!2r##b)Ffv3Mvr)go#jyLoc>p6~0RKX|Fi?B%?C(Iqrv``(>tPFY@Y?xjf=f^7K4RH^{R^7U7on6VZpVjKd zjPpp$Ub__`*0pS`=}(-*WNp51!!r$w&nmQ0`-X>2x*ZZy-hdawRfp$q->%w=E}BG{ zbN{0mwlZdQNUwjQ8k-cLA8zSw??D)OpKN8If)*L}N4-E%3(Ll5SuL_b@c^Oe@#th( zUFT5iG;E^}bo!wXwyfDzV0(~kJIXimhltLMI*PJ9ytcUB{^J7E$$9N@h;7{0A)->+ z<@!#ChhuEQM@@y!)`;0uJzG$om!x1xr`%fG^8SIIj!YU+*qs?H36(k1+~Oe2oMMEZ zqU9bM{6xPkey`Z5Dvc2V9_bYRT(&akB3V3LrjBD-#_O!<;ZKt>;7RTCQ0HxWMju2y z(8;7svbSay4J_8VKAtDDo>_pUVU|+7;SW*q0uSNZlt{V%{!#AlAQsjarg~kdOi1}kVYuCAn=#sK@8>*6cALt^{*J!5UC6Lr6cd1jw<442jl$k6 zjIJE|WrBa%WLy9A-$&Ni^g?${|LvNQ<)NX}W+( z_B2SPvf&gUfSc7eUXq=AGmE=>vD@Ylt8=RI$VDVIP%dK7L`6JT_gMw)iL4bt+<^iA zcg%!ZP2~ykI&}7&egrvJK9NHH@&lhTS%{8pW>$w_hE{4E5dJ9mxtCrD8bYcE5tgYQ?%9EE1kG z=vIWNCF6H5lj}PMa8R$zsb>YZkekM}-t>m7R7AXQWiK`|=rc2KeEEh%{U^ z2B7HIB>>ptA48 zZH##{>AriryES;VwWB_|958DJq8!&J3ZxamB!jw8&~NG5Db={XWmb1LRG$o4`VndA zqGWU1DXeGG33sHLXQ|S{_w$msQ=fGQd3Mq|9*&cfUW^dax+qX*xpFH5QJ^IiGf_-wowYpxF! z)m<5l>dpmt=Jt`2z4IZ5>lp|#IW`a^Z;KW5tiYmrOTy99t{=(^3e9yy7149uYHIs7 zY=S7;reZ?AA$MW{gndaVT{$StKQ}e>U+9Kx8C>ML>d?fprXF5}JmiEj26VXzdeFRsJ<%xK*4r7!`4+;CQ<(ws_LdO@q3DR@f~Vlm0?*%NB7Cyy&bJ)tC?fRMk&!=(mME%QIWOm z;f=^Ig*ZP1P76rMCW)~dAZ~Pn%!`-eS*~bYT_;D^+vM6?$Oa1)bfhgcH`=B>5Rwhn z&z0D62fH;&d>#*#OCdBBr5m?80%2detO`!ZA%)1*`4H`Bq~=``WuYyOT>08IM|s*Z zvb|1nayEp%sas|Nr{nNvZ*#}^6>Zu%Wdm67jU)6eDA;w{uTnf%8*d-&3W;+G&0emj zWkXM7jF=P*1n>$rHsaH)ix};$6K+EkVvVQbhqsY=&b7KREL`Ir)qvhO!4%@K?D>%$ z@f6+-Id%Ze$rxW#6cmBPWH$!HrtA>HRu>ILhs4mWx!U&eP{Cab@e!GRXD%tRE-S{7 zBDSYEV!h-fc-`e(Ok;hf;Kpiu5>J~#I3N}Ul%=sQU`D#p9a*0BRAN3gZ+{`r*NMCp zuzV%LaJ{DHHioQYDzg!jQOkIQQtTQ%=?{IW$y&QZ?3s{A%;fZ!}`+YliZoA8|uTv;HCEX2o=qh?lpeNrCpAtEmJc9J`t^{n^*=HnHqpbRyhk*wznw%-5I~(xzx6 zuFW+}nXVjx-RUJl-3^?O^ZY*AX2RlHjSO7vv!g0GvTZ?9PNWs( z9et5#IgSf*XJNytlc2q{?rW}F^9>cBT?xgIH4j52E73-B0M3zeV37+wLNtiy0gHs8 z!H44yE+sEAl*`{0K{sKpY3OOu;Ao|bPHl@fq#UbkF^d--_YHz$ZV8e~pg&-##A;)> zB2x{J@fIc7D5^#x)LS~byE3|c&pc?@NDwy4Hf~`F)~UD^#9S)ui9nvy!9>Lk!(@yS zX|pVWjqd!-9^VSJp{u&WBRCs#6%44awjg9wwF+%sZHuTxMM@n38oQk7=~#|&L&yUF zNhr@3g%OSRi0tSp?R-7MWO6fvvcYbCdo$ZBG#K@_+=)twsbmZ@a7M7arr{?hE3o2+ zyKGSMSa_ku2n+=)a7v||POqDZMZGzB^M2-YQDMm`COW0%i#^AtIUHRVn*Z-6);fP^&vGDC+=An1DEgAGYA^^LOp7*YvTxE#j-3ho)nC#tL3s z2|2&1Gj3CjN5oDSV_1Nm2;o@}97Mb5XgpEfi2ZN7`c&AAc<`TBtX*KUBDD?#uHm2iPCk$+Nf-v}v4Z{6 zWaH^auP^ibFE(Qp)3v$zQR_|Qxh<0ty;@-PmCmVdj5*vwKA%*9V8Y=m0vVppY3VF9 zK$R%Fjkfg_w}4t}kI%trA$45fGWFY6O+pQqKq2(Hain3$Y?W# z6W$gjm{Tprgb6b+GhygBI~kucDAKE!sA^X=nQodpJ)N32BQ4fN)^V1L{#x6Je?20- zbO%h|N?7MbkRe5$id_PkFIMhzhF_Al9le}&ENjJ`75LwClB`IZUt+PQAM_?7fd)Ep zW=2#!4c< zCnsC$Iq_AKT?%NLaD!)P(b=Mkbmo5eUA44!%w2S;2Udd8-LYU*vUO`2m*M9{R&tGP zBqVQgTSxO^Jw+Af})Q0r5PM=E`!Nr0;oIcIQvoUU{)&|(u&C0Q}r-P zI_?n;x7AaW2ea#srllL}oD|@-eE;xziJ+Vdqu!GtN2eQ}8a$NQ&?;mfTh?Uvsfx6) zNxDZB>oYpQPgJ#ZclPwcGKcQOKA?jct|lB>4^%`KAv!T{k_!9p?^Zk`!5ME+A9-|i z9#xMq+Hr8h+~ZB@dU!k{sy*L3J|`q9@E3J;_jY1O6fN)>uGN9#U@I_+TA$fqHpnz5G~-Z=Wf5@ z!W=5#dH8x%ju+SUs#rYVt5OeRD(BmZh?d#6*i0ATwrYTbEF;F`rv@?unWq2K-L=Fvnq}qi zW(0x(As8NmN-$#Anb>*nx*pDSx~nQtQq?LUgxhicB(91dZ9A#T%mxsPVS`u$>-}z4GTthG{ z;Ogzz)_|tA5Pkv|BhedAJXy-6?HgqWhFY6@G^j12+IlH6h15BT5yCE*l@jcMa3MFg zUOnyfi@jcPdHVFKe`4B)$M@&dZiHz?{cbV6TZr(;6!7Bi%d&CvLC3$3%<^{C8TM7Xxh1X)!+QbPJR0u+BpkVZN9KfqsKQ zb2jDdu027>)l7RJ$rk23Es0SGxxATjD83v>+-x&~!7o8)3z3Eq!5>DkNiI|kh|5C1 zH&H-r-Gr(oWAKnub$^p)6wp zeF3FWtWe;Wgl4lbK6QHhM~?tNP2P+|(zD(SzRGwrh`#TUN=phYYFsImHpo1pl-(Iu zzSc(_BCSMzSZYG4A{HgL^NsPS`?z;9CiII)7Wm00G^)~lY3@=61jOquWC@AXn@T)r zY-G~Bd0U2L&(IJw*ndrInDKdm2J>`wLacG}Q}UjfKvXtJ<^-+NoLtF9LF*|)tVq_X z#U5mPWF|et`Jx891d)W=JeCUXvUulH?PYN6`Fa?ml3Ddv95aT^WaSE`tDUJRTlF;tEQK3Yk5{Q2*4J!X4WU}ZL@3$T zfwfX16QU&Bs&IpNX_N+4bO0ZI*(nC&`GmQ4Z&hy_)KY+5#oTWyHUM39sFlwSq!-!x zvvuwbvvd@m%}4Ip!?Mx{g<3P!OfoRq{)lei$Dng>Iy9>co%^W33C|kxf&| zdhy8K^3njMSehyDr=pw)lfI;Nq#NG^>Ah^^CQOf>P@5{|KhOFVKebXJW1b$4R;J&0 zDV55J^<72nYv#2e*uKN)Oq5LZgnQ6nf)2fRxt@NEI#sh6@HT`7`HPx ze^_^;6j95zsOyqN%?BsFTN`D?Pa>&4X>2K(6bdgr-?ye%y4ODv4}JdmF%D5CR1yk+ zm?tm@mqfpsf@&HS)FGahg5T>E7Z7m>@F~ zF=x(3vzLMh%k(NY&Om&f+SXA~FQl1c*N(DMd=gi-q3VE50IGodm>`3G*HP8RHE-BapeUCky8Zfdc-vT`*^OUOhq?V|=;fV!*`lhNKU)xEv$cna-QmLxW5zgal z%M?^g*bJ!DR{*iowY3wJeqTnWj8lyzo_%>7IGZL*;@61>6l4(jUEuEVaf(0N=*B*}BCtNMxwk%;HW>tZM;=;F=5`$T= zP$7zu!v-@!ok{GQO8Y>rOY7Yl=bX%)T&2l zYyb*7lbb;|7WlW!ch$4@y|3jZAq0KmLcut))kjOzw1KEo_}PQ2-X%iZjV%CNANMBH z0-P}Chr_Wn-T!L5E#WN*^iN#RSStGXhIpy`7sZn&&`XjSgATt~v%ckQQVOf2viB@js3 z9Jgj@7{ZTk>%4t_*&DH7t4N$TT5m=u#qUio0i-Zx0w}>=Bv$A+@e`Fu*6NJK-LxMR zY;(AGg6;wiYlX-F0jg11@}x89oTFXV&^GSFwABR0xl3t59pa0!)s_%9nQCj>HcZ1f zFN?XL(Ltekz%@3X^v=gzYIWSbDEb}fUi!voyZ+!ME9o8G?X5%kjmAc6aMgELVn0_O z$NS1t)b?JMwTtW6sa2ApBs+{qHW`i{fT{|uF1~00)FD%imVpJMS1f}DTAoSBq! z04g1{fKFrBjel2Rh^Nui28!T_D1w~2Ciz^IgrA{N6KDHyJe&?6a6>?6o~rd~H^rO@ zYg%%Uomg~QUE(z>`JhYkv$1Kvno2e0vv#YI?^YsBAN*NRgFSji&5R}LV89xcj258T zI7l;w{5g4Zqhy=S=Aqj8Y?kqr`8OFpYHVb~G8SFG5i}VCC|L2{xs}n25~{~c(}3~= zW+%@_!xMwdY#Z{t7WbMLFUPpW&}gi=EHTBI)e)*gK~h`paqs*B0B{I~Tpg+vd20Q` z_Mt|*++#1YSQk{9rerfQy#m}tbB$640S&fz*@Ngj*S80{uud>HsLb z9?cLA52=?lt$S{@HAdU< z@$hxb#88hXh+fw1SH+F&hY|o0?%WauQB~k_VvA&{Xqk}8`Y?kQ#8%TBnj+d~gTA=^ z635;sGYN_6S0KG4F%U=Zl7M9cOn6AS?it2K5nS=8tb?P5OsE?I5=mrRB;baH7jWnC z7>$gf!iv+PqH|LtVhe`J`Se0AjYrPHjo{@Yfe%;$GlGxk(R(MOB0>=w4d|S_>u6hs zVL?KD)a2PgJdl3K6^*mxNQ%ZEwvV5<{F;hJ6FQ<89j&ND$HHW#x&A|iG5F({OSoELjxw^=R{E8EUQr!|rp3ATDb!Sr;+m$z)^49nCN48op;0#yCp5Wp z2;^IxTC?=j30>bP@3y2Bo+17zsOIrVjc3tRfr$WJYIza*6= z00?ZmED#@M+}xaIv;Fv_L7pug@{7K!=C%e;w3zseYR0kFfqarn3ZI|m8Zy`xYOs~G zf|XSfu^ZE!l4AM6l9+((A|^FxJ$lx?v;+&MQ=o@O&sdN3&nBbpr3F$VP;)jSZ->|o z-n%6)?Q4k*B0ad8hC0G#sFA&hO8|JW`)bSI*@PO@q8V!g}+MQ%C=ib;rUJPiu1qV+VPECwu6%#q@)rE&{q13noG^bEdWZI=WakDJkl8(VR<2$w z6uNqrX`bJPYbjwxRcJ^&EI~5)7ZpmLT=P@)0Wg~>y+AZPiQu7K@fsPs`$vFnGx!-Z zi!~)Z!Tcyk)@-zPWy&@KuI3DG0(pQ?vqGOxZop%7hd?GfQ0qMF0qS&9!zOufz1B`NLAm9oXqweUiJb_E_I zsn>YizXLn9(|<<&3FOczz}XnIwGAjlm@DmkS%ok1v1BBFmf`V-tIO3a1{oJ(a0Efb z(bb@JxY1;8-2g~Mq{smKUnmIc@XuC;bm=5F(}cV^@@ z%g`3|3jUHv@N&|BRT9EZkHskkS+|)bcs$jG{PYSBbIimE;1A-LoD|6DzRlquSzJPGa3UK)CbK48^(=JtGI^mp8;lyRrRKcay)(i~=LE(0NHGW>GN^Ze z9ed1t!3dYa?h*1~aHqVv3Bm$~eYi3xg0u{t7^H*TSxviWgDfa!-r>jwsHWXkf~qYc zl_lTNc(%2z25ecPRAJsvv(fk8MIEgL9pd10%0b?NscQ^6F9HrYTt33OUJe zTd>M)hBEWp?s`V2kmN*;3)s(#;b}GrM*N%128C8s91PKL_|sq24vlxoz1`}gl7nN+P#ROPdpD2bXCuh zKWa1?1bZ+dV&;kZMN8fjNTw0aas*Ho;{CkEjWTODSDUMwypU%LO3OtDnPn1uo;aNk zVdhDJMZ`EJti%AsJ!wAIN%9PRBzqyTGoIvyJWc}*Lb{`-q%Z0&*Nr)2P)_^&&6_q# zMJB@mIF+V1?d!Gd>a!Q@$1pd+w~C^$gHh{nn*&0_(IGp08MvRowL`d{iN87zj$8_q zf>J9sie|w4fh{<1@Er385hAM<&^}||Bx^Q)Z1xU)!;X4cr>J&yAJv}FomYOy7;`5L z-GRDOTBsheAM6lDh12T-H7P%ym#5r4e$^W>c#jgeXsed1C~8UhNwPF~twCv7CupJi zCTqwd7K*=Q;mp$O&QBnf-)cN{YZRxFa^b2Q##}72a^jRgYCVwDATY#Q+W{mjEP|gv z%>2WqT!JLKL-1MG8y?)en`5)+kESLfJ*-9Pqb&7+=f4g3CgK|> z0yVM{=JWyCjVmoNWFL>p5uOeYM*EL@>$r@k$Z+Au4fi9YqJBzE$_3F=cLNSTR)y_{ z1mQV);awD$knQ`F>A2l6MY51W9T#^dj3)huKLpBh zF*HBtTuB;knSX8PlE27haC<5gaPY$ovcDBEr(LBb)Vf1T>2O8GgARb~w4hU+K)LRU zEsweZ3IcX|$S9~J3a4tlS&D(%>vX5X@l6#1Zp%;sXPEinn!!ZC^1AGydjCF^?jIH4 zj7A)gv;vko#|P+_GF(CY@n+P@gl!C8mh&kH+D@m?XeW{Wu!D!`4?|P4>?}r&xoDN( zb$Oe4dH4C8=;xQ$Es9?PLT(a};UnECVxZHOLo4ZK4f!{j7ujFcflO z7Di=k3lG1n4R3rS2`y88T8ux5rg@T9#Oo$WS`n}OqZO~uj&ogtN$>hMs%9GyAJeN7 z%K?8&8D5r1&8dDh2Rv+~==)hvIy|X>QF^VR$RQ%7N|6L>mBp~5y6aI;3n|PT&qmsL zXQ(l$NIN|4yH283AEZ`OPXEB-g?4oN;se7mF0-;DHXf=1s0F|=5bp(MrLo42#)RHt zo*`W|Z;tuOM_#I~s**?%maJn+f{lDvh%_E6;H7TItV-PB$E@ILm zgqUo=1+pBC23bu(47S{wtw*=g-Y2!}8PsM!ESka(b94b!ENjHslla(Tv0+L1NWMPJ z%%E9ivJdIORvMR^o^csrvLa^+(?g+ga46wQ`khyW^t|kyK|~gBy2S{Z3sof@7#Yh$ zvf-AJ7&>+Lg0*}oi4b4SgmGEKGcG#g;`AY|h%Y@2EJY9pTD|hfQ*?%`4g^VD%+#5x z88nAR$l_Jp*f2maV~;r`zSiaNYU^M(?;$%+9`E5Es?ip4s@(-zNxUrc;jIbfYFHN1 z&T@F|UF*)^fEIQDNG2W)L^$2WI-mdqmSnkgusp6?*L#SNoQAm2l~V9BwNEwLs^uy_ zS5D!VAHNkucg%A~gqSe+5uSh3Iq6+Dnt;k)_iv*+-+zW)Hb4VQg&W$hUk(T8nTVdd zc5hetFoDq;BCr5yWF&G%rrXD`L3VSs7ZZyEJGRk$Hgt3Z!c@r*dC}`_F6DZ|btYN3 zgORvsSvF*VKab|YL^GSy1gV#MIhv4g??K>jb4tAzAu(RzdpJlCzWDJu}la+ zu<@7nDLMPAu0WmG%?sFXq>Ke3)H>?-gKcT@26$L^_Kg+%<;phBdIN@z`?DVGz#Ne$ z$#!@fRxqmN#c0C+uH^E6Y3?T7mfmJ4!fu6)}+eq_pG@dMojeqnhA=r*b* zrRN&8_XMP9+qhgf%UT=ZS$uodoi5MUd!NhTs4p8~#{^FtF7QQE%q;ZP6Cyum4J;;0 z9H~~=u2h<&8lq}-VYXs%DzeQvE*YKUjyU5!P~{OXJM9p)P)2q$Na5}Y&__9zuh$d;8&cSVA2%a4J?v*DgZ)Ht!R^?WetoE6l8 zOd|Ji4i}K}&PiX;(jUAA0idxTXHSv1`-)bWR&dFNzZ?FXlInUxPX55Fs=x zj@?;Ov`u5t7E6?43h-Anh1R3+-PsumMI~lgS#uGfNX`9g@j)wmD8(1+Y zQAvZGdO^a-v&E^{BtbKx;<&CQZ(IgP;}MJbGgn##iD-eRp_w}z30IC+jyBGh;p+p|<%nTq?8Mrm*B zYBm$cb|XZON0W^k-R^;f2W-ukQeWR0OihTxn63dey%=J=>40@W6d#ZPP_|D{SYW3d z4G>jwFxn7hu!#3#D@)eOgz|k6rLk5ih~n7X<9<8g<}VSSHm5rY-{ z7n*iMA2&8RRj%SId;};)|LFJuD_NLj!KJdaecp%SmWR&^zicr#A(_YL#UWM+#071AeXsjR14ENTo>6$btempHc{^E*YAzXy#1z>$GH%n%) z(e$bOSYUC5((R%AUFRnlAi9d8nk>ytR_m;t*gl4@g8Z^oB2wf9^TN6>xf)(r!v>F5 zi#1GjfuI#bABhui^PZMnVoCXgVlcw>7A1Y>#8cLR%#{btwKt=yanZh(#+-2hgulxJ zyEjuL9m58*=5A6XeR_F#eJrXp7Gloi-K_=7xpO!jqn-8@fk8Lh4%tZxUQ(c}S7wG2 z+w0BPnZ!p_5djHMAn`nqh)gLinrmEF@?i(v!vG1psot_QCe(g40a7cEEwg2P^RR5Norrs(8Uja3;j&2C8~@8c2J$0a_0<<(~1>T zegJwAxP!5Lk~ls%#*DQQNO$_IY>~YU8o^k?vGlQ*9CT|y&{ZNktmy7a(4fyM)SC5p zGMY<(c{vLbX%P>Sf{j|)8Qziyo+hC4;>5DB3^~?ENQK7!(My9>08qhXZjPs*!Yl0= zSso_m1}>2OejZ}cN3S>VvT?x7yO zU9rqAh}@S7?Lf)_$GlB9ls)nstF%kI^m|K+5s|oYp&ycjr~=^-G<*zj7^eI`VsJJR zmPZJey|!WHt&{<8fhjseJ5xNmw^YqSiMG3hdd}^Z_{F*;I2BLAO}%KD+h(E+MhEN$W$3?esIK#nTLi*Rj3@rb~aS5 zUa-}iWqB5s`18*ctntH(YbKutTt_*~VyB8iI=jDHjE97u+#gupQe#D`H*GI6gBD0` zEesQ>_IubQsaQpmr3DD6Eu#z@J?3!1koOcN#6HYRC?* zO0uLTDF)aal%)5irZKPLuo*DLUeRa{WAYRo8mV*ewKPr7J+HZno_PnZtWIwF)6NNA zr(=1&(4Q!YJ|3;C0y9#q-hZ(F4)|ityYs=->It=sf2Vi4vP$nRI+Kf))zg~+jwi3v zv3!FTrW0Ucf;Vk^H!dzaG{F2cx}2`80uGG-@#E_G5I;~;%9T|H39pWa#2LG?T3ocx z#^@~DzBt7}^c{}g?Y2#EAnpTIIDD{nhmz%T4E>poLubb!`AR$eUKitsQ#vs|;nSeO z(8?<4uKPd(tSsfvuj42`f`311j<#cd(AVFH&O*QI|M_ja`6>L<@z2Z;`g+g*W&Hf( z(fbD8`{So(yuN-d`u%wPBYgkgpMO5o^M7J~(AO`U0Y71m^V8Asp5pz_;Gd5FtDlr# z(AV$%vb?8{>E3nxSLEZB5AphA_^0E){Z;uwU;lm6{Gxe@=kNFN`RCsC|K73uqP~9L z4AAS>^XTg<{QCcTC&3b-dpH zADi(H%mLq>$PfDZZ8Lzz|0@2)#xXL`@ead_WhsWCx86+ z%y@nMXT5MU;>*$NccSs%{X_W$ebwtV!|e6z=YJ86|64O&U&sHWBjr`kub=*9H2!Pf zqPtmH(bq5WJNI9F|9_3IXoNn$cg=Wx{fA$3W9g@R;oFtJ!+U@HXMZl|*VpgpgEr&h z^Z!#c{?GnK#_Q{6MR-D;H~sWqqw(MVCAkxQ{d-*)WCeu+-!iXq zoO}Gv{io;G*Z;&Nl`is%{Pn$CS)20l3VModjdfoc*S1_KAW#?~Q#=o~Nfj|KyM4^WVe^t#!R`-4?Vz_1fh(&Hw)>M}6`K bdM5cie7Cal3nk;9Y{^RhooGPxcIE#7vdv

metadata = context->client_metadata(); for (auto iter = metadata.begin(); iter != metadata.end(); ++iter) { - std::cout << "Header key: " << iter->first << " , value: " << iter->second << std::endl; + std::cout << "Header key: " << iter->first << ", value: "; + // Check for binary value + size_t isbin = iter->first.find("-bin"); + if ((isbin != std::string::npos) && (isbin + 4 == iter->first.size())) { + std::cout << std::hex; + for (auto c : iter->second) { + std::cout << static_cast(c); + } + std::cout << std::dec; + } else { + std::cout << iter->second; + } + std::cout << std::endl; } context->AddInitialMetadata("custom-server-metadata", "initial metadata value"); diff --git a/examples/cpp/metadata/greeter_server.o b/examples/cpp/metadata/greeter_server.o deleted file mode 100644 index dc197b2d14cb36605b595aec47dfbde9cb1df81b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 112144 zcmdVD3t$z+^*_Gh@`#EO-}sIZEh=CVUcqO0T)lw+k$~d!a!D>El2?-(2r7yKN`zEe zrKQzcY|&CnEwjRbgXsuG~*J2-vt+pswv9&hs7xj0}%sIPfcV}|%4T<0Xf0fMa zXU>^(X6DSy+1a@}H%7}Z?30t@@Rj47?|65NI?kGyhn6b1)OjT5CyH}D++*qn3h$%v zeh9xy@r@LIkHQBi{62-7DEtA04^sSx5N@XULlFK5{{5KlABONJ6n_N5pTfT_bpI%X zKco21A$*MDk3;wb#h-+5E5)CJ@M(%a1K~D`|ANA2DSQsX=PCXIgukTtuONJp;=hLQ zC5pcc;dc1<8@hi5!rxN-RS5rw;;%vYJBq&!;qNK_2MGU2@jpTM2F2fma3{szg7D82 z{|kg~Q~VtW|4Q+{LAZP<$eUlPDgA@Is1T1R)L+@V`?A zeVcPPFA!u#Og{qXO*gl&ZIdlY|w!XH5RApDyZYk%iw5IV6{{otKROqwJ+&xZ~bW1tdC-=qMdsOJ(btK-A&om-ugDcyH+{v(S0hC zw<`K}&eIrehv+_{T(&2V^4Zn?*=L`v*g9zK*5zAMhf}WYuf^J*+w~<#*?p)FS_{w% zN{!0cO?%LaV;#{qkyvTlG3!mZ-yG{0t!`adl0=t!pS3gA(F!>! z5}XnpFU?1{lxSjFX|2bKjhJ!ATAjZtjZV;tb)1KHTIcqsmCEhU#@c`9B2@bV?9f?q zkyho!mOVWa$ls1tpMEwbnvmQD&$fBHMjKto<2Z{k8AlG@ats$L^yQ;FGdD zqA^*Agn4z$fGad6WZbk3Tks0cCfb+mi?z4zRn>s*h@;y&2Ic}u?X8{5mh8)EExu_< z=VvhcwVoc671?nla&X&o4Qk6+qceH}*`7rE-n9WN$u-+flnOSw_bPN?0#_e#Kfk%D zYIsX3k!o!jUY$%OYU^5t&#i56@($5Nkm-#OTM8jw7{^Q9V?@KBeOC0wa0mbO1*|mx zq`Z6xQLV$^-{BOGK#1vxa~z@$>Vx-qnd5m*ELm6AnD0!it4%hf^6Np<>O?AWc0ME| zs*}z63zCcBCVyD|!bDwb5~8&YwW-=folB|{oT}EARAc?{mSpq7Wb<&&$4NCq$!iSC`+=m_p5Jt2Md%mj@1Z?DLUt#aegS%LSt(tM;@1BT}6Otu$; zKCQCH0IabhSKn6ThN#=u2~BIXrML+mjEa zfDBr9LcWl}7 z#Iwh;JuxWq7AP_d^3e}iXJ8OR)ieIvXJZ|+J^<>ivG(7@+JEozbj;ccgpijv(5rzJ z=y+lh654m{K2r~`ZaR;Wo*H75T(&I+L*!?l*0MbhpQvG~l&Rpcx2U|r&YBcYhn z`pt40g2h!G#U0!IRgqyDXwV7D=X(}W17%zX@VY^dILo&VTCoi*6>pz)a$?U#xmJJz zyG3-@pk*6~Al5NE9|>ctVuPW;yJGFzV>w%)f5o2K*+&PFSkCjYj*5J3KAxduzy)p6 z5#25-5X^9EtYhkSfY*!urfc0g`m8BMH}9A ztQY_-#!AFG)~ef%6+2a8z^@I^8l6jaggpOp)e0?_#wIi`a)jN+a1o{`jU~W_ovI04LSwc|xy+rgPgwnUj88u{zA}mMTqG zT;Q)e_vT&cQ7;i!nSt>CVn|E{a1nbkjB*P4pC5 zeo4Qb{hhY+f0*lhxzGH&a-APX`aL|rc{9@Q%LAOxBK9;c{=XG?MKFB%n zKRM2=eISa(RTt$3^e5yTc_ySR_-f7%`{ewh&w(%ZasK3yesJJ_4;RqYt_T(%8e&u~8g ze*@g=K~OKs_wWj=T9^DO|Kp{;3rI$<2OMHC5DJ$AMCf&}@&5XU<^UemB<|Q4Ymao* zQdoL(Nl0~VJy0z$lae>+PeIi6w$L-$tDLT z_{0TSoDRLvd-5)H%~CttUY~@1KfXfx_t5ca(7-lxR|U9iH~=hLveQXT0Wn}>vOQ$Q z`BSkH!q%l)FuHU1gKkOLO5mZ=(Ejio#RAE)h+fnIU@fna%X(PI`oMBxzWC9T58aW3j}Kmk-x5gk*ZBBRfjwL?DtVFF&Ukya0j8Bc&i zUus>T8fKyMQQwYc%S&$cUg+17z(uA@D!!II0ZN0#mOE#DJ^<_<%+ zV3Q&$&{kLn?ig7vv<$zCUgEdU)2+bvhOz+PBd|7^QkZ(T_#bZaZi z-l!X{bgF|nC9Ef|k}H*1B^w1h6dFAS7%gM4@`u!*8H|fuhnTdgbSSJy zsL(+$4e6ziSal4)qP=E=!ep-p&T)k%1ekoWn z+rhJ-GMR>NJ+>VOtRUYmk1vuo6^srm1oKd##Xey0#GyKU59q>A=xQ{|gQ@@-I4n?^ zSHUYWYfZUT1Lkrlux*c>6Mf!qIFK^X_ts3;AaHt(sH+c(+&O6Bc`%Wx%2Y3bWyfhp zlk*!3PQ3w0wgNnZsOAD;;8VR!>!~58-NU@ndhEQmNFfNO8qpost&_n}Wzf{%0r-5N zz!S|I%x?CR*}7RqJE$Jrt6z+Jy0ZgA3n8Wb9+NG+aX#FyxM|fASqR^>_(^?q4p}34cQ-;1}zk- z16&ss;*bYfxLgolwq(0AX!$Bw2e2!FmIRzIII0(VYQD%+A>@TJNrf;Qs`ao!?_PtR zC}_KTq|2o|TFk|*@=W@ITldShvQJ_kX?T!^JC&EB9~!_erjp&d=H>NXTM7KK{de5w`HiXD#Lx|WJqm1aDnej~u4uTW z)f<=>3f%!qd7QF0hDKO=h1VOIS-eyFi(gN=C~MDFa`RJe^fDerbtKSAZ~k0 z*;BBd#EcFlw2oWQ1mTqy(%=bPTJzLVbjG(+SYgjTSqjv;Tddd$RRO(4_c`TU$vX8- z1j@;B=K^1!!=4LmmPwxzZ>grmkdj0n`d`|DD+Z`YJp4!=;%i_&= zLtQm>2Xk#h`;*Fi@`d@N4vMwAHi7o%%Akq??xQ1iTH=pZ}8F|LmaNt z@eik0d+C2f94=e>KAr5GiXrpQ@%WFYmp13f^o3sfxs*O!rq_7sS5msIeAiR@p_0Gc zS(SC8kr$Op^2D@}SXyraeI0{p`=z|LDi z0_wr--Ue}>9@rNebiJXR3d+Y+o_t7eqk10~%qOMuK$<%#k4qsgb?GC<-YrBkGC)%c z*`OXfDBU*pbW*z7j?CpP^U5)}KW6MWrgW^2QmW5o5D(SIVlSULl#gu=Sehn%J*Aua zG?sHKrJo6Lx31=S@^@1D2{L`QPRDX^yU&Gqs2oIxa)u7T3}6=l{^9!SGec#B=`l*T zm9vJ@50v~-PtTQl$nc@I$X9f zXDFqc#vE0CN;laHrq`rNUrFg|BfML`*Sht)kQ+k;%eUi(+i_&f7 z%RK-YyC^@UpNm8+f00+eF-kvOrVC%BCQbTEO1IVTMoPEY*Yj!8cTswg)UVFdKUW#1 z-B%k*={Ea|QM#>uYtp2zq;wn?-TI|55!-iT8vf@geVF8*@0D*CrB9dXeI~p1k*hjR z7v=9FJs} zX)>MWedNy@hzam3F8srGuB*w(2dI$JH^_7>=Qq4^&LkR}t)|kX-e>J6>^dAE0 ztEs*4x1Yg!j>J75Z&Mffpqv*e-Byo#((n&d1+b3+!zf*4!|f=1rt&oWb!pO9r%B&L z>85&A<)?I;etRh0*7pah^S6>j>Aly0k^J!#Shst2|%+CNQtd7AV(N>|Om_CsSUmTxtspCZe5wO9X} zDE$jEeXdT&e)KA}@4XQB^&>q;tVK$c^AY7^>+eUX3N-uv$UlnGZFVp-O?ryb&w#vK zI}__ZcT&2|7kHS`ZFcr5rQ7W2qcr?S;14U|vgJRD(kCDhx1)Ochv#O1W>Wf8nT~U$ zHf6Q0vXt5&U0bcEywo}!%bKp+9A#~#bl-Cc$`a3tZxfBJKKs%l;CQL;^`49&lx`~z z+C+?KY;!~nrQ61ym6Tp4b?7rmDUlD@MoL#d0N{G4&^jWE?aG0KzRriAnbIT9-6j}* zGkcE(|CR+`Z^5y3{TDVxj^p8|A72sY+Z=U69E)=VPLDB89PmCu|C5LV*C!C?d(}q) zTTi&M0f?)<2jNSES3!u^L>)MvLYU)t$Gr}@ywG;~s-bov z7uUu0w=nK?$R%@e{mqJd9hyR&!9q;Lc~sna(TMYN??%KT&g0_Fi$N_q~Z zd$upUjW|yc>IH8SeIY??pYTHvWw)aO_(^>A<#hw4(-3c}U8 z5g?5JnDBW-$M_!!pC7;v0zo)#)C6$6jW{n5>JK8$ulxYql~6u)l*0Nq6W$cSHxZr+ z;Cl$i@e(i2XJ|jI=k*$P@oK`C2Jrg{Umn2!M)=AAKD58ie{}$FBz#Q({|@1I2Jqhz zzAk_t3hR7W&pfknxh^7neSm%m;Tr<@ql9k^;C*v-{yZXb{?iHH9H3uMIFDpZk7N<& z*F^0PBF@WxfbJsd3t!=+i1SJq1SI0TYQbN#;5#h%>lXYE7W_{Z{7nn~mIeQd1%Jna z|ILEGYr)^M;JYpO`xg8I3;v-6|Az(t$bx@t!85gT3YO zFz8E-I1vlp*Mj%A-~%jpt_45Pf)BLdhgk4I7Cg^_A7;Uiu;52o@WB@RSPOo<1wX-p zpJc&Lw%`R8{1gj*ss%sIf)BOeXIOCja$Wd}IKwUYSr)v|f)`ovkrsTk1;?-Ag|CQH zV!_Y0;OAKI^DOuU7JR$~pJ>6O7W^U$j!!+|E8^f6`odSlnQFnOS@7u={9+4UX~Ab% zaC~YAUl9kt2pGO1&Se(-atnT?1;5II$1V6A3qIF^S6lFT7JR-1$ET<86>+Yy;P?f@ z@D*_yEO?^@Z?fR{<-_n5aZ(n%)q*dy;B6NCS_^)?1z%#pZ?xbyS@2~Re1!$S#e%Q2 z;I~fia1}g;I~_F{K{kaia7Yy$M6+_PY8rj^l#xSPlhYv;MXC;SH!_DMTW14 z^9>7rw*|*9N`|k9v)+Q^mnOp(tp8Z>`z`oJ3;sX|e+iyDa2@O`@SKfTnGT#!3I7A( zYCVzCVEreQ4<^Anj|Jas!5<3Y#~pw<$)_K@hj(rYhljbqRjF`z2n$?|3Rf%BzLZ-P zPA>pN$|nlX6Nrw+)PfMN4tmL7Q~2>7K(QYyT)k2CrS(+{NNU%D4TbhQ$l#P!iR+LZz}w>5dNCNPY>ZG2P0G%!dn%tKHlR?`<24a^I>=s zRZTKIgnvWfl_5M=HPs~{e2T)=YQ8V6L*bYCFuZwJ;mHs_Q#E-_2!BxFcZBfW3SS$- zk5=y~c$LAQ4C|aBJ4Xt54)PPyT?Bfh>4N7Y6AWm$zaU}6fyEWW6>-A-2+1N&xF2a8 z1_Q$taa5-Xr9|9SRDV*$QO4^B;V$B?qWY5}jxr)YsOZD}8i^u$H->>;HJSmZmrH?^ zh~C{5Krw%MK@>=dxVyvs2@yw*nqFGOIm){cv50fDxbvbB-zu`ikMV9qETVUk3q(gF zj@oT$z{BGh5=ETwIHvLNIHvLNIHvJ@3_@4L36F0`6mi1io5sWAo5sWAo5oMYAaq5X z@VJLW5$6jbT8$62;Nfvn)1P6XKhuH_v*5!m_y`MrmIW`g;6)a^*n*F=;G-;fcwRul zh~7aH;)yt8Lzt#7vEbt@_}Lcx91DJ~1rN_(NEm@LDNI*H?}`p3MV!(QhCsv_Z^0*6 z@QD_Dk_C@i@Cz;YMHW0}!OJZ8WD7pUf|pzHsTO>i1)pxgD=hfM7JP;U5Bn!b7;$D= z=x15*us@^o3Hvh|pKZw}?B{6u%PsU*Snw+?_*EACY6~8>;Bzc^!h+AW;8hm9+JcAu zJtT}c^DOl9EqK^J)cMp}=&!Nh3oLk@1+TZ@4Hmr7f;U<4FIw=eziy%bh6TSX zgpWMb0dIS~iyua@a{$kCQ7>|_qTk>G>;Ye=@cTmeeG0$d#ZRT!R)ueLarVsqY@z=| z;oo!V*)u*C6fO|^mlz+b@CRJ_GbmPR!5bC+eU~1@sjEZbn_Qfql)k6%AGr8WDfTPC zP4)JQqW_^w&*lA4;Sag^BNRLAaK|~hkGGzdOZW)DP5GY#c!BdLHy<7`ms{v}S@41* z%=w>X!H==zb3V`)h<#Z+LtmqCE~Vq}NPV*<|E(7K9SVQcE$?v@n|371eKUmPPs|I% z{wt=B9EJGLL-f-W{+5f6qu3@3{l69dxJzF^vEz@%{GW93T@;Hd{4XwkDaCG3_&Y8> zl46|-f6B%A34F+4%>Nk|=Mj0G!k=|d9c|Am`B z_oK6pMY+$pIGDYh<#984;L%^S1vt2$!u2muU-5!ihZW= z-7d~EYXT~&K$d`{H%X31QYw; zR7ipI0o{4{Eeik8#o0c$EBqrDhiuh#)Jd4nKV1Awid_M?slA@E;6w8}qdqJPDuKb>OtS?FH?{A9;_Z!(nV{|tD6*zd&oe5&wQiHg3-0C&?*M*6?GIL{X= z6&|L4UE!~}^k7cvItVJZzzO3AAArA^yxZNG`ftgAexn6H;1qK{r53yv z@B-(*q_t-!-&J_0i}Sejwk03jq+cN3PjNjT4>*>0Q6HTZ*U!m{{&hEh#%lpL)x$yy z{SylRgPYF<6w3hzqrlnc;s;XfVugR=;yfPyMB#sOah^9n1>B@h6b1wneh1(MYB#vf zs)Ta{$zdh+YO)^4GmY|c>AV!yuDT7xi0;Ul;a7|K}`MS5``b=(qBjPcPTtP-hQHR zZ=Y2e(Jz7lr@%SH&4rtXnR|_bS}muT@0lI`J&b-`lUn^j9m~ z+pooT__V^qb~v~Y^Eug-%k_MR!V5z9!Jt5aO`|MD-w@;7jXS>3^{a38#amAR= zS)u$}74GfJdXUQdzQVozSDeok;2;$^MQ%QOiT?Oeh==X!s|xq_WpTUrAC2_h{;NTh zPfX$7{;LgyzoGE6UAe5!*<&ytZ~qnJw};g> z_GNKCD-=G|&1X90^N_;NaBjO+PTg?szWYN;eQm0~{LelwmUX8ISbdelw5N@TV+zpQt&X zi!As`3;vn~KjA`i{%2Y677Kop1^+VO1&+5LkL$nhMTpn9^>!NdivGbv{))oA z{dipe(_)xUxPLvW@CG*@mV0s;(l>_iI)yj6IIyd$&t#+z_m?Xb?(N^3L-hYqxVL|g z?V)uF=F{rt&-h-2d;9meT<4b~y|;gl@oy>oS~nlY`%guBZ~q?m>uVJ5?cY0v^n6L- z-u^vs=hQWJ8s>A8oBzFp|3=~7{yiR-u7ZKI!14C)aXqh9_$_Wetmm5wUm3zjRG95> zG~fl!Z7w~yXX;w3aBp89&-;g7jPze}=~BrB&e7t>qjKk;l z0QdIw!7!q(-z$8rn-5g4x+*J?-rLuAFX4YvxVNwG2*RT?&Gm3K;00p8AN$XDDcsxd z=hnk4GyOD$uMg?@l)}CJf#XS^_bvD_m*8{mMmL|qL|+VefjW&^1Kh8tDcsvP$n(@S zfSbn2FIn)P0)8@_j!EL&9WC1}^#8Qr2SEkq_2FE+a4_QDts5(};O7CJ?^21#eEpfn zxIS5TL{*g&zq~S4UNo+$Hd&QiRNIpDj=qJY%gc*O;_>;Znr1k^H=d|U)hNWO|q@3CebiI8Ba7o#?{r)ic4y119Zisn;PqCs}@Ir z3@d140!}urN~9W_^oorUTgcPNk7speL5-LnoH#TVjKs0R> z9_(CF+W=qQY)I6V7Z)#>P}`7bUL0+1Zfu^U4|<-GR7z;t^5W48rY73Px29@lHZDju zl-JHnrfTbxmC33WRCU^z`HhWGKP64gjj6`Dt@FyqEr9Gt7S|`*x=ycc=pud0sIK`T z-Ns*3xS+Lb4T!=nLsZb%1ygGq^kLGMB%51m8yhZcY%Z^z+l-ZFD!}R#pg?8qwaGO6P{QdA$;Nq86DYfM!nsum=xGa)ZtP}ZOhytWdTj~t~cVp6iDs=2laI)_j~rvseiqlzx9 ztxHaCN`b|-#4)S~yPMiro%G*W)z3HsYZ=C7ra_v56ql%~;F3&K_M-nyOEWxM5D)MtChc)YDz30IdXv-PA0U@gGu$$=31B`VcyfX<;ezcNw9~Hf=Rn2 zl}OcA#c@inP1Mz13wMnT%B`qQwxpU{!D)f}Li86dDxW@Kd^xbR&W)GFfN+4m7rs5i{z@5BEid@ycXfvMN>7k}9hlh0v(F zWJ^n#N=_&!S~QX~jn~2_yvr&};^lLTqR~lI43Jt64o+=-qRA)~gavX9=+UED>G~*9 zb!hqmIafXuz8D&?8l4%3)&!dysp<=afMl<^8(<~?gsjG7QN{77tbyJzKd+Qp50e^T%upn4*2*@c z(`Uw~&(u8$iZse?>8i%ohE!RmE!rF9(FQtRS2*;*)`r?Iw!#CDYl3661!DIc#SahF z&`VR$7En;ve7uLBqLB^BMRE6GBHKoUe(&Y_`HmsFGA43mjP*tu7@P6ID82bX78Ouc zZd1k4YU9wKl6v@c6S#+q0k_*jViEO2l!axer1tDy2hz1LhH3$xgL%GKkX#Ip&hioGse1)g0hjx$~6wK=7$>eQXkQsZc!&=F@~vZsR{M&e~t z460X-0pptie4%dJv*xWUNKXr0j%bFVq%vMMGY*4^a{tpado5v_e`q*sSX5sDP5?O% z(=WWR62{`0<0q6yxi7eO>lrjo*Kv3#uB~sa2cu6*nP>}8hCGpC?TJ8h1(QnRQ^6%^ zNv5n66N_waOmSCkOi@>f#ZjM+<8zLR+_Whn=VBDjR1^3DP)|E*$~h+z42lYHN!(!IDBFEX35N z7RMJBsxb-Ya<09~RMwMsk!kX-Ox1y(01at$9A;pL)ILTdI2p-AJ(+YR47pGMn-bs? zR*sI(#A!#5rr9bxiHt<~FZyOy!=hSPpPP|vX{}ddv~JCkO63R7NY1;kxv{=$xodq!LpTO(WrHNDPl=B3%5a17c0cGmB}K#967x z?%?kC1K60_23WmU&wwN)3Qq?xXqY@Qn6kmW#@T2QHDPB+2 zp^Fz>ME0s=)cEFPLqd1|id1t^VP!Hktx5)U&cbmm9l+s)%Vu;(<>++aDjL(A#4K+?JyuT1xK4`-FLE1l!f5rNo5mE1#{x&RzA3d>Tf_J|d`Gmn43=S%)fr|nW?pR@ zJkrDKA8=n<;;?)L6EDnpu*SkUbZr{NMbWkIaz1-d zFqPFLVS#^9V{=_~QE?38Gm`M=*OD65kf=|xa>|GC(H0VIQ{CdCBJjwdW3{v-=7ULe zM-L4AlFGzlRngH38iD=88jcITX7M#4 zFu~(jk!Y%JI!sV%aDn+@4u%w1vB1}g%D)S{ci@4BJi96wGr((uY!u%p@P6w|uAzxn zKj^?ynKF|`aB(Xx1ShvrKm5Rx;eNM+&sFb%{DgB~xj#?74N3F|N9%cGzjA7FpPBaK zLA*)24@G`cEGijaU5$exEKjn}0m^r0G@yx6yWjyS<3P$xSb(g9p|eNCRHk70*g9+5 z)mKKT9zvjnO5(KGBAxc)=~GmHGd*#`NEI4W$I{W1YPA<0Er@33C8i9pE0}Qa5w53} zl3fQl+Z9XK3GXRQybLp4)b@1GltX&aY~d4HYwPe8iA*aVT?XE1RckZsNWk|ha&2C< ztj~HWhoUiHz2&tn@ahW8x1zB*)!iNfYqWA*9~J}*?+9Qo2%3pelhHF^aRLvo*4fR3#bTPz^77KzqHm0i%8PE5_b{)D32SZZhe}X{O$x(&`hn4QeK_EihO| zgTSi}wk}*c@g8)uU5yB2s*MchAlT89N}#t5b0#eLz#|N=nDQGKm{N;ISJ&c;Lv+jI z$|Z*xU$40W2P{{*Jg}uFIlr-aao5?64bkHSq}Fh;m0{=5{%8d=*qCP62h~^)Tdb?Aj8_~+2v^0guA)a;||Zg;dr~s^~yR7E-Z`H+TK}WLm}|WqXm`_p)Unr zMZgO$-2u9OqgZTNZ~;S|*Vw!$(G1UodQ_CJlyGeXR{#vp@|EzqR6opvc#%t2D?j*# zwTm2~C~l4*v^UHFUJXozoe;P_6o=>41ndAPj`J#!b&&`ZqeUX9iY(v1@?Z~j7_V%C zJ_+w^;gKHS>7{vf3&SS9wx~;D)2kV?cj^TEMHs8yXH$M*XR-%w+#cF>0izs9)^AMl zajX|akHtD{Y;>Pu{{Jkast6;$p)>uF!dDiYC<=}dMk(BaE!3jt}7Ey zw6;li29$@bPxD}FllEhK!M*8K{{&V5;?1@5Yf_*8#*eWex-L2I|3ES{+0=M-b7Pa* z4$!q*v)|oaIJ;xwu(1e!lK}HCyd8(l|6T9M842!+ughUq@$E89H}q72e^ChjMR6S6 zCDU%&Z}*PeJtv!YX+@Z_0Hr6OLkM^*x{we1HaqAcm2G-#vOora=!O%DS}D9 zcfAYrlc(ZNVDDXghP(Z)SE|dK(R`aywPU8;BVonh zfU50r{5YTePDdy%Tu>90@H;2mG8=~t!0cV{Ymjbj-BPY(Z<-eRbEql2!3wvo<@rc? zw=?ux-u+q($EWhHoD6`-?T)?_Vrdpfol5uENbfwB> z&%}MuqZL>-c~TSZ{EE_3){M$=`ppP#nCg~4qMlGf&O|pe^NqCKa1*R69?;~4^o(m* zH|muRjZc|sbA99D45qkVQK1M_XlhOUABo4tbT_K?&g2G<({b2S+GUUI9m(jk!2?Ar z?&*Rq=Qf|Wxe>k4Za53x0|qeLcgTV}4nrFJ6v2HMG0kb|d=r>mEOVY-PclxFX)}cp z(q1L|H$LLfk2@jwDbB6;9`sy%M&(V*de<*Zo4RV!?;9@anSH~(W4}J92%QXa&%o$< zqfUL|&?A;BZk8!qFSo(SJ&xBO*u%r0LpLYqChG7V$6SlCfzv(1-BLWp{V_rJJtlk< zfDJHXrMuLSf)_&YgJyI`ya!bHEfx08v3hFl-jcX>{PeyB(Pw(#mk~N=a`C#UoLaQo zuMPex2kj;HlFfZC3-jIaMPbH>#w}Lsx~RR>3*j{tJnq*ww)E<1C_W*Jjs4d7v6luL zbOY6b%I8x~_h$)Rlyg6J&fp}Cj)ZFw0Utw*4&8X-@Xe?o1y<5msppUDR`4(^z^EE`yOE z8eKR8T10mR>}x$IrUgpvwi0bv1{G)I*Qe&dhscf?Ek;C@BVNw&ln!LkmR6~0%pXhTCQSYBZqKTk#*py2&R;1Q#IZecVkx)r}n@>^_qJv>09?^nK@ z+|^Q_?RT@g)2}P4>+qNF>dQDi=gE}#+!!+B9`uyPxdw$U*<^TtE7QAwagB@pGc+Id z%@H}@gDL5?Pvhqg(roV=`+qU>lU3Tx((NQ6!^~vZR^NFLw(43~b~er*yXe{R(6gfY ziYdxSdp3V*MPtBD1q-k!lyUkONUt1 zU`_Dwsvq*_;)g-;V~8|RbkTtfzl;uiucP-y0jM~9JPY@KXuUKl2lf{GRPNbY4%i&% zjQ)gjD5SNe(-#-$d0t6F>n&B!EHnKw1P6Z;KB-W<1;#Ym6D)s$8T=6!Z5Et)3H(k| zeON0ow{~F>epa@nHeOYiXlYR!h~TZryheO0HM7zr2@}eEzw`{sp*LD3wT&%mN*;wj z#nZo7idVNZ#^D>Z)pbcMC3IpRk^a4mTD*Y8r#AdvENo8HAHr4N`cV&H^l9CJ6ykTF zSHkyu_kE_XpAp^{Li{Q*<1Y}7pZe_&|0dCwgMULf(!V6=`Q#PEHwpY*qQ`vR6nH1$ zNdH%X^T`v4|4rce5XTGgT>>9QIOhMhz$Xa$cLjchz~2)%f4QE^JA>%>JN$^hEa>?Q z>8Q_kfiERK#PMs(T%Y_UZmfSiGl+5i@-@=GB5?lVGs@j9@TVb;7vg&aj(OsR`MfXi zKMDH33moeNFQosz!2c_7*^d2CAY4d~r`fUoM-YyItpA|`mwKKn@{xK@74%Zis|CH( zvsU0zpIb#f?+87ABycPP>;F@c&vJ+}{)C`kA@E-aT;}s4;n=>n2>MqEM_Sa4^M_k? zVRd7FEr2Iq4U;Yg2PA!oc;;NKDWF@$42vcI1y=)W!KM+y91 zf%A9TQSSEyK8NTre`)`X0+;Q`=L#Xcw71(W^y>vK>Ax>IeS%LGs zhWR`va9OTx0_Sraf^y+FDs>_L3qjB40wDf`z-7PtmB7!|*{E?+_Aj<8%m?Swhlx)1 zYdN2C{a}4cJFh1`&gbWJpAxv7rxp{A`N(-{8R5bC=u3iL&PU%Q9OXVP%KIaMzbNph z1pZrr|4!hq3jE&!{~v+(hd5qb-e2om=U{=$@*YNbu)ISA{c8|sJ3LF^_X~WCz_Go4 zPjb&EJeYrlpqKgc2|B31%%A;=VEyw6D44&je?CD3^ZA|7lTXM%dTDQHGk9^my`yi{ zScFlem-dEz4XbvCB5_?Bz;WK z%X+w+a15{=`JAn}f?n$1AaI$_l0ZIZQu)z0z$;jv-xm1mq8=U;xGdMt1TM?tzfCv>&kMPq2>kZ~KRlw;SIzcRzD3}dTJmoY zxGdLVfy;SzmB6K*-x9dY=Rtu>`lkgh>3=J5N&mLMCH+4IF6sMXMZ$%Fq(4&NlKynU zvDsw3ooAts30&3>`x}^y&jQ>ZkAr)>F#k6I=Xq4ln{Nqv&IjqS?{hwkWBwlsoc&Cs z|486PaE}+_{}MR+pP0|T1uo~)PJy#uf%*JL;B(;~FU0>LaGp0Ye^dP+JwE#c%Z2zS z0zVDz@k0DlflGh;CjviNQEPf+;{1mR{2oDHDsV{;$6culje^byG30&Gqi3LAf;If~} z^2+(;JV7tV!}A3W$LgsIAm;*sR|~vU;4K0lFYucMK0)Bpt|nRVs0F{!f?p(XSr7Qk z!u@4}&cH0Vg5x{Yh3!%%=%qdUQ}m0anq2vrlLh@(1U^OJ_X)gQ;13BL*JfGI z=L9}Y;QV}ydQKPk+k(DA;ClsrvB3W&@EHRCMBtSI&!u`oxzewbPRSI0%+tmV>_9okL9nf&QNE}ZsHQ{qa{Yd(R1)nQ$*^X5L|AMH`YJtoA zrM*czPYQb3U!+~ZvDfMXQfHo^mv$@jm-F3xK`-^GvEa29{2GC?TpR}$2wdhb`|rtG zeKqgb3Hl)d|Eg#&IX=jGm>}roICHVUrQEo{>xJA}!cl)|x7Q1L>37{E=%wAZ3tZam zodTD3n@>2X;xq_-m-X2!aBeSv99f@od}|T(nb@b)U)pC%v zH(77k`FK2(n z0%zMme7(Tg2S$9Wz>h_MuAKtsHDOFTh$<0-?-C8-`2y#@hB&Sj;DrJAalFT89K0~# zy$yJeb3I-daGT&g&K-DRkdG0%)(HGm1|i%maQ3k=dAq>b7eaimzRs$zf|BG1dg)rr?ejke72x}QQ%0Ab0J=P1b&%@)Zc;B z$&rkoc`;#_z^_o0`p;;Aqg?hoXA1mEL7x)%RRUikaLk9>V4c9P7W9t^oP9h@{-eO> z2>N{jPYC?@{`v;XJ6GW63cO0-QGuhL6DX}(;MIbDxxkYG-yraL0^cU^`2v4i;57p8 zJ3!x{{_JBQa1_c=_(ia0tO+h6F5J6V)AN%^Sd6zHwnA}0lHokIPc-X zq&)&}Vqypf(!_@4`l7&x3A|b04qm$j0v{&u zn+0Aj@MQw86Zmq0uNL?Ufo~G{Edqa0;I|5VkHA+7eBeR)2K8?j_%MOrCh&5BuM&8Z zz*h@=jlequzFFX368NhEzg^%T34D#fk01vU_5ZTKM+y8Z0-r7LI|SY)@H+**PT*?= zzD3|)75EN;e@)<>0$(TaoP+fZ>W||OkBRvL|GJ<*UEoN+n$ji-{2PLPs=$$+>#j!N z{4N05Rto%XkU=h1@@>c3gwg#v#_;1vS@k-(b-{$qi!5%|Lb-z@N-2z3kCkDz$*m)Gl4e={O1B+Bk;!rzFFXp3w*o4pAh)#0!KUK zy66=6lY)NmVfqHkwN>CH0)I;2vjzUNz}p1=jKJ3ke4D_x2>cfU-y!g41>Py}=LA0Z zaD9XNKQHhSfxjT|*#iHiz^@nhuLQnA;8>sADQ$zmUljD)1paG*?-KY+0?$1{-=O|4 z3w)@+Stcfz3;Y#9UnlV23VgM|QN~yB4_uo9xV!!^qGfS?Dlyj?0Y~=fu!duBBtT*W z9!}|uz>l^#Bj&cWI0_gMzg(ZiJfgW#Cn;Kt!XdtOfVy<}?G5)wdES>B0v~URXGZUS z1PSO}?LZk65=GG;#igo5z7GHDd13of1 zoY(`=@U;l7Kb#Zi5boWI5) zZ{KNu)|`nsIHHFp^Q=F}RvaIXzkH9^)WSK4;ZYNeZNJWi+iwL;hrk8uuzMd#4VM*v zKh58=HO@QyD|?z{u<_!R>g)VPE$T3H_>PeNCN$4W_^Ab>AU$7&ou(*qLYcJ)_4Nw; zRG0eDN1)jIKS_4y81|qNMcp`Tizf}Jt=>MtoJCEupCjHI2XF^#sWaU3GKamQ~g7_YoJP6Bs z%nQ#V)^zgWtjO9XiK~i%)48 zCg-lcnh9CbS2GQHu`-4{)v;4ueAp9Q2+r3x8265|vR|ifhMHtQ&(jR%*Bdr1%*MAY zp=Vb(*@;^dXR6*%06&pM$6valdSBA#U`qPiU+#IB{>JR3%Iv~%;nAT7J$v?Le3gk) z=l%^vzU&~k{XVV9U-dYJ;?b6^Nj#~Ns)IjF3W>oFq2d!sGAcr31I7|0z zO1~P&n7tl!Or<}oZcNhIomlCXws$(F_y8|diaW@7YyRFK)H@1zU*WaM57?xuV-NNw z~lHX z(_a>0c)fqxreAdSr+KQAWwl2Mr!omc*sl{j16uW(ciQd4JY_*Wmq>lu*j*Ut`g~uk zIH))40XzOGm?Dg#=SHJ$ol=7>8?@pPDYnemhE_<7|Sz}MBgBIxvPef6ZrE?tf+ zj*SdfNe_N9JG=8AO|9J%=gFuYIB=efn}07gKv(Obz0u&jq?66j-sz50bnB?sY}9wC zV$k+_qndE+NqfFxZZ_?E@3dQhWdGMAuTqoCqGD^#nzizIS@G{a8F-1)&Gta|gb7$0PYp$m>OkzQdBd z!}5X>dt>|xxLQV!&wb1Lc^qlS7A4-!DHq8tytiW3)hjyhV7t$w7GY;h_s_WdTolCP zGxzgQI&PU>d*NHDj|%Q$34opc-WhGYrEz?6HW*y!;U{5<5{44%=Mcdj8q7t8KcFg&5iUns~TaCBX_4#7*8 zX}5+Hbsk&GeiodB{|{JM^XwUhriQ@zkm?{We^vGDknb6u zI!3QIMM=Z!>O?)i4!tx7n8sr^jx-}N`%Ll?ya#4OdBk3@3cBcUhAr>j33b7IdT$tk zx-*@x7gQi!LFni@KU>dQe83Dr@!%nQTDtgI=?M6dN1_gPT+h73^t+e9Xl)`fY%?{I z;jwyQ@p#Ogi5y7P4`ER=^8tA}uUa_tE}m#^PArz0Pr4LR=Z%QR=eM=Ro082fjSY#q z+SKCs!a`?6Rbzd9vH^aB+t8Rwj<{&rtl=%GMAZV~Pu9feH7Dwm@H5Hg#?~hNW8eMw z`@%W!y>473aq}j)ULv>q|I?HvX7_AHN^Ud>q>ND-8Vjol)lF(8iCy<;IIX zo1ygoBiu6|hc^Cd#qBt<{CI8|^Koe7uQTxfDGT{21OFRY@bfopr2cr$8SBlVP5*qC+W7gK0J8peX2FlPj+f+r3+`Dihc@}U6t|!M(JadUk%1r2e`C2E z+T=SxitlwHu?DmemrlE`8c%k4<&wCemuX8 z`8c%kk23J%xk=2&p^d-Pz>nuBF&~FE{&EBVpP@aOk3$>(Y~q*w7rz6_d>q>NYYg)L zl7)OeuT0ke+gb20HOPM_3;xvx{=a6yk8>?vQvZJf#`VUbt^PI``2Pm^F&~FE{>=t{ z98;K&LmNMy<%pNm|6RCeJ`QdCXzO@M{`cUX`8c%kziQw|otTe98~;uN|L!d0?;(CU z{%p-cKAug5m*mHDBw23`ZTjycep!EeAV22g(8ixj-=UHGzs*Aa5e9y26PC-NO@2P{ z%kty-i_FKNjen>?KAum=d>q>NM;Z8E%Ywhuz>nwKv0M&q^6|_Iykz~q5BJQ+p^bmG zfq!=v^6}gJc**)ln`F5h+T`Q6>x2Awt{U@kXyeCkqvIvZkLRf|ABQ&nr3U$bhy0k2 zLmU4}gZxjkkbkE^KA!u-ayhigzuO=mzpKuC9NPFd8sy_gc$tqw8$W-)ShhcYPoDWW zwDE5t`Lg}`WWm49z~46ue*Vs~l>b2%?f*xTFUybT%yGFnw3YvD13!+b%*UaPe-H6X z{SU~3ztg~fU>5v+BiQ@={SUvr&3bca(?8F^kLPYMABQ&n;|=_IS?~`v@E@85KYw3a zw*O&S@Skgte|Q%Bd_Jjcf1Fdf-Z-??-%OG(^~dwSn2$pn|CI**qqE?zHk5yG7W_>H z`DbRq&)++j^*1aF{^bV!@f(27~^1 z&LQ)0Xye~((EqqB`1$+s(*8coqWoJ8`k$DE{1*-U=u>jJIkc6ZzjH6^{~uZC|F)t2 z{+R{;9)tb`S?J$skdJFRTy73+q^COv$LmU4P z13#WK$$T8z_zMmE_)Nik9NPHLHSptE6wJq=ji1j=mi33{EHNL4HvXAJAo)jT!9T~q zKRgTmI^vi8e?%7iDFc6T7W~&6^#4~D_P^4=kLOYn?1r}bztg~9k_G>I;+OUJaTfY- zH1Oj&mYM3m*`Pn3bC)UqV+Q$nE@r0u+YIvYnL1Pc?FRYdv*6!hkUt>{{Tfw93Q<>PswneyimzqH?27W{(^{4=xQ&o}6g=VxZB zKcC|w%a7-2X3Ae;kdNnXX39UwP<}jbGgJO@13#Y2nJGV?OC!sFMHc*X4CTjjH8Yi8 zXVCxZEcp5S9BF@e9%rWVuQ%vFCky_S2L41A{C67o=Vrmb-cWyd4riw2-)N9uody5H z27WxhGgJ9n4g7eXXQuow8u;;i&rJDu5Wlpank@Kt8sy`7p_$6xW8lYgMKk5^H1Ok^ zY^MBu`-jJWJQp-m{ygHB^@ryYX39Unv1 zW~%=h13#X3nJNF>#D9eDhHC%Qf3nbjvq3(d=b5Se$B19{-Wc*B4}(<9)5ag958f96FJk=zorHv$a2AA_=U%85Uy z|57?{i|dQ&gZCFff~o%VakCs;T+dkl--dhUXZ$k2P{m;RSCahGAx&O^;;1vrO#BaJ z$d709nD~EB{HIFc5D(Tfo++ftA4n)Ml>dI94VEAGl$qr7gBNV?^j!fl&H!LG@t;eM z`*0t3SpPFD{MQiw8EN=&pO8uZox~s9n;O)=$-;j>@gJW?{?{!0PZPg9BMP$$%Kr-R zo7%6!(0+KnR|6Kq~`C z+af6c+ay0&e^(AtZ0`Bh`Yzmlzp?0FNBlTH$}6bg$DVLLq@^!<9i}g`JW~EyQFZ4 z2j&0PB0om*=MX>I&yx@j%E$LCCixH2M1Laja}bn20QgPyztK?srwsBZTI9b-^4nQ3 zg+ck}TjXyg`D=&|%m0i){^J(;m(awMZvN>H&&j6xt0Bg8^UqQX|8n9_=f7PC{HFS^ z*r^L%D9VrL>IK{XC5!y8lKgb-|AIySQj#zG{|g5B{lQN+)!)M;AN@ml1=~Ld_)X|P{?Gz#~!T(r<*^=0>7#J z+YRzxGssVo{9w6CNd6wJhWj^QPR=Te{zItX>GZ$FqW>;~{`g1@@OZ$7rAb+1l z{tl9V1`DPzDF5FU`Rho&Y=7*M!SbI2>l9EmA^*G2v05NK#*lPP>)t@*ehYt|g+Hi& z0X%1$qxNtcUbs4iT}(r{9gioQ~Na; z^#6xJ|G!w|521ncgf#Nsu*hF&kdOP{g7z~CI*6(M#*_TH0r^NPud{&PRQ~lOe-06& z{eBGbp#0Sq`5Q=ny7BW?i+t5tKweD9?=;AN)gpf%$xqjRUbe`OVP}O)_MiX4eX#t4 z;W^n<|3}e-*MTY*?@zG)8!Y_!#2TLI0O5@{gi{2h7`dVOiyMEELdG{vjFiFS76#6aS4; z7{r71*9`oo^6#bcw-GCi!{qYeqT#A7+sM9gF-v^x&UP{yi4?Lk;qeFvuSS>kOv$ z8%FY}8r)h4_P+yx-&FomgZ!fm@~^hYpG@-8&A*pf_@2B`)$rp|6<@bwckpE{wEmpzu6-Hmn1)(|FFa& zf4xEeNe20QEb{y0>-q|gUszZ2s)r70s=p)hHB~zPe^~fWBmQ*j5AOrNss6W6`Q`j^ zilO{%@SJVZe~v}}p#A*S!rx5%!*n&ce^Hja-U5D;{<{qNpJvd10d#Pa{`cf-DbuAe zhzIqb2mB`aga57><@`6)Ape^d`G3#X{OQJ@Pb~boCuhcw&zUCu=aBwj9_m8>+D8C5&T*x-0|DTCJ zUHv~`;onF6d%55g2Ib!e{HF5ff1nw*5+9bo2>u1hT0vytRPl09(&fiEYuP*|> zN&ZffFWY~lLH>sp`A40irKEfRv&SO8(;$DeLH^m`AehR3F3BGx3k&gJ{oiWgFDL#D zY4~pjepCJBQNv67EiveS3d~a`{r8gmboO_fh5x`ITJd!JD}djm{}$3;w*NT>{ok_4 zA7YV@WtG<-E%LV;#RALU04^7|B+%l}J~KPHX*Pb~7EC;5d!{zV4)t1a>!8u-%rFSi1} zsr;P=`DF(Ahr&1kaA^D=M)HIGA8F+^5co~Cy)|8s!fRQ~mb_OCR^-)512;1_hor<;F=fSxA(k0t(e_OsT)KaBWmF>`SR z?Pm?}o65h1%8zq4UO4_-3jc!sR}ADJNpSu3t3wr=lTQD~Ec_dZKVAR*De#;0--|C> z;FA6Ka)bV*AjhQt(;4dj6AS;V8S1|o=uGDqsvMSh7v{#=9nMHcym8Om=4epC4?4DzcD^53(_ zpG@+D{Ri7xUdNtkuD>gZKVAE;v+!R-{4|WZB7^ep0De>XYYgQ_Un-Y!;(mD`I0%?$ zaQs+9@<+ImbtEXiAMl&xFEz-&#vuQCi~J`@emeVGWRbtlAivHa|5J{=nZ_1lzv~8W_tIZ2xniU*I)I{q_C? zpy|ylN;#j5R`um@SEhXB>7Oi>O%Xu z(IEdT7WvnZ{Ci!=IuexMVUfRu!{@9V`@(+Y@6|XTmaQ_D77X!bk{2TwR zS!DT_8RWlUkw1at2j^eN!gmcEW!Arf_|x_O0l;t4e+TI=`~NKl{Sy}X*JLRFN{jrx z2Kg%u@_%lTzntXLFyPi%u>Kyg$j|N6EVBH!8RVZf+Fbt+lKkNNqoDkgf!|dB`6OT3 z&uWAGjTZTTBl+p%zg&Sq`;P#>N&gDcpZT%>-EPqT9*g|*!7soo zo&FzK_{%foA34@s{>zDff>y)*8!Z0_;5U_jouT}9n96UFe>cgW>Pps;p!}~}dz=)nCOEdQy{!64g^ z{jMkeOI=PK3G(Lyze)eW|JC$!h#&12e~TW}zuqGM-y|QBeHZE~uNsT|Hj*#<|J?@p zf49gl1iuom@j7t-2Fw4hMgB&E{Cf=YPd(dQ|IH*no&Dwmzp4IrkbF6QtT)L24#|%M z3bvKx4|PkfBiw!r-(!)V|G%1I4iRGe#r|cfogI-w#eUXkdNor1mzc;quW1N|0N`!>xnCX`T70?;5W7Z zPLdxZLahId2Kh0PAN>7T1<5~>1yPt6xNiV{oMR#ZyoUIL`tm)8wXA=Df9O69aQRXH z?;G^Lk@OGNUsD?SEbdyCA86Q8gZv*Drl8c@o&Y=o^Wl4^2sa6|Nj6)z7byl diff --git a/examples/cpp/metadata/helloworld.grpc.pb.cc b/examples/cpp/metadata/helloworld.grpc.pb.cc deleted file mode 100644 index 4255687148b..00000000000 --- a/examples/cpp/metadata/helloworld.grpc.pb.cc +++ /dev/null @@ -1,70 +0,0 @@ -// Generated by the gRPC C++ plugin. -// If you make any local change, they will be lost. -// source: helloworld.proto - -#include "helloworld.pb.h" -#include "helloworld.grpc.pb.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -namespace helloworld { - -static const char* Greeter_method_names[] = { - "/helloworld.Greeter/SayHello", -}; - -std::unique_ptr< Greeter::Stub> Greeter::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) { - (void)options; - std::unique_ptr< Greeter::Stub> stub(new Greeter::Stub(channel)); - return stub; -} - -Greeter::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel) - : channel_(channel), rpcmethod_SayHello_(Greeter_method_names[0], ::grpc::internal::RpcMethod::NORMAL_RPC, channel) - {} - -::grpc::Status Greeter::Stub::SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) { - return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_SayHello_, context, request, response); -} - -void Greeter::Stub::experimental_async::SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response, std::function f) { - return ::grpc::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_SayHello_, context, request, response, std::move(f)); -} - -::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::AsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { - return ::grpc::internal::ClientAsyncResponseReaderFactory< ::helloworld::HelloReply>::Create(channel_.get(), cq, rpcmethod_SayHello_, context, request, true); -} - -::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* Greeter::Stub::PrepareAsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { - return ::grpc::internal::ClientAsyncResponseReaderFactory< ::helloworld::HelloReply>::Create(channel_.get(), cq, rpcmethod_SayHello_, context, request, false); -} - -Greeter::Service::Service() { - AddMethod(new ::grpc::internal::RpcServiceMethod( - Greeter_method_names[0], - ::grpc::internal::RpcMethod::NORMAL_RPC, - new ::grpc::internal::RpcMethodHandler< Greeter::Service, ::helloworld::HelloRequest, ::helloworld::HelloReply>( - std::mem_fn(&Greeter::Service::SayHello), this))); -} - -Greeter::Service::~Service() { -} - -::grpc::Status Greeter::Service::SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) { - (void) context; - (void) request; - (void) response; - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); -} - - -} // namespace helloworld - diff --git a/examples/cpp/metadata/helloworld.grpc.pb.h b/examples/cpp/metadata/helloworld.grpc.pb.h deleted file mode 100644 index 73cc75e0a62..00000000000 --- a/examples/cpp/metadata/helloworld.grpc.pb.h +++ /dev/null @@ -1,197 +0,0 @@ -// Generated by the gRPC C++ plugin. -// If you make any local change, they will be lost. -// 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. -// -#ifndef GRPC_helloworld_2eproto__INCLUDED -#define GRPC_helloworld_2eproto__INCLUDED - -#include "helloworld.pb.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace grpc { -class CompletionQueue; -class Channel; -class ServerCompletionQueue; -class ServerContext; -} // namespace grpc - -namespace helloworld { - -// The greeting service definition. -class Greeter final { - public: - static constexpr char const* service_full_name() { - return "helloworld.Greeter"; - } - class StubInterface { - public: - virtual ~StubInterface() {} - // Sends a greeting - virtual ::grpc::Status SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) = 0; - std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>> AsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>>(AsyncSayHelloRaw(context, request, cq)); - } - std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>> PrepareAsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>>(PrepareAsyncSayHelloRaw(context, request, cq)); - } - class experimental_async_interface { - public: - virtual ~experimental_async_interface() {} - // Sends a greeting - virtual void SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response, std::function) = 0; - }; - virtual class experimental_async_interface* experimental_async() { return nullptr; } - private: - virtual ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>* AsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) = 0; - virtual ::grpc::ClientAsyncResponseReaderInterface< ::helloworld::HelloReply>* PrepareAsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) = 0; - }; - class Stub final : public StubInterface { - public: - Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); - ::grpc::Status SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::helloworld::HelloReply* response) override; - std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>> AsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>>(AsyncSayHelloRaw(context, request, cq)); - } - std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>> PrepareAsyncSayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) { - return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>>(PrepareAsyncSayHelloRaw(context, request, cq)); - } - class experimental_async final : - public StubInterface::experimental_async_interface { - public: - void SayHello(::grpc::ClientContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response, std::function) override; - private: - friend class Stub; - explicit experimental_async(Stub* stub): stub_(stub) { } - Stub* stub() { return stub_; } - Stub* stub_; - }; - class experimental_async_interface* experimental_async() override { return &async_stub_; } - - private: - std::shared_ptr< ::grpc::ChannelInterface> channel_; - class experimental_async async_stub_{this}; - ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* AsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) override; - ::grpc::ClientAsyncResponseReader< ::helloworld::HelloReply>* PrepareAsyncSayHelloRaw(::grpc::ClientContext* context, const ::helloworld::HelloRequest& request, ::grpc::CompletionQueue* cq) override; - const ::grpc::internal::RpcMethod rpcmethod_SayHello_; - }; - static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); - - class Service : public ::grpc::Service { - public: - Service(); - virtual ~Service(); - // Sends a greeting - virtual ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response); - }; - template - class WithAsyncMethod_SayHello : public BaseClass { - private: - void BaseClassMustBeDerivedFromService(const Service *service) {} - public: - WithAsyncMethod_SayHello() { - ::grpc::Service::MarkMethodAsync(0); - } - ~WithAsyncMethod_SayHello() override { - BaseClassMustBeDerivedFromService(this); - } - // disable synchronous version of this method - ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { - abort(); - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); - } - void RequestSayHello(::grpc::ServerContext* context, ::helloworld::HelloRequest* request, ::grpc::ServerAsyncResponseWriter< ::helloworld::HelloReply>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); - } - }; - typedef WithAsyncMethod_SayHello AsyncService; - template - class WithGenericMethod_SayHello : public BaseClass { - private: - void BaseClassMustBeDerivedFromService(const Service *service) {} - public: - WithGenericMethod_SayHello() { - ::grpc::Service::MarkMethodGeneric(0); - } - ~WithGenericMethod_SayHello() override { - BaseClassMustBeDerivedFromService(this); - } - // disable synchronous version of this method - ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { - abort(); - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); - } - }; - template - class WithRawMethod_SayHello : public BaseClass { - private: - void BaseClassMustBeDerivedFromService(const Service *service) {} - public: - WithRawMethod_SayHello() { - ::grpc::Service::MarkMethodRaw(0); - } - ~WithRawMethod_SayHello() override { - BaseClassMustBeDerivedFromService(this); - } - // disable synchronous version of this method - ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { - abort(); - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); - } - void RequestSayHello(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); - } - }; - template - class WithStreamedUnaryMethod_SayHello : public BaseClass { - private: - void BaseClassMustBeDerivedFromService(const Service *service) {} - public: - WithStreamedUnaryMethod_SayHello() { - ::grpc::Service::MarkMethodStreamed(0, - new ::grpc::internal::StreamedUnaryHandler< ::helloworld::HelloRequest, ::helloworld::HelloReply>(std::bind(&WithStreamedUnaryMethod_SayHello::StreamedSayHello, this, std::placeholders::_1, std::placeholders::_2))); - } - ~WithStreamedUnaryMethod_SayHello() override { - BaseClassMustBeDerivedFromService(this); - } - // disable regular version of this method - ::grpc::Status SayHello(::grpc::ServerContext* context, const ::helloworld::HelloRequest* request, ::helloworld::HelloReply* response) override { - abort(); - return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); - } - // replace default version of method with streamed unary - virtual ::grpc::Status StreamedSayHello(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::helloworld::HelloRequest,::helloworld::HelloReply>* server_unary_streamer) = 0; - }; - typedef WithStreamedUnaryMethod_SayHello StreamedUnaryService; - typedef Service SplitStreamedService; - typedef WithStreamedUnaryMethod_SayHello StreamedService; -}; - -} // namespace helloworld - - -#endif // GRPC_helloworld_2eproto__INCLUDED diff --git a/examples/cpp/metadata/helloworld.grpc.pb.o b/examples/cpp/metadata/helloworld.grpc.pb.o deleted file mode 100644 index 234283660c2185112bf5a40874899672b328aa80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 398496 zcmeFa3wTu36*hd5ArKWMUaF|Hjutg|fq*wa)F4C$4H&^FUPB-QL}L;|f_Oop0cDJ% zse@eKuL}K| z&g#RAs@O>8F=kR?VU-AiUpfBLN5#JZ_-GndUFM)2xcZ)o41$|lgSA_lm^i|=1 z2>K&@U&FUuu-8G~5dKZjxA6TjzCRJ{r$ReGe}?bR<@s&Uckq1|-(TSS9=@bgC+IJQ ze;@Q$!fylpweTMZ{ZMEZ=tubeMxMJtx8wU;e1C`U@A0LydqDpn{2xL8B>WDce+K;v zzJJBHSFpc<{vF?c;QO&){}lQ!(4E42G2}sC6y?C$t>&eBmzuohkfmBQD8)(Kw^dX?}EpbLa=1Z@(2q0p;A7YTn2=(WOM2YS8mi$QM?{zlLx z!Y>8=g7D3t%YHpbrWEbV*WvqJ!5#zsp74)@J|X;i(C_2B0pBMDdkXYv;hzD0R`};YpBKIj^abHJ z3VjiDlkhKrZpL>DzFP%*8T1u=e}M0+g8dNmN5a1b+AjR-Lf;VjrqH)Qe=Ph@Kz}NH z2k6g)|2gQ}!oMT*U7^1a`W|Sf@V^xLKIpH6-v;_?;Xe@iA!wKI9|`>pXt(g&L4Pa! z??8Vqd=Ka!g#RPxpM>85`e)()0{U0sdqMvu{NF+UA^gXn{}ldTpgV>4Fh!@aAO|#8 z_!#H_;qyQT3O@)mU-;dG?hd+#@Pk436n-zzA;K4c?k)U2LiYvTPx#LW-5>M-;fD%6 z5cDA74;DHM^s~Z$4)hS=b_?tj)7Jdb2O88rZ zwt(I$d>ZsN;cpk(3i?Ii?+|(?=t|*Nf!-zj-Jq+5zX$YQ;qMcAKj@c)|FY1pfUXh# z0no1s|25DDg?|Y2>%u<_x>opa2>mALw}gKL^xMLJN9d!V>xBO<=wrfvPw3-9pAfoU z==VW42>+zer$C<;{u!aqf<7nw^FrG|Ul4wy&=-Yn0)0vN%|f>b-3t1$@UMXWK=@aM z{!r+TKwlHSUFhqeZwUXU(6>N;Ec{P|{uH!B_@4>=xzM*k-x2;@p}zoqPxwyIUkd*| z=&yv|2KsB^KLGtu_%6_og#Qg_xA5CRe=Gd&Kz}cM59lB8{Ug4A5^M+PpN0Pm=wI>e z#rJQ5{T=il!ha0^3x6Bv?ZUST{i4u2gx)E1rO;JE z?-F{q(A7fk5qdA^eZt=l`X%AN4Ehz}*ML4C{8vH0Cj5h-4+;Nu(1(RzEA$&ezX|#+ z;U5wDZP4!s|ESP)px+h#F`?fBeO&k_gsunuzVI7_J_-7i@J|bU2J~6spA-5#Xq)ga z2;B(!qVSu9z682i_$@-Wg1#*LE1*9R{#Btr1pSfluL*4jeO>rBg#H-xC-{~pQonwR zoN9t<9b|c1Q{Gd=4OzeO(icgbNGFpWvLP4rMt0bqO)yKP1P1_K> ztHn!|e9TNiOUbsJjl`zFe(Z;&v?<{hpgTA~Z^}=od3%9m-!*;b&YjEKhOBB^*4DVM zD3kh0BDJOK0!X^|4nYe6y==61k{F^UF*2IOrGQ#rezBEIF!8(@iRSHbsM3{4HFYLZ z5;7o-~n=-z)yYLk_frV!HLWQ#=erufAZFS*p@ zL%9s~bKz7ZX!xZbdaBHE@b=sKy%n-Y6o=aM3DB0Pf{0k%wnnyji=DD$G@LCnWnGQC!RmC-1LDWlz_|v zduO&xKn0~OO&caYvp15P_$(z_n)+pFsvB*-H1(TA3N`VXZE}g!3yIX5up4UcM>et2 zbh7RFBE&OR=8lDAHEIB>Ya=b?6;7SZP7L)Dyua0S6g4mM(XS2P;dNIcg)mZ z5P$)BP&#fr)!b_#LztW`Kb}On%mfpuw^)b7d}X+!eL!`E27<(>k>4 zwP@FC(5_d*QopxJCer1~FMf`qJx^`B>p{5N zOJAhe{s+ei9?%;>mVnZSc>3@&F$Sh&u)qF`WBE(`sHO!CqiX8rRMw2DuANiURFxbx zudZ%hO>$IyLtSIt?54S+u1qdiP&qGIQB&QR966sN;WH^wGU@F2+{)^jWYze1;ezUG zlOy62P65|g*;qZNVov3P#tDR0G@e>mwCJR{<}+f%__#;Ql;Zdy1#!@M4fS)5r8rFs zj;%^IBE1F2&aSS7#C)>phbZ;+qpGj0uNgI`t|~b%Sv!i7fr7IeDjTk09p_cdtEsM! zA8|zduzAzVCdEY-udQp0SJzfIR#(BD4jB?q@uKB+L`Ai3K!H=&q-ErBMO3f9G9ZH?F!X&YN49K2rjr+z+@NO zPe}i(8_?1lp#Py{5h>NNr=E|xswy1eF=)#aZ>(#qtf}CZP8sfEe&}yCWF6S%$}8(? zkr#P$eCp~KRD6PlLBYLI^OH3-bywFl)KrZ;vmu#;@}p){UXviyTbP{FSl2Lqe8p6% z7a(&gs%sY{8yZc1)9T{Vzft9lO%1ils`%WxhImsgdJ-VC+65GJSIbpXokU%8Z1{kh z8nUA4-W4P3u7LIA^U2b)=0a+7u8JReO1!qIrl!7e*V||1f@^B$gw-;NEU2!9v!gm5 zIU`wHHP!gKLMiwNU+3AC3*gljG&UeS8*@%wEuNa@G_o%2R~AwO`DEoY?XIa2ZVzR{ zhkL*LB~uWm@XCPHe_k8w-!g>{IVIfhJXQwX=#%lPB!-4$A;mrF7*66Szkk@AoP<>yO_+Y_`0*G^su#>JoQ{-? z9wtXW;rPW@Lyh?K_$l$gU5p>kPGWkpzUG=sZI&Ur%lT7v$w)a>>e-ZR#J`!dQDc|$ zM{ye($>QiZpP;DG`s>@wO64tRtQtR_2Z6@^vp*SwnI9bWQBzkt4-R($27EMA^kAnd z{zLk48|z=QOL?CI(`wAhn|d%u?isS4C+REvod!o1Y)w#T>}fbHhc`rICXbDaRC!Nm z-+@A6!q1^7MXUpctS=s(u~slT^d`1&!n_FBQk+i@%(s;HBvNIp-e%T41Ykw1uDU zY`1HpmtPFp2#n{nfyfh#!;>&-8POby3$TaQc#z2s4=qh-22*?K(gKX}+Rk>g4`><6 z4OD znaNOzXcda27kAMvo^0bFsjimtZJbnB!X(uZPKw|{go9E2-KXx)1zSt`R@?9v3GHFP zB7=`Zm7SG$u6H@8+k;xX468^V79~)Re%qn)+M2ZM?I1MiriGT?+Tuwy1RB`*E!-o` z>b@t@!rO01tt>y%4s8GCj!d!8pJfG(*3LR0meo^oMx(Ut$w!Lw{gP9yqUNyqNE=}$ zcktNC8n|c1x;cNAuzx-Zg_Z&@#IFEPA+M z&<5(M-KUr+vdJjO5ZER(w$r3?jrQzs!N7IL1=sLuYT0reM z(XuC{=kHzO0I3lAB}`@PtRK3wzF=p4{>~!mT5r&9s&p^g8%!!(BWANiHX>l2yf~+X z#HJ!2a=NB>x^0hK1-dgC7-3*wG9`7H-NGIs9IniUOPB3tVun&F;A*0gA%DpFwnR?5 zNz3lB4Mo8_P}S|FEr(|oeio}d6p6OmHZ>*nlKY75GCX#arat0bvn@N{q(@k0C~sV4 zwlU*g(1gX4vG<^H&$y3>^*gyXs3oBlQYhHWWQo2|V8=e&_tVVt0220Knn z%PaS4?KojAMx}7ZM7Ef-scu_=Jv&&7X1)f2)(lziEo&RHY%@23k~KISh@;$XnKKoF zoI{=z_CygGIl@}jy`!h4aqN+%4RXJ1lsH`;2aJ7e3Ccl)Z*D8_aXw5y>};aVNc;n2 z3eC;&h@Y09?ne(&Mq5g{P#E+q=*Pahq-#iXf+UP2;6PBf*pSa5_mg;`GuMzuEIX-{hYp`{F`tpuX#|xea^wKTP zf*j*?mnND^x^h1H`agH>gr*2-nqT+v<|x5$gYNW>n{!~_(3!$oj7oGqhEDyN5_IPF zoV=e5^u9GPuV5hBDHxZToDGjz~wmlV3yK?(_ddd-#xZxxW^9GFPPNO z@u23SQdB#giS)2sblq0x_z-X_Vy#Z3aD+D_ACKrwbc8kuy3ZJj(8$)h%tZXtWH1Rn ze@3B`LlK_GhH~J(^3Q*9U-A8Ua}OHZkY!t`xGj+hDb4OmX+oqp=WxlNJb;a6rZTB5 z6EP9%#{j#QF0zNd{^%7XsuY@69KqqB%tV59>*nGCp5Mwt(oED}=>@&Jho=>|5&|_c zR^=G43EYf55+r2TtuxW#p?=f4RQV$iZy+&KFNa7=`6H>a0jQ{cPgCj4Go8Ryf$}y) zT<5kkt_Ng-O&XpQ*ftd;`pJ%0eK$Dd?7RnZyt#SsXX}F<3|K=h$)GS)3SQHf4U0re4SroG)k;nkvbY7{koG3NrEC}ok{#ZiW6NN@ zpUhEh8Jb2%=ljiVW#qef)i9;NE*mICvEARZJ6 zo~g5Tm~P&c;-1<8dle>HE(I-F6CMWEm=aE!iLq`LBCazd#iaRouBU|1$P2A$X!gNZ za(K&xQk^MzB6VozHgeBd;IXBN_^) z#~%99E{vY*ocgdW2CZa95mISG3)+hL*;qUmx1#nF!4;z{)-L8<@@4lM)1e*P{;+E% zALyIB7!{P=)uy=<^h(!&{=B12&v7obxnD`o)QtPCBkR>n3wCERXkzSfWHfSp28lRn z)0tcmwqB?u(h1Dc?VVJZ)U!jebDKy#Q9z_+IX}r^!m^KeN-r4sz~ylc>?CO;6jC$Z zH%MSCo^cw{joRfP7|x3@Z(Z5OM?O4`^VHke@T0GjF6olztx?TkkFO4=j^=4qDWd&P z^N=pX03XsK2vsgaoOMN_%PO~}E z<*l$xF`Bv~X9hz{bn||s;$>>gThjtH2(0zNdC0+2F z+Q!4iYjz=S9_5O$JA#E$kMu@=znsmyv%Yv|{n(xLMLX-!31!dR*R+^*I$ED|rA-T) zGBoJaruO7a%x`4Il-<>I+0wC5cPu!_^9@y+`c?Pg{ar_tdz#XQZRhQF9P$PYk zj{9vQ=8&Cs1Ts%Lq($@DH&jO+krh+K7I44$aQf%(k{YzDu`6l}rH(~vpf2b@Jlq={ zt8zVxwKFW7p=q?NW4ZTEMF$G66m9K&^1RLc2Wm83yy(VU_BkkzqKHrOb%Goh;tw~? z*Z6hzD40l~>``6WAT8*$)C>7)!e$h`^GQyCF2R3@vpnvZNSP*HG#L{=%RfSJ0Cx+v zc~gOPjC&mdJ!PP_wuxK@Iw+*2PafavDH(WyabT7NadYryn zc*G~!**fYf!&~{1T~65@Y0PZ0m0R$$^UZ8>mYGeOr;KL3+@Ppm!}*&+_L1+#SSjt* z*pAV%oYR#@uF{P-{iqRQrgV@0S+;A@qjj0-=z5NoT!hVOQe_A zqpZ)-q{-2fiYbR^atOtIx`Gujr zKgx*BsY&5KxgT|B1mqJkbu&F)PA7WV3z0K1OTgR6p>T|r;v$+x%LR?Hv2sBpT{bR@ zxVYHAc`=rj6Lt%6#MT7=@(_**cP+&=6f|C zjpUL9=?y4VyG&y#dZ!FNx`4ym-OzePx#Y(XO7S1a;=30 zmYGO4x4~L8!^G+;2t`+bs5He1HpN2S6c_8J2<4Y){_-x)v8%VdE3WiQ9?Ck_QuakXql%fwsPA=K8STEeXEQP~QRTFdCP4>YYS$-la zKYgVh%D&TRQz@pwlUKHHbVEF z2tT4^TlYikyRA)ReUY%c@zgy=;Ae{M!FkA73>Y04+}l&-ucoGMMRs_y9!t7DLDcX& zS`da87vQ$0%IMNb2e#+LrI&PUE{;>TYqu$&AiCiuW-(lr-J(tk*5dJA;d9{Oi1|(t znT6c~atoHmnMxCF~AEo|rn5HN3-{8Ew`bU{tHAmEysP)wt((y>9CnWVfg@>S#e! zZm1pXI=O9Nx&_nH1~Zj)$g-Qb0_fMKP57Qsm}oh_D3O|&NTkk14?ANlo{RB36VJ0K zo-_hVF=2f#JNISZwIf1D$V{&FsDoPhBbUl^rX}%DQWa zq3bFrEL0qF2L8~DF?vuMXD{kKMa#rQ^Wx5-i6N7)U&*`HQ`eXV6rBE|Br{Nwl6A;< z19lrx65hY|wW8639?IAscAzif0Hhr4j{Kn?iu@rx%^Be&){lGK>Sh`)4l#1IZpDwYRb80$skd z3hEM#L+X-_@u)6OF4@+HgS;+lX(O|WnWoOz3AO|qNSJP$7E0Or?J255Vq80|ec?e{ zn(#d%fo55TW?6`4S%l}Ac%Fr4lJi1=y5)4l<{{M{90F`>^(k^b*<= zr0IaW55VougiIB5j|?uBF_Z=ZQO45AqJ1}SPA$b?(jL9pBRU$exUMx!aVRq*1c`ig% zc~^V4N`iZi0x%OfEE8bJIpug;W=`HmGJQkj-Dc!1^3o#DpO|+ZzkP{PMUn11Jm;XJ zCgDY9IcIE%<-D1TO{zb|O7IG}%>#@UMhS#I>I*q}4-E32&e=OX2-ik7L#4)duPT7o$s0GF?J#G@E(*E3<#_$C@h^kcK5vWqyRIGEY!t4C7feCezrP zz^;aUO%~l(l#WC5G7c1aJ+M(*(0;EhMwT32}f5msA0lq4KZ{_kS;n-?J5k;oS{lkV=zj*wYz(3)UOIDs+90_x%+@(W*<1iNN*ah5hJFsb){J>|Dvzn5lh zqf&0PM|&?IOP`kpO_zdJP%hRosqz(x)YK)VspX5Xm0g-j(@{rh3!iu-TAn2k-ERpj zxB_KhD^5+lFeQbeiebozWK6}7^5!$wkfEqcH<3Ql25hZufFajm!+$Mw<2PHCrl#6j zgoE&_th8n7YMdXUCa122itC`_22}KGupCw0pc31jsI`}_bk-k0I@%| zT%?$5a%$^}<&A72T8-HKS>(J1T0vpoaI5*=J@lj^(e40W--N!j*F0>ncAAd2|Hl8xMXIwEZ5yvi-!F1r8z9y)_xnH=NNXP?c?r44mQx%>lc)Gu`H4 z{4Ij|EsbN!j83kv+X)`_SNa-`$WPGX+V^o;=Y@{WO=Q)Mu&T1UBkc=}D(tlpGFT2$ z*?4cMtgtVAL>*->$m-F79@vhYK&7Aa8rFHly#wriatQpm2VUKVqs>@19@I*6RYP0f zp3B;rj^M4>$Y_I#@*64Y#cT%KZcB5%&QJ;LD>te1<`OsBnx74VXP)*Dgt;slrBT># zrUkZ9(M%U_oufOGCP;H{4z4vqnW-F^J36WXeG`L`y(EKJgR{pvAc!^8jpdB^`Jueg zpFNwmor(BfzPQjIAyEcwIdQ$0k(ba*9)$dKHY(yA{oj!|b2E6{iDgdrMC={fN;B$QM0;vTP&YNf|G?R--!$iv(;`gd0? z(ReiUv;LR`c;?hC@j@?tc_#Bjbf*HXms*aIM^pZNmH6u;@CYV{-2?N-)vW_~yk@*iDzDXH@sVA0x-YZ?m5$P<51 z_=P}IQ+lA&3us8@m(lK%7y)5V9F4+bW(G-ZgSeEW!K zsEClQFOvS1p$!_Bv_OnSdB!&E{by1domOZX4Z>1#JKwa*hP~5&+T(_1H9?7NhvCBK z`x-j+VlAJo&Nv+@a)uv|<|pC)&Gh=y$T>KP^=vQwygv0r50h10OwyeoSjcrSNw*W&vfP9;)v#qbHb?0{@OfL74**B=j4jLa z!GXaGA(qoGM3_ylqL7L7a*uwS9JEU$$a%sKnY$>7^s{jUDV2~dtVE*4sMNv=V(Ek5 zLvT9M8stYNEvrb?L^{pF<`)Vb2VgZ%uZoi*jt2G@Dz;^XN+=h?_!lT2{f3rGEz8L) zwlY!}%nXoTv6jj#n(=O``c>-LE;i;9olI7B zFiE$Azz1z*l5Qgqt(*zDjAEW?uQGAWMez>ICpx@7ezI^fH&3$y4z6uGiK1-i$j|mr zo-`?GVJ*`&aA&p`W%>In%PFq4=TmKLyU-R3L3U0;GlD&X89@itJtinLpA4ll z1#Tg2t|zxNVca*ppfvsMS?DHx?e>IHd1^^i8-iSI=tY87bH*)H)Y7jWrmY%hl@6TBe}ex)f>|)-103;1}fh7PX<>4BgO6H&GAe ztvml;5b(wwmW-H<+FfFTLNk}h8D&U{s5F61`1+aW!qBr6|C7yY{Fz_2{PI72`s76y zVNSmqE6-M}Z&#$Ynwum5qyhLj10vVB8dZ&;v?!Viz64nLP+S}-)bCa`4jGOzJGR#5WjKEvD=%Fs~8v~WQJ(3&o|MMMh?x>^!i zo6$N$ZdcW@b|>I3l;j@4jOqZx3!ExK74VZhm*Kf~?Tv{e;cd$a?cdEZ9|Z-ml*eQIhO{>jD$97U`PCramB z>uet6^+St)dhudgAf>$kq~$oCl8&jVKTJ(!?gY?C*1ReFpG2r+XjA@O?Us^Pu{YT` z27hiGi1Vhsy035U&22orxi{8$Nq0T6g8D&L^26a&Zg+WDL?v*n6ze_#O|qTC$iANM z?Py=Gdw(lB*H4~o$d~v6L;jb{UTk}T&S*`=_WGaffYGeU^@zr+$y>xi_J-%+Mu7QB zyNB}vx=0){8y#?>rrqOfe-cjSMZJf@m$Y|(FM>P(%hOg@m)k&Tu4XQ(`-QRVcfLQ+ zLo=Xp8?j04_r5r9V(=u-X#gb{Ui_-`SJcI}NpTTP{+&)hZVZw4vUWnt9w(GN+YW{r zm>c^c?%Od6kP}c;gfvTMJJK)FF2;$xkLTatjmCHta#|q;!}}&7krs(d7`)udzP!Z1 z=9dzEWa*5aREw|`d?@Yp`uo;o*e(oBfc-^lW`b-^n35It>pU}5s5o3w>pjr`{gbG` zi_lN*Xz8)}`Fyx>GYN&`*~8hxq+x&#yd1v{{du#!z-Z&&503V)kjEmo6l6W(MLK4p z9)y;D2OY=IPfr40>W0lctb)pEn!AzezAdQJ}wFR|R$5m#ub=!?UGe(p4`z`7rlAfJ+aynE@+b^OaDG2YlS>y0? zq2J<+d~C*ZamKT|q@(m^`SOs?usd}RsNc%V%iwVxO+@K&%MzZs;4v^t5%*^60=Y-~ z+MYZNF7g=wSE|MB14%UKp1Tc#CNI9H|aE9fr=gn3} zP7eBz$2R%&^^>q=k@V*K&szQX6=JH3Dn;t24J>_v`uXIoO3AgXp7Y==%N9v~OE@<_ zzrb-**G|tYMliT~Tz`}5N?~7FkUVZ>!9D^FhxU$JkdARALF38vxtpJ--&30L755^S zzf2b)Vu_X+$kHr?oMe5s$c{&vqivS*!bWLL_DT~vm#mMXOPh7JROYSm8-hn#ytLUz zGh%HG9$|x~c7(us=A)_fFHD1TQ5sEY0!#lEv5)qtw@D-Uzh}QlbLyj|ao?0-D{cmT za`@Kn^uJ27PO~F3x>$d2ljOCRUn6}aV6zlcNNY3hjrhOE1vRcqj)ybcxeWv^MQOt~peOS;DxmD6<+L5+` zH7$M?gz8=ChFO^ zoPn3M<621S@76d&)|Y%}b|mP<^z9aIwbuoMzU6M}QBwW%H8E|-Pfffa*hovDWE)Vo z>o7ZC8@|(vYqC-lvvamOc%+@PHNhhdK8S3~8QOIt>(H(n?N(jjY^Md+60twUA=1eX z*%_Z$@hL_kbKCZ-?ZZ$$-K0_%CadLY^6b3gxFoq zn!FP}zJve6Kqp>%x&lK^x*R7tG!prp9(R#CbNGe)-9JR@jkHm#wJ)=MUw*ET(bt`R z(N|~Uq0x9onAd zG(MxcZQ00C8)uCjnM1=e-;amfi1WJ?-5R>Y)@}jUu4Cs<(VoIq_FqpZ_r>}Bic((W z=kzwerUI`+M(seOYv*mv@b>*y-)tD$cza`derfs`_y}~xmVKJv&q*wQgN#Uz)AQ+- z$-L7Ff^+Py90urRoa9G&Q*510u~cpcO1+e}#1W{?N=-7DBKP3tUuo)h!2SQe6m0gZ zmJLem%oMp*$*#+Y;LR>nD|U9$Z~qDsrbg6n`bbW%oJ?*?nAKQ<^D+PN4glHCh*C%GzHG*X(E(Q%kq^ z()gZwmM&7^QWoEwO0DYUBknZcEWoWPJn@^O`3ja*JXP{eOUXNURYP;{0Yh#+1jmE) zhin z9;Vag$bb1*luq7l=g(#n=~Vkz7VHo{1mp9?~+6Vj*Up#XLt5%eeQ?r^| zBbXw8R8Qt9e<#uM1ZRdzImkNoI%b^(u)cK)#u|}V^71W&iOb{n5DTQp) z&lLbPk4P?4Q`<8$qIc?Il)~NSP=@YZ0;#2?o2ZSuzXl3Bl<<=siJcK4;qaMbuj{^o zxl6_l7{x~$H?v_3y#O^`!#l4lYFw2E94DHhtSL^bHBpz zZshDbZ51cRy@;8jyQAY9lt+Td`$R7#e-}iT)^Bc_`*3OMeO@(~yUVl>W!~{=ogc=A z&`byRwTRtk4>@F>Uj#)6&bP9T9d^cx2=*L_wZ@2S9X{=pKwB(q0u}v}BU9$MUyb~m zsBjAXmN$+T8#IZ+a9YkBJVnzZDC+pHObbVp3=JA)Uf1ImjT%Fcpx;hx8_JBqvkPk1 z{e>j?f7d5uiRdnC=1#Iyf25pjFzd$2c!uBg;`XD*|FwMo)3wo0IWn&i^aMP9sHr;X z%!XvLG1+j^jAX;Y>N&}hGo~Fsuc3a-B?{&Gd0;*SykCs zS;D0{DUeT1E?7`GFUh!#H$6FLVPEk`F7c*>tUo$zF4kqV$!k(gb+Wc`MzXeQQcc|g z$#0A+qg17q6iWxT$SD8l6Q|eDK@sQIRV6BGt7?)BVZ9=)V%m%`nf1+3SpOiuOfFRF zNa~rPqt996A3vk9X?FHDmYISnKkAFEI&r}@wR5H?7u46)E=W#KR#s(}KcikUQ!~$> zsvTz}8R-Z8$TP%VM*U{A@6pnJKT$i>+8Q;|vD6Ny)tys6rL_7u^z&&mPO1QVe88R% zuqT4;tATzhJND-f5@Ac_&JRD^r@rlH`#JT-zWO=IL;j(!zAQfHKk7TQI_t~)YywmM zFtY*Z%o5-DrCp7G z;=H=Lc{Rzg^`yY;rnzIP>qd{eDA`aqsjmK-DYf-YjWZe>l9gBXksfXIXdltZ+3SlC`=5|4~1XQIP)pYesOXPk&OB zDULjw^7`|O(Z_`bSG~+Oq0IQ~V9f+&SDJUG{~tXzqoU5MoChUjHAWi|SXs&OG_A7C zRupy(+=E$y3(aOiCOkGfT$~-gFgrXe8{E<=H>a=xfqgM~Sxg?;iT2F$f>(iJ4=uHU zV7fPqjadE-g>2tsUSP0iFZBOy=^YEaLxMut`x|5e{De#up}blwlvxv@+?ohw&mxMH zmVae~V%zJ{wBJni#b<8(8wD(kxmIP9Ezz=MEo>6(eHHk1&9|1Z>sSvHl;B_06b~hu zXjw$tkD#~#W?szz9yxN=_eNfjWzVVX-VbS$`HOI8mn5=o&$g!$Uh!w9_KEj8$R70j z@&r0PjxsjzZ>FDE$G^`G9a&&Un^E^FLuz>;?N_G_k-X`p*y-i#=v+X4O&;7;hoF@Y z3}m}U!bwbQ&|i*hj1KrAq2!pNx8RB{xHVvt!0(gN%ZoUF{0=eLaYL>KH9EKg6Wr=4 z$)hguCiAg}jU` z6hdWViwBmRl%OA&rB|`N(`i<<`2}o+2AR^^+iVR4JD|=>$K3qW>)MU_QnQ?3`Ybd@ z96VarAf<(^RvFs_$=VX4l}Y6zq7=pPq!#fTNFVJ5(ao8g3EYi~!E~hI)`~sma8t1u z7eth?n46w^9I|v1b&zboaa+2$hqlui53#>?o5yB~{Mya>9>*7;*%k4%oF+eVL-xoC zc#h4*MYtUR49gtI$kC0n^$!P04SF#(`9i1i z47`Z79hU%$4ydvs`JtTnIXv-ipvdL0G9)GdRep zgZ!gsBQb+yv>;~mw2hU+t|&xJ`=z6cj8u5r_}RIe5-#0ne)8!T@}qlvRoHBupTKPC z)+Hu##MaGSaD38JjDl-yHe~)j6bx5E&^F`#2uQy>;xzdh+Ahs@B!*kH|270;w(za& zU7Fgkfx=UpKHCx|Fl3%ilrU0<+T4ah^UYZFz`%!cBA*)mgmW1xuB|hFE>m3ZpH_aV zTJ*bimO3x?4d!;CvP5=xem1y;XJU}-QpL8Rr2oBhR+L+7LnwO|(I>2DDt)A$m(ZMF z=B#wqIv-tjH5MqXu<2@^nc_c#Ec+E1&ioj?!1@SsiE9krYTW+yCJw!tfq(Ap2jw5f zg|3%kQdhEu-}e|aerKwXqLb9t6>xtgNSnxNJU9U|bLhrh4E$z3s%7_Q9RWP~P;+yY zZd|q6;9H9GQ4YMApANU_WxTex7r_{4w@sb6`qhCLU1E?%{`Wz22P=IRjiMd9^l#W{ zC56D*{*gDQ9hwW9n|AbO73Y7ZMtdSTWxGNNT(^vUyLN}IJ*d#&=3#rH1#bgOhkuZs zcHc(#5~OW5DjlJxogYzB{o%qKEaTjw&2~f0EEvo`h2H>6uS1*-Xzc5pA-(mZ+sSfv zXxhbpw}^C}qpb%gp06%+_5Xij7s7bmsA+mPpC3YIa2dheIUL^;=6@n@TT20tb~MUa zRf%_2WK{WCR%~Pa@X-~T`3aM(%Q1-Y572n&O=)de(ni|jWBYaH1>aBki!-y%m65>i zTu{!u3NBj|y8D3{GDK+ z`JfOw#JOkQe8X~;b@69~ ziI!EYHI}rjd?4@_(2775fotR?kGqt?Wv|am8Bn5(_~xZNbfeD7a0M)qHz7}9Wqspw z^v7@PEz8-sxMLTNVI1@|$du*S5TVz_fTUNI(fYh4&A80ZENT{S8D_SxpUX5SDHmD%>K_;@!XF831=rpHNotQf=peA zlK;qQ8qo@q6|pUCdaJnLrUg0<6$LgHG2uRXgq5YmuG=i_A~w|GgI{!*)v;^1?!)_Y zqBcp_z7}(fV=-6DkniO_g?~~@eb$cG(Obi~tDX2S`|ZpBoQ>@j|8q7pZllk+o#B7Z z#vNY&JDp9|35Gr8u>Zgy>n}|HchUcU7ybW#c+sEyTpyo|^H+P}BirSStf^$g&$xeM zll#Q?N8~<-xqU~m<-S+u9UOD<<^;NfV=mq>+uy|-rz9Erf6@y>PDyK&K}*b1v1Ou$A!(TCC!L$+qZjR%kH4WKh1dob|uUqQh2BNQ=J+7e`t64 zKXRZD*>vdp7DO8=-0nR2CkJ*%IcsCc0%o)i+rJ`?H%nB8W;7l*x?*bOHM5fyO|`h} zR8iMZF}s?%xlOfm=)%+#lZU-neO6i4J8k}zBXgZP%f;)+MO=ggwu?7$&zv-Ae7taS za&~oPZTzH>$BisH_Jk3Jp@Qru1u41)Y~ zU*H6W5r$9BwPmGTbA#@q$AfMC4aWn0>GM^52M}Y+aOSPC<^j2PQ9_i?0NSy}=UDn< z!^{u#94_*`T=|qhKDi%xmB{h`aD()xoA_}+uM&>WiTH-}yei0Jt)!vV^;VJ7?|}U> zGzRgzM1F=V&z;Bt$WCQq>xJM$I+QfWa%+Ngim**ep91=0ZFP1aFB7?D%ldxgts-Zi zXwxqX(qGq4{C1I_;ObW&#P1RL-mbhfkQZ>_^*&uB^6$Ixb06abs4bO={A5?Y(4-#+ zwn6G)BKVMe*PbeT=Q?kcBhDDT=vWF^!*7Uf0+XL_SwYg z#{pd;^8ILRwQ_1}yXW{iERispjn{}=)3HtDg~-Cs!x;-YMShzr&rSLHdwY-oeuDm3 z9i8}bk$>KmU&hhBIIv=ouXN?)TW&F7sGU?v7_FTx6ZuRxja)O4JqFlzsi)6p`ku3B z9v3@3cVzs=kzVedlq2Q$mZUeaS<&km7m?P|Zl6j7f894~TSJ6M~Y6QqBh$Tk1a zC~|FGuu|mOnDw~GFCisu{<&sh!sQpa<|B8AJe!ZC`1|ci347jU^v6%%I4F`IFLG_J zd7j9Rb>lnp=|+)j`L7iDQEq%^-SW7|v$g3s;tZ4W(Y4o*f6Tp>D~Za`+lLO6#wEGalP!9sjJsvpf_&~y(*rOJ3R9FQqYz zC$*ke@7jXKueoNfL}7|0%#Yo+OJRNxjB!;GM)SAJM6R{32SuJuPb$Zze&TQIC;k9d z4F7x&Y58?3?T^wQE^>Xo4)v4D#!I= z%jdy|%0V`NBGBU!NvGURC)aFd#3>z-U+&5&4QKsk>+QP;6Upo0pucaGv_fMxr6p@4 z%5Qr=VaWCcJZZ^ZcA6tD65Ab=>3`0?EtVc|YhLp}GrOgBF|P2 zWan*?*F)eVWxp>-XHy?KlOEedel&Pr4`-b+fG5|Umu(GA@rR2%+j@-TlSO`*o4&J; zQYCV2J-JNe+4>fx|Debxxam9XeUr#F{kHWZAHbU*o~OkhE^@7WlSQuCw@T#M%1`zD zs?^US@R53U_G%vKL(e$k?kDA>_7qB|GH5G3lEwuH|W@PM#gEmPkpeEE7J2$0`J$C znO3r`6Cxk)%AGyi`6Acqaz#J#wf)Gq_8}*m6p3x`1s|zvr_B|x@jWlw*h}dwl60D~ zrE^8lc4taDJXG4cmN`$H(h>Qi;C*{i{X7(;aleGo#*b%2uI;0}Bl7FqJaVb_&D`o^ zkyE*R9V&wShf&4jldTLSnjmsbzf1a&UoUb^|NBKgmXxqIboMcx5jj`Al{@Ey?}+>a zH@>sy`*A<F^Q?h}`YoXu?Y6F*AvukS-1hkTpVPZ{`7o6R)` zPLxKQq@nezPLXS4tH;LI_j=#pC$5aZG_t0R;h#Yu*M3Nk>|v* z1g*3v$XZE9tLv@($h$ON$S(o!ms9qf;(!t&Ki8F0e>TTX z+#YHqjMg4+6}eW%M?^lw%_DcR-=ALa=;LCM8EzH1=4&1i z`Dt!^)EP}Ps0^=){61Iiugh{Z^@VnTq*fK(F^% z{m7T}A&(>dH6p(Yyl-#P^;V-R>99${aItKiIP0%%B0t7WV_pz{02LUYbLfwa@0>vo z7rEw_Cif$+>PNn;ANhkK*X9A6M6Qjq+xkg=055#?aelbSPj&5cO<=#tBG>Y-61nF0 zmx)~K+YgF7oBiX^X_LsOy82NYnH1>QC1H3vVCz`UbSaH|&fN1}&P>A`hjRZuM#6AX zHVxUU;r=i3Nf~L7skr}({5V(ctZ#1>dA9x^N1R7Qex4hj%IWx!b_v78>gcY2MV`%; zq+`L6l(^m&ibS4GM~Yu2^3a}Et~tCRd3`_eTSY#dl(70cXU^;TiQnE&{GNW|7tp|m zkJgrpM6TJdOyt@)S18*ORpjeQ3BUZ`<%Uf1bt2dLV!OyS{d+{tTWdD`X+b|J zV8!(LaFNJ)Dq`b1cNfY;u9jcqTKjAjxmtda*N5z57M^6Ec9ADsIr<1)TZ{wi5%~of za%p1R&-dfSg6CyhGmtAiUgRk^4ZCM>U0};gB%Ib(uJ1!0N80y`yf0nbB#c(yog&ZX z_sCuzZ`ygDHa5mZu9cx!Z-k!yBNh&iul6I~ zE^@7n4Cczw+rTj*A5TWI<(EA^YO5>7zTW^JsskFMzY^4SV?X(<6!~6mKC%itgxpxP7b@r2&S;**Rj`KptGutG#%#Ob=7P;F0MV@WVLUp!8 z}xi>^gGV+F;sB9eH4rQL<(ff=iCvTCGu?cC7-cGpj>toMg2hl;0!!Fh8>G<+ek&kfGaPE85h+LcB z-74}>eK}_-kBD4bJHFaa{@eSBKbR-qo_DsZf39(YRL{qVoTu8h{Bwi;QY!LLdw0$! zYDB&*l>U310HuGc$p09U|JIj3BJ$6;^0FZRS4Do2E6+6tf|UMtk@J+u>hJ7N4`#!A zo~HjXBF|=j>MtwBzD2Q&{zB&ypQn=ovrpbA=}d6-bndgP6#2QXTpA*k<8hI{7Lvc> zr~j77uf>|tZ||`tUMy1l9U^}{6#rE}{(j?0;Cb)UA8V)FcYXQsBHzcA%h@)if1b#- zdTtcCR?jO%o~@qaNdIw>)4c^>KlIgDELabBNSIax@xz!S03PpqMV_rMQ(X={nId}L z!}Q16Aefi%3WLI}5L<2nKfn!3zT+u28Rs`&(!0qGBZp07vlSxO_O;fET-$frD)NKf z^qsTjE|Cv$<<7oo{sa=}cR&mKkth0*&lmZ=l!>*cv+uT|ANksTJ)Y7XO{#gGCRE?}db^9t#Aw@kR=6?PBq1 zg2yw`p*#GPPGLqmcL*-q1PEh34+_ry0+7YOFF4gReJuX6;4)?Q%bN#(Lix(n!^bIZ z%sT|JqMw*|sDdA+;Pw~#;k07j5lZ+YBY3gs`M4xu?Y~6u4T9V9eoOEtGw`1Y{!|8@ ziv-CIPiNqx1%D<3r^lE#BBH0kk5cfX75o?lKUTr1bwxih^Q)MMAm)u$!XKyLCn)%d z3VxD;k5llI6?}q%pQ7NWDR{AhPgL+p3SOe%XDT@T1B>V<=AEVBXDfKAf|K`%eq!D^ z3VyDF&roo>=&rh;Fn;1?A8O{3-=spx{jkzEHuhR`5j%evN`(tKiow_+kaW zLBVfS@TCggtl-NP{ALATq2MV6zeT}Y6g;iqw=4J;75q*GU#Z}$6#Q-lU#;NxDENH} z{v`$fih@6&;QST}>A?Ysd0$h))2uA|iFpqx_}3NuVFh2S;NMX2Zz=e<75q^J|E_|6 zPr;v1aGIS)KQZq~1%Fz>pH*=F-v*HkVqTjPexriFsNgRt_!b4m@#qSY3o{`RLg4>mc4ZjB#V!Y1E2!Fodb|!Aa zKOlHfMtCw-%=>|$#&-5^%=@8&zoy`?EBKoV{$mCIse*SX_|FymZ3TZwT@uc27y(Z|*!@iDI}65imyQSfdB|E+@mPQiN={ErI0L&5*7;D1%{ zzbW`X6#SnG{x1cGNwa)nUao@2B6xf^(;t_hztYF<8xbG#Xm=v|iFtz*d^ZK(UBUNI z@I4iLh=T7O!RK?i0vyfK|HQm~BjHIH^Y&Bl{T1A{azANiuz#q8AEw}+Q}DQgAEw~L z75s1oKT^R*DELtdevE>TRB$>0i+*C>7zICG!B151lN5ZMf}gD5rzrSo3O-T6CnlJ*1f&pL#?1Z_Il=5}pJx?+pciQ^DU-@SiAnhl2lH!QWBvcNP2>3jUsg|5Cx< zSMY5L{(*vjsNf$d_-_<^yMq5t!Fv?^j|#p+!T+M*y$b$!1^-yV|E1ue<*?s!V_uHC zOm^^?g6AptAO+t|!FN~i!3w^Yg4?%(`>Hb&^Y&4~@2lXSQSkj0e5isSsNe@H_%H?k zoPx&{{4fO{uHZ)~c%g!iQ1GJ^{1^p4R>4OpIGw^rKQZq(1wTQ-Pg3x43VyPJpQ7NW zDfmPMpQPX=3Vx=7Pf_r*6}(izrz-d~1-Eb057$l1o34aEPr=Vu@R;42iIPG_Q@nAf7g5Rg$_bd3975pm-{(ypi zO~D^h@P`%r8w&nS1%E`rzoX!fD)@I5{Cf)ixPm{S;OiCq`wIS~fGU)DiFun9e2ao_Rq$67{8a`2p@RQN!P^!5bp?M@!QWEwpD6fG75rxk z{&NL?TfyH|@Lwo+r-Hw);M)}Z0|oC=@ZTu-b_M^Pg7+x+9~FFug8xOqdlmfe3jVQz z)2)E$2a7?R=0`s`r&I6&3O-Q5^A&t|1s|;7dntHDKf_(%mGrQo9#e2ju0uiz&r_(=*r zR>8+B_{j=>ih|Rvo9HLz6)X5e1)rqglNJ071wT{4rzrSY3SO$*?Fm67lyht>g*pT;I-q-2#j;O+cOXK!8Y1ajFX21oqQnKE@Qso1?@9Ps z5`Jzd{K821X?P(3>C-9qOlm^m7e&I8IOfr7pi?rH{D?F$4y7_aw=>RvLXvMV#BTrz;m97cXB;)+1 zjgagD#z%%QdZ=TZ-)s?*H8XC1l^Te?&A7Z6C4jxHjLXXr9Q<#LpXMNjJ&a9%dIUd* z@iQX$V#d#k;NM|;(gYkKh@cH}_j`aoAH|?_}z@Jh~QfpPet(e7{4WgSFr18iQo@2{>2F1$@m=+{Im4p z1Mi*)o@D&K2>uM?_eb#E`3IF>ir`l={^bbX&iGd&_}>`+dIT>$kf5~@d@bXTMDR%m z5%gFD|A6uDMese?Wj`LlA7}i92);YJ@|Pm`7Z~3h!M8KMC4!&-S%O}V;5RV-;|Si) z_)jDF9~ke5;0J$>pr1wX$&CLzf~OdNJA&8q3nJc$;01Alei6aPGyYx#|1;yijNqs9 zQ1^ZWA8{B#zlz|mGrlc?pZ9r!K8WD&F}^*5&lyh8jtIVi@xMgy6AmZnZxQ@f#y^hW z1CAi*pAq~*#{Ji0`0`&dPH*oGe@;A-o<9@8XEDBi1iyvx10wiUg_O=`BlvTSe=dSQ zG=jqOe_AER|4coK*in)2Ut@es1n*`1xCmawQ}g6}($!e0`>s~E3{;EyprD}w)y@%a&a;wVbLCW7C` z_*D`7H;mI;S;C)5Mf7}q1Ygbg;t2jW<4Yp=sL_$56PN zBlzQtuZZ9U$5HrH1izT^TO#-d#&3(@!;hzQS|j*{jNci-zr^?(5&Q>?zZt=6PN4L+ zMQ}o6-cR$0W`1zrFB9TtoChg*Ou+{zc-Cy8&p;*oAO+7?aM@JMkjA{-GZ6C_v;Rar zLmKl2XCO8_FNPwrn0X6t7MvFWS#X}DXTkT5U%wNy&oqoH zEI1F^S#Tblv*0|~X2E&z%!2bEnFZ%TG7HXwUKX4Ow=6ghN?C9ol(OJFXk@{85XgeF zQ_q64lg@&(GtPpubIpRYQ_O<1Q_O;&7{LgLng1FYk;S~R5zK@ir{Loi{A2~6px~z{ z_^Aqhnt~TA_(TOiUBM?Q_+$kyQSdVq{7eN;DEJfwKTE;SR`5~A8Oyk5btQt$=^U!dTP3f`pP3l;oo1z)7# z*C_b43Vxk}U$5Yc75oMTzfr-LDELwZ|AK-yEBG=6U#{RcDfrC_zCyuM3Vw@%wu-Q75p9rzgNNUQ}Fv0{7VY{Wd;9= zg0E5V2Ne9P3jQ?(e^9|6Qt+=U_`?dmR>8la;NMj6Zz=dA3jS>c|Biw`s^IGs{JRSN zn1X*#!5>%fClq|Wf`4DZHz@d%3jUOWKds=;DEPAq{+xn8ui$M8{(^#URPYxSe3OE| zq~Mzse2ao_Rq&S;{1pZNfr7uP;6GIGA1U~23f`{ZuPgW)3jU^ozopH(|3kq)R`7o+ z_`ei0kf)^9CT=e7oqp4%FHsFMDH3Vx7+AFSZ?-yfo% zSeEl*qfhj_*x=FgVuQz(^bb|=!xa4U3O-!H4_ELb6#Pg9FI4am3VxJ=AFbfWDEP4o zK2pJ>=kmt>MN0V53LZVjH|a#r@eO{wlFkVVexia$?*o|h$135+DfoB=KUu*iDEKJ~ zeyW0>rr^a2K2gD=_Z*BJCMn@3D|m^5pP}GqDtJP{rzrSY3VybNmnwMlUWc(m^j?R- z&r#ATQ}F0L5R=YyCHxEpKTpBS6+C*+#N>N{5`LzFU#Q^G`zj{=i$YcQo-jc_&f!lui(`Rez}5Qq2SSbKE`fWD&cDtyiURE z6+C*6$mH9ggkPZGjSAkR;L&?ZCf}=-@QW1u8U?>r!LL*B==~_8PxOA2!EaE~xlzHF zDELwZ|AK-yEBG=6U#{RcDfrC_zCyuM3Vw@%wu-Q75p9r|3B=V2Yg(`@yCx|Lp5N!EF04ttW$SrZf7i8wuB@w5W@K+ zoh4y4PAAz0LJ7_E-U$$T$Mg;cOn}fkgic5Tfe?C0DF2y#JNtgG?CDNA87H6reZZ2w zH*a>f&GvogS@`)Deu0Jm-oh`m@QW<`VhjI+gP zW8v3Y_;nV3y@lUk;Wt|NA`8FC!f&?lTP*xm3%||6Z@2I}Ec{Ljzsth!w(xr_{9X&c z&%*Dw@CPh>v4uZq;SX8(!xp~8!XL5lKU(;s7XFxpKW^cFvhXJ?{7DOc%EF(v@MkRi zSqp#8!k@SB7cBfm3xCPNU$*d9Ec{gqf6c=GY~in4_!}1friH&{;cr{`I~M+~g}-Ov zf3fiQE&Q(*{x=K%yM=#X;U8M~KP>zs3;)={|7qc$Sopsz{8J16%)&pn@GmUTaCz&MU;nxm`SmP(eG8Yj zXSw=+Q67mD!uz8)(_a-SzNyi(p5~Q`%UiYd`_<{Y3B=cN)tcXCDfumpp3(Z7vn}#3 zEBO&dUcwz-!FCoJE;|F_#KXe9)WTo3=-IrI^~>A8B9Tk9ol}U9Sl+!iU{%cs3M)HM`txfv;QrkICareE$YiWME;@cT{;foaC-tdjI{GTlR zeZ}Q1X!^bH^vsVIKKxf~=MF~yaIODWijOs%9#@~4#KY2gp+)`z#iK^g6s_kgi=L7l z*`A>M35u5(J$+gazrQ}rp2D42Pf-34#ohNH%d@{%yu#?0{Q9Hf;{yC&itlLn2HKvL zcII&1_aKX&LJQwj@tuvHGOcGH;$oXd>PNyNf3V`a8a?akht5-cyx~%R?^1k%;df~H z*NKOP`<{}YWaKH?)n~a~IKDB%Culy5c$l6_i~MxOry4y}Jk)1D3qL^dX-0k`@GBLsG4fNj{F4^`nc}+}`N>*- z_3<2TkdIWn!N}KW`SFUo?|q)Ac|!5MjJ()?nBsdIUZUkMQrvy-v-qF;6#uo6r)ENZ zK3DuVhD$kIj|xU%WIw~jzf~w6H+&PVr^Uk0R(!UR7yXYao-lkXt>**9n+!it^T+dprW6j499|8ApO1<90B7dmj2N*rlpShZNm_3V>e2G@2_7q6hrj);8IZmg#?z+X_j-0(vE;4b743M1}&e8acU;a;Tp0>dS~&sz9$)7Vb;ecumhJ=YSKuryLX zK34L-HTnzmmsQhQ&mo2{(R`uehZpw{GV+@yiag~L?r1-*s{JJwZT=)IpDXqU+@#BoV_~*kFKi+Whw>Mh&n~I-ktjfHeBR86hFuCky`$I3x8bkbB+8NT7LBItp9w&rCc>C{(Hms(((%wzsT^Bx+dSK zxcmOc`C9%P#l^cs%t_QTO29&R|G1Q&2E{Kk`h_2$_~nKV)A}z`+ss&=WwqwT-x^%3vX21eJ}aGTF+gIyYICWKd^BF>krCzD}JpBSN!~$#79InSxKvn zNdDesk$+3^>x~}q^DFGZ;ofNYep=z)itlRtt;jF3$gjL7>$%D3k@3!^#79Ji8#@cM z{;^7alF`4Z=BHWoT&egiM*lCh{Jo0Dj2>z()o06DY)??WRPo!49*I|#;&&Lnoz`=d z;#Effd73Xz1-lU5+b;EPB=HfEVS)HgBEF7(7JoEY^z ztBNl+oT`=jd`)~rWW9i$>+j9+3d%rWFO5n0FBKVI`oE%GlY{!~EE3cu!XgSSOO zARd;#ODytVDgHu0&uDTKg^?hirT9xmUhG+@_$!8szj{n@_r2$`GWRX<5s|e5>9)~t zINYH8Zi>Hd^v~1j++yL!DE^j_7dx+1{2jx`>ffGG{5`{^UVo*y`#$uv4tEoBP=yiq zedq^hzO&+gH+l**pQHE(hOef})j7mRMAkIvK;1?4xx*s=q2eDIJ*`@PwK&@o7diqlqb{TZi!o=$v3#C;Ei*!ieM{wKwkH+m$Ui<>yy6$~G%^*0d@tM3OW`IU_P zrds}N3%^hCRgC--T7KJR4%dCJ^jezFSG?ND7i<0p#ohO|OZ&A#lJx}jcPYNQ(IfG_ zLh&^WpQ82uRq>gIi#?;}uzvTw@W0met6p*Ueb${?&&7(n@3W@vg!(+aMucwv*?IzL66<&V?y4`}(}^k8A6&e%Cx^SO!-GhE8mSr-1F;u{+IowS|}sN&On zZ-Cb+9+baA@!>{(OReW?#m5*f`8BqU^#|n-ReTd8FY&t7!ar1eGb1nMaFhL6e~?cn z9+sYG5g!q8-@`Iq+kd;#3%)!Se3=%}>_+TjDG~M~6UeUw!tc0$dnz z-+TTGDd$~|{1Tu1lf(-n1;$QE|LX2={v>e@w{S%#yiK(JPl=C+xbN%PM%%MKHGGAU zxY7SB%`a9wY4~}XPfD?To8i5he@r|q+;w^!zSByMpyY3a8gS7l6eXJ+wA7&|@Hu9si{2vtWGhF=eDC%exM%?$gi=9^~?!M1m z_;&Nd)9u&93nT7(-X&g(6%UTPS6vXUr^dp6PrNYVzAwH~$LnLo4>j@HMDyJbWclE@ z@+!sM_sExN`5zUZVD!*%Ons^;!D-&faM6F6;ztGe4~idScvS1z>0s6q)PJ1f!SU%o z6+h1C*;MP9^;^~x9EaYm_(?`y+RchXSl)f_{B~N;C5oS5qJ+CN!iQ)Td zzQXTVkNbZ4-8COWJgmO&V&OBDo?!d_2gTj@)JysKLh(I}J(6EFN3cCXey!r}``;ha zPfkCQ+^{C>la*YSE;@x_MUr++*3DAx0k;ZomUQQUnGds_SdeU4`NXN>$< zt^X3me`9!s<~tw5^6q=sMgB3xgYr!aSw3O(NIAJp@x}oEN%5utuRWIaGza*FiU-@H z3CFSg^G1GcZU1tVfHeL!TRm<;x0?WT_`1zVwoXGrD!*9@h^^=&l7{0OQ zV=cTv@nF081Mv|N_kDTNF1Mb{`rY@=OL_QM@wp~k$@kq)VfnWL{8q)^HvBAY=kBMn z{JVx1YJR5T?-@Qu^R-W7`S%U4(R@e6-S^9jKRHG5zZ-esuPgpxfbVrW>v!KTFY=El z{;`plc43<{SpIOsrJf$5_$P)-J$*@W_r3F?fA=$4&*w&7_zj9LG+gwIrUWdEd>!Bi zDIS#nLh&z+{4P4(=AO-Zg8u&{#lJQ360h2GSU%{_?^fJ>uf6n_HaVB&-S^r{yv|qr zN27m+wrA9NEbqS8Ui|+JiZ8dK7K=Qte;Gj)gvPUmZ>9M{#ohPXPtrVk0n4vqt8ZPnO@xpNbUq!qya-NB=q{C&3uVwTIA9)eWUl5Q# zRPl8J@^34Cp^@KG+qufctS89FDt@t%FV^x0D89bYFXNQqe_%Zu8eXU6-&TC%06+hd z@N~GBcwuByBQNRvgW|#VuI5sf-^|EM`M*T*tBn1UZeJ_Dg^?HDc^T`u#>iJ``%kv; zMT%c%9FIKY`^<{Rq<~lu3|kw`BkrGey7nR_Ww)qV1MJ}Ygm5N zijqFJ>tFh=Wj@+)@k=i&zK!9M4%=SG^4l7|zSeWF;`bYSq@B7#@$HPf_>-p<5B6t{ zy`J@tG4fkz{RiE^{9&VC+S$j5kBF?ilEh2WZP<*qto@OT#7oPg6YDKivE-maj1Kv$URn zD?ZNf?KHpRZkFHC@MAS!cn|ZP4HtiM2k{Y+0+XJ@wS39FEWc|&{z=6r7%ui)av#f2 zGF-}e-~G&k{jPs29y9V%o)3P2<=-&*wVt-;8^zxY@B{>u~(_Pf4QyxPc%pN~DndV>9~hZLU?kS}_eCJ=#OrRw8v?xi5ta}3mu^sePa`k+wZb1+elNq<(BXC|9_*(rQG9PBzk`;a z@F?r~wc%2a?o|9YhKv0rkFk8*aH*#!Djw`dZS*+HCyacd4)=G8HyJK^J|w=5mcbvZ z{E7868+oZmzg2vW;alm4)_j8HTMdtD{s+bPH(c7UO`l}>cEcsUXDHqo;Ojrd^6MEc z<*ion4Fddn#fJy@Pl^Zo8+A{!{%#{L zea^7(`xOtiry&zR@G;v*nA-4>Vlz>t@9dGF1F1J2KeEMA8xp`Up~xSqX;7eKc(A^_t$47$Z25QA zbGy+a_O~j2hv8!9!-@y%#n=y6&s|1d^c<{supGXm_}xZc@^S2ktmj_Chw1oUN<7S8 z-K*q-<#6ObSkHY%&-Gf*Ly8B>;rbu3`~yZ_?2jwH*lQ;tv}=67K7YFELzpY|Qy5>;I$SB7ckG!Sb;3CoKPHK)zA&VEW&y_+v(1`UxBS zi}n1;@NIN@9-;VChOevnhl)RKc$MZ2pR%4O4KL9AF2$cUT;etSGnNmga|`jX@~}k7 zKWFqvx!U-1*7Jhl;ve=^JQ&~G6o1jkkJEOJ{DSqoY`EBYk>alyUZ>^1Q2aH+rJPiK z$$ElzUZ{A`&UY36v(Y2zJnbvi6Abr4#osjYV&^Jfv;6CZOS`b2;%^x){e%Y;58A)M zH>@Wp->3LHM$b&04zE~v<+rToJtM!TmcLx__YIF~zT9^#|2M<8)x28qpq{%F|G>y^ zspU8PH|q)NPbnVMf1lz(J)8W8$I&BK(rP0M<(KbSf5PzhHUCcWCc~+isn36YVELrs z8)*LbA6fslh7Z?#^`DrJ4)9*$g^^E9e5KsJtN7=JOMiGqWI2-WGe+L- zYQ zQhb`>V%yP*&oErtsY?~FHC*H$R(wOlD|O_WXhYG6NWI~b&MU0N>9)V&(ym>mc)Q_J zzhY~%y!*cUSGE3c6?flvPu(;1xpf_uf70lYeA#DRwr3B+#r{sk_X_aS6#up1lFs)i zzMtWu=Y8VxyEaAr_{Dl0ZlRH%ufIH2@dpeS{cF<%SD2o0#79K7GV)T+x1@tPBO(tO zF3;8|{z!n&Q~Zhmzf$pQ0{kPzuMhBzHsEmY4e-f|Z)13ij_-|%Z*RD?BhM?ogW=LY z|6K8?;k#-*WgBw1rG{Us`5THaGF;LjvJuPQ65yj0zdgXGDt=dhw<}&@xTJsG@bLVa zPkcn=S4MuSwsVQ%I~!i4`L~LXH(bhp;l`|IlHrrJ{QinhF~Q z(UHtgGkk3=zn|i#2l(-dpAq19Dt=~w|5fp`3}0XCA3lo1Jv+dsD}GLZAENlV0e+L> z=NT^fGI}f4e}Un$61hn6VEXSqn&mGv@>gp+A5{Ee!$nWk*5UbbfrUR#yfAW!(NnJV z@3IZ^%M6!s_oKu|M6NP?jF$gK@#_p9ulbJKviyyPOFyJV@tX}V(DKJCep`UwsQ8@$ z{(|E71o$_K-*33|w?}Qq_B?3#?{v7=DE_SBQg?RUp5>PqF7fSB{87V4X+38v{*2)g z?h?hHH~dsBzxSBsA_e+)&yUt*dwbWsu2g&T4lSwfrX9K)cW7#g#P_LBS4YQnwOVZA~_b;<9+$uPNTs*4fgY zjMWD9kqxdsyIgTah}Pz|p6*1tsWn7zanz&NCrQamY1r1)*4f5M%BfwFpqywTQ&RCn zs>OljZ7rQ$siZFnSaox9PNKIx9j8a;#=E=P+nN@{SggFItBWF9*`4Z2cQy9TsUA1C ztutLx+>w}{`TMrc4BwZRW`3T&w>=*%n%kS%0xe;};KV4R_$5;+b~<^Y>C}RFx(iWJ zqPeTvNrJGbS5mOaRA-{Sy0~KQjJD3HR9us(J(H=Pwyw@8U8(A}##AB|o^0@JdDyeH zoV-n;Dds*}66HthlHJKfI@vs>E!o~Y!O3GXpuX+EWIxYS!qjvoyXMSD^vvx~v}CS? zlZEuSxeW`tlUWExOXtq)O4lZu<|do75ig!w)!CP5Z*zr9*{iroQd~TDVp}JtdMeeG znw(50+S+@jC&M$Lx};Pk+T>(UQ>v|-YKBVoI2-T$Goxx|Xu@Ri`Jyt#k@icv$_|Sr(mbh5K)L3Of^3UmNijURw2Ta3yo za<$4EP34oSOG@S{cQUbe4mCBiQf<^&%t*|4{;W=RQU`}?_&zheF042@i5luga*4Cr z(yjIBM7p=9A<@#@9;@xEFOJ8e)SsxWi#0Ut9iOtt%t;MZH8bOJZl0n=ZeOdqxM;Uj zGD#uEJ5&P4I};tr9tf|vY*Kq$vNJuQXF+FEU9zW}>SVG`wO~~qRnelU+=V0W-@YIg zbId5Un^8)AhaNJTx=-BqXd`ERApOaNvD^`e;28)l8*jh%;~VE$>5Zaqr^|8 zIX7Z`Lli`G94C2|lTcLX63vNpf--uDf}@(++15k7Nh(OSGwb8!PVveR;BM756DL$t zmi9KrtKz;=R-wyS#mwZq`gCt&tZsUJI$G4znn)#^?x~2=V4$jrLW1c%; zL@f)YZ}5p5&sjdvCHgN$%An87)@cS{F-C^o$a6 zSmYRLy6cmj{`wpKK(xYrU`Dd1C(&Yxq{=T>vuXfpx*h+_`X{w_x#ia(Ys3+EuNMu1hxc`J7I;(ZyQ5V+%i)N&UFG?k1<@R2kL8RkVT_cRp0D^xB?LJm^ZO z>V^0bQzA_yqa}_FQ)!Ujo=kai))guzyXupvJ}T>8lZ)c6UB-CwHbrrtVmC$=T9GFW z1$x4dR_;c_6+JLy57LtCq^BB9EW!l58p?cyH}kioyl#3)F%Obxjzvm+`~WWYG%Z0M zqOmuf?BVeJBYXC|Vg6NOnXSAS7$RR>B>uamH;vw1dFremkPsZdR{^~)r$a*)b8Cmr z#m&5EP~NW3>BWWVbLM@57C29cM(m?W>lrQKHqbPUIfxclCg*o2Q*9m8k4v=26Wo=f zUYBlT^QK5LJk0n~wmlkR2d5ELe=b<{>B>2}C9ay%=d?1~K~rNWW_o>tr5DUv$2oSkHxwKN9AoA5Kdq_f28RRy&HM&3H$pmla)_MjKQr^We>O3l8=SfX_7nR%jX=>k9 zzpz*jI>=G=5LC=F5HaPZKIi@yCH@4SCX2VW(R`gmPxT8Wqno;VJJVH}b9BHDdUGMy z-s7aQs@m4RSgavlUlFGwRbq0px3i6s3;Nw|Yv*keV;onR;B8J)PbgW%LrW^8Ra8Vt zIS&w=sv9jDyjnM<%KMT{G|g7UB{qZJK;s;0aS2&WJ?i>$Wx4e3hb#y;7Ma``Wp0fn zPr|&8@}Hrx3(XI|lbp!Y^EBAlgQq;XCs;*Iyl?#OtxCa~YSXCR)lZ1mPoiSirz#?w=*<~lSCI;Z>e2XwxR`tTs@|LnILr{w7|c!z z%j=TeX0etcpgKZ_1#>d2%Jk=nOfFgZY*w2{`k>aDYNGof>cPaEAngY3&9X z6PkW1Ay-)%_xRX8m`jD}y^>P<9J`FtG8J61HKf_dSHaCx$n5h(125D$7F=I6W%?|q zdSnZdi>z`>GrMZKtE$^dsH-uPnsxfM)cv*0{k5EaH6spHEC;w?K|KmJaqaCFap-Z= zTQ6nLWT{6DaWz*I=rJwD9-Hc!QPKR_`)2GYV$xlqu}~vTv?r5sUT5Q7F4W4Gb|>0W zRnwi$8BU1D^l*n7wKQ!ul1DpvEt-1>j-M(nG2f{DNnxsUAAZJUz(T$xL*QlUUYet> znpT^+YiS)jsKH!GoO*UnS6UW7Ob=;jdO~jhhkIb+!FZUKkG>ucicCFpH+My85Ka4- zI%pEi(n%?7#+20arTdGU3jGftKS zACQ*|>&@m^wj^Pcr`)NEKKQ2vUQJlAMI#Ux|u=;Cys~d|{JD{Fl8rco8 z4-V>m?Lc5gz}o(hR+#TC>FA>E)_HD5d8(FMOlmsy^wQv)W-hMcrL!&$_Hx@_QLsPh zDF$STw-`mk(!IZ8DSd2RGTq+AfHT?F9n8j9d(>k-L$h(t*%wSMF;X{uUO&6q9t^6# zT<$l01DQSOWemsd(yBq3sT&?YlvM!=iK#zp^6D{ooyb`xs%Z#xf%{Fw5J#;BWL!w= zXoAHIT1a_KgR^fbSjEFy{$M)v7uGZijQ01%D5%NZ_P_>J;GEPlDdqDJAq`D18oJ!6 zP9eqWn(EXp#Ljsg zwe0kp+iAZuxfZI~v}u6kKLPE*#jt-7}(*&ORkx20&OncDZ~G-_FCm{iOYfthx?W~HXs^ovu;re1YG zDc;VB5m)v zo_my~BzUaiYMPH+&{j=H<zu-Q3ZXcsK* znhQl4S0Ko-Q+C_7Zb3!Cqnq5W$TPP<|eE3^! zgm$;CDo?3o^kZ0E^=X7+I8UHa)ImKvwVSRi(90*>(TG&4Q}E46`E`d z+v5N*Y&x8lOr$IpkDE;Mzio7qUDx42T&br*kN4QVF0G%J=%y(zr+!H#aFeQRPd;I6 z37qOuG99Ob?^IG^wb6358M%>KUd>E>!01#q$rIsu5G@t~-fm?JIpjPHXOY*5xX}nZ zKf}3|gM3pTr;=k&Fr6wJDH(hQyREg?y9xI@HqAXHL>LxKx0}Q#M%6L78Hw)V=x)h$ z@VvLjAJayS4!X#ots~Jb$I;+qRE+oYrAyn%<5$tIYCowg8}nC$VzJUW)DMf*nF*Rf zD|EdNcY+48blu5k&%_`;RYn!jaoPh^*qwHs&)w@N7tqu}=IE`+Y>ukg)D(1L6A_+? zC5e=$$b0t=6&G`TYfd)yw#1#**=b+~;hA%fBKPK{Z>H;k-%5Shm5y(qeL@sYE>c;~18(EJT-AJJzFq3vgj6cAfYSmi zRqpA@>j0+K(Q3Nd9-udC@KKI+SbE zT?WIJrDAS*6L#bVogdjGP?PC1Q4EK2Z;a#IoU^P$9F*(!hB89k-A=)BdMe)2rJlZ# z_baTy-ZQD#Khh4#^Jtmh`*V#qLo}&lf?*oI!cn zgl4)?BUW3XI;UOTweGp?Y_frFH{n|XSc7{o)jTK*_MBBRwT5LlqhM%>2+^2L3_>2u zY`L?6IC!u+)Owq6XbddEQGLe-CzU$G4PL+`ljYfLQo!%ISZf?04SPds%S%cGZZpK+6n^n$Pp6w^=?Ax*}xtHOA@C>v+z*m(7ZVd?C zrEK?AAsVtuExT3yB$!U-!1V>;Ro*5Yo>UfTT7*&;>u_AGW!!|5-}OZ14GTV(wQEt<)DnO`!W#6P-=1 zvK>U9oft6U0O*7CXP z*F`ZzzvXJBOz9K;h%JG_rNx_OZBd3K3J*c*XZ9iJL<;Plp+XcMM6`4Qoz+7;sK0ck zx|XMQdS9*DE~Td%gM#Hf>aJ3B8X-axsg2m9JEm0GOe(FPOMX6cXyZ7wC-F5swgB~A zT_L%nHUNg^kMoQrf3(7o{ORZNFC1-pt{c;rgL(WurkVcUnnTX_l0!O!f~o3=m1EL} zi~UAA@&vS=@3`i$xLBXGW~TKCcH&N0p^>#d z2fobo=$%xIw}dJRNRPcoH`&!M~SoxXmi3#z2O@Lgb`yoO9j(ZMS8N&T6^E#Tm9 z<)Z~*K6*wc95UV)7^~qce9Kcwbxw`81*;uf$*P8UtTfFRjn?O zj(iz3U20v|+Zn4ZbrxwnmoM^sk#nW2zFbpXdDxY58@m2N;4(A#RP@a?SPBpC2;_^! zeYuCZOgR+)^o><@=)8tH zHRhkX2~**7tU35#ijtaaB}4Ob1*Y2a>SQ?2MwzL_Y;Ie0(%0Ndm>+{wo*9GkqSJM+ zIYv-CZoX0*^m*oct!0u*29;ow!dX6~k}$`IAdRvMMdA`xzExZ5*zTLzw#KxdEj=LgwH<`!7`m79Ic8JZ88Z`%fZI&05HNMP1+7}OJd=IJZZ>~zrnl;=e2FWJvoO=;kj>*OXGpNW2qDAUSvz2j)qJ1 zyQ$TgpDRr#QSTLOBBQgtT$h))oV73gjt6f=4#YjA4hNeOYI40P;SL(Izc&{%%5R2r zr!&b&&nTlz7G*Khe2@_ol)?)5RTy+_#KSzk;XOgm1KxA&J#p}}nBX}c`78 z6l)b2NJjFj1cG%W=h0hn*oL^=?V-5M;P=tewU+M5&HY@(Vbt5+WOJr(=*J(1deuSm*zPZdr7OGA?nW5Mm_ z%SKL8YzOj?q|qql5uMfJ7mB2uxkD}x{%vQzDQe%Ixmc`;EY0hmA=?C{JO8{i zF~k?_x*-i&WT3PSab(C@sEQqL=yvbNR3(QSBYH1$I@PtHDnD2Gs-1x3;MrSIJ41&6 zX&59k@k1O>Nl~s2nJQXv^Ik~(p}G-^xpQi)vtOr>y<+qW)Yj07&%8vcxvDO38D>x= z-=Rjg-h{2r@fk~JdCqBdqUE$yqu)laUyrFyW#%Du)LoOYac&bu_iekI66HO(k+ND6 zpe}cym^R=`_=c~_D z1&Dc)GB&BIn0!=!Z$9%0EcF+C6uU3_a3_$LYAQwhOC{*0^s@?)sfR)nc&3Nq(Wr`< ze^x$|ChCENYRWi~pGl$BG;F23r7J^M49%mS3AD^haYct);VftWxgqynNJtYS6B9kj zct@g>UZc%#dKq}pEDNo`w8ZFjPE>)3c`I0GJ`C$b@kH-@SSzBCX=mY_L_2ljc+JSASRHJr%m2%nRa5R+uu(a)G~dxI+dcC63ND!|Tk4T93r$143gqfnuUTAb z;YtT=DWohfem6Vw+I-b7zn@$k!5I3W^>%LV1mu4SO0Peufnf$G5?o!Oc>7mU)qFNJ z>b&NXizAt?JqffRL-vX~T!^Vq3o+Egp*;hhMHnz7bd@3>t7aT5ti#}|JXH_Yd6g$M zxI?#8Lvwxcrq*QBT)OSAlO|G~OWKDpMBLxwrg2AGo|aVYNviIG56Mb;gA282(X!?? zzCfFuSKj)h_63t~pm!(KHK?Pq z>{*6-skWk7uk$M#`t%B|Ui?cX)2*qldD(Ulvv-@=z0KI2%U&hF@+CJ%?Dpt9i<%+R z8@x5Qt%=?sly2>6wsw3&cHodj{dTLfk7BUH*q^P^7wcC}_hER%<8SBuJBEVx!logb zZ{@{j8p^rvxFL6x9+&J)H1d06=Tz<0lOm@}gFjkXuAQ>ub_>TRq?(Cda6>sbzWx0;i#`-u`=3j+ee(c!6w)qA}4P4f-l18WZF7)!u0Ik>!x&HQvR9A+&vx-FEsa#P&(? z`WcSx#gyI3zt9HeW;1_JyA9gg`RFSRon`-vFE$yLS7>*RS^Z&u5UhP+6VUzbSqL4_ z=B_AgFqXZo=x&M3740SvC+51LogG023 z?0+sBWP&c-SA+MDM&S>ix8 zn$pep2e9vNaK$^PeSfCw@IP1bX(f?gsc}F& zooI={tBguY?FaSg>|$yTU0v%d|DKME-k2bb@nF@tP2ONNg;(`_xw#2HsKn**ZhZOhnz1k@rfv%*1hMJ44G(G($T>zN(pH3zvD! z!1YoM8)tUabkiH+OK9R_CQa?qug-hp)vskPb>17F-9Td*u(bcmu?!fQRq0+9?8M?Z zzzy`Yfj19(_@z}Hpb`C-3Tdmj1T*$*P%O1`3tO&H?6Uw1TeLOr^Pd zQN?|;&V+v9i|Td{w!*e%BGeS-B6&` zMG~}ysZni{(hGLWYUFq)CLdPs?&1ifc>NjHF4%Zphx&O-NmF~(G(J&C%c8U(OYcIZ z#(Q!@Q+p*XQK?tTHCI?>d` zZ$0KMhU0jD87ZC96^qq1#ChqXVNi!E25~CNDLCP#;{N(vk01@^oQEU|uaqpKC7Sn0 zH??>1t5dNgQ@K_<^8Z`wDc>2Sw+DD5*1zw8nIG@sT|Z~U26X}?MzaN!=FV<-s#!me z5lu2%H8lI!>7A+ZR9j1Hnx^io`@DxHXxghnd#C373?Y*fcK5dXFCC(dP>$akie2@b z+|Dk7jN8E}D?GPO$)!|I;rHybSNjI()IF8d!ELnXEA_1<0CrRjV52=>Ye08(>3d{` zc&9zZgWG$Pd+wnN)fLDxCIj7R?~iKETkX}p!jLPODAkJe28MVWb#oGQ>nTr>Mfe&lVsl{ z`{2RvAEcdZ^x@l)CODg;vZ-^yop>3l-E^*Z>}Ne5B3SXb$_zd}p>Ie4PyRFP@^w0g zL%-3ylCC_B_t4g1XU&q5e8~2+yO&sUV8=3(9%^Y2dDrLQOPktBO`hHfMz^)JOIvTNrqd3pMJXn8ynDO( z9#Y!RO-2Ns&4*pQML$MYJn@k}XL~p8+??QCe@5*b_XMC$44HR!_jr>X>hOn3j=Z~= zJhbdVmqvNx-;u045(8`8;YJ8|o+FF*8mXNM=HZ++4)=ct#5kvb>US{JPU&wuZ~q!q zGeRlk_A{+pD|rufcoOqHAzAh@2c%t}xd<(Yc7+)lx$H`yfB#I#i%+HV>%V{vTBvB8o&RHqpnM=LGQdKv7DXtCrS9`d3!RL|GVh`Q% z+0)yeruQ69)7Jtxr%Y;Sf}d{hte=)?k!LW8nx};mGq;w<`$l{-qn24&9&!4=>Thz? ze+fMFk!jpWr@cCR+uLRJu!`*}kDt$F7>d^BExlSuzNcIpgxotWhw zG3QieTTgeFJ_O7~!!t=z-9eL(A)RD@KhigKOJhH2sp#RN_|zmFb93I+(NQFC-7>AT z@3O6!nrDLNeHIlBVp>!-iv;627_D4DS}BS&{x5fiGl70RzvU+|)aWl2r}475bI@B2Ms<^)GREG;Y;IvlsKjp3po|*8|P+k zI+a{e%uT&n)=+*fFOg7_d-{$9`zs4L!G?O3z@6EpiF8%WmWs!5XIAOb65aX^&3vV* zM3kdW9u02*CSs~xS+^W`}CgtIr%adc0Jx-~{!y4sLRw55A| zhnu{I`}$($5n48xKC`@~tE;6wS=pWHN_WwXh!t|4P94B3nz$gHoY>2E_rz-XRixC{ zl^YV4>QFh;ZP|4BvblhPvbDsFpw)&1r?2N8XY6l$Pq$GHYDXBqyMXr<$QDi-ZP0BZ z#wNOVlI}F7rCfR^T@CdyYiRcYzl_5f?oEdt(g60*cyDCjk*OJO@-kTqzXLbZK(rzt z&Rd3*X_Td;$JUE|Ca72l9$K%IBB9ocl51CH0?p?q~RWL)L? zg@KK$2KhXA5wnNO=b#1}HBjx`77L|t$i@UR{!j(0pK)ril~T^%wHx-e1+QQ6Wo=NI ztu3HJBppp$)f%wA(92k`$`4s$yWL1V2TM~a?maka8GR}A^5}wXrwi+B9SG^@scdBr z?tG^vZ-%V*$4m7wS{s*p&?d*-tJw3@{gX{rS0rOQ@avA5X`RH2laaff##m* ztX#0Y7etdtQO_h)c0MYDLeiGWb=seFI*5aK*7Yws?N!Z>mhYDAq+VB(biMec@pM^C zE%%_DzLHwEOT|1#7JP4R@LjTyYd>rzx{U$!6gXkSb@`cfqIZpuGT#OwT1wCkEab~P2Hxy! zGvnCACz)Nyd5au(o}Dd2+%GN?r{{}o9^=#9?QEM<5yGBGRz)^g;v5$kQfjlRWOje1 zU8}BO)BPj2XjBi~s;L)WTxPseL)SjZRM#Zhc2=LJb)gQvT8Hj*XzMC2k}qm{)7`yk z{dL|O8R(1m+j9=4rsKukhSb-d400A!H!bz)trls3Aigbv%(sSSFu+S)#~G~#PK|K~EdVoDodDBKgP9oLfT zZc>+K*H)-sySi)DPBU*m>VGZ;%JpS~JXK1SIc%g>q3`YInh>b(QTF=Ijs8>h%PKP~ zQSTu2uHS{cmXv!f-jpAjfMhXyse~1}t$b+W6)mdk?bI2Mf_{t*xh34T*RU zfUKMkUbCFo9!#v&Yuvf52{>0@YqJcT#c+$Qtv9p`7&*Z1%rap4VEZG>Kooo(3U9;e zE6`M(^`X80){71MuMhwIaU5WE`tOhUU~A)le+qq$)$N@=e6MdsE4HUt22O zn`n0$zp!pvw4^@W+h`8|a(%P(8-0?+Aw5VshDQBdK18hbDDM=u%*|b4|6-JNc_~_^ z7RM*Fx6zbtb6sK{-Ne+_1`WC=1n%NEoo$LpNEp#^vV>LD=~=;&?m@I{QWsrIl;k6{ zyZ0vP&0H8%{hq$@RK8rXK9Z<-zu_MkVtclXvDK)Ln$#6k!wedd~)W)rR9BX~CCYGM{K{>x=R|Ks{}A z9VxvHQN7;XxmuP5>-lixjATcAPG?nrJFgwLVaA&?Y3+vEDdj6^n@Ku3pKgJ4W@o%p zV$ODL&pSMv*wEto&wHb9NK(;G@V*X9S`CrkTxKrc2rXlo8Y@me|DuTu+u)jwjC#Xf zT9QdGys5}L#TyMNVZI!*z5OjLykhMgoENTesJb)2!u3AILo@NI(yc!86trVaSZ~vL zgC$r?IoaMubC45w0+JR-x@m71Es}5#uHTgON7&cnl1$GwbJPweTLSZ!*xSnP)fu6M z%&#Uaqfv%CcKyk4kFP%&?g~Q6=e;MB>295&a3{8`a$>nB6;Zdf;n#JCHZ@M2$-|I~ z>z}p6+h*G>&-g}KI@iLq`y{g%lj%z188PXt$4&tX88O*6{fX1@sDlAmeQpCVF)nlf zCSTeHVEwp*Ol^i*zR^eOu#G^MkoN(YIP-vFsHC25n?HiS1*g!;ZSA%Nl!e?G#u{lu zS!G*SkGc?|lvfU%-AVE0p00SST96DAa>h(*8iLM{&2LMykav8NqkFD&mKbWfoil}l zQ&u*ixtTS2R-yw24#~>vfEEs8GpFy--WMYm=BxqHZo;4G()jim%`4D}96AD{_lo}(Au}bUx%3j^R_WkFq&=MW=$=<^nvWZVcVIW6tqfxrfS0B_(IzcJ+s6r?^?BGxXfO8zV~E}NDNH^E;GHt zXer;p)TK@>_+S5NDuU0&NGAP^Lx`-*#^C~uOft8XC`@CE?1gENk-adDHnJBcn?svq zUn}pkJl99a{#+lSSY&u48@G-Xw=Xt0r|z^RmHH?lG!KEpgt`mvZ3aBGUM&$AFT$HP zqB%4#L*py*F!w3vhP(z!J51_@2;@sZ&*i{NfxiZPJ>VY!Umy4yD{!owc%lAc;N>8{3-EP-*I4*In)~B*I>=+V zcLA>i{ht9x`Hfhywjbqp2EGK+c{1>wNxzhnUf{bxxW@tC75F)t^A9Zl*Mt0ckiXj^ zzXas5yuAYaVX*%_;7qq&GfTMgNa7?$|HRtqaT@tT7LH^@aT>cx7|0nQf;HYP==IpmW0r?)#|1aPq zratWc*w4#nOZ^M$9tG)ejOJ|r*1*rO@CP(!J==gh+s7Z)LpZV%|3RM$=Z8w0F(AL2 z<|3cgf7gKgFF`&5da7iELGl8$I^)RmkzM+M$Z{eF* z_;3qHJ26}=pL>HnQ?wo~=lcNP$fAD>3*XejrCj;bAy@fa({mKqlYn?(xcdXQl~1gv zSgxA2eoi+mpIyMQd`f=#<+lNO)H7CdPB$_$ansd1GfWHYG+o_+R-%H{qeO6%u z>BD*!fSyf(W4y-bewshrO5hl7EpYU23E(K-4jjwFLBLV|Xy7P6TE)tV*TE34H8khw z9ZFpKhr@s$2J!`(b9}MivN^~f3G!n={wUzhAdh}V{4?8w{Cbe*zLS*O`+y$<{6*jk zfqww}Sm2vOdDsj1RNyFo2ym3gaoKU8XR(&&bi;Ib9`s;*U$gMxx*YNkQg6y_4{)@n zOvjhQ#d14YbI~K|RSojkpKJm7BOqRffIRvi>{np8Nc+foFyAi$Jy?Ht0{_5cMu`{B zJ52=sTadpI_zA$ffuEx}+k^Ra6>zMl_X9^e-vj-m-i%wn0(tZ^D{{iqhkqOd_N=41 z-=58Yqdg-*59aT77T#vz-4=eW=6-wbweaVFqn&>Rj_Le0aFkyi+IN)S066-|Qk9xc zdfo%+iS7RV#Mjhv=qDcl`2zht#~0iEZ8c|e?*#c-z#js>Ht*C*TD-T)+Jz!Jel;9`!s!T+*iqZ6&{sisJHT`FRooIi9h0A;n+w*6z=L(R= z_}-*Br*jd==Q_`@E9gf%r61xiZ?{_H@3C+h_pu%_Gm_TzK52hxWe(^2~45_G3S%6ViDc#24c= z-op0;j^X~s$KTN5%6OLl{0oGO!jA>cc5bHo$2d-BzPIM* zf;{TK*utL&J_q9U1@ONC|50-;&$jxA>45z-vBjr%i+223x(&;=B$|vgI&cg4t@P{oN=gl~O#h!OSp1IVEU+QwoKhPd&H~d`Y zRs4Jcqyy@~aS+R~fJMu>SQy&%VI1f7JvW^KpL*$NtqY(0@6|V|#rYaNPH@ zSaZK0!}K2x`q7_YKMKbM8-x5v2p4$`aEvduN64|gzA*MA;WDoVj^%tNa7>?C;HaPX(uAc$orTu}7kfBf4I!NE+ynSl+J2Uw z1zg%e=6eC(UCXncy@59Zp9;J~bJm0XB8=}oAdl(4FL0FK4>s=XDV9_t_8s}pd z$QOVf97jmKWBG27M?a5#rWW)dmvID_hXX*5lpp3P;8-5gz%iXsKlV%KfqW9|nGgH` z;C;Y{21U3z!w6K13wmcC-CEd z9|0WO5vh0ne8Kh+*I#hH`gqVk3iO{uT>8%#uaiL@?Y|H5QT&GAo{d5Osh|hf(@z0D z0pw2uj{YCp!B&tz9pn!Neg<$!H!fFa0>2RCQ9t^Dvp^pG+u6V|ojHuNwBCBqkK8Z+ znwGFf z{{S5OKUV-pd#(h&8R)_G4(t0>Adl&PHSjG!4^@lE=3EizgYDflAityYwVDsS7C5#e z*8xYreLe8QK@ZxGzCdFda&Hy1{~{Y0yvh#JAjWSJNU!);Jh4`=es~&`r&Nu-N5%?CG=r_4{-GJkHsGe)+eBud{*^ zKmMBI+pOcek&j=b`7eQE`JV|K_j@#I&W~ffdVpiRjsZQW|9s%6|3=`Lo_B+OY>%*A z!0|Zxc^n^YhwR}$N#DMqrfrWpSJK1 zf#bM!WvF)r6tK*1YzQ3vQWQAq*$p_3-(`KD%NyFcFUTX8^?jB{{bztY+IbW34Isas z1dj6n=x5Nceh>0kzcz+?gym-p@QoncO5j*N_Xdvs7Wbu}2I+qy$fLi#5;*$XJAk9V zeH1wQ+t-0_2=;#p9R2VLQ14y?`Hg|!4ECenz;qZ7@*_Zgx~2Zg`ZJsL3kbIx^kDwt zxeu(5$ALWBbD@P_ZLtUEC0-|cr2m8ckhg%3hI*H;e#qO94h332y9MkIqdo6sVGoWI zZT+9WWD#y5#P`o2zb){;fjvh6|2xQ^3H$@#IM0Ul_g;|4`itX1%=cG89{tbT7XB4* zDz=gDwIBZ8$GOkPpS8fBV7)5<{vpH*$B&rK)gX`g{u|)`06ndmvw2wl*H>0K{U|o^ zjny20?IXr(v`@aj^;~REasCkJEk6c3$AbQU0^bGrk-%pFKLYr^z<&pPF7U&F9}WBy z;5d)*FW@nd{}lM1z&`_?1dj2-a{f8Up9k_^0LS#S^-sP6`CR)aV<6mbLC*x>X9CA` z{suVC_kIoh7|?_BjX0kA4&+CJ{J(*Z1diu|aU6%d3gm04KudoH!~GugBmWUN&Nu!9 z9OajzJrQC0m$&d0EPN#kUm5rg5U*8%WBpwXING^7aGa;bc{W_9!~PYPhczsEegPcI z)mp%-wf*du)&{;8#0%wHEc_7QRgf=d07pGn07pCTwD3)V`UV}-W?JV|S zeL;J+2YGBquwR7oV?Z9;_g?~^2j5V}TzA@!lKCFpMlJ{9;} z;7QK>iBI$CE)G+uyT+WBYpva9jJ^2ln82uo&v^ zT(D;k;0FSq1^hDLdjh`?IL;d{v2f|PaQc&)$Qk?(ecp9`sC7n0Pins0a?TelzaKG~ zU)lsX_uYh#0FL%-W8pJ_<9gP9z-NPgxsR9asRw=<$bSR;TFtpU%!hojozr{_^q~EC z?=IRY>vXIi*YV~46G`W-sLb(4_Cc}y>0oC$3(|*w;5t6;Yr^&GSz2Dj3-rtZJ$Qcb zK;W33CjrOwlykJKAItgm5H8xY7&xw{%l-lW8tr)xeRcFDBLym z-=l%=NL=bQmbd%B?_v38dqloK>tR2J{acLJ@4+5Sw;doIFkTmeyy)k6m4Q6QYjxrh zuR?7P`?2LAUT8mun~VJygFR^f!(b2EzXUkiUkn_};hMm)9996Y)bZkU7zZ5F`41L5 zF9D8rUJ4xTybL(nc{y;j^9taYFSzb6dN^PHLiS7gOT3uldN=yve}FvZBgaehY(>xW zhxJ?q9Mk7&uoLrj&T%uiL?%@t|Msu4jby-vRPy|0kdy?f)0> z0?_{{aJ2t(;AsCBz|sCMfuo&wf}I#H<|BrS9K%J9;UdRy?}BhKeO>`OF@0VIj(YC4 z=y?I;QO}FOQO~^=J@)}eJ@*60bbA0errToRm~IaOM|&Ouj_Jeq2g(QSc>*}GK@OWBOou$VSie7Cl%#v(fW{ zMGv+|+30!Eq6gbe)MLx{mq1T8`HuO8`HuO5`TjEK$9#VUIOhASz%k!n1D;L1{tWWj z#4FeGjO7#Kh2JcgSuzx{X6kL5gH_1BgTA3(U64mSA@E%LT<@(+;5a)Rx0HsO8*dbZXN@VM_R z>W9d95cd_I2Ye5ZzXo_a@J~s<=)rxw7lHhFAioIsEx>Vp`)&)zdATz|56-`x3p@#W zt_FS>@Xx^h^MPLo^0x!O0eG(K9krn63kX;019>i0H%h1V+za>}V9)P>p9cI) z;I{+64)|@r@%}?zbCdkV_laP7egk^G2Rnbk2}2+Lf$53o!Z1Cjg8U^AZZq(kf%gHw z75MSM@qFufz_Hw3tvT1DAHe=QK_2atb73t1Bgo^qFx3Aqi+(&8hWh0^sb7EL3KSrH zm={5Oah-y2WG8(-Wm^`e4+qa&&fOF-q>pf3cm7aP&VI z?g1dr{7W6~aln6qa&kFvJfFB2IF|FRfwO+;L*x1v+Vd-)yrhGyPx;fK4di+9OY$At z>ldLsoC)%HUh)p$c>eJv;25vZfMfcs3H}7rXEboMryMxigMJe2=>d7P2h$n*E!h8A zLbA{|EamSii7;k^ns`LAdjQ zuMGTT;Hv& z57w7)ATRw=_LF#DO*QD}KAQM}Ujsh^`2N6g-d=*!}%j15YIqF-deaHPgDa~0P#~qTt%yIvW)Gy|^5A6(#p38xw zo@;=kp4)(9|7V!yoSs`ix{U&U3gmAo@UwwW27WPc-0z3uDct{g0?4EOHKDv=Is651 z>=$7^Vz{I}va`;|dTl4CGv;F_*pK=6Tad?mJOMbS|2d!s{q{u`{s?f~Z}t}Ok0E`& z0sa|qyiWuD1Mc5L|A6PdQO`cmzHbZqvE3gD`~)q}>A4o<%S)gK(-ZgC;kf1pkViY$ zJ@?3eb7IkwkRS(rY|vAs?z>hN_S zzpy=R1pOz0Jlc7#=3LIv&j0ssKdI0E`!^>Y{@=ej>G1#l%}IxB{M)+VmnMM!DF(kZ z7x*5)4+K67_+`NV|D1y3|LY-r{{NhUQ$GLO&nf6)uJ)PO)*siS`sM#{ch)Aqevb0P za+Kd7NBIqNl;0>v`QbUrZ)}mbt>JdRIuoqxL={6?!b zl>3=D|9KE_od3lBB+h?c3Gz4&y}`n9KIcrZ2j@R+>%W(QJobBW{_}JQ7w11^zJlY6 z^Pe|?JlcP!g=?I#o^Ap8m5uzC7J0VyKpIowhs#xz(m_52`WKefLrq1-14s3sp z)Qo=|27Dy&i-C^hF5 zRV&EL+8^_Uz@rTGN5=d7wXCV}S2C_=E^ANBp9DQJ_r?5U;Ig*Jd`%eV%Gi*(yl0#r zlQlc$r64b3TjmYGrHn971D82c=4Sxkk%9i)3VbJl^z%jFI|Kg`xU3EF*TZ<=OCPph z*4p^*QsCnm=uZRi2?FV78u&!uzXd)C_&LBQ1HTh^4EU?SrvU#J_-?=pbQ$J&O$9z4 zxXd~8*Rz3(?`7TwT;?{J9|>IM*qO6W<`0J}Yqk9M65ul#=+FDWYXs8I6}6vZJ+jA! zza9nL_!8oif!DF1{xk!ZIavPcNZ<`3Og}FJz6bCn!1o0HKJZz<`7T8Mu>E_f-<*He z)J~cC-oVEIm$eE0x(xWfAm0G|H^9@t_XBg&}VA-2B<4KHx_Jmo;(z z`ZD12L4FDF1;F12E@OQDdc`#yA+}%o0!&5$mp&fz$-rf;gn27)S@UAP5cr`C^yezz zhY6&gHvvB!_^ZHw2mD*$M*ttbrt=5K>qy|0z>fmH7x1Hj&j)@C@N0zV%3@LxE8u>B_huLOP~@V$Va1bja5lYyTD{1o7K0zVb_tH4hK{w{Fo^Yho= z13v@gH(Sg3gX483@U4KK1$;d4vw_bBeh%<9;O7Eg2weKM{Pk79&j9T zUv+Kg502L&;M)Md3HVgtHv?}4ehcu0z;6Y974X}D-vs=2;LifT1Ndve?*#rO@VkHy zTgUl><9j#oQsDOhZvcKT@HFuIfS&>Ue&DwPUkv;{;12?S1NcM0{|fwJ;E{EmKR8}X zfENIN1o&j&e+1qN{88WwfjAafPVn|3E-=)=lsF;KM8yr;7e--#!z`q6lHt^xYoIlu>cYs#{=kJcwc1{4!cIsjrnGO71 z&~q4Y)-#R&q0ePLF7IK#9ysgYTuD<|0?sPttl)g{sgEzweAoug_bmIK^Q-!|6gYoZ zsK-$|1LttJ*U!ub&hm2a{b4>nM~`PN_Ho{8!k?>wv;Jv{(%DJif6g}^@qeiiV40DlblN5DS-{xR@XH*)@9`~L}i8{nS+ zp9=h6z*~WT3Vb2(&w!r_oYP;%REvOr4)V_e{{r}Hz*$eb{_acQUxNIw;m#i%->-mg z4xIIL>+dRoe+}{zfU|sBf4492Z$SQF;NJqj82ER<7X$w{@OOa!2Y6&-=MRq8_rO;J z&UVh%-)#f@2at~fXZbVqch$gu1o=IHv-~;wyKdk=f&3}JBie`Y*NcG5U1ZGf0?zs` zU`U@=fy+DAnZFC1<*#SRpG}+}oIWc+xT^tYdFfk>0lp&0R|A)KqOs<7;IdbN`3b;R z0X^3Nm%CnB{z>4gf&9n7R|ozTaJK(BRzja)n>s%^zH5MdDR9{<&XPL=XFbwZ?F;-D zpyy!V^3D;~b20F>L4GlCIs3!%?*LyHpcbd4j{h>_*mf20xtsoDR6lw8tY%Dfd6&uF9!Ld0)^H5X9@6H;BtnJCA)!_f&3}J z<;)1nF9I%mN}1mUobyZS%&WjFLI1bF#{pk%1U*b2t}m=-ivF$u_^&{ITi`5Tr@yNP zz9Y!D1K$bw3BY#-ejV^#fIkU*SKuE59}j%ZLNbm%9Ipw$HvrD|pRB(t1wIkvYk^M& z-VI#NLUMSg0GG66z6iLyQ;+$xz^8)#Z-G|<-)tm5<-}_m@U4JzyspvTO$I(4 z_+!9l0sp`9&IP`T>e~PDS!z*H(Z+YG)JBV#6JEh*fCLkH#Uv^!^&}(*5(!C64j6o* zMN3<%*rG+H7A;z|sHswo*4k82(Ne{V79ZDgz0^{rmRf4LUT^Pz?b&P2S+nQ2GqWL4 z+W&k$y-+b3z`~8@i%_7{tS4-K`@5}11_W$|f{CpAa@9|dWm5J~R#rX{)e5wdv zAj183fvM}P5aIqaT~+uR5uOy+*&@PgM0o$>luFxQE5Zvz_%sn-A;RlKc&iAn7vYOU zcuItKityT!g1Z_!T02u?W9Xgs&3eSBdcTBK&F*zD-eWpC`iSi|}P4{5lc7T7+LO!Z(TVZ;0?cc|vA)GIxOp zA0)!RDZ)!c__suOy$Jud2%j&)7mD!ZBK$id{C*Lx+Ltc=ZLJ8uL7cxug!^r*@_hfn z>aVVU7K!r*i}0I7_yiIDT@l_S!oMfN7mD!3B7CI?zgdK@72&st@K;5+itk4LZL0|X zzBqrtiC(n4c5R6WFA(9kitq{%ewzqy72&sw@I@kgsR-{B;Xe@J>qPh+B7Ca||DgyU zFeGdLG7(-N!tWH}6(amD5q`c1SAN^XzjcW4ABppqi16hiyi0`NEy6d6@Own~o+oAP z|FH-kB*IsS@DdSzuL!Rf;eH=VU3tC;|A{z%xd>k=!dHv%`$hOB5&nP(-?JcV|AQiY zkO=P-;Uyycry{&wgg+$0=Zo-%Mfh?NzDk6z7U4e=;hRMGBO-jyMArUCMfe~Q?$;UW z%n}j)m^i;)gg-9A=Zo;4i}2+l{0R}hT7>^Xgl`hzPm1t83$ynBQiKl@;oTyq!ut=++W(vgA1uPxi0}y_{CN@HB*I@1 z;R{9huSNJu5x!Q0uNC3H5#g_ja8*BS=ij!8@E67T1BYef^^yo5Cc@W=@M;nMvItL$ z@ZXB?D@C}nXP|0u=~yPhUlHebi}3X#e4_||RfPKwE>V|#O@!wS_b^_2@jDS-EW$U4 z@EQ^Rx(J^q!ru_#%S8B_BD`CKza_#qitzss;r@eBl>Kju@VpUO`+qOOj~C&}pQp1w z%S5=}mZ~c>i17au*I6LK-x1*}MEHM+@HHabZ*$c3H;eE;i1Yi8RKMze$h#uEK!pEM zgjb00%_6*2g#Sr|FB0K@7U7*D`~wlbPK0k2;af%cUq$$UqOASfM0kM+|GNmU5aB9G z5_@ZXs|ZhUTB%`);EB7CGcze0o; ziSYA9xXN#1__q!bK1!UwM1-Fr!n;Jce=oDLXM+eoL!7@|gpU^CxhE@?&R4!I>i@zX(^? z8MKEArFl*fK3iO8s|fe+{a5D?I9>hKez;VeUm(I&aOOUdA?CXoL zTU)BBc1Swak^qx20-lC5oz2>FSnrZPS>!=~VlK##xQ&(#FON zYf`MM6eh;DG`G*5m8vgoPB*rtCZ^ikYiFcN$>xkBRD5GyY;0j^#iXi4GBN6cR9nl~ zme#q#-qMIG7Bx1fQ*F()O{1z?%A3KJ<{;#G*7Fl^oqXH>nb8RB~dnwyuu6qg>-B)cELAD5DHZj+@(6g;FH9ggqYObRqL^VA9-Qhy!8^_6~>b5bnr_C9_*8MQhVu;j+efWMzu3*WU9TT= zZ7r?v@|b@mKi6g*GyL4zrbbH=O3Nt!rqW4jw#nh86^Rk5o=r}pG~lpo<_V=w5uK=Y zqJ;>Zl_>O2OSYyxSNTSVPaT=HzoNx!VJQz(=%VhTs+*(S6H1n_mx`uQ41Bx7Nu6zQ zxW0)|Q(J2$zL?H|VOFMFpql!0t!l<6*0vTV&P=7pG&a|^%`H_GbV;ZNwVJe}7YsNW zUu0-)n=R819oy8HYEDx>OB``7MzqOt+BZ=-B{a{oW&kY zPH(E6;dO#~a(K~Ls<)d`s?T%w?9}X3b?uDkR6?SHP?q!Zc-Dy{$2B%J`N=!Ft*v&h zYRS??vt~D?8)wzFmhVVErD|ldDm|=;+T(KiT1vea`fqD(V_W%n^%Dh^mR8KFtQtcN zW*~7Bh3BVDlg6N=4(S=4fwF7o%Zz zPj$t}Y{ujfS!9Mxgf)(qgDV6rwxmu%8>_2imG#FqwU|S?U=2khY_H%Mk_44~Rjp^P zp(;8jD2lPu1%eUoA&CkL{UmCelWJ2I_dIOO<`0W7F`_CJyws;uWvF3mlDiFXG#Y6- z^7;DNnW~!ut88akVidTRnzKnJg6)2UZ|sI4_c)sw%Q>92bSYBNa?F#a zkY?Dt0-3!Obc}MAQwB1xiaZp~K#ZVPeX?cf8_KCBDCouLPOV?cd%g}%%wej6NEB40 z+NQU(&6?cWu6$RJOcePQN1CSe=*QZ+6lE>{8oINSiHLWRVRdvRSr?*{3hOQjpOP4= zD;4f2C%n0XU`r{gSiid)&=e*@jcAhE+(=eop}m{zM>g0hjH+y{qyASzOT9N9t5ega zBPpzUZmaT8I74K-)T2^$eQEqj6Vs`BH3*~LZ;~>0Lv3?&swtZUJrfc`wPj_s&Gk*G zw&;$#aeicd#0ulgY4`gwECGTg$Uu63$fcTubb!!x9|R zMcIMR2S$WWjB5dTt#bU(Z0}bOIFpyC5ofYCO_ONTX4BG055t5|q+(w(Mm&aBG|jG? zY2*oA~n#Fc`A6I&WiQy?uY z@E49I&rWAny5d=kwed{0Xg!<#qzNq`k%O@=F>G{GQ_H38qnjFOSp+1N9=?yPP|JII zVzx3>TklQJdVMi58%ue^Uee=U0p!)NG^#k;6!9(|PJWvchE1YbuF{H%@pCF@F*9&= zZnMLdjA-|ku|j3S#uzcCwr=J*t)*hM)OPBys+o;}6Rk#!Qd6yCTV^+V{e^(x;fs6I zL~1@hl;CO!H(rwWe2rKJxFov9fdXZVT}hlo*H`ruJ)GvYi-RNtDWk96L&_uy8d9pT zwzM_Xk36$2m7-oMbtKcXr)7FeAjWZ2;mF5O6&9sBT2pO}vuI|3CS7aW=Qh_Ry=i;Z zb>1;cBCZ*z|RSq#5q|rc&D8QD`or(q!~>UjHv2H)oP}DSrf6S_;xM7EDEOl%Dsa0h7VV z4pC{Ing?RR&KsHAQ_~U^)n1|dEo-d!s#RgNRl&Zr6lL=$8k*Lnl5Mk_)ta%N0!9-P z%a&0p$s6k`=}HyDboVn*Y}Ft#&=>X6zopG=&tk!bDvUok$m|(vYN2s*xS=p&gEGBQ zyMcm6L&(BpQVt?LL%}$5!lY5jhmh69tu)4x8Rc`zI=^hKIA0SnJ!dYY*kE8GePN zCQ(KvE2q)szEmnn>v?Up>6W(a8lX-)RU@fw8fyPcDaE<8v{~(o3R}3Nmun4oB+0O0 znW9;z`kLiEmqD2Jj@QuTI8<16ewB52Hra<8$xc5}5G8xN+6QQkbw3sKh`P*Hra)i% zQ-Kew3+Ktgp_x2cN2|+elr!B6c4^g!Ox9If=K^u9O7|tSwH2jopAu1#a^1!_wy?aS zVNPi&Rd!TMjISDMdQBC0Y8bOEC~qAt=ZYgdA=_gio-nPTRQ)T(6+*%6=0>Xg^>nXS z0cLta#!POhsy^yd(`#vO1Z^RqE=sE0tGFme)J{{BDp1{>=mi3-hepgv)#-}0M?`p9 z6~$vH5+l8BGut|HB>t>dp zRars#n=0ZtC9RXIDWhlF{9&_N=A_Ci1D%@C=%#eC+9^MxEu~IY4W+lkF;!ljEFG3s zOC6J`2!-mLp2kaF*GiQ*(~w|?Dh4>zF*VB0h_SV4Z>m+TVR_Cl;+h>qP|j0MnnNC% zT&;G|`aKCl;Sv0iM`5Yxe8(uBf}Usgd7QaGjZXnS#24R>r#5g&R8y2J>Lp1 zd0fQEAk|Iev)Vu|FaQSktcv<4^1)FO~)De%FZ2r*NFDI%8H8C|S zIlZ}jVjy+=>A}pXY+SI)Av=cBK8nDCvNuShb@0$2jlu%nDIHs0=oL_n_HGm@uPRAS zn3kZ*m%ap3rYb#RmbNi$1YJ68gseuw)(kVOnMA#TP;{xn$$EzJI@RG-XJ+d<`jsYF zF0E~=FOL|_mQpoYiQ5I@a>J0RLj%|KGNc*3o~}pLvTkVL^~MJh*zikFmyIwp;O#&< z_YieqYM>Gc6jw9LNm3}qC`ZD~K%G1zu5>1a1uUgb6peVZDNacv)mYWs zd41qu#?INpOsHa_*PPC_0Cz~wcjm13EK|!VJE-gIR>>Hjx znGzbg^bO9RUoo^DF8mJX!(gn;y)ojYw9t((YKA6QR8?>PEYWsS!$< ziPR;{+#a&i*BegPtF5nB-CVMx)w|`+Z&lQ!K{n&4a^-mITy_Jxo*FT8mf9rk=PaH~ zQJbXg^CzE$HQ76)0?z)doCEWv>L*(>=8hzs8j$vwb6xWSb>k;e2BR6Ew%K)Qnv0;S z*qe(ms$vzBzLL3lhWO$<*a)og^Ci%2$lJ$|EpH@0z+g_a2k%Tz>f0aP3;^+-?S z_L$};667DAVF}!zrIN&qaL-LZ#50!`fB#+1~wJJi%zDUEgFsld|*mmdf9u zdOv_Mn!-@-232gF_9Ap0dy~=A#OknibrWe1fmM74K!Abn#!~^ zec?>uesNJ51#Guo38atx-0=1a~5Hfy>MTL?qZUk;GT+LQvLhI zI4Ym@&ZIwe`Mmj<9iE7%3QSGv7?oHsaeBwp5td!Y)K}|a!yiQutr?pJhL;N57f^Q6 zm-Ltj?Mov<+1WGoL?6GS>_wobIsD*UYhbRi`O;GFFDjYDa< zW)gM#>FcoU*WuZ(Bj_vIlGkIl+!ai=czFklJgqKxkBSSfj49tGGph&Q4WZWcR&(KQ zXDT4Qbz8L>esxAYSej<@*4Xs?%BQ#(=q>tD&E+lo34@FW$j zPt2~?1S;Fms!4d!a5!2tjJHlyT9}~WUvo=ZKWHwQY5Qn(u(WiVS{l!|m8PiuZ6iBw zE3HyED~$~;QFG-E~4nRu_<0jMUqtU(Fh0{o_GI0qFCJ*%j%V`5_f)@XD0Zz8itv_^QK}&c~kmyi;sw=>% zt6G{ZzJ0d*S(R*SoY6qr*FAsuJFnHMpjY{3>W@A$fY!9>Svu1{GrpRN;QhWvaTSY( zUi%i@biQM&%~YLDOwv7XskY=aS}v{kylyUe(XzB9G4vFX-z=#asvX%YpSlF@l@BbF z_F9Z-hA}xaHCH|OPL(&1zXEQjv-BFhE^7gwtK}Ff6tui=^cHr+32J~A%OY``&4?te z63~N&X_1?@0MWztdR{kI%PC@}%TKnx-Po<-71Px*W40p;uj(;vBI_rCRMP@U1UtRcl1FtH9g4Tj}kLG29xxTog0L z-u4W=NjzidqUULiFe=roURpu&pin#;+mpKE z)zmoCyFH5Pg~9}ddf7A6?QEorm8&~rNmb!INndCrNe2H>}<;XnSL5=86B4$ z#b+X2F>YF5!iXvn+N}&{B;w4RnRk!+PI1EYnbXGDokl+ar;SNgO@L0DLw*wJJUKWc z6US3(N4YHiSx-e>yU*N18~SZ|O6~Oz=c%#Ds)^D)nY%v>cl2<_1NGM|JGT4*2fmY} z=S?F{LnSoR8FBeu7$zCj7C`+A&y-@^9A+tYhdro>{2!DKS?R6A5u54ZFnc ztUGyO{p7hxEq-d5gI21z#8h(VcHO!;(^Qwq@4^Lh+`nDsp?N*^JoQWH#Zoiq$xXp3 zStrEKZa=VXjN0kzS{7q7IkLABYnNH%k1Xj%j2(-luGegvDt2s<-)8a-u9zoA(qpIE z(rROn_iQ?PRhl`zQN8Ye-L*)1=AyG`#DjiQQyrh-HiNn*nv|xQGqnqQRFd9kLVdlG>bj;P8k2YnvGr+sVn}PX zH<3PTdV6bKQ>Ld^oh+T+>IqsWSCtukTGdkpug@!23j?Fn{4rgBdJE0hRVU4=*QS(< z$Dif~2W;c6TGG_bq;*X#>S0vUk(3X;<>r5bBBqwqc`_pyM~50D*b@qlS@5W%cQ!zj zavw_$|EQ>B7A1S}uHwL|Cs^M#>Y~0ef?n36?%Ad32>Xhl-``ZVVc>RYe|=jgPhcI^ zo9x$Xv2r0+OgiqsLaDlsh3?=D-m(|-lI|;trQYG*KQ1@xugPqI78;f8`bL# zIUc$rkaP^=f$k-P;j?PtFXiQL*}D_3AtL(%E$o9q$=Vy)7f zy$-Kest#~rl5dps*66(lr;$_q$?x7-ckrG~=q+Q0r}D^v$UGii&+H+ak5~Cz)s68p zy7EKs+|t(5qv6P=K3jwf@^8&sTWDFZVO$eH}a!e?JK2) zXw`1&^-j!UtE~lrcZZrKhpJgPbpPze z-*gW_c3#@cMP5IhUW3^(o!-g16E{BW%*_N;+$%%#9%>lHQzzw><3Gi_M$Bm()dx^3 z%ib&w-Jai0Pkp5aZ=S`Q`1H!#WSSJ98}F;mGAb?-?_ya1O%wISsM#2>Mvt2*``I5D zp!`O_$j0?pROtow}p zqSOTlj(F%21<5jcff7ITi}t`qjVZlB0jPDuChp9BS~aq7AiHReYJ^d|2xRsP5^DY3 z)fZ=}`BUpCczAXc46<0Cb&7yvMb7RsY+!s?p}W!?Z7*F#i$VY2`O%T;Fqe8wfcXex z)dcVuw0Fk&9xB|s1VswvSBE}cHp`9=nJQVt-) z4b{%q4r*!+&yyLAV6T_*50mnZ0YS6 zB4?V7v$q6MnyoTJ3Bb!1qv(;)jdah}W!}A=)orzn>GmG?9nC4tNN5pn{3P>DnIrw} zJ>HX2rgR~G6(%T4b)u>K_OR?DQKdW2`D zM^DcNOwCXaTJNc^KQeT>+JvBN&0e&CX2f@5+(6zL(MCI&TW0aAO|m9>%SwKeN+}!c zo5!kv%pSl0JcM8~6})iFPQNIvYT0nds;l6>IP)bdRAmW@dS8{*8^GvrkWL*H(htNX0`p6!-}w}TW?b_IO|&oip((7$=(&_3%psCzg{ zX|~zFlcPjE1ihEjmTIA1%9G)AcgU8wklNcudOH!lr9cn+{5%sX`6{p5FJWZzup{(D z%7`;l&D5Bxx5s-es(PIS-6tj9q^#fgS{gtZ54-msGLvmvcC2}wBn!n3RQ0Mrn_CS+ zKEnxN6meKvX6p;OTO=}1?PMP`Jm9ZNH`9ESiVqb{+smoKc@))6-oSyLB169!0|J`Y zGK-*bMlV{R-&N-4ZeUF>vg*N&Yt)X8%{=nE*Bq<*JbK;Ae@3kzLxl*;s>RBS;Uv{{ zgIjjAj1r7|4_L7(p~%Zv#tc>I)Fq#Go~8*||D`IumgYTm&}kJDbYJu&^*yZYtYB_1hok1aIVvAL+>F)3#94|D)^ZpYklVZ)@?0A)RXX=h9objKG(?E#+@Gi-DqlY z{9p4fHh=xy5_{BZ&TK~J5@eBrwyxLTuH;+q*XW-H6U?lBD%k98R~Cn(wDRsJO%w%Q z5nrp`p=Wx|Neo=zrr+_n_;y=-;HAV4-sI$8I*^%m@LIq_J7Zc&q{D()(5R+%fg93% z=k}Ct|Gsw+qS$9!mz}*M(|UDODCzm7>Dkk~yZENlt9ExrTL|hE+VjJY#h-S~=#@MPXx0V$=nxwwAH9RkXahb#}TcO>YjFg)U%r01}~>e8w@h=*+g( zx(SWb+SH3^>4B0n=y^ghbiG~<_})_edQjC@p}RTLv)jEJPvrxo^;4sVs|QFAr#ZVx z)SaZS-czIF*xggdAe-AWu`?&HfoG5kyu1P#hovp_K(&;5%<0*)Q?pambn`W)(o`ONv*zX6a+&3>pRfW## z>b^t5T#edDS&<1lqfU)|ef^Y|pcBx=Gv~o8?@WghrN9n$b!|0h&n0LV>5_`n{a5Tk zgA&_Y_3|$B^bM3%d%YFfrDAI@?Y%KlFtdDbToYPstVg)8O zGfwEO&O%?jWvr(r+4iuk(!{WFjr4FTdb)0_@EyEtVwCDYnhWswv6?%G7(wky zV|##0lC7hSkrv75Hb z_@H<4FjZ&#EN;ggNV|+5;uQhMvRb68>&dO95xsxM>kc1XU#~7IyVK#ZMIv(#UHseb z5(&C(+rPCyzj!uqcb)xK0i(gEou}eC+qx#nv{r$86GHE1-KqQ7)Z6K3!I*BcRc{&z zy(ZJ>zz!W-o33kUY@RW0c5|Itkmb&B`2}8AS?xFs^p=A+Eru+gM4JYUTP?hxz$;jH ztWWOs$OHFnWcLi>&R}m<*S*lm4&NSOG%bGqkNJ3?fIq3XpXmqn^oaW2^2aVyWhI8G zr? zLU+jVJb$1SGOF!BO&h++Ja#h}Y;XK>*BjMbltOUJMlg%*sIIqK$6n|y#N5i^7pAz4SWjNtfosKB zIw`bt6?(Fy2Tcs3Z1+?<+!G0$>qt-=HRBTaTt|Z1{~4FS=Q6XOL_RSfA$m|N%ATJps4ZnUw_eurg=LtoKui9q^@O_dT)Ks5PG+2YRH+B&N-1D zj#@X9^{IyBbhXZ#Gh{|v%k0*iojrDYBPZtoaFJpT>&KsO?v;~sH2vF?|L=d=^kqPw z=b*0u`Y$=?r?9?1e=7TrbT`_1o#si>>mvD6CL!!fc=vk z^u<75;h>+udYON}>EOSqfd4HAeFN)d{yEpd{#Kwr&q3b-?4RPGpAY!oc8LE%z+dQ~ zU&4Bse&2D>uK@g7hxo4o`e_dOZr026uXE6^0s49e{W_peIp{Zl_)mAxZvy-o4*D%X z-{7F%2J|;LO{ZX`k%J)+XU>t-+|u&^ba`b=L7wN4*Er`m-Tn2gMJz7W&U}{LB9g%A9m1p0{ton zeHYOG%t7A`^p7~`*8u&a4*GRKf2%|O-N1TT|J~-G-^6;^f4kj5za8+GI_UT00xIqQ zfrEYk>!tm7IOqof{#u9hD**Z*I`B_reXedsz5cW6lW}n7(^h{~1O1&2`X<)P`r|GK z{S~a2>Gzg{{}!-b)<17J=obP0j~wh@%6gf9mOJP>0sn3X{S$zHkAr?4>!ttx)?O2R-g`)gkTQ*FnDl=pS^je-rCv z`B8HkT&-n3ZSAirtLl*HcZh@iDzB?U#{Y{B`hIk-sUPT|SLd4gLml*aK>t$*{|yHE zhaB`pK>x6Vz69u3Ip`~Z{$~#QsX+gTgT4XiA9c{DfnLqY#m)coSTFN`Ifcd5F97^D zDid+_i-Eq~LB9;xuiBKj{1t#d$3ede=pS?Ne>c!S?x0@_^z$9;-vIR2JLoq7{Wl!+ zTUjsj-vS5ycEJCZgMQD?h3n66I_L)g{m&iJ?+B!K;O7JV6At`gK>rH|eKF8K>7btg z^uKh_PXT&Wr^YS+^+5j{2miOSUgqBe9rzu9uhvB3+CLxga~=2#0sk-u{Sv@G+(Ew# z@PFkH|CNA0)PcVW@Sk$vcLV(}2mV^1AK{?i0Q9O)6*vEE0{W*N;=dK>Pj}#d!g^VL zu5r-s$wH~W)U0o{dS;V=b+znA6DkmcK&#f#N+y}8|c63pkE90-*V7z0Qxr^{J)9yGW|Ys;BNu? ze>mv30sT!5`cFXozw4my_XS=5%J_fJK|g@?vi?jvi0{wqD*xvy3KXBluf&LB${XC$5+rj>YK>vFO{Su&G z?qL6NpufjK-wE_TcF;co^lD8pZuwoqdRc#LbnxFgz`xId{}#~y#6iCq=vO-Ew*meA z4tjs%h4kM84*Gsv@yh!5K?nUnpzn0h=K=l04*J1B|1$@D5$mP@4xu^uxcRpj@E>#F zPXPQcI`FFj|8WO?4dCZG@EZXC=MMZd;Qzuwe+A(Gr$ha*0O)_^z+VjX?>O+60sVhD z=vM;0x+g1c{_O(#R~+KMn)R~$tas3_1^QPV^y`8BzjM%U1pL<>^qW~P$FF~I@c$>k z{&yYp{q_ydAOF!oKM?5ufCy4+5Iq07N z`ppjIe+|&@?$G|P2l_o6^c#WxPY(8PVZBWM_Z;-w0KcDu{W<%E>)+2i==%fxJ`Va^ zpnu;X{)2#iUk82x>!ttqbI=z7zS>h5xBpTC^anWTD}eq$2mMr_KgdDf0Q3VL^l6|! z*g-!J=(jlJpM^kwxC4I)(Er(izZ~d~ao~3X{Z}0HPq1F*f3+tyZvI^j_{Tfw*8%+r z4*Iu%{;Ll9%|JicLBEal(tjs9=syAclN|K@_7B(JYEN+7^cx8DA2{USJl4zj|HVO{ z5BMiL*gp*DPjS!}1N+r8J>vSW4Dioz;8z2_+LIlZKNavtJLnsLevE@Y4fKC?@ZUV3 zALqbd$a{XS0KeRUzY6I8=D_a;`tc6@wLm|?LB9d$w>j9q ziS;u5|L&mQ0{9gU_HPIJN(cR(eB-0Ezsf=1pY=QqecF^Yn{W%W$LBRfV9rS~N z{yYc$Frfd)A^lGU`U@TSC9IeJpX#8m0Q`#_^iu%;9}e-a2mD$GeiPuUdvfBoUmbuy z-9bMO@Mk#a7XrR|CRbeh7X$rF2mVrEf0KiL1>nze(02lTi-W!k*#F-S{#y<7Z4Uf( z!2a0|`VBze?x5cY>`y!Bw*dYe2mLm{|JcF*{zLI)`}02z`hNUSeOdoq;b8wj)=U1C z4*DYi{}TuM^8x>V9rOi2f31W4MZo^+9P}lCukI;~TYpUe{C_&ce+tn5pM$<0=+!d~ z(4Xd@UkUU#IOw}rFV_$Ebcp|2z~9G# zzX9;~a^PiHY#zr7vo&t<)=f8TN74+8qP9rOi2|E7cfRG|Mq zhx@n7fPN1Lel^g4R&~F2L^-O}e?SIZe zy8e{$f7wCbkM*+t{Jw*JAmIPjL4O3`t7j_2jekDizv7@T0Q@^0^rr&;dIx<8;NR<@ zuK@g49rRNG|9%I3J>b9Lpl<^FpE~F}0RJrq{XD?`frEY_;Qxn%elg%b?4Vx;_-{Mt zR{;Jh2mLC*|Gk6$3BdoEgMJO*Z*Vd0 z_vDVdY=6`o2;{aG*DpT`~axq$x%2YnvkKjEMs4D?Sq=!<~;n;rDUfd90EegfeC z$w6NY_^TcCHGuz~gT4XqpK;Kq0snmm{S|<}*g?Ml=x=t=F9!DC;-Fs&_#ZmxR{;Iz z9LDdfSkE8c`dvQ<{Tjf(-NF9#K)=F4zY*w{JLtCn{oM}w?LdEzgMQD0!~19MbI=a} z`ky%Hk6^uQKUO;E2Lb*A4*CM1f6zgHDzLxPL0X~G5+s_K1|Eq(3D$s9t&^G}6 z-yHO5p#RuGKM&|X?@)g%1o}@L_)AzX^Y8yT=$8S#dYE(E^j`t=yE*7Pfqr)feHYO0 z;h^sZdi6}axba^D^m{qz*8%VB| z{S?4I$ie;^z<ff6f=f z?Z;XNet*^zGE;vZ>A)Wd_`h`E=K;NXrgGf)4+i%C%0WL2@c-zbF9!Uh9Q;=X_=h{_ zs{#LL2mMsQ|0-C2%%j|)UKLGCi-Dto^*0(n&=#J+aX9@?rD<^>G$&_@+AKrIW@4&C zwciJmn4;hv{(Fs%qyH(sK3o5${{G|0?05N%Uu&HS8cg5RHEnwHeDnVa(yA~sUO7im zARYd5;Pn4;a`OBy{5gs~m40vI0u}lCgd_Mo|HI@@qaTpIiS@h;>dU=zGykD4trq=N ztmkd$8HvfC&wA5;i&)<;qtsu_|6fhPDE*7oWECBLI;-?Q5~TkvbPkID66UM?ArHgN zIXBUd9^d$33g90N_-~OO@t3;*0b3BQWejV$dmB!O|Q$L8r$o^Kgzl`{fQZ+ z{$gNq{$R1cLrr$jA@ko?fc+{@Dw|Axn)!Sio_8(v$K;=3(O(-=Kh2_F#CooVt^8{( z`W37nkx}X|ru}!Z-b}x@S+DY@Jk0b{&s0VJdx!PD|NU#2e6^<-=|5(@s$b<{>iv5< zij5x@arzgqSmoc7=$wB1f8VadD4QVuu&?S9$4NMSH!wK|lOC1dZop3f{#6$KWz3%w z!Jlj4Z)JWB>s9=R0{%wko9Vxm`MixhV}+UilPL1Ye>tjQro+^m{_C*l2e3Y>{I`=H z`M+WxiWnV!I;;4P1o2;K;h!Fp|6>ck0q{ow{+kwl6Z3f*%8QHoWBTtO7X7s`?LV6Q zg3_;(^}{n{{l(-TMtU+K$1H#IK>SYw@h`UU-(@~;qs>@h^6M@7?W~V#zi+VU_u-89 zXoigA@4r*ZjQHm$S zN9n&2@Jj*zpUgMwpVNkDu)4N9%=qW;jq~pq)}JiJ^xd@oSkfc=2Yf--AJTti!2Zz| z{uRvUZeYd=ldsDsY%~89bNp*qujx6`*)`?InuYW-tYhV7clkzOMH}m%Ru@~2KEVKc#0T@I$@ib> zVES(z;GYfnXEWc-|NmruRQ|ulV*l=(aVJOE@86SU+Mm-uod2tV{c2ApO210xkBQ*> zdjd>;0pOnt_-alP@fR~cD*yf6qQ8&zLnG{0bBc)nHtVDM?_(|ck60hoe?Oh{DF4^6 z|78E?Lg2rvEd0T0VuX&U_E){<2gUz%*6*h;lle;~1df+1`U$K*EO2(X{@#n;vw-;1 zW7@CYlY;aetp9QZ{}j?A|91fY*8=}HS@?G_|FQ`F3=4k|^J`eI>hC(h{}%Jj`X{$g z3kMi{^Bl>h0#e)XOYlzvl~f3vQ}to&Cj{Jed&Z~z;u z{MP{ZNA9EfrvLuT9p^(cWc|hTUo-2?`G>u^;79de@381|Ssyiix|Q@O{}$}8<1g!v zCJ_HGd;$A^9P__p#Gl=n2`#ti*R$UApQ%^RiAVOA0sC8k{a0D|A29#8jHUXE$)9WC z*D#-}ac}vCfTR3( zI`gC2zjG}5ikSNETlCXd-xd*n^_&o7|9aLR5~0sM0PEjlJvT#{tB?x=$3dh=`F{h* zf8PfFKik63J6&U*575HpUp*%R@%tU5%U?I^Rr-Gi@cUB&Bmcd}{DJC6ahUP{9O)5% z4f6|FtN1qpewBs)&oi{JQn1xmlRwGA-wyaU0sf5^enqhcN9CVqE&A!K&)1j9{59=Y z_lY9^-@y7CGD`i$)E`TFzApWx~{3AwdUX=YSE&3AH9~)u+A1wL?)-R6G zZ?wd}nBy<=->o426X`w$YugfpJF|^Cvcejk1hJwSWiC(4pU!96&&*4 z7S>buB5;`cnHK#gtREUshy8!IMPG2H7EX=OFC#rFfB9bw*MIkt@n--1b2LGS;=hpj zheq&sCq3d91O86{f24(f5A%Qg-r&;(50RKV2Ut{5) zP^Q5=jLcX;mk1nBTligo|5L!Y$_i_g&^krT-qJ zNBJ)|SLc73{yzi!d<(ye`6oog|5yvZjQRAlcc}XRQNVAp@ZVv6RR8B<3%`c>-GcuZ z;NNcHx0Y+6+FvIRxVkSPBic9ypCY-ucgH~se|(xd!4Ky3`7qsIHI_pf#X{#nd7 z{Wp{OQU1HyVt*^^qx^T7#r{^dU;6K9VE+mW{}$#y$?^9;O#l7J!e7Sx4Z?rV0RCT? zZ~Cu#ycU}MA2a`*NfUG^{in13XhUGyKZf)u{W}iV>7U1XResh0`xjaG*H6&)AMQJj zKTZCxE&97yPwojErv6!r{Y#F}_EYil4rRZ3e|)BgXm*uUl&oquXruhLJwKh3m%KU&~XHktN6#r&x9 zU&?y3{6EY3sPbP-dgT9np7@jHU%h|Gw7=ED-@<%<{?B)#>A#s4{uJiR^jGiyG5L2{ z_*2i*#8-_3H~BxX@H+*qx>_E`7-~g_g|R)n`Pn8j~V|43%?V@U%mgpnr=CA=`fsI${{izy1*{FX zzdyF{2OOvKugpK{CR3CDo`s)(fd)sFzx-pc|4(N9NrwHq8UH_)^vHk3Y<~@(uj+sG z{CU&>^M4(nh0|}5h2O<|Isc%Zzh=h& zbI0QL@9YaT*v$W?|F2`c+5XkAJ}Uj6v*_DcKQ1EvPmvy_|Dvz#;VH{lul%pJq?_?S zU=YrKUCckh;G6O9PkO}Pz16(?5&Qw9S8*yf_+5a12;iqJ{4LCe>32#DOHodKLJz`G1I@0`G*H$AFe<5AwBYc z&Itsg!_TLx{!mj|CV#wzKZ*J0MDWL1__@rN?e9^5Kg+^j9y9(87JeCse;(j(xA41T z^8aSx*8sj6(wY7r_Z6J}Z!$k>|H2H5e(z~I;V63s4zv7BBR$GL9l(Cor8Dh++QJ{q z{KEqDaQ=PL!e0dVs!1^UhvZ}bjbr{X5&V=z-@tmBUI`q#2mVLvOQc8sTLJ7>L8kqk z7XJ0jH`{NM{}T(p8}J7M{x%E0llf8g|6eTp4S+uc@J~G+r{5OlN9CW9q(}bW3it(p z|EPt(cb!h?DE>nhe!s60j1F1<76Se-O5ok-JhT4Ki^)HU^eFy$fIkfI@3ZhvX8ti= zEV6&h{Fg@+6taIR>&^Ph)E`bKAp47e{Ud?>H(B@#m>*Ss7h3ogfIkZG_ZW=he-HCJ zvaa*KneqRph2Ow@U$5HlQvm;53;(Ek4UWpcXOkZJeau^@Z|e`fl2PBk7U<%1$I> z>5%>J3BdlRE&P3^d-9wp`}ZXPihnNaoAqTff6e&!BR#UegY93$N>%Z0ds|LCEZ|Fs4U-q!#c|IIm!^oXB-62a(Lp)cdze|jO{A2bZ}FK*Prk*xPW%>1(- z=@EY&^JV`18sI->;or&plYKCMn(<#{;co`~B;ZdNj^qC(^P}po@`OAr< zNBnN)%ltP3@UOM-*D!xJ+wXsv`Tt4_e*^Pn{nH5ei6R{T(`Ra8)cV1l7JUWlAM_39 zPt*RTq(}a%NQBd`3D`e?7T8ew1bQ`wxr$W7bFIpARkeF97ym3hclB6zso2v$W%)_}7pg`EMEE&jtL0 zXo3u--z4To<=_2CkN91He>vcP-NJ8TK2;Ba!z@2nS@`P!|4P9B4-0=e^A8Kq!{uj# zg})i_uLk^yr(yp;$$V;_1BV&^GSVae=L{tn9kTph1NaYE_}gN}|6U8ffcdii{5s$t za5|3vemwAs@_&EQqxhEr{&j%gYT@TIpSt&f!}R~-7X1aRj~c)H%wm5Huzvxt|Fko( z|K`Nx7m*(MuLJPE1^5qH_}^uIMZkOE@^in1zlixV|1JdlV~TP7-(miK5&Zis`mL-# z!O*L^QXY2~WB+vn|J?}e&l`>HKdePlj+8L^ZsxzkNsrQR1K{5T_}5zaBbjgd&y4>j zi@ucg)V&BCrvCS&NA_<8>Ax7*fB6{fzpI!Z)qc()J>uu7#RfWL{dEiAzi;8MV7_{0 zp*)QL=Dcg+7ct-8m!SGzO8|e_SRDUPF45Ge`tx?uqxg4>AQ&Ao{ON8M6Lj@^82ByO}TRzh!{` zXAA#Y=1+~_Z?^EaGGDGA+y(f9N^$zX&HS??_(zj|PddlX=l^P0R97j zf2W0iSX#&TIQ^0NYsP=6g}(ssI{{xk=R&oq=KNJL^P~EoFI)Is%$ND^A;90~Ow6Ck z{HXeOFVds*UkCWB0RI9D{|e?u<^OXm{LRd-;gnPP{}I5SKou17|FbdE|4h=O_?M~0 zdOBqO?*jbODT0WDlxI%NKP0`Si{3&;O$=6_pbGk;Bf1?f@z^O#@5N)`Vn0smVT{>5{(@E1B7R{nJs z{ygSyV7=mZ1OE8&IR0O`QX>z{ko6apSLCtOqCc7Shsu-byXn90lOFkRirQ>IhfKex zf&JSo{A%V?_6Qs%|1TDPEAwkut^D^4;J-To`|l3sN7di|NqQ9jbJ{rA5C{IwSTlB+fUB+ftnhha|6a~A%967ByQ7OMRB65t)3N!l;d(YE?sPX@xN~|Bq`ZM%pGJj3}(WFP|*UJ8r`DZ=w z-&PC1iut!^$oh-Pf8WAi#{5OBSLyc};IFB|@&ADN4@B^vCOwLOf!eG@hvciapdVk) zuUGG>#{8w%=o7!q=ldUK{<)L%h~Lfp8WyVfzXA9K=V1OJ+glZ+b_%CJHY-!reOQWFrTW&z+w9D0MaA=8s^LPYZKs?S@_>&e$@DT zg+;$Irv673`v<7aestt=>{a>sBe4I!E&OL=@~=4``+s9h{S~A~{?7;YzlZF%@IPjL z5y#*EFw=jVg4Dh!B{wXxUiTK^j zKRiGWk6%WR9>u>4@IM0l+b#UJm>)I&c#DO<4)C`F{+GUnR-k_!rjV_z(Jq2AktAlfTuXFJwJ+?*oVFzxPRx{I`Vdm-&AmVE;F#Vf(LVepLN4 zpY({o5%{k^;2%(j`74qW%{QUs`b_@Sm3*St?TP*wmXYJvon=C&A0Drf7 z9RH2XH}j8~{^b_^2duw1kb5*s29=PW%nGgF<+J@V{~Saon)S~|7XFk4ni6IIMJXKr z>8z*Wec&+Te?IAv{jI?MLxBBXosRikG3{Sq(LWp0{;!iB+1~~1KNQ%1)(mWa?l

IMzq?ziuKuvOi~hIR763?B8bLk7j;U`TvWBp9}a$0sf^8*nd-*e`p~0h1>r& z(xdnn0Dd0eue9*zF#q@n{*NvEGUm(n^BBPYPYZt;^B;-ezh&WfFu$Ais{b+w@Ly@f z{y+CyS{OC{c#-tT|3wpY{*&=P4)8}&1*z&3bNsWI`BC}*yB2*X>ks1i`yXcevDKnq z&HAYR=li5b@o(Vx%l7945dWiQ;`qPA{G)us`O~!jaN1{${FlQMmr>>C5Yi+2=K=dq z1opRE_=hpy?7x`yH(U5iK>j%i@PBRL7c)Pq{5)&nuVH>S`(2fv1mORI_W2_Jf5iOO zi1h0sJ@Ws8iMssM2>wvOZ*9i>=?k^6EP_9i^oYNi`Lg^D2mEyw{sYXX>CwPp_8)$2 z;pa}$@%Qal{vQeWT`f5NdwoY^PYBTUxiaWs(xdp-Fki-h6yVRJ1V-s!zj~9`XB44)-5U1N>Vo{Pi*UH(B_3fPV(y zpWKGy{{i!(^51aMqxcswU*^BjfPZ*9=9k`}6V7bE%=~`{=@EY(i2qo?|JcH>VSZHm z^>+(@3E-Ck{x@i!49b63GJkL;=j$(K{I4ZFihn2bW%)Z3@cYlk{Ck;i=6{p_InpEk zMiBpUz`w!5U(I}T{mv|ZFI)7lv3@_pf2RJ}IXM2CV(OP#^dGYRAj4rM|NEpz{@c#} zYhb;qza|0y?RP1*fA2*);$Mk~|K~}M_%&yT`=1qn-(umP$o#1MbFqcLi21VrR|)uA zE&MZM^53`cR{(xB;9p7&j7lQ2|2>WQX8mQRe;etM|GNSIT)_XWg?|v|LvLi~oD$L_`!@jl&jUv(Ld|6iCNm47FZ z9>qVeGTi=u4e(#L@b|e%8y?mFUvJ?T0e%wjPrn?;zkvD282&f&?MnaJDBu{-wphCCE)+U!oSGEH{;)B;co!^s{y}cK8}9}^N-^E=YN>_ z=M2)*Wkc(4TLJ$Xz`w!5zlHe+`e6PvB=MCgA(dNM0ye?RrGE;?lYWj>wQ z&kN1&E7<=!?7u%U|13V=|1j;}hxCYF#C%!*T@Uz87JlK)niw_ym|@{p0R95NUv1$} zV*Vk1#QD?AKl@*g{a4R=v;GSCkMziY4Z!|y1N-M%_*cc`r!D+>fd3u9|Eq<+g!xh9 zw}x+E|1D?zu@U~SBR%rp5@7!#VE<+d|2gJI)&J)$!1lk&dNco;>0e2DWPc~H|9imx zUt0KEnIDz^9=Gt<0RGK@e(uXpR)eC74Y|^bvhLP3z%=_AG7|r#iDOu{g?><-9&oizkIg8jP(&$NHOMZcQ$QRBC(NssJr1^)jbu>W9MXF~RW#QgIj{5OE~h`#{%?@qwK z#KNEWeGQJve@zztIuQRK0sh+-{*0LX*Dd_bfPXjOUqtIH$p6m=4{Bu6(k^ghf z3zxqi1O7u6{vFIeBqII)+oE3;(|_A6_U8io?*sNHZ@~V0k@+JG`<1WdaRKR({|W$q zCE&kh;qSRbQ_T9ym$+|C{OGkMzj@-N65k0{=H#_>*JW|ExuS5$mJsuU}d0-vI1?9N2#x%@ZL1 zUB>)@M*5ri_il^+2G-wi=uQ7GBR%r}Rs9&t1+f1t8Yd$APq|GCqw>$47JWJE zqw>#E(j)sfP6@Xk-N636sGp4NuV;Q#`MJQNZ;2WI`z-n^S+CytC=WCJ?j}8o|8|al zfp&v8f3zCJ{}k#cq4;c}PR^zl! z*MRt+Pwgy<|IeA9FP%@{P5Y}!kN8uVpDXw;0RC?*{7uZyGx(RGJ_V0Oz79J3x zzt^HanDym`-i-fp(xdpda{T4^<3$kv!>FD@_Fu&OsQP2RMc>5wsQUYA(j)u3K>EE5 z?Ek%mzkvCN82&TU??fu+DE@b_ew3j%{hv>IWdAyl|JMWi@3ioL7t{aww`2R?WqqY# zzZw5yNssK$`I;`jHLO?V_jkblYc2euA8KJ#{r$E@U&8vR@>97K$NyZ`508ldMAD=9 z*Kqu0{q-h@|AQ9(x0xSRevYMj2IaroSbs)@{YQ}=*}n+b|2DAyMhpK9=1+>?f6Kz} zX1=U{HUj?tSorzNH2B;I{zn#mzl*~8_Z`4*r*eY)e--l+5&UM-BmXxrU*?}pfd7Vt z-^u*rBlxdc_)C~C+rM`Kzkt#i#s3ZFA05H}D(O-DI{|+);4fkR9%jXKrv?`p{C>v& zzh~jEVg4dMU)5jl0sbw^bo@l_cv?-{Fj$ueoajN zTGAta7vO&Y_|?SOjchdMj~6iCZ2!z;noQ>*er}D9zbyY-0sq$){!`39j{WC3x=(*HElqxdgkehnM0^4~VVzk&It{|8XGI-<(|H!b|FApRc# z{)-m=$;^-P|MM1pUad}l>HqD3zu%9r|7)0E?0F&k$1H!JCq43i1@l+1RQdm7z#nJf zFJpdG{WIFa-_Cql|9k@YcQW5h{|(F^pN+crZFl4UOD+5b)AsPrtl{%j{Qn8~TP^%S z6t0f1>W|D{lmEVjznS?m{d33$KmGi6>5Sz#{VSLs<^PjOPtgjkzvtHN;n^(xzdPXn z)52d6lmFiq{tCd~6YxK|8^^ypCjTF#NAWMJ*YU66lvC-yH{f4z59V)YelhF)4?q3< z|DQv8#9zYv4n9%w`vLwf7Jd==RUP^IBlFkf-(=wrNa^^?{I?I_Z?*7im|vD5>n|q% zeG9*s`Q5Bn@$V1#U-~ij{|e?8v)=zO`A3i*`9Ej6j{ge5-w*JoSooV`@~bTT70j3E zKLGG=wea)r)`sW#5$8`c{);XAycs(FWvo;FKM?R=wD8Mf@}IZx8vuVG;O|Wdv>VxI z_CFh#A65VDMtYR~oy?c@-ywkiq=mmMX8a$s@QWM5{?7&c_bmKw=I2MG{~s*;1mxp|GSu9Bl6!7fPbNdpGWnII-=r#u7#i57_R@00{mMn{4(a} zYBMr_`(?iAFE?5EWy~+*^HurF1N@`!)BfMx=vdS+->*M>Y@YvxKUc8cEI%7qzrZ-( zwEst>N9nhS?ccz9W&g3j{@Z_Iv7hP%b-bfLGJo?j-}ILoR^t3uwnG0N<^OMz9@*b; zak%^)2khUQ7N}JH6Y@XvXBhV88UMeE^``&V#I%1d>5=`N!2aWb{SR2|-^hG({$hY( z|JxS(b0}Y{Bg+4;TkPKs>>mv5|H1><|EgY6hq?Z2+F!(a)BnXW?H@{dYw8t!uB^%y`l~? zznT9366ulsMYFX11^P1H`ezZa|7zx&_0K%!m$Bae$n(GO=LU=YYgivueqXWJ-@x|! zd{zIS0_;EZVeJ2n%=hE(n{C>E0qf23JAmpHbwv699MU8IcLM*P4(z|lVt*dSc9A*?-K>aQ&0VdNaOe z{c|Mgk^h&m{eJmV<@YRL|3%C<>z`ugoAY0JUaYczZnN0m%KH55sopo!{+liKuLJ&{ z2<%^Nv40u!4>kCvKR>Y8-yPHcf3n!0+Y+w-D}eonKZ48eI_5|9f67>Imfx+cUtq-F z^#54Wqx@6G_RIFS3fTX#h2KH_3U!$NHu-+H)%FP5&*k z=uP`ak{d~33Cu6hm(j-1Uz7j1gl=_RQ&m}#|KOL8c?Y|P(|D~rf|DVkNFoJ&s=@Gx^iZK6b zz(0O9=5M8XSshXBU*0oVzcex3T{~u0zWdC+x|FyvW4hw%E)hp^)q(3r$&Gc)x z@VlNmV`Qu_<6lL3=ii7_`hf2cU-0YU&I2%{}$k{eGbQeOt;2fAE1ZZpXW%A z;@^3-=F9eHA>enc!TdGMKRtrqPI|=8pQrh<|8)c4zh&X?{VNSVDuTb^d2Ih6)*l|B zzxf5MFJ}Gz5&AV2eMLSwf$m%;RZ=&xD-UO;*j{}uDK;VW3F_;&#Q8y5a7s#nz!75`T) z{EF)|U&enK;Lmyy$G?Eer8-9FkIY}w{|%%^@n7&w&6nwa7vTTd!k^CksQdpmTlmYE z?~mV<|Ca;)H8j9baWd!M8pyBe7@$8gfBR*==`UB19>ss%LLGlu|K9`nPcq+}|Cz`9 z!3HnS`2R;1eK+fu8t0q(AFadjuOYvxBP#xPkRHW9=R4u}-v{EqjrpPYGr!ogBKs#V z`_=naN&_U6e%&$cFD5;*zW~^OKd}EQ=9~6!WPZM3uWA3I7W?~Ax~e0}{|{O0uL1UV z0{b^x?9XF2LafV@&(cV7*!Y=1{$$j;Q>9 zGU-wN$-5z3|2zTgpKGx{kNL-IGctekGT-!@z{_jWif;yu7zn=8S|4V@Xp91zD@+!7JkNHvUUlr?3 z`zvDFKZ*3n{x!hNh^I5;aIN$7lc3JG-&h~e+ zUge)P!2Zi$)BZR4Q>k81$GiF?^Vj6hAwBY6*NwXTb+c0OUjY2meuw#Es9dPyVEvK# zYw|x}y_x<~SRa*t|3rFZf5)P5{qY-Me?BFU>VKH^-#q3=)gRMXZ`$7()BdlK9@)PF z*uM_gzvt`N{%+>ql<~a&l4tz?9@6heVcJ{SAE!{gpboRX^Z)OE-bs4Tetml8?*_I% zmqS$kc?H=2DBExPuO@=;gC6qvM#kC-_^$%~>&!3kFUX$_%skibG w=02@|e2cV41O4aeXEX08#pYMFzIkvk#=-yP - -#include -#include -#include -#include -#include -#include -#include -#include -// This is a temporary google only hack -#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS -#include "third_party/protobuf/version.h" -#endif -// @@protoc_insertion_point(includes) - -namespace helloworld { -class HelloRequestDefaultTypeInternal { - public: - ::google::protobuf::internal::ExplicitlyConstructed - _instance; -} _HelloRequest_default_instance_; -class HelloReplyDefaultTypeInternal { - public: - ::google::protobuf::internal::ExplicitlyConstructed - _instance; -} _HelloReply_default_instance_; -} // namespace helloworld -namespace protobuf_helloworld_2eproto { -static void InitDefaultsHelloRequest() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::helloworld::_HelloRequest_default_instance_; - new (ptr) ::helloworld::HelloRequest(); - ::google::protobuf::internal::OnShutdownDestroyMessage(ptr); - } - ::helloworld::HelloRequest::InitAsDefaultInstance(); -} - -::google::protobuf::internal::SCCInfo<0> scc_info_HelloRequest = - {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsHelloRequest}, {}}; - -static void InitDefaultsHelloReply() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - { - void* ptr = &::helloworld::_HelloReply_default_instance_; - new (ptr) ::helloworld::HelloReply(); - ::google::protobuf::internal::OnShutdownDestroyMessage(ptr); - } - ::helloworld::HelloReply::InitAsDefaultInstance(); -} - -::google::protobuf::internal::SCCInfo<0> scc_info_HelloReply = - {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsHelloReply}, {}}; - -void InitDefaults() { - ::google::protobuf::internal::InitSCC(&scc_info_HelloRequest.base); - ::google::protobuf::internal::InitSCC(&scc_info_HelloReply.base); -} - -::google::protobuf::Metadata file_level_metadata[2]; - -const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { - ~0u, // no _has_bits_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloRequest, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloRequest, name_), - ~0u, // no _has_bits_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloReply, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::helloworld::HelloReply, message_), -}; -static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { - { 0, -1, sizeof(::helloworld::HelloRequest)}, - { 6, -1, sizeof(::helloworld::HelloReply)}, -}; - -static ::google::protobuf::Message const * const file_default_instances[] = { - reinterpret_cast(&::helloworld::_HelloRequest_default_instance_), - reinterpret_cast(&::helloworld::_HelloReply_default_instance_), -}; - -void protobuf_AssignDescriptors() { - AddDescriptors(); - AssignDescriptors( - "helloworld.proto", schemas, file_default_instances, TableStruct::offsets, - file_level_metadata, NULL, NULL); -} - -void protobuf_AssignDescriptorsOnce() { - static ::google::protobuf::internal::once_flag once; - ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); -} - -void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD; -void protobuf_RegisterTypes(const ::std::string&) { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 2); -} - -void AddDescriptorsImpl() { - InitDefaults(); - static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { - "\n\020helloworld.proto\022\nhelloworld\"\034\n\014HelloR" - "equest\022\014\n\004name\030\001 \001(\t\"\035\n\nHelloReply\022\017\n\007me" - "ssage\030\001 \001(\t2I\n\007Greeter\022>\n\010SayHello\022\030.hel" - "loworld.HelloRequest\032\026.helloworld.HelloR" - "eply\"\000B6\n\033io.grpc.examples.helloworldB\017H" - "elloWorldProtoP\001\242\002\003HLWb\006proto3" - }; - ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - descriptor, 230); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( - "helloworld.proto", &protobuf_RegisterTypes); -} - -void AddDescriptors() { - static ::google::protobuf::internal::once_flag once; - ::google::protobuf::internal::call_once(once, AddDescriptorsImpl); -} -// Force AddDescriptors() to be called at dynamic initialization time. -struct StaticDescriptorInitializer { - StaticDescriptorInitializer() { - AddDescriptors(); - } -} static_descriptor_initializer; -} // namespace protobuf_helloworld_2eproto -namespace helloworld { - -// =================================================================== - -void HelloRequest::InitAsDefaultInstance() { -} -#if !defined(_MSC_VER) || _MSC_VER >= 1900 -const int HelloRequest::kNameFieldNumber; -#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 - -HelloRequest::HelloRequest() - : ::google::protobuf::Message(), _internal_metadata_(NULL) { - ::google::protobuf::internal::InitSCC( - &protobuf_helloworld_2eproto::scc_info_HelloRequest.base); - SharedCtor(); - // @@protoc_insertion_point(constructor:helloworld.HelloRequest) -} -HelloRequest::HelloRequest(const HelloRequest& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (from.name().size() > 0) { - name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); - } - // @@protoc_insertion_point(copy_constructor:helloworld.HelloRequest) -} - -void HelloRequest::SharedCtor() { - name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - -HelloRequest::~HelloRequest() { - // @@protoc_insertion_point(destructor:helloworld.HelloRequest) - SharedDtor(); -} - -void HelloRequest::SharedDtor() { - name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - -void HelloRequest::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const ::google::protobuf::Descriptor* HelloRequest::descriptor() { - ::protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); - return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; -} - -const HelloRequest& HelloRequest::default_instance() { - ::google::protobuf::internal::InitSCC(&protobuf_helloworld_2eproto::scc_info_HelloRequest.base); - return *internal_default_instance(); -} - - -void HelloRequest::Clear() { -// @@protoc_insertion_point(message_clear_start:helloworld.HelloRequest) - ::google::protobuf::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - _internal_metadata_.Clear(); -} - -bool HelloRequest::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:helloworld.HelloRequest) - for (;;) { - ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // string name = 1; - case 1: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - this->name().data(), static_cast(this->name().length()), - ::google::protobuf::internal::WireFormatLite::PARSE, - "helloworld.HelloRequest.name")); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, _internal_metadata_.mutable_unknown_fields())); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:helloworld.HelloRequest) - return true; -failure: - // @@protoc_insertion_point(parse_failure:helloworld.HelloRequest) - return false; -#undef DO_ -} - -void HelloRequest::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:helloworld.HelloRequest) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - // string name = 1; - if (this->name().size() > 0) { - ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - this->name().data(), static_cast(this->name().length()), - ::google::protobuf::internal::WireFormatLite::SERIALIZE, - "helloworld.HelloRequest.name"); - ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( - 1, this->name(), output); - } - - if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); - } - // @@protoc_insertion_point(serialize_end:helloworld.HelloRequest) -} - -::google::protobuf::uint8* HelloRequest::InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused - // @@protoc_insertion_point(serialize_to_array_start:helloworld.HelloRequest) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - // string name = 1; - if (this->name().size() > 0) { - ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - this->name().data(), static_cast(this->name().length()), - ::google::protobuf::internal::WireFormatLite::SERIALIZE, - "helloworld.HelloRequest.name"); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name(), target); - } - - if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); - } - // @@protoc_insertion_point(serialize_to_array_end:helloworld.HelloRequest) - return target; -} - -size_t HelloRequest::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:helloworld.HelloRequest) - size_t total_size = 0; - - if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); - } - // string name = 1; - if (this->name().size() > 0) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - } - - int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void HelloRequest::MergeFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_merge_from_start:helloworld.HelloRequest) - GOOGLE_DCHECK_NE(&from, this); - const HelloRequest* source = - ::google::protobuf::internal::DynamicCastToGenerated( - &from); - if (source == NULL) { - // @@protoc_insertion_point(generalized_merge_from_cast_fail:helloworld.HelloRequest) - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - // @@protoc_insertion_point(generalized_merge_from_cast_success:helloworld.HelloRequest) - MergeFrom(*source); - } -} - -void HelloRequest::MergeFrom(const HelloRequest& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:helloworld.HelloRequest) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - if (from.name().size() > 0) { - - name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); - } -} - -void HelloRequest::CopyFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_copy_from_start:helloworld.HelloRequest) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void HelloRequest::CopyFrom(const HelloRequest& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:helloworld.HelloRequest) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool HelloRequest::IsInitialized() const { - return true; -} - -void HelloRequest::Swap(HelloRequest* other) { - if (other == this) return; - InternalSwap(other); -} -void HelloRequest::InternalSwap(HelloRequest* other) { - using std::swap; - name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - _internal_metadata_.Swap(&other->_internal_metadata_); -} - -::google::protobuf::Metadata HelloRequest::GetMetadata() const { - protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); - return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages]; -} - - -// =================================================================== - -void HelloReply::InitAsDefaultInstance() { -} -#if !defined(_MSC_VER) || _MSC_VER >= 1900 -const int HelloReply::kMessageFieldNumber; -#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 - -HelloReply::HelloReply() - : ::google::protobuf::Message(), _internal_metadata_(NULL) { - ::google::protobuf::internal::InitSCC( - &protobuf_helloworld_2eproto::scc_info_HelloReply.base); - SharedCtor(); - // @@protoc_insertion_point(constructor:helloworld.HelloReply) -} -HelloReply::HelloReply(const HelloReply& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (from.message().size() > 0) { - message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_); - } - // @@protoc_insertion_point(copy_constructor:helloworld.HelloReply) -} - -void HelloReply::SharedCtor() { - message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - -HelloReply::~HelloReply() { - // @@protoc_insertion_point(destructor:helloworld.HelloReply) - SharedDtor(); -} - -void HelloReply::SharedDtor() { - message_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - -void HelloReply::SetCachedSize(int size) const { - _cached_size_.Set(size); -} -const ::google::protobuf::Descriptor* HelloReply::descriptor() { - ::protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); - return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; -} - -const HelloReply& HelloReply::default_instance() { - ::google::protobuf::internal::InitSCC(&protobuf_helloworld_2eproto::scc_info_HelloReply.base); - return *internal_default_instance(); -} - - -void HelloReply::Clear() { -// @@protoc_insertion_point(message_clear_start:helloworld.HelloReply) - ::google::protobuf::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - _internal_metadata_.Clear(); -} - -bool HelloReply::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:helloworld.HelloReply) - for (;;) { - ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // string message = 1; - case 1: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_message())); - DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - this->message().data(), static_cast(this->message().length()), - ::google::protobuf::internal::WireFormatLite::PARSE, - "helloworld.HelloReply.message")); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0) { - goto success; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, _internal_metadata_.mutable_unknown_fields())); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:helloworld.HelloReply) - return true; -failure: - // @@protoc_insertion_point(parse_failure:helloworld.HelloReply) - return false; -#undef DO_ -} - -void HelloReply::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:helloworld.HelloReply) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - // string message = 1; - if (this->message().size() > 0) { - ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - this->message().data(), static_cast(this->message().length()), - ::google::protobuf::internal::WireFormatLite::SERIALIZE, - "helloworld.HelloReply.message"); - ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( - 1, this->message(), output); - } - - if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); - } - // @@protoc_insertion_point(serialize_end:helloworld.HelloReply) -} - -::google::protobuf::uint8* HelloReply::InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused - // @@protoc_insertion_point(serialize_to_array_start:helloworld.HelloReply) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - // string message = 1; - if (this->message().size() > 0) { - ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - this->message().data(), static_cast(this->message().length()), - ::google::protobuf::internal::WireFormatLite::SERIALIZE, - "helloworld.HelloReply.message"); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->message(), target); - } - - if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); - } - // @@protoc_insertion_point(serialize_to_array_end:helloworld.HelloReply) - return target; -} - -size_t HelloReply::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:helloworld.HelloReply) - size_t total_size = 0; - - if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); - } - // string message = 1; - if (this->message().size() > 0) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->message()); - } - - int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void HelloReply::MergeFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_merge_from_start:helloworld.HelloReply) - GOOGLE_DCHECK_NE(&from, this); - const HelloReply* source = - ::google::protobuf::internal::DynamicCastToGenerated( - &from); - if (source == NULL) { - // @@protoc_insertion_point(generalized_merge_from_cast_fail:helloworld.HelloReply) - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - // @@protoc_insertion_point(generalized_merge_from_cast_success:helloworld.HelloReply) - MergeFrom(*source); - } -} - -void HelloReply::MergeFrom(const HelloReply& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:helloworld.HelloReply) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - if (from.message().size() > 0) { - - message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_); - } -} - -void HelloReply::CopyFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_copy_from_start:helloworld.HelloReply) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void HelloReply::CopyFrom(const HelloReply& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:helloworld.HelloReply) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool HelloReply::IsInitialized() const { - return true; -} - -void HelloReply::Swap(HelloReply* other) { - if (other == this) return; - InternalSwap(other); -} -void HelloReply::InternalSwap(HelloReply* other) { - using std::swap; - message_.Swap(&other->message_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - _internal_metadata_.Swap(&other->_internal_metadata_); -} - -::google::protobuf::Metadata HelloReply::GetMetadata() const { - protobuf_helloworld_2eproto::protobuf_AssignDescriptorsOnce(); - return ::protobuf_helloworld_2eproto::file_level_metadata[kIndexInFileMessages]; -} - - -// @@protoc_insertion_point(namespace_scope) -} // namespace helloworld -namespace google { -namespace protobuf { -template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::helloworld::HelloRequest* Arena::CreateMaybeMessage< ::helloworld::HelloRequest >(Arena* arena) { - return Arena::CreateInternal< ::helloworld::HelloRequest >(arena); -} -template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::helloworld::HelloReply* Arena::CreateMaybeMessage< ::helloworld::HelloReply >(Arena* arena) { - return Arena::CreateInternal< ::helloworld::HelloReply >(arena); -} -} // namespace protobuf -} // namespace google - -// @@protoc_insertion_point(global_scope) diff --git a/examples/cpp/metadata/helloworld.pb.h b/examples/cpp/metadata/helloworld.pb.h deleted file mode 100644 index 57f6817e310..00000000000 --- a/examples/cpp/metadata/helloworld.pb.h +++ /dev/null @@ -1,419 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto - -#ifndef PROTOBUF_INCLUDED_helloworld_2eproto -#define PROTOBUF_INCLUDED_helloworld_2eproto - -#include - -#include - -#if GOOGLE_PROTOBUF_VERSION < 3006001 -#error This file was generated by a newer version of protoc which is -#error incompatible with your Protocol Buffer headers. Please update -#error your headers. -#endif -#if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION -#error This file was generated by an older version of protoc which is -#error incompatible with your Protocol Buffer headers. Please -#error regenerate this file with a newer version of protoc. -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include // IWYU pragma: export -#include // IWYU pragma: export -#include -// @@protoc_insertion_point(includes) -#define PROTOBUF_INTERNAL_EXPORT_protobuf_helloworld_2eproto - -namespace protobuf_helloworld_2eproto { -// Internal implementation detail -- do not use these members. -struct TableStruct { - static const ::google::protobuf::internal::ParseTableField entries[]; - static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; - static const ::google::protobuf::internal::ParseTable schema[2]; - static const ::google::protobuf::internal::FieldMetadata field_metadata[]; - static const ::google::protobuf::internal::SerializationTable serialization_table[]; - static const ::google::protobuf::uint32 offsets[]; -}; -void AddDescriptors(); -} // namespace protobuf_helloworld_2eproto -namespace helloworld { -class HelloReply; -class HelloReplyDefaultTypeInternal; -extern HelloReplyDefaultTypeInternal _HelloReply_default_instance_; -class HelloRequest; -class HelloRequestDefaultTypeInternal; -extern HelloRequestDefaultTypeInternal _HelloRequest_default_instance_; -} // namespace helloworld -namespace google { -namespace protobuf { -template<> ::helloworld::HelloReply* Arena::CreateMaybeMessage<::helloworld::HelloReply>(Arena*); -template<> ::helloworld::HelloRequest* Arena::CreateMaybeMessage<::helloworld::HelloRequest>(Arena*); -} // namespace protobuf -} // namespace google -namespace helloworld { - -// =================================================================== - -class HelloRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:helloworld.HelloRequest) */ { - public: - HelloRequest(); - virtual ~HelloRequest(); - - HelloRequest(const HelloRequest& from); - - inline HelloRequest& operator=(const HelloRequest& from) { - CopyFrom(from); - return *this; - } - #if LANG_CXX11 - HelloRequest(HelloRequest&& from) noexcept - : HelloRequest() { - *this = ::std::move(from); - } - - inline HelloRequest& operator=(HelloRequest&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - #endif - static const ::google::protobuf::Descriptor* descriptor(); - static const HelloRequest& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const HelloRequest* internal_default_instance() { - return reinterpret_cast( - &_HelloRequest_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - void Swap(HelloRequest* other); - friend void swap(HelloRequest& a, HelloRequest& b) { - a.Swap(&b); - } - - // implements Message ---------------------------------------------- - - inline HelloRequest* New() const final { - return CreateMaybeMessage(NULL); - } - - HelloRequest* New(::google::protobuf::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CopyFrom(const ::google::protobuf::Message& from) final; - void MergeFrom(const ::google::protobuf::Message& from) final; - void CopyFrom(const HelloRequest& from); - void MergeFrom(const HelloRequest& from); - void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) final; - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const final; - ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const final; - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const final; - void InternalSwap(HelloRequest* other); - private: - inline ::google::protobuf::Arena* GetArenaNoVirtual() const { - return NULL; - } - inline void* MaybeArenaPtr() const { - return NULL; - } - public: - - ::google::protobuf::Metadata GetMetadata() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // string name = 1; - void clear_name(); - static const int kNameFieldNumber = 1; - const ::std::string& name() const; - void set_name(const ::std::string& value); - #if LANG_CXX11 - void set_name(::std::string&& value); - #endif - void set_name(const char* value); - void set_name(const char* value, size_t size); - ::std::string* mutable_name(); - ::std::string* release_name(); - void set_allocated_name(::std::string* name); - - // @@protoc_insertion_point(class_scope:helloworld.HelloRequest) - private: - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - ::google::protobuf::internal::ArenaStringPtr name_; - mutable ::google::protobuf::internal::CachedSize _cached_size_; - friend struct ::protobuf_helloworld_2eproto::TableStruct; -}; -// ------------------------------------------------------------------- - -class HelloReply : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:helloworld.HelloReply) */ { - public: - HelloReply(); - virtual ~HelloReply(); - - HelloReply(const HelloReply& from); - - inline HelloReply& operator=(const HelloReply& from) { - CopyFrom(from); - return *this; - } - #if LANG_CXX11 - HelloReply(HelloReply&& from) noexcept - : HelloReply() { - *this = ::std::move(from); - } - - inline HelloReply& operator=(HelloReply&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { - if (this != &from) InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - #endif - static const ::google::protobuf::Descriptor* descriptor(); - static const HelloReply& default_instance(); - - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY - static inline const HelloReply* internal_default_instance() { - return reinterpret_cast( - &_HelloReply_default_instance_); - } - static constexpr int kIndexInFileMessages = - 1; - - void Swap(HelloReply* other); - friend void swap(HelloReply& a, HelloReply& b) { - a.Swap(&b); - } - - // implements Message ---------------------------------------------- - - inline HelloReply* New() const final { - return CreateMaybeMessage(NULL); - } - - HelloReply* New(::google::protobuf::Arena* arena) const final { - return CreateMaybeMessage(arena); - } - void CopyFrom(const ::google::protobuf::Message& from) final; - void MergeFrom(const ::google::protobuf::Message& from) final; - void CopyFrom(const HelloReply& from); - void MergeFrom(const HelloReply& from); - void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) final; - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const final; - ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const final; - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const final; - void InternalSwap(HelloReply* other); - private: - inline ::google::protobuf::Arena* GetArenaNoVirtual() const { - return NULL; - } - inline void* MaybeArenaPtr() const { - return NULL; - } - public: - - ::google::protobuf::Metadata GetMetadata() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // string message = 1; - void clear_message(); - static const int kMessageFieldNumber = 1; - const ::std::string& message() const; - void set_message(const ::std::string& value); - #if LANG_CXX11 - void set_message(::std::string&& value); - #endif - void set_message(const char* value); - void set_message(const char* value, size_t size); - ::std::string* mutable_message(); - ::std::string* release_message(); - void set_allocated_message(::std::string* message); - - // @@protoc_insertion_point(class_scope:helloworld.HelloReply) - private: - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - ::google::protobuf::internal::ArenaStringPtr message_; - mutable ::google::protobuf::internal::CachedSize _cached_size_; - friend struct ::protobuf_helloworld_2eproto::TableStruct; -}; -// =================================================================== - - -// =================================================================== - -#ifdef __GNUC__ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif // __GNUC__ -// HelloRequest - -// string name = 1; -inline void HelloRequest::clear_name() { - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline const ::std::string& HelloRequest::name() const { - // @@protoc_insertion_point(field_get:helloworld.HelloRequest.name) - return name_.GetNoArena(); -} -inline void HelloRequest::set_name(const ::std::string& value) { - - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:helloworld.HelloRequest.name) -} -#if LANG_CXX11 -inline void HelloRequest::set_name(::std::string&& value) { - - name_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:helloworld.HelloRequest.name) -} -#endif -inline void HelloRequest::set_name(const char* value) { - GOOGLE_DCHECK(value != NULL); - - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:helloworld.HelloRequest.name) -} -inline void HelloRequest::set_name(const char* value, size_t size) { - - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:helloworld.HelloRequest.name) -} -inline ::std::string* HelloRequest::mutable_name() { - - // @@protoc_insertion_point(field_mutable:helloworld.HelloRequest.name) - return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline ::std::string* HelloRequest::release_name() { - // @@protoc_insertion_point(field_release:helloworld.HelloRequest.name) - - return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void HelloRequest::set_allocated_name(::std::string* name) { - if (name != NULL) { - - } else { - - } - name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); - // @@protoc_insertion_point(field_set_allocated:helloworld.HelloRequest.name) -} - -// ------------------------------------------------------------------- - -// HelloReply - -// string message = 1; -inline void HelloReply::clear_message() { - message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline const ::std::string& HelloReply::message() const { - // @@protoc_insertion_point(field_get:helloworld.HelloReply.message) - return message_.GetNoArena(); -} -inline void HelloReply::set_message(const ::std::string& value) { - - message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:helloworld.HelloReply.message) -} -#if LANG_CXX11 -inline void HelloReply::set_message(::std::string&& value) { - - message_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:helloworld.HelloReply.message) -} -#endif -inline void HelloReply::set_message(const char* value) { - GOOGLE_DCHECK(value != NULL); - - message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:helloworld.HelloReply.message) -} -inline void HelloReply::set_message(const char* value, size_t size) { - - message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:helloworld.HelloReply.message) -} -inline ::std::string* HelloReply::mutable_message() { - - // @@protoc_insertion_point(field_mutable:helloworld.HelloReply.message) - return message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline ::std::string* HelloReply::release_message() { - // @@protoc_insertion_point(field_release:helloworld.HelloReply.message) - - return message_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void HelloReply::set_allocated_message(::std::string* message) { - if (message != NULL) { - - } else { - - } - message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message); - // @@protoc_insertion_point(field_set_allocated:helloworld.HelloReply.message) -} - -#ifdef __GNUC__ - #pragma GCC diagnostic pop -#endif // __GNUC__ -// ------------------------------------------------------------------- - - -// @@protoc_insertion_point(namespace_scope) - -} // namespace helloworld - -// @@protoc_insertion_point(global_scope) - -#endif // PROTOBUF_INCLUDED_helloworld_2eproto diff --git a/examples/cpp/metadata/helloworld.pb.o b/examples/cpp/metadata/helloworld.pb.o deleted file mode 100644 index 85671e8aaa3b10080aba2cde1b103fe994eaa612..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111592 zcmeIb3!GI|*+0IA1B#?FDk$$CG-Pc}cubX3y(}t9kcqWv1mwCaHK|OEFI|H;%!F67uWS-)@nVvazrCe9Z z^;WsArt58T|30~{p=-a~zhACv<$60^*U9}Ibp3$bub1ncbp4>*e@Lzy=z5pj-%ZyK z%l$^Wenjp+D%X$6^&Yx@oc@18p6{jWCi;J$Jb#j|pOX8{a{V-2KO^^_rRx^Czn`xE zMgKoX{~r+S^KyMqu3wPrR=R#s?!P40FUxfsUB4pt57G5ux!+FLugd)+bp4v#KT6lH z%l%_?eO&Gb==y}*KS|eb$o&qwepBwBlIzoS-AVtyCC}fc>v!b-8M=N~?!QOZ@5}ul zU4J0=KcwrAt4FPAoqWy>pr>PPuKsJ`#;h3MY%s9*FV$sCAt3#U0;^_ztZ(@ za{qU_9+dlk$n_Pva-pYx9#?`Pav!1VP`MvQ*CXWqNV*P}`=jVOLhj!r*Q4cn3|)_v z`;l}lmHXr9dc549AlFfJeY4!3NY|6(el%TAmitradaB%?M%UBj{tUUEDc3T(j*MWv*rFAxxR(2ZO1kbF>$!-MT6NWht$)Q{DwRQT5PvABRK=_s7|tD2;82cRH89$w zKf@ppweLLkizcR`sf&DuF7OkVLa=Kt)uAm^hc*#CU4_@TjUcvd3z?B+8-syuOth|P zI1z7R;`;tMd+YmSd+2!&U3b%!@+vk+SNiX*+EcRXV9Cf0Tw$*hnw@mrNi+j=r96*q zrz`yrXh%LYKn;Pe<;Q7avA6%peZzGz?SGOYNV8w{>5&YZTPo2{nVL!XCO^F<-A4NC z5Z4omdTkxGI8WC1f6vG;j#uvSg`pz@$FHaQKNmeuu9FgBv5u+zd@|)$+AFfjHp_cXczO1ZT*ED)nNwUkMymfIMt347|-ay6h!-SGO_Cr5s8K+58++?(kb>YC`^fG+Dq$7W4l;bh-foEKc>1kv1-+d=iaky_}bX!+Sqg5M{egR>bBT`HL-{5*Uh2-vCUAh zU*G`{G2J}!HXe40e5!*b`ZjFomViiE%2kogq;gZDP5=Agn88&CZytHCq%Pg}bZqdI z%LCay;&2SQC4Q_~<{??SP1~?t!(j2l`|CM?MtWy6Qm5tpg)h z^R#4bY`<|bH9D(#21L*$BSx-Xqn$#zFBPJnlSPHVZ$BiXxuqJpn#a%-59FFnHNRPC zz3%zcxTXJ>Mgk8{M-(2)ot+OOs857MPh3TpzEM+M)v@8lTo+md9jj0H#0$!?x_07f!Ha5 zL~))Pavn=WgT@E@j#l#a4HM($kimXw;-;q_y*Zb?*?)k#%PnhS+X`{%LS<#h;jhl6 zTe4hA^$nas)tsuj>BYebx!jt1o!v@C`)(!M*k0;~gFcoT_9j(SpN{dAl{-j_fM3EGTTHVK$W9?n~k})1KDNu7gEXjLGA~&df z&1@E-bly79dp6Nf*>m@-*@;NE3D0)AZYN$U@$}y``XC>hTQ2=XY(^$e?&ARw0`y46 z`aX4*M(N1)vd~(!W+biX8#8?ALvv>N8#8>%1on*?zTfG*F~fgjhVQ*G!yljyO?PlP zI<%eP4h?}fX81IivCI|{7 ztsCt-UE?#hn%Ba?0uDvnwyhj%-doeYiS_%c=x$=b)bXM#C(H_LkA6C;rdj!rq?l3p-M+iH-}~J6k(? z+maV9Or;ifBrojhPNh@xdly`o=uUPfdeYtPoeRe;QcUz`N_}j~^s)ts_KsxRMP==s z?dkSJM|^3bqc>SL=F+m6a~c~jDkHj~^uMm`%+j(&$&QZHvQ&3R+qkaz<62t@=fHLi zm#eX{GzV^Y%IM|@q2qfL&xRAE!idsv%<&@vr2MoIN7u7qvy<=YP4=XZKYGN_&cu@B z=#sLMu}77kK4OH#c6BU2e&mQFmn3_75(_1|vSGxLS9B+n>16lumyHu)C{uT(U2*q^l#@1GJMzDlu2H_nJ6$O(mZk5~**z zdj1hAm&WUTmJYS!I7P-EnfW&MEepC+OU~sS8=GF#-gB!U`UqSUov?VLljwm)W2(-JoF>#;+t4xCB0OAZ}bzbba1WZ$nS!k`?-n;iljW&JDm(?)<* zJ4>X#^~Vm8as7i&?1}J(hK48h9??G_`Z$$lpUc`(+U8QfvA%>AQrb%?p~`MfHzTVC z$bdZu1zokj%=Z!Ri(-nkbzS_njz`Ra|z?sI;mydV#M?eGljuW%&u(a!#-> zJ=5x7KT?0M9(&M^mD<>zG`|QX!$$LdOp-18G39C&SFtPwX;&$uS9D^CQGxcZ}SS)%V|Z@PEy###LYEd#|^te%y&8UQ}UiskxL@z?TpsXuV7ZQULJ!`N(W)xh#q$nymRWB&!4Fz z&KV$xmY@7rCG@zHD7MppWh>op&5R;Awq@#?PoJTgHxb3AObQ+)ZRFQiG*a5=^kS1BEO7Ai4cIM9Ba#<*OEr>n%GGP&*qWze?;}6UODX+|N=&9v42`kgN2O^E5%8Pb zHLFwfcjc$~Z^mFt-d5fA*^e(X9WO1kl&_BjS& z$2Io2Ct0{sLOm)j5<8iH&e&^#NJ3)k7`M|v&v}l zjUMWUs7LPaCBM(vL;Vi#+j~|LKwUF&QO-~&PQ4e2r;;Rb#<7Z@a2krJZk8n+Qo9j_ zkhrPOP#qeP_ysZ0Uus%^<2Q2+?JywweUW+$P~v+__om!wQaWM>pN{b_WoX0U%a8G( z+fR;i!dfq|olD>D{@z{0NTn=xaBXZCZQ^-4#y`Lz_5+#h`}OXggZ-r=A3P8eA`%YJ z8#bO1kQ+03*|q~~>6ObN8a;Wmp<2cuyi1l;>k<>l1gAVzpE*G>L}uK>Kair$j8e3* zbOlnW68beR5KYBy^#E-bg7QnkGe(2D2hS=!#s;I!@2z=^00|ka&)5NN((s?vD}}03pYbQ5j!v?4@)6&!B$e%3<@ptIpxse%A8|M^XIw!#0$7^Masd$V9nj$T{ zTrS3PHzdvDpo!N%Fe2DAd{5ADhq||)!AzA32<_q*^qlDpmSc+8Kc zpaY^;+Hs-bVJT&UnbXNGI-tcJaK~$6V{qMY)rbeVNWZEKZ5K@Q?mV)^WV8CYBNeC2 z>9wMfu3oJOgD*3BUw>T$+e#7c_K%JU+9;hFH1rFs!m)YqV}a1LUuUKNbIybHGL|Cq z_wr!lboDbu(>G<#R^+EQzLBq;tjq%EKbiW;iVmugj$SD`V3MuM8x8lA_2P<=5Aox{ zHBCcJar^hnJ1o1zOzxal?fGBnhqK?V$#&y@`o)d<)eUc1<=v>VKUFUFks25NHO6`T z!!1?#1H=sUVCy2SY4lPvOpMg<1shb?d_1ku0Yd3F1S__Cz2`s9YtyRT<+kzZh-yur zo-$mws;0i|e&O@n%If;P^{Lnw_+8K!XbQ5GW+fy%Ad2jK z2~y-zZWA1Eah|;q{vYtb%xe8Qu*SR&tZDD07hau-j>_5wxtozpC)yI}#MSNTMU(ht z;p9Y5vSDU(MLarTPUqsz)UwWL?a7X|=43iHvpE{CoZ#e)#cHRdI@5{v&SZD25ckb& zPEU--Tl@N=(P-uTL{EEbT)(PpXl+hMqpgb)-SKpHqCMTy&>Cw_(4SaNxig~`!K<%m zg?jHcJ4x@pa&iThX7X1Gzk0c7mvF_DDHoNEotm8Ap6D!_IBxv7iVG&3t8ZB9C=p$9 z<7}^_ue9XUqmLZEo@P0x5zhZP9M69y9b0f65oWe-{W8$w2;;&_# z!kPTX#9tG{-^4ftnqvj=y+Qmvj8jlH8va>9{G&SBJAtnzer6E=oW!4n@z)3Oha~=T zjK496=kK*}xRC!C`8Ndd{QVOSXY(Hu9}nWMmG~1e{_R2hO%gv9<8Kb)?~(XP7=Kd` z|ER>Dg7I^L_~#^k7RC?J8FU(9ha~mwwG_X+qi z8rMZ`AG&H-CN@49(x&8ae3Qhx z($ppKt~#||;!j5TEkT;M=7}Ga__rW`BH%wD@vb^ssuJ&c=OF*QfWJcGUHnZFufEP= z{8JzBcS*eZy_1P=3gXx2k-t^qUG@!1d>z{V?m+$liFeic(qYW#dFA}a*mqsPUm@{l zVLY@cO%h*?@$U-wyCgn_@k8nq0hgck65o;$uNys%-zxFvU_9i{pv2qSoHF96k^HCi zrp$7FRbb;N-uOb{t^CLMV15u^CGoB@){-YaE%D1x{*Z3p2OILlZng13_^2Z}!t-45RTBReCNlnkI@Tib=V5#@(4UrgR~^|P@uQKy zIpE(W@n>NCJA(LKdE#G|cvl@BrKX#n=d!O#;$8N&NW9Cwbe{MP67RBaTOR&h5`RAW zhx#Qh!dyOH&ci?IC}yNpWBz0ESNO*gbd!{y+vr|3Cx)g$_bWrV1Ee_CHBV%nMEAa| z**czO?JPpp10u^do?=;}Bwx4DeTH3R`;e>0l@5V2bWmiu#tx%LkPr&4cBV$+E11Zn ze{qoRxf1V^-zV{|vE4?AS4lGRCkOJkOFXw@zJ6%Kc1wI2#=leZpG{aDXAp%C)Bh}A ztqbTD3EgrUD~0JIsS-uV`CP9W8_&Cdg&KRw@2x~pM$lG~6QlbKInegsE;3y0$^$uc zuno^h{9EbXw*lJi{SxmQdmMcLennuO*8?q`e) zqKTXpQAA9W78?GhUk1$-?N6rJC^XlFX_^C{KPoi*O+{Z$WV9mSJU&~>z^~{&!{>TT z_hUAQ=^BM@8_CI_yOPI#kx#Qg_V4+sLG->Hn8!4#M|l>`(mz?k$m-HrO@T87xUCW*j+Dnikw{a zVzbC_)r%cDba1}>R^natVyMax_dNG(iFehDsS=;7UMv!tT=n91p~+P*whB$Ida+Ar zT=n7-DFgZHMVrv&s~1yCxv;tGMO&WuTP0qZZR!=QBW#vS))Su@%I>C+>ny4_*gn+l{YBieata!qXm-TQ3@x0%wHG0m+7&}_*=quPI=QRW#x z!hCvvp7^6x$KZLh(bge)!AG@!5^w8sIUS7>KZyLC)~AB@r%PyD6EGg8GQp8?SnE@A@R2Pdl~UGN&Jtf9{J^6_fb1cAC=CdV?&oD7AP%i)kny#@1DN;#=~>rzL(4${(T^f!IGABwm?m z{4Z-n%wh{%+=hC8e#I6S@ou!iUc|e}fv<4j@5#csIVtf1ob50n;@xa+Gp-SDWyZ64 zhe>V6- zg45Ee3I_j%;Hrzte$#$boNg z;CDOljSl>y4*X*d{2mAX2?u_!1HaFKf6{?(cHp0O;GcEi_dD>CTQj*;tga1@)Yr&bl^K2 z_)`x2X$Sr-2mWmb{)_|vo&z6r;6HTWyBzql4t%!*|Cs}S&Vm2Zfj{rSf91e`+c>e=W z!EMC*NALi55$~Vyq;I#2e3N5F{>xGyO^QbYXT#2VI@uxOo#4PnIdDF0Cp$#E(GHwX z;mHmW?=%O_t3cTy;+^ThO|ED1L_Gf4X?BQsXE|^_J`4Yx!p*EQi2jbkV*wy{#~jHw)3Wdeg$rt?-U4oPmgUO;$c?+zJyt4c;w*`cn(a@=dRv8BP6cCLm7{ z^`)5XDC&Q+K|&%Ks}TVS^~=En+(o<*@D$ueJb8H*Kky(JslRsM$2xF%kraxJ z_^UIS5!AnD0`e5mJ4mzQsNc`R7>M}0QZu6?9<~ZWT*Nyuc!0Zzev=J|zNK+O7RErt z%dYPl&#vzpS1Y7^n-OSSk@0LEBA!~YHIM!^;+^5&;|+~B@X^1IcxC=Q-bB1H_~_r$ zIK;ol8ybh;qkkXqcTW0{x{2uBAekUN(fA|_V<4h;kY&ZuxFrkI^yfP8>~>YtXSb^w zKi?sTS5vb?#LI4nnJS`p{$?@II429!^k$VXGdkk05{B{Yc3#WLZs#>VAya@nMZ9VU zKGA{KIPh8revt#e*nwZ-z%O;+mpSmu9eAAspX9(NJMbwEe5wP_?q`{h#%~V#?0#0$ z*E{GN9Qc(Ee7XZ~bl@`_cy_M&}aAin*Qw$`q>V=*@3q>a5GxWjHdBnCLm7{ z?`j90Jw9Q=h`%b4$wuRiOhBF@-a8$5_IQQ~Bi?lm`s*Ed+=0(?;0Xsl-+{L}@HPjY zbl?jd_(BK1$bq*z@EaWXVh8RTH!g9|cRKKt1MhO+?{eVX4!p;KryY2&17GUE`E6i! zhC>B$;vWew^-;K?A#6Fk9~>o7l?uPrCp06% zxWZTaxEZPRDEuEjev;gMz(M~hg}=|IH$BQ96u!pCFO<76G^8%~-tXgQ%Uz4Y*ZQ~_ zao()(+kM>h9NP%D`Qar+e}_+RdaN6cX1(|LIR9pa!ygsCUO&)ZGZLLgL-}&=P9HZd z^)7|q>*KrSZq~7Od)5(N?tRFoKThrj6~4j8&B%cFx|Mr(`?%>@w-atnuLJ)dC1;~A z=R&#bCLuOCTL~=pKI+qxc`E#`!awHYX5_tu5;A5;us$$cDEbMv$$#2`|IL9<)KpUQR zq_>gi%e_w;@%r~q^z@X%H~Y9r?_U)DX&RUz9(|%q~4UtXGV}zH(d)RW}97hGxM&Chrx%a3q-?Z~v75Oco1)+0%Q60W!a@I%13#Ch^yS`Dz8oqBD$I7^?^gKJ zK0PHzh0O~8wvWG6?tb8){|Di=bXCw&Lb>;hFUOSIxWa??HM51{f-{-^ds*~pg$M6t zOuzGY2mNJbEN9S{vrO*pQh4w_!j#){$1r{HK7#ktaClVVKhzKO*T^}A3X(0ovj{Ku zcKP&XBzmX9pY?I-c2)R=L(Yj*@XFP%KQ-OCLSId|P465BeXqiQCfxEHGJ3kpfqzBe z&-wHwzkaOnU;6lYau=ZiNxApDkDGR5{xIIJxWdQF|0^G->aRkp!h`o~CV!t& z_-}lADmE%asDhMxzsthMEBp^WZrY!P3g7GF#?DQIvz=uUW3GdW{*OMrvGXqq58n3~ zJ6p(6X^i=#*xRf%~X6Jhd zXZg#7-uU4w4*G)*eE9`z&nu!W_%6fO9QeNo=X{wb9O7>8vT=;leoL`usKloTFNb{v zrr-IT!h`qngF=7Sg?9S5!h?MXWkP?u1OF=FwsQV+!pFe-&D|pBkkCIThEpnSXc0VWtC53qE3)riU)?p<3`~ z1efaP%@_Qaf}bSx8wCHG;9Y`0BKU$MG@yPrM7L*Da=rxnJsO36sltQ(9tQtD;iW=@ zmp6@PIl(>j}5n|Af%j9j)orZ=>k;fP=nqqLzRCF`E8Y`r_S5c)1tsCoz6INVrY!Wi?t( z-LYB#|CWkFhu|-d)X$gci?>zqN)cx8UkKhMxUhN0)N1)F1*hy*VS?aa5?uW@ieeTJ zE|5^_%V&iCy~pe4F%r9raBfdpLhZ>B7iqoWe&;QOkAeLRyG2e+=pP%U0aNc%f=@j` zIjr@{}wVh%5F@jeLy{Xre1iwviQ?FBkKPb4k$@_@l z1A?1+{Vlx0`{MJjg zoI08xa4_Ze2Exl>zmqAq-xvCF8OWIO`A@;0m4SdMhnLa~*Sk?=O1%CpEZr^=e74}G zeBLeie8Elmd{poaf}8TWPw=*K5=z08!;`3kX1%uwZgyz(5IzR>pN!UQ-Uhw-BgAYwr&V&mKR-r!sx^{PEWczo10a`RP4{DsnmOLo;?>qwruqSf4QV z6K-qAwm9&Im7Hw<|5V}Gem?D?U>gMD|$3D*e?EI-&U zXZ$~(aGU%z;YKDZzQuumT*(ji-AVK0{Z!%E{(R?^cKLTW@b5eDlcw9{T<5^=bl{IW z@ZS+W2KL>p5N9l)26hbWubUwFy@cERwo}mu`|C_O`GdlPeRRfe!)Ms#lrcU8b41@? z;GmB=@Y#fyWsC6^I&eJDNuR$Jzot3e7_IGUPqrqPwf7|Bt*K7>bY5?3+KXRvO=Gks z9$%PV)SXPU#S^XR_NB>q*V0&JMK+r5CI&mbil_=$Qk|{IruL?3OP9tdiu99`_7tBU zrXQo@6Lc6?Ya*TMjwiYoYOuO}VP~p4Ne?q?NmOSqf9|ibG8&J!B^M-mJJNAtSsd?5 zb+otAXZnaN{LR9~+QszM!ts?$5`DSj+dFf_S6Aicr+62Cv|@2@ZVQCM*TH#HLFr3& ztJH~mqUrAC@pKBIibPwgOS{09bpLaWjg=D@&uH(gr~FKIUzP0cX-{=dOLaH4&+krj z+ua7d)iz#r6j`g)V*%^@@qad3+Sjnzs9vwQ<0#` ztXT7yIKIM9{iL2As?1Z9J+0mCT~x_?W|558(pVKY43yS9lA<+}+S-7-fey+eZmuXs zVgW*`GKGNpDr!?GU1|D=sGMlnej`1lI^&7XHcGp09{IVVz1@pn(Ku`Jq()-togZ(A zQ%>QxL&rzsn3Y+ciz}x$r>m*4ThiXz&>ovIAx1*8Td!zzhCX(%u|1t6B9*b>CN6_$ zs*5Q6Iaa5%FriDLU(a)V)0LDo@yB2%sBgns>+nQLq01f?i#`#hD0Pw7q_^g(SI9IkX#q4|}5jO{VWCN2?oC3oEB}q*C28Q=Qi&yHl|nm^h;;tJF;y=_C2N zg^SbInUmbi`Ek(nMeR*rWqT?*aZ0K!**2>;-PN0JPSbdFNoB>=-P9Cbm7pVOX;jye zn$+E$SRT8fX_3unyNqb1X6LFpzEYC~ zr>iAZ6I;S|O%IFL?P0AN4b`Voi(^gGo71&v8kA7)vmlj=DLQdhr)o`up_Gj~tTC{z zN^z4r=}_OMboay=z3IgKjwA^=oDXW}Yu=rDqg7KVL(|Cy8BSz$6o+Svtq8dFSI_C} zNi0axm&s-Pb(kI~PHP3}n@OdXK9zo$`erxR=5BnVp&YJ^W_tS7spsSt|KasSb8PnX z<|<`)R&8+SQNf!q?RqFA6qE$5fNOz}}zj~d;J9=tVd5AlN z;tFQ%l#XPgyCoG{(v|*?SU#bZ4Ja~yD=T#^o}E}GEgCH;&>;mGrKRu!SKH9@DjS2T zSC8vXE*M9P6@7j2E}Cnn=)8pX^z!)9iro28L0zjE3PpLR1M{-9#$#aauZkbz+y&X`TV3}Y0{lWA!?%4X6jB7TGYVV z>I=WI9A8OtD+GkRIs^Lgp1+`|kZ+%!ulq(MjQH!}VdzZ|ovwGANuwXNy z6|8hv4{MNY^N4>^vbT}=wY{=y0Xk+&t znWvqI3a46^FP6KqYF20SqTX~H9Tz5ZCm9OUP&Rk#=ufr^W*8snn%&zO<8jXPrLpGm z)*(jLDQ41%X7^a(WpigI876dglwraNYKCUd@GLu>J!@EMbi5KfEz!|2pWbs7D88zB zS)wb}M1_PZ3@xPg&|^artphHlv1_WkA=^JRQ45ZPwRJWa}bi9G)1rz9XaZfzm+eMTe?TeEQEyPZXm{CI2gu#D@-A=+9 znkUC8Hdrqj$*aUh{*Q;JYsj0JRE@0luTHC*ISMT4t|{K{;|~Vl+B6H6z)*FgdL|wS?xq?o0@e z+p-#xT9l*fdsgKx#H5K+Q#snNLL@}1+ho&+c?E5EP*xHOWi+oE-4i84VeJe}q^spO z@va8nk9SP3{CL-V$Ph$%U@$wmpo7|CdSk7jLBKFMlV6DDVOxr4H@suGfmPpGTaX3v!f}iU_x7%gIW0t)(=!mkc*xtL2BYS zGj&yace*!0TM@WL%kUE%Aez_1$XHoxb`Q{2j;tKflfF#jK+|iNA0V`l+yHWALlJoa ztOeu*QoHgY(>)o5y{a>@Bx%-YvNJ7%mR^`jo;Go{FIX;Hxnk|@vfzuwD6>MDHpxvW_ojX)=Os=mcl27%K6MI;tE>YD zn{s;8kfiwK9eyoL)6xku+81`K%~{QA6C0VqF%@ys0TOV7>O5-92s_rKDWX-e&fX<~ zB|bi}nO5f7TayswyU5I?a%OD)t!^yOS*L4TX#y7Ky>Jaz&ZapL-^CYnBo@x*9kUdc zPVJIiCppcitn>@Y?Bv4s9(otXt9*y+@tihCtBneJm7uj~F9&W{%MCdVwr}jS=~YvG z**(~lN_Ft&NqrtUy|=g`NymoMb^_XFs`fH0wJvl-t7PyojrKLuR+wN^Z&DJL(@N_D zhqscHzb(kUTTRx_b2=}#1Q|!>mQX9Z9^3qVl)(l_K8QWsh-dbY)r)6Re~PQYww&{u zf*dnw*Qhw)tu@(gD)nn}=zM;??rD~37@V~_V^^T#g@~WP3}VSUcYhsBQrtB8a<8I! z5xsnDn?hB=GJwswoc-0gu%VUw7;UAh7EgC4Xd7iiE3bdH#$weS>IHxsWkbOLgQ*WGVXVHcgHLi-uRxP*Gis0p9ZS&&xF4YC-l|yT8 z&=yViB2?yVDx=-0tfGOL-oVYxeNaXDrCr!O`+F(X3WiCY{;3=fZ?W_%;*R!25AEY< zKfG~(O7~$|20pH=^xc5#=z3UJK|^9h`8`iQtvOsi-tTCAogvqomwNNy&X)GBhA8?EGbxcu&{F-3)0%~##IjTTi+NiCtxz2<$qD#AVfyF;5-bB~5H zmP)emDOJ#%#_qmsx1P39aZr<&;aV0~~_SI-31 zmB>P|Z)lUu?A(1&MvC)}4r->Px|W+2>2MbLT66mtWr)IDWn+9p55Jhy4MvnWBN=uGr+-pe&ES*Ga7n?~Azeo#28&1mLc=Y}1;>1@^uveVWa zgK%s}b0^8A4JBBcV$c@N+YkeBj%FCB9F4F$!?T;va37>!7Zv@o>PpEdTASoWI@KA_ z9^(wZW%k!O`)22k;2Z*-JAVsK5_mRNNP>|5HAoJMGl`)ImDyB2KiB?nnt%HH!+~e^ z4Y`=2z(f<>;Kzbd+m8iNY))Hpip~CoAnKGq}k!X(GfNw6j%AHH?T)pBI=!;2gBs)pLmr5P`9$P(-o!oGre zPrOY}{o<`O_v1Ddo25!yvy?@V-NJ-O!fi!X*Z+DK;h-MNn@8#?!#?@<*^ql}$k`K9 zPyf0%GW^a@{hEi@EQ7a$c?wx<=JYuoOJng?y(OhN&7axnT$-W{lZKNUc-~E^Q2L!! z4}C|67Im+j+QlomeltIwi>;oS9*zYSfeEZlz0c%S@D@xe+eM1xG*!f_;?w5LRI}eA z*_BVoqNPpLYA6A`Buo2D^$&Pb3mS?Os9a3jUnj(8(|<~i7Uw6@lLXVd*uLc|n!lbz zpHxaMi}x(2m$FOZ$?on{H@{{eR{Ej54XlG_ut z^Y%Yjb7avV`!`OeK~qZ>{8pIX5N2$L$?7%@3%?$e#TvZ~%|6nL)ENT8?S;=Dow6v| zsy^;Rzh=XYi)!r|Kc=E8ewHB_o7Toh{S`~c`lo&Q)3>H#YI{#B{UkDDy;CpVWN9`` zw4TtFXid(c1!sRblYX%krQ$=c783K@mqz)WOlt>iXjboFsBkPuacWwc|AVDL4503` z$X6hWF*AK!ReIVTNz9l7;iN%(AR{_^&PB~(d#Xo$jzWETNq0fDmHv%$I!`$8?#K3K)L~=*^cY z8OL;)FDWwqFwjq@dk&0ax~>vDoURU_{|d-?7vQ%5-Us-0z*hi{^mhRMb)f&K;B3!h zfZq@F?B}8K{6(OD9O!of{Ud;XAMmdM{w&~~B;VxwF92t~`{_T2-wDok4uG7$0{(Wu zOW5%gnEnaCj|Uv-&jK9j#{rJz@N&WV@+iok1~}`UNB=oY2mBjA9|!zNz!w9K{_GN* zWq%XsZvy(S0=@=t_UCC7$6+1Fc^c?90R0ZYKL$9KhfN@d%Yezp2Z8=6z`p`Gr=d+* z<9X&BERIJ1JP-6A0Xe@1oX-?7?c44t@_*H_l53pRl8|X2;?*$yw`w74?y$=G8>3th3q`?09AlNej@DBri1>hS1 zZvlKE;BmnD^m5~e#ehEuc#q(G;kL`rzaQvP{-*#>0{wQt(f>ODNB@6caK51bUjlm6 z`!B#TT_fTNxDfTNvlfd3TabP3L8@z-RH-);wbwEx3^^VhEp z{SLra0{#QQv0d5?IJQf_103to9|6aD^djJ!K<^1hus5|o(f%_4ZwC5n0KXgX1Ay~a znN51jjtu1Q0sLvek^Ucm{|e}j8Ls89|9=g5rQlp1egpU%z?TBv3-}iRe;?q>0N)Ha z)}sdmXM27N^p7~`p9FgDTaACd1@xRn=6sReK>vH7zw{^~q7ZIRW&-{ppr0=|+xZ8; zw*ft->rtS`_Th&P`kw(k`eCnw{s7RUAN~&X=!YXlsN||~1^VH5!PyUJ|G7Z_0;KmU zpzi@Z<-oTCj_vm2fMdJ;lmq{<;OzfDg5D$Fq|+6)f280{kN!W$L4N_zqyH~<&`$w+ z^#7GWkN$rL(4+s8K#%^v3Gf>sy`Kjh{r{8$A1MQja5+B_aP4#`{o4S)3FKc6_yWM20slGR zw*$`Q;nUhY?<0bio7yul{hr2-z+W#BC(a$H!$NM>5zl8ic7w{JW zZvh>2OQITx*Y7lcJkVS>Bp-acpUJ0puf?9e^_w#|3RRi zDF@?(^F0nY_WSPw{7#Vb0l;ybc{kuV&ir@?XS+B&0XWW^b^?Bg^h$H*{T6VXH@yrv z&YS)TIIg#Na-I?U0mrvT1O6{a?-;;w{C@%9IR38@oYRTr^E#l%^tJ(x>0JpprguHy znBHUL+@)~-o&-47>vI9edR+}TmfJ~y<9uoc;9J3Oa|92!106t*@>c_n?Z8I?NB@5Y zaP?dO19~2Zm~-PE0eT#tpDE{^ae8sQS^+rr z7gGgiJO2Rbx*O;*U7rAYoTqGa&_4?F=!b7R=zj?G=!c&IJ^EoU(4!w-270vrO>*uV zrx)jmHG;F>a9;3s2mVpO(a-k*j_vjq2mY|&Y!A*8UjTZv|Ia{={y$OLm>9{qm>(4#%q1AZfvw+{f0{@>!j{|q?#{~+M#|5qINv2xxY z`v>QValymoq0fQyIp-Y0^=>ENXwUZ@_)i39dvKok2cSoPz6kVK9)`)mR^jq+4B$6` z|HlBn0PqQb4<%uy-|Pe&=SO@VI|sHO=ZR}W^k#naA)v?k(We2&`O#MZ$N9w*ApaP! z^Le2EGo%f-_&i+4G64b|v@<2Z3`y{}z-){!|PLT61z;T?}2RM#1Zw}!y{PrFYob9|0Eo^{+tQ) zr+}Py06qG%9q7@Y%K?7~{P01*(Vrg&`RJc5fTKUZ3^>yN8srb9v|Xp&<^2KZc`t$K z@BRezje!3ZaFlaM@bgIS44@x+j#k99GXZ~--~@T!0Y8)i{%ydu6q?J@4ewJjL52fr z98w4Lrd~4XWq@BQjBL*pfL965^bLSl0Nx0Az2Gc|&ssKqJKsS+4(Q(w^wof4K8^*v z1?Z=MeC~fQk>@6$$Nsl9M4y)D#Xyh!?@GY2|NRi)*nfRRaQ54^VCPR9_)89a6!CHh z%c*wYQv_%KWBb6q<-qv$bZ_#7`(h4Z`R{k&+}0U-Y)^R2#NctdH}Zc1IJPJMBRJcG z?KAheMot3coFO>VV|y|V=&?PS1oW8RYk(fxlO)h%`+)m@upGYILH}{Uu{>-69Ob`F zCs+9&%WaL|oL(%qrhc(FrZ?pl%Q=?Y`5*_&Z8zX(=S_fP`MCpd^yhy8j&e--XZta| z13-`d{0`tqkL}nTC=VA3J^KOiM!;tRz3~In^IkzyK4rUs^8X^h&H5SBw*xM(D;51> z!VR4Z$M&`p>>u<4+LH!)8TP9B+XuKzUz9z)fY*wAwtq6<<$x~-+|aWyA-PN+kyUY<*@yCft&`AkM>** zINB2j9R0&>4hNRM5#*ykZvb4DTU2^KO1P;n@)|G;FIUpFAC`a|l>c$S%Y>foan+;y zfL>lJDZQTpT$WLD;x_|5*3&J3qx}B@9Ob)kl#le-j+t`K_Y zpvU%MCE(|P-unPY`Y!^0Hqd`n@Nhjvd)^H6h>r#w{W%tJ%-?eX9}o7N2RODrzW_hr zyav}9CW4%|ft<@BUA%^8{E709037Axyt`QW*#BaAM)_FY3ZZwEbCmN=@B`-i62P&X zJPiK14*dKBpsxV`3?Uj01bH~Wcr)Nppg$dOoL`vv5tlcdU+~8b(xse&{8MSwR8&hjn>9LG5XdnP^a5_jeP%oYc$p9|ZhphUkZG?N zzn}j|F!h(A&jDT|@eFkVUI+NQ0Ivs}*S$?>0{l3@=K@{__&mVPoSLCUfDZ@yF2LUe zcpu%0le7q_Dhh{1akfg z_*}q?EpN|*oGy^_-+=c4z8CP7fV;}ur-6Pw(C-6$BjB#`_7|YX^7bO&TR~2-u^gJ;))h*B1(aLE!}9AL@*9BO=x2H!Uxh<1IadOGA##}f zq;oPgu>3auBcV*LOl#(P4At=;3XB_H@$)?XLxFMrZ^BBsF}N8AYyw=id@5uB@X>P5 zmpyXNa?F~Bg2ZOVjcmrt054-eLLJ~^3`kcVBXM9k}j=oUes=sdryaMnlz@vb-0A2}r8gMhm;ph#3R{{Mtz$XB{ z3-D^dUk2RFO*ncK51=S;x@y#&{!;~bE#UaOMKiYK=rqt@0`waIH*;Z*-Uj$(K)(xc zGZ*9NmjSN>`cblg#r97EybAEifVTi%4|p1Iv$n?38vwr&=(hnr9q?U%Hv;}L;ARbw zqyGi?OrRePzrULWcn#o9fX@Z|?SS_IJ{$0jfSWNtM{ftb1?YDJJ_qoFfL{gpXlZ0Q zU#i|CpxS8W{^l0e}*#0=s*8n~b z@VS5|0Ph2QKHwVxZv}ii;BA2K20RJ)LBJOPJ{o?1w-E3ez&UNk*OLHm2l_U^ZvgyO zz*)}o61NU;mSg(wt$;IqQrhCd5YB7;9DWKo%PC`!!Xdy}4$o;hoHjyV`H}z67W|SB zzD)3IL-=O}zX|XjEmHlx2XH2RQs^HAJPq{E0p1JvA;4M0w?)n{neg)?r`NR6X9Lc0 z^Q9d(zY{d{Qz?!^V~GAaX*WAU_y}otdI4v>rY%?xIO}K<`mG^+so;Yle6!#OLijU+ zm&%I+md*cvDR@N)|C`_~A$)6 zmqYkw!AD6tOu8Nr{B*!MU8byG0yy(bJwYcp1~}8-qG7KMaHfB3l#aMHgzp#J{4S4a zSK!WxD3 zA^N4V;Jqz`?~wi9=680+o^n~}Js6^|J6+2!k$h%)_Rj_ldu4!gT)9j#@b`C2|4E^* z579p>laECqd{micSQEl$3%(_U&lh}W2;U$${w|O0Y%8Zf6pofj6l47VHo@NvINSe4 z`p=;TaHijUmV&)WfHVDfHSDzkzEm*2tO0x(;12-a2lyc1%K<+C_>F*gN{7%3R0{%h3M@xId_J0WQ8o)OIZrVSlzYFj_puZdNjevg`@a=$a1bjE(9|8Oz z;2#Biw6u$C&&L3-0sJ1o=K}t5!21AaSx=s=BR7U{e_d!?&+;Yd#C&fYodcw=i_Bej zvLi8$J|>s;#_<_G-njWaJ>IzPlz!ldaq(+9mo1?WfGRS2YU^lP+8ie$W@S3QBNm^a zIi2XF??qNFNiLzI?c%BKwj_N#v64P6i3lB*-qucsOn3WyS)UE8noNfjMXMWA3oEB} zq*C28Q=Qi&yHl|nM7fwpAIhsvq*HWONke;#J_p(EmS{izrm{jEwR2U1P9aK)M7euiN5K|Cupg!H-`Dc$qlqt zsZ)pb7cuED^NBO``LraDGNb5EFJ^p0+375&_GtB-&Yr}ABpo+2RUgcKn0AERS8(#_ zn2%(7W=i?wFjddyubKNv&&oJ=+AHWh7Ev91nlyK*bqlMKe0+6jIczsp(V?g5?$q-C zkosD6E__QWwxlcls%>ypd8hL$D|IQJomeLIDn+ePvKw;M$Sk~g)HaxNln=999)4cx zgVz1yo3V}`UMt~^TS&({C;M8HUFkS=V;xEAjI#O+r+=eWuY*N?_gR!FmC;O7UTt}Q zRepJ`jX6A*MCEK|{=o68YsBd!$eKOY_oyjZZPC>Iw#`V&q-3y)q47goUsiRy9}oU52Me&nd)$6$r} zJnXFK1T}W1G@4;^$ZL5A(SCMjiLQYYFn#HVdH7|%p}gCQ3hicZ)+RXxvW!@ z9qmiFfl)SuN9j360~J9NH=YV&;WZ17faVj4c`i~|ot(%`Ve^zJTneM{Xq0Xn=)>@n z6Fppk3X@S;HLJ6EQE$2}wX9QygmRJ~jbd`t=&aL63u#-!Czk5=wU90~OI;yNb6A~! zU|w$DWa%%!@=XQoUk)eRXY)A_zh(2lV;ejEGa{Cb+)tcoC_jw1E6Vx=O zGtof@crQrM885Wf&_hc^w89bY=`+vF%Q!Y+{LJLCqUp0wW;Q1^Wx70vUX}2m8D$gv zX_!0Fs^3>5shO#(+Pl-e2|flVQ)vb_oFH-d4g(@b-k_K?Oo|qw|^Q=vb%s*sE{6~fELOZgM*Q5^|XMwgvRUfu0(q`A59iBhn3MN zm`|u_OSUGK$LUa&cn_U2-$e&Z#j5EDBp%Suq`6`PpEYHG*ep6}dRB9Fs80>4m|dKX z@mV^mNXNvSI;Izy4z~`I$EqlEHtm+@BP#C8(a&^$R#vC$e6OXnrgf<5a|QL)&BrHPJS z>I>z-v)RPZ+!!hy?q#mm{rI@Yy7X0xk@H7ijhxIwM_-Mk@cE+|vSpFNLTHo?)0{r~WRwpRZiR?#CjtBrj+O^5%IFjN*Aa+U?qSY(k2 z$;~PY zq`rB`-|vv0xA<2Vf4znO;v)E)Ec}-i!Eb)+hW1}p1phqIFF!|7>3@*0Let-2v43(A z`qLKu{5`lr^{=$(pIQXJ+4GJ57P>s{{ag>fA71{^dA)d zQn_AFybVS04<}j<$j{&DEmZ$#;m7jJzrie&|7_vM`nRA6{_`#R`FnST>aVfze}Vi_ zC_lF~9OP#es{Pzb&xP{O6@E-Ve@CTI{&^OD{=QG4{EIC7{GF0Q`OP<9F#mgs;O8?X zIAHpFi{QW2!oRc#e*T6g2ef}#5&ZmZ%P>EGFSStrZMN{=SOou83qSj`Q2mcu`1zY< zh4SyT@bmX63+3Ns;a^zp`$Z}cg{EKq2$ATq{ryrA z{H6ROB?_2+{tj!Q`uUrHVScU?h4S+^)x!K=CZJG${>ELH|IQ-x*ID>C6v5Bm<`3(? zy9oZd7XA+x!QW=#-$n)%>Ob?{aqNG-QUw34q94mIe}}A4{kL1}-&6$uMhicGcdStT zn=Sm@rWVS-)xyu;^(vJAQQ=4beWnQh9TxqcErNg0!q49cEY$wzEd2aE!9w}>TKFF* zg8yaVNB@1k2>wGB{SOwwKU}_hf$irPir^n*;paZNQ2&)#_`g^L|M|j?{;Mm3zsjQj zp(5IkIt%~9MesLT__r6qKi9&~V}e5c-)7RSJyDD{d~Seq54}a z`uV%=h4No(;paI`q5N$^h~?IbosvTP^ze`{jl5Z@1{@?}r!4zr&)R&kHP+{}~HEpO054zxl2u zmcPe~sQ-IJ5%MRBsDJw{{QSNALhV0j;XhP_{-N?6H?;ppMevte`1#y`LhV0I__6%+ z_mB(aKii@|UWEM>7XAEvSoHIE>hV$uxWrq1T34aF?(|uX!IZDqgGn_8NzcdsP=C2ig zKH~(#i5KW6`7D?p6}JBhieW6wKUVnVGj>k?cM5+v{WZdG{A~n;pRb|_TmJ2p7icD* zIR9=TTElPfMWR1!f1T(z{lC#4PX8tce~a+TXUPn^@|FKUH@hADi-i9yB&PdNHhDiH zOr<{@ag?^yq?6OXnrOr6e~B=r45$Bg(SJF`VF;_?vzu)E&j|m8$V~TP{!572X8&l5 z{cDInY(KwKu<1V}`p?dz{}Bg&**MK8pBM9`ur3Tdr?cs=7XGP7O!wjR^O*#;^jBEY ze>?Gq(_cXXZTfE%{gd+O=Wq4f^w(ST-(k`JphN$oqW_dU`Y)u4Z?ped;h&X<|2*Qi z**{P0uMmDN|NOnZu>bCN=zoh8-0!Cxc%+`eK6^S|VgrvF$ec#nh>h9133iQne`1Csvj!ocPC9!vUnivA%X z!83irl`}Ye!_fHr?YP@TR-)8@oqqU|oQONe+OM=4XcaP`~+rMMH z)@u4MV}pn@k6t$kWGvi&JtzG94Ok3e`E&HkOoXif8kneG21-G}Xe$)P`1r5VHJ zFKqvLN7?Of7XEzWuXBjsX8+h@wI*!;K5enT&!K;T=s#J~Z!Tf~^*Hp;75ygv*ngk3 z=-=Ydzp_C6pK|E$vgp6xqJOtT|3^hXkMA*r)Bhuf{xuf=e~tu&%TI*9Q_eXRF24h! ze_6M2mhe(pOc4wse}J-1?qp;!9Q$*R(woIf4KaAiTG{hce^G3wvw!{|NhsZ z|9H_apQZJ!2>Y*rzE^Ma|5)MA=l{DM{58U#&;NH4zb*ZPmh^A4r2lQSz+$uideL9! zr(EBJ)BhIYx9Q(&DZl*wG3@`_9Qr>Y`t!{nZgJ=zJyMqxY`?Z!^dC(H%$ELNivIFE z=|7VAZRxMK=;!xe;q<@Hq2H_4iqFcU|Gf_VeWD-RPkw(A*8i+S|JkBnF1{7v{QrSN z|9Xplet!|xe;jpiHveBEietWJeG}GyH1XT~zr~_|z@mS;L;t;^za^w!m#P4q=FmT2 z$^R!U`aj^%{}<68uK!{E?|0}wV9~$BqJPk#fAmD1#uJ02s=KiNhf)J)%fE5L&+B6t z!u+o|>@O?TDaG>pGzkiqpYftUJpOAC{aiLMg#Fj!uz#lTzZIG3K5Ty{@!QH@jm7?N z6MxwL&pGrj75(|f51(=9Z?for#-jgs4*mBOsDF<`|00Y2?^*OuEVY-PCq@4<;=vI1 zKc9bM^Z!cGUoXr&ejKFxu>U{e(0@^lX3VF5gG2vLi~b*4^bes00$ct0lIUL`_M1yM z{r__4FFj6|bWHy)i~d;-{i9{!frb|uAzXj1Bz~L!=Zb!;zt39qf5xHzY|(#ihW70G zcb`Llm*}q$e$M~h7X3eP=$~1j{%0KeH(B)m%%cC0Lw}#>&sYEd?$AGI(f^!9e>qJM zZRPJ1qW?VcpSgs~-#Z=rJB6Qy2N@w;ey$>ZTlw*h*OXX(o+nA+`g@;4|Ffds@Eaq- z_TS^sKiZ=IR~G$0aOnS&=$B)3jQXtp;~9tk3XA^VSoEJvF9>Y;cl1SCWj_6*h~MV_ zdW-(wS@h3x=s!>NQ}>V&!v4R*!Cx!<`N~hf!~S^|`}bPx|Di+wG|`{0{CwA;zt5uo zj~4y>10!4hU0-1S{nMd;y+!|ii~ea2{Wle;e-iQA%Fh;y{y$mt-{{c)QPH2T{55=rN7mozfAOF`u}dxzghH${d$?`e?gn!|JAATAH9bh z_K&?p)0`BLs=KhBUkE?FhRFzZ!e5ht2EPX~FrSB{{BHocHd)gDPl^lY|4R=2D@8vI z4>Lme`M(|dS6cM{%c6e-O%QGE*Lu-U#XBQ}{WpyGZRKyPrTo2O(SNl=|7OvjZ~i&k zp?{}Ee+eZt?EgGkBmA=iQgs*R{{`{e{6A<(Kflrnr~hjw z+wHHsOe@Y;{~jWKoBq*n)|QfaDscJZC9Saj`cv%sXNvwo;WwAC|ECbYO@D>x?-NGW z&r_H>$OZ>L_!pZqJ+M<7jL;vSQalZDe&!NAJ6H8&9 z`s=Ch2b^Nj|Dr?x-wV|LM~D8E7X7DL^j~wj-TzbSwBh0QOQ%W_MVGrA{BJLif0u)Q zp72i!RH?gg{rNue+wy;pq#wtRWtQ|Ga_GOWK>IJD2{!vA-2ZJA{(SaNBz~Lyr6;je zItN<))#c|bi~UK5{y*1g#(eqr83(^7hRZUBSdl$`xzAyLo!F1<_ggIXf5)M}R`lny z|DrSP{;wB)8s27vaQXSEga3Nr{}I`YA|A0k* zl|_FUIhf$A_UmEMZ^l2y2&TnwD)HO=Km24(xkZS%{8!WeaQUC(&|fiCGv=$m2ORt{ z;g6!RbRV{VpTqvGVn3GOT8sUcoMrdlQqiBU{@(52zg76Dd&&r5`|l+Fp+r$PB!kS` zBlctYh|L=C_zfbg&don^;f7RLc^nas3{tr3$e=qzryvzupWO{cH|4^a`r~jZO z{dJb~m(dG$PE)x5E|HA~Vg2FspGy2T{iQtEqk#VB@8^a6{}G4&(+bqT!J&VwMgLTb z{;AZ!v!#)cV{1hJZk3AQkFnn%mlMA&{dJ<>e8+_AKYu^Z@EgDMI`o%L(;D*W?{eth z%7a}BsK4H#e~Ux^UeOE?W>Z9fcMHGqlM!S5 zXP&1Mzs>%YVt>65a`|hr*ngAg5BvXs=nvQbus^p5f7t#~QJl~IPZ7V({+$;4n=SS~ z>#)B<^oRS8u>C{n1v~dq5#vy~HVOam5N@8$^_8(=e~7NMjEtpV($D_C%3}YUNk3DD z{WrH>vHSH!KLz#2JeLx`&3|Jp`sZ5oPZa&8o*KFHM1R Date: Fri, 14 Dec 2018 16:06:15 -0800 Subject: [PATCH 0565/2143] more nullability annotation --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index d4d16024fa0..404d4b76568 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -282,7 +282,7 @@ NS_ASSUME_NONNULL_END */ @interface GRPCCall : GRXWriter -- (nullable instancetype)init NS_UNAVAILABLE; +- (instancetype)init NS_UNAVAILABLE; /** * The container of the request headers of an RPC conforms to this protocol, which is a subset of diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index b7f08480dc0..b866f268ee1 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -18,6 +18,8 @@ #import +NS_ASSUME_NONNULL_BEGIN + /** * Safety remark of a gRPC method as defined in RFC 2616 Section 9.1 */ @@ -66,7 +68,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)provideTokenToHandler:(void (^_Nullable)(NSString *_Nullable token))handler; +- (void)provideTokenToHandler:(void (^)(NSString *_Nullable token))handler; /** * This method is deprecated. Please use \a provideTokenToHandler. @@ -74,7 +76,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)getTokenWithHandler:(void (^_Nullable)(NSString *_Nullable token))handler; +- (void)getTokenWithHandler:(void (^)(NSString *_Nullable token))handler; @end @@ -210,7 +212,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * Return if the channel options are equal to another object. */ -- (BOOL)hasChannelOptionsEqualTo:(nonnull GRPCCallOptions *)callOptions; +- (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions; /** * Hash for channel options. @@ -352,3 +354,5 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { @property(readwrite) NSUInteger channelID; @end + +NS_ASSUME_NONNULL_END From b90652ab0329e67697e71282b785187a4d1cb223 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Dec 2018 16:07:20 -0800 Subject: [PATCH 0566/2143] remove debug information --- src/core/lib/iomgr/cfstream_handle.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index bb402f96cf5..6cb9ca1a0d4 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -79,7 +79,6 @@ void CFStreamHandle::WriteCallback(CFWriteStreamRef stream, void* clientCallBackInfo) { grpc_core::ExecCtx exec_ctx; CFStreamHandle* handle = static_cast(clientCallBackInfo); - printf("** CFStreamHandle::WriteCallback\n"); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_DEBUG, "CFStream WriteCallback (%p, %p, %lu, %p)", handle, stream, type, clientCallBackInfo); From c097e21259db28d8b80ed661c0c0e3d808466ed1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Dec 2018 17:55:11 -0800 Subject: [PATCH 0567/2143] Nullability annotation fix --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 404d4b76568..15b1c904498 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -282,7 +282,7 @@ NS_ASSUME_NONNULL_END */ @interface GRPCCall : GRXWriter -- (instancetype)init NS_UNAVAILABLE; +- (nonnull instancetype)init NS_UNAVAILABLE; /** * The container of the request headers of an RPC conforms to this protocol, which is a subset of From 0531d3d3adfd12e1d9aeaa49fb19096b4c1fb5d9 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Sun, 16 Dec 2018 14:50:26 -0800 Subject: [PATCH 0568/2143] extend local credentials to support tcp loopback --- CMakeLists.txt | 98 +- Makefile | 92 +- build.yaml | 2 + gRPC-Core.podspec | 2 + grpc.gyp | 2 + include/grpc/grpc_security_constants.h | 6 +- .../lib/http/httpcli_security_connector.cc | 2 +- .../alts/alts_security_connector.cc | 10 +- .../fake/fake_security_connector.cc | 7 +- .../local/local_security_connector.cc | 103 +- .../security_connector/security_connector.h | 3 +- .../ssl/ssl_security_connector.cc | 4 +- .../security/transport/security_handshaker.cc | 3 +- test/core/end2end/BUILD | 13 + test/core/end2end/fixtures/h2_local_ipv4.cc | 72 + test/core/end2end/fixtures/h2_local_ipv6.cc | 72 + test/core/end2end/fixtures/h2_local_uds.cc | 71 + .../fixtures/{h2_local.cc => local_util.cc} | 84 +- test/core/end2end/fixtures/local_util.h | 41 + test/core/end2end/gen_build_yaml.py | 4 +- test/core/end2end/generate_tests.bzl | 6 +- .../generated/sources_and_headers.json | 43 +- tools/run_tests/generated/tests.json | 3600 ++++++++++++++++- 23 files changed, 4131 insertions(+), 209 deletions(-) create mode 100644 test/core/end2end/fixtures/h2_local_ipv4.cc create mode 100644 test/core/end2end/fixtures/h2_local_ipv6.cc create mode 100644 test/core/end2end/fixtures/h2_local_uds.cc rename test/core/end2end/fixtures/{h2_local.cc => local_util.cc} (61%) create mode 100644 test/core/end2end/fixtures/local_util.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e296eaee734..b6ceb50a5f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -456,7 +456,13 @@ add_dependencies(buildtests_c h2_full+trace_test) add_dependencies(buildtests_c h2_full+workarounds_test) add_dependencies(buildtests_c h2_http_proxy_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_dependencies(buildtests_c h2_local_test) +add_dependencies(buildtests_c h2_local_ipv4_test) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c h2_local_ipv6_test) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c h2_local_uds_test) endif() add_dependencies(buildtests_c h2_oauth2_test) add_dependencies(buildtests_c h2_proxy_test) @@ -1784,6 +1790,7 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc test/core/end2end/cq_verifier.cc test/core/end2end/fixtures/http_proxy_fixture.cc + test/core/end2end/fixtures/local_util.cc test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc @@ -2104,6 +2111,7 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc test/core/end2end/cq_verifier.cc test/core/end2end/fixtures/http_proxy_fixture.cc + test/core/end2end/fixtures/local_util.cc test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc @@ -17028,12 +17036,12 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_executable(h2_local_test - test/core/end2end/fixtures/h2_local.cc +add_executable(h2_local_ipv4_test + test/core/end2end/fixtures/h2_local_ipv4.cc ) -target_include_directories(h2_local_test +target_include_directories(h2_local_ipv4_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${_gRPC_SSL_INCLUDE_DIR} @@ -17046,7 +17054,7 @@ target_include_directories(h2_local_test PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) -target_link_libraries(h2_local_test +target_link_libraries(h2_local_ipv4_test ${_gRPC_ALLTARGETS_LIBRARIES} end2end_tests grpc_test_util @@ -17057,8 +17065,84 @@ target_link_libraries(h2_local_test # avoid dependency on libstdc++ if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(h2_local_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(h2_local_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + set_target_properties(h2_local_ipv4_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_local_ipv4_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(h2_local_ipv6_test + test/core/end2end/fixtures/h2_local_ipv6.cc +) + + +target_include_directories(h2_local_ipv6_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_local_ipv6_test + ${_gRPC_ALLTARGETS_LIBRARIES} + end2end_tests + grpc_test_util + grpc + gpr_test_util + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_local_ipv6_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_local_ipv6_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(h2_local_uds_test + test/core/end2end/fixtures/h2_local_uds.cc +) + + +target_include_directories(h2_local_uds_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_local_uds_test + ${_gRPC_ALLTARGETS_LIBRARIES} + end2end_tests + grpc_test_util + grpc + gpr_test_util + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_local_uds_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_local_uds_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) endif() endif() diff --git a/Makefile b/Makefile index 9cc4aeecc4d..7b4a1fb0d5e 100644 --- a/Makefile +++ b/Makefile @@ -1324,7 +1324,9 @@ h2_full+pipe_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_test h2_full+trace_test: $(BINDIR)/$(CONFIG)/h2_full+trace_test h2_full+workarounds_test: $(BINDIR)/$(CONFIG)/h2_full+workarounds_test h2_http_proxy_test: $(BINDIR)/$(CONFIG)/h2_http_proxy_test -h2_local_test: $(BINDIR)/$(CONFIG)/h2_local_test +h2_local_ipv4_test: $(BINDIR)/$(CONFIG)/h2_local_ipv4_test +h2_local_ipv6_test: $(BINDIR)/$(CONFIG)/h2_local_ipv6_test +h2_local_uds_test: $(BINDIR)/$(CONFIG)/h2_local_uds_test h2_oauth2_test: $(BINDIR)/$(CONFIG)/h2_oauth2_test h2_proxy_test: $(BINDIR)/$(CONFIG)/h2_proxy_test h2_sockpair_test: $(BINDIR)/$(CONFIG)/h2_sockpair_test @@ -1582,7 +1584,9 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/h2_full+trace_test \ $(BINDIR)/$(CONFIG)/h2_full+workarounds_test \ $(BINDIR)/$(CONFIG)/h2_http_proxy_test \ - $(BINDIR)/$(CONFIG)/h2_local_test \ + $(BINDIR)/$(CONFIG)/h2_local_ipv4_test \ + $(BINDIR)/$(CONFIG)/h2_local_ipv6_test \ + $(BINDIR)/$(CONFIG)/h2_local_uds_test \ $(BINDIR)/$(CONFIG)/h2_oauth2_test \ $(BINDIR)/$(CONFIG)/h2_proxy_test \ $(BINDIR)/$(CONFIG)/h2_sockpair_test \ @@ -4268,6 +4272,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ test/core/end2end/cq_verifier.cc \ test/core/end2end/fixtures/http_proxy_fixture.cc \ + test/core/end2end/fixtures/local_util.cc \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ @@ -4574,6 +4579,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ test/core/end2end/cq_verifier.cc \ test/core/end2end/fixtures/http_proxy_fixture.cc \ + test/core/end2end/fixtures/local_util.cc \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ @@ -23711,34 +23717,98 @@ endif endif -H2_LOCAL_TEST_SRC = \ - test/core/end2end/fixtures/h2_local.cc \ +H2_LOCAL_IPV4_TEST_SRC = \ + test/core/end2end/fixtures/h2_local_ipv4.cc \ -H2_LOCAL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_TEST_SRC)))) +H2_LOCAL_IPV4_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_IPV4_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/h2_local_test: openssl_dep_error +$(BINDIR)/$(CONFIG)/h2_local_ipv4_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/h2_local_test: $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_local_ipv4_test: $(H2_LOCAL_IPV4_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_test + $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_IPV4_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_ipv4_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local_ipv4.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_h2_local_test: $(H2_LOCAL_TEST_OBJS:.o=.dep) +deps_h2_local_ipv4_test: $(H2_LOCAL_IPV4_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(H2_LOCAL_TEST_OBJS:.o=.dep) +-include $(H2_LOCAL_IPV4_TEST_OBJS:.o=.dep) +endif +endif + + +H2_LOCAL_IPV6_TEST_SRC = \ + test/core/end2end/fixtures/h2_local_ipv6.cc \ + +H2_LOCAL_IPV6_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_IPV6_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/h2_local_ipv6_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/h2_local_ipv6_test: $(H2_LOCAL_IPV6_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_IPV6_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_ipv6_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local_ipv6.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_h2_local_ipv6_test: $(H2_LOCAL_IPV6_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(H2_LOCAL_IPV6_TEST_OBJS:.o=.dep) +endif +endif + + +H2_LOCAL_UDS_TEST_SRC = \ + test/core/end2end/fixtures/h2_local_uds.cc \ + +H2_LOCAL_UDS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_UDS_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/h2_local_uds_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/h2_local_uds_test: $(H2_LOCAL_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_uds_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_h2_local_uds_test: $(H2_LOCAL_UDS_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(H2_LOCAL_UDS_TEST_OBJS:.o=.dep) endif endif diff --git a/build.yaml b/build.yaml index 5f4d554a467..7f1f11a3c03 100644 --- a/build.yaml +++ b/build.yaml @@ -900,6 +900,7 @@ filegroups: - src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h - test/core/end2end/cq_verifier.h - test/core/end2end/fixtures/http_proxy_fixture.h + - test/core/end2end/fixtures/local_util.h - test/core/end2end/fixtures/proxy.h - test/core/iomgr/endpoint_tests.h - test/core/util/debugger_macros.h @@ -920,6 +921,7 @@ filegroups: - src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc - test/core/end2end/cq_verifier.cc - test/core/end2end/fixtures/http_proxy_fixture.cc + - test/core/end2end/fixtures/local_util.cc - test/core/end2end/fixtures/proxy.cc - test/core/iomgr/endpoint_tests.cc - test/core/util/debugger_macros.cc diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 5ab7a49cd27..4826044a3d7 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1207,6 +1207,7 @@ Pod::Spec.new do |s| 'test/core/security/oauth2_utils.cc', 'test/core/end2end/cq_verifier.cc', 'test/core/end2end/fixtures/http_proxy_fixture.cc', + 'test/core/end2end/fixtures/local_util.cc', 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', @@ -1233,6 +1234,7 @@ Pod::Spec.new do |s| 'test/core/security/oauth2_utils.h', 'test/core/end2end/cq_verifier.h', 'test/core/end2end/fixtures/http_proxy_fixture.h', + 'test/core/end2end/fixtures/local_util.h', 'test/core/end2end/fixtures/proxy.h', 'test/core/iomgr/endpoint_tests.h', 'test/core/util/debugger_macros.h', diff --git a/grpc.gyp b/grpc.gyp index 00f06a1e54e..32d4bd409e6 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -617,6 +617,7 @@ 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', 'test/core/end2end/cq_verifier.cc', 'test/core/end2end/fixtures/http_proxy_fixture.cc', + 'test/core/end2end/fixtures/local_util.cc', 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', @@ -857,6 +858,7 @@ 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', 'test/core/end2end/cq_verifier.cc', 'test/core/end2end/fixtures/http_proxy_fixture.cc', + 'test/core/end2end/fixtures/local_util.cc', 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h index f935557f2d4..a082f670107 100644 --- a/include/grpc/grpc_security_constants.h +++ b/include/grpc/grpc_security_constants.h @@ -106,10 +106,10 @@ typedef enum { } grpc_ssl_client_certificate_request_type; /** - * Type of local connection for which local channel/server credentials will be - * applied. It only supports UDS for now. + * Type of local connections for which local channel/server credentials will be + * applied. It supports UDS and local TCP connections. */ -typedef enum { UDS = 0 } grpc_local_connect_type; +typedef enum { UDS = 0, LOCAL_TCP } grpc_local_connect_type; #ifdef __cplusplus } diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 6802851392c..fdea7511cca 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -85,7 +85,7 @@ class grpc_httpcli_ssl_channel_security_connector final return handshaker_factory_; } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* /*auth_context*/, grpc_closure* on_peer_checked) override { grpc_error* error = GRPC_ERROR_NONE; 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 6db70ef1720..3ad0cc353cb 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 @@ -48,7 +48,7 @@ void alts_set_rpc_protocol_versions( GRPC_PROTOCOL_VERSION_MIN_MINOR); } -void atls_check_peer(tsi_peer peer, +void alts_check_peer(tsi_peer peer, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) { *auth_context = @@ -93,10 +93,10 @@ class grpc_alts_channel_security_connector final handshake_manager, grpc_security_handshaker_create(handshaker, this)); } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { - atls_check_peer(peer, auth_context, on_peer_checked); + alts_check_peer(peer, auth_context, on_peer_checked); } int cmp(const grpc_security_connector* other_sc) const override { @@ -151,10 +151,10 @@ class grpc_alts_server_security_connector final handshake_manager, grpc_security_handshaker_create(handshaker, this)); } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { - atls_check_peer(peer, auth_context, on_peer_checked); + alts_check_peer(peer, auth_context, on_peer_checked); } int cmp(const grpc_security_connector* other) const override { 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 d2cdaaac77c..e3b8affb360 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 @@ -71,7 +71,7 @@ class grpc_fake_channel_security_connector final if (target_name_override_ != nullptr) gpr_free(target_name_override_); } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override; @@ -250,7 +250,8 @@ end: } void grpc_fake_channel_security_connector::check_peer( - tsi_peer peer, grpc_core::RefCountedPtr* auth_context, + tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) { fake_check_peer(this, peer, auth_context, on_peer_checked); fake_secure_name_check(); @@ -265,7 +266,7 @@ class grpc_fake_server_security_connector std::move(server_creds)) {} ~grpc_fake_server_security_connector() override = default; - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { fake_check_peer(this, peer, auth_context, on_peer_checked); 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 7a59e54e9a7..7cc482c16c5 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 @@ -32,12 +32,16 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/socket_utils.h" +#include "src/core/lib/iomgr/unix_sockets_posix.h" #include "src/core/lib/security/credentials/local/local_credentials.h" #include "src/core/lib/security/transport/security_handshaker.h" #include "src/core/tsi/local_transport_security.h" #define GRPC_UDS_URI_PATTERN "unix:" -#define GRPC_UDS_URL_SCHEME "unix" #define GRPC_LOCAL_TRANSPORT_SECURITY_TYPE "local" namespace { @@ -55,18 +59,59 @@ grpc_core::RefCountedPtr local_auth_context_create() { } void local_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, - grpc_closure* on_peer_checked) { + grpc_closure* on_peer_checked, + grpc_local_connect_type type) { + int fd = grpc_endpoint_get_fd(ep); + grpc_resolved_address resolved_addr; + memset(&resolved_addr, 0, sizeof(resolved_addr)); + resolved_addr.len = GRPC_MAX_SOCKADDR_SIZE; + bool is_endpoint_local = false; + if (getsockname(fd, reinterpret_cast(resolved_addr.addr), + &resolved_addr.len) == 0) { + grpc_resolved_address addr_normalized; + grpc_resolved_address* addr = + grpc_sockaddr_is_v4mapped(&resolved_addr, &addr_normalized) + ? &addr_normalized + : &resolved_addr; + grpc_sockaddr* sock_addr = reinterpret_cast(&addr->addr); + // UDS + if (type == UDS && grpc_is_unix_socket(addr)) { + is_endpoint_local = true; + // IPV4 + } else if (type == LOCAL_TCP && sock_addr->sa_family == GRPC_AF_INET) { + const grpc_sockaddr_in* addr4 = + reinterpret_cast(sock_addr); + if (grpc_htonl(addr4->sin_addr.s_addr) == INADDR_LOOPBACK) { + is_endpoint_local = true; + } + // IPv6 + } else if (type == LOCAL_TCP && sock_addr->sa_family == GRPC_AF_INET6) { + const grpc_sockaddr_in6* addr6 = + reinterpret_cast(addr); + if (memcmp(&addr6->sin6_addr, &in6addr_loopback, + sizeof(in6addr_loopback)) == 0) { + is_endpoint_local = true; + } + } + } + grpc_error* error = GRPC_ERROR_NONE; + if (!is_endpoint_local) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Endpoint is neither UDS or TCP loopback address."); + GRPC_CLOSURE_SCHED(on_peer_checked, error); + return; + } /* Create an auth context which is necessary to pass the santiy check in - * {client, server}_auth_filter that verifies if the pepp's auth context is + * {client, server}_auth_filter that verifies if the peer's auth context is * obtained during handshakes. The auth context is only checked for its * existence and not actually used. */ *auth_context = local_auth_context_create(); - grpc_error* error = *auth_context != nullptr - ? GRPC_ERROR_NONE - : GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Could not create local auth context"); + error = *auth_context != nullptr ? GRPC_ERROR_NONE + : GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Could not create local auth context"); GRPC_CLOSURE_SCHED(on_peer_checked, error); } @@ -77,8 +122,7 @@ class grpc_local_channel_security_connector final grpc_core::RefCountedPtr channel_creds, grpc_core::RefCountedPtr request_metadata_creds, const char* target_name) - : grpc_channel_security_connector(GRPC_UDS_URL_SCHEME, - std::move(channel_creds), + : grpc_channel_security_connector(nullptr, std::move(channel_creds), std::move(request_metadata_creds)), target_name_(gpr_strdup(target_name)) {} @@ -102,10 +146,13 @@ class grpc_local_channel_security_connector final return strcmp(target_name_, other->target_name_); } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { - local_check_peer(this, peer, auth_context, on_peer_checked); + grpc_local_credentials* creds = + reinterpret_cast(mutable_channel_creds()); + local_check_peer(this, peer, ep, auth_context, on_peer_checked, + creds->connect_type()); } bool check_call_host(const char* host, grpc_auth_context* auth_context, @@ -134,8 +181,7 @@ class grpc_local_server_security_connector final public: grpc_local_server_security_connector( grpc_core::RefCountedPtr server_creds) - : grpc_server_security_connector(GRPC_UDS_URL_SCHEME, - std::move(server_creds)) {} + : grpc_server_security_connector(nullptr, std::move(server_creds)) {} ~grpc_local_server_security_connector() override = default; void add_handshakers(grpc_pollset_set* interested_parties, @@ -147,10 +193,13 @@ class grpc_local_server_security_connector final handshake_manager, grpc_security_handshaker_create(handshaker, this)); } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { - local_check_peer(this, peer, auth_context, on_peer_checked); + grpc_local_server_credentials* creds = + static_cast(mutable_server_creds()); + local_check_peer(this, peer, ep, auth_context, on_peer_checked, + creds->connect_type()); } int cmp(const grpc_security_connector* other) const override { @@ -171,23 +220,18 @@ grpc_local_channel_security_connector_create( "Invalid arguments to grpc_local_channel_security_connector_create()"); return nullptr; } - // Check if local_connect_type is UDS. Only UDS is supported for now. + // Perform sanity check on UDS address. For TCP local connection, the check + // will be done during check_peer procedure. grpc_local_credentials* creds = static_cast(channel_creds.get()); - if (creds->connect_type() != UDS) { - gpr_log(GPR_ERROR, - "Invalid local channel type to " - "grpc_local_channel_security_connector_create()"); - return nullptr; - } - // Check if target_name is a valid UDS address. 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); - if (strncmp(GRPC_UDS_URI_PATTERN, server_uri_str, + if (creds->connect_type() == UDS && + strncmp(GRPC_UDS_URI_PATTERN, server_uri_str, strlen(GRPC_UDS_URI_PATTERN)) != 0) { gpr_log(GPR_ERROR, - "Invalid target_name to " + "Invalid UDS target name to " "grpc_local_channel_security_connector_create()"); return nullptr; } @@ -204,15 +248,6 @@ grpc_local_server_security_connector_create( "Invalid arguments to grpc_local_server_security_connector_create()"); return nullptr; } - // Check if local_connect_type is UDS. Only UDS is supported for now. - const grpc_local_server_credentials* creds = - static_cast(server_creds.get()); - if (creds->connect_type() != UDS) { - gpr_log(GPR_ERROR, - "Invalid local server type to " - "grpc_local_server_security_connector_create()"); - return nullptr; - } return grpc_core::MakeRefCounted( std::move(server_creds)); } diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index d90aa8c4dab..74b0ef21a62 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.h @@ -56,7 +56,8 @@ class grpc_security_connector /* Check the peer. Callee takes ownership of the peer object. When done, sets *auth_context and invokes on_peer_checked. */ virtual void check_peer( - tsi_peer peer, grpc_core::RefCountedPtr* auth_context, + tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) GRPC_ABSTRACT; /* Compares two security connectors. */ 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 14b2c4030f2..7414ab1a37f 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 @@ -146,7 +146,7 @@ class grpc_ssl_channel_security_connector final grpc_security_handshaker_create(tsi_hs, this)); } - void check_peer(tsi_peer peer, + void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { const char* target_name = overridden_target_name_ != nullptr @@ -299,7 +299,7 @@ class grpc_ssl_server_security_connector grpc_security_handshaker_create(tsi_hs, this)); } - void check_peer(tsi_peer peer, + 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); diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index 48d6901e883..01831dab10f 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -231,7 +231,8 @@ static grpc_error* check_peer_locked(security_handshaker* h) { return grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Peer extraction failed"), result); } - h->connector->check_peer(peer, &h->auth_context, &h->on_peer_checked); + h->connector->check_peer(peer, h->args->endpoint, &h->auth_context, + &h->on_peer_checked); return GRPC_ERROR_NONE; } diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index 398e8a2d9ad..9d7f96683e0 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -70,6 +70,19 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "local_util", + srcs = ["fixtures/local_util.cc"], + hdrs = ["fixtures/local_util.h", + "end2end_tests.h"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "bad_server_response_test", srcs = ["bad_server_response_test.cc"], diff --git a/test/core/end2end/fixtures/h2_local_ipv4.cc b/test/core/end2end/fixtures/h2_local_ipv4.cc new file mode 100644 index 00000000000..f6996bf6be3 --- /dev/null +++ b/test/core/end2end/fixtures/h2_local_ipv4.cc @@ -0,0 +1,72 @@ +/* + * + * 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 + +#include "src/core/lib/gpr/host_port.h" +#include "test/core/end2end/end2end_tests.h" +#include "test/core/end2end/fixtures/local_util.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv4( + grpc_channel_args* client_args, grpc_channel_args* server_args) { + grpc_end2end_test_fixture f = + grpc_end2end_local_chttp2_create_fixture_fullstack(); + int port = grpc_pick_unused_port_or_die(); + gpr_join_host_port( + &static_cast(f.fixture_data) + ->localaddr, + "127.0.0.1", port); + return f; +} + +static void chttp2_init_client_fullstack_ipv4(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, LOCAL_TCP); +} + +static void chttp2_init_server_fullstack_ipv4(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, LOCAL_TCP); +} + +/* All test configurations */ +static grpc_end2end_test_config configs[] = { + {"chttp2/fullstack_local_ipv4", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | + FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, + nullptr, chttp2_create_fixture_fullstack_ipv4, + chttp2_init_client_fullstack_ipv4, chttp2_init_server_fullstack_ipv4, + grpc_end2end_local_chttp2_tear_down_fullstack}}; + +int main(int argc, char** argv) { + size_t i; + grpc::testing::TestEnvironment env(argc, argv); + grpc_end2end_tests_pre_init(); + grpc_init(); + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + grpc_shutdown(); + return 0; +} diff --git a/test/core/end2end/fixtures/h2_local_ipv6.cc b/test/core/end2end/fixtures/h2_local_ipv6.cc new file mode 100644 index 00000000000..e360727ca82 --- /dev/null +++ b/test/core/end2end/fixtures/h2_local_ipv6.cc @@ -0,0 +1,72 @@ +/* + * + * 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 + +#include "src/core/lib/gpr/host_port.h" +#include "test/core/end2end/end2end_tests.h" +#include "test/core/end2end/fixtures/local_util.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv6( + grpc_channel_args* client_args, grpc_channel_args* server_args) { + grpc_end2end_test_fixture f = + grpc_end2end_local_chttp2_create_fixture_fullstack(); + int port = grpc_pick_unused_port_or_die(); + gpr_join_host_port( + &static_cast(f.fixture_data) + ->localaddr, + "[::1]", port); + return f; +} + +static void chttp2_init_client_fullstack_ipv6(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, LOCAL_TCP); +} + +static void chttp2_init_server_fullstack_ipv6(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, LOCAL_TCP); +} + +/* All test configurations */ +static grpc_end2end_test_config configs[] = { + {"chttp2/fullstack_local_ipv6", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | + FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, + nullptr, chttp2_create_fixture_fullstack_ipv6, + chttp2_init_client_fullstack_ipv6, chttp2_init_server_fullstack_ipv6, + grpc_end2end_local_chttp2_tear_down_fullstack}}; + +int main(int argc, char** argv) { + size_t i; + grpc::testing::TestEnvironment env(argc, argv); + grpc_end2end_tests_pre_init(); + grpc_init(); + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + grpc_shutdown(); + return 0; +} diff --git a/test/core/end2end/fixtures/h2_local_uds.cc b/test/core/end2end/fixtures/h2_local_uds.cc new file mode 100644 index 00000000000..f1bce213dc2 --- /dev/null +++ b/test/core/end2end/fixtures/h2_local_uds.cc @@ -0,0 +1,71 @@ +/* + * + * 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 + +#include "test/core/end2end/end2end_tests.h" +#include "test/core/end2end/fixtures/local_util.h" +#include "test/core/util/test_config.h" + +static int unique = 1; + +static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_uds( + grpc_channel_args* client_args, grpc_channel_args* server_args) { + grpc_end2end_test_fixture f = + grpc_end2end_local_chttp2_create_fixture_fullstack(); + gpr_asprintf( + &static_cast(f.fixture_data) + ->localaddr, + "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), unique++); + return f; +} + +static void chttp2_init_client_fullstack_uds(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, UDS); +} + +static void chttp2_init_server_fullstack_uds(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, UDS); +} + +/* All test configurations */ +static grpc_end2end_test_config configs[] = { + {"chttp2/fullstack_local_uds", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | + FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, + nullptr, chttp2_create_fixture_fullstack_uds, + chttp2_init_client_fullstack_uds, chttp2_init_server_fullstack_uds, + grpc_end2end_local_chttp2_tear_down_fullstack}}; + +int main(int argc, char** argv) { + size_t i; + grpc::testing::TestEnvironment env(argc, argv); + grpc_end2end_tests_pre_init(); + grpc_init(); + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + grpc_shutdown(); + return 0; +} diff --git a/test/core/end2end/fixtures/h2_local.cc b/test/core/end2end/fixtures/local_util.cc similarity index 61% rename from test/core/end2end/fixtures/h2_local.cc rename to test/core/end2end/fixtures/local_util.cc index 18d690ff222..5f0b0300ac0 100644 --- a/test/core/end2end/fixtures/h2_local.cc +++ b/test/core/end2end/fixtures/local_util.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015 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. @@ -16,11 +16,7 @@ * */ -#include "test/core/end2end/end2end_tests.h" - -#include -#include -#include +#include "test/core/end2end/fixtures/local_util.h" #include #include @@ -34,39 +30,28 @@ #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/security/credentials/credentials.h" -#include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; - -static int unique = 1; - -static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( - grpc_channel_args* client_args, grpc_channel_args* server_args) { +grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack() { grpc_end2end_test_fixture f; - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + grpc_end2end_local_fullstack_fixture_data* ffd = + static_cast( + gpr_malloc(sizeof(grpc_end2end_local_fullstack_fixture_data))); memset(&f, 0, sizeof(f)); - - gpr_asprintf(&ffd->localaddr, "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), - unique++); - 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; } -void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, - grpc_channel_args* client_args) { - grpc_channel_credentials* creds = grpc_local_credentials_create(UDS); - fullstack_fixture_data* ffd = - static_cast(f->fixture_data); +void grpc_end2end_local_chttp2_init_client_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* client_args, + grpc_local_connect_type type) { + grpc_channel_credentials* creds = grpc_local_credentials_create(type); + grpc_end2end_local_fullstack_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); @@ -98,11 +83,12 @@ static void process_auth_failure(void* state, grpc_auth_context* ctx, cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr); } -void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, - grpc_channel_args* server_args) { - grpc_server_credentials* creds = grpc_local_server_credentials_create(UDS); - fullstack_fixture_data* ffd = - static_cast(f->fixture_data); +void grpc_end2end_local_chttp2_init_server_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* server_args, + grpc_local_connect_type type) { + grpc_server_credentials* creds = grpc_local_server_credentials_create(type); + grpc_end2end_local_fullstack_fixture_data* ffd = + static_cast(f->fixture_data); if (f->server) { grpc_server_destroy(f->server); } @@ -119,36 +105,10 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, grpc_server_start(f->server); } -void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { - fullstack_fixture_data* ffd = - static_cast(f->fixture_data); +void grpc_end2end_local_chttp2_tear_down_fullstack( + grpc_end2end_test_fixture* f) { + grpc_end2end_local_fullstack_fixture_data* ffd = + static_cast(f->fixture_data); gpr_free(ffd->localaddr); gpr_free(ffd); } - -/* All test configurations */ -static grpc_end2end_test_config configs[] = { - {"chttp2/fullstack_local", - FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | - FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | - FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | - FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, - nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, - chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, -}; - -int main(int argc, char** argv) { - size_t i; - - grpc::testing::TestEnvironment env(argc, argv); - grpc_end2end_tests_pre_init(); - grpc_init(); - - for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { - grpc_end2end_tests(argc, argv, configs[i]); - } - - grpc_shutdown(); - - return 0; -} diff --git a/test/core/end2end/fixtures/local_util.h b/test/core/end2end/fixtures/local_util.h new file mode 100644 index 00000000000..f133b4d977e --- /dev/null +++ b/test/core/end2end/fixtures/local_util.h @@ -0,0 +1,41 @@ +/* + * + * 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 "src/core/lib/surface/channel.h" + +typedef struct grpc_end2end_local_fullstack_fixture_data { + char* localaddr; +} grpc_end2end_local_fullstack_fixture_data; + +/* Utility functions shared by h2_local tests. */ +grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack(); + +void grpc_end2end_local_chttp2_init_client_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* client_args, + grpc_local_connect_type type); + +void grpc_end2end_local_chttp2_init_server_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* server_args, + grpc_local_connect_type type); + +void grpc_end2end_local_chttp2_tear_down_fullstack( + grpc_end2end_test_fixture* f); diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 601d3bac387..c9518d9b815 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -74,7 +74,9 @@ 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_local': local_fixture_options, + 'h2_local_uds': local_fixture_options, + 'h2_local_ipv4': local_fixture_options, + 'h2_local_ipv6': local_fixture_options, 'h2_ssl_proxy': default_secure_fixture_options._replace( includes_proxy=True, ci_mac=False, exclude_iomgrs=['uv']), 'h2_uds': uds_fixture_options, diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 81956db841f..8f194b28252 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -85,7 +85,9 @@ END2END_FIXTURES = { client_channel = False, ), "h2_ssl": _fixture_options(secure = True), - "h2_local": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), + "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"]), "h2_ssl_proxy": _fixture_options(includes_proxy = True, secure = True), "h2_uds": _fixture_options( dns_resolver = False, @@ -376,6 +378,7 @@ def grpc_end2end_tests(): ":ssl_test_data", ":http_proxy", ":proxy", + ":local_util", ], ) @@ -426,6 +429,7 @@ def grpc_end2end_nosec_tests(): ":ssl_test_data", ":http_proxy", ":proxy", + ":local_util", ], ) diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 38cdd49fc7f..40c49895fd7 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -6241,9 +6241,45 @@ "headers": [], "is_filegroup": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "src": [ - "test/core/end2end/fixtures/h2_local.cc" + "test/core/end2end/fixtures/h2_local_ipv4.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "end2end_tests", + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "h2_local_ipv6_test", + "src": [ + "test/core/end2end/fixtures/h2_local_ipv6.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "end2end_tests", + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "h2_local_uds_test", + "src": [ + "test/core/end2end/fixtures/h2_local_uds.cc" ], "third_party": false, "type": "target" @@ -10683,6 +10719,7 @@ "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h", "test/core/end2end/cq_verifier.h", "test/core/end2end/fixtures/http_proxy_fixture.h", + "test/core/end2end/fixtures/local_util.h", "test/core/end2end/fixtures/proxy.h", "test/core/iomgr/endpoint_tests.h", "test/core/util/debugger_macros.h", @@ -10710,6 +10747,8 @@ "test/core/end2end/cq_verifier.h", "test/core/end2end/fixtures/http_proxy_fixture.cc", "test/core/end2end/fixtures/http_proxy_fixture.h", + "test/core/end2end/fixtures/local_util.cc", + "test/core/end2end/fixtures/local_util.h", "test/core/end2end/fixtures/proxy.cc", "test/core/end2end/fixtures/proxy.h", "test/core/iomgr/endpoint_tests.cc", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index bca2ef53878..3a348e4a92f 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -22376,7 +22376,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22399,7 +22399,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22422,7 +22422,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22445,7 +22445,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22468,7 +22468,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22491,7 +22491,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22514,7 +22514,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22537,7 +22537,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22560,7 +22560,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22583,7 +22583,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22606,7 +22606,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22629,7 +22629,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22652,7 +22652,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22675,7 +22675,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22698,7 +22698,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22721,7 +22721,7 @@ ], "flaky": true, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22744,7 +22744,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22767,7 +22767,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22790,7 +22790,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22813,7 +22813,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22836,7 +22836,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22859,7 +22859,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22882,7 +22882,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22905,7 +22905,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22928,7 +22928,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22951,7 +22951,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22974,7 +22974,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22997,7 +22997,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23020,7 +23020,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23043,7 +23043,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23066,7 +23066,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23089,7 +23089,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23112,7 +23112,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23135,7 +23135,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23158,7 +23158,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23181,7 +23181,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23204,7 +23204,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23227,7 +23227,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23250,7 +23250,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23273,7 +23273,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23296,7 +23296,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23319,7 +23319,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23342,7 +23342,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23365,7 +23365,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23388,7 +23388,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23411,7 +23411,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23434,7 +23434,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23457,7 +23457,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23480,7 +23480,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23503,7 +23503,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23526,7 +23526,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23549,7 +23549,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23572,7 +23572,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23595,7 +23595,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23618,7 +23618,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23641,7 +23641,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23664,7 +23664,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23687,7 +23687,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23710,7 +23710,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23733,7 +23733,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23756,7 +23756,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23779,7 +23779,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23802,7 +23802,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23825,7 +23825,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23848,7 +23848,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23871,7 +23871,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23894,7 +23894,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23917,7 +23917,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23940,7 +23940,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23963,7 +23963,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23986,7 +23986,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -24009,7 +24009,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -24032,7 +24032,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -24055,7 +24055,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -24078,7 +24078,3457 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "authority_not_supported" + ], + "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": [ + "bad_hostname" + ], + "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": [ + "bad_ping" + ], + "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": [ + "binary_metadata" + ], + "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": [ + "call_creds" + ], + "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": [ + "cancel_after_accept" + ], + "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": [ + "cancel_after_client_done" + ], + "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": [ + "cancel_after_invoke" + ], + "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": [ + "cancel_after_round_trip" + ], + "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": [ + "cancel_before_invoke" + ], + "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": [ + "cancel_in_a_vacuum" + ], + "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": [ + "cancel_with_status" + ], + "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": [ + "channelz" + ], + "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": [ + "compressed_payload" + ], + "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": [ + "connectivity" + ], + "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": [ + "disappearing_server" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": true, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "empty_batch" + ], + "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": [ + "filter_call_init_fails" + ], + "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_causes_close" + ], + "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": [ + "filter_latency" + ], + "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": [ + "filter_status_code" + ], + "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": [ + "graceful_server_shutdown" + ], + "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": [ + "high_initial_seqno" + ], + "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": [ + "hpack_size" + ], + "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": [ + "idempotent_request" + ], + "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": [ + "invoke_large_request" + ], + "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": [ + "keepalive_timeout" + ], + "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": [ + "large_metadata" + ], + "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": [ + "max_concurrent_streams" + ], + "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": [ + "max_connection_age" + ], + "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": [ + "max_connection_idle" + ], + "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": [ + "max_message_length" + ], + "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": [ + "negative_deadline" + ], + "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": [ + "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" + ], + "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": [ + "no_logging" + ], + "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": [ + "no_op" + ], + "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": [ + "payload" + ], + "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": [ + "ping" + ], + "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": [ + "ping_pong_streaming" + ], + "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": [ + "registered_call" + ], + "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": [ + "request_with_flags" + ], + "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": [ + "request_with_payload" + ], + "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": [ + "resource_quota_server" + ], + "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": [ + "retry" + ], + "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": [ + "retry_cancellation" + ], + "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": [ + "retry_disabled" + ], + "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": [ + "retry_exceeds_buffer_size_in_initial_batch" + ], + "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": [ + "retry_exceeds_buffer_size_in_subsequent_batch" + ], + "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": [ + "retry_non_retriable_status" + ], + "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": [ + "retry_non_retriable_status_before_recv_trailing_metadata_started" + ], + "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": [ + "retry_recv_initial_metadata" + ], + "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": [ + "retry_recv_message" + ], + "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": [ + "retry_server_pushback_delay" + ], + "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": [ + "retry_server_pushback_disabled" + ], + "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": [ + "retry_streaming" + ], + "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": [ + "retry_streaming_after_commit" + ], + "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": [ + "retry_streaming_succeeds_before_replay_finished" + ], + "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": [ + "retry_throttled" + ], + "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": [ + "retry_too_many_attempts" + ], + "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": [ + "server_finishes_request" + ], + "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": [ + "shutdown_finishes_calls" + ], + "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": [ + "shutdown_finishes_tags" + ], + "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": [ + "simple_cacheable_request" + ], + "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": [ + "simple_delayed_request" + ], + "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": [ + "simple_metadata" + ], + "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": [ + "simple_request" + ], + "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": [ + "stream_compression_compressed_payload" + ], + "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": [ + "stream_compression_payload" + ], + "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": [ + "stream_compression_ping_pong_streaming" + ], + "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": [ + "streaming_error_response" + ], + "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": [ + "trailing_metadata" + ], + "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": [ + "workaround_cronet_compression" + ], + "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": [ + "write_buffering" + ], + "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": [ + "write_buffering_at_end" + ], + "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": [ + "authority_not_supported" + ], + "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": [ + "bad_hostname" + ], + "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": [ + "bad_ping" + ], + "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": [ + "binary_metadata" + ], + "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": [ + "call_creds" + ], + "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": [ + "cancel_after_accept" + ], + "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": [ + "cancel_after_client_done" + ], + "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": [ + "cancel_after_invoke" + ], + "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": [ + "cancel_after_round_trip" + ], + "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": [ + "cancel_before_invoke" + ], + "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": [ + "cancel_in_a_vacuum" + ], + "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": [ + "cancel_with_status" + ], + "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": [ + "channelz" + ], + "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": [ + "compressed_payload" + ], + "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": [ + "connectivity" + ], + "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": [ + "disappearing_server" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": true, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "empty_batch" + ], + "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": [ + "filter_call_init_fails" + ], + "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_causes_close" + ], + "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": [ + "filter_latency" + ], + "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": [ + "filter_status_code" + ], + "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": [ + "graceful_server_shutdown" + ], + "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": [ + "high_initial_seqno" + ], + "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": [ + "hpack_size" + ], + "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": [ + "idempotent_request" + ], + "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": [ + "invoke_large_request" + ], + "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": [ + "keepalive_timeout" + ], + "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": [ + "large_metadata" + ], + "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": [ + "max_concurrent_streams" + ], + "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": [ + "max_connection_age" + ], + "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": [ + "max_connection_idle" + ], + "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": [ + "max_message_length" + ], + "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": [ + "negative_deadline" + ], + "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": [ + "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" + ], + "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": [ + "no_logging" + ], + "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": [ + "no_op" + ], + "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": [ + "payload" + ], + "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": [ + "ping" + ], + "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": [ + "ping_pong_streaming" + ], + "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": [ + "registered_call" + ], + "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": [ + "request_with_flags" + ], + "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": [ + "request_with_payload" + ], + "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": [ + "resource_quota_server" + ], + "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": [ + "retry" + ], + "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": [ + "retry_cancellation" + ], + "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": [ + "retry_disabled" + ], + "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": [ + "retry_exceeds_buffer_size_in_initial_batch" + ], + "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": [ + "retry_exceeds_buffer_size_in_subsequent_batch" + ], + "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": [ + "retry_non_retriable_status" + ], + "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": [ + "retry_non_retriable_status_before_recv_trailing_metadata_started" + ], + "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": [ + "retry_recv_initial_metadata" + ], + "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": [ + "retry_recv_message" + ], + "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": [ + "retry_server_pushback_delay" + ], + "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": [ + "retry_server_pushback_disabled" + ], + "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": [ + "retry_streaming" + ], + "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": [ + "retry_streaming_after_commit" + ], + "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": [ + "retry_streaming_succeeds_before_replay_finished" + ], + "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": [ + "retry_throttled" + ], + "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": [ + "retry_too_many_attempts" + ], + "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": [ + "server_finishes_request" + ], + "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": [ + "shutdown_finishes_calls" + ], + "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": [ + "shutdown_finishes_tags" + ], + "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": [ + "simple_cacheable_request" + ], + "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": [ + "simple_delayed_request" + ], + "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": [ + "simple_metadata" + ], + "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": [ + "simple_request" + ], + "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": [ + "stream_compression_compressed_payload" + ], + "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": [ + "stream_compression_payload" + ], + "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": [ + "stream_compression_ping_pong_streaming" + ], + "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": [ + "streaming_error_response" + ], + "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": [ + "trailing_metadata" + ], + "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": [ + "workaround_cronet_compression" + ], + "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": [ + "write_buffering" + ], + "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": [ + "write_buffering_at_end" + ], + "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", From f2324e1c056249dd7862799443809e4964c4866a Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Sun, 16 Dec 2018 16:01:14 -0800 Subject: [PATCH 0569/2143] Reset the SendMessage pointer before post-interception --- include/grpcpp/impl/codegen/call_op_set.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index b4c34a01c9a..b2100c68b7f 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -325,7 +325,11 @@ class CallOpSendMessage { } void SetFinishInterceptionHookPoint( - InterceptorBatchMethodsImpl* interceptor_methods) {} + InterceptorBatchMethodsImpl* interceptor_methods) { + // The contents of the SendMessage value that was previously set + // has had its references stolen by core's operations + interceptor_methods->SetSendMessage(nullptr); + } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { hijacked_ = true; From 76f0cd4d4d0e5051806a04063d0f86508eda9c12 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 17 Dec 2018 16:19:46 +0100 Subject: [PATCH 0570/2143] prevent setting wrong time on macos high sierra kokoro workers --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index bafe0d98c1a..d80bcbd1838 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -19,14 +19,6 @@ launchctl limit maxfiles ulimit -a -# synchronize the clock -date -sudo systemsetup -setusingnetworktime off -sudo systemsetup -setnetworktimeserver "$( ipconfig getoption en0 server_identifier )" -sudo systemsetup -settimezone America/Los_Angeles -sudo systemsetup -setusingnetworktime on -date - # Add GCP credentials for BQ access pip install google-api-python-client oauth2client --user python export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json From 240eb480864a0be9f9af5c452b290de3385f1211 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 17 Dec 2018 16:19:46 +0100 Subject: [PATCH 0571/2143] prevent setting wrong time on macos high sierra kokoro workers --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 0ef9735c1cd..067a60da822 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -19,14 +19,6 @@ launchctl limit maxfiles ulimit -a -# synchronize the clock -date -sudo systemsetup -setusingnetworktime off -sudo systemsetup -setnetworktimeserver "$( ipconfig getoption en0 server_identifier )" -sudo systemsetup -settimezone America/Los_Angeles -sudo systemsetup -setusingnetworktime on -date - # Add GCP credentials for BQ access # pin google-api-python-client to avoid https://github.com/grpc/grpc/issues/15600 pip install google-api-python-client==1.6.7 --user python From 191e8f1c9cbf0080910e5c43a0997f90a5f5bd0f Mon Sep 17 00:00:00 2001 From: kkm Date: Fri, 7 Dec 2018 00:29:32 -0800 Subject: [PATCH 0572/2143] Use x64 tools on 64-bit Windows in Grpc.Tools The Windows Nano Server Docker image does not support 32-bit executables. See: https://docs.microsoft.com/windows-server/get-started/getting-started-with-nano-server#important-differences-in-nano-server See: https://github.com/grpc/grpc/pull/13207#issuecomment-444846082 Close: #13098 (wontfix) --- src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets | 3 +-- .../Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets b/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets index 5f76c03ce57..3fe1ccc9181 100644 --- a/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets @@ -22,9 +22,8 @@ - $(Protobuf_PackagedToolsPath)\$(Protobuf_ToolsOs)_x86\$(gRPC_PluginFileName).exe + >$(Protobuf_PackagedToolsPath)\$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)\$(gRPC_PluginFileName).exe $(Protobuf_PackagedToolsPath)/$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)/$(gRPC_PluginFileName) 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 1d233d23a80..26f9efb5a84 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets @@ -74,9 +74,8 @@ $(_Protobuf_ToolsOs) $(_Protobuf_ToolsCpu) - $(Protobuf_PackagedToolsPath)\$(Protobuf_ToolsOs)_x86\protoc.exe + >$(Protobuf_PackagedToolsPath)\$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)\protoc.exe $(Protobuf_PackagedToolsPath)/$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)/protoc From 082b63e09592502b0900a5dff214dc70efb9de56 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 7 Dec 2018 09:23:54 -0800 Subject: [PATCH 0573/2143] Refactor server deallocation --- .../_cython/_cygrpc/completion_queue.pyx.pxi | 2 +- .../grpc/_cython/_cygrpc/server.pyx.pxi | 10 +- src/python/grpcio/grpc/_server.py | 106 +++++++++++------- .../tests/channelz/_channelz_servicer_test.py | 2 - 4 files changed, 73 insertions(+), 47 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 141116df5dd..3c33b46dbb8 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi @@ -49,7 +49,7 @@ cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline): cdef _interpret_event(grpc_event c_event): cdef _Tag tag if c_event.type == GRPC_QUEUE_TIMEOUT: - # NOTE(nathaniel): For now we coopt ConnectivityEvent here. + # TODO(ericgribkoff) Do not coopt ConnectivityEvent here. return None, ConnectivityEvent(GRPC_QUEUE_TIMEOUT, False, None) elif c_event.type == GRPC_QUEUE_SHUTDOWN: # NOTE(nathaniel): For now we coopt ConnectivityEvent here. diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index ce701724fd3..1b8d6790fb3 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -128,7 +128,9 @@ cdef class Server: with nogil: grpc_server_cancel_all_calls(self.c_server) - def __dealloc__(self): + # TODO(ericgribkoff) Determine what, if any, portion of this is safe to call + # from __dealloc__, and potentially remove backup_shutdown_queue. + def destroy(self): if self.c_server != NULL: if not self.is_started: pass @@ -146,4 +148,8 @@ cdef class Server: while not self.is_shutdown: time.sleep(0) grpc_server_destroy(self.c_server) - grpc_shutdown() + self.c_server = NULL + + def __dealloc(self): + if self.c_server == NULL: + grpc_shutdown() diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 3bbfa47da53..eb750ef1a82 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -48,7 +48,7 @@ _CANCELLED = 'cancelled' _EMPTY_FLAGS = 0 -_UNEXPECTED_EXIT_SERVER_GRACE = 1.0 +_DEALLOCATED_SERVER_CHECK_PERIOD_S = 1.0 def _serialized_request(request_event): @@ -676,6 +676,9 @@ class _ServerState(object): self.rpc_states = set() self.due = set() + # A "volatile" flag to interrupt the daemon serving thread + self.server_deallocated = False + def _add_generic_handlers(state, generic_handlers): with state.lock: @@ -702,6 +705,7 @@ def _request_call(state): # TODO(https://github.com/grpc/grpc/issues/6597): delete this function. def _stop_serving(state): if not state.rpc_states and not state.due: + state.server.destroy() for shutdown_event in state.shutdown_events: shutdown_event.set() state.stage = _ServerStage.STOPPED @@ -715,49 +719,69 @@ def _on_call_completed(state): state.active_rpc_count -= 1 +def _process_event_and_continue(state, event): + should_continue = True + if event.tag is _SHUTDOWN_TAG: + with state.lock: + state.due.remove(_SHUTDOWN_TAG) + if _stop_serving(state): + should_continue = False + elif event.tag is _REQUEST_CALL_TAG: + with state.lock: + state.due.remove(_REQUEST_CALL_TAG) + concurrency_exceeded = ( + state.maximum_concurrent_rpcs is not None and + state.active_rpc_count >= state.maximum_concurrent_rpcs) + rpc_state, rpc_future = _handle_call( + event, state.generic_handlers, state.interceptor_pipeline, + state.thread_pool, concurrency_exceeded) + if rpc_state is not None: + state.rpc_states.add(rpc_state) + if rpc_future is not None: + state.active_rpc_count += 1 + rpc_future.add_done_callback( + lambda unused_future: _on_call_completed(state)) + if state.stage is _ServerStage.STARTED: + _request_call(state) + elif _stop_serving(state): + should_continue = False + else: + rpc_state, callbacks = event.tag(event) + for callback in callbacks: + callable_util.call_logging_exceptions(callback, + 'Exception calling callback!') + if rpc_state is not None: + with state.lock: + state.rpc_states.remove(rpc_state) + if _stop_serving(state): + should_continue = False + return should_continue + + def _serve(state): while True: - event = state.completion_queue.poll() - if event.tag is _SHUTDOWN_TAG: - with state.lock: - state.due.remove(_SHUTDOWN_TAG) - if _stop_serving(state): - return - elif event.tag is _REQUEST_CALL_TAG: - with state.lock: - state.due.remove(_REQUEST_CALL_TAG) - concurrency_exceeded = ( - state.maximum_concurrent_rpcs is not None and - state.active_rpc_count >= state.maximum_concurrent_rpcs) - rpc_state, rpc_future = _handle_call( - event, state.generic_handlers, state.interceptor_pipeline, - state.thread_pool, concurrency_exceeded) - if rpc_state is not None: - state.rpc_states.add(rpc_state) - if rpc_future is not None: - state.active_rpc_count += 1 - rpc_future.add_done_callback( - lambda unused_future: _on_call_completed(state)) - if state.stage is _ServerStage.STARTED: - _request_call(state) - elif _stop_serving(state): - return - else: - rpc_state, callbacks = event.tag(event) - for callback in callbacks: - callable_util.call_logging_exceptions( - callback, 'Exception calling callback!') - if rpc_state is not None: - with state.lock: - state.rpc_states.remove(rpc_state) - if _stop_serving(state): - return + timeout = time.time() + _DEALLOCATED_SERVER_CHECK_PERIOD_S + event = state.completion_queue.poll(timeout) + if state.server_deallocated: + _begin_shutdown_once(state) + if event.completion_type != cygrpc.CompletionType.queue_timeout: + if not _process_event_and_continue(state, event): + return # We want to force the deletion of the previous event # ~before~ we poll again; if the event has a reference # to a shutdown Call object, this can induce spinlock. event = None +def _begin_shutdown_once(state): + with state.lock: + if state.stage is _ServerStage.STARTED: + state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG) + state.stage = _ServerStage.GRACE + state.shutdown_events = [] + state.due.add(_SHUTDOWN_TAG) + + def _stop(state, grace): with state.lock: if state.stage is _ServerStage.STOPPED: @@ -765,11 +789,7 @@ def _stop(state, grace): shutdown_event.set() return shutdown_event else: - if state.stage is _ServerStage.STARTED: - state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG) - state.stage = _ServerStage.GRACE - state.shutdown_events = [] - state.due.add(_SHUTDOWN_TAG) + _begin_shutdown_once(state) shutdown_event = threading.Event() state.shutdown_events.append(shutdown_event) if grace is None: @@ -840,7 +860,9 @@ class _Server(grpc.Server): return _stop(self._state, grace) def __del__(self): - _stop(self._state, None) + # 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, 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 8ca51895224..5265911a0be 100644 --- a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -88,8 +88,6 @@ def _generate_channel_server_pairs(n): def _close_channel_server_pairs(pairs): for pair in pairs: pair.server.stop(None) - # TODO(ericgribkoff) This del should not be required - del pair.server pair.channel.close() From a76d72e0a62d512f919f0fa79e24809427c9e4e7 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 14 Dec 2018 17:41:02 -0800 Subject: [PATCH 0574/2143] add tests --- src/python/grpcio_tests/tests/tests.json | 1 + .../tests/unit/_server_shutdown_scenarios.py | 113 ++++++++++++++++++ .../tests/unit/_server_shutdown_test.py | 87 ++++++++++++++ 3 files changed, 201 insertions(+) create mode 100644 src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py create mode 100644 src/python/grpcio_tests/tests/unit/_server_shutdown_test.py diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index b27e6f26938..f202a3f932f 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -57,6 +57,7 @@ "unit._reconnect_test.ReconnectTest", "unit._resource_exhausted_test.ResourceExhaustedTest", "unit._rpc_test.RPCTest", + "unit._server_shutdown_test.ServerShutdown", "unit._server_ssl_cert_config_test.ServerSSLCertConfigFetcherParamsChecks", "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestCertConfigReuse", "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestWithClientAuth", diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py new file mode 100644 index 00000000000..da8cef0c430 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py @@ -0,0 +1,113 @@ +# 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. +"""Defines a number of module-scope gRPC scenarios to test server shutdown.""" + +import argparse +import os +import threading +import time +import logging + +import grpc + +from concurrent import futures +from six.moves import queue + +WAIT_TIME = 1000 + +REQUEST = b'request' +RESPONSE = b'response' + +SERVER_RAISES_EXCEPTION = 'server_raises_exception' +SERVER_DEALLOCATED = 'server_deallocated' +SERVER_FORK_CAN_EXIT = 'server_fork_can_exit' + +FORK_EXIT = '/test/ForkExit' + + +class ForkExitHandler(object): + + def unary_unary(self, request, servicer_context): + pid = os.fork() + if pid == 0: + os._exit(0) + return RESPONSE + + def __init__(self): + self.request_streaming = None + self.response_streaming = None + self.request_deserializer = None + self.response_serializer = None + self.unary_stream = None + self.stream_unary = None + self.stream_stream = None + + +class GenericHandler(grpc.GenericRpcHandler): + + def service(self, handler_call_details): + if handler_call_details.method == FORK_EXIT: + return ForkExitHandler() + else: + return None + + +def run_server(port_queue,): + server = grpc.server( + futures.ThreadPoolExecutor(max_workers=10), + options=(('grpc.so_reuseport', 0),)) + port = server.add_insecure_port('[::]:0') + port_queue.put(port) + server.add_generic_rpc_handlers((GenericHandler(),)) + server.start() + # threading.Event.wait() does not exhibit the bug identified in + # https://github.com/grpc/grpc/issues/17093, sleep instead + time.sleep(WAIT_TIME) + + +def run_test(args): + if args.scenario == SERVER_RAISES_EXCEPTION: + server = grpc.server( + futures.ThreadPoolExecutor(max_workers=1), + options=(('grpc.so_reuseport', 0),)) + server.start() + raise Exception() + elif args.scenario == SERVER_DEALLOCATED: + server = grpc.server( + futures.ThreadPoolExecutor(max_workers=1), + options=(('grpc.so_reuseport', 0),)) + server.start() + server.__del__() + while server._state.stage != grpc._server._ServerStage.STOPPED: + pass + elif args.scenario == SERVER_FORK_CAN_EXIT: + port_queue = queue.Queue() + thread = threading.Thread(target=run_server, args=(port_queue,)) + thread.daemon = True + thread.start() + port = port_queue.get() + channel = grpc.insecure_channel('[::]:%d' % port) + multi_callable = channel.unary_unary(FORK_EXIT) + result, call = multi_callable.with_call(REQUEST, wait_for_ready=True) + os.wait() + else: + raise ValueError('unknown test scenario') + + +if __name__ == '__main__': + logging.basicConfig() + parser = argparse.ArgumentParser() + parser.add_argument('scenario', type=str) + args = parser.parse_args() + run_test(args) diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py new file mode 100644 index 00000000000..25d7f5e8198 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py @@ -0,0 +1,87 @@ +# 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. +"""Tests clean shutdown of server on various interpreter exit conditions. + +The tests in this module spawn a subprocess for each test case, the +test is considered successful if it doesn't hang/timeout. +""" + +import atexit +import os +import subprocess +import sys +import threading +import unittest +import logging + +from tests.unit import _server_shutdown_scenarios + +SCENARIO_FILE = os.path.abspath( + os.path.join( + os.path.dirname(os.path.realpath(__file__)), + '_server_shutdown_scenarios.py')) +INTERPRETER = sys.executable +BASE_COMMAND = [INTERPRETER, SCENARIO_FILE] + +processes = [] +process_lock = threading.Lock() + + +# Make sure we attempt to clean up any +# processes we may have left running +def cleanup_processes(): + with process_lock: + for process in processes: + try: + process.kill() + except Exception: # pylint: disable=broad-except + pass + + +atexit.register(cleanup_processes) + + +def wait(process): + with process_lock: + processes.append(process) + process.wait() + + +class ServerShutdown(unittest.TestCase): + + def test_deallocated_server_stops(self): + process = subprocess.Popen( + BASE_COMMAND + [_server_shutdown_scenarios.SERVER_DEALLOCATED], + stdout=sys.stdout, + stderr=sys.stderr) + wait(process) + + def test_server_exception_exits(self): + process = subprocess.Popen( + BASE_COMMAND + [_server_shutdown_scenarios.SERVER_RAISES_EXCEPTION], + stdout=sys.stdout, + stderr=sys.stderr) + wait(process) + + def test_server_fork_can_exit(self): + process = subprocess.Popen( + BASE_COMMAND + [_server_shutdown_scenarios.SERVER_FORK_CAN_EXIT], + stdout=sys.stdout, + stderr=sys.stderr) + wait(process) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) From 468ae0f48615a58d8f09b76ca142fee27563964a Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Sat, 15 Dec 2018 08:36:32 -0800 Subject: [PATCH 0575/2143] add tracking issue --- src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index 1b8d6790fb3..e89e02b171e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -128,8 +128,9 @@ cdef class Server: with nogil: grpc_server_cancel_all_calls(self.c_server) - # TODO(ericgribkoff) Determine what, if any, portion of this is safe to call - # from __dealloc__, and potentially remove backup_shutdown_queue. + # TODO(https://github.com/grpc/grpc/issues/17515) Determine what, if any, + # portion of this is safe to call from __dealloc__, and potentially remove + # backup_shutdown_queue. def destroy(self): if self.c_server != NULL: if not self.is_started: From 718084c6b4aac0099d52a0dcf4c529e5b46ee686 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Sun, 16 Dec 2018 19:03:18 -0800 Subject: [PATCH 0576/2143] disable fork test on windows --- .../grpcio_tests/tests/unit/_server_shutdown_scenarios.py | 2 +- src/python/grpcio_tests/tests/unit/_server_shutdown_test.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py index da8cef0c430..acbec0f77dd 100644 --- a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py @@ -63,7 +63,7 @@ class GenericHandler(grpc.GenericRpcHandler): return None -def run_server(port_queue,): +def run_server(port_queue): server = grpc.server( futures.ThreadPoolExecutor(max_workers=10), options=(('grpc.so_reuseport', 0),)) diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py index 25d7f5e8198..0e4591c5e56 100644 --- a/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py @@ -74,6 +74,7 @@ class ServerShutdown(unittest.TestCase): stderr=sys.stderr) wait(process) + @unittest.skipIf(os.name == 'nt', 'fork not supported on windows') def test_server_fork_can_exit(self): process = subprocess.Popen( BASE_COMMAND + [_server_shutdown_scenarios.SERVER_FORK_CAN_EXIT], From aa2e731508de93c2756aac782f166598569ddc44 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 17 Dec 2018 08:54:32 -0800 Subject: [PATCH 0577/2143] Fix new target --- CMakeLists.txt | 1 - Makefile | 6 +++--- build.yaml | 1 - tools/run_tests/generated/sources_and_headers.json | 1 - 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 634844b28b9..8d67c9415da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11089,7 +11089,6 @@ target_link_libraries(bm_byte_buffer grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} diff --git a/Makefile b/Makefile index e1145f7b77c..f9d5ed41639 100644 --- a/Makefile +++ b/Makefile @@ -16089,17 +16089,17 @@ $(BINDIR)/$(CONFIG)/bm_byte_buffer: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_byte_buffer: $(PROTOBUF_DEP) $(BM_BYTE_BUFFER_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/bm_byte_buffer: $(PROTOBUF_DEP) $(BM_BYTE_BUFFER_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_BYTE_BUFFER_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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_byte_buffer + $(Q) $(LDXX) $(LDFLAGS) $(BM_BYTE_BUFFER_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_byte_buffer endif endif $(BM_BYTE_BUFFER_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_byte_buffer.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_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_byte_buffer.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_byte_buffer: $(BM_BYTE_BUFFER_OBJS:.o=.dep) diff --git a/build.yaml b/build.yaml index a8b7df84cc9..9e1f8d2c378 100644 --- a/build.yaml +++ b/build.yaml @@ -3904,7 +3904,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 54354395b2f..75b4fa47ef8 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -2706,7 +2706,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", From 951254151bbd43f56374e3608feaa9ff663332d2 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 17 Dec 2018 10:12:50 -0800 Subject: [PATCH 0578/2143] Revert "Metadata tutorial" --- examples/BUILD | 15 ---- examples/cpp/metadata/Makefile | 96 ------------------------- examples/cpp/metadata/README.md | 66 ----------------- examples/cpp/metadata/greeter_client.cc | 95 ------------------------ examples/cpp/metadata/greeter_server.cc | 94 ------------------------ 5 files changed, 366 deletions(-) delete mode 100644 examples/cpp/metadata/Makefile delete mode 100644 examples/cpp/metadata/README.md delete mode 100644 examples/cpp/metadata/greeter_client.cc delete mode 100644 examples/cpp/metadata/greeter_server.cc diff --git a/examples/BUILD b/examples/BUILD index 22f2f0a4f1a..0f18cfa9ba7 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -51,18 +51,3 @@ cc_binary( defines = ["BAZEL_BUILD"], deps = [":helloworld", "//:grpc++"], ) - -cc_binary( - name = "metadata_client", - srcs = ["cpp/metadata/greeter_client.cc"], - defines = ["BAZEL_BUILD"], - deps = [":helloworld", "//:grpc++"], -) - -cc_binary( - name = "metadata_server", - srcs = ["cpp/metadata/greeter_server.cc"], - defines = ["BAZEL_BUILD"], - deps = [":helloworld", "//:grpc++"], -) - diff --git a/examples/cpp/metadata/Makefile b/examples/cpp/metadata/Makefile deleted file mode 100644 index 46be8bfaa3c..00000000000 --- a/examples/cpp/metadata/Makefile +++ /dev/null @@ -1,96 +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. -# - HOST_SYSTEM = $(shell uname | cut -f 1 -d_) -SYSTEM ?= $(HOST_SYSTEM) -CXX = g++ -CPPFLAGS += `pkg-config --cflags protobuf grpc` -CXXFLAGS += -std=c++11 -ifeq ($(SYSTEM),Darwin) -LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ - -lgrpc++_reflection\ - -ldl -else -LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ - -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ - -ldl -endif -PROTOC = protoc -GRPC_CPP_PLUGIN = grpc_cpp_plugin -GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` - PROTOS_PATH = ../../protos - vpath %.proto $(PROTOS_PATH) - all: system-check greeter_client greeter_server - greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o - $(CXX) $^ $(LDFLAGS) -o $@ - greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o - $(CXX) $^ $(LDFLAGS) -o $@ - .PRECIOUS: %.grpc.pb.cc -%.grpc.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< - .PRECIOUS: %.pb.cc -%.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< - clean: - rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server - # The following is to test your system and ensure a smoother experience. -# They are by no means necessary to actually compile a grpc-enabled software. - PROTOC_CMD = which $(PROTOC) -PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 -PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) -HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) -ifeq ($(HAS_PROTOC),true) -HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) -endif -HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) - SYSTEM_OK = false -ifeq ($(HAS_VALID_PROTOC),true) -ifeq ($(HAS_PLUGIN),true) -SYSTEM_OK = true -endif -endif - system-check: -ifneq ($(HAS_VALID_PROTOC),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have protoc 3.0.0 installed in your path." - @echo "Please install Google protocol buffers 3.0.0 and its compiler." - @echo "You can find it here:" - @echo - @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" - @echo - @echo "Here is what I get when trying to evaluate your version of protoc:" - @echo - -$(PROTOC) --version - @echo - @echo -endif -ifneq ($(HAS_PLUGIN),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have the grpc c++ protobuf plugin installed in your path." - @echo "Please install grpc. You can find it here:" - @echo - @echo " https://github.com/grpc/grpc" - @echo - @echo "Here is what I get when trying to detect if you have the plugin:" - @echo - -which $(GRPC_CPP_PLUGIN) - @echo - @echo -endif -ifneq ($(SYSTEM_OK),true) - @false -endif diff --git a/examples/cpp/metadata/README.md b/examples/cpp/metadata/README.md deleted file mode 100644 index 96ad3d19bdb..00000000000 --- a/examples/cpp/metadata/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# Metadata Example - -## Overview - -This example shows you how to add custom headers on the client and server and -how to access them. - -Custom metadata must follow the "Custom-Metadata" format listed in -https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md, with the -exception of binary headers, which don't have to be base64 encoded. - -### Get the tutorial source code - The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: - ```sh -$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc -``` - Change your current directory to examples/cpp/metadata - ```sh -$ cd examples/cpp/metadata -``` - -### Generating gRPC code - To generate the client and server side interfaces: - ```sh -$ make helloworld.grpc.pb.cc helloworld.pb.cc -``` -Which internally invokes the proto-compiler as: - ```sh -$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto -$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto -``` -### Try it! -Build client and server: - -```sh -$ make -``` - -Run the server, which will listen on port 50051: - -```sh -$ ./greeter_server -``` - -Run the client (in a different terminal): - -```sh -$ ./greeter_client -``` - -If things go smoothly, you will see in the client terminal: - -"Client received initial metadata from server: initial metadata value" -"Client received trailing metadata from server: trailing metadata value" -"Client received message: Hello World" - - -And in the server terminal: - -"Header key: custom-bin , value: 01234567" -"Header key: custom-header , value: Custom Value" -"Header key: user-agent , value: grpc-c++/1.16.0-dev grpc-c/6.0.0-dev (linux; chttp2; gao)" - -We did not add the user-agent metadata as a custom header. This shows how -the gRPC framework adds some headers under the hood that may show up in the -metadata map. diff --git a/examples/cpp/metadata/greeter_client.cc b/examples/cpp/metadata/greeter_client.cc deleted file mode 100644 index 80494389937..00000000000 --- a/examples/cpp/metadata/greeter_client.cc +++ /dev/null @@ -1,95 +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 -#include - -#include - -#ifdef BAZEL_BUILD -#include "examples/protos/helloworld.grpc.pb.h" -#else -#include "helloworld.grpc.pb.h" -#endif - -using grpc::Channel; -using grpc::ClientContext; -using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; -using helloworld::Greeter; - -class CustomHeaderClient { - public: - CustomHeaderClient(std::shared_ptr channel) - : stub_(Greeter::NewStub(channel)) {} - - // Assembles the client's payload, sends it and presents the response back - // from the server. - std::string SayHello(const std::string& user) { - // Data we are sending to the server. - HelloRequest request; - request.set_name(user); - - // Container for the data we expect from the server. - HelloReply reply; - - // Context for the client. It could be used to convey extra information to - // the server and/or tweak certain RPC behaviors. - ClientContext context; - - // Setting custom metadata to be sent to the server - context.AddMetadata("custom-header", "Custom Value"); - - // Setting custom binary metadata - char bytes[8] = {'\0', '\1', '\2', '\3', - '\4', '\5', '\6', '\7'}; - context.AddMetadata("custom-bin", grpc::string(bytes, 8)); - - // The actual RPC. - Status status = stub_->SayHello(&context, request, &reply); - - // Act upon its status. - if (status.ok()) { - std::cout << "Client received initial metadata from server: " << context.GetServerInitialMetadata().find("custom-server-metadata")->second << std::endl; - std::cout << "Client received trailing metadata from server: " << context.GetServerTrailingMetadata().find("custom-trailing-metadata")->second << std::endl; - return reply.message(); - } else { - std::cout << status.error_code() << ": " << status.error_message() - << std::endl; - return "RPC failed"; - } - } - - private: - std::unique_ptr stub_; -}; - -int main(int argc, char** argv) { - // Instantiate the client. It requires a channel, out of which the actual RPCs - // 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()). - CustomHeaderClient greeter(grpc::CreateChannel( - "localhost:50051", grpc::InsecureChannelCredentials())); - std::string user("world"); - std::string reply = greeter.SayHello(user); - std::cout << "Client received message: " << reply << std::endl; - return 0; -} diff --git a/examples/cpp/metadata/greeter_server.cc b/examples/cpp/metadata/greeter_server.cc deleted file mode 100644 index a9a4f33cb0b..00000000000 --- a/examples/cpp/metadata/greeter_server.cc +++ /dev/null @@ -1,94 +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 -#include - -#include - -#ifdef BAZEL_BUILD -#include "examples/protos/helloworld.grpc.pb.h" -#else -#include "helloworld.grpc.pb.h" -#endif - -using grpc::Server; -using grpc::ServerBuilder; -using grpc::ServerContext; -using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; -using helloworld::Greeter; - -// Logic and data behind the server's behavior. -class GreeterServiceImpl final : public Greeter::Service { - Status SayHello(ServerContext* context, const HelloRequest* request, - HelloReply* reply) override { - std::string prefix("Hello "); - - // Get the client's initial metadata - std::cout << "Client metadata: " << std::endl; - const std::multimap metadata = context->client_metadata(); - for (auto iter = metadata.begin(); iter != metadata.end(); ++iter) { - std::cout << "Header key: " << iter->first << ", value: "; - // Check for binary value - size_t isbin = iter->first.find("-bin"); - if ((isbin != std::string::npos) && (isbin + 4 == iter->first.size())) { - std::cout << std::hex; - for (auto c : iter->second) { - std::cout << static_cast(c); - } - std::cout << std::dec; - } else { - std::cout << iter->second; - } - std::cout << std::endl; - } - - context->AddInitialMetadata("custom-server-metadata", "initial metadata value"); - context->AddTrailingMetadata("custom-trailing-metadata", "trailing metadata value"); - reply->set_message(prefix + request->name()); - return Status::OK; - } -}; - -void RunServer() { - std::string server_address("0.0.0.0:50051"); - GreeterServiceImpl service; - - ServerBuilder builder; - // Listen on the given address without any authentication mechanism. - builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); - // Register "service" as the instance through which we'll communicate with - // clients. In this case it corresponds to an *synchronous* service. - builder.RegisterService(&service); - // Finally assemble the server. - std::unique_ptr server(builder.BuildAndStart()); - std::cout << "Server listening on " << server_address << std::endl; - - // Wait for the server to shutdown. Note that some other thread must be - // responsible for shutting down the server for this call to ever return. - server->Wait(); -} - -int main(int argc, char** argv) { - RunServer(); - - return 0; -} From 1bd231605a341bea7ac841b72be212bb8df12f25 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 17 Dec 2018 11:21:15 -0800 Subject: [PATCH 0579/2143] Revert "re-enable ExitTest" --- src/python/grpcio_tests/commands.py | 8 -------- src/python/grpcio_tests/tests/unit/_exit_test.py | 15 +-------------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 18413abab02..65e9a99950e 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -133,14 +133,6 @@ class TestGevent(setuptools.Command): # TODO(https://github.com/grpc/grpc/issues/15411) unpin gevent version # 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._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', - 'unit._exit_test.ExitTest.test_in_flight_stream_stream_call', - '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', # 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', diff --git a/src/python/grpcio_tests/tests/unit/_exit_test.py b/src/python/grpcio_tests/tests/unit/_exit_test.py index b429ee089f7..52265375799 100644 --- a/src/python/grpcio_tests/tests/unit/_exit_test.py +++ b/src/python/grpcio_tests/tests/unit/_exit_test.py @@ -71,6 +71,7 @@ def wait(process): process.wait() +@unittest.skip('https://github.com/grpc/grpc/issues/7311') class ExitTest(unittest.TestCase): def test_unstarted_server(self): @@ -129,8 +130,6 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_unary_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_UNARY_CALL], @@ -139,8 +138,6 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_STREAM_CALL], @@ -148,8 +145,6 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_UNARY_CALL], @@ -158,8 +153,6 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_STREAM_CALL], @@ -168,8 +161,6 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_partial_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -178,8 +169,6 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -189,8 +178,6 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') - @unittest.skipIf(os.name == 'nt', - 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + From 93151145c20e50816e38a73c167ed16e288eb4f6 Mon Sep 17 00:00:00 2001 From: hcaseyal Date: Mon, 17 Dec 2018 12:09:11 -0800 Subject: [PATCH 0580/2143] Revert "Revert "Metadata tutorial"" --- examples/BUILD | 15 ++++ examples/cpp/metadata/Makefile | 96 +++++++++++++++++++++++++ examples/cpp/metadata/README.md | 66 +++++++++++++++++ examples/cpp/metadata/greeter_client.cc | 95 ++++++++++++++++++++++++ examples/cpp/metadata/greeter_server.cc | 94 ++++++++++++++++++++++++ 5 files changed, 366 insertions(+) create mode 100644 examples/cpp/metadata/Makefile create mode 100644 examples/cpp/metadata/README.md create mode 100644 examples/cpp/metadata/greeter_client.cc create mode 100644 examples/cpp/metadata/greeter_server.cc diff --git a/examples/BUILD b/examples/BUILD index 0f18cfa9ba7..22f2f0a4f1a 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -51,3 +51,18 @@ cc_binary( defines = ["BAZEL_BUILD"], deps = [":helloworld", "//:grpc++"], ) + +cc_binary( + name = "metadata_client", + srcs = ["cpp/metadata/greeter_client.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) + +cc_binary( + name = "metadata_server", + srcs = ["cpp/metadata/greeter_server.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) + diff --git a/examples/cpp/metadata/Makefile b/examples/cpp/metadata/Makefile new file mode 100644 index 00000000000..46be8bfaa3c --- /dev/null +++ b/examples/cpp/metadata/Makefile @@ -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. +# + HOST_SYSTEM = $(shell uname | cut -f 1 -d_) +SYSTEM ?= $(HOST_SYSTEM) +CXX = g++ +CPPFLAGS += `pkg-config --cflags protobuf grpc` +CXXFLAGS += -std=c++11 +ifeq ($(SYSTEM),Darwin) +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -lgrpc++_reflection\ + -ldl +else +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ + -ldl +endif +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + PROTOS_PATH = ../../protos + vpath %.proto $(PROTOS_PATH) + all: system-check greeter_client greeter_server + greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + .PRECIOUS: %.grpc.pb.cc +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + .PRECIOUS: %.pb.cc +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + clean: + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server + # The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif diff --git a/examples/cpp/metadata/README.md b/examples/cpp/metadata/README.md new file mode 100644 index 00000000000..96ad3d19bdb --- /dev/null +++ b/examples/cpp/metadata/README.md @@ -0,0 +1,66 @@ +# Metadata Example + +## Overview + +This example shows you how to add custom headers on the client and server and +how to access them. + +Custom metadata must follow the "Custom-Metadata" format listed in +https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md, with the +exception of binary headers, which don't have to be base64 encoded. + +### Get the tutorial source code + The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: + ```sh +$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc +``` + Change your current directory to examples/cpp/metadata + ```sh +$ cd examples/cpp/metadata +``` + +### Generating gRPC code + To generate the client and server side interfaces: + ```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + ```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` +### Try it! +Build client and server: + +```sh +$ make +``` + +Run the server, which will listen on port 50051: + +```sh +$ ./greeter_server +``` + +Run the client (in a different terminal): + +```sh +$ ./greeter_client +``` + +If things go smoothly, you will see in the client terminal: + +"Client received initial metadata from server: initial metadata value" +"Client received trailing metadata from server: trailing metadata value" +"Client received message: Hello World" + + +And in the server terminal: + +"Header key: custom-bin , value: 01234567" +"Header key: custom-header , value: Custom Value" +"Header key: user-agent , value: grpc-c++/1.16.0-dev grpc-c/6.0.0-dev (linux; chttp2; gao)" + +We did not add the user-agent metadata as a custom header. This shows how +the gRPC framework adds some headers under the hood that may show up in the +metadata map. diff --git a/examples/cpp/metadata/greeter_client.cc b/examples/cpp/metadata/greeter_client.cc new file mode 100644 index 00000000000..80494389937 --- /dev/null +++ b/examples/cpp/metadata/greeter_client.cc @@ -0,0 +1,95 @@ +/* + * + * 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 +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class CustomHeaderClient { + public: + CustomHeaderClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + HelloRequest request; + request.set_name(user); + + // Container for the data we expect from the server. + HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + + // Setting custom metadata to be sent to the server + context.AddMetadata("custom-header", "Custom Value"); + + // Setting custom binary metadata + char bytes[8] = {'\0', '\1', '\2', '\3', + '\4', '\5', '\6', '\7'}; + context.AddMetadata("custom-bin", grpc::string(bytes, 8)); + + // The actual RPC. + Status status = stub_->SayHello(&context, request, &reply); + + // Act upon its status. + if (status.ok()) { + std::cout << "Client received initial metadata from server: " << context.GetServerInitialMetadata().find("custom-server-metadata")->second << std::endl; + std::cout << "Client received trailing metadata from server: " << context.GetServerTrailingMetadata().find("custom-trailing-metadata")->second << std::endl; + return reply.message(); + } else { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + return "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // 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()). + CustomHeaderClient greeter(grpc::CreateChannel( + "localhost:50051", grpc::InsecureChannelCredentials())); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Client received message: " << reply << std::endl; + return 0; +} diff --git a/examples/cpp/metadata/greeter_server.cc b/examples/cpp/metadata/greeter_server.cc new file mode 100644 index 00000000000..a9a4f33cb0b --- /dev/null +++ b/examples/cpp/metadata/greeter_server.cc @@ -0,0 +1,94 @@ +/* + * + * 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 +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { + Status SayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + std::string prefix("Hello "); + + // Get the client's initial metadata + std::cout << "Client metadata: " << std::endl; + const std::multimap metadata = context->client_metadata(); + for (auto iter = metadata.begin(); iter != metadata.end(); ++iter) { + std::cout << "Header key: " << iter->first << ", value: "; + // Check for binary value + size_t isbin = iter->first.find("-bin"); + if ((isbin != std::string::npos) && (isbin + 4 == iter->first.size())) { + std::cout << std::hex; + for (auto c : iter->second) { + std::cout << static_cast(c); + } + std::cout << std::dec; + } else { + std::cout << iter->second; + } + std::cout << std::endl; + } + + context->AddInitialMetadata("custom-server-metadata", "initial metadata value"); + context->AddTrailingMetadata("custom-trailing-metadata", "trailing metadata value"); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} From 7bd03aeb0d007e9c820d4d426c50accc85392b36 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 17 Dec 2018 14:24:35 -0800 Subject: [PATCH 0581/2143] Revert "Revert "re-enable ExitTest"" This reverts commit 1bd231605a341bea7ac841b72be212bb8df12f25. --- src/python/grpcio_tests/commands.py | 8 ++++++++ src/python/grpcio_tests/tests/unit/_exit_test.py | 15 ++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 65e9a99950e..18413abab02 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -133,6 +133,14 @@ class TestGevent(setuptools.Command): # TODO(https://github.com/grpc/grpc/issues/15411) unpin gevent version # 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._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', + 'unit._exit_test.ExitTest.test_in_flight_stream_stream_call', + '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', # 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', diff --git a/src/python/grpcio_tests/tests/unit/_exit_test.py b/src/python/grpcio_tests/tests/unit/_exit_test.py index 52265375799..b429ee089f7 100644 --- a/src/python/grpcio_tests/tests/unit/_exit_test.py +++ b/src/python/grpcio_tests/tests/unit/_exit_test.py @@ -71,7 +71,6 @@ def wait(process): process.wait() -@unittest.skip('https://github.com/grpc/grpc/issues/7311') class ExitTest(unittest.TestCase): def test_unstarted_server(self): @@ -130,6 +129,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_unary_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_UNARY_CALL], @@ -138,6 +139,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_STREAM_CALL], @@ -145,6 +148,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_UNARY_CALL], @@ -153,6 +158,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_STREAM_CALL], @@ -161,6 +168,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -169,6 +178,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -178,6 +189,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + From b1407a95c3183714557d753d704bd6b98e603258 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 17 Dec 2018 14:51:20 -0800 Subject: [PATCH 0582/2143] Improve grpclb trace logging. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 57 ++++++++++--------- 1 file changed, 31 insertions(+), 26 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 a9a5965ed1c..6671e708c84 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 @@ -525,8 +525,7 @@ void GrpcLb::BalancerCallState::Orphan() { void GrpcLb::BalancerCallState::StartQuery() { GPR_ASSERT(lb_call_ != nullptr); if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] Starting LB call (lb_calld: %p, lb_call: %p)", + gpr_log(GPR_INFO, "[grpclb %p] lb_calld=%p: Starting LB call %p", grpclb_policy_.get(), this, lb_call_); } // Create the ops. @@ -670,8 +669,9 @@ void GrpcLb::BalancerCallState::SendClientLoadReportLocked() { grpc_call_error call_error = grpc_call_start_batch_and_execute( lb_call_, &op, 1, &client_load_report_closure_); if (GPR_UNLIKELY(call_error != GRPC_CALL_OK)) { - gpr_log(GPR_ERROR, "[grpclb %p] call_error=%d", grpclb_policy_.get(), - call_error); + gpr_log(GPR_ERROR, + "[grpclb %p] lb_calld=%p call_error=%d sending client load report", + grpclb_policy_.get(), this, call_error); GPR_ASSERT(GRPC_CALL_OK == call_error); } } @@ -732,15 +732,17 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( &initial_response->client_stats_report_interval)); if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p] Received initial LB response message; " - "client load reporting interval = %" PRId64 " milliseconds", - grpclb_policy, lb_calld->client_stats_report_interval_); + "[grpclb %p] lb_calld=%p: Received initial LB response " + "message; client load reporting interval = %" PRId64 + " milliseconds", + grpclb_policy, lb_calld, + lb_calld->client_stats_report_interval_); } } else if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p] Received initial LB response message; client load " - "reporting NOT enabled", - grpclb_policy); + "[grpclb %p] lb_calld=%p: Received initial LB response message; " + "client load reporting NOT enabled", + grpclb_policy, lb_calld); } grpc_grpclb_initial_response_destroy(initial_response); lb_calld->seen_initial_response_ = true; @@ -750,15 +752,17 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( GPR_ASSERT(lb_calld->lb_call_ != nullptr); if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p] Serverlist with %" PRIuPTR " servers received", - grpclb_policy, serverlist->num_servers); + "[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] Serverlist[%" PRIuPTR "]: %s", - grpclb_policy, i, ipport); + gpr_log(GPR_INFO, + "[grpclb %p] lb_calld=%p: Serverlist[%" PRIuPTR "]: %s", + grpclb_policy, lb_calld, i, ipport); gpr_free(ipport); } } @@ -778,9 +782,9 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_, serverlist)) { if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p] Incoming server list identical to current, " - "ignoring.", - grpclb_policy); + "[grpclb %p] lb_calld=%p: Incoming server list identical to " + "current, ignoring.", + grpclb_policy, lb_calld); } grpc_grpclb_destroy_serverlist(serverlist); } else { // New serverlist. @@ -806,8 +810,9 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( char* response_slice_str = grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX); gpr_log(GPR_ERROR, - "[grpclb %p] Invalid LB response received: '%s'. Ignoring.", - grpclb_policy, response_slice_str); + "[grpclb %p] lb_calld=%p: Invalid LB response received: '%s'. " + "Ignoring.", + grpclb_policy, lb_calld, response_slice_str); gpr_free(response_slice_str); } grpc_slice_unref_internal(response_slice); @@ -838,9 +843,9 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( char* status_details = grpc_slice_to_c_string(lb_calld->lb_call_status_details_); gpr_log(GPR_INFO, - "[grpclb %p] Status from LB server received. Status = %d, details " - "= '%s', (lb_calld: %p, lb_call: %p), error '%s'", - grpclb_policy, lb_calld->lb_call_status_, status_details, lb_calld, + "[grpclb %p] lb_calld=%p: Status from LB server received. " + "Status = %d, details = '%s', (lb_call: %p), error '%s'", + grpclb_policy, lb_calld, lb_calld->lb_call_status_, status_details, lb_calld->lb_call_, grpc_error_string(error)); gpr_free(status_details); } @@ -1592,6 +1597,10 @@ void GrpcLb::CreateRoundRobinPolicyLocked(const Args& args) { this); return; } + if (grpc_lb_glb_trace.enabled()) { + 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"); @@ -1685,10 +1694,6 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { lb_policy_args.client_channel_factory = client_channel_factory(); lb_policy_args.args = args; CreateRoundRobinPolicyLocked(lb_policy_args); - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this, - rr_policy_.get()); - } } grpc_channel_args_destroy(args); } From 05d3ab2852cb2d7ce13f7ca059b36884e37175fd Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 17 Dec 2018 14:54:10 -0800 Subject: [PATCH 0583/2143] Address comments, improve tests --- .../grpcio_tests/tests/unit/BUILD.bazel | 1 + .../tests/unit/_server_shutdown_scenarios.py | 36 ++++++------------- .../tests/unit/_server_shutdown_test.py | 2 ++ 3 files changed, 13 insertions(+), 26 deletions(-) diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel index 4f850220f8f..7a910fd9feb 100644 --- a/src/python/grpcio_tests/tests/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel @@ -28,6 +28,7 @@ GRPCIO_TESTS_UNIT = [ # TODO(ghostwriternr): To be added later. # "_server_ssl_cert_config_test.py", "_server_test.py", + "_server_shutdown_test.py", "_session_cache_test.py", ] diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py index acbec0f77dd..1797e9bbfec 100644 --- a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py @@ -20,6 +20,7 @@ import time import logging import grpc +from tests.unit import test_common from concurrent import futures from six.moves import queue @@ -36,37 +37,24 @@ SERVER_FORK_CAN_EXIT = 'server_fork_can_exit' FORK_EXIT = '/test/ForkExit' -class ForkExitHandler(object): - - def unary_unary(self, request, servicer_context): - pid = os.fork() - if pid == 0: - os._exit(0) - return RESPONSE - - def __init__(self): - self.request_streaming = None - self.response_streaming = None - self.request_deserializer = None - self.response_serializer = None - self.unary_stream = None - self.stream_unary = None - self.stream_stream = None +def fork_and_exit(request, servicer_context): + pid = os.fork() + if pid == 0: + os._exit(0) + return RESPONSE class GenericHandler(grpc.GenericRpcHandler): def service(self, handler_call_details): if handler_call_details.method == FORK_EXIT: - return ForkExitHandler() + return grpc.unary_unary_rpc_method_handler(fork_and_exit) else: return None def run_server(port_queue): - server = grpc.server( - futures.ThreadPoolExecutor(max_workers=10), - options=(('grpc.so_reuseport', 0),)) + server = test_common.test_server() port = server.add_insecure_port('[::]:0') port_queue.put(port) server.add_generic_rpc_handlers((GenericHandler(),)) @@ -78,15 +66,11 @@ def run_server(port_queue): def run_test(args): if args.scenario == SERVER_RAISES_EXCEPTION: - server = grpc.server( - futures.ThreadPoolExecutor(max_workers=1), - options=(('grpc.so_reuseport', 0),)) + server = test_common.test_server() server.start() raise Exception() elif args.scenario == SERVER_DEALLOCATED: - server = grpc.server( - futures.ThreadPoolExecutor(max_workers=1), - options=(('grpc.so_reuseport', 0),)) + server = test_common.test_server() server.start() server.__del__() while server._state.stage != grpc._server._ServerStage.STOPPED: diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py index 0e4591c5e56..47446d65a51 100644 --- a/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py @@ -60,6 +60,8 @@ def wait(process): class ServerShutdown(unittest.TestCase): + # Currently we shut down a server (if possible) after the Python server + # instance is garbage collected. This behavior may change in the future. def test_deallocated_server_stops(self): process = subprocess.Popen( BASE_COMMAND + [_server_shutdown_scenarios.SERVER_DEALLOCATED], From 08a90f03d4d0ac846f517c9aeab7aeb05b1cfdca Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 17 Dec 2018 15:09:59 -0800 Subject: [PATCH 0584/2143] Remove the fake package dependency && temporarily skip the Channelz tests --- src/python/grpcio_tests/setup.py | 12 +++++++++--- .../tests/channelz/_channelz_servicer_test.py | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py index f9cb9d0cec9..800b865da62 100644 --- a/src/python/grpcio_tests/setup.py +++ b/src/python/grpcio_tests/setup.py @@ -37,13 +37,19 @@ 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), - 'grpcio-channelz>={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-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 8ca51895224..d060a4973e4 100644 --- a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -93,6 +93,7 @@ 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 c52ae0d0005ccf98c6e734db34cd2634e5aa26ef Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 17 Dec 2018 13:27:42 -0800 Subject: [PATCH 0585/2143] Give the interceptors header files in include/grpcpp/support --- BUILD | 3 +++ CMakeLists.txt | 9 +++++++ Makefile | 9 +++++++ build.yaml | 3 +++ gRPC-C++.podspec | 3 +++ include/grpcpp/support/client_interceptor.h | 24 +++++++++++++++++++ include/grpcpp/support/interceptor.h | 24 +++++++++++++++++++ include/grpcpp/support/server_interceptor.h | 24 +++++++++++++++++++ .../client_interceptors_end2end_test.cc | 2 +- .../server_interceptors_end2end_test.cc | 2 +- tools/doxygen/Doxyfile.c++ | 3 +++ tools/doxygen/Doxyfile.c++.internal | 3 +++ .../generated/sources_and_headers.json | 6 +++++ 13 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 include/grpcpp/support/client_interceptor.h create mode 100644 include/grpcpp/support/interceptor.h create mode 100644 include/grpcpp/support/server_interceptor.h diff --git a/BUILD b/BUILD index fe93f1281ed..b9b39a37a7e 100644 --- a/BUILD +++ b/BUILD @@ -244,10 +244,13 @@ GRPCXX_PUBLIC_HDRS = [ "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", diff --git a/CMakeLists.txt b/CMakeLists.txt index b6ceb50a5f1..378681ae20b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3034,10 +3034,13 @@ foreach(_hdr 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 @@ -3619,10 +3622,13 @@ foreach(_hdr 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 @@ -4571,10 +4577,13 @@ foreach(_hdr 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 diff --git a/Makefile b/Makefile index 7b4a1fb0d5e..c433ac4cfcb 100644 --- a/Makefile +++ b/Makefile @@ -5405,10 +5405,13 @@ PUBLIC_HEADERS_CXX += \ 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 \ @@ -5999,10 +6002,13 @@ PUBLIC_HEADERS_CXX += \ 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 \ @@ -6908,10 +6914,13 @@ PUBLIC_HEADERS_CXX += \ 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 \ diff --git a/build.yaml b/build.yaml index 7f1f11a3c03..8e80cf3fb04 100644 --- a/build.yaml +++ b/build.yaml @@ -1365,10 +1365,13 @@ filegroups: - 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 diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 414e788a962..f918fe8ad9c 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -116,10 +116,13 @@ Pod::Spec.new do |s| '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', diff --git a/include/grpcpp/support/client_interceptor.h b/include/grpcpp/support/client_interceptor.h new file mode 100644 index 00000000000..50810e3fe3c --- /dev/null +++ b/include/grpcpp/support/client_interceptor.h @@ -0,0 +1,24 @@ +/* + * + * 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_SUPPORT_CLIENT_INTERCEPTOR_H +#define GRPCPP_SUPPORT_CLIENT_INTERCEPTOR_H + +#include + +#endif // GRPCPP_SUPPORT_CLIENT_INTERCEPTOR_H diff --git a/include/grpcpp/support/interceptor.h b/include/grpcpp/support/interceptor.h new file mode 100644 index 00000000000..7ff79516bae --- /dev/null +++ b/include/grpcpp/support/interceptor.h @@ -0,0 +1,24 @@ +/* + * + * 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_SUPPORT_INTERCEPTOR_H +#define GRPCPP_SUPPORT_INTERCEPTOR_H + +#include + +#endif // GRPCPP_SUPPORT_INTERCEPTOR_H diff --git a/include/grpcpp/support/server_interceptor.h b/include/grpcpp/support/server_interceptor.h new file mode 100644 index 00000000000..b0a6229b667 --- /dev/null +++ b/include/grpcpp/support/server_interceptor.h @@ -0,0 +1,24 @@ +/* + * + * 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_SUPPORT_SERVER_INTERCEPTOR_H +#define GRPCPP_SUPPORT_SERVER_INTERCEPTOR_H + +#include + +#endif // GRPCPP_SUPPORT_SERVER_INTERCEPTOR_H diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 968b5d49d10..34f5b93cabc 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -23,11 +23,11 @@ #include #include #include -#include #include #include #include #include +#include #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 9460a7d6c64..4efe13fdec1 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -24,10 +24,10 @@ #include #include #include -#include #include #include #include +#include #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index a5f817997dc..1ab3a394b96 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -1008,10 +1008,13 @@ 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 \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 1535aa06d32..5f488d51940 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1010,10 +1010,13 @@ 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 \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 40c49895fd7..ad8c894fde6 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11546,10 +11546,13 @@ "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", @@ -11652,10 +11655,13 @@ "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", From afc2fabe0c16efbf768c70f365688156b457619d Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 17 Dec 2018 16:10:06 -0800 Subject: [PATCH 0586/2143] Avoid taking refs on the stream by getting a copy of the context --- .../chttp2/transport/context_list.cc | 38 +++++++++++++------ .../transport/chttp2/transport/context_list.h | 35 ++++------------- 2 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc index f30d41c3326..df09809067d 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.cc +++ b/src/core/ext/transport/chttp2/transport/context_list.cc @@ -21,31 +21,47 @@ #include "src/core/ext/transport/chttp2/transport/context_list.h" namespace { -void (*write_timestamps_callback_g)(void*, grpc_core::Timestamps*) = nullptr; -} +void (*write_timestamps_callback_g)(void*, grpc_core::Timestamps*, + grpc_error* error) = nullptr; +void* (*get_copied_context_fn_g)(void*) = nullptr; +} // namespace namespace grpc_core { +void ContextList::Append(ContextList** head, grpc_chttp2_stream* s) { + if (get_copied_context_fn_g == nullptr || + write_timestamps_callback_g == nullptr) { + return; + } + /* Create a new element in the list and add it at the front */ + ContextList* elem = grpc_core::New(); + elem->trace_context_ = get_copied_context_fn_g(s->context); + elem->byte_offset_ = s->byte_counter; + elem->next_ = *head; + *head = elem; +} + void ContextList::Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error) { ContextList* head = static_cast(arg); ContextList* to_be_freed; while (head != nullptr) { - if (error == GRPC_ERROR_NONE && ts != nullptr) { - if (write_timestamps_callback_g) { - ts->byte_offset = static_cast(head->byte_offset_); - write_timestamps_callback_g(head->s_->context, ts); - } + if (write_timestamps_callback_g) { + ts->byte_offset = static_cast(head->byte_offset_); + write_timestamps_callback_g(head->trace_context_, ts, error); } - GRPC_CHTTP2_STREAM_UNREF(static_cast(head->s_), - "timestamp"); to_be_freed = head; head = head->next_; grpc_core::Delete(to_be_freed); } } -void grpc_http2_set_write_timestamps_callback( - void (*fn)(void*, grpc_core::Timestamps*)) { +void grpc_http2_set_write_timestamps_callback(void (*fn)(void*, + grpc_core::Timestamps*, + grpc_error* error)) { write_timestamps_callback_g = fn; } + +void grpc_http2_set_fn_get_copied_context(void* (*fn)(void*)) { + get_copied_context_fn_g = fn; +} } /* namespace grpc_core */ diff --git a/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h index d8701077494..5b9d2ab3784 100644 --- a/src/core/ext/transport/chttp2/transport/context_list.h +++ b/src/core/ext/transport/chttp2/transport/context_list.h @@ -31,42 +31,23 @@ class ContextList { public: /* Creates a new element with \a context as the value and appends it to the * list. */ - static void Append(ContextList** head, grpc_chttp2_stream* s) { - /* Make sure context is not already present */ - GRPC_CHTTP2_STREAM_REF(s, "timestamp"); - -#ifndef NDEBUG - ContextList* ptr = *head; - while (ptr != nullptr) { - if (ptr->s_ == s) { - GPR_ASSERT( - false && - "Trying to append a stream that is already present in the list"); - } - ptr = ptr->next_; - } -#endif - - /* Create a new element in the list and add it at the front */ - ContextList* elem = grpc_core::New(); - elem->s_ = s; - elem->byte_offset_ = s->byte_counter; - elem->next_ = *head; - *head = elem; - } + static void Append(ContextList** head, grpc_chttp2_stream* s); /* Executes a function \a fn with each context in the list and \a ts. It also - * frees up the entire list after this operation. */ + * frees up the entire list after this operation. It is intended as a callback + * and hence does not take a ref on \a error */ static void Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error); private: - grpc_chttp2_stream* s_ = nullptr; + void* trace_context_ = nullptr; ContextList* next_ = nullptr; size_t byte_offset_ = 0; }; -void grpc_http2_set_write_timestamps_callback( - void (*fn)(void*, grpc_core::Timestamps*)); +void grpc_http2_set_write_timestamps_callback(void (*fn)(void*, + grpc_core::Timestamps*, + grpc_error* error)); +void grpc_http2_set_fn_get_copied_context(void* (*fn)(void*)); } /* namespace grpc_core */ #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H */ From 906cf5b428f31513321c8d2e3530aa7a03cca400 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 17 Dec 2018 16:15:46 -0800 Subject: [PATCH 0587/2143] Add error details on context list clearing --- .../ext/transport/chttp2/transport/chttp2_transport.cc | 7 ++++--- 1 file changed, 4 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 9b6574b612d..3b7c48a72ca 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -170,9 +170,6 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { grpc_slice_buffer_destroy_internal(&outbuf); grpc_chttp2_hpack_compressor_destroy(&hpack_compressor); - grpc_core::ContextList::Execute(cl, nullptr, GRPC_ERROR_NONE); - cl = nullptr; - grpc_slice_buffer_destroy_internal(&read_buffer); grpc_chttp2_hpack_parser_destroy(&hpack_parser); grpc_chttp2_goaway_parser_destroy(&goaway_parser); @@ -569,6 +566,10 @@ static void close_transport_locked(grpc_chttp2_transport* t, grpc_error* error) { end_all_the_calls(t, GRPC_ERROR_REF(error)); cancel_pings(t, GRPC_ERROR_REF(error)); + // ContextList::Execute follows semantics of a callback function and does not + // need a ref on error + grpc_core::ContextList::Execute(cl, nullptr, error); + cl = nullptr; if (t->closed_with_error == GRPC_ERROR_NONE) { if (!grpc_error_has_clear_grpc_status(error)) { error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, From 6692429f31dc715e55fe37d95837b773494fcd99 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 17 Dec 2018 16:25:25 -0800 Subject: [PATCH 0588/2143] Download private key from KeyStore --- .../linux/pull_request/grpc_microbenchmark_diff.cfg | 8 ++++++++ .../internal_ci/linux/pull_request/grpc_trickle_diff.cfg | 8 ++++++++ .../macos/pull_request/grpc_ios_binary_size.cfg | 8 ++++++++ tools/run_tests/python_utils/check_on_pr.py | 4 ++-- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg b/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg index 47301d61415..3c62401cc3a 100644 --- a/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg @@ -17,6 +17,14 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/linux/grpc_microbenchmark_diff.sh" timeout_mins: 120 +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73836 + keyname: "grpc_checks_private_key" + } + } +} action { define_artifacts { regex: "**/*sponge_log.*" diff --git a/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg b/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg index 78358eac28e..69e44276625 100644 --- a/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg @@ -17,6 +17,14 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/linux/grpc_trickle_diff.sh" timeout_mins: 120 +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73836 + keyname: "grpc_checks_private_key" + } + } +} action { define_artifacts { regex: "**/*sponge_log.*" 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 fb215bdf994..1c4f7b23109 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 @@ -18,6 +18,14 @@ 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 { + keystore_config_id: 73836 + keyname: "grpc_checks_private_key" + } + } +} action { define_artifacts { regex: "**/*sponge_log.*" diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index f756e4bdaa4..78f1dca817d 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -26,8 +26,8 @@ _GITHUB_REPO = 'grpc/grpc' _GITHUB_APP_ID = 22338 _INSTALLATION_ID = 519109 _GITHUB_APP_KEY = open( - os.environ['HOME'] + '/.ssh/google-grpc-checker.2018-12-13.private-key.pem', - 'r').read() + os.path.join(os.environ['KOKORO_KEYSTORE_DIR'], '73836_grpc_checks_private_key'), + 'rb').read() _ACCESS_TOKEN_CACHE = None From 915cd71b4a6aceb8003077e0e360ea7accbde38c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 17 Dec 2018 17:36:28 -0800 Subject: [PATCH 0589/2143] nullability revert --- src/objective-c/GRPCClient/GRPCCall.h | 32 +++++++++++++----------- src/objective-c/ProtoRPC/ProtoRPC.h | 9 +++---- src/objective-c/ProtoRPC/ProtoService.h | 33 +++++++++++++------------ 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 15b1c904498..6669067fbff 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -275,6 +275,9 @@ extern NSString *const kGRPCTrailersKey; NS_ASSUME_NONNULL_END +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability-completeness" + /** * This interface is deprecated. Please use \a GRPCcall2. * @@ -282,7 +285,7 @@ NS_ASSUME_NONNULL_END */ @interface GRPCCall : GRXWriter -- (nonnull instancetype)init NS_UNAVAILABLE; +- (instancetype)init NS_UNAVAILABLE; /** * The container of the request headers of an RPC conforms to this protocol, which is a subset of @@ -308,7 +311,7 @@ NS_ASSUME_NONNULL_END * * The property is initialized to an empty NSMutableDictionary. */ -@property(nonnull, atomic, readonly) NSMutableDictionary *requestHeaders; +@property(atomic, readonly) NSMutableDictionary *requestHeaders; /** * This dictionary is populated with the HTTP headers received from the server. This happens before @@ -319,7 +322,7 @@ NS_ASSUME_NONNULL_END * The value of this property is nil until all response headers are received, and will change before * any of -writeValue: or -writesFinishedWithError: are sent to the writeable. */ -@property(nullable, atomic, readonly) NSDictionary *responseHeaders; +@property(atomic, readonly) NSDictionary *responseHeaders; /** * Same as responseHeaders, but populated with the HTTP trailers received from the server before the @@ -328,7 +331,7 @@ NS_ASSUME_NONNULL_END * The value of this property is nil until all response trailers are received, and will change * before -writesFinishedWithError: is sent to the writeable. */ -@property(nullable, atomic, readonly) NSDictionary *responseTrailers; +@property(atomic, readonly) NSDictionary *responseTrailers; /** * The request writer has to write NSData objects into the provided Writeable. The server will @@ -341,9 +344,9 @@ NS_ASSUME_NONNULL_END * host parameter should not contain the scheme (http:// or https://), only the name or IP addr * and the port number, for example @"localhost:5050". */ -- (nullable instancetype)initWithHost:(nonnull NSString *)host - path:(nonnull NSString *)path - requestsWriter:(nonnull GRXWriter *)requestWriter; +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + requestsWriter:(GRXWriter *)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -354,12 +357,10 @@ NS_ASSUME_NONNULL_END /** * The following methods are deprecated. */ -+ (void)setCallSafety:(GRPCCallSafety)callSafety - host:(nonnull NSString *)host - path:(nonnull NSString *)path; -@property(nullable, atomic, copy, readwrite) NSString *serverName; ++ (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path; +@property(atomic, copy, readwrite) NSString *serverName; @property NSTimeInterval timeout; -- (void)setResponseDispatchQueue:(nonnull dispatch_queue_t)queue; +- (void)setResponseDispatchQueue:(dispatch_queue_t)queue; @end @@ -370,11 +371,11 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @protocol GRPCRequestHeaders @property(nonatomic, readonly) NSUInteger count; -- (nullable id)objectForKeyedSubscript:(nonnull id)key; -- (void)setObject:(nonnull id)obj forKeyedSubscript:(nonnull id)key; +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)obj forKeyedSubscript:(id)key; - (void)removeAllObjects; -- (void)removeObjectForKey:(nonnull id)key; +- (void)removeObjectForKey:(id)key; @end #pragma clang diagnostic push @@ -383,3 +384,4 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @interface NSMutableDictionary (GRPCRequestHeaders) @end #pragma clang diagnostic pop +#pragma clang diagnostic pop diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index e6ba1f66ca5..91a50d395af 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -142,11 +142,10 @@ __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC * addr and the port number, for example @"localhost:5050". */ - - (nullable instancetype)initWithHost : (nonnull NSString *)host method - : (nonnull GRPCProtoMethod *)method requestsWriter - : (nonnull GRXWriter *)requestsWriter responseClass - : (nonnull Class)responseClass responsesWriteable - : (nonnull id)responsesWriteable NS_DESIGNATED_INITIALIZER; + (instancetype)initWithHost : (NSString *)host method + : (GRPCProtoMethod *)method requestsWriter : (GRXWriter *)requestsWriter responseClass + : (Class)responseClass responsesWriteable + : (id)responsesWriteable NS_DESIGNATED_INITIALIZER; - (void)start; @end diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index 70423ee9def..d76e96ce2a6 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -27,38 +27,41 @@ @class GRPCStreamingProtoCall; @protocol GRPCProtoResponseCallbacks; -NS_ASSUME_NONNULL_BEGIN +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability-completeness" __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoService : NSObject - - (nullable instancetype)initWithHost : (NSString *)host packageName - : (NSString *)packageName serviceName : (NSString *)serviceName callOptions + (nullable instancetype)initWithHost : (nonnull NSString *)host packageName + : (nonnull NSString *)packageName serviceName : (nonnull NSString *)serviceName callOptions : (nullable GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName serviceName:(NSString *)serviceName; -- (nullable GRPCProtoCall *)RPCToMethod:(NSString *)method - requestsWriter:(GRXWriter *)requestsWriter - responseClass:(Class)responseClass - responsesWriteable:(id)responsesWriteable; +- (GRPCProtoCall *)RPCToMethod:(NSString *)method + requestsWriter:(GRXWriter *)requestsWriter + responseClass:(Class)responseClass + responsesWriteable:(id)responsesWriteable; -- (nullable GRPCUnaryProtoCall *)RPCToMethod:(NSString *)method - message:(id)message - responseHandler:(id)handler +- (nullable GRPCUnaryProtoCall *)RPCToMethod:(nonnull NSString *)method + message:(nonnull id)message + responseHandler:(nonnull id)handler callOptions:(nullable GRPCCallOptions *)callOptions - responseClass:(Class)responseClass; + responseClass:(nonnull Class)responseClass; -- (nullable GRPCStreamingProtoCall *)RPCToMethod:(NSString *)method - responseHandler:(id)handler +- (nullable GRPCStreamingProtoCall *)RPCToMethod:(nonnull NSString *)method + responseHandler:(nonnull id)handler callOptions:(nullable GRPCCallOptions *)callOptions - responseClass:(Class)responseClass; + responseClass:(nonnull Class)responseClass; @end +#pragma clang diagnostic pop + /** * This subclass is empty now. Eventually we'll remove ProtoService class * to avoid potential naming conflict @@ -69,5 +72,3 @@ __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoServ #pragma clang diagnostic pop @end - - NS_ASSUME_NONNULL_END From eafb1d527d8fc1f367215429fde9421aac876ef2 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 17 Dec 2018 18:14:58 -0800 Subject: [PATCH 0590/2143] Reorgnize dependencies and variables --- .../prepare_build_linux_perf_rc | 5 +++ .../helper_scripts/prepare_build_macos_rc | 4 +- tools/run_tests/python_utils/check_on_pr.py | 37 ++++++++++--------- 3 files changed, 27 insertions(+), 19 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 dc3c75a6a12..8223e03abd5 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc @@ -34,4 +34,9 @@ fi sudo pip install tabulate +# Python dependencies for tools/run_tests/python_utils/check_on_pr.py +sudo -H pip install pyjwt cryptography requests + +ls -al "${KOKORO_KEYSTORE_DIR}/73836_grpc_checks_private_key" + git submodule update --init diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index bafe0d98c1a..b770808db99 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -31,6 +31,8 @@ date pip install google-api-python-client oauth2client --user python export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json +ls -al "${KOKORO_KEYSTORE_DIR}/73836_grpc_checks_private_key" + # 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 @@ -63,7 +65,7 @@ time pod repo update # needed by python # python time pip install virtualenv --user python -time pip install -U Mako six tox setuptools twisted pyyaml --user python +time pip install -U Mako six tox setuptools twisted pyyaml pyjwt cryptography requests --user python export PYTHONPATH=/Library/Python/3.4/site-packages # Install Python 3.7 diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index 78f1dca817d..d59f99b2520 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -25,21 +25,21 @@ _GITHUB_API_PREFIX = 'https://api.github.com' _GITHUB_REPO = 'grpc/grpc' _GITHUB_APP_ID = 22338 _INSTALLATION_ID = 519109 -_GITHUB_APP_KEY = open( - os.path.join(os.environ['KOKORO_KEYSTORE_DIR'], '73836_grpc_checks_private_key'), - 'rb').read() _ACCESS_TOKEN_CACHE = None def _jwt_token(): + github_app_key = open( + os.path.join(os.environ['KOKORO_KEYSTORE_DIR'], + '73836_grpc_checks_private_key'), 'rb').read() return jwt.encode( { 'iat': int(time.time()), 'exp': int(time.time() + 60 * 10), # expire in 10 minutes 'iss': _GITHUB_APP_ID, }, - _GITHUB_APP_KEY, + github_app_key, algorithm='RS256') @@ -90,25 +90,26 @@ def check_on_pr(name, summary, success=True): summary: A str in Markdown to be used as the detail information of the check. success: A bool indicates whether the check is succeed or not. """ - if 'ghprbPullId' not in os.environ: - print('Missing ghprbPullId env var: not commenting') + if 'KOKORO_GIT_COMMIT' not in os.environ: + print('Missing KOKORO_GIT_COMMIT env var: not checking') return - commit = _latest_commit() + if 'KOKORO_KEYSTORE_DIR' not in os.environ: + print('Missing KOKORO_KEYSTORE_DIR env var: not checking') + return + if 'ghprbPullId' not in os.environ: + print('Missing ghprbPullId env var: not checking') + return + completion_time = str( + datetime.datetime.utcnow().replace(microsecond=0).isoformat()) + 'Z' resp = _call( '/repos/%s/check-runs' % _GITHUB_REPO, method='POST', json={ - 'name': - name, - 'head_sha': - commit['sha'], - 'status': - 'completed', - 'completed_at': - '%sZ' % - datetime.datetime.utcnow().replace(microsecond=0).isoformat(), - 'conclusion': - 'success' if success else 'failure', + 'name': name, + 'head_sha': os.environ['KOKORO_GIT_COMMIT'], + 'status': 'completed', + 'completed_at': completion_time, + 'conclusion': 'success' if success else 'failure', 'output': { 'title': name, 'summary': summary, From 3347158533460f15bc1621a2ed0c6d298a82e339 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 17 Dec 2018 18:25:42 -0800 Subject: [PATCH 0591/2143] Use python2.7 -m pip instead of default pip --- tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc | 4 +--- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 2 -- 2 files changed, 1 insertion(+), 5 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 8223e03abd5..ec1ec1179d3 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc @@ -35,8 +35,6 @@ fi sudo pip install tabulate # Python dependencies for tools/run_tests/python_utils/check_on_pr.py -sudo -H pip install pyjwt cryptography requests - -ls -al "${KOKORO_KEYSTORE_DIR}/73836_grpc_checks_private_key" +time python2.7 -m pip install pyjwt cryptography requests --user git submodule update --init diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index b770808db99..114dc2ef558 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -31,8 +31,6 @@ date pip install google-api-python-client oauth2client --user python export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json -ls -al "${KOKORO_KEYSTORE_DIR}/73836_grpc_checks_private_key" - # 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 From 8183fe12992ac36fd99b637422d6bf158e760036 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 17 Dec 2018 18:29:25 -0800 Subject: [PATCH 0592/2143] fix BUILD.bazel --- src/python/grpcio_tests/tests/unit/BUILD.bazel | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel index 7a910fd9feb..1b462ec67a6 100644 --- a/src/python/grpcio_tests/tests/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel @@ -50,6 +50,11 @@ py_library( srcs = ["_exit_scenarios.py"], ) +py_library( + name = "_server_shutdown_scenarios", + srcs = ["_server_shutdown_scenarios.py"], +) + py_library( name = "_thread_pool", srcs = ["_thread_pool.py"], @@ -71,6 +76,7 @@ py_library( ":resources", ":test_common", ":_exit_scenarios", + ":_server_shutdown_scenarios", ":_thread_pool", ":_from_grpc_import_star", "//src/python/grpcio_tests/tests/unit/framework/common", From 3c49252d47f149c8b3262f9a1db83f11340e368b Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 17 Dec 2018 21:05:13 -0800 Subject: [PATCH 0593/2143] bazel docker image does not support ipv6 --- .../grpcio_tests/tests/unit/_server_shutdown_scenarios.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py index 1797e9bbfec..1d1fdba11ee 100644 --- a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py @@ -81,7 +81,7 @@ def run_test(args): thread.daemon = True thread.start() port = port_queue.get() - channel = grpc.insecure_channel('[::]:%d' % port) + channel = grpc.insecure_channel('localhost:%d' % port) multi_callable = channel.unary_unary(FORK_EXIT) result, call = multi_callable.with_call(REQUEST, wait_for_ready=True) os.wait() From 8c3df503ad59a6c66e1b1ab6257b52c508ec37dc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 17 Dec 2018 21:54:53 -0800 Subject: [PATCH 0594/2143] Fix compatibility test failures --- src/objective-c/GRPCClient/GRPCCall.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index cfd0de1a8a2..39e4967ec98 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -484,8 +484,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; callSafety:(GRPCCallSafety)safety requestsWriter:(GRXWriter *)requestWriter callOptions:(GRPCCallOptions *)callOptions { - // Purposely using pointer rather than length ([host length] == 0) for backwards compatibility. - NSAssert(host.length != 0 && path.length != 0, @"Neither host nor path can be nil."); + // Purposely using pointer rather than length (host.length == 0) for backwards compatibility. + NSAssert(host != nil && path != nil, @"Neither host nor path can be nil."); NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); NSAssert(requestWriter.state == GRXWriterStateNotStarted, @"The requests writer can't be already started."); From d36a13af3182495079bee65ff78e3e7e7f0d5901 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 17 Dec 2018 21:55:26 -0800 Subject: [PATCH 0595/2143] Try use alternative simulator for APIv2Tests --- src/objective-c/tests/run_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index e8c3e6ec2a4..f075d9baadd 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -187,7 +187,7 @@ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ -scheme APIv2Tests \ - -destination name="iPhone 8" \ + -destination name="iPhone X" \ test \ | egrep -v "$XCODEBUILD_FILTER" \ | egrep -v '^$' \ From eb9064db2fd38025dfa4fbe813de8798b5f1d0ed Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 18 Dec 2018 10:35:07 -0800 Subject: [PATCH 0596/2143] Clarify compression algorithm enum order --- include/grpc/impl/codegen/compression_types.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h index e35d8929678..f778b005b9b 100644 --- a/include/grpc/impl/codegen/compression_types.h +++ b/include/grpc/impl/codegen/compression_types.h @@ -52,7 +52,8 @@ extern "C" { "grpc.compression_enabled_algorithms_bitset" /** \} */ -/** The various compression algorithms supported by gRPC */ +/** The various compression algorithms supported by gRPC (not sorted by + * compression level) */ typedef enum { GRPC_COMPRESS_NONE = 0, GRPC_COMPRESS_DEFLATE, From 8bc8ff3dce507f912b8985fefaa22da1e2d95b6d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 18 Dec 2018 11:13:13 -0800 Subject: [PATCH 0597/2143] Fix nullability incompatibility --- src/compiler/objective_c_generator.cc | 11 +++++------ src/objective-c/ProtoRPC/ProtoRPC.h | 5 +++++ src/objective-c/ProtoRPC/ProtoService.m | 10 +++++++++- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc index 0a6b64f5952..af5398ec683 100644 --- a/src/compiler/objective_c_generator.cc +++ b/src/compiler/objective_c_generator.cc @@ -355,7 +355,7 @@ void PrintMethodImplementations(Printer* printer, "@implementation $service_class$\n\n" "// Designated initializer\n" "- (instancetype)initWithHost:(NSString *)host " - "callOptions:(GRPCCallOptions *_Nullable)callOptions{\n" + "callOptions:(GRPCCallOptions *_Nullable)callOptions {\n" " self = [super initWithHost:host\n" " packageName:@\"$package$\"\n" " serviceName:@\"$service_name$\"\n" @@ -363,10 +363,9 @@ void PrintMethodImplementations(Printer* printer, " return self;\n" "}\n\n" "- (instancetype)initWithHost:(NSString *)host {\n" - " return [self initWithHost:host\n" - " packageName:@\"$package$\"\n" - " serviceName:@\"$service_name$\"\n" - " callOptions:nil];\n" + " return [super initWithHost:host\n" + " packageName:@\"$package$\"\n" + " serviceName:@\"$service_name$\"];\n" "}\n\n"); printer.Print( @@ -381,7 +380,7 @@ void PrintMethodImplementations(Printer* printer, printer.Print( "#pragma mark - Class Methods\n\n" "+ (instancetype)serviceWithHost:(NSString *)host {\n" - " return [self serviceWithHost:host callOptions:nil];\n" + " return [[self alloc] initWithHost:host];\n" "}\n\n" "+ (instancetype)serviceWithHost:(NSString *)host " "callOptions:(GRPCCallOptions *_Nullable)callOptions {\n" diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 91a50d395af..8ce3421cc17 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -134,6 +134,9 @@ NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability-completeness" + __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC : GRPCCall @@ -160,3 +163,5 @@ __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC #pragma clang diagnostic pop @end + +#pragma clang diagnostic pop diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m index 3d998bfaeb8..b7c7fadbcf0 100644 --- a/src/objective-c/ProtoRPC/ProtoService.m +++ b/src/objective-c/ProtoRPC/ProtoService.m @@ -61,7 +61,15 @@ - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName serviceName:(NSString *)serviceName { - return [self initWithHost:host packageName:packageName serviceName:serviceName callOptions:nil]; + // Do not call designated initializer here due to nullability incompatibility. This method is from + // old API and does not assert on nullability of the parameters. + if ((self = [super init])) { + _host = [host copy]; + _packageName = [packageName copy]; + _serviceName = [serviceName copy]; + _callOptions = nil; + } + return self; } - (GRPCProtoCall *)RPCToMethod:(NSString *)method From 9a7eec0c455b3f6db9c1d06e73398a330e2c0729 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 18 Dec 2018 11:36:09 -0800 Subject: [PATCH 0598/2143] Suppress compiler error by initializing sent_length --- 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 211ae011cbc..c268c18664a 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -818,7 +818,7 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { struct msghdr msg; struct iovec iov[MAX_WRITE_IOVEC]; msg_iovlen_type iov_size; - ssize_t sent_length; + ssize_t sent_length = 0; size_t sending_length; size_t trailing; size_t unwind_slice_idx; From 71094e25c5355190eed4463cf3b1e48db053c6e0 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 18 Dec 2018 11:43:53 -0800 Subject: [PATCH 0599/2143] 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 233123ae3fa73b632c7b81b1131edb83c4fcf13a Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Fri, 14 Dec 2018 15:06:35 -0800 Subject: [PATCH 0600/2143] Improve metadata documentation for the user --- include/grpcpp/impl/codegen/client_context.h | 7 +++++++ include/grpcpp/impl/codegen/server_context.h | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 0a71f3d9b6a..5946488566e 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -200,6 +200,13 @@ class ClientContext { /// end in "-bin". /// \param meta_value The metadata value. If its value is binary, the key name /// must end in "-bin". + /// + /// Metadata must conform to the following format: + /// Custom-Metadata -> Binary-Header / ASCII-Header + /// Binary-Header -> {Header-Name "-bin" } {binary value} + /// ASCII-Header -> Header-Name ASCII-Value + /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . + /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII void AddMetadata(const grpc::string& meta_key, const grpc::string& meta_value); diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index ccb5925e7d8..affe61b547b 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -131,6 +131,13 @@ class ServerContext { /// end in "-bin". /// \param value The metadata value. If its value is binary, the key name /// must end in "-bin". + /// + /// Metadata must conform to the following format: + /// Custom-Metadata -> Binary-Header / ASCII-Header + /// Binary-Header -> {Header-Name "-bin" } {binary value} + /// ASCII-Header -> Header-Name ASCII-Value + /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . + /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII void AddInitialMetadata(const grpc::string& key, const grpc::string& value); /// Add the (\a key, \a value) pair to the initial metadata @@ -145,6 +152,13 @@ class ServerContext { /// it must end in "-bin". /// \param value The metadata value. If its value is binary, the key name /// must end in "-bin". + /// + /// Metadata must conform to the following format: + /// Custom-Metadata -> Binary-Header / ASCII-Header + /// Binary-Header -> {Header-Name "-bin" } {binary value} + /// ASCII-Header -> Header-Name ASCII-Value + /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . + /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII void AddTrailingMetadata(const grpc::string& key, const grpc::string& value); /// IsCancelled is always safe to call when using sync or callback API. From d5905834569d2d3c53e80722e4389cf03d689132 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 18 Dec 2018 12:10:20 -0800 Subject: [PATCH 0601/2143] Allow interceptor creators to return nullptr --- include/grpcpp/impl/codegen/client_interceptor.h | 15 +++++++++++++-- include/grpcpp/impl/codegen/server_interceptor.h | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index 2bae11a2516..da75bde499d 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -38,9 +38,17 @@ class InterceptorBatchMethodsImpl; namespace experimental { class ClientRpcInfo; +// A factory interface for creation of client interceptors. A vector of +// factories can be provided at channel creation which will be used to create a +// new vector of client interceptors per RPC. Client interceptor authors should +// create a subclass of ClientInterceptorFactorInterface which creates objects +// of their interceptors. class ClientInterceptorFactoryInterface { public: virtual ~ClientInterceptorFactoryInterface() {} + // Returns a pointer to an Interceptor object on successful creation, nullptr + // otherwise. If nullptr is returned, this server interceptor factory is + // ignored for the purposes of that RPC. virtual Interceptor* CreateClientInterceptor(ClientRpcInfo* info) = 0; }; } // namespace experimental @@ -120,8 +128,11 @@ class ClientRpcInfo { } for (auto it = creators.begin() + interceptor_pos; it != creators.end(); ++it) { - interceptors_.push_back(std::unique_ptr( - (*it)->CreateClientInterceptor(this))); + auto* interceptor = (*it)->CreateClientInterceptor(this); + if (interceptor != nullptr) { + interceptors_.push_back( + std::unique_ptr(interceptor)); + } } if (internal::g_global_client_interceptor_factory != nullptr) { interceptors_.push_back(std::unique_ptr( diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h index afc3c198ccf..8652ec5c649 100644 --- a/include/grpcpp/impl/codegen/server_interceptor.h +++ b/include/grpcpp/impl/codegen/server_interceptor.h @@ -37,9 +37,17 @@ class InterceptorBatchMethodsImpl; namespace experimental { class ServerRpcInfo; +// A factory interface for creation of server interceptors. A vector of +// factories can be provided to ServerBuilder which will be used to create a new +// vector of server interceptors per RPC. Server interceptor authors should +// create a subclass of ServerInterceptorFactorInterface which creates objects +// of their interceptors. class ServerInterceptorFactoryInterface { public: virtual ~ServerInterceptorFactoryInterface() {} + // Returns a pointer to an Interceptor object on successful creation, nullptr + // otherwise. If nullptr is returned, this server interceptor factory is + // ignored for the purposes of that RPC. virtual Interceptor* CreateServerInterceptor(ServerRpcInfo* info) = 0; }; @@ -90,8 +98,11 @@ class ServerRpcInfo { std::unique_ptr>& creators) { for (const auto& creator : creators) { - interceptors_.push_back(std::unique_ptr( - creator->CreateServerInterceptor(this))); + auto* interceptor = creator->CreateServerInterceptor(this); + if (interceptor != nullptr) { + interceptors_.push_back( + std::unique_ptr(interceptor)); + } } } From 75077243de21f13889e32c77fdb5d94ba59c392e Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Tue, 18 Dec 2018 12:30:30 -0800 Subject: [PATCH 0602/2143] Add 1.17.1 to interop --- tools/interop_matrix/client_matrix.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 931beddb9cf..c0b08a59b26 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -104,6 +104,9 @@ LANG_RELEASE_MATRIX = { { 'v1.16.0': None }, + { + 'v1.17.1': None + }, ], 'go': [ { @@ -260,6 +263,9 @@ LANG_RELEASE_MATRIX = { { 'v1.16.0': None }, + { + 'v1.17.1': None + }, ], 'node': [ { @@ -354,6 +360,9 @@ LANG_RELEASE_MATRIX = { { 'v1.16.0': None }, + { + 'v1.17.1': None + }, ], 'php': [ { @@ -404,6 +413,9 @@ LANG_RELEASE_MATRIX = { { 'v1.16.0': None }, + { + 'v1.17.1': None + }, ], 'csharp': [ { @@ -459,6 +471,9 @@ LANG_RELEASE_MATRIX = { { 'v1.16.0': None }, + { + 'v1.17.1': None + }, ], } From a20263f64de839e4981ac3e05df328081438e453 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 18 Dec 2018 12:41:49 -0800 Subject: [PATCH 0603/2143] Add tests using NullInterceptorFactory --- .../client_interceptors_end2end_test.cc | 22 +++++++++++++++++++ test/cpp/end2end/interceptors_util.h | 16 ++++++++++++++ .../server_interceptors_end2end_test.cc | 3 +++ 3 files changed, 41 insertions(+) diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 968b5d49d10..033268a73d9 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -467,6 +467,28 @@ TEST_F(ClientInterceptorsEnd2endTest, EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } +TEST_F(ClientInterceptorsEnd2endTest, + ClientInterceptorFactoryAllowsNullptrReturn) { + ChannelArguments args; + DummyInterceptor::Reset(); + std::vector> + creators; + creators.push_back(std::unique_ptr( + new LoggingInterceptorFactory())); + // Add 20 dummy interceptors and 20 null interceptors + for (auto i = 0; i < 20; i++) { + creators.push_back(std::unique_ptr( + new DummyInterceptorFactory())); + creators.push_back( + std::unique_ptr(new NullInterceptorFactory())); + } + auto channel = server_->experimental().InProcessChannelWithInterceptors( + args, std::move(creators)); + MakeCallbackCall(channel); + // Make sure all 20 dummy interceptors were run + EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); +} + class ClientInterceptorsStreamingEnd2endTest : public ::testing::Test { protected: ClientInterceptorsStreamingEnd2endTest() { diff --git a/test/cpp/end2end/interceptors_util.h b/test/cpp/end2end/interceptors_util.h index d886e32494c..659e613d2eb 100644 --- a/test/cpp/end2end/interceptors_util.h +++ b/test/cpp/end2end/interceptors_util.h @@ -82,6 +82,22 @@ class DummyInterceptorFactory } }; +/* This interceptor factory returns nullptr on interceptor creation */ +class NullInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface, + public experimental::ServerInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return nullptr; + } + + virtual experimental::Interceptor* CreateServerInterceptor( + experimental::ServerRpcInfo* info) override { + return nullptr; + } +}; + class EchoTestServiceStreamingImpl : public EchoTestService::Service { public: ~EchoTestServiceStreamingImpl() override {} diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 9460a7d6c64..e837a2cd18e 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -176,9 +176,12 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { creators.push_back( std::unique_ptr( new LoggingInterceptorFactory())); + // Add 20 dummy interceptor factories and null interceptor factories for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); + creators.push_back(std::unique_ptr( + new NullInterceptorFactory())); } builder.experimental().SetInterceptorCreators(std::move(creators)); server_ = builder.BuildAndStart(); From 31a775b425eac37bb43c301cfb25e1f6a4bde106 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 18 Dec 2018 12:52:14 -0800 Subject: [PATCH 0604/2143] Add missing argument --- include/grpcpp/impl/codegen/call_op_set.h | 3 +-- include/grpcpp/impl/codegen/interceptor_common.h | 1 + test/cpp/end2end/client_interceptors_end2end_test.cc | 8 +++----- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 3db9f48bffe..1c0ccbab527 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -340,12 +340,11 @@ class CallOpSendMessage { if (send_buf_.Valid()) { interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_SEND_MESSAGE); - // We had already registered failed_send_ earlier. No need to do it again. } send_buf_.Clear(); // The contents of the SendMessage value that was previously set // has had its references stolen by core's operations - interceptor_methods->SetSendMessage(nullptr); + interceptor_methods->SetSendMessage(nullptr, &failed_send_); } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 321691236be..b01706af8d9 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -403,6 +403,7 @@ class CancelInterceptorBatchMethods false && "It is illegal to call GetSendMessageStatus on a method which " "has a Cancel notification"); + return false; } std::multimap* GetSendInitialMetadata() override { diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 33773e3b3b9..c55eaab4d6f 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -580,11 +580,9 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) { TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingHijackingTest) { ChannelArguments args; - auto creators = std::unique_ptr>>( - new std::vector< - std::unique_ptr>()); - creators->push_back( + std::vector> + creators; + creators.push_back( std::unique_ptr( new ClientStreamingRpcHijackingInterceptorFactory())); auto channel = experimental::CreateCustomChannelWithInterceptors( From 1438b17890b56f57b21e49bc7bcd4e5d589425cc Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 18 Dec 2018 14:14:42 -0800 Subject: [PATCH 0605/2143] Fix bug that was breaking subchannel reuse in grpclb. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 18 ++++---- test/cpp/end2end/grpclb_end2end_test.cc | 41 +++++++++++++++++++ 2 files changed, 51 insertions(+), 8 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 a9a5965ed1c..49a1b2d6921 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 @@ -361,7 +361,9 @@ void lb_token_destroy(void* token) { } } int lb_token_cmp(void* token1, void* token2) { - return GPR_ICMP(token1, token2); + // Always indicate a match, since we don't want this channel arg to + // affect the subchannel's key in the index. + return 0; } const grpc_arg_pointer_vtable lb_token_arg_vtable = { lb_token_copy, lb_token_destroy, lb_token_cmp}; @@ -422,7 +424,7 @@ ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { grpc_resolved_address addr; ParseServer(server, &addr); // LB token processing. - void* lb_token; + grpc_mdelem lb_token; if (server->has_load_balance_token) { const size_t lb_token_max_length = GPR_ARRAY_SIZE(server->load_balance_token); @@ -430,9 +432,7 @@ ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { strnlen(server->load_balance_token, lb_token_max_length); grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer( server->load_balance_token, lb_token_length); - lb_token = - (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr) - .payload; + lb_token = grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr); } else { char* uri = grpc_sockaddr_to_uri(&addr); gpr_log(GPR_INFO, @@ -440,14 +440,16 @@ ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { "be used instead", uri); gpr_free(uri); - lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; + lb_token = GRPC_MDELEM_LB_TOKEN_EMPTY; } // Add address. grpc_arg arg = grpc_channel_arg_pointer_create( - const_cast(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token, - &lb_token_arg_vtable); + const_cast(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), + (void*)lb_token.payload, &lb_token_arg_vtable); grpc_channel_args* args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); addresses.emplace_back(addr, args); + // Clean up. + GRPC_MDELEM_UNREF(lb_token); } return addresses; } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 2eaacd429de..f739ed032bb 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -145,6 +146,7 @@ class BackendServiceImpl : public BackendService { IncreaseRequestCount(); const auto status = TestServiceImpl::Echo(context, request, response); IncreaseResponseCount(); + AddClient(context->peer()); return status; } @@ -157,9 +159,21 @@ class BackendServiceImpl : public BackendService { 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) { @@ -303,6 +317,11 @@ class BalancerServiceImpl : public BalancerService { 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; } @@ -675,6 +694,28 @@ TEST_F(SingleBalancerTest, Vanilla) { EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } +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_); + 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) { ResetStub(0, kApplicationTargetName_ + ";lb"); SetNextResolution({AddressData{balancer_servers_[0].port_, true, "lb"}}); From 886a932a1a09a567bd790ea949d9ccc9df86cdba Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 18 Dec 2018 14:24:58 -0800 Subject: [PATCH 0606/2143] Use KOKORO_GITHUB_PULL_REQUEST_NUMBER instead of ghprbPullId --- tools/run_tests/python_utils/check_on_pr.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index d59f99b2520..3f335c8ea93 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -71,8 +71,9 @@ def _call(url, method='GET', json=None): def _latest_commit(): - resp = _call('/repos/%s/pulls/%s/commits' % (_GITHUB_REPO, - os.environ['ghprbPullId'])) + resp = _call('/repos/%s/pulls/%s/commits' % + (_GITHUB_REPO, + os.environ['KOKORO_GITHUB_PULL_REQUEST_NUMBER'])) return resp.json()[-1] @@ -82,7 +83,7 @@ def check_on_pr(name, summary, success=True): The check runs are aggregated by their name, so newer check will update the older check with the same name. - Requires environment variable 'ghprbPullId' to indicate which pull request + Requires environment variable 'KOKORO_GITHUB_PULL_REQUEST_NUMBER' to indicate which pull request should be updated. Args: @@ -96,8 +97,8 @@ def check_on_pr(name, summary, success=True): if 'KOKORO_KEYSTORE_DIR' not in os.environ: print('Missing KOKORO_KEYSTORE_DIR env var: not checking') return - if 'ghprbPullId' not in os.environ: - print('Missing ghprbPullId env var: not checking') + if 'KOKORO_GITHUB_PULL_REQUEST_NUMBER' not in os.environ: + print('Missing KOKORO_GITHUB_PULL_REQUEST_NUMBER env var: not checking') return completion_time = str( datetime.datetime.utcnow().replace(microsecond=0).isoformat()) + 'Z' From d79b3fe3207f7bd064d584c6e15517680749e2d5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 18 Dec 2018 14:28:36 -0800 Subject: [PATCH 0607/2143] Fix test --- src/objective-c/tests/GRPCClientTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index b16720557f7..3ef046835e4 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -365,7 +365,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; GRXWriter *writer = [GRXWriter writerWithValue:[NSData data]]; // Try to set parameters to nil for GRPCCall. This should cause an exception @try { - (void)[[GRPCCall alloc] initWithHost:@"" path:@"" requestsWriter:writer]; + (void)[[GRPCCall alloc] initWithHost:nil path:nil requestsWriter:writer]; XCTFail(@"Did not receive an exception when parameters are nil"); } @catch (NSException *theException) { NSLog(@"Received exception as expected: %@", theException.name); From cfe08f35f30d272a8f2e851fb9e069498b264f5f Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 18 Dec 2018 12:52:26 -0800 Subject: [PATCH 0608/2143] Add comments explaining purpose and validity of interception API --- .../grpcpp/impl/codegen/client_interceptor.h | 15 ++ include/grpcpp/impl/codegen/interceptor.h | 130 ++++++++++++------ .../grpcpp/impl/codegen/server_interceptor.h | 14 ++ 3 files changed, 115 insertions(+), 44 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index 2bae11a2516..2eca596f1dc 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -50,11 +50,16 @@ extern experimental::ClientInterceptorFactoryInterface* g_global_client_interceptor_factory; } +/// ClientRpcInfo represents the state of a particular RPC as it +/// appears to an interceptor. It is created and owned by the library and +/// passed to the CreateClientInterceptor method of the application's +/// ClientInterceptorFactoryInterface implementation namespace experimental { class ClientRpcInfo { public: // TODO(yashykt): Stop default-constructing ClientRpcInfo and remove UNKNOWN // from the list of possible Types. + /// Type categorizes RPCs by unary or streaming type enum class Type { UNARY, CLIENT_STREAMING, @@ -65,13 +70,23 @@ class ClientRpcInfo { ~ClientRpcInfo(){}; + // Delete copy constructor but allow default move constructor ClientRpcInfo(const ClientRpcInfo&) = delete; ClientRpcInfo(ClientRpcInfo&&) = default; // Getter methods + + /// Return the fully-specified method name const char* method() const { return method_; } + + /// Return a pointer to the channel on which the RPC is being sent ChannelInterface* channel() { return channel_; } + + /// Return a pointer to the underlying ClientContext structure associated + /// with the RPC to support features that apply to it grpc::ClientContext* client_context() { return ctx_; } + + /// Return the type of the RPC (unary or a streaming flavor) Type type() const { return type_; } private: diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index e449e44a23b..46175cd73b8 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -31,99 +31,141 @@ class ChannelInterface; class Status; namespace experimental { -class InterceptedMessage { - public: - template - bool Extract(M* msg); // returns false if definitely invalid extraction - template - M* MutableExtract(); - uint64_t length(); // length on wire -}; +/// An enumeration of different possible points at which the \a Intercept +/// method of the \a Interceptor interface may be called. Any given call +/// to \a Intercept will include one or more of these hook points, and +/// each hook point makes certain types of information available to the +/// interceptor. +/// In these enumeration names, PRE_SEND means that an interception has taken +/// place between the time the application provided a certain type of data +/// (e.g., initial metadata, status) and the time that that data goes to the +/// other side. POST_SEND means that the data has been committed for going to +/// the other side (even if it has not yet been received at the other side). +/// 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. enum class InterceptionHookPoints { - /* The first two in this list are for clients and servers */ + /// The first two in this list are for clients and servers PRE_SEND_INITIAL_METADATA, PRE_SEND_MESSAGE, - PRE_SEND_STATUS /* server only */, - PRE_SEND_CLOSE /* client only */, - /* The following three are for hijacked clients only and can only be - registered by the global interceptor */ + 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 PRE_RECV_INITIAL_METADATA, PRE_RECV_MESSAGE, PRE_RECV_STATUS, - /* The following two are for all clients and servers */ + /// The following two are for all clients and servers POST_RECV_INITIAL_METADATA, POST_RECV_MESSAGE, - POST_RECV_STATUS /* client only */, - POST_RECV_CLOSE /* server only */, - /* This is a special hook point available to both clients and servers when - TryCancel() is performed. - - No other hook points will be present along with this. - - It is illegal for an interceptor to block/delay this operation. - - ALL interceptors see this hook point irrespective of whether the RPC was - hijacked or not. */ + POST_RECV_STATUS, // client only + POST_RECV_CLOSE, // server only + /// This is a special hook point available to both clients and servers when + /// TryCancel() is performed. + /// - No other hook points will be present along with this. + /// - It is illegal for an interceptor to block/delay this operation. + /// - ALL interceptors see this hook point irrespective of whether the + /// RPC was hijacked or not. PRE_SEND_CANCEL, NUM_INTERCEPTION_HOOKS }; +/// Class that is passed as an argument to the \a Intercept method +/// of the application's \a Interceptor interface implementation. It has five +/// purposes: +/// 1. Indicate which hook points are present at a specific interception +/// 2. Allow an interceptor to inform the library that an RPC should +/// continue to the next stage of its processing (which may be another +/// interceptor or the main path of the library) +/// 3. Allow an interceptor to hijack the processing of the RPC (only for +/// client-side RPCs with PRE_SEND_INITIAL_METADATA) so that it does not +/// proceed with normal processing beyond that stage +/// 4. Access the relevant fields of an RPC at each interception point +/// 5. Set some fields of an RPC at each interception point, when possible class InterceptorBatchMethods { public: virtual ~InterceptorBatchMethods(){}; - // Queries to check whether the current batch has an interception hook point - // of type \a type + /// Determine whether the current batch has an interception hook point + /// of type \a type virtual bool QueryInterceptionHookPoint(InterceptionHookPoints type) = 0; - // Calling this will signal that the interceptor is done intercepting the - // current batch of the RPC. - // Proceed is a no-op if the batch contains PRE_SEND_CANCEL. Simply returning - // from the Intercept method does the job of continuing the RPC in this case. + /// Signal that the interceptor is done intercepting the current batch of the + /// RPC. Every interceptor must either call Proceed or Hijack on each + /// interception. In most cases, only Proceed will be used. Explicit use of + /// Proceed is what enables interceptors to delay the processing of RPCs + /// while they perform other work. + /// Proceed is a no-op if the batch contains PRE_SEND_CANCEL. Simply returning + /// from the Intercept method does the job of continuing the RPC in this case. + /// This is because PRE_SEND_CANCEL is always in a separate batch and is not + /// allowed to be delayed. virtual void Proceed() = 0; - // Calling this indicates that the interceptor has hijacked the RPC (only - // valid if the batch contains send_initial_metadata on the client side) + /// Indicate that the interceptor has hijacked the RPC (only valid if the + /// batch contains send_initial_metadata on the client side). Later + /// interceptors in the interceptor list will not be called. Later batches + /// on the same RPC will go through interception, but only up to the point + /// of the hijacking interceptor. virtual void Hijack() = 0; - // Returns a modifable ByteBuffer holding serialized form of the message to be - // sent + /// 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. virtual ByteBuffer* GetSendMessage() = 0; - // Returns a modifiable multimap of the initial metadata to be sent + /// Returns a modifiable multimap of the initial metadata to be sent. Valid + /// for PRE_SEND_INITIAL_METADATA interceptions. A value of nullptr indicates + /// that this field is not valid. virtual std::multimap* GetSendInitialMetadata() = 0; - // Returns the status to be sent + /// Returns the status to be sent. Valid for PRE_SEND_STATUS interceptions. virtual Status GetSendStatus() = 0; - // Modifies the status with \a status + /// Overwrites the status with \a status. Valid for PRE_SEND_STATUS + /// interceptions. virtual void ModifySendStatus(const Status& status) = 0; - // Returns a modifiable multimap of the trailing metadata to be sent + /// Returns a modifiable multimap of the trailing metadata to be sent. Valid + /// for PRE_SEND_STATUS interceptions. A value of nullptr indicates + /// that this field is not valid. virtual std::multimap* GetSendTrailingMetadata() = 0; - // Returns a pointer to the modifiable received message. Note that the message - // is already deserialized + /// Returns a pointer to the modifiable received message. Note that the + /// message is already deserialized but the type is not set; the interceptor + /// should static_cast to the appropriate type before using it. This is valid + /// for POST_RECV_MESSAGE interceptions; nullptr for not valid virtual void* GetRecvMessage() = 0; - // Returns a modifiable multimap of the received initial metadata + /// Returns a modifiable multimap of the received initial metadata. + /// Valid for POST_RECV_INITIAL_METADATA interceptions; nullptr if not valid virtual std::multimap* GetRecvInitialMetadata() = 0; - // Returns a modifiable view of the received status + /// Returns a modifiable view of the received status on POST_RECV_STATUS + /// interceptions; nullptr if not valid. virtual Status* GetRecvStatus() = 0; - // Returns a modifiable multimap of the received trailing metadata + /// Returns a modifiable multimap of the received trailing metadata on + /// POST_RECV_STATUS interceptions; nullptr if not valid virtual std::multimap* GetRecvTrailingMetadata() = 0; - // Gets an intercepted channel. When a call is started on this interceptor, - // only interceptors after the current interceptor are created from the - // factory objects registered with the channel. + /// Gets an intercepted channel. When a call is started on this interceptor, + /// only interceptors after the current interceptor are created from the + /// factory objects registered with the channel. This allows calls to be + /// started from interceptors without infinite regress through the interceptor + /// list. virtual std::unique_ptr GetInterceptedChannel() = 0; }; +/// Interface for an interceptor. Interceptor authors must create a class +/// that derives from this parent class. class Interceptor { public: virtual ~Interceptor() {} + /// The one public method of an Interceptor interface. Override this to + /// trigger the desired actions at the hook points described above. virtual void Intercept(InterceptorBatchMethods* methods) = 0; }; diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h index afc3c198ccf..6664d09e4ac 100644 --- a/include/grpcpp/impl/codegen/server_interceptor.h +++ b/include/grpcpp/impl/codegen/server_interceptor.h @@ -43,19 +43,33 @@ class ServerInterceptorFactoryInterface { virtual Interceptor* CreateServerInterceptor(ServerRpcInfo* info) = 0; }; +/// ServerRpcInfo represents the state of a particular RPC as it +/// appears to an interceptor. It is created and owned by the library and +/// passed to the CreateServerInterceptor method of the application's +/// ServerInterceptorFactoryInterface implementation class ServerRpcInfo { public: + /// Type categorizes RPCs by unary or streaming type enum class Type { UNARY, CLIENT_STREAMING, SERVER_STREAMING, BIDI_STREAMING }; ~ServerRpcInfo(){}; + // Delete all copy and move constructors and assignments ServerRpcInfo(const ServerRpcInfo&) = delete; + ServerRpcInfo& operator=(const ServerRpcInfo&) = delete; ServerRpcInfo(ServerRpcInfo&&) = delete; ServerRpcInfo& operator=(ServerRpcInfo&&) = delete; // Getter methods + + /// Return the fully-specified method name const char* method() const { return method_; } + + /// Return the type of the RPC (unary or a streaming flavor) Type type() const { return type_; } + + /// Return a pointer to the underlying ServerContext structure associated + /// with the RPC to support features that apply to it grpc::ServerContext* server_context() { return ctx_; } private: From 09a173b4b612d1cb27d82490d83dd95e0aece203 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 18 Dec 2018 12:51:48 -0800 Subject: [PATCH 0609/2143] Remove now-unnecessary workarounds for alignment issues. --- .../ext/filters/client_channel/lb_policy.h | 6 -- .../composite/composite_credentials.cc | 61 ++++--------------- .../composite/composite_credentials.h | 43 +++---------- test/core/security/credentials_test.cc | 22 +++---- 4 files changed, 29 insertions(+), 103 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 6b76fe5d5d7..29b8c28be6a 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -205,12 +205,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_pollset_set* interested_parties_; /// Callback to force a re-resolution. grpc_closure* request_reresolution_; - - // Dummy classes needed for alignment issues. - // See https://github.com/grpc/grpc/issues/16032 for context. - // TODO(ncteisen): remove this as soon as the issue is resolved. - channelz::ChildRefsList dummy_list_foo; - channelz::ChildRefsList dummy_list_bar; }; } // namespace grpc_core diff --git a/src/core/lib/security/credentials/composite/composite_credentials.cc b/src/core/lib/security/credentials/composite/composite_credentials.cc index 85dcd4693bc..586bbed778e 100644 --- a/src/core/lib/security/credentials/composite/composite_credentials.cc +++ b/src/core/lib/security/credentials/composite/composite_credentials.cc @@ -35,44 +35,6 @@ static void composite_call_metadata_cb(void* arg, grpc_error* error); -grpc_call_credentials_array::~grpc_call_credentials_array() { - for (size_t i = 0; i < num_creds_; ++i) { - creds_array_[i].~RefCountedPtr(); - } - if (creds_array_ != nullptr) { - gpr_free(creds_array_); - } -} - -grpc_call_credentials_array::grpc_call_credentials_array( - const grpc_call_credentials_array& that) - : num_creds_(that.num_creds_) { - reserve(that.capacity_); - for (size_t i = 0; i < num_creds_; ++i) { - new (&creds_array_[i]) - grpc_core::RefCountedPtr(that.creds_array_[i]); - } -} - -void grpc_call_credentials_array::reserve(size_t capacity) { - if (capacity_ >= capacity) { - return; - } - grpc_core::RefCountedPtr* new_arr = - static_cast*>(gpr_malloc( - sizeof(grpc_core::RefCountedPtr) * capacity)); - if (creds_array_ != nullptr) { - for (size_t i = 0; i < num_creds_; ++i) { - new (&new_arr[i]) grpc_core::RefCountedPtr( - std::move(creds_array_[i])); - creds_array_[i].~RefCountedPtr(); - } - gpr_free(creds_array_); - } - creds_array_ = new_arr; - capacity_ = capacity; -} - namespace { struct grpc_composite_call_credentials_metadata_context { grpc_composite_call_credentials_metadata_context( @@ -103,13 +65,13 @@ static void composite_call_metadata_cb(void* arg, grpc_error* error) { grpc_composite_call_credentials_metadata_context* ctx = static_cast(arg); if (error == GRPC_ERROR_NONE) { - const grpc_call_credentials_array& inner = ctx->composite_creds->inner(); + const grpc_composite_call_credentials::CallCredentialsList& inner = + ctx->composite_creds->inner(); /* See if we need to get some more metadata. */ if (ctx->creds_index < inner.size()) { - if (inner.get(ctx->creds_index++) - ->get_request_metadata( - ctx->pollent, ctx->auth_md_context, ctx->md_array, - &ctx->internal_on_request_metadata, &error)) { + if (inner[ctx->creds_index++]->get_request_metadata( + ctx->pollent, ctx->auth_md_context, ctx->md_array, + &ctx->internal_on_request_metadata, &error)) { // Synchronous response, so call ourselves recursively. composite_call_metadata_cb(arg, error); GRPC_ERROR_UNREF(error); @@ -130,12 +92,11 @@ bool grpc_composite_call_credentials::get_request_metadata( ctx = grpc_core::New( this, pollent, auth_md_context, md_array, on_request_metadata); bool synchronous = true; - const grpc_call_credentials_array& inner = ctx->composite_creds->inner(); + const CallCredentialsList& inner = ctx->composite_creds->inner(); while (ctx->creds_index < inner.size()) { - if (inner.get(ctx->creds_index++) - ->get_request_metadata(ctx->pollent, ctx->auth_md_context, - ctx->md_array, - &ctx->internal_on_request_metadata, error)) { + if (inner[ctx->creds_index++]->get_request_metadata( + ctx->pollent, ctx->auth_md_context, ctx->md_array, + &ctx->internal_on_request_metadata, error)) { if (*error != GRPC_ERROR_NONE) break; } else { synchronous = false; // Async return. @@ -149,7 +110,7 @@ bool grpc_composite_call_credentials::get_request_metadata( void grpc_composite_call_credentials::cancel_get_request_metadata( grpc_credentials_mdelem_array* md_array, grpc_error* error) { for (size_t i = 0; i < inner_.size(); ++i) { - inner_.get(i)->cancel_get_request_metadata(md_array, GRPC_ERROR_REF(error)); + inner_[i]->cancel_get_request_metadata(md_array, GRPC_ERROR_REF(error)); } GRPC_ERROR_UNREF(error); } @@ -172,7 +133,7 @@ void grpc_composite_call_credentials::push_to_inner( auto composite_creds = static_cast(creds.get()); for (size_t i = 0; i < composite_creds->inner().size(); ++i) { - inner_.push_back(std::move(composite_creds->inner_.get_mutable(i))); + inner_.push_back(std::move(composite_creds->inner_[i])); } } diff --git a/src/core/lib/security/credentials/composite/composite_credentials.h b/src/core/lib/security/credentials/composite/composite_credentials.h index 6b7fca13708..7a1c7d5e42b 100644 --- a/src/core/lib/security/credentials/composite/composite_credentials.h +++ b/src/core/lib/security/credentials/composite/composite_credentials.h @@ -21,43 +21,10 @@ #include +#include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/credentials/credentials.h" -// TODO(soheil): Replace this with InlinedVector once #16032 is resolved. -class grpc_call_credentials_array { - public: - grpc_call_credentials_array() = default; - grpc_call_credentials_array(const grpc_call_credentials_array& that); - - ~grpc_call_credentials_array(); - - void reserve(size_t capacity); - - // Must reserve before pushing any data. - void push_back(grpc_core::RefCountedPtr cred) { - GPR_DEBUG_ASSERT(capacity_ > num_creds_); - new (&creds_array_[num_creds_++]) - grpc_core::RefCountedPtr(std::move(cred)); - } - - const grpc_core::RefCountedPtr& get(size_t i) const { - GPR_DEBUG_ASSERT(i < num_creds_); - return creds_array_[i]; - } - grpc_core::RefCountedPtr& get_mutable(size_t i) { - GPR_DEBUG_ASSERT(i < num_creds_); - return creds_array_[i]; - } - - size_t size() const { return num_creds_; } - - private: - grpc_core::RefCountedPtr* creds_array_ = nullptr; - size_t num_creds_ = 0; - size_t capacity_ = 0; -}; - /* -- Composite channel credentials. -- */ class grpc_composite_channel_credentials : public grpc_channel_credentials { @@ -97,6 +64,10 @@ class grpc_composite_channel_credentials : public grpc_channel_credentials { class grpc_composite_call_credentials : public grpc_call_credentials { public: + using CallCredentialsList = + grpc_core::InlinedVector, + 2>; + grpc_composite_call_credentials( grpc_core::RefCountedPtr creds1, grpc_core::RefCountedPtr creds2); @@ -111,13 +82,13 @@ class grpc_composite_call_credentials : public grpc_call_credentials { void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, grpc_error* error) override; - const grpc_call_credentials_array& inner() const { return inner_; } + const CallCredentialsList& inner() const { return inner_; } private: void push_to_inner(grpc_core::RefCountedPtr creds, bool is_composite); - grpc_call_credentials_array inner_; + CallCredentialsList inner_; }; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_COMPOSITE_COMPOSITE_CREDENTIALS_H \ diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index b3a81617865..b6555353359 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -465,14 +465,14 @@ static void test_oauth2_google_iam_composite_creds(void) { google_iam_creds->Unref(); GPR_ASSERT(strcmp(composite_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); - const grpc_call_credentials_array& creds_array = + const grpc_composite_call_credentials::CallCredentialsList& creds_list = static_cast(composite_creds) ->inner(); - GPR_ASSERT(creds_array.size() == 2); - GPR_ASSERT(strcmp(creds_array.get(0)->type(), - GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); - GPR_ASSERT( - strcmp(creds_array.get(1)->type(), GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); + GPR_ASSERT(creds_list.size() == 2); + GPR_ASSERT(strcmp(creds_list[0]->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == + 0); + GPR_ASSERT(strcmp(creds_list[1]->type(), GRPC_CALL_CREDENTIALS_TYPE_IAM) == + 0); run_request_metadata_test(composite_creds, auth_md_ctx, state); composite_creds->Unref(); } @@ -492,13 +492,13 @@ class check_channel_oauth2_google_iam final : public grpc_channel_credentials { GPR_ASSERT(call_creds != nullptr); GPR_ASSERT( strcmp(call_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); - const grpc_call_credentials_array& creds_array = + const grpc_composite_call_credentials::CallCredentialsList& creds_list = static_cast(call_creds.get()) ->inner(); - GPR_ASSERT(strcmp(creds_array.get(0)->type(), - GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); - GPR_ASSERT(strcmp(creds_array.get(1)->type(), - GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); + GPR_ASSERT( + strcmp(creds_list[0]->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); + GPR_ASSERT(strcmp(creds_list[1]->type(), GRPC_CALL_CREDENTIALS_TYPE_IAM) == + 0); return nullptr; } }; From 82797771679c93045876f48707c5cb46bfae4f53 Mon Sep 17 00:00:00 2001 From: easy Date: Wed, 19 Dec 2018 12:22:38 +1100 Subject: [PATCH 0610/2143] Destruct CensusContext to avoid leaking memory. Otherwise, the placement-new leaks context -> span_ -> impl_ which is a std::shared_ptr. --- src/cpp/ext/filters/census/context.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cpp/ext/filters/census/context.cc b/src/cpp/ext/filters/census/context.cc index 78fc69a8054..160590353a7 100644 --- a/src/cpp/ext/filters/census/context.cc +++ b/src/cpp/ext/filters/census/context.cc @@ -28,6 +28,9 @@ using ::opencensus::trace::SpanContext; void GenerateServerContext(absl::string_view tracing, absl::string_view stats, absl::string_view primary_role, absl::string_view method, CensusContext* context) { + // Destruct the current CensusContext to free the Span memory before + // overwriting it below. + context->~CensusContext(); GrpcTraceContext trace_ctxt; if (TraceContextEncoding::Decode(tracing, &trace_ctxt) != TraceContextEncoding::kEncodeDecodeFailure) { @@ -42,6 +45,9 @@ void GenerateServerContext(absl::string_view tracing, absl::string_view stats, void GenerateClientContext(absl::string_view method, CensusContext* ctxt, CensusContext* parent_ctxt) { + // Destruct the current CensusContext to free the Span memory before + // overwriting it below. + ctxt->~CensusContext(); if (parent_ctxt != nullptr) { SpanContext span_ctxt = parent_ctxt->Context(); Span span = parent_ctxt->Span(); From 3f57e3451bf4a3687e70e92fc218ea25ff7a17c9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 08:09:12 -0800 Subject: [PATCH 0611/2143] Try earlier APIv2Tests --- src/objective-c/tests/run_tests.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index f075d9baadd..aab80ded61b 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -176,7 +176,7 @@ xcodebuild \ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ - -scheme ChannelTests \ + -scheme APIv2Tests \ -destination name="iPhone 8" \ test \ | egrep -v "$XCODEBUILD_FILTER" \ @@ -186,11 +186,12 @@ xcodebuild \ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ - -scheme APIv2Tests \ - -destination name="iPhone X" \ + -scheme ChannelTests \ + -destination name="iPhone 8" \ test \ | egrep -v "$XCODEBUILD_FILTER" \ | egrep -v '^$' \ | egrep -v "(GPBDictionary|GPBArray)" - + exit 0 From 6211f4589b47620440ea60c614116398a7a1ab43 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 19 Dec 2018 08:34:13 -0800 Subject: [PATCH 0612/2143] removed unused traceback import --- src/python/grpcio_tests/commands.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 18413abab02..496bcfbcbff 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -22,7 +22,6 @@ import re import shutil import subprocess import sys -import traceback import setuptools from setuptools.command import build_ext From 25e73664136ea01e2b8a64149a97e782c57d9f7d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 09:16:26 -0800 Subject: [PATCH 0613/2143] Revert "Rename getTokenWithHandler" Since the renamed protocol is breaking people and is not general enough, we revert the rename and leave the work to interceptor This reverts commit 92db5fc72488f9d62b81ee311a79832df787f3ef. --- src/objective-c/GRPCClient/GRPCCall.m | 14 ++------------ src/objective-c/GRPCClient/GRPCCallOptions.h | 12 +----------- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 2 +- 4 files changed, 5 insertions(+), 25 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 39e4967ec98..9bcacac0dfc 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -885,7 +885,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(self) { self.isWaitingForToken = YES; } - void (^tokenHandler)(NSString *token) = ^(NSString *token) { + [_callOptions.authTokenProvider getTokenWithHandler:^(NSString *token) { @synchronized(self) { if (self.isWaitingForToken) { if (token) { @@ -895,17 +895,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; self.isWaitingForToken = NO; } } - }; - id authTokenProvider = _callOptions.authTokenProvider; - if ([authTokenProvider respondsToSelector:@selector(provideTokenToHandler:)]) { - [_callOptions.authTokenProvider provideTokenToHandler:tokenHandler]; - } else { - NSAssert([authTokenProvider respondsToSelector:@selector(getTokenWithHandler:)], - @"authTokenProvider has no usable method"); - if ([authTokenProvider respondsToSelector:@selector(getTokenWithHandler:)]) { - [_callOptions.authTokenProvider getTokenWithHandler:tokenHandler]; - } - } + }]; } else { [self startCallWithWriteable:writeable]; } diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index b866f268ee1..b5bf4c9eb6c 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -60,22 +60,12 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * Implement this protocol to provide a token to gRPC when a call is initiated. */ -@protocol GRPCAuthorizationProtocol - -@optional +@protocol GRPCAuthorizationProtocol /** * This method is called when gRPC is about to start the call. When OAuth token is acquired, * \a handler is expected to be called with \a token being the new token to be used for this call. */ -- (void)provideTokenToHandler:(void (^)(NSString *_Nullable token))handler; - -/** - * This method is deprecated. Please use \a provideTokenToHandler. - * - * This method is called when gRPC is about to start the call. When OAuth token is acquired, - * \a handler is expected to be called with \a token being the new token to be used for this call. - */ - (void)getTokenWithHandler:(void (^)(NSString *_Nullable token))handler; @end diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index abf224c3cfd..48a38bd35ac 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -175,7 +175,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)writeMessage:(GPBMessage *)message { - NSAssert([message isKindOfClass:[GPBMessage class]], @"Parameter message must be a GPBMessage"); + NSAssert([message isKindOfClass:[GPBMessage class]]); if (![message isKindOfClass:[GPBMessage class]]) { NSLog(@"Failed to send a message that is non-proto."); return; diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index fd472aafebd..ca7bf472830 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -241,7 +241,7 @@ static const NSTimeInterval kTestTimeout = 16; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } -- (void)provideTokenToHandler:(void (^)(NSString *token))handler { +- (void)getTokenWithHandler:(void (^)(NSString *token))handler { dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); dispatch_sync(queue, ^{ handler(@"test-access-token"); From 72dc62ee2e20919b98939ee2e6337fd63a988f48 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 10:30:54 -0800 Subject: [PATCH 0614/2143] Revert "Try earlier APIv2Tests" This reverts commit 3f57e3451bf4a3687e70e92fc218ea25ff7a17c9. --- src/objective-c/tests/run_tests.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index aab80ded61b..f075d9baadd 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -176,7 +176,7 @@ xcodebuild \ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ - -scheme APIv2Tests \ + -scheme ChannelTests \ -destination name="iPhone 8" \ test \ | egrep -v "$XCODEBUILD_FILTER" \ @@ -186,12 +186,11 @@ xcodebuild \ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ - -scheme ChannelTests \ - -destination name="iPhone 8" \ + -scheme APIv2Tests \ + -destination name="iPhone X" \ test \ | egrep -v "$XCODEBUILD_FILTER" \ | egrep -v '^$' \ | egrep -v "(GPBDictionary|GPBArray)" - - exit 0 From 33a4b502c450fa05814992147679d0e77a23d4a5 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 13 Dec 2018 15:55:20 -0800 Subject: [PATCH 0615/2143] Add LB example --- examples/BUILD | 14 +++ examples/cpp/load_balancing/Makefile | 110 ++++++++++++++++++ examples/cpp/load_balancing/README.md | 64 ++++++++++ examples/cpp/load_balancing/greeter_client.cc | 90 ++++++++++++++ examples/cpp/load_balancing/greeter_server.cc | 72 ++++++++++++ 5 files changed, 350 insertions(+) create mode 100644 examples/cpp/load_balancing/Makefile create mode 100644 examples/cpp/load_balancing/README.md create mode 100644 examples/cpp/load_balancing/greeter_client.cc create mode 100644 examples/cpp/load_balancing/greeter_server.cc diff --git a/examples/BUILD b/examples/BUILD index 0f18cfa9ba7..525e6989ee8 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -51,3 +51,17 @@ cc_binary( defines = ["BAZEL_BUILD"], deps = [":helloworld", "//:grpc++"], ) + +cc_binary( + name = "lb_client", + srcs = ["cpp/load_balancing/greeter_client.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) + +cc_binary( + name = "lb_server", + srcs = ["cpp/load_balancing/greeter_server.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) diff --git a/examples/cpp/load_balancing/Makefile b/examples/cpp/load_balancing/Makefile new file mode 100644 index 00000000000..7c8d0727705 --- /dev/null +++ b/examples/cpp/load_balancing/Makefile @@ -0,0 +1,110 @@ +# +# 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. +# + +HOST_SYSTEM = $(shell uname | cut -f 1 -d_) +SYSTEM ?= $(HOST_SYSTEM) +CXX = g++ +CPPFLAGS += `pkg-config --cflags protobuf grpc` +CXXFLAGS += -std=c++11 +ifeq ($(SYSTEM),Darwin) +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -lgrpc++_reflection\ + -ldl +else +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ + -ldl +endif +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + +PROTOS_PATH = ../../protos + +vpath %.proto $(PROTOS_PATH) + +all: system-check greeter_client greeter_server + +greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + +greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + +.PRECIOUS: %.grpc.pb.cc +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + +.PRECIOUS: %.pb.cc +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + +clean: + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server + + +# The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + +PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + +SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + +system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif \ No newline at end of file diff --git a/examples/cpp/load_balancing/README.md b/examples/cpp/load_balancing/README.md new file mode 100644 index 00000000000..f48aca5307f --- /dev/null +++ b/examples/cpp/load_balancing/README.md @@ -0,0 +1,64 @@ +# gRPC C++ Load Balancing Tutorial + +### Prerequisite +Make sure you have run the [hello world example](../helloworld) or understood the basics of gRPC. We will not dive into the details that have been discussed in the hello world example. + +### Get the tutorial source code + +The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: + + +```sh +$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc +``` + +Change your current directory to examples/cpp/load_balancing + +```sh +$ cd examples/cpp/load_balancing/ +``` + +### Generating gRPC code + +To generate the client and server side interfaces: + +```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` + +### Writing a client and a server + +The client and the server can be based on the hello world example. + +Additionally, we can configure the load balancing policy. (To see what load balancing policies are available, check out [this folder](https://github.com/grpc/grpc/tree/master/src/core/ext/filters/client_channel/lb_policy).) + +In the client, set the load balancing policy of the channel via the channel arg (to, for example, Round Robin). + +```cpp + ChannelArguments args; + // Set the load balancing policy for the channel. + args.SetLoadBalancingPolicyName("round_robin"); + GreeterClient greeter(grpc::CreateCustomChannel( + "localhost:50051", grpc::InsecureChannelCredentials(), args)); +``` + +For a working example, refer to [greeter_client.cc](greeter_client.cc) and [greeter_server.cc](greeter_server.cc). + +Build and run the client and the server with the following commands. + +```sh +make +./greeter_server +``` + +```sh +./greeter_client +``` + +(Note that the case in this example is trivial because there is only one server resolved from the name.) \ No newline at end of file diff --git a/examples/cpp/load_balancing/greeter_client.cc b/examples/cpp/load_balancing/greeter_client.cc new file mode 100644 index 00000000000..5b08204a96b --- /dev/null +++ b/examples/cpp/load_balancing/greeter_client.cc @@ -0,0 +1,90 @@ +/* + * + * 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 +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ChannelArguments; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + HelloRequest request; + request.set_name(user); + + // Container for the data we expect from the server. + HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + + // The actual RPC. + Status status = stub_->SayHello(&context, request, &reply); + + // Act upon its status. + if (status.ok()) { + return reply.message(); + } else { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + return "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // 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()). + ChannelArguments args; + // Set the load balancing policy for the channel. + args.SetLoadBalancingPolicyName("round_robin"); + GreeterClient greeter(grpc::CreateCustomChannel( + "localhost:50051", grpc::InsecureChannelCredentials(), args)); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; + + return 0; +} diff --git a/examples/cpp/load_balancing/greeter_server.cc b/examples/cpp/load_balancing/greeter_server.cc new file mode 100644 index 00000000000..f36ad906a29 --- /dev/null +++ b/examples/cpp/load_balancing/greeter_server.cc @@ -0,0 +1,72 @@ +/* + * + * 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 +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { + Status SayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + std::string prefix("Hello "); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} From 92123a4a333719fa3aa55b3db9f36c136e108a47 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 10:42:31 -0800 Subject: [PATCH 0616/2143] Rebuild APIv2Tests --- .../tests/Tests.xcodeproj/project.pbxproj | 410 +++++++++--------- .../xcschemes/APIv2Tests.xcscheme | 8 +- src/objective-c/tests/run_tests.sh | 2 +- 3 files changed, 214 insertions(+), 206 deletions(-) diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 6f24d3512f8..47b79a05345 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -16,7 +16,7 @@ 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; 5E0282E9215AA697007AC99D /* UnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* UnitTests.m */; }; 5E0282EB215AA697007AC99D /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 5E10F5AA218CB0D2008BAB68 /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */; }; + 5E3B95A521CAC6C500C0A151 /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */; }; 5E7D71AD210954A8001EA6BA /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; 5E7D71B5210B9EC9001EA6BA /* InteropTestsCallOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */; }; 5E7D71B7210B9EC9001EA6BA /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; @@ -66,10 +66,10 @@ 6C1A3F81CCF7C998B4813EFD /* libPods-InteropTestsCallOptions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */; }; 886717A79EFF774F356798E6 /* libPods-InteropTestsMultipleChannels.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */; }; 91D4B3C85B6D8562F409CB48 /* libPods-InteropTestsLocalSSLCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */; }; + 98478C9F42329DF769A45B6C /* libPods-APIv2Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */; }; BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */; }; C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */; }; CCF5C0719EF608276AE16374 /* libPods-UnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */; }; - E7F4C80FC8FC667B7447BFE7 /* libPods-APIv2Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */; }; F15EF7852DC70770EFDB1D2C /* libPods-AllTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */; }; /* End PBXBuildFile section */ @@ -212,9 +212,9 @@ 5E0282E6215AA697007AC99D /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E0282E8215AA697007AC99D /* UnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UnitTests.m; sourceTree = ""; }; 5E0282EA215AA697007AC99D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = APIv2Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = APIv2Tests.m; sourceTree = ""; }; - 5E10F5AB218CB0D2008BAB68 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5E3B95A221CAC6C500C0A151 /* APIv2Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = APIv2Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = APIv2Tests.m; sourceTree = ""; }; + 5E3B95A621CAC6C500C0A151 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsCallOptions.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsCallOptions.m; sourceTree = ""; }; 5E7D71B6210B9EC9001EA6BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -313,11 +313,11 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5E10F5A4218CB0D1008BAB68 /* Frameworks */ = { + 5E3B959F21CAC6C500C0A151 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E7F4C80FC8FC667B7447BFE7 /* libPods-APIv2Tests.a in Frameworks */, + 98478C9F42329DF769A45B6C /* libPods-APIv2Tests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -561,11 +561,11 @@ path = UnitTests; sourceTree = ""; }; - 5E10F5A8218CB0D1008BAB68 /* APIv2Tests */ = { + 5E3B95A321CAC6C500C0A151 /* APIv2Tests */ = { isa = PBXGroup; children = ( - 5E10F5A9218CB0D2008BAB68 /* APIv2Tests.m */, - 5E10F5AB218CB0D2008BAB68 /* Info.plist */, + 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */, + 5E3B95A621CAC6C500C0A151 /* Info.plist */, ); path = APIv2Tests; sourceTree = ""; @@ -636,7 +636,7 @@ 5EB2A2F62109284500EB4B69 /* InteropTestsMultipleChannels */, 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */, 5E0282E7215AA697007AC99D /* UnitTests */, - 5E10F5A8218CB0D1008BAB68 /* APIv2Tests */, + 5E3B95A321CAC6C500C0A151 /* APIv2Tests */, 635697C81B14FC11007A7283 /* Products */, 51E4650F34F854F41FF053B3 /* Pods */, 136D535E19727099B941D7B1 /* Frameworks */, @@ -662,7 +662,7 @@ 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */, 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */, 5E0282E6215AA697007AC99D /* UnitTests.xctest */, - 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */, + 5E3B95A221CAC6C500C0A151 /* APIv2Tests.xctest */, ); name = Products; sourceTree = ""; @@ -715,15 +715,15 @@ productReference = 5E0282E6215AA697007AC99D /* UnitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 5E10F5A6218CB0D1008BAB68 /* APIv2Tests */ = { + 5E3B95A121CAC6C500C0A151 /* APIv2Tests */ = { isa = PBXNativeTarget; - buildConfigurationList = 5E10F5B0218CB0D2008BAB68 /* Build configuration list for PBXNativeTarget "APIv2Tests" */; + buildConfigurationList = 5E3B95A721CAC6C500C0A151 /* Build configuration list for PBXNativeTarget "APIv2Tests" */; buildPhases = ( - 031ADD72298D6C6979CB06DB /* [CP] Check Pods Manifest.lock */, - 5E10F5A3218CB0D1008BAB68 /* Sources */, - 5E10F5A4218CB0D1008BAB68 /* Frameworks */, - 5E10F5A5218CB0D1008BAB68 /* Resources */, - FBB92A8B11C52512E67791E8 /* [CP] Copy Pods Resources */, + EDDD3FA856BCA3443ED36D1E /* [CP] Check Pods Manifest.lock */, + 5E3B959E21CAC6C500C0A151 /* Sources */, + 5E3B959F21CAC6C500C0A151 /* Frameworks */, + 5E3B95A021CAC6C500C0A151 /* Resources */, + C17B826BBD02FDD4A5F355AF /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -731,7 +731,7 @@ ); name = APIv2Tests; productName = APIv2Tests; - productReference = 5E10F5A7218CB0D1008BAB68 /* APIv2Tests.xctest */; + productReference = 5E3B95A221CAC6C500C0A151 /* APIv2Tests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */ = { @@ -1043,7 +1043,7 @@ CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; }; - 5E10F5A6218CB0D1008BAB68 = { + 5E3B95A121CAC6C500C0A151 = { CreatedOnToolsVersion = 10.0; ProvisioningStyle = Automatic; }; @@ -1128,7 +1128,7 @@ 5EB2A2F42109284500EB4B69 /* InteropTestsMultipleChannels */, 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */, 5E0282E5215AA697007AC99D /* UnitTests */, - 5E10F5A6218CB0D1008BAB68 /* APIv2Tests */, + 5E3B95A121CAC6C500C0A151 /* APIv2Tests */, ); }; /* End PBXProject section */ @@ -1141,7 +1141,7 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5E10F5A5218CB0D1008BAB68 /* Resources */ = { + 5E3B95A021CAC6C500C0A151 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -1271,24 +1271,6 @@ 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; }; - 031ADD72298D6C6979CB06DB /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-APIv2Tests-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; - }; 0617B5294978A95BEBBFF733 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1721,6 +1703,28 @@ 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; }; + C17B826BBD02FDD4A5F355AF /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-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-APIv2Tests/Pods-APIv2Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; C2E09DC4BD239F71160F0CC1 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1793,6 +1797,28 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + EDDD3FA856BCA3443ED36D1E /* [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-APIv2Tests-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; + }; F07941C0BAF6A7C67AA60C48 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1847,24 +1873,6 @@ 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; }; - FBB92A8B11C52512E67791E8 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1876,11 +1884,11 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5E10F5A3218CB0D1008BAB68 /* Sources */ = { + 5E3B959E21CAC6C500C0A151 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5E10F5AA218CB0D2008BAB68 /* APIv2Tests.m in Sources */, + 5E3B95A521CAC6C500C0A151 /* APIv2Tests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2207,141 +2215,6 @@ }; name = Release; }; - 5E10F5AC218CB0D2008BAB68 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 5E10F5AD218CB0D2008BAB68 /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Test; - }; - 5E10F5AE218CB0D2008BAB68 /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Cronet; - }; - 5E10F5AF218CB0D2008BAB68 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; 5E1228981E4D400F00E8504F /* Test */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2550,6 +2423,141 @@ }; name = Test; }; + 5E3B95A821CAC6C500C0A151 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5E3B95A921CAC6C500C0A151 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5E3B95AA21CAC6C500C0A151 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5E3B95AB21CAC6C500C0A151 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 5E7D71BB210B9EC9001EA6BA /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 3A98DF08852F60AF1D96481D /* Pods-InteropTestsCallOptions.debug.xcconfig */; @@ -3892,13 +3900,13 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 5E10F5B0218CB0D2008BAB68 /* Build configuration list for PBXNativeTarget "APIv2Tests" */ = { + 5E3B95A721CAC6C500C0A151 /* Build configuration list for PBXNativeTarget "APIv2Tests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 5E10F5AC218CB0D2008BAB68 /* Debug */, - 5E10F5AD218CB0D2008BAB68 /* Test */, - 5E10F5AE218CB0D2008BAB68 /* Cronet */, - 5E10F5AF218CB0D2008BAB68 /* Release */, + 5E3B95A821CAC6C500C0A151 /* Debug */, + 5E3B95A921CAC6C500C0A151 /* Test */, + 5E3B95AA21CAC6C500C0A151 /* Cronet */, + 5E3B95AB21CAC6C500C0A151 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme index b444ddc2b67..e0d1d1fdcac 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme @@ -14,7 +14,7 @@ buildForAnalyzing = "NO"> @@ -32,7 +32,7 @@ skipped = "NO"> @@ -55,7 +55,7 @@ @@ -73,7 +73,7 @@ diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index f075d9baadd..e8c3e6ec2a4 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -187,7 +187,7 @@ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ -scheme APIv2Tests \ - -destination name="iPhone X" \ + -destination name="iPhone 8" \ test \ | egrep -v "$XCODEBUILD_FILTER" \ | egrep -v '^$' \ From 1600fde6b69a361203cb47ef983e6b4aac873b6a Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 19 Dec 2018 12:22:00 -0800 Subject: [PATCH 0617/2143] Add Bazel targets for compression example --- examples/BUILD | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/examples/BUILD b/examples/BUILD index 1fa8102cd1d..c4f25d0de9f 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -79,3 +79,17 @@ cc_binary( defines = ["BAZEL_BUILD"], deps = [":helloworld", "//:grpc++"], ) + +cc_binary( + name = "compression_client", + srcs = ["cpp/compression/greeter_client.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) + +cc_binary( + name = "compression_server", + srcs = ["cpp/compression/greeter_server.cc"], + defines = ["BAZEL_BUILD"], + deps = [":helloworld", "//:grpc++"], +) From ad8f04feca10075982208ef8a4c7ce92900d5077 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 19 Dec 2018 12:57:07 -0800 Subject: [PATCH 0618/2143] Fix compiler error --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 4 ++-- 1 file changed, 2 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 3b7c48a72ca..9e03c90ccb9 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -568,8 +568,8 @@ static void close_transport_locked(grpc_chttp2_transport* t, cancel_pings(t, GRPC_ERROR_REF(error)); // ContextList::Execute follows semantics of a callback function and does not // need a ref on error - grpc_core::ContextList::Execute(cl, nullptr, error); - cl = nullptr; + grpc_core::ContextList::Execute(t->cl, nullptr, error); + t->cl = nullptr; if (t->closed_with_error == GRPC_ERROR_NONE) { if (!grpc_error_has_clear_grpc_status(error)) { error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, From 1876d0d3669147e68c64d7916082de64025e9b6f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 13:06:34 -0800 Subject: [PATCH 0619/2143] ProtoRPC bug --- src/objective-c/ProtoRPC/ProtoRPC.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 48a38bd35ac..03e6839c5a0 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -175,7 +175,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)writeMessage:(GPBMessage *)message { - NSAssert([message isKindOfClass:[GPBMessage class]]); + NSAssert([message isKindOfClass:[GPBMessage class]], @"Parameter message must be a GPBMessage"); if (![message isKindOfClass:[GPBMessage class]]) { NSLog(@"Failed to send a message that is non-proto."); return; @@ -199,7 +199,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { @synchronized(self) { - if (initialMetadata != nil && [_handler respondsToSelector:@selector(initialMetadata:)]) { + if (initialMetadata != nil && [_handler respondsToSelector:@selector(didReceiveInitialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { From 0de27b5d2955c2d19a998e133580b721836676da Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 13:08:04 -0800 Subject: [PATCH 0620/2143] More fix ProtoRPC --- src/objective-c/ProtoRPC/ProtoRPC.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 03e6839c5a0..053eaf47f2f 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -235,7 +235,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } [copiedHandler didCloseWithTrailingMetadata:nil - error:ErrorForBadProto(message, _responseClass, error)]; + error:ErrorForBadProto(message, self->_responseClass, error)]; }); [_call cancel]; _call = nil; From c5f84c5cb8830ad5ac4a9f097804308adce204be Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 14:09:56 -0800 Subject: [PATCH 0621/2143] Batch fix --- .../GRPCClient/private/GRPCWrappedCall.m | 4 ++++ src/objective-c/ProtoRPC/ProtoService.h | 6 +++--- src/objective-c/ProtoRPC/ProtoService.m | 13 +++++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 1a848a4b7c3..7d7e77f6ba0 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -292,6 +292,10 @@ gpr_free(ops_array); NSAssert(error == GRPC_CALL_OK, @"Error starting a batch of operations: %i", error); + // To avoid compiler complaint when NSAssert is disabled. + if (error != GRPC_CALL_OK) { + return; + } } } } diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index d76e96ce2a6..900ec8d0e1e 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -25,7 +25,7 @@ @class GRPCProtoCall; @class GRPCUnaryProtoCall; @class GRPCStreamingProtoCall; -@protocol GRPCProtoResponseCallbacks; +@protocol GRPCProtoResponseHandler; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnullability-completeness" @@ -49,12 +49,12 @@ __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoServ - (nullable GRPCUnaryProtoCall *)RPCToMethod:(nonnull NSString *)method message:(nonnull id)message - responseHandler:(nonnull id)handler + responseHandler:(nonnull id)handler callOptions:(nullable GRPCCallOptions *)callOptions responseClass:(nonnull Class)responseClass; - (nullable GRPCStreamingProtoCall *)RPCToMethod:(nonnull NSString *)method - responseHandler:(nonnull id)handler + responseHandler:(nonnull id)handler callOptions:(nullable GRPCCallOptions *)callOptions responseClass:(nonnull Class)responseClass; diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m index b7c7fadbcf0..80a1f2f226c 100644 --- a/src/objective-c/ProtoRPC/ProtoService.m +++ b/src/objective-c/ProtoRPC/ProtoService.m @@ -58,11 +58,14 @@ return self; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" +// Do not call designated initializer here due to nullability incompatibility. This method is from +// old API and does not assert on nullability of the parameters. + - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName serviceName:(NSString *)serviceName { - // Do not call designated initializer here due to nullability incompatibility. This method is from - // old API and does not assert on nullability of the parameters. if ((self = [super init])) { _host = [host copy]; _packageName = [packageName copy]; @@ -72,6 +75,8 @@ return self; } +#pragma clang diagnostic pop + - (GRPCProtoCall *)RPCToMethod:(NSString *)method requestsWriter:(GRXWriter *)requestsWriter responseClass:(Class)responseClass @@ -87,7 +92,7 @@ - (GRPCUnaryProtoCall *)RPCToMethod:(NSString *)method message:(id)message - responseHandler:(id)handler + responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { GRPCProtoMethod *methodName = @@ -104,7 +109,7 @@ } - (GRPCStreamingProtoCall *)RPCToMethod:(NSString *)method - responseHandler:(id)handler + responseHandler:(id)handler callOptions:(GRPCCallOptions *)callOptions responseClass:(Class)responseClass { GRPCProtoMethod *methodName = From f7ca97a6fedc4d20aab6a09b26b143a8996c9b48 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 14:15:12 -0800 Subject: [PATCH 0622/2143] clang-format --- src/objective-c/ProtoRPC/ProtoRPC.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 053eaf47f2f..0ab96a5ba2b 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -199,7 +199,8 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { @synchronized(self) { - if (initialMetadata != nil && [_handler respondsToSelector:@selector(didReceiveInitialMetadata:)]) { + if (initialMetadata != nil && + [_handler respondsToSelector:@selector(didReceiveInitialMetadata:)]) { dispatch_async(_dispatchQueue, ^{ id copiedHandler = nil; @synchronized(self) { From c72a0af7816be07d3bec926f86288f9f97cb6cbd Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 16:19:48 -0800 Subject: [PATCH 0623/2143] change deployment target --- src/objective-c/tests/Tests.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 47b79a05345..b6762cc6001 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -2449,7 +2449,7 @@ ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -2483,7 +2483,7 @@ CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; @@ -2516,7 +2516,7 @@ CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; @@ -2549,7 +2549,7 @@ CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; From 6cf4622cd1a721704c70be2160b6454937771141 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Dec 2018 23:15:26 -0800 Subject: [PATCH 0624/2143] provide host --- src/objective-c/tests/run_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index e8c3e6ec2a4..8402809c097 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -188,6 +188,7 @@ xcodebuild \ -workspace Tests.xcworkspace \ -scheme APIv2Tests \ -destination name="iPhone 8" \ + HOST_PORT_LOCAL=localhost:5050 \ test \ | egrep -v "$XCODEBUILD_FILTER" \ | egrep -v '^$' \ From a022c8204c2d104d741e20e82bd2c89ad0e6788f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Dec 2018 18:20:48 +0100 Subject: [PATCH 0625/2143] csharp interop client: dont set override by default --- src/csharp/Grpc.IntegrationTesting/InteropClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs index e83a8a7274a..47503530820 100644 --- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs +++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs @@ -45,7 +45,7 @@ namespace Grpc.IntegrationTesting [Option("server_host", Default = "localhost")] public string ServerHost { get; set; } - [Option("server_host_override", Default = TestCredentials.DefaultHostOverride)] + [Option("server_host_override")] public string ServerHostOverride { get; set; } [Option("server_port", Required = true)] From 3458ede262ab9398d1baf0d0871b09444d1973a7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Dec 2018 18:29:44 +0100 Subject: [PATCH 0626/2143] dont set server_override for cloud_to_prod tests --- tools/run_tests/run_interop_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index d026145d66f..e015e0a1d14 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -776,7 +776,7 @@ def cloud_to_prod_jobspec(language, container_name = None cmdargs = [ '--server_host=%s' % server_host, - '--server_host_override=%s' % server_host, '--server_port=443', + '--server_port=443', '--test_case=%s' % test_case ] if transport_security == 'tls': From 2b028c8cecf3875665079adeafd974e592c6a638 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 10:37:08 +0100 Subject: [PATCH 0627/2143] do not use default server override for C++ interop client --- test/cpp/interop/client.cc | 2 +- test/cpp/interop/stress_test.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index a4b1a85f856..08aad0b0118 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -38,7 +38,7 @@ DEFINE_string(custom_credentials_type, "", "User provided credentials type."); DEFINE_bool(use_test_ca, false, "False to use SSL roots for google"); DEFINE_int32(server_port, 0, "Server port."); DEFINE_string(server_host, "localhost", "Server host to connect to"); -DEFINE_string(server_host_override, "foo.test.google.fr", +DEFINE_string(server_host_override, "", "Override the server host which is sent in HTTP header"); DEFINE_string( test_case, "large_unary", diff --git a/test/cpp/interop/stress_test.cc b/test/cpp/interop/stress_test.cc index ebbd14beba2..3e00980a269 100644 --- a/test/cpp/interop/stress_test.cc +++ b/test/cpp/interop/stress_test.cc @@ -103,7 +103,7 @@ DEFINE_bool(use_alts, false, "Whether to use alts. Enable alts will disable tls."); DEFINE_bool(use_tls, false, "Whether to use tls."); DEFINE_bool(use_test_ca, false, "False to use SSL roots for google"); -DEFINE_string(server_host_override, "foo.test.google.fr", +DEFINE_string(server_host_override, "", "Override the server host which is sent in HTTP header"); using grpc::testing::ALTS; From f9e1cde01cd83ef6ee34a5ef734aa591f9095ed7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 10:43:17 +0100 Subject: [PATCH 0628/2143] yapf run_interop_tests.py --- tools/run_tests/run_interop_tests.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index e015e0a1d14..fe691fdbf5e 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -775,8 +775,7 @@ def cloud_to_prod_jobspec(language, """Creates jobspec for cloud-to-prod interop test""" container_name = None cmdargs = [ - '--server_host=%s' % server_host, - '--server_port=443', + '--server_host=%s' % server_host, '--server_port=443', '--test_case=%s' % test_case ] if transport_security == 'tls': From 4f261a071e8e49373bf6b26831cc4768e00ac38d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 10:44:09 +0100 Subject: [PATCH 0629/2143] do not use server override in python interop client by default --- src/python/grpcio_tests/tests/interop/client.py | 12 +++++++----- src/python/grpcio_tests/tests/stress/client.py | 1 - 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/python/grpcio_tests/tests/interop/client.py b/src/python/grpcio_tests/tests/interop/client.py index 698c37017f5..56cb29477c8 100644 --- a/src/python/grpcio_tests/tests/interop/client.py +++ b/src/python/grpcio_tests/tests/interop/client.py @@ -54,7 +54,6 @@ def _args(): help='replace platform root CAs with ca.pem') parser.add_argument( '--server_host_override', - default="foo.test.google.fr", type=str, help='the server host to which to claim to connect') parser.add_argument( @@ -100,10 +99,13 @@ def _stub(args): channel_credentials = grpc.composite_channel_credentials( channel_credentials, call_credentials) - channel = grpc.secure_channel(target, channel_credentials, (( - 'grpc.ssl_target_name_override', - args.server_host_override, - ),)) + channel_opts = None + if args.server_host_override: + channel_opts = (( + 'grpc.ssl_target_name_override', + args.server_host_override, + ),) + channel = grpc.secure_channel(target, channel_credentials, channel_opts) else: channel = grpc.insecure_channel(target) if args.test_case == "unimplemented_service": diff --git a/src/python/grpcio_tests/tests/stress/client.py b/src/python/grpcio_tests/tests/stress/client.py index 41f2e1b6c2d..07aff15ed7e 100644 --- a/src/python/grpcio_tests/tests/stress/client.py +++ b/src/python/grpcio_tests/tests/stress/client.py @@ -71,7 +71,6 @@ def _args(): '--use_tls', help='Whether to use TLS', default=False, type=bool) parser.add_argument( '--server_host_override', - default="foo.test.google.fr", help='the server host to which to claim to connect', type=str) return parser.parse_args() From b4d4f2c46736294ed6ed2790074ceb92ceb29dd1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 10:58:55 +0100 Subject: [PATCH 0630/2143] do not use server override in php interop client by default --- src/php/tests/interop/interop_client.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index c865678f704..3e19c7ae339 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -538,7 +538,7 @@ function _makeStub($args) $test_case = $args['test_case']; - $host_override = 'foo.test.google.fr'; + $host_override = ''; if (array_key_exists('server_host_override', $args)) { $host_override = $args['server_host_override']; } @@ -565,7 +565,9 @@ function _makeStub($args) $ssl_credentials = Grpc\ChannelCredentials::createSsl(); } $opts['credentials'] = $ssl_credentials; - $opts['grpc.ssl_target_name_override'] = $host_override; + if (!empty($host_override)) { + $opts['grpc.ssl_target_name_override'] = $host_override; + } } else { $opts['credentials'] = Grpc\ChannelCredentials::createInsecure(); } From b904fdaa40f74498dcc5a6c6c75612599b79d7c6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 13:42:27 +0100 Subject: [PATCH 0631/2143] do not use server override in ruby interop client by default --- src/ruby/pb/test/client.rb | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb index b2303c6e142..03f3d9001aa 100755 --- a/src/ruby/pb/test/client.rb +++ b/src/ruby/pb/test/client.rb @@ -111,10 +111,13 @@ def create_stub(opts) if opts.secure creds = ssl_creds(opts.use_test_ca) stub_opts = { - channel_args: { - GRPC::Core::Channel::SSL_TARGET => opts.server_host_override - } + channel_args: {} } + unless opts.server_host_override.empty? + stub_opts[:channel_args].merge!({ + GRPC::Core::Channel::SSL_TARGET => opts.server_host_override + }) + end # Add service account creds if specified wants_creds = %w(all compute_engine_creds service_account_creds) @@ -603,7 +606,7 @@ class NamedTests if not op.metadata.has_key?(initial_metadata_key) fail AssertionError, "Expected initial metadata. None received" elsif op.metadata[initial_metadata_key] != metadata[initial_metadata_key] - fail AssertionError, + fail AssertionError, "Expected initial metadata: #{metadata[initial_metadata_key]}. "\ "Received: #{op.metadata[initial_metadata_key]}" end @@ -611,7 +614,7 @@ class NamedTests fail AssertionError, "Expected trailing metadata. None received" elsif op.trailing_metadata[trailing_metadata_key] != metadata[trailing_metadata_key] - fail AssertionError, + fail AssertionError, "Expected trailing metadata: #{metadata[trailing_metadata_key]}. "\ "Received: #{op.trailing_metadata[trailing_metadata_key]}" end @@ -639,7 +642,7 @@ class NamedTests fail AssertionError, "Expected trailing metadata. None received" elsif duplex_op.trailing_metadata[trailing_metadata_key] != metadata[trailing_metadata_key] - fail AssertionError, + fail AssertionError, "Expected trailing metadata: #{metadata[trailing_metadata_key]}. "\ "Received: #{duplex_op.trailing_metadata[trailing_metadata_key]}" end @@ -710,7 +713,7 @@ Args = Struct.new(:default_service_account, :server_host, :server_host_override, # validates the command line options, returning them as a Hash. def parse_args args = Args.new - args.server_host_override = 'foo.test.google.fr' + args.server_host_override = '' OptionParser.new do |opts| opts.on('--oauth_scope scope', 'Scope for OAuth tokens') { |v| args['oauth_scope'] = v } From dcb194c6e3836e57ca41ef13ab1ee633590a5af4 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 20 Dec 2018 14:46:18 +0100 Subject: [PATCH 0632/2143] PHP interop client: do not append :443 to host name unless necessary $server_port is actually a string and appending the port number to server_host breaks jwt_token_creds testcase. --- src/php/tests/interop/interop_client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index 3e19c7ae339..19cbf21bc2b 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -530,7 +530,7 @@ function _makeStub($args) throw new Exception('Missing argument: --test_case is required'); } - if ($args['server_port'] === 443) { + if ($args['server_port'] === '443') { $server_address = $args['server_host']; } else { $server_address = $args['server_host'].':'.$args['server_port']; From 291b4f363bbf7226eb7a3bbd7ad620f5be67c625 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 20 Dec 2018 09:52:26 -0800 Subject: [PATCH 0633/2143] More test fix --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/tests/run_tests.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9bcacac0dfc..b0412cddb09 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -69,7 +69,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @implementation GRPCRequestOptions - (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { - NSAssert(host.length != 0 && path.length != 0, @"Host and Path cannot be empty"); + NSAssert(host.length != 0 && path.length != 0, @"host and path cannot be empty"); if (host.length == 0 || path.length == 0) { return nil; } diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index 8402809c097..f6fea96920e 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -189,6 +189,7 @@ xcodebuild \ -scheme APIv2Tests \ -destination name="iPhone 8" \ HOST_PORT_LOCAL=localhost:5050 \ + HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \ test \ | egrep -v "$XCODEBUILD_FILTER" \ | egrep -v '^$' \ From 09f57c17ee22e344adad9d81be5747305a02d33e Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 20 Dec 2018 10:10:19 -0800 Subject: [PATCH 0634/2143] Refactor request routing code out of client_channel. --- BUILD | 2 + CMakeLists.txt | 6 + Makefile | 6 + build.yaml | 2 + config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + grpc.gyp | 4 + package.xml | 2 + .../filters/client_channel/client_channel.cc | 1035 +++-------------- .../ext/filters/client_channel/lb_policy.h | 7 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 8 +- .../lb_policy/pick_first/pick_first.cc | 8 +- .../lb_policy/round_robin/round_robin.cc | 8 +- .../client_channel/lb_policy/xds/xds.cc | 8 +- .../filters/client_channel/request_routing.cc | 936 +++++++++++++++ .../filters/client_channel/request_routing.h | 177 +++ .../client_channel/resolver_result_parsing.cc | 14 +- .../client_channel/resolver_result_parsing.h | 30 +- src/python/grpcio/grpc_core_dependencies.py | 1 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 3 + 24 files changed, 1361 insertions(+), 906 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 diff --git a/BUILD b/BUILD index b9b39a37a7e..e3c765198b2 100644 --- a/BUILD +++ b/BUILD @@ -1056,6 +1056,7 @@ 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", @@ -1079,6 +1080,7 @@ 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", diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f34bf841d2..76886307813 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1210,6 +1210,7 @@ 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 @@ -1562,6 +1563,7 @@ 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 @@ -1935,6 +1937,7 @@ 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 @@ -2256,6 +2259,7 @@ 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 @@ -2589,6 +2593,7 @@ 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 @@ -3443,6 +3448,7 @@ 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 diff --git a/Makefile b/Makefile index 2ad3eb4c142..147e9505a33 100644 --- a/Makefile +++ b/Makefile @@ -3723,6 +3723,7 @@ 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 \ @@ -4069,6 +4070,7 @@ 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 \ @@ -4435,6 +4437,7 @@ 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 \ @@ -4743,6 +4746,7 @@ 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 \ @@ -5050,6 +5054,7 @@ 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 \ @@ -5881,6 +5886,7 @@ 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 \ diff --git a/build.yaml b/build.yaml index 830123110ac..9d73e31b2e5 100644 --- a/build.yaml +++ b/build.yaml @@ -584,6 +584,7 @@ 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 @@ -608,6 +609,7 @@ 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 diff --git a/config.m4 b/config.m4 index 16de5204bb2..25ffe2148ab 100644 --- a/config.m4 +++ b/config.m4 @@ -352,6 +352,7 @@ 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 \ diff --git a/config.w32 b/config.w32 index be10faab9cd..b6e71dd09a5 100644 --- a/config.w32 +++ b/config.w32 @@ -327,6 +327,7 @@ 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 " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index f918fe8ad9c..29a79dd47ab 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -355,6 +355,7 @@ 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', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 0a78733f8da..f873bc693bc 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -349,6 +349,7 @@ 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', @@ -791,6 +792,7 @@ 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', @@ -970,6 +972,7 @@ 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', diff --git a/grpc.gemspec b/grpc.gemspec index 1ee7bec8e7d..3c680b044f7 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -285,6 +285,7 @@ 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 ) @@ -730,6 +731,7 @@ 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 ) diff --git a/grpc.gyp b/grpc.gyp index 641235eec20..80b6d0315a1 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -534,6 +534,7 @@ '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', @@ -794,6 +795,7 @@ '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', @@ -1035,6 +1037,7 @@ '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', @@ -1288,6 +1291,7 @@ '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', diff --git a/package.xml b/package.xml index 68fc7433cb4..2632fcb276b 100644 --- a/package.xml +++ b/package.xml @@ -290,6 +290,7 @@ + @@ -735,6 +736,7 @@ + diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 70aac472314..dd741f1e2de 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -35,10 +35,10 @@ #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/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/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" @@ -63,7 +63,6 @@ #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_metadata.h" -using grpc_core::ServerAddressList; using grpc_core::internal::ClientChannelMethodParams; using grpc_core::internal::ClientChannelMethodParamsTable; using grpc_core::internal::ProcessedResolverResult; @@ -88,31 +87,18 @@ grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel"); struct external_connectivity_watcher; typedef struct client_channel_channel_data { - grpc_core::OrphanablePtr resolver; - bool started_resolving; + grpc_core::ManualConstructor request_router; + bool deadline_checking_enabled; - grpc_client_channel_factory* client_channel_factory; bool enable_retries; size_t per_rpc_retry_buffer_size; /** combiner protecting all variables below in this data structure */ grpc_combiner* combiner; - /** currently active load balancer */ - grpc_core::OrphanablePtr lb_policy; /** retry throttle data */ grpc_core::RefCountedPtr retry_throttle_data; /** maps method names to method_parameters structs */ grpc_core::RefCountedPtr method_params_table; - /** incoming resolver result - set by resolver.next() */ - grpc_channel_args* resolver_result; - /** a list of closures that are all waiting for resolver result to come in */ - grpc_closure_list waiting_for_resolver_result_closures; - /** resolver callback */ - grpc_closure on_resolver_result_changed; - /** connectivity state being tracked */ - grpc_connectivity_state_tracker state_tracker; - /** when an lb_policy arrives, should we try to exit idle */ - bool exit_idle_when_lb_policy_arrives; /** owning stack */ grpc_channel_stack* owning_stack; /** interested parties (owned) */ @@ -129,418 +115,40 @@ typedef struct client_channel_channel_data { grpc_core::UniquePtr info_lb_policy_name; /** service config in JSON form */ grpc_core::UniquePtr info_service_config_json; - /* backpointer to grpc_channel's channelz node */ - grpc_core::channelz::ClientChannelNode* channelz_channel; - /* caches if the last resolution event contained addresses */ - bool previous_resolution_contained_addresses; } channel_data; -typedef struct { - channel_data* chand; - /** used as an identifier, don't dereference it because the LB policy may be - * non-existing when the callback is run */ - grpc_core::LoadBalancingPolicy* lb_policy; - grpc_closure closure; -} reresolution_request_args; - -/** We create one watcher for each new lb_policy that is returned from a - resolver, to watch for state changes from the lb_policy. When a state - change is seen, we update the channel, and create a new watcher. */ -typedef struct { - channel_data* chand; - grpc_closure on_changed; - grpc_connectivity_state state; - grpc_core::LoadBalancingPolicy* lb_policy; -} lb_policy_connectivity_watcher; - -static void watch_lb_policy_locked(channel_data* chand, - grpc_core::LoadBalancingPolicy* lb_policy, - grpc_connectivity_state current_state); - -static const char* 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_channel_connectivity_state_locked(channel_data* chand, - grpc_connectivity_state state, - grpc_error* error, - const char* reason) { - /* TODO: Improve failure handling: - * - Make it possible for policies to return GRPC_CHANNEL_TRANSIENT_FAILURE. - * - Hand over pending picks from old policies during the switch that happens - * when resolver provides an update. */ - if (chand->lb_policy != nullptr) { - if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) { - /* cancel picks with wait_for_ready=false */ - chand->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 */ - chand->lb_policy->CancelMatchingPicksLocked(/* mask= */ 0, /* check= */ 0, - GRPC_ERROR_REF(error)); - } - } - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: setting connectivity state to %s", chand, - grpc_connectivity_state_name(state)); - } - if (chand->channelz_channel != nullptr) { - chand->channelz_channel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string( - channel_connectivity_state_change_string(state))); - } - grpc_connectivity_state_set(&chand->state_tracker, state, error, reason); -} - -static void on_lb_policy_state_changed_locked(void* arg, grpc_error* error) { - lb_policy_connectivity_watcher* w = - static_cast(arg); - /* check if the notification is for the latest policy */ - if (w->lb_policy == w->chand->lb_policy.get()) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: lb_policy=%p state changed to %s", w->chand, - w->lb_policy, grpc_connectivity_state_name(w->state)); - } - set_channel_connectivity_state_locked(w->chand, w->state, - GRPC_ERROR_REF(error), "lb_changed"); - if (w->state != GRPC_CHANNEL_SHUTDOWN) { - watch_lb_policy_locked(w->chand, w->lb_policy, w->state); - } - } - GRPC_CHANNEL_STACK_UNREF(w->chand->owning_stack, "watch_lb_policy"); - gpr_free(w); -} - -static void watch_lb_policy_locked(channel_data* chand, - grpc_core::LoadBalancingPolicy* lb_policy, - grpc_connectivity_state current_state) { - lb_policy_connectivity_watcher* w = - static_cast(gpr_malloc(sizeof(*w))); - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "watch_lb_policy"); - w->chand = chand; - GRPC_CLOSURE_INIT(&w->on_changed, on_lb_policy_state_changed_locked, w, - grpc_combiner_scheduler(chand->combiner)); - w->state = current_state; - w->lb_policy = lb_policy; - lb_policy->NotifyOnStateChangeLocked(&w->state, &w->on_changed); -} - -static void start_resolving_locked(channel_data* chand) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: starting name resolution", chand); - } - GPR_ASSERT(!chand->started_resolving); - chand->started_resolving = true; - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); - chand->resolver->NextLocked(&chand->resolver_result, - &chand->on_resolver_result_changed); -} - -// Invoked from the resolver NextLocked() callback when the resolver -// is shutting down. -static void on_resolver_shutdown_locked(channel_data* chand, - grpc_error* error) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: shutting down", chand); - } - if (chand->lb_policy != nullptr) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: shutting down lb_policy=%p", chand, - chand->lb_policy.get()); - } - grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - chand->lb_policy.reset(); - } - if (chand->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 (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: spontaneous shutdown from resolver %p", - chand, chand->resolver.get()); - } - chand->resolver.reset(); - set_channel_connectivity_state_locked( - chand, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Resolver spontaneous shutdown", &error, 1), - "resolver_spontaneous_shutdown"); - } - grpc_closure_list_fail_all(&chand->waiting_for_resolver_result_closures, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Channel disconnected", &error, 1)); - GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures); - GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "resolver"); - grpc_channel_args_destroy(chand->resolver_result); - chand->resolver_result = nullptr; - GRPC_ERROR_UNREF(error); -} - -static void request_reresolution_locked(void* arg, grpc_error* error) { - reresolution_request_args* args = - static_cast(arg); - channel_data* chand = args->chand; - // If this invocation is for a stale LB policy, treat it as an LB shutdown - // signal. - if (args->lb_policy != chand->lb_policy.get() || error != GRPC_ERROR_NONE || - chand->resolver == nullptr) { - GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "re-resolution"); - gpr_free(args); - return; - } - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: started name re-resolving", chand); - } - chand->resolver->RequestReresolutionLocked(); - // Give back the closure to the LB policy. - chand->lb_policy->SetReresolutionClosureLocked(&args->closure); -} - -using TraceStringVector = grpc_core::InlinedVector; - -// 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. -static void create_new_lb_policy_locked( - channel_data* chand, char* lb_policy_name, grpc_json* lb_config, - grpc_connectivity_state* connectivity_state, - grpc_error** connectivity_error, TraceStringVector* trace_strings) { - grpc_core::LoadBalancingPolicy::Args lb_policy_args; - lb_policy_args.combiner = chand->combiner; - lb_policy_args.client_channel_factory = chand->client_channel_factory; - lb_policy_args.args = chand->resolver_result; - lb_policy_args.lb_config = lb_config; - grpc_core::OrphanablePtr new_lb_policy = - grpc_core::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 (chand->channelz_channel != nullptr) { - char* str; - gpr_asprintf(&str, "Could not create LB policy \'%s\'", lb_policy_name); - trace_strings->push_back(str); - } - } else { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: created new LB policy \"%s\" (%p)", chand, - lb_policy_name, new_lb_policy.get()); - } - if (chand->channelz_channel != 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 - // chand->interested_parties. - if (chand->lb_policy != nullptr) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: shutting down lb_policy=%p", chand, - chand->lb_policy.get()); - } - grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - chand->lb_policy->HandOffPendingPicksLocked(new_lb_policy.get()); - } - chand->lb_policy = std::move(new_lb_policy); - grpc_pollset_set_add_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - // Set up re-resolution callback. - reresolution_request_args* args = - static_cast(gpr_zalloc(sizeof(*args))); - args->chand = chand; - args->lb_policy = chand->lb_policy.get(); - GRPC_CLOSURE_INIT(&args->closure, request_reresolution_locked, args, - grpc_combiner_scheduler(chand->combiner)); - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "re-resolution"); - chand->lb_policy->SetReresolutionClosureLocked(&args->closure); - // Get the new LB policy's initial connectivity state and start a - // connectivity watch. - GRPC_ERROR_UNREF(*connectivity_error); - *connectivity_state = - chand->lb_policy->CheckConnectivityLocked(connectivity_error); - if (chand->exit_idle_when_lb_policy_arrives) { - chand->lb_policy->ExitIdleLocked(); - chand->exit_idle_when_lb_policy_arrives = false; - } - watch_lb_policy_locked(chand, chand->lb_policy.get(), *connectivity_state); - } -} - -static void maybe_add_trace_message_for_address_changes_locked( - channel_data* chand, TraceStringVector* trace_strings) { - const ServerAddressList* addresses = - grpc_core::FindServerAddressListChannelArg(chand->resolver_result); - const bool resolution_contains_addresses = - addresses != nullptr && addresses->size() > 0; - if (!resolution_contains_addresses && - chand->previous_resolution_contained_addresses) { - trace_strings->push_back(gpr_strdup("Address list became empty")); - } else if (resolution_contains_addresses && - !chand->previous_resolution_contained_addresses) { - trace_strings->push_back(gpr_strdup("Address list became non-empty")); - } - chand->previous_resolution_contained_addresses = - resolution_contains_addresses; -} - -static void concatenate_and_add_channel_trace_locked( - channel_data* chand, TraceStringVector* trace_strings) { - 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); - chand->channelz_channel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_new(flat, flat_len, gpr_free)); - gpr_strvec_destroy(&v); - } -} - -// Callback invoked when a resolver result is available. -static void on_resolver_result_changed_locked(void* arg, grpc_error* error) { +// 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); + ProcessedResolverResult resolver_result(args, chand->enable_retries); + grpc_core::UniquePtr service_config_json = + resolver_result.service_config_json(); if (grpc_client_channel_trace.enabled()) { - const char* disposition = - chand->resolver_result != nullptr - ? "" - : (error == GRPC_ERROR_NONE ? " (transient error)" - : " (resolver shutdown)"); - gpr_log(GPR_INFO, - "chand=%p: got resolver result: resolver_result=%p error=%s%s", - chand, chand->resolver_result, grpc_error_string(error), - disposition); + gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", + chand, service_config_json.get()); } - // Handle shutdown. - if (error != GRPC_ERROR_NONE || chand->resolver == nullptr) { - on_resolver_shutdown_locked(chand, 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"); - // chand->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 (chand->resolver_result == nullptr) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: resolver transient failure", chand); - } - // Don't override connectivity state if we already have an LB policy. - if (chand->lb_policy != nullptr) set_connectivity_state = false; - } else { - // Parse the resolver result. - ProcessedResolverResult resolver_result(chand->resolver_result, - chand->enable_retries); - chand->retry_throttle_data = resolver_result.retry_throttle_data(); - chand->method_params_table = resolver_result.method_params_table(); - grpc_core::UniquePtr service_config_json = - resolver_result.service_config_json(); - if (service_config_json != nullptr && grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", - chand, service_config_json.get()); - } - grpc_core::UniquePtr lb_policy_name = - resolver_result.lb_policy_name(); - grpc_json* lb_policy_config = resolver_result.lb_policy_config(); - // Check to see if we're already using the right LB policy. - // Note: It's safe to use chand->info_lb_policy_name here without - // taking a lock on chand->info_mu, because this function is the - // only thing that modifies its value, and it can only be invoked - // once at any given time. - bool lb_policy_name_changed = - chand->info_lb_policy_name == nullptr || - strcmp(chand->info_lb_policy_name.get(), lb_policy_name.get()) != 0; - if (chand->lb_policy != nullptr && !lb_policy_name_changed) { - // Continue using the same LB policy. Update with new addresses. - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: updating existing LB policy \"%s\" (%p)", - chand, lb_policy_name.get(), chand->lb_policy.get()); - } - chand->lb_policy->UpdateLocked(*chand->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. - create_new_lb_policy_locked(chand, lb_policy_name.get(), lb_policy_config, - &connectivity_state, &connectivity_error, - &trace_strings); - } - // Note: It's safe to use chand->info_service_config_json here without - // taking a lock on chand->info_mu, because this function is the - // only thing that modifies its value, and it can only be invoked - // once at any given time. - if (chand->channelz_channel != nullptr) { - if (((service_config_json == nullptr) != - (chand->info_service_config_json == nullptr)) || - (service_config_json != nullptr && - strcmp(service_config_json.get(), - chand->info_service_config_json.get()) != 0)) { - // 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")); - } - maybe_add_trace_message_for_address_changes_locked(chand, &trace_strings); - concatenate_and_add_channel_trace_locked(chand, &trace_strings); - } - // Swap out the data used by cc_get_channel_info(). - gpr_mu_lock(&chand->info_mu); - chand->info_lb_policy_name = std::move(lb_policy_name); - chand->info_service_config_json = std::move(service_config_json); - gpr_mu_unlock(&chand->info_mu); - // Clean up. - grpc_channel_args_destroy(chand->resolver_result); - chand->resolver_result = nullptr; - } - // Set the channel's connectivity state if needed. - if (set_connectivity_state) { - set_channel_connectivity_state_locked( - chand, 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(&chand->waiting_for_resolver_result_closures); - chand->resolver->NextLocked(&chand->resolver_result, - &chand->on_resolver_result_changed); + // Update channel state. + chand->retry_throttle_data = resolver_result.retry_throttle_data(); + chand->method_params_table = 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(); + const bool service_config_changed = + ((service_config_json == nullptr) != + (chand->info_service_config_json == nullptr)) || + (service_config_json != nullptr && + strcmp(service_config_json.get(), + chand->info_service_config_json.get()) != 0); + chand->info_service_config_json = std::move(service_config_json); + gpr_mu_unlock(&chand->info_mu); + // Return results. + *lb_policy_name = chand->info_lb_policy_name.get(); + *lb_policy_config = resolver_result.lb_policy_config(); + return service_config_changed; } static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { @@ -550,15 +158,14 @@ 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) { - if (chand->lb_policy == nullptr) { + 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)); @@ -567,7 +174,8 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { 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->lb_policy->PickLocked(&pick_state, &error)); + 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); @@ -586,37 +194,14 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { } if (op->disconnect_with_error != GRPC_ERROR_NONE) { - if (chand->resolver != nullptr) { - set_channel_connectivity_state_locked( - chand, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(op->disconnect_with_error), "disconnect"); - chand->resolver.reset(); - if (!chand->started_resolving) { - grpc_closure_list_fail_all(&chand->waiting_for_resolver_result_closures, - GRPC_ERROR_REF(op->disconnect_with_error)); - GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures); - } - if (chand->lb_policy != nullptr) { - grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - chand->lb_policy.reset(); - } - } - GRPC_ERROR_UNREF(op->disconnect_with_error); + chand->request_router->ShutdownLocked(op->disconnect_with_error); } if (op->reset_connect_backoff) { - if (chand->resolver != nullptr) { - chand->resolver->ResetBackoffLocked(); - chand->resolver->RequestReresolutionLocked(); - } - if (chand->lb_policy != nullptr) { - chand->lb_policy->ResetBackoffLocked(); - } + chand->request_router->ResetConnectionBackoffLocked(); } GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "start_transport_op"); - GRPC_CLOSURE_SCHED(op->on_consumed, GRPC_ERROR_NONE); } @@ -667,12 +252,9 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); chand->owning_stack = args->channel_stack; - GRPC_CLOSURE_INIT(&chand->on_resolver_result_changed, - on_resolver_result_changed_locked, chand, - grpc_combiner_scheduler(chand->combiner)); + chand->deadline_checking_enabled = + grpc_deadline_checking_enabled(args->channel_args); chand->interested_parties = grpc_pollset_set_create(); - grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE, - "client_channel"); grpc_client_channel_start_backup_polling(chand->interested_parties); // Record max per-RPC retry buffer size. const grpc_arg* arg = grpc_channel_args_find( @@ -682,8 +264,6 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, // Record enable_retries. arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_ENABLE_RETRIES); chand->enable_retries = grpc_channel_arg_get_bool(arg, true); - chand->channelz_channel = nullptr; - chand->previous_resolution_contained_addresses = false; // Record client channel factory. arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_CLIENT_CHANNEL_FACTORY); @@ -695,9 +275,7 @@ 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_ref( - static_cast(arg->value.pointer.p)); - chand->client_channel_factory = + grpc_client_channel_factory* client_channel_factory = static_cast(arg->value.pointer.p); // Get server name to resolve, using proxy mapper if needed. arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI); @@ -713,39 +291,24 @@ 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 resolver. - chand->resolver = grpc_core::ResolverRegistry::CreateResolver( - proxy_name != nullptr ? proxy_name : arg->value.string, - new_args != nullptr ? new_args : args->channel_args, - chand->interested_parties, chand->combiner); - if (proxy_name != nullptr) gpr_free(proxy_name); - if (new_args != nullptr) grpc_channel_args_destroy(new_args); - if (chand->resolver == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed"); - } - chand->deadline_checking_enabled = - grpc_deadline_checking_enabled(args->channel_args); - return GRPC_ERROR_NONE; + // Instantiate request router. + grpc_client_channel_factory_ref(client_channel_factory); + 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); + grpc_channel_args_destroy(new_args); + 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->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. - chand->resolver.reset(); - } - if (chand->client_channel_factory != nullptr) { - grpc_client_channel_factory_unref(chand->client_channel_factory); - } - if (chand->lb_policy != nullptr) { - grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - chand->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->info_lb_policy_name.reset(); @@ -753,7 +316,6 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { chand->retry_throttle_data.reset(); chand->method_params_table.reset(); grpc_client_channel_stop_backup_polling(chand->interested_parties); - grpc_connectivity_state_destroy(&chand->state_tracker); grpc_pollset_set_destroy(chand->interested_parties); GRPC_COMBINER_UNREF(chand->combiner, "client_channel"); gpr_mu_destroy(&chand->info_mu); @@ -810,6 +372,7 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { // - add census stats for retries namespace { + struct call_data; // State used for starting a retryable batch on a subchannel call. @@ -894,12 +457,12 @@ struct subchannel_call_retry_state { bool completed_recv_initial_metadata : 1; bool started_recv_trailing_metadata : 1; bool completed_recv_trailing_metadata : 1; + // State for callback processing. subchannel_batch_data* recv_initial_metadata_ready_deferred_batch = nullptr; grpc_error* recv_initial_metadata_error = GRPC_ERROR_NONE; subchannel_batch_data* recv_message_ready_deferred_batch = nullptr; grpc_error* recv_message_error = GRPC_ERROR_NONE; subchannel_batch_data* recv_trailing_metadata_internal_batch = nullptr; - // State for callback processing. // NOTE: Do not move this next to the metadata bitfields above. That would // save space but will also result in a data race because compiler will // generate a 2 byte store which overwrites the meta-data fields upon @@ -908,12 +471,12 @@ struct subchannel_call_retry_state { }; // Pending batches stored in call data. -typedef struct { +struct pending_batch { // The pending batch. If nullptr, this slot is empty. grpc_transport_stream_op_batch* batch; // Indicates whether payload for send ops has been cached in call data. bool send_ops_cached; -} pending_batch; +}; /** Call data. Holds a pointer to grpc_subchannel_call and the associated machinery to create such a pointer. @@ -950,11 +513,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.subchannel_call_context[i].value != nullptr) { - pick.subchannel_call_context[i].destroy( - pick.subchannel_call_context[i].value); - } + if (have_request) { + request.Destroy(); } } @@ -981,12 +541,11 @@ struct call_data { // Set when we get a cancel_stream op. grpc_error* cancel_error = GRPC_ERROR_NONE; - grpc_core::LoadBalancingPolicy::PickState pick; + grpc_core::ManualConstructor request; + bool have_request = false; grpc_closure pick_closure; - grpc_closure pick_cancel_closure; grpc_polling_entity* pollent = nullptr; - bool pollent_added_to_interested_parties = false; // Batches are added to this list when received from above. // They are removed when we are done handling the batch (i.e., when @@ -1036,6 +595,7 @@ struct call_data { grpc_linked_mdelem* send_trailing_metadata_storage = nullptr; grpc_metadata_batch send_trailing_metadata; }; + } // namespace // Forward declarations. @@ -1438,8 +998,9 @@ static void do_retry(grpc_call_element* elem, "client_channel_call_retry"); calld->subchannel_call = nullptr; } - if (calld->pick.connected_subchannel != nullptr) { - calld->pick.connected_subchannel.reset(); + if (calld->have_request) { + calld->have_request = false; + calld->request.Destroy(); } // Compute backoff delay. grpc_millis next_attempt_time; @@ -1588,6 +1149,7 @@ static bool maybe_retry(grpc_call_element* elem, // namespace { + subchannel_batch_data::subchannel_batch_data(grpc_call_element* elem, call_data* calld, int refcount, bool set_on_complete) @@ -1628,6 +1190,7 @@ void subchannel_batch_data::destroy() { call_data* calld = static_cast(elem->call_data); GRPC_CALL_STACK_UNREF(calld->owning_call, "batch_data"); } + } // namespace // Creates a subchannel_batch_data object on the call's arena with the @@ -2644,17 +2207,18 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { 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.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* new_error = calld->pick.connected_subchannel->CreateCall( - call_args, &calld->subchannel_call); + 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, grpc_error_string(new_error)); @@ -2666,7 +2230,8 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { if (parent_data_size > 0) { new (grpc_connected_subchannel_call_get_parent_data( calld->subchannel_call)) - subchannel_call_retry_state(calld->pick.subchannel_call_context); + subchannel_call_retry_state( + calld->request->pick()->subchannel_call_context); } pending_batches_resume(elem); } @@ -2678,7 +2243,7 @@ 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->pick.connected_subchannel == nullptr)) { + 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. @@ -2707,135 +2272,27 @@ static void pick_done(void* arg, grpc_error* error) { } } -static void maybe_add_call_to_channel_interested_parties_locked( - grpc_call_element* elem) { +// 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); - if (!calld->pollent_added_to_interested_parties) { - calld->pollent_added_to_interested_parties = true; - grpc_polling_entity_add_to_pollset_set(calld->pollent, - chand->interested_parties); + 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; } + return false; } -static void maybe_del_call_from_channel_interested_parties_locked( - grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (calld->pollent_added_to_interested_parties) { - calld->pollent_added_to_interested_parties = false; - grpc_polling_entity_del_from_pollset_set(calld->pollent, - chand->interested_parties); - } -} - -// Invoked when a pick is completed to leave the client_channel combiner -// and continue processing in the call combiner. -// If needed, removes the call's polling entity from chand->interested_parties. -static void pick_done_locked(grpc_call_element* elem, grpc_error* error) { - call_data* calld = static_cast(elem->call_data); - maybe_del_call_from_channel_interested_parties_locked(elem); - GRPC_CLOSURE_INIT(&calld->pick_closure, pick_done, elem, - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_SCHED(&calld->pick_closure, error); -} - -namespace grpc_core { - -// Performs subchannel pick via LB policy. -class LbPicker { - public: - // Starts a pick on chand->lb_policy. - static void StartLocked(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()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: starting pick on lb_policy=%p", - chand, calld, chand->lb_policy.get()); - } - // 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 - // list, as set by get_batch_index() above. - calld->pick.initial_metadata = - calld->seen_send_initial_metadata - ? &calld->send_initial_metadata - : calld->pending_batches[0] - .batch->payload->send_initial_metadata.send_initial_metadata; - calld->pick.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; - GRPC_CLOSURE_INIT(&calld->pick_closure, &LbPicker::DoneLocked, elem, - grpc_combiner_scheduler(chand->combiner)); - calld->pick.on_complete = &calld->pick_closure; - GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback"); - grpc_error* error = GRPC_ERROR_NONE; - const bool pick_done = chand->lb_policy->PickLocked(&calld->pick, &error); - if (GPR_LIKELY(pick_done)) { - // Pick completed synchronously. - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: pick completed synchronously", - chand, calld); - } - pick_done_locked(elem, error); - GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback"); - } else { - // Pick will be returned asynchronously. - // Add the polling entity from call_data to the channel_data's - // interested_parties, so that the I/O of the LB policy can be done - // under it. It will be removed in pick_done_locked(). - maybe_add_call_to_channel_interested_parties_locked(elem); - // Request notification on call cancellation. - GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback_cancel"); - grpc_call_combiner_set_notify_on_cancel( - calld->call_combiner, - GRPC_CLOSURE_INIT(&calld->pick_cancel_closure, - &LbPicker::CancelLocked, elem, - grpc_combiner_scheduler(chand->combiner))); - } - } - - private: - // Callback invoked by LoadBalancingPolicy::PickLocked() for async picks. - // Unrefs the LB policy and invokes pick_done_locked(). - static void DoneLocked(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 (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: pick completed asynchronously", - chand, calld); - } - pick_done_locked(elem, GRPC_ERROR_REF(error)); - GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback"); - } - - // Note: This runs under the client_channel combiner, but will NOT be - // holding the call combiner. - static void CancelLocked(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); - // Note: chand->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 (GPR_UNLIKELY(error != GRPC_ERROR_NONE && chand->lb_policy != nullptr)) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: cancelling pick from LB policy %p", chand, - calld, chand->lb_policy.get()); - } - chand->lb_policy->CancelPickLocked(&calld->pick, GRPC_ERROR_REF(error)); - } - GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback_cancel"); - } -}; - -} // namespace grpc_core - // Applies service config to the call. Must be invoked once we know // that the resolver has returned results to the channel. static void apply_service_config_to_call_locked(grpc_call_element* elem) { @@ -2892,224 +2349,66 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) { } } -// 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 (grpc_connectivity_state_check(&chand->state_tracker) == - 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; - } - return false; -} - // Invoked once resolver results are available. -static void process_service_config_and_start_lb_pick_locked( - grpc_call_element* elem) { +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); // 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; + if (fail_call_if_in_transient_failure(elem)) return false; } - // Start LB pick. - grpc_core::LbPicker::StartLocked(elem); + return true; } -namespace grpc_core { - -// Handles waiting for a resolver result. -// Used only for the first call on an idle channel. -class ResolverResultWaiter { - public: - explicit ResolverResultWaiter(grpc_call_element* elem) : elem_(elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: deferring pick pending resolver result", - chand, calld); - } - // Add closure to be run when a resolver result is available. - GRPC_CLOSURE_INIT(&done_closure_, &ResolverResultWaiter::DoneLocked, this, - grpc_combiner_scheduler(chand->combiner)); - AddToWaitingList(); - // Set cancellation closure, so that we abort if the call is cancelled. - GRPC_CLOSURE_INIT(&cancel_closure_, &ResolverResultWaiter::CancelLocked, - this, grpc_combiner_scheduler(chand->combiner)); - grpc_call_combiner_set_notify_on_cancel(calld->call_combiner, - &cancel_closure_); - } - - private: - // Adds closure_ to chand->waiting_for_resolver_result_closures. - void AddToWaitingList() { - channel_data* chand = static_cast(elem_->channel_data); - grpc_closure_list_append(&chand->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); - // 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 elem_. - if (GPR_UNLIKELY(self->finished_)) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "call cancelled before resolver result"); - } - Delete(self); - return; - } - // Otherwise, process the resolver result. - grpc_call_element* elem = self->elem_; - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: resolver failed to return data", - chand, calld); - } - pick_done_locked(elem, GRPC_ERROR_REF(error)); - } else if (GPR_UNLIKELY(chand->resolver == nullptr)) { - // Shutting down. - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: resolver disconnected", chand, - calld); - } - pick_done_locked(elem, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); - } else if (GPR_UNLIKELY(chand->lb_policy == nullptr)) { - // Transient resolver failure. - // If call has wait_for_ready=true, try again; otherwise, fail. - 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; - if (send_initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: resolver returned but no LB policy; " - "wait_for_ready=true; trying again", - chand, calld); - } - // Re-add ourselves to the waiting list. - self->AddToWaitingList(); - // Return early so that we don't set finished_ to true below. - return; - } else { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: resolver returned but no LB policy; " - "wait_for_ready=false; failing", - chand, calld); - } - pick_done_locked( - elem, - grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Name resolution failure"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); - } - } else { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: resolver returned, doing LB pick", - chand, calld); - } - process_service_config_and_start_lb_pick_locked(elem); - } - 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); - // If DoneLocked() has already run, delete ourselves without doing anything. - if (GPR_LIKELY(self->finished_)) { - Delete(self); - return; - } - // If we are being cancelled, immediately invoke pick_done_locked() - // to propagate the error back to the caller. - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - grpc_call_element* elem = self->elem_; - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: cancelling call waiting for name " - "resolution", - chand, calld); - } - // 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 call pick_done_locked() here -- we are essentially - // calling it here instead of calling it in DoneLocked(). - pick_done_locked(elem, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick cancelled", &error, 1)); - } - self->finished_ = true; - } - - grpc_call_element* elem_; - grpc_closure done_closure_; - grpc_closure cancel_closure_; - bool finished_ = false; -}; - -} // namespace grpc_core - 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.connected_subchannel == nullptr); + GPR_ASSERT(!calld->have_request); GPR_ASSERT(calld->subchannel_call == nullptr); - if (GPR_LIKELY(chand->lb_policy != nullptr)) { - // We already have resolver results, so process the service config - // and start an LB pick. - process_service_config_and_start_lb_pick_locked(elem); - } else if (GPR_UNLIKELY(chand->resolver == nullptr)) { - pick_done_locked(elem, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); - } else { - // We do not yet have an LB policy, so wait for a resolver result. - if (GPR_UNLIKELY(!chand->started_resolving)) { - start_resolving_locked(chand); - } else { - // Normally, we want to do this check in - // process_service_config_and_start_lb_pick_locked(), so that we - // can honor the wait_for_ready setting in the service config. - // However, if the channel is in TRANSIENT_FAILURE 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 (fail_call_if_in_transient_failure(elem)) return; - } - // Create a new waiter, which will delete itself when done. - grpc_core::New(elem); - // Add the polling entity from call_data to the channel_data's - // interested_parties, so that the I/O of the resolver can be done - // under it. It will be removed in pick_done_locked(). - maybe_add_call_to_channel_interested_parties_locked(elem); + // 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 + // list, as set by get_batch_index() above. + // TODO(roth): What if the LB policy needs to add something to the + // call's initial metadata, and then there's a retry? We don't want + // the new metadata to be added twice. We might need to somehow + // 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->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 = + calld->seen_send_initial_metadata + ? &calld->send_initial_metadata_flags + : &calld->pending_batches[0] + .batch->payload->send_initial_metadata + .send_initial_metadata_flags; + 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()); } // @@ -3249,23 +2548,10 @@ const grpc_channel_filter grpc_client_channel_filter = { "client-channel", }; -static void try_to_connect_locked(void* arg, grpc_error* error_ignored) { - channel_data* chand = static_cast(arg); - if (chand->lb_policy != nullptr) { - chand->lb_policy->ExitIdleLocked(); - } else { - chand->exit_idle_when_lb_policy_arrives = true; - if (!chand->started_resolving && chand->resolver != nullptr) { - start_resolving_locked(chand); - } - } - GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "try_to_connect"); -} - 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_channel = node; + chand->request_router->set_channelz_node(node); } void grpc_client_channel_populate_child_refs( @@ -3273,17 +2559,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->lb_policy != nullptr) { - chand->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->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( @@ -3328,19 +2619,19 @@ static void external_connectivity_watcher_list_append( } static void external_connectivity_watcher_list_remove( - channel_data* chand, external_connectivity_watcher* too_remove) { + channel_data* chand, external_connectivity_watcher* to_remove) { GPR_ASSERT( - lookup_external_connectivity_watcher(chand, too_remove->on_complete)); + lookup_external_connectivity_watcher(chand, to_remove->on_complete)); gpr_mu_lock(&chand->external_connectivity_watcher_list_mu); - if (too_remove == chand->external_connectivity_watcher_list_head) { - chand->external_connectivity_watcher_list_head = too_remove->next; + if (to_remove == chand->external_connectivity_watcher_list_head) { + chand->external_connectivity_watcher_list_head = to_remove->next; gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); return; } external_connectivity_watcher* w = chand->external_connectivity_watcher_list_head; while (w != nullptr) { - if (w->next == too_remove) { + if (w->next == to_remove) { w->next = w->next->next; gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); return; @@ -3392,15 +2683,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.h b/src/core/ext/filters/client_channel/lb_policy.h index 29b8c28be6a..293d8e960cf 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -65,10 +65,10 @@ class LoadBalancingPolicy : public InternallyRefCounted { struct PickState { /// Initial metadata associated with the picking call. grpc_metadata_batch* initial_metadata = nullptr; - /// Bitmask used for selective cancelling. See + /// Pointer to bitmask used for selective cancelling. See /// \a CancelMatchingPicksLocked() and \a GRPC_INITIAL_METADATA_* in /// grpc_types.h. - uint32_t initial_metadata_flags = 0; + 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. @@ -88,6 +88,9 @@ class LoadBalancingPolicy : public InternallyRefCounted { LoadBalancingPolicy(const LoadBalancingPolicy&) = delete; LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete; + /// 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. Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. 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 3c4f0d6552f..ba40febd534 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 @@ -122,10 +122,14 @@ TraceFlag grpc_lb_glb_trace(false, "glb"); namespace { +constexpr char kGrpclb[] = "grpclb"; + class GrpcLb : public LoadBalancingPolicy { public: explicit GrpcLb(const Args& args); + const char* name() const override { return kGrpclb; } + void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; bool PickLocked(PickState* pick, grpc_error** error) override; @@ -1136,7 +1140,7 @@ void GrpcLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, pending_picks_ = nullptr; while (pp != nullptr) { PendingPick* next = pp->next; - if ((pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == + 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, @@ -1819,7 +1823,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { return OrphanablePtr(New(args)); } - const char* name() const override { return "grpclb"; } + const char* name() const override { return kGrpclb; } }; } // namespace 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 74c17612a28..d6ff74ec7f7 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 @@ -43,10 +43,14 @@ namespace { // pick_first LB policy // +constexpr char kPickFirst[] = "pick_first"; + class PickFirst : public LoadBalancingPolicy { public: explicit PickFirst(const Args& args); + const char* name() const override { return kPickFirst; } + void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; bool PickLocked(PickState* pick, grpc_error** error) override; @@ -234,7 +238,7 @@ void PickFirst::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, pending_picks_ = nullptr; while (pick != nullptr) { PickState* next = pick->next; - if ((pick->initial_metadata_flags & initial_metadata_flags_mask) == + 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( @@ -622,7 +626,7 @@ class PickFirstFactory : public LoadBalancingPolicyFactory { return OrphanablePtr(New(args)); } - const char* name() const override { return "pick_first"; } + const char* name() const override { return kPickFirst; } }; } // namespace 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 63089afbd78..3bcb33ef11c 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 @@ -53,10 +53,14 @@ namespace { // round_robin LB policy // +constexpr char kRoundRobin[] = "round_robin"; + class RoundRobin : public LoadBalancingPolicy { public: explicit RoundRobin(const Args& args); + const char* name() const override { return kRoundRobin; } + void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; bool PickLocked(PickState* pick, grpc_error** error) override; @@ -291,7 +295,7 @@ void RoundRobin::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, pending_picks_ = nullptr; while (pick != nullptr) { PickState* next = pick->next; - if ((pick->initial_metadata_flags & initial_metadata_flags_mask) == + if ((*pick->initial_metadata_flags & initial_metadata_flags_mask) == initial_metadata_flags_eq) { pick->connected_subchannel.reset(); GRPC_CLOSURE_SCHED(pick->on_complete, @@ -700,7 +704,7 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory { return OrphanablePtr(New(args)); } - const char* name() const override { return "round_robin"; } + const char* name() const override { return kRoundRobin; } }; } // namespace 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 3c25de2386c..8787f5bcc24 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 @@ -115,10 +115,14 @@ TraceFlag grpc_lb_xds_trace(false, "xds"); namespace { +constexpr char kXds[] = "xds_experimental"; + class XdsLb : public LoadBalancingPolicy { public: explicit XdsLb(const Args& args); + const char* name() const override { return kXds; } + void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; bool PickLocked(PickState* pick, grpc_error** error) override; @@ -1053,7 +1057,7 @@ void XdsLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, pending_picks_ = nullptr; while (pp != nullptr) { PendingPick* next = pp->next; - if ((pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == + 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, @@ -1651,7 +1655,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { return OrphanablePtr(New(args)); } - const char* name() const override { return "xds_experimental"; } + const char* name() const override { return kXds; } }; } // namespace 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..f9a7e164e75 --- /dev/null +++ b/src/core/ext/filters/client_channel/request_routing.cc @@ -0,0 +1,936 @@ +/* + * + * 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/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 { + +// +// 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) { + 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.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( + grpc_core::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..0c671229c8e --- /dev/null +++ b/src/core/ext/filters/client_channel/request_routing.h @@ -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. + * + */ + +#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/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 = grpc_core::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; + + 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/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 22b06db45c4..9a0122e8ece 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -43,16 +43,16 @@ namespace grpc_core { namespace internal { ProcessedResolverResult::ProcessedResolverResult( - const grpc_channel_args* resolver_result, bool parse_retry) { + const grpc_channel_args& resolver_result, bool parse_retry) { 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); } void ProcessedResolverResult::ProcessServiceConfig( - const grpc_channel_args* resolver_result, bool parse_retry) { + const grpc_channel_args& resolver_result, bool parse_retry) { const grpc_arg* channel_arg = - grpc_channel_args_find(resolver_result, GRPC_ARG_SERVICE_CONFIG); + 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)); @@ -60,7 +60,7 @@ void ProcessedResolverResult::ProcessServiceConfig( if (service_config_ != nullptr) { if (parse_retry) { channel_arg = - grpc_channel_args_find(resolver_result, GRPC_ARG_SERVER_URI); + 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); @@ -78,7 +78,7 @@ void ProcessedResolverResult::ProcessServiceConfig( } void ProcessedResolverResult::ProcessLbPolicyName( - const grpc_channel_args* resolver_result) { + const grpc_channel_args& 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,13 +96,13 @@ 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, 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); + FindServerAddressListChannelArg(&resolver_result); if (addresses != nullptr) { bool found_balancer_address = false; for (size_t i = 0; i < addresses->size(); ++i) { 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 f1fb7406bcb..98a9d26c467 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -36,8 +36,7 @@ namespace internal { class ClientChannelMethodParams; // A table mapping from a method name to its method parameters. -typedef grpc_core::SliceHashTable< - grpc_core::RefCountedPtr> +typedef SliceHashTable> ClientChannelMethodParamsTable; // A container of processed fields from the resolver result. Simplifies the @@ -47,33 +46,30 @@ 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, + ProcessedResolverResult(const grpc_channel_args& resolver_result, bool parse_retry); // Getters. Any managed object's ownership is transferred. - grpc_core::UniquePtr service_config_json() { + UniquePtr service_config_json() { return std::move(service_config_json_); } - grpc_core::RefCountedPtr retry_throttle_data() { + RefCountedPtr retry_throttle_data() { return std::move(retry_throttle_data_); } - grpc_core::RefCountedPtr - method_params_table() { + RefCountedPtr method_params_table() { return std::move(method_params_table_); } - grpc_core::UniquePtr lb_policy_name() { - return std::move(lb_policy_name_); - } + UniquePtr lb_policy_name() { return std::move(lb_policy_name_); } grpc_json* lb_policy_config() { return lb_policy_config_; } 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 grpc_channel_args& 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 grpc_channel_args& resolver_result); // Parses the service config. Intended to be used by // ServiceConfig::ParseGlobalParams. @@ -85,16 +81,16 @@ class ProcessedResolverResult { void ParseRetryThrottleParamsFromServiceConfig(const grpc_json* field); // Service config. - grpc_core::UniquePtr service_config_json_; - grpc_core::UniquePtr service_config_; + UniquePtr service_config_json_; + UniquePtr service_config_; // LB policy. grpc_json* lb_policy_config_ = nullptr; - grpc_core::UniquePtr lb_policy_name_; + UniquePtr lb_policy_name_; // Retry throttle data. char* server_name_ = nullptr; - grpc_core::RefCountedPtr retry_throttle_data_; + RefCountedPtr retry_throttle_data_; // Method params table. - grpc_core::RefCountedPtr method_params_table_; + RefCountedPtr method_params_table_; }; // The parameters of a method. diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index c6ca970beee..6a1fd676ca6 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -326,6 +326,7 @@ 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', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 5011e19b03a..ba2eaecafda 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -932,6 +932,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 \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 46e5d54c851..336d499be9d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9840,6 +9840,7 @@ "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", @@ -9882,6 +9883,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", From 05b61a5199dd69e33011ed0e677d9d43a77c01a4 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 20 Dec 2018 12:10:53 -0800 Subject: [PATCH 0635/2143] 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 1ac4a01a0edd9c1c790157d436b9c76e49b2c539 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 20 Dec 2018 12:13:08 -0800 Subject: [PATCH 0636/2143] Fix Complain of Higher Version Pylint --- src/python/grpcio_status/grpc_status/rpc_status.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio_status/grpc_status/rpc_status.py b/src/python/grpcio_status/grpc_status/rpc_status.py index e23a20968ec..87618fa5412 100644 --- a/src/python/grpcio_status/grpc_status/rpc_status.py +++ b/src/python/grpcio_status/grpc_status/rpc_status.py @@ -24,7 +24,7 @@ import grpc import google.protobuf # pylint: disable=unused-import from google.rpc import status_pb2 -_CODE_TO_GRPC_CODE_MAPPING = dict([(x.value[0], x) for x in grpc.StatusCode]) +_CODE_TO_GRPC_CODE_MAPPING = {x.value[0]: x for x in grpc.StatusCode} _GRPC_DETAILS_METADATA_KEY = 'grpc-status-details-bin' From 30e1991bf93e010964ccaf326081398ed3cd4e4e Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 20 Dec 2018 13:22:48 -0800 Subject: [PATCH 0637/2143] Update context list test --- test/core/transport/chttp2/context_list_test.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/core/transport/chttp2/context_list_test.cc b/test/core/transport/chttp2/context_list_test.cc index edbe658a89f..0379eaaee4c 100644 --- a/test/core/transport/chttp2/context_list_test.cc +++ b/test/core/transport/chttp2/context_list_test.cc @@ -36,8 +36,12 @@ namespace { const uint32_t kByteOffset = 123; -void TestExecuteFlushesListVerifier(void* arg, grpc_core::Timestamps* ts) { +void* DummyArgsCopier(void* arg) { return arg; } + +void TestExecuteFlushesListVerifier(void* arg, grpc_core::Timestamps* ts, + grpc_error* error) { ASSERT_NE(arg, nullptr); + EXPECT_EQ(error, GRPC_ERROR_NONE); EXPECT_EQ(ts->byte_offset, kByteOffset); gpr_atm* done = reinterpret_cast(arg); gpr_atm_rel_store(done, static_cast(1)); @@ -52,6 +56,7 @@ void discard_write(grpc_slice slice) {} TEST(ContextList, ExecuteFlushesList) { grpc_core::ContextList* list = nullptr; grpc_http2_set_write_timestamps_callback(TestExecuteFlushesListVerifier); + grpc_http2_set_fn_get_copied_context(DummyArgsCopier); const int kNumElems = 5; grpc_core::ExecCtx exec_ctx; grpc_stream_refcount ref; From d6dd6f25f4e900d6099098d5d1f0bd52f0581750 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 20 Dec 2018 15:37:30 -0800 Subject: [PATCH 0638/2143] Correctly reference the internal string for socket mutator arg --- src/cpp/common/channel_arguments.cc | 2 ++ test/cpp/common/channel_arguments_test.cc | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index 50ee9d871f0..214d72f853f 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -106,7 +106,9 @@ void ChannelArguments::SetSocketMutator(grpc_socket_mutator* mutator) { } if (!replaced) { + strings_.push_back(grpc::string(mutator_arg.key)); args_.push_back(mutator_arg); + args_.back().key = const_cast(strings_.back().c_str()); } } diff --git a/test/cpp/common/channel_arguments_test.cc b/test/cpp/common/channel_arguments_test.cc index 183d2afa783..12fd9784f47 100644 --- a/test/cpp/common/channel_arguments_test.cc +++ b/test/cpp/common/channel_arguments_test.cc @@ -209,6 +209,9 @@ TEST_F(ChannelArgumentsTest, SetSocketMutator) { channel_args_.SetSocketMutator(mutator0); EXPECT_TRUE(HasArg(arg0)); + // Exercise the copy constructor because we ran some sanity checks in it. + grpc::ChannelArguments new_args{channel_args_}; + channel_args_.SetSocketMutator(mutator1); EXPECT_TRUE(HasArg(arg1)); // arg0 is replaced by arg1 From b09ed93d02197235471e6e65df2df2cbeb506f50 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 20 Dec 2018 16:16:00 -0800 Subject: [PATCH 0639/2143] Revert changes to Context list cleanup --- .../transport/chttp2/transport/chttp2_transport.cc | 12 ++++++++---- 1 file changed, 8 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 9e03c90ccb9..78833723a2c 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -170,6 +170,14 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { grpc_slice_buffer_destroy_internal(&outbuf); grpc_chttp2_hpack_compressor_destroy(&hpack_compressor); + grpc_error* error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"); + // ContextList::Execute follows semantics of a callback function and does not + // take a ref on error + grpc_core::ContextList::Execute(t->cl, nullptr, error); + GRPC_ERROR_UNREF(error); + t->cl = nullptr; + grpc_slice_buffer_destroy_internal(&read_buffer); grpc_chttp2_hpack_parser_destroy(&hpack_parser); grpc_chttp2_goaway_parser_destroy(&goaway_parser); @@ -566,10 +574,6 @@ static void close_transport_locked(grpc_chttp2_transport* t, grpc_error* error) { end_all_the_calls(t, GRPC_ERROR_REF(error)); cancel_pings(t, GRPC_ERROR_REF(error)); - // ContextList::Execute follows semantics of a callback function and does not - // need a ref on error - grpc_core::ContextList::Execute(t->cl, nullptr, error); - t->cl = nullptr; if (t->closed_with_error == GRPC_ERROR_NONE) { if (!grpc_error_has_clear_grpc_status(error)) { error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, From 810a93e783bb3bb8a3f736fefd46793241100481 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 21 Dec 2018 10:55:20 +0100 Subject: [PATCH 0640/2143] inject extra details to Bazel RBE links --- .../linux/grpc_bazel_on_foundry_base.sh | 1 + tools/remote_build/workspace_status_kokoro.sh | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100755 tools/remote_build/workspace_status_kokoro.sh diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index d35bbbd2756..4d7d4271d61 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -44,6 +44,7 @@ bazel \ --bazelrc=tools/remote_build/kokoro.bazelrc \ test \ --invocation_id="${BAZEL_INVOCATION_ID}" \ + --workspace_status_command=tools/remote_build/workspace_status_kokoro.sh \ $@ \ -- //test/... || FAILED="true" diff --git a/tools/remote_build/workspace_status_kokoro.sh b/tools/remote_build/workspace_status_kokoro.sh new file mode 100755 index 00000000000..8d5db7f8bd5 --- /dev/null +++ b/tools/remote_build/workspace_status_kokoro.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# 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. + +# Adds additional labels to results page for Bazel RBE builds on Kokoro + +# Provide a way to go from Bazel RBE links back to Kokoro job results +# which is important for debugging test infrastructure problems. +# TODO(jtattermusch): replace this workaround by something more user-friendly. +echo "KOKORO_RESULTSTORE_URL https://source.cloud.google.com/results/invocations/${KOKORO_BUILD_ID}" +echo "KOKORO_SPONGE_URL http://sponge.corp.google.com/${KOKORO_BUILD_ID}" + +echo "KOKORO_BUILD_NUMBER ${KOKORO_BUILD_NUMBER}" +echo "KOKORO_JOB_NAME ${KOKORO_JOB_NAME}" +echo "KOKORO_GITHUB_COMMIT ${KOKORO_GITHUB_COMMIT}" From c4c4b9152fb0359f2c1e47191c0c4f7195be859f Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 21 Dec 2018 10:57:54 -0800 Subject: [PATCH 0641/2143] 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 15460eb3c9f58ba7f8a4db9bebff0aaa00b57d27 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 21 Dec 2018 13:36:59 -0800 Subject: [PATCH 0642/2143] Fix error --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 4 ++-- 1 file changed, 2 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 78833723a2c..7f4627fa773 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -174,9 +174,9 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"); // ContextList::Execute follows semantics of a callback function and does not // take a ref on error - grpc_core::ContextList::Execute(t->cl, nullptr, error); + grpc_core::ContextList::Execute(cl, nullptr, error); GRPC_ERROR_UNREF(error); - t->cl = nullptr; + cl = nullptr; grpc_slice_buffer_destroy_internal(&read_buffer); grpc_chttp2_hpack_parser_destroy(&hpack_parser); From 49beab68be9a90de48832404519af9da34e83910 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 21 Dec 2018 14:03:18 -0800 Subject: [PATCH 0643/2143] 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 50eaf4671814f017ed44ce9a220025c87e1a1cc2 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 20 Dec 2018 17:35:12 -0800 Subject: [PATCH 0644/2143] Refactor benchmark initial channel wait for ready to be single threaded --- test/cpp/qps/client.h | 89 +++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 668d9419169..73f91eed2d8 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -429,13 +429,7 @@ class ClientImpl : public Client { config.server_targets(i % config.server_targets_size()), config, create_stub_, i); } - std::vector> connecting_threads; - for (auto& c : channels_) { - connecting_threads.emplace_back(c.WaitForReady()); - } - for (auto& t : connecting_threads) { - t->join(); - } + WaitForChannelsToConnect(); median_latency_collection_interval_seconds_ = config.median_latency_collection_interval_millis() / 1e3; ClientRequestCreator create_req(&request_, @@ -443,6 +437,61 @@ class ClientImpl : public Client { } virtual ~ClientImpl() {} + void WaitForChannelsToConnect() { + int connect_deadline_seconds = 10; + /* Allow optionally overriding connect_deadline in order + * to deal with benchmark environments in which the server + * can take a long time to become ready. */ + char* channel_connect_timeout_str = + gpr_getenv("QPS_WORKER_CHANNEL_CONNECT_TIMEOUT"); + if (channel_connect_timeout_str != nullptr && + strcmp(channel_connect_timeout_str, "") != 0) { + connect_deadline_seconds = atoi(channel_connect_timeout_str); + } + gpr_log(GPR_INFO, + "Waiting for up to %d seconds for all channels to connect", + connect_deadline_seconds); + gpr_free(channel_connect_timeout_str); + gpr_timespec connect_deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_seconds(connect_deadline_seconds, GPR_TIMESPAN)); + CompletionQueue cq; + size_t num_remaining = 0; + for (auto& c : channels_) { + if (!c.is_inproc()) { + Channel* channel = c.get_channel(); + grpc_connectivity_state last_observed = channel->GetState(true); + if (last_observed == GRPC_CHANNEL_READY) { + gpr_log(GPR_INFO, "Channel %p connected!", channel); + } else { + num_remaining++; + channel->NotifyOnStateChange(last_observed, connect_deadline, &cq, + channel); + } + } + } + while (num_remaining > 0) { + bool ok = false; + void* tag = nullptr; + cq.Next(&tag, &ok); + Channel* channel = static_cast(tag); + if (!ok) { + gpr_log(GPR_ERROR, "Channel %p failed to connect within the deadline", + channel); + abort(); + } else { + grpc_connectivity_state last_observed = channel->GetState(true); + if (last_observed == GRPC_CHANNEL_READY) { + gpr_log(GPR_INFO, "Channel %p connected!", channel); + num_remaining--; + } else { + channel->NotifyOnStateChange(last_observed, connect_deadline, &cq, + channel); + } + } + } + } + protected: const int cores_; RequestType request_; @@ -485,31 +534,7 @@ class ClientImpl : public Client { } Channel* get_channel() { return channel_.get(); } StubType* get_stub() { return stub_.get(); } - - std::unique_ptr WaitForReady() { - return std::unique_ptr(new std::thread([this]() { - if (!is_inproc_) { - int connect_deadline = 10; - /* Allow optionally overriding connect_deadline in order - * to deal with benchmark environments in which the server - * can take a long time to become ready. */ - char* channel_connect_timeout_str = - gpr_getenv("QPS_WORKER_CHANNEL_CONNECT_TIMEOUT"); - if (channel_connect_timeout_str != nullptr && - strcmp(channel_connect_timeout_str, "") != 0) { - connect_deadline = atoi(channel_connect_timeout_str); - } - gpr_log(GPR_INFO, - "Waiting for up to %d seconds for the channel %p to connect", - connect_deadline, channel_.get()); - gpr_free(channel_connect_timeout_str); - GPR_ASSERT(channel_->WaitForConnected(gpr_time_add( - gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(connect_deadline, GPR_TIMESPAN)))); - gpr_log(GPR_INFO, "Channel %p connected!", channel_.get()); - } - })); - } + bool is_inproc() { return is_inproc_; } private: void set_channel_args(const ClientConfig& config, ChannelArguments* args) { From 2f029bade0cdadcfdd955773bd43cc2f061cd3f7 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 19 Dec 2018 09:44:38 -0800 Subject: [PATCH 0645/2143] Clean up server and channel objects in tests --- .../health_check/_health_servicer_test.py | 8 +++-- .../reflection/_reflection_servicer_test.py | 8 +++-- .../grpcio_tests/tests/unit/_api_test.py | 1 + .../tests/unit/_auth_context_test.py | 6 ++-- .../tests/unit/_channel_connectivity_test.py | 6 +++- .../tests/unit/_channel_ready_future_test.py | 5 ++++ .../tests/unit/_compression_test.py | 5 ++++ .../tests/unit/_empty_message_test.py | 1 + .../unit/_error_message_encoding_test.py | 1 + .../tests/unit/_interceptor_test.py | 1 + .../tests/unit/_invalid_metadata_test.py | 3 ++ .../tests/unit/_invocation_defects_test.py | 1 + .../tests/unit/_metadata_code_details_test.py | 14 +++++---- .../tests/unit/_metadata_flags_test.py | 29 ++++++++++--------- .../grpcio_tests/tests/unit/_metadata_test.py | 1 + .../tests/unit/_reconnect_test.py | 2 ++ .../tests/unit/_resource_exhausted_test.py | 1 + .../grpcio_tests/tests/unit/_rpc_test.py | 1 + 18 files changed, 68 insertions(+), 26 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 350b5eebe5b..c1d9436c2fa 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 @@ -39,8 +39,12 @@ class HealthServicerTest(unittest.TestCase): health_pb2_grpc.add_HealthServicer_to_server(servicer, self._server) self._server.start() - channel = grpc.insecure_channel('localhost:%d' % port) - self._stub = health_pb2_grpc.HealthStub(channel) + 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_empty_service(self): request = health_pb2.HealthCheckRequest() 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 bcd9e14a386..560f6d3ddb3 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,12 @@ class ReflectionServicerTest(unittest.TestCase): port = self._server.add_insecure_port('[::]:0') self._server.start() - channel = grpc.insecure_channel('localhost:%d' % port) - self._stub = reflection_pb2_grpc.ServerReflectionStub(channel) + self._channel = grpc.insecure_channel('localhost:%d' % port) + self._stub = reflection_pb2_grpc.ServerReflectionStub(self._channel) + + def tearDown(self): + self._server.stop(None) + self._channel.close() def testFileByName(self): requests = ( diff --git a/src/python/grpcio_tests/tests/unit/_api_test.py b/src/python/grpcio_tests/tests/unit/_api_test.py index 427894bfe9f..0dc6a8718c3 100644 --- a/src/python/grpcio_tests/tests/unit/_api_test.py +++ b/src/python/grpcio_tests/tests/unit/_api_test.py @@ -101,6 +101,7 @@ class ChannelTest(unittest.TestCase): def test_secure_channel(self): channel_credentials = grpc.ssl_channel_credentials() channel = grpc.secure_channel('google.com:443', channel_credentials) + channel.close() if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_auth_context_test.py b/src/python/grpcio_tests/tests/unit/_auth_context_test.py index b1b5bbdcab3..96c4e9ec76a 100644 --- a/src/python/grpcio_tests/tests/unit/_auth_context_test.py +++ b/src/python/grpcio_tests/tests/unit/_auth_context_test.py @@ -71,8 +71,8 @@ class AuthContextTest(unittest.TestCase): port = server.add_insecure_port('[::]:0') server.start() - channel = grpc.insecure_channel('localhost:%d' % port) - response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + with grpc.insecure_channel('localhost:%d' % port) as channel: + response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) server.stop(None) auth_data = pickle.loads(response) @@ -98,6 +98,7 @@ class AuthContextTest(unittest.TestCase): channel_creds, options=_PROPERTY_OPTIONS) response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + channel.close() server.stop(None) auth_data = pickle.loads(response) @@ -132,6 +133,7 @@ class AuthContextTest(unittest.TestCase): options=_PROPERTY_OPTIONS) response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + channel.close() server.stop(None) auth_data = pickle.loads(response) 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 727fb7d65fe..565bd39b3aa 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py @@ -75,6 +75,8 @@ class ChannelConnectivityTest(unittest.TestCase): channel.unsubscribe(callback.update) fifth_connectivities = callback.connectivities() + channel.close() + self.assertSequenceEqual((grpc.ChannelConnectivity.IDLE,), first_connectivities) self.assertNotIn(grpc.ChannelConnectivity.READY, second_connectivities) @@ -108,7 +110,8 @@ class ChannelConnectivityTest(unittest.TestCase): _ready_in_connectivities) second_callback.block_until_connectivities_satisfy( _ready_in_connectivities) - del channel + channel.close() + server.stop(None) self.assertSequenceEqual((grpc.ChannelConnectivity.IDLE,), first_connectivities) @@ -139,6 +142,7 @@ class ChannelConnectivityTest(unittest.TestCase): callback.block_until_connectivities_satisfy( _last_connectivity_is_not_ready) channel.unsubscribe(callback.update) + channel.close() self.assertFalse(thread_pool.was_used()) 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 345460ef40d..46a4eb9bb60 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 @@ -60,6 +60,8 @@ class ChannelReadyFutureTest(unittest.TestCase): self.assertTrue(ready_future.done()) self.assertFalse(ready_future.running()) + 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),)) @@ -84,6 +86,9 @@ class ChannelReadyFutureTest(unittest.TestCase): self.assertFalse(ready_future.running()) self.assertFalse(thread_pool.was_used()) + channel.close() + server.stop(None) + if __name__ == '__main__': logging.basicConfig() diff --git a/src/python/grpcio_tests/tests/unit/_compression_test.py b/src/python/grpcio_tests/tests/unit/_compression_test.py index 876d8e827ea..87884a19dc0 100644 --- a/src/python/grpcio_tests/tests/unit/_compression_test.py +++ b/src/python/grpcio_tests/tests/unit/_compression_test.py @@ -77,6 +77,9 @@ class CompressionTest(unittest.TestCase): self._port = self._server.add_insecure_port('[::]:0') self._server.start() + def tearDown(self): + self._server.stop(None) + def testUnary(self): request = b'\x00' * 100 @@ -102,6 +105,7 @@ class CompressionTest(unittest.TestCase): response = multi_callable( request, metadata=[('grpc-internal-encoding-request', 'gzip')]) self.assertEqual(request, response) + compressed_channel.close() def testStreaming(self): request = b'\x00' * 100 @@ -115,6 +119,7 @@ class CompressionTest(unittest.TestCase): call = multi_callable(iter([request] * test_constants.STREAM_LENGTH)) for response in call: self.assertEqual(request, response) + compressed_channel.close() if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_empty_message_test.py b/src/python/grpcio_tests/tests/unit/_empty_message_test.py index 3e8393b53c3..f27ea422d0c 100644 --- a/src/python/grpcio_tests/tests/unit/_empty_message_test.py +++ b/src/python/grpcio_tests/tests/unit/_empty_message_test.py @@ -96,6 +96,7 @@ class EmptyMessageTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testUnaryUnary(self): response = self._channel.unary_unary(_UNARY_UNARY)(_REQUEST) diff --git a/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py b/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py index 6c551df3ec4..81de1dae1d1 100644 --- a/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py +++ b/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py @@ -71,6 +71,7 @@ class ErrorMessageEncodingTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testMessageEncoding(self): for message in _UNICODE_ERROR_MESSAGES: diff --git a/src/python/grpcio_tests/tests/unit/_interceptor_test.py b/src/python/grpcio_tests/tests/unit/_interceptor_test.py index 99db0ac58b1..a647e5e720c 100644 --- a/src/python/grpcio_tests/tests/unit/_interceptor_test.py +++ b/src/python/grpcio_tests/tests/unit/_interceptor_test.py @@ -337,6 +337,7 @@ class InterceptorTest(unittest.TestCase): def tearDown(self): self._server.stop(None) self._server_pool.shutdown(wait=True) + self._channel.close() def testTripleRequestMessagesClientInterceptor(self): diff --git a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py index 0ff49490d5f..7ed7c838936 100644 --- a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py +++ b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py @@ -62,6 +62,9 @@ class InvalidMetadataTest(unittest.TestCase): self._stream_unary = _stream_unary_multi_callable(self._channel) self._stream_stream = _stream_stream_multi_callable(self._channel) + def tearDown(self): + self._channel.close() + def testUnaryRequestBlockingUnaryResponse(self): request = b'\x07\x08' metadata = (('InVaLiD', 'UnaryRequestBlockingUnaryResponse'),) diff --git a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py index 00949e22366..e89b521cc5c 100644 --- a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py +++ b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py @@ -215,6 +215,7 @@ class InvocationDefectsTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testIterableStreamRequestBlockingUnaryResponse(self): requests = [b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)] diff --git a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py index 0dafab827a8..a63664ac5d0 100644 --- a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py +++ b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py @@ -198,8 +198,8 @@ class MetadataCodeDetailsTest(unittest.TestCase): port = self._server.add_insecure_port('[::]:0') self._server.start() - channel = grpc.insecure_channel('localhost:{}'.format(port)) - self._unary_unary = channel.unary_unary( + self._channel = grpc.insecure_channel('localhost:{}'.format(port)) + self._unary_unary = self._channel.unary_unary( '/'.join(( '', _SERVICE, @@ -208,17 +208,17 @@ class MetadataCodeDetailsTest(unittest.TestCase): request_serializer=_REQUEST_SERIALIZER, response_deserializer=_RESPONSE_DESERIALIZER, ) - self._unary_stream = channel.unary_stream('/'.join(( + self._unary_stream = self._channel.unary_stream('/'.join(( '', _SERVICE, _UNARY_STREAM, )),) - self._stream_unary = channel.stream_unary('/'.join(( + self._stream_unary = self._channel.stream_unary('/'.join(( '', _SERVICE, _STREAM_UNARY, )),) - self._stream_stream = channel.stream_stream( + self._stream_stream = self._channel.stream_stream( '/'.join(( '', _SERVICE, @@ -228,6 +228,10 @@ class MetadataCodeDetailsTest(unittest.TestCase): response_deserializer=_RESPONSE_DESERIALIZER, ) + def tearDown(self): + self._server.stop(None) + self._channel.close() + def testSuccessfulUnaryUnary(self): self._servicer.set_details(_DETAILS) diff --git a/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py b/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py index 2d352e99d4a..7b32b5b5f3e 100644 --- a/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py +++ b/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py @@ -187,13 +187,14 @@ class MetadataFlagsTest(unittest.TestCase): def test_call_wait_for_ready_default(self): for perform_call in _ALL_CALL_CASES: - self.check_connection_does_failfast(perform_call, - create_dummy_channel()) + with create_dummy_channel() as channel: + self.check_connection_does_failfast(perform_call, channel) def test_call_wait_for_ready_disabled(self): for perform_call in _ALL_CALL_CASES: - self.check_connection_does_failfast( - perform_call, create_dummy_channel(), wait_for_ready=False) + with create_dummy_channel() as channel: + self.check_connection_does_failfast( + perform_call, channel, wait_for_ready=False) def test_call_wait_for_ready_enabled(self): # To test the wait mechanism, Python thread is required to make @@ -210,16 +211,16 @@ class MetadataFlagsTest(unittest.TestCase): wg.done() def test_call(perform_call): - try: - channel = grpc.insecure_channel(addr) - channel.subscribe(wait_for_transient_failure) - perform_call(channel, wait_for_ready=True) - except BaseException as e: # pylint: disable=broad-except - # If the call failed, the thread would be destroyed. The channel - # object can be collected before calling the callback, which - # will result in a deadlock. - wg.done() - unhandled_exceptions.put(e, True) + with grpc.insecure_channel(addr) as channel: + try: + channel.subscribe(wait_for_transient_failure) + perform_call(channel, wait_for_ready=True) + except BaseException as e: # pylint: disable=broad-except + # If the call failed, the thread would be destroyed. The + # channel object can be collected before calling the + # callback, which will result in a deadlock. + wg.done() + unhandled_exceptions.put(e, True) test_threads = [] for perform_call in _ALL_CALL_CASES: diff --git a/src/python/grpcio_tests/tests/unit/_metadata_test.py b/src/python/grpcio_tests/tests/unit/_metadata_test.py index 777ab683e36..892df3df08f 100644 --- a/src/python/grpcio_tests/tests/unit/_metadata_test.py +++ b/src/python/grpcio_tests/tests/unit/_metadata_test.py @@ -186,6 +186,7 @@ class MetadataTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testUnaryUnary(self): multi_callable = self._channel.unary_unary(_UNARY_UNARY) diff --git a/src/python/grpcio_tests/tests/unit/_reconnect_test.py b/src/python/grpcio_tests/tests/unit/_reconnect_test.py index f6d4fcbd0a5..d4ea126e2b5 100644 --- a/src/python/grpcio_tests/tests/unit/_reconnect_test.py +++ b/src/python/grpcio_tests/tests/unit/_reconnect_test.py @@ -98,6 +98,8 @@ class ReconnectTest(unittest.TestCase): server.add_insecure_port('[::]:{}'.format(port)) server.start() self.assertEqual(_RESPONSE, multi_callable(_REQUEST)) + server.stop(None) + channel.close() if __name__ == '__main__': 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 4fead8fcd54..517c2d2f97b 100644 --- a/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py +++ b/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py @@ -148,6 +148,7 @@ class ResourceExhaustedTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testUnaryUnary(self): multi_callable = self._channel.unary_unary(_UNARY_UNARY) diff --git a/src/python/grpcio_tests/tests/unit/_rpc_test.py b/src/python/grpcio_tests/tests/unit/_rpc_test.py index a768d6c7c1c..a99121cee57 100644 --- a/src/python/grpcio_tests/tests/unit/_rpc_test.py +++ b/src/python/grpcio_tests/tests/unit/_rpc_test.py @@ -193,6 +193,7 @@ class RPCTest(unittest.TestCase): def tearDown(self): self._server.stop(None) + self._channel.close() def testUnrecognizedMethod(self): request = b'abc' From b6b745f22dd66748fbcb2e7c0d10dc83be84d63a Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 21 Dec 2018 14:16:59 -0800 Subject: [PATCH 0646/2143] disable broken gevent test --- src/python/grpcio_tests/commands.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 496bcfbcbff..d5327711d33 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -133,6 +133,7 @@ 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._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', From 40f22bfc94304e382be770352ca0e7efd0b1c57d Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 21 Dec 2018 15:09:17 -0800 Subject: [PATCH 0647/2143] 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 08dc0ade6790087702a9b7a01b6565e5d8b03832 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 21 Dec 2018 15:49:15 -0800 Subject: [PATCH 0648/2143] Fix bazel build for fling, memory_usage test --- test/core/fling/BUILD | 12 ++++++------ test/core/memory_usage/BUILD | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/test/core/fling/BUILD b/test/core/fling/BUILD index 5c6930cc85b..0c16b2a8799 100644 --- a/test/core/fling/BUILD +++ b/test/core/fling/BUILD @@ -21,7 +21,7 @@ licenses(["notice"]) # Apache v2 load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_cc_binary( - name = "client", + name = "fling_client", testonly = 1, srcs = ["client.cc"], language = "C++", @@ -34,7 +34,7 @@ grpc_cc_binary( ) grpc_cc_binary( - name = "server", + name = "fling_server", testonly = 1, srcs = ["server.cc"], language = "C++", @@ -50,8 +50,8 @@ grpc_cc_test( name = "fling", srcs = ["fling_test.cc"], data = [ - ":client", - ":server", + ":fling_client", + ":fling_server", ], deps = [ "//:gpr", @@ -65,8 +65,8 @@ grpc_cc_test( name = "fling_stream", srcs = ["fling_stream_test.cc"], data = [ - ":client", - ":server", + ":fling_client", + ":fling_server", ], deps = [ "//:gpr", diff --git a/test/core/memory_usage/BUILD b/test/core/memory_usage/BUILD index 2fe94dfa120..dd185e6577b 100644 --- a/test/core/memory_usage/BUILD +++ b/test/core/memory_usage/BUILD @@ -12,14 +12,14 @@ # 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_package") +load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_test", "grpc_package") grpc_package(name = "test/core/memory_usage") licenses(["notice"]) # Apache v2 -grpc_cc_library( - name = "client", +grpc_cc_binary( + name = "memory_usage_client", testonly = 1, srcs = ["client.cc"], deps = [ @@ -29,8 +29,8 @@ grpc_cc_library( ], ) -grpc_cc_library( - name = "server", +grpc_cc_binary( + name = "memory_usage_server", testonly = 1, srcs = ["server.cc"], deps = [ @@ -45,8 +45,8 @@ grpc_cc_test( name = "memory_usage_test", srcs = ["memory_usage_test.cc"], data = [ - ":client", - ":server", + ":memory_usage_client", + ":memory_usage_server", ], language = "C++", deps = [ From 2e017da58aeb335e79f7bbf0797aad45a59d293b Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 21 Dec 2018 18:14:08 -0500 Subject: [PATCH 0649/2143] Add microbenchmarks for grpc_timer This helps assessing upcoming changes. --- CMakeLists.txt | 48 +++++++ Makefile | 49 ++++++++ build.yaml | 21 ++++ test/cpp/microbenchmarks/BUILD | 7 ++ test/cpp/microbenchmarks/bm_timer.cc | 118 ++++++++++++++++++ .../generated/sources_and_headers.json | 21 ++++ tools/run_tests/generated/tests.json | 22 ++++ 7 files changed, 286 insertions(+) create mode 100644 test/cpp/microbenchmarks/bm_timer.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 76886307813..d3ebb5d1773 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -576,6 +576,9 @@ endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_pollset) endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_timer) +endif() add_dependencies(buildtests_cxx byte_stream_test) add_dependencies(buildtests_cxx channel_arguments_test) add_dependencies(buildtests_cxx channel_filter_test) @@ -11748,6 +11751,51 @@ target_link_libraries(bm_pollset ) +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(bm_timer + test/cpp/microbenchmarks/bm_timer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bm_timer + 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_timer + ${_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) diff --git a/Makefile b/Makefile index 147e9505a33..b8a1c921862 100644 --- a/Makefile +++ b/Makefile @@ -1150,6 +1150,7 @@ bm_fullstack_trickle: $(BINDIR)/$(CONFIG)/bm_fullstack_trickle bm_fullstack_unary_ping_pong: $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong bm_metadata: $(BINDIR)/$(CONFIG)/bm_metadata bm_pollset: $(BINDIR)/$(CONFIG)/bm_pollset +bm_timer: $(BINDIR)/$(CONFIG)/bm_timer byte_stream_test: $(BINDIR)/$(CONFIG)/byte_stream_test channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test channel_filter_test: $(BINDIR)/$(CONFIG)/channel_filter_test @@ -1661,6 +1662,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_metadata \ $(BINDIR)/$(CONFIG)/bm_pollset \ + $(BINDIR)/$(CONFIG)/bm_timer \ $(BINDIR)/$(CONFIG)/byte_stream_test \ $(BINDIR)/$(CONFIG)/channel_arguments_test \ $(BINDIR)/$(CONFIG)/channel_filter_test \ @@ -1846,6 +1848,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_metadata \ $(BINDIR)/$(CONFIG)/bm_pollset \ + $(BINDIR)/$(CONFIG)/bm_timer \ $(BINDIR)/$(CONFIG)/byte_stream_test \ $(BINDIR)/$(CONFIG)/channel_arguments_test \ $(BINDIR)/$(CONFIG)/channel_filter_test \ @@ -2296,6 +2299,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/bm_metadata || ( echo test bm_metadata failed ; exit 1 ) $(E) "[RUN] Testing bm_pollset" $(Q) $(BINDIR)/$(CONFIG)/bm_pollset || ( echo test bm_pollset failed ; exit 1 ) + $(E) "[RUN] Testing bm_timer" + $(Q) $(BINDIR)/$(CONFIG)/bm_timer || ( echo test bm_timer failed ; exit 1 ) $(E) "[RUN] Testing byte_stream_test" $(Q) $(BINDIR)/$(CONFIG)/byte_stream_test || ( echo test byte_stream_test failed ; exit 1 ) $(E) "[RUN] Testing channel_arguments_test" @@ -16747,6 +16752,50 @@ endif endif +BM_TIMER_SRC = \ + test/cpp/microbenchmarks/bm_timer.cc \ + +BM_TIMER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_TIMER_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_timer: 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_timer: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_timer: $(PROTOBUF_DEP) $(BM_TIMER_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_TIMER_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_timer + +endif + +endif + +$(BM_TIMER_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_timer.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_timer: $(BM_TIMER_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_TIMER_OBJS:.o=.dep) +endif +endif + + BYTE_STREAM_TEST_SRC = \ test/core/transport/byte_stream_test.cc \ diff --git a/build.yaml b/build.yaml index 9d73e31b2e5..a41decd84f7 100644 --- a/build.yaml +++ b/build.yaml @@ -4230,6 +4230,27 @@ targets: - mac - linux - posix +- name: bm_timer + build: test + language: c++ + src: + - test/cpp/microbenchmarks/bm_timer.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 + uses_polling: false - name: byte_stream_test gtest: true build: test diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index b5890bece73..a29462f78fc 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -189,3 +189,10 @@ grpc_cc_binary( "//src/proto/grpc/testing:echo_proto", ], ) + +grpc_cc_binary( + name = "bm_timer", + testonly = 1, + srcs = ["bm_timer.cc"], + deps = [":helpers"], +) diff --git a/test/cpp/microbenchmarks/bm_timer.cc b/test/cpp/microbenchmarks/bm_timer.cc new file mode 100644 index 00000000000..f5a411251b5 --- /dev/null +++ b/test/cpp/microbenchmarks/bm_timer.cc @@ -0,0 +1,118 @@ +/* + * + * 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 "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" + +#include "src/core/lib/iomgr/timer.h" + +namespace grpc { +namespace testing { + +auto& force_library_initialization = Library::get(); + +struct TimerClosure { + grpc_timer timer; + grpc_closure closure; +}; + +static void BM_InitCancelTimer(benchmark::State& state) { + constexpr int kTimerCount = 1024; + TrackCounters track_counters; + grpc_core::ExecCtx exec_ctx; + std::vector timer_closures(kTimerCount); + int i = 0; + while (state.KeepRunning()) { + TimerClosure* timer_closure = &timer_closures[i++ % kTimerCount]; + GRPC_CLOSURE_INIT(&timer_closure->closure, + [](void* /*args*/, grpc_error* /*err*/) {}, nullptr, + grpc_schedule_on_exec_ctx); + grpc_timer_init(&timer_closure->timer, GRPC_MILLIS_INF_FUTURE, + &timer_closure->closure); + grpc_timer_cancel(&timer_closure->timer); + exec_ctx.Flush(); + } + track_counters.Finish(state); +} +BENCHMARK(BM_InitCancelTimer); + +static void BM_TimerBatch(benchmark::State& state) { + constexpr int kTimerCount = 1024; + const bool check = state.range(0); + const bool reverse = state.range(1); + + const grpc_millis start = + reverse ? GRPC_MILLIS_INF_FUTURE : GRPC_MILLIS_INF_FUTURE - kTimerCount; + const grpc_millis end = + reverse ? GRPC_MILLIS_INF_FUTURE - kTimerCount : GRPC_MILLIS_INF_FUTURE; + const grpc_millis increment = reverse ? -1 : 1; + + TrackCounters track_counters; + grpc_core::ExecCtx exec_ctx; + std::vector timer_closures(kTimerCount); + while (state.KeepRunning()) { + for (grpc_millis deadline = start; deadline != end; deadline += increment) { + TimerClosure* timer_closure = &timer_closures[deadline % kTimerCount]; + GRPC_CLOSURE_INIT(&timer_closure->closure, + [](void* /*args*/, grpc_error* /*err*/) {}, nullptr, + grpc_schedule_on_exec_ctx); + + grpc_timer_init(&timer_closure->timer, deadline, &timer_closure->closure); + } + if (check) { + grpc_millis next; + grpc_timer_check(&next); + } + for (grpc_millis deadline = start; deadline != end; deadline += increment) { + TimerClosure* timer_closure = &timer_closures[deadline % kTimerCount]; + grpc_timer_cancel(&timer_closure->timer); + } + exec_ctx.Flush(); + } + track_counters.Finish(state); +} +BENCHMARK(BM_TimerBatch) + ->Args({/*check=*/false, /*reverse=*/false}) + ->Args({/*check=*/false, /*reverse=*/true}) + ->Args({/*check=*/true, /*reverse=*/false}) + ->Args({/*check=*/true, /*reverse=*/true}) + ->ThreadRange(1, 128); + +} // 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 336d499be9d..8d1bca22be9 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3005,6 +3005,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_timer", + "src": [ + "test/cpp/microbenchmarks/bm_timer.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 3a348e4a92f..e35d4db2767 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3715,6 +3715,28 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": true, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_timer", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, From 5ac6ab67e4278b977dde50891f6aed6cb0e9e078 Mon Sep 17 00:00:00 2001 From: xtao Date: Sat, 22 Dec 2018 09:49:22 +0800 Subject: [PATCH 0650/2143] * Fixed issue(17563) "Freeing heap block containing an active critical section." reported by Application Verifier on Windows. --- src/core/lib/iomgr/resource_quota.cc | 1 + src/core/lib/transport/metadata.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/src/core/lib/iomgr/resource_quota.cc b/src/core/lib/iomgr/resource_quota.cc index 7e4b3c9b2ff..61c366098e1 100644 --- a/src/core/lib/iomgr/resource_quota.cc +++ b/src/core/lib/iomgr/resource_quota.cc @@ -665,6 +665,7 @@ void grpc_resource_quota_unref_internal(grpc_resource_quota* resource_quota) { GPR_ASSERT(resource_quota->num_threads_allocated == 0); GRPC_COMBINER_UNREF(resource_quota->combiner, "resource_quota"); gpr_free(resource_quota->name); + gpr_mu_destroy(&resource_quota->thread_count_mu); gpr_free(resource_quota); } } diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index 60af22393ef..30482a1b3b1 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -187,6 +187,7 @@ static void gc_mdtab(mdtab_shard* shard) { ((destroy_user_data_func)gpr_atm_no_barrier_load( &md->destroy_user_data))(user_data); } + gpr_mu_destroy(&md->mu_user_data); gpr_free(md); *prev_next = next; num_freed++; From 7bb853ebdd0b6e057de447147ad60ebf42e0903d Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Fri, 21 Dec 2018 22:40:38 -0800 Subject: [PATCH 0651/2143] Addressed PR comments. Made Client::Thread public and removed use of void ptr to refer it. Avoided overloading of NextIssue TIme by renaming it NextRPCIssueTime --- test/cpp/qps/client.h | 116 ++++++++++++++++---------------- test/cpp/qps/client_callback.cc | 18 ++--- 2 files changed, 67 insertions(+), 67 deletions(-) diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 0b9837660be..4b8ac9bd94e 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -251,64 +251,6 @@ class Client { return static_cast(gpr_atm_acq_load(&thread_pool_done_)); } - protected: - bool closed_loop_; - gpr_atm thread_pool_done_; - double median_latency_collection_interval_seconds_; // In seconds - - void StartThreads(size_t num_threads) { - gpr_atm_rel_store(&thread_pool_done_, static_cast(false)); - threads_remaining_ = num_threads; - for (size_t i = 0; i < num_threads; i++) { - threads_.emplace_back(new Thread(this, i)); - } - } - - void EndThreads() { - MaybeStartRequests(); - threads_.clear(); - } - - virtual void DestroyMultithreading() = 0; - - void SetupLoadTest(const ClientConfig& config, size_t num_threads) { - // Set up the load distribution based on the number of threads - const auto& load = config.load_params(); - - std::unique_ptr random_dist; - switch (load.load_case()) { - case LoadParams::kClosedLoop: - // Closed-loop doesn't use random dist at all - break; - case LoadParams::kPoisson: - random_dist.reset( - new ExpDist(load.poisson().offered_load() / num_threads)); - break; - default: - GPR_ASSERT(false); - } - - // Set closed_loop_ based on whether or not random_dist is set - if (!random_dist) { - closed_loop_ = true; - } else { - closed_loop_ = false; - // set up interarrival timer according to random dist - interarrival_timer_.init(*random_dist, num_threads); - const auto now = gpr_now(GPR_CLOCK_MONOTONIC); - for (size_t i = 0; i < num_threads; i++) { - next_time_.push_back(gpr_time_add( - now, - gpr_time_from_nanos(interarrival_timer_.next(i), GPR_TIMESPAN))); - } - } - } - - std::function NextIssuer(int thread_idx) { - return closed_loop_ ? std::function() - : std::bind(&Client::NextIssueTime, this, thread_idx); - } - class Thread { public: Thread(Client* client, size_t idx) @@ -387,6 +329,64 @@ class Client { double interval_start_time_; }; + protected: + bool closed_loop_; + gpr_atm thread_pool_done_; + double median_latency_collection_interval_seconds_; // In seconds + + void StartThreads(size_t num_threads) { + gpr_atm_rel_store(&thread_pool_done_, static_cast(false)); + threads_remaining_ = num_threads; + for (size_t i = 0; i < num_threads; i++) { + threads_.emplace_back(new Thread(this, i)); + } + } + + void EndThreads() { + MaybeStartRequests(); + threads_.clear(); + } + + virtual void DestroyMultithreading() = 0; + + void SetupLoadTest(const ClientConfig& config, size_t num_threads) { + // Set up the load distribution based on the number of threads + const auto& load = config.load_params(); + + std::unique_ptr random_dist; + switch (load.load_case()) { + case LoadParams::kClosedLoop: + // Closed-loop doesn't use random dist at all + break; + case LoadParams::kPoisson: + random_dist.reset( + new ExpDist(load.poisson().offered_load() / num_threads)); + break; + default: + GPR_ASSERT(false); + } + + // Set closed_loop_ based on whether or not random_dist is set + if (!random_dist) { + closed_loop_ = true; + } else { + closed_loop_ = false; + // set up interarrival timer according to random dist + interarrival_timer_.init(*random_dist, num_threads); + const auto now = gpr_now(GPR_CLOCK_MONOTONIC); + for (size_t i = 0; i < num_threads; i++) { + next_time_.push_back(gpr_time_add( + now, + gpr_time_from_nanos(interarrival_timer_.next(i), GPR_TIMESPAN))); + } + } + } + + std::function NextIssuer(int thread_idx) { + return closed_loop_ ? std::function() + : std::bind(&Client::NextIssueTime, this, thread_idx); + } + virtual void ThreadFunc(size_t thread_idx, Client::Thread* t) = 0; std::vector> threads_; diff --git a/test/cpp/qps/client_callback.cc b/test/cpp/qps/client_callback.cc index 1880f46d43d..4a06325f2b7 100644 --- a/test/cpp/qps/client_callback.cc +++ b/test/cpp/qps/client_callback.cc @@ -90,7 +90,7 @@ class CallbackClient } } - gpr_timespec NextIssueTime() { + gpr_timespec NextRPCIssueTime() { std::lock_guard l(next_issue_time_mu_); return Client::NextIssueTime(0); } @@ -166,7 +166,7 @@ class CallbackUnaryClient final : public CallbackClient { private: void ScheduleRpc(Thread* t, size_t vector_idx) { if (!closed_loop_) { - gpr_timespec next_issue_time = NextIssueTime(); + gpr_timespec next_issue_time = NextRPCIssueTime(); // Start an alarm callback to run the internal callback after // next_issue_time ctx_[vector_idx]->alarm_.experimental().Set( @@ -221,13 +221,13 @@ class CallbackStreamingClient : public CallbackClient { } ~CallbackStreamingClient() {} - void AddHistogramEntry(double start_, bool ok, void* 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); } - ((Client::Thread*)thread_ptr)->UpdateHistogram(&entry); + thread_ptr->UpdateHistogram(&entry); } int messages_per_stream() { return messages_per_stream_; } @@ -297,7 +297,7 @@ class CallbackStreamingPingPongReactor final if (client_->ThreadCompleted()) return; if (!client_->IsClosedLoop()) { - gpr_timespec next_issue_time = client_->NextIssueTime(); + gpr_timespec next_issue_time = client_->NextRPCIssueTime(); // Start an alarm callback to run the internal callback after // next_issue_time ctx_->alarm_.experimental().Set(next_issue_time, @@ -307,13 +307,13 @@ class CallbackStreamingPingPongReactor final } } - void set_thread_ptr(void* ptr) { thread_ptr_ = ptr; } + void set_thread_ptr(Client::Thread* ptr) { thread_ptr_ = ptr; } CallbackStreamingPingPongClient* client_; std::unique_ptr ctx_; - void* thread_ptr_; // Needed to update histogram entries - double start_; // Track message start time - int messages_issued_; // Messages issued by this stream + Client::Thread* thread_ptr_; // Needed to update histogram entries + double start_; // Track message start time + int messages_issued_; // Messages issued by this stream }; class CallbackStreamingPingPongClientImpl final From 25e13ac79b67383765c0b786c7647af97676539a Mon Sep 17 00:00:00 2001 From: Max Vorobev Date: Mon, 24 Dec 2018 16:10:27 +0300 Subject: [PATCH 0652/2143] Fix incompatible_bzl_disallow_load_after_statement, deprecated attribute usage --- bazel/cc_grpc_library.bzl | 2 +- bazel/generate_cc.bzl | 2 +- bazel/grpc_build_system.bzl | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/bazel/cc_grpc_library.bzl b/bazel/cc_grpc_library.bzl index 32885657141..6bfcd653f51 100644 --- a/bazel/cc_grpc_library.bzl +++ b/bazel/cc_grpc_library.bzl @@ -1,6 +1,6 @@ """Generates and compiles C++ grpc stubs from proto_library rules.""" -load("//:bazel/generate_cc.bzl", "generate_cc") +load("//bazel:generate_cc.bzl", "generate_cc") def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, generate_mocks = False, use_external = False, **kwargs): """Generates C++ grpc classes from a .proto file. diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index ae747aa42ca..2f14071f92d 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -83,7 +83,7 @@ _generate_cc = rule( attrs = { "srcs": attr.label_list( mandatory = True, - non_empty = True, + allow_empty = False, providers = ["proto"], ), "plugin": attr.label( diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 65fe5a10aa2..caeafc76b69 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -23,6 +23,8 @@ # each change must be ported from one to the other. # +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"] @@ -111,7 +113,6 @@ def grpc_proto_plugin(name, srcs = [], deps = []): deps = deps, ) -load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library") def grpc_proto_library( name, From 00763bc3eaff1523a70e5e791924c16abd2fe526 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Mon, 30 Jul 2018 17:22:25 -0700 Subject: [PATCH 0653/2143] Support named scope id's with ipv6 resolver on posix --- BUILD | 3 + CMakeLists.txt | 102 +++++++++++++- Makefile | 106 +++++++++++++-- build.yaml | 38 +++++- config.m4 | 2 + config.w32 | 2 + gRPC-C++.podspec | 2 + gRPC-Core.podspec | 4 + grpc.gemspec | 3 + grpc.gyp | 8 ++ package.xml | 3 + .../filters/client_channel/parse_address.cc | 29 +++- src/core/lib/iomgr/grpc_if_nametoindex.h | 30 +++++ .../lib/iomgr/grpc_if_nametoindex_posix.cc | 41 ++++++ .../iomgr/grpc_if_nametoindex_unsupported.cc | 37 +++++ src/python/grpcio/grpc_core_dependencies.py | 2 + test/core/client_channel/BUILD | 11 ++ .../parse_address_with_named_scope_id_test.cc | 126 ++++++++++++++++++ test/core/iomgr/BUILD | 19 ++- test/core/iomgr/resolve_address_posix_test.cc | 81 ++++++++++- tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core.internal | 3 + .../generated/sources_and_headers.json | 38 +++++- tools/run_tests/generated/tests.json | 54 +++++++- 24 files changed, 717 insertions(+), 28 deletions(-) create mode 100644 src/core/lib/iomgr/grpc_if_nametoindex.h create mode 100644 src/core/lib/iomgr/grpc_if_nametoindex_posix.cc create mode 100644 src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc create mode 100644 test/core/client_channel/parse_address_with_named_scope_id_test.cc diff --git a/BUILD b/BUILD index e3c765198b2..5a9e46acf9e 100644 --- a/BUILD +++ b/BUILD @@ -732,6 +732,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", @@ -873,6 +875,7 @@ grpc_cc_library( "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/gevent_util.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", diff --git a/CMakeLists.txt b/CMakeLists.txt index d3ebb5d1773..9e07a204b71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -371,11 +371,17 @@ add_dependencies(buildtests_c murmur_hash_test) add_dependencies(buildtests_c no_server_test) add_dependencies(buildtests_c num_external_connectivity_watchers_test) add_dependencies(buildtests_c parse_address_test) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c parse_address_with_named_scope_id_test) +endif() add_dependencies(buildtests_c percent_encoding_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_dependencies(buildtests_c resolve_address_posix_test) +add_dependencies(buildtests_c resolve_address_using_ares_resolver_posix_test) endif() add_dependencies(buildtests_c resolve_address_using_ares_resolver_test) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c resolve_address_using_native_resolver_posix_test) +endif() add_dependencies(buildtests_c resolve_address_using_native_resolver_test) add_dependencies(buildtests_c resource_quota_test) add_dependencies(buildtests_c secure_channel_create_test) @@ -989,6 +995,8 @@ add_library(grpc 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 @@ -1411,6 +1419,8 @@ add_library(grpc_cronet 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 @@ -1817,6 +1827,8 @@ add_library(grpc_test_util 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 @@ -2139,6 +2151,8 @@ add_library(grpc_test_util_unsecure 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 @@ -2438,6 +2452,8 @@ add_library(grpc_unsecure 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 @@ -3323,6 +3339,8 @@ add_library(grpc++_cronet 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 @@ -9132,6 +9150,42 @@ target_link_libraries(parse_address_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(parse_address_with_named_scope_id_test + test/core/client_channel/parse_address_with_named_scope_id_test.cc +) + + +target_include_directories(parse_address_with_named_scope_id_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(parse_address_with_named_scope_id_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(parse_address_with_named_scope_id_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(parse_address_with_named_scope_id_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) add_executable(percent_encoding_test test/core/slice/percent_encoding_test.cc @@ -9168,12 +9222,12 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_executable(resolve_address_posix_test +add_executable(resolve_address_using_ares_resolver_posix_test test/core/iomgr/resolve_address_posix_test.cc ) -target_include_directories(resolve_address_posix_test +target_include_directories(resolve_address_using_ares_resolver_posix_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${_gRPC_SSL_INCLUDE_DIR} @@ -9186,7 +9240,7 @@ target_include_directories(resolve_address_posix_test PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) -target_link_libraries(resolve_address_posix_test +target_link_libraries(resolve_address_using_ares_resolver_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc @@ -9195,8 +9249,8 @@ target_link_libraries(resolve_address_posix_test # avoid dependency on libstdc++ if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(resolve_address_posix_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(resolve_address_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + set_target_properties(resolve_address_using_ares_resolver_posix_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(resolve_address_using_ares_resolver_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) endif() endif() @@ -9236,6 +9290,42 @@ target_link_libraries(resolve_address_using_ares_resolver_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(resolve_address_using_native_resolver_posix_test + test/core/iomgr/resolve_address_posix_test.cc +) + + +target_include_directories(resolve_address_using_native_resolver_posix_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(resolve_address_using_native_resolver_posix_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(resolve_address_using_native_resolver_posix_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(resolve_address_using_native_resolver_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) add_executable(resolve_address_using_native_resolver_test test/core/iomgr/resolve_address_test.cc diff --git a/Makefile b/Makefile index b8a1c921862..9e8e06c5491 100644 --- a/Makefile +++ b/Makefile @@ -1076,11 +1076,13 @@ nanopb_fuzzer_serverlist_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test no_server_test: $(BINDIR)/$(CONFIG)/no_server_test num_external_connectivity_watchers_test: $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test parse_address_test: $(BINDIR)/$(CONFIG)/parse_address_test +parse_address_with_named_scope_id_test: $(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test percent_decode_fuzzer: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer percent_encode_fuzzer: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer percent_encoding_test: $(BINDIR)/$(CONFIG)/percent_encoding_test -resolve_address_posix_test: $(BINDIR)/$(CONFIG)/resolve_address_posix_test +resolve_address_using_ares_resolver_posix_test: $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test resolve_address_using_ares_resolver_test: $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test +resolve_address_using_native_resolver_posix_test: $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test resolve_address_using_native_resolver_test: $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test resource_quota_test: $(BINDIR)/$(CONFIG)/resource_quota_test secure_channel_create_test: $(BINDIR)/$(CONFIG)/secure_channel_create_test @@ -1527,9 +1529,11 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/no_server_test \ $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test \ $(BINDIR)/$(CONFIG)/parse_address_test \ + $(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test \ $(BINDIR)/$(CONFIG)/percent_encoding_test \ - $(BINDIR)/$(CONFIG)/resolve_address_posix_test \ + $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test \ $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test \ + $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test \ $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test \ $(BINDIR)/$(CONFIG)/resource_quota_test \ $(BINDIR)/$(CONFIG)/secure_channel_create_test \ @@ -2129,12 +2133,16 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test || ( echo test num_external_connectivity_watchers_test failed ; exit 1 ) $(E) "[RUN] Testing parse_address_test" $(Q) $(BINDIR)/$(CONFIG)/parse_address_test || ( echo test parse_address_test failed ; exit 1 ) + $(E) "[RUN] Testing parse_address_with_named_scope_id_test" + $(Q) $(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test || ( echo test parse_address_with_named_scope_id_test failed ; exit 1 ) $(E) "[RUN] Testing percent_encoding_test" $(Q) $(BINDIR)/$(CONFIG)/percent_encoding_test || ( echo test percent_encoding_test failed ; exit 1 ) - $(E) "[RUN] Testing resolve_address_posix_test" - $(Q) $(BINDIR)/$(CONFIG)/resolve_address_posix_test || ( echo test resolve_address_posix_test failed ; exit 1 ) + $(E) "[RUN] Testing resolve_address_using_ares_resolver_posix_test" + $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test || ( echo test resolve_address_using_ares_resolver_posix_test failed ; exit 1 ) $(E) "[RUN] Testing resolve_address_using_ares_resolver_test" $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test || ( echo test resolve_address_using_ares_resolver_test failed ; exit 1 ) + $(E) "[RUN] Testing resolve_address_using_native_resolver_posix_test" + $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test || ( echo test resolve_address_using_native_resolver_posix_test failed ; exit 1 ) $(E) "[RUN] Testing resolve_address_using_native_resolver_test" $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test || ( echo test resolve_address_using_native_resolver_test failed ; exit 1 ) $(E) "[RUN] Testing resource_quota_test" @@ -3504,6 +3512,8 @@ LIBGRPC_SRC = \ 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 \ @@ -3920,6 +3930,8 @@ LIBGRPC_CRONET_SRC = \ 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 \ @@ -4319,6 +4331,8 @@ LIBGRPC_TEST_UTIL_SRC = \ 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 \ @@ -4628,6 +4642,8 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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 \ @@ -4901,6 +4917,8 @@ LIBGRPC_UNSECURE_SRC = \ 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 \ @@ -5763,6 +5781,8 @@ LIBGRPC++_CRONET_SRC = \ 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 \ @@ -13988,6 +14008,38 @@ endif endif +PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_SRC = \ + test/core/client_channel/parse_address_with_named_scope_id_test.cc \ + +PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test: $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_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) $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/client_channel/parse_address_with_named_scope_id_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_parse_address_with_named_scope_id_test: $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS:.o=.dep) +endif +endif + + PERCENT_DECODE_FUZZER_SRC = \ test/core/slice/percent_decode_fuzzer.cc \ @@ -14084,34 +14136,34 @@ endif endif -RESOLVE_ADDRESS_POSIX_TEST_SRC = \ +RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_SRC = \ test/core/iomgr/resolve_address_posix_test.cc \ -RESOLVE_ADDRESS_POSIX_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RESOLVE_ADDRESS_POSIX_TEST_SRC)))) +RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/resolve_address_posix_test: openssl_dep_error +$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/resolve_address_posix_test: $(RESOLVE_ADDRESS_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_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) $(RESOLVE_ADDRESS_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_posix_test + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test endif $(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_resolve_address_posix_test: $(RESOLVE_ADDRESS_POSIX_TEST_OBJS:.o=.dep) +deps_resolve_address_using_ares_resolver_posix_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(RESOLVE_ADDRESS_POSIX_TEST_OBJS:.o=.dep) +-include $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS:.o=.dep) endif endif @@ -14148,6 +14200,38 @@ endif endif +RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_SRC = \ + test/core/iomgr/resolve_address_posix_test.cc \ + +RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_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) $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_resolve_address_using_native_resolver_posix_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS:.o=.dep) +endif +endif + + RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_SRC = \ test/core/iomgr/resolve_address_test.cc \ diff --git a/build.yaml b/build.yaml index a41decd84f7..3985668532d 100644 --- a/build.yaml +++ b/build.yaml @@ -276,6 +276,8 @@ filegroups: - 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 @@ -452,6 +454,7 @@ filegroups: - 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 @@ -3241,6 +3244,20 @@ targets: - grpc - gpr uses_polling: false +- name: parse_address_with_named_scope_id_test + build: test + language: c + src: + - test/core/client_channel/parse_address_with_named_scope_id_test.cc + deps: + - grpc_test_util + - grpc + - gpr + platforms: + - mac + - linux + - posix + uses_polling: false - name: percent_decode_fuzzer build: fuzzer language: c @@ -3275,7 +3292,7 @@ targets: - grpc - gpr uses_polling: false -- name: resolve_address_posix_test +- name: resolve_address_using_ares_resolver_posix_test build: test language: c src: @@ -3284,6 +3301,8 @@ targets: - grpc_test_util - grpc - gpr + args: + - --resolver=ares exclude_iomgrs: - uv platforms: @@ -3301,6 +3320,23 @@ targets: - gpr args: - --resolver=ares +- name: resolve_address_using_native_resolver_posix_test + build: test + language: c + src: + - test/core/iomgr/resolve_address_posix_test.cc + deps: + - grpc_test_util + - grpc + - gpr + args: + - --resolver=native + exclude_iomgrs: + - uv + platforms: + - mac + - linux + - posix - name: resolve_address_using_native_resolver_test build: test language: c diff --git a/config.m4 b/config.m4 index 25ffe2148ab..3c3c0210d87 100644 --- a/config.m4 +++ b/config.m4 @@ -128,6 +128,8 @@ if test "$PHP_GRPC" != "no"; then 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 \ diff --git a/config.w32 b/config.w32 index b6e71dd09a5..f87859ad09f 100644 --- a/config.w32 +++ b/config.w32 @@ -103,6 +103,8 @@ if (PHP_GRPC != "no") { "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 " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 29a79dd47ab..cdea73abc8b 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -423,6 +423,7 @@ Pod::Spec.new do |s| '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', @@ -616,6 +617,7 @@ Pod::Spec.new do |s| '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', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f873bc693bc..6c97dc42dc8 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -417,6 +417,7 @@ Pod::Spec.new do |s| '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', @@ -571,6 +572,8 @@ Pod::Spec.new do |s| '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', @@ -1040,6 +1043,7 @@ Pod::Spec.new do |s| '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', diff --git a/grpc.gemspec b/grpc.gemspec index 3c680b044f7..42b1db35b4d 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -353,6 +353,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/exec_ctx.h ) s.files += %w( src/core/lib/iomgr/executor.h ) s.files += %w( src/core/lib/iomgr/gethostname.h ) + s.files += %w( src/core/lib/iomgr/grpc_if_nametoindex.h ) s.files += %w( src/core/lib/iomgr/internal_errqueue.h ) s.files += %w( src/core/lib/iomgr/iocp_windows.h ) s.files += %w( src/core/lib/iomgr/iomgr.h ) @@ -507,6 +508,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/gethostname_fallback.cc ) s.files += %w( src/core/lib/iomgr/gethostname_host_name_max.cc ) s.files += %w( src/core/lib/iomgr/gethostname_sysconf.cc ) + s.files += %w( src/core/lib/iomgr/grpc_if_nametoindex_posix.cc ) + s.files += %w( src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc ) s.files += %w( src/core/lib/iomgr/internal_errqueue.cc ) s.files += %w( src/core/lib/iomgr/iocp_windows.cc ) s.files += %w( src/core/lib/iomgr/iomgr.cc ) diff --git a/grpc.gyp b/grpc.gyp index 80b6d0315a1..13b9c1bc78b 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -310,6 +310,8 @@ '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', @@ -672,6 +674,8 @@ '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', @@ -914,6 +918,8 @@ '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', @@ -1133,6 +1139,8 @@ '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', diff --git a/package.xml b/package.xml index 2632fcb276b..6c1d902abcd 100644 --- a/package.xml +++ b/package.xml @@ -358,6 +358,7 @@ + @@ -512,6 +513,8 @@ + + diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc index 707beb88769..c5e1ed811bc 100644 --- a/src/core/ext/filters/client_channel/parse_address.cc +++ b/src/core/ext/filters/client_channel/parse_address.cc @@ -19,6 +19,7 @@ #include #include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/lib/iomgr/grpc_if_nametoindex.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/socket_utils.h" @@ -35,6 +36,11 @@ #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#ifdef GRPC_POSIX_SOCKET +#include +#include +#endif + #ifdef GRPC_HAVE_UNIX_SOCKET bool grpc_parse_unix(const grpc_uri* uri, @@ -69,7 +75,12 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr, // Split host and port. char* host; char* port; - if (!gpr_split_host_port(hostport, &host, &port)) return false; + if (!gpr_split_host_port(hostport, &host, &port)) { + if (log_errors) { + gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport); + } + return false; + } // Parse IP address. memset(addr, 0, sizeof(*addr)); addr->len = static_cast(sizeof(grpc_sockaddr_in)); @@ -115,7 +126,12 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, // Split host and port. char* host; char* port; - if (!gpr_split_host_port(hostport, &host, &port)) return false; + if (!gpr_split_host_port(hostport, &host, &port)) { + if (log_errors) { + gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport); + } + return false; + } // Parse IP address. memset(addr, 0, sizeof(*addr)); addr->len = static_cast(sizeof(grpc_sockaddr_in6)); @@ -150,10 +166,13 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, if (gpr_parse_bytes_to_uint32(host_end + 1, strlen(host) - host_without_scope_len - 1, &sin6_scope_id) == 0) { - if (log_errors) { - gpr_log(GPR_ERROR, "invalid ipv6 scope id: '%s'", host_end + 1); + if ((sin6_scope_id = grpc_if_nametoindex(host_end + 1)) == 0) { + gpr_log(GPR_ERROR, + "Invalid interface name: '%s'. " + "Non-numeric and failed if_nametoindex.", + host_end + 1); + goto done; } - goto done; } // Handle "sin6_scope_id" being type "u_long". See grpc issue #10027. in6->sin6_scope_id = sin6_scope_id; diff --git a/src/core/lib/iomgr/grpc_if_nametoindex.h b/src/core/lib/iomgr/grpc_if_nametoindex.h new file mode 100644 index 00000000000..ed9612dcb93 --- /dev/null +++ b/src/core/lib/iomgr/grpc_if_nametoindex.h @@ -0,0 +1,30 @@ +/* + * + * 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 GRPC_CORE_LIB_IOMGR_GRPC_IF_NAMETOINDEX_H +#define GRPC_CORE_LIB_IOMGR_GRPC_IF_NAMETOINDEX_H + +#include + +#include + +/* Returns the interface index corresponding to the interface "name" provided. + * Returns non-zero upon success, and zero upon failure. */ +uint32_t grpc_if_nametoindex(char* name); + +#endif /* GRPC_CORE_LIB_IOMGR_GRPC_IF_NAMETOINDEX_H */ diff --git a/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc b/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc new file mode 100644 index 00000000000..8f9137455d2 --- /dev/null +++ b/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc @@ -0,0 +1,41 @@ +/* + * + * 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_SOCKET + +#include "src/core/lib/iomgr/grpc_if_nametoindex.h" + +#include +#include + +#include + +uint32_t grpc_if_nametoindex(char* name) { + uint32_t out = if_nametoindex(name); + if (out == 0) { + gpr_log(GPR_DEBUG, "if_nametoindex failed for name %s. errno %d", name, + errno); + } + return out; +} + +#endif /* GRPC_POSIX_SOCKET */ diff --git a/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc b/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc new file mode 100644 index 00000000000..1faaaa6e420 --- /dev/null +++ b/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc @@ -0,0 +1,37 @@ +/* + * + * 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" + +#ifndef GRPC_POSIX_SOCKET + +#include "src/core/lib/iomgr/grpc_if_nametoindex.h" + +#include + +uint32_t grpc_if_nametoindex(char* name) { + gpr_log(GPR_DEBUG, + "Not attempting to convert interface name %s to index for current " + "platform.", + name); + return 0; +} + +#endif /* GRPC_POSIX_SOCKET */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 6a1fd676ca6..06de23903cb 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -102,6 +102,8 @@ CORE_SOURCE_FILES = [ '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', diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD index 04485f5240f..57e5191af4c 100644 --- a/test/core/client_channel/BUILD +++ b/test/core/client_channel/BUILD @@ -43,6 +43,17 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "parse_address_with_named_scope_id_test", + srcs = ["parse_address_with_named_scope_id_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "uri_parser_test", srcs = ["uri_parser_test.cc"], diff --git a/test/core/client_channel/parse_address_with_named_scope_id_test.cc b/test/core/client_channel/parse_address_with_named_scope_id_test.cc new file mode 100644 index 00000000000..bfafa745178 --- /dev/null +++ b/test/core/client_channel/parse_address_with_named_scope_id_test.cc @@ -0,0 +1,126 @@ +/* + * + * 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 "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/socket_utils.h" + +#include +#include +#ifdef GRPC_HAVE_UNIX_SOCKET +#include +#endif + +#include +#include +#include + +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/socket_utils.h" +#include "test/core/util/test_config.h" + +static void test_grpc_parse_ipv6_parity_with_getaddrinfo( + const char* target, const struct sockaddr_in6 result_from_getaddrinfo) { + // Get the sockaddr that gRPC's ipv6 resolver resolves this too. + grpc_core::ExecCtx exec_ctx; + grpc_uri* uri = grpc_uri_parse(target, 0); + grpc_resolved_address addr; + GPR_ASSERT(1 == grpc_parse_ipv6(uri, &addr)); + grpc_sockaddr_in6* result_from_grpc_parser = + reinterpret_cast(addr.addr); + // Compare the sockaddr returned from gRPC's ipv6 resolver with that returned + // from getaddrinfo. + GPR_ASSERT(result_from_grpc_parser->sin6_family == AF_INET6); + GPR_ASSERT(result_from_getaddrinfo.sin6_family == AF_INET6); + GPR_ASSERT(memcmp(&result_from_grpc_parser->sin6_addr, + &result_from_getaddrinfo.sin6_addr, sizeof(in6_addr)) == 0); + GPR_ASSERT(result_from_grpc_parser->sin6_scope_id == + result_from_getaddrinfo.sin6_scope_id); + GPR_ASSERT(result_from_grpc_parser->sin6_scope_id != 0); + // TODO: compare sin6_flow_info fields? parse_ipv6 zero's this field as is. + // Cleanup + grpc_uri_destroy(uri); +} + +struct sockaddr_in6 resolve_with_gettaddrinfo(const char* uri_text) { + grpc_uri* uri = grpc_uri_parse(uri_text, 0); + char* host = nullptr; + char* port = nullptr; + gpr_split_host_port(uri->path, &host, &port); + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_NUMERICHOST; + struct addrinfo* result; + int res = getaddrinfo(host, port, &hints, &result); + if (res != 0) { + gpr_log(GPR_ERROR, + "getaddrinfo failed to resolve host:%s port:%s. Error: %d.", host, + port, res); + abort(); + } + size_t num_addrs_from_getaddrinfo = 0; + for (struct addrinfo* resp = result; resp != nullptr; resp = resp->ai_next) { + num_addrs_from_getaddrinfo++; + } + GPR_ASSERT(num_addrs_from_getaddrinfo == 1); + GPR_ASSERT(result->ai_family == AF_INET6); + struct sockaddr_in6 out = + *reinterpret_cast(result->ai_addr); + // Cleanup + freeaddrinfo(result); + gpr_free(host); + gpr_free(port); + grpc_uri_destroy(uri); + return out; +} + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + char* arbitrary_interface_name = static_cast(gpr_zalloc(IF_NAMESIZE)); + // Per RFC 3493, an interface index is a "small positive integer starts at 1". + // Probe candidate interface index numbers until we find one that the + // system recognizes, and then use that for the test. + for (size_t i = 1; i < 65536; i++) { + if (if_indextoname(i, arbitrary_interface_name) != nullptr) { + gpr_log( + GPR_DEBUG, + "Found interface at index %d named %s. Will use this for the test", + (int)i, arbitrary_interface_name); + break; + } + } + GPR_ASSERT(strlen(arbitrary_interface_name) > 0); + char* target = nullptr; + gpr_asprintf(&target, "ipv6:[fe80::1234%%%s]:12345", + arbitrary_interface_name); + struct sockaddr_in6 result_from_getaddrinfo = + resolve_with_gettaddrinfo(target); + // Run the test + gpr_log(GPR_DEBUG, + "Run test_grpc_parse_ipv6_parity_with_getaddrinfo with target: %s", + target); + test_grpc_parse_ipv6_parity_with_getaddrinfo(target, result_from_getaddrinfo); + // Cleanup + gpr_free(target); + gpr_free(arbitrary_interface_name); + grpc_shutdown(); +} diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index e920ceacf00..5acf269988b 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -128,8 +128,25 @@ grpc_cc_test( ) grpc_cc_test( - name = "resolve_address_posix_test", + name = "resolve_address_using_ares_resolver_posix_test", srcs = ["resolve_address_posix_test.cc"], + args = [ + "--resolver=ares", + ], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "resolve_address_using_native_resolver_posix_test", + srcs = ["resolve_address_posix_test.cc"], + args = [ + "--resolver=native", + ], language = "C++", deps = [ "//:gpr", diff --git a/test/core/iomgr/resolve_address_posix_test.cc b/test/core/iomgr/resolve_address_posix_test.cc index 5785c73e225..826c7e1fafa 100644 --- a/test/core/iomgr/resolve_address_posix_test.cc +++ b/test/core/iomgr/resolve_address_posix_test.cc @@ -18,12 +18,14 @@ #include "src/core/lib/iomgr/resolve_address.h" +#include #include #include #include #include #include +#include #include #include @@ -33,6 +35,7 @@ #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" +#include "test/core/util/cmdline.h" #include "test/core/util/test_config.h" static gpr_timespec test_deadline(void) { @@ -117,12 +120,18 @@ static void must_succeed(void* argsp, grpc_error* err) { GPR_ASSERT(args->addrs != nullptr); GPR_ASSERT(args->addrs->naddrs > 0); 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_fail(void* argsp, grpc_error* err) { args_struct* args = static_cast(argsp); GPR_ASSERT(err != GRPC_ERROR_NONE); 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_unix_socket(void) { @@ -159,22 +168,92 @@ static void test_unix_socket_path_name_too_long(void) { args_finish(&args); } +static void resolve_address_must_succeed(const char* target) { + grpc_core::ExecCtx exec_ctx; + args_struct args; + args_init(&args); + poll_pollset_until_request_done(&args); + grpc_resolve_address( + target, "1" /* port number */, args.pollset_set, + GRPC_CLOSURE_CREATE(must_succeed, &args, grpc_schedule_on_exec_ctx), + &args.addrs); + grpc_core::ExecCtx::Get()->Flush(); + args_finish(&args); +} + +static void test_named_and_numeric_scope_ids(void) { + char* arbitrary_interface_name = static_cast(gpr_zalloc(IF_NAMESIZE)); + int interface_index = 0; + // Probe candidate interface index numbers until we find one that the + // system recognizes, and then use that for the test. + for (size_t i = 1; i < 65536; i++) { + if (if_indextoname(i, arbitrary_interface_name) != nullptr) { + gpr_log( + GPR_DEBUG, + "Found interface at index %d named %s. Will use this for the test", + (int)i, arbitrary_interface_name); + interface_index = (int)i; + break; + } + } + GPR_ASSERT(strlen(arbitrary_interface_name) > 0); + // Test resolution of an ipv6 address with a named scope ID + gpr_log(GPR_DEBUG, "test resolution with a named scope ID"); + char* target_with_named_scope_id = nullptr; + gpr_asprintf(&target_with_named_scope_id, "fe80::1234%%%s", + arbitrary_interface_name); + resolve_address_must_succeed(target_with_named_scope_id); + gpr_free(target_with_named_scope_id); + gpr_free(arbitrary_interface_name); + // Test resolution of an ipv6 address with a numeric scope ID + gpr_log(GPR_DEBUG, "test resolution with a numeric scope ID"); + char* target_with_numeric_scope_id = nullptr; + gpr_asprintf(&target_with_numeric_scope_id, "fe80::1234%%%d", + interface_index); + resolve_address_must_succeed(target_with_numeric_scope_id); + gpr_free(target_with_numeric_scope_id); +} + int main(int argc, char** argv) { + // First set the resolver type based off of --resolver + const char* resolver_type = nullptr; + gpr_cmdline* cl = gpr_cmdline_create("resolve address test"); + gpr_cmdline_add_string(cl, "resolver", "Resolver type (ares or native)", + &resolver_type); + // In case that there are more than one argument on the command line, + // --resolver will always be the first one, so only parse the first argument + // (other arguments may be unknown to cl) + gpr_cmdline_parse(cl, argc > 2 ? 2 : argc, argv); + const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER"); + if (cur_resolver != nullptr && strlen(cur_resolver) != 0) { + gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s", + cur_resolver); + } + if (gpr_stricmp(resolver_type, "native") == 0) { + gpr_setenv("GRPC_DNS_RESOLVER", "native"); + } else if (gpr_stricmp(resolver_type, "ares") == 0) { + gpr_setenv("GRPC_DNS_RESOLVER", "ares"); + } else { + gpr_log(GPR_ERROR, "--resolver_type was not set to ares or native"); + abort(); + } grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; - char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); + test_named_and_numeric_scope_ids(); // c-ares resolver doesn't support UDS (ability for native DNS resolver // to handle this is only expected to be used by servers, which // unconditionally use the native DNS resolver). + char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) { test_unix_socket(); test_unix_socket_path_name_too_long(); } gpr_free(resolver_env); } + gpr_cmdline_destroy(cl); grpc_shutdown(); return 0; diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 5f488d51940..08741168275 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1100,6 +1100,7 @@ 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 \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index ba2eaecafda..38d17b6f21f 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1214,6 +1214,9 @@ 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 \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8d1bca22be9..1478ac2cd5e 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -1722,6 +1722,22 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "parse_address_with_named_scope_id_test", + "src": [ + "test/core/client_channel/parse_address_with_named_scope_id_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -1779,7 +1795,7 @@ "headers": [], "is_filegroup": false, "language": "c", - "name": "resolve_address_posix_test", + "name": "resolve_address_using_ares_resolver_posix_test", "src": [ "test/core/iomgr/resolve_address_posix_test.cc" ], @@ -1802,6 +1818,22 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "resolve_address_using_native_resolver_posix_test", + "src": [ + "test/core/iomgr/resolve_address_posix_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -9371,6 +9403,8 @@ "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", @@ -9548,6 +9582,7 @@ "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", @@ -9701,6 +9736,7 @@ "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", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index e35d4db2767..f2d0cab5ede 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -2057,6 +2057,28 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "parse_address_with_named_scope_id_test", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, @@ -2082,7 +2104,9 @@ "uses_polling": false }, { - "args": [], + "args": [ + "--resolver=ares" + ], "benchmark": false, "ci_platforms": [ "linux", @@ -2097,7 +2121,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "resolve_address_posix_test", + "name": "resolve_address_using_ares_resolver_posix_test", "platforms": [ "linux", "mac", @@ -2131,6 +2155,32 @@ ], "uses_polling": true }, + { + "args": [ + "--resolver=native" + ], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "gtest": false, + "language": "c", + "name": "resolve_address_using_native_resolver_posix_test", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": true + }, { "args": [ "--resolver=native" From 39ac83a49ea73f619edbfd7ebde47f12d67a18f3 Mon Sep 17 00:00:00 2001 From: Tommy Chen Date: Wed, 26 Dec 2018 11:17:48 -0800 Subject: [PATCH 0654/2143] ruby-sigint ready to be merged! --- examples/ruby/greeter_server.rb | 5 +- .../ruby/route_guide/route_guide_server.rb | 5 +- .../end2end/graceful_sig_handling_client.rb | 61 ++++++++++++++ .../end2end/graceful_sig_handling_driver.rb | 83 +++++++++++++++++++ src/ruby/end2end/graceful_sig_stop_client.rb | 78 +++++++++++++++++ src/ruby/end2end/graceful_sig_stop_driver.rb | 62 ++++++++++++++ src/ruby/lib/grpc/generic/rpc_server.rb | 61 ++++++++++++++ .../helper_scripts/run_ruby_end2end_tests.sh | 2 + 8 files changed, 355 insertions(+), 2 deletions(-) create mode 100755 src/ruby/end2end/graceful_sig_handling_client.rb create mode 100755 src/ruby/end2end/graceful_sig_handling_driver.rb create mode 100755 src/ruby/end2end/graceful_sig_stop_client.rb create mode 100755 src/ruby/end2end/graceful_sig_stop_driver.rb diff --git a/examples/ruby/greeter_server.rb b/examples/ruby/greeter_server.rb index dca61714b88..52904297426 100755 --- a/examples/ruby/greeter_server.rb +++ b/examples/ruby/greeter_server.rb @@ -39,7 +39,10 @@ def main s = GRPC::RpcServer.new s.add_http2_port('0.0.0.0:50051', :this_port_is_insecure) s.handle(GreeterServer) - s.run_till_terminated + # Runs the server with SIGHUP, SIGINT and SIGQUIT signal handlers to + # gracefully shutdown. + # User could also choose to run server via call to run_till_terminated + s.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT']) end main diff --git a/examples/ruby/route_guide/route_guide_server.rb b/examples/ruby/route_guide/route_guide_server.rb index 5eb268b5336..ffcebd8418d 100755 --- a/examples/ruby/route_guide/route_guide_server.rb +++ b/examples/ruby/route_guide/route_guide_server.rb @@ -172,7 +172,10 @@ def main s.add_http2_port(port, :this_port_is_insecure) GRPC.logger.info("... running insecurely on #{port}") s.handle(ServerImpl.new(feature_db)) - s.run_till_terminated + # Runs the server with SIGHUP, SIGINT and SIGQUIT signal handlers to + # gracefully shutdown. + # User could also choose to run server via call to run_till_terminated + s.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT']) end main diff --git a/src/ruby/end2end/graceful_sig_handling_client.rb b/src/ruby/end2end/graceful_sig_handling_client.rb new file mode 100755 index 00000000000..14a67a62ccc --- /dev/null +++ b/src/ruby/end2end/graceful_sig_handling_client.rb @@ -0,0 +1,61 @@ +#!/usr/bin/env ruby + +# 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. + +require_relative './end2end_common' + +# Test client. Sends RPC's as normal but process also has signal handlers +class SigHandlingClientController < ClientControl::ClientController::Service + def initialize(stub) + @stub = stub + end + + def do_echo_rpc(req, _) + response = @stub.echo(Echo::EchoRequest.new(request: req.request)) + fail 'bad response' unless response.response == req.request + ClientControl::Void.new + end +end + +def main + client_control_port = '' + server_port = '' + OptionParser.new do |opts| + opts.on('--client_control_port=P', String) do |p| + client_control_port = p + end + opts.on('--server_port=P', String) do |p| + server_port = p + end + end.parse! + + # Allow a few seconds to be safe. + srv = new_rpc_server_for_testing + srv.add_http2_port("0.0.0.0:#{client_control_port}", + :this_port_is_insecure) + stub = Echo::EchoServer::Stub.new("localhost:#{server_port}", + :this_channel_is_insecure) + control_service = SigHandlingClientController.new(stub) + srv.handle(control_service) + server_thread = Thread.new do + srv.run_till_terminated_or_interrupted(['int']) + end + srv.wait_till_running + # send a first RPC to notify the parent process that we've started + stub.echo(Echo::EchoRequest.new(request: 'client/child started')) + server_thread.join +end + +main diff --git a/src/ruby/end2end/graceful_sig_handling_driver.rb b/src/ruby/end2end/graceful_sig_handling_driver.rb new file mode 100755 index 00000000000..e12ae284858 --- /dev/null +++ b/src/ruby/end2end/graceful_sig_handling_driver.rb @@ -0,0 +1,83 @@ +#!/usr/bin/env ruby + +# 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. + +# smoke test for a grpc-using app that receives and +# handles process-ending signals + +require_relative './end2end_common' + +# A service that calls back it's received_rpc_callback +# upon receiving an RPC. Used for synchronization/waiting +# for child process to start. +class ClientStartedService < Echo::EchoServer::Service + def initialize(received_rpc_callback) + @received_rpc_callback = received_rpc_callback + end + + def echo(echo_req, _) + @received_rpc_callback.call unless @received_rpc_callback.nil? + @received_rpc_callback = nil + Echo::EchoReply.new(response: echo_req.request) + end +end + +def main + STDERR.puts 'start server' + client_started = false + client_started_mu = Mutex.new + client_started_cv = ConditionVariable.new + received_rpc_callback = proc do + client_started_mu.synchronize do + client_started = true + client_started_cv.signal + end + end + + client_started_service = ClientStartedService.new(received_rpc_callback) + server_runner = ServerRunner.new(client_started_service) + server_port = server_runner.run + STDERR.puts 'start client' + control_stub, client_pid = start_client('graceful_sig_handling_client.rb', server_port) + + client_started_mu.synchronize do + client_started_cv.wait(client_started_mu) until client_started + end + + control_stub.do_echo_rpc( + ClientControl::DoEchoRpcRequest.new(request: 'hello')) + + STDERR.puts 'killing client' + Process.kill('SIGINT', client_pid) + Process.wait(client_pid) + client_exit_status = $CHILD_STATUS + + if client_exit_status.exited? + if client_exit_status.exitstatus != 0 + STDERR.puts 'Client did not close gracefully' + exit(1) + end + else + STDERR.puts 'Client did not close gracefully' + exit(1) + end + + STDERR.puts 'Client ended gracefully' + + # no need to call cleanup, client should already be dead + server_runner.stop +end + +main diff --git a/src/ruby/end2end/graceful_sig_stop_client.rb b/src/ruby/end2end/graceful_sig_stop_client.rb new file mode 100755 index 00000000000..b672dc3f2ac --- /dev/null +++ b/src/ruby/end2end/graceful_sig_stop_client.rb @@ -0,0 +1,78 @@ +#!/usr/bin/env ruby + +# 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. + +require_relative './end2end_common' + +# Test client. Sends RPC's as normal but process also has signal handlers +class SigHandlingClientController < ClientControl::ClientController::Service + def initialize(srv, stub) + @srv = srv + @stub = stub + end + + def do_echo_rpc(req, _) + response = @stub.echo(Echo::EchoRequest.new(request: req.request)) + fail 'bad response' unless response.response == req.request + ClientControl::Void.new + end + + def shutdown(_, _) + # Spawn a new thread because RpcServer#stop is + # synchronous and blocks until either this RPC has finished, + # or the server's "poll_period" seconds have passed. + @shutdown_thread = Thread.new do + @srv.stop + end + ClientControl::Void.new + end + + def join_shutdown_thread + @shutdown_thread.join + end +end + +def main + client_control_port = '' + server_port = '' + OptionParser.new do |opts| + opts.on('--client_control_port=P', String) do |p| + client_control_port = p + end + opts.on('--server_port=P', String) do |p| + server_port = p + end + end.parse! + + # The "shutdown" RPC should end very quickly. + # Allow a few seconds to be safe. + srv = new_rpc_server_for_testing(poll_period: 3) + srv.add_http2_port("0.0.0.0:#{client_control_port}", + :this_port_is_insecure) + stub = Echo::EchoServer::Stub.new("localhost:#{server_port}", + :this_channel_is_insecure) + control_service = SigHandlingClientController.new(srv, stub) + srv.handle(control_service) + server_thread = Thread.new do + srv.run_till_terminated_or_interrupted(['int']) + end + srv.wait_till_running + # send a first RPC to notify the parent process that we've started + stub.echo(Echo::EchoRequest.new(request: 'client/child started')) + server_thread.join + control_service.join_shutdown_thread +end + +main diff --git a/src/ruby/end2end/graceful_sig_stop_driver.rb b/src/ruby/end2end/graceful_sig_stop_driver.rb new file mode 100755 index 00000000000..7a132403ebf --- /dev/null +++ b/src/ruby/end2end/graceful_sig_stop_driver.rb @@ -0,0 +1,62 @@ +#!/usr/bin/env ruby + +# 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. + +# smoke test for a grpc-using app that receives and +# handles process-ending signals + +require_relative './end2end_common' + +# A service that calls back it's received_rpc_callback +# upon receiving an RPC. Used for synchronization/waiting +# for child process to start. +class ClientStartedService < Echo::EchoServer::Service + def initialize(received_rpc_callback) + @received_rpc_callback = received_rpc_callback + end + + def echo(echo_req, _) + @received_rpc_callback.call unless @received_rpc_callback.nil? + @received_rpc_callback = nil + Echo::EchoReply.new(response: echo_req.request) + end +end + +def main + STDERR.puts 'start server' + client_started = false + client_started_mu = Mutex.new + client_started_cv = ConditionVariable.new + received_rpc_callback = proc do + client_started_mu.synchronize do + client_started = true + client_started_cv.signal + end + end + + client_started_service = ClientStartedService.new(received_rpc_callback) + server_runner = ServerRunner.new(client_started_service) + server_port = server_runner.run + STDERR.puts 'start client' + control_stub, client_pid = start_client('./graceful_sig_stop_client.rb', server_port) + + client_started_mu.synchronize do + client_started_cv.wait(client_started_mu) until client_started + end + + cleanup(control_stub, client_pid, server_runner) +end + +main diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index 3b5a0ce27f3..f0f73dc56ea 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -240,6 +240,13 @@ module GRPC # the call has no impact if the server is already stopped, otherwise # server's current call loop is it's last. def stop + # if called via run_till_terminated_or_interrupted, + # signal stop_server_thread and dont do anything + if @stop_server.nil? == false && @stop_server == false + @stop_server = true + @stop_server_cv.broadcast + return + end @run_mutex.synchronize do fail 'Cannot stop before starting' if @running_state == :not_started return if @running_state != :running @@ -354,6 +361,60 @@ module GRPC alias_method :run_till_terminated, :run + # runs the server with signal handlers + # @param signals + # List of String, Integer or both representing signals that the user + # would like to send to the server for graceful shutdown + # @param wait_interval (optional) + # Integer seconds that user would like stop_server_thread to poll + # stop_server + def run_till_terminated_or_interrupted(signals, wait_interval = 60) + @stop_server = false + @stop_server_mu = Mutex.new + @stop_server_cv = ConditionVariable.new + + @stop_server_thread = Thread.new do + loop do + break if @stop_server + @stop_server_mu.synchronize do + @stop_server_cv.wait(@stop_server_mu, wait_interval) + end + end + + # stop is surrounded by mutex, should handle multiple calls to stop + # correctly + stop + end + + valid_signals = Signal.list + + # register signal handlers + signals.each do |sig| + # input validation + if sig.class == String + sig.upcase! + if sig.start_with?('SIG') + # cut out the SIG prefix to see if valid signal + sig = sig[3..-1] + end + end + + # register signal traps for all valid signals + if valid_signals.value?(sig) || valid_signals.key?(sig) + Signal.trap(sig) do + @stop_server = true + @stop_server_cv.broadcast + end + else + fail "#{sig} not a valid signal" + end + end + + run + + @stop_server_thread.join + end + # Sends RESOURCE_EXHAUSTED if there are too many unprocessed jobs def available?(an_rpc) return an_rpc if @pool.ready_for_work? diff --git a/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh b/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh index 7ff877e8306..1c48ed20ba6 100755 --- a/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh +++ b/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh @@ -30,4 +30,6 @@ time ruby src/ruby/end2end/multiple_killed_watching_threads_driver.rb || EXIT_CO time ruby src/ruby/end2end/load_grpc_with_gc_stress_driver.rb || EXIT_CODE=1 time ruby src/ruby/end2end/client_memory_usage_driver.rb || EXIT_CODE=1 time ruby src/ruby/end2end/package_with_underscore_checker.rb || EXIT_CODE=1 +time ruby src/ruby/end2end/graceful_sig_handling_driver.rb || EXIT_CODE=1 +time ruby src/ruby/end2end/graceful_sig_stop_driver.rb || EXIT_CODE=1 exit $EXIT_CODE From 71e7e6ddc73175df0793748e290e29321934fd7c Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 26 Dec 2018 12:29:52 -0800 Subject: [PATCH 0655/2143] Add Watch method to health check service --- .../grpc_health/v1/health.py | 76 +++++++- .../health_check/_health_servicer_test.py | 174 ++++++++++++++++-- 2 files changed, 223 insertions(+), 27 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 05836594281..75c480b0a7a 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py @@ -23,15 +23,61 @@ from grpc_health.v1 import health_pb2_grpc as _health_pb2_grpc SERVICE_NAME = _health_pb2.DESCRIPTOR.services_by_name['Health'].full_name +class _Watcher(): + + def __init__(self): + self._condition = threading.Condition() + self._responses = list() + self._open = True + + def __iter__(self): + return self + + def _next(self): + with self._condition: + while not self._responses and self._open: + self._condition.wait() + if self._responses: + return self._responses.pop(0) + else: + raise StopIteration() + + def next(self): + return self._next() + + def __next__(self): + return self._next() + + def add(self, response): + with self._condition: + self._responses.append(response) + self._condition.notify() + + def close(self): + with self._condition: + self._open = False + self._condition.notify() + + class HealthServicer(_health_pb2_grpc.HealthServicer): """Servicer handling RPCs for service statuses.""" def __init__(self): - self._server_status_lock = threading.Lock() + self._lock = threading.RLock() self._server_status = {} + self._watchers = {} + + def _on_close_callback(self, watcher, service): + + def callback(): + with self._lock: + self._watchers[service].remove(watcher) + watcher.close() + + return callback def Check(self, request, context): - with self._server_status_lock: + with self._lock: status = self._server_status.get(request.service) if status is None: context.set_code(grpc.StatusCode.NOT_FOUND) @@ -39,14 +85,30 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): else: return _health_pb2.HealthCheckResponse(status=status) + def Watch(self, request, context): + 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 + def set(self, service, status): """Sets the status of a service. Args: - service: string, the name of the service. - NOTE, '' must be set. - status: HealthCheckResponse.status enum value indicating - the status of the service + service: string, the name of the service. NOTE, '' must be set. + status: HealthCheckResponse.status enum value indicating the status of + the service """ - with self._server_status_lock: + 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)) 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 c1d9436c2fa..657ceef1e48 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 @@ -13,6 +13,7 @@ # limitations under the License. """Tests of grpc_health.v1.health.""" +import threading import unittest import grpc @@ -22,21 +23,36 @@ from grpc_health.v1 import health_pb2_grpc from tests.unit import test_common +from six.moves import queue + +_QUEUE_TIMEOUT_S = 5 + +_SERVING_SERVICE = 'grpc.test.TestServiceServing' +_UNKNOWN_SERVICE = 'grpc.test.TestServiceUnknown' +_NOT_SERVING_SERVICE = 'grpc.test.TestServiceNotServing' +_WATCH_SERVICE = 'grpc.test.WatchService' + + +def _consume_responses(response_iterator, response_queue): + for response in response_iterator: + response_queue.put(response) + class HealthServicerTest(unittest.TestCase): def setUp(self): - servicer = health.HealthServicer() - servicer.set('', health_pb2.HealthCheckResponse.SERVING) - servicer.set('grpc.test.TestServiceServing', - health_pb2.HealthCheckResponse.SERVING) - servicer.set('grpc.test.TestServiceUnknown', - health_pb2.HealthCheckResponse.UNKNOWN) - servicer.set('grpc.test.TestServiceNotServing', - health_pb2.HealthCheckResponse.NOT_SERVING) + 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(servicer, self._server) + health_pb2_grpc.add_HealthServicer_to_server(self._servicer, + self._server) self._server.start() self._channel = grpc.insecure_channel('localhost:%d' % port) @@ -46,37 +62,155 @@ class HealthServicerTest(unittest.TestCase): self._server.stop(None) self._channel.close() - def test_empty_service(self): + def test_check_empty_service(self): request = health_pb2.HealthCheckRequest() resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status) - def test_serving_service(self): - request = health_pb2.HealthCheckRequest( - service='grpc.test.TestServiceServing') + def test_check_serving_service(self): + request = health_pb2.HealthCheckRequest(service=_SERVING_SERVICE) resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status) - def test_unknown_serivce(self): - request = health_pb2.HealthCheckRequest( - service='grpc.test.TestServiceUnknown') + def test_check_unknown_serivce(self): + request = health_pb2.HealthCheckRequest(service=_UNKNOWN_SERVICE) resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.UNKNOWN, resp.status) - def test_not_serving_service(self): - request = health_pb2.HealthCheckRequest( - service='grpc.test.TestServiceNotServing') + def test_check_not_serving_service(self): + request = health_pb2.HealthCheckRequest(service=_NOT_SERVING_SERVICE) resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, resp.status) - def test_not_found_service(self): + def test_check_not_found_service(self): request = health_pb2.HealthCheckRequest(service='not-found') with self.assertRaises(grpc.RpcError) as context: resp = self._stub.Check(request) 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=_QUEUE_TIMEOUT_S) + 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=_QUEUE_TIMEOUT_S) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response.status) + + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response.status) + + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.NOT_SERVING) + response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + 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=_QUEUE_TIMEOUT_S) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response.status) + + self._servicer.set('some-other-service', + health_pb2.HealthCheckResponse.SERVING) + with self.assertRaises(queue.Empty) as context: + response_queue.get(timeout=_QUEUE_TIMEOUT_S) + + 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=_QUEUE_TIMEOUT_S) + response2 = response_queue2.get(timeout=_QUEUE_TIMEOUT_S) + 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=_QUEUE_TIMEOUT_S) + response2 = response_queue2.get(timeout=_QUEUE_TIMEOUT_S) + 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=_QUEUE_TIMEOUT_S) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response.status) + + rendezvous.cancel() + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + thread.join() + 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') From b74af8c70bad274c4955a0e242c725409872342d Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 26 Dec 2018 15:04:38 -0800 Subject: [PATCH 0656/2143] skip test with gevent --- src/python/grpcio_tests/commands.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index d5327711d33..582ce898dee 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -141,6 +141,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', + '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', 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels_and_sockets', From e678187996bb7239315f30d9e50734c50ee4027b Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 27 Dec 2018 09:39:53 -0800 Subject: [PATCH 0657/2143] use test constants, fix formatting --- .../grpc_health/v1/health.py | 10 +++---- .../health_check/_health_servicer_test.py | 27 +++++++++---------- 2 files changed, 18 insertions(+), 19 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 75c480b0a7a..0a5bbb5504c 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py @@ -102,11 +102,11 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): def set(self, service, status): """Sets the status of a service. - Args: - service: string, the name of the service. NOTE, '' must be set. - status: HealthCheckResponse.status enum value indicating the status of - the service - """ + Args: + service: string, the name of the service. NOTE, '' must be set. + status: HealthCheckResponse.status enum value indicating the status of + the service + """ with self._lock: self._server_status[service] = status if service in self._watchers: 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 657ceef1e48..bf90fa15c0e 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 @@ -22,11 +22,10 @@ from grpc_health.v1 import health_pb2 from grpc_health.v1 import health_pb2_grpc from tests.unit import test_common +from tests.unit.framework.common import test_constants from six.moves import queue -_QUEUE_TIMEOUT_S = 5 - _SERVING_SERVICE = 'grpc.test.TestServiceServing' _UNKNOWN_SERVICE = 'grpc.test.TestServiceUnknown' _NOT_SERVING_SERVICE = 'grpc.test.TestServiceNotServing' @@ -98,7 +97,7 @@ class HealthServicerTest(unittest.TestCase): target=_consume_responses, args=(rendezvous, response_queue)) thread.start() - response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) self.assertEqual(health_pb2.HealthCheckResponse.SERVING, response.status) @@ -114,19 +113,19 @@ class HealthServicerTest(unittest.TestCase): target=_consume_responses, args=(rendezvous, response_queue)) thread.start() - response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + 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=_QUEUE_TIMEOUT_S) + 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=_QUEUE_TIMEOUT_S) + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, response.status) @@ -142,14 +141,14 @@ class HealthServicerTest(unittest.TestCase): target=_consume_responses, args=(rendezvous, response_queue)) thread.start() - response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + 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) as context: - response_queue.get(timeout=_QUEUE_TIMEOUT_S) + with self.assertRaises(queue.Empty): + response_queue.get(timeout=test_constants.SHORT_TIMEOUT) rendezvous.cancel() thread.join() @@ -168,8 +167,8 @@ class HealthServicerTest(unittest.TestCase): thread1.start() thread2.start() - response1 = response_queue1.get(timeout=_QUEUE_TIMEOUT_S) - response2 = response_queue2.get(timeout=_QUEUE_TIMEOUT_S) + 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, @@ -177,8 +176,8 @@ class HealthServicerTest(unittest.TestCase): self._servicer.set(_WATCH_SERVICE, health_pb2.HealthCheckResponse.SERVING) - response1 = response_queue1.get(timeout=_QUEUE_TIMEOUT_S) - response2 = response_queue2.get(timeout=_QUEUE_TIMEOUT_S) + 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, @@ -199,7 +198,7 @@ class HealthServicerTest(unittest.TestCase): target=_consume_responses, args=(rendezvous, response_queue)) thread.start() - response = response_queue.get(timeout=_QUEUE_TIMEOUT_S) + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, response.status) From e2f3741c7434facf2438197d9865af5679f667bc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Sep 2018 11:53:55 -0700 Subject: [PATCH 0658/2143] Changed podspec templates and Podfile for test --- include/grpc/impl/codegen/port_platform.h | 64 +++++++++++------------ src/objective-c/GRPCClient/GRPCCall.m | 1 + src/objective-c/tests/Podfile | 30 ++--------- templates/gRPC-Core.podspec.template | 11 ++-- templates/gRPC-ProtoRPC.podspec.template | 6 +-- templates/gRPC.podspec.template | 7 +-- 6 files changed, 43 insertions(+), 76 deletions(-) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 031c0c36aef..46d831395da 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -185,38 +185,39 @@ #define _BSD_SOURCE #endif #if TARGET_OS_IPHONE -#define GPR_PLATFORM_STRING "ios" -#define GPR_CPU_IPHONE 1 -#define GPR_PTHREAD_TLS 1 + #define GPR_PLATFORM_STRING "ios" + #define GPR_CPU_IPHONE 1 + #define GPR_PTHREAD_TLS 1 + #define GRPC_CFSTREAM 1 #else /* TARGET_OS_IPHONE */ -#define GPR_PLATFORM_STRING "osx" -#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED -#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 -#define GPR_CPU_IPHONE 1 -#define GPR_PTHREAD_TLS 1 -#else /* __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 */ -#define GPR_CPU_POSIX 1 -/* TODO(vjpai): there is a reported issue in bazel build for Mac where __thread - in a header is currently not working (bazelbuild/bazel#4341). Remove - the following conditional and use GPR_GCC_TLS when that is fixed */ -#ifndef GRPC_BAZEL_BUILD -#define GPR_GCC_TLS 1 -#else /* GRPC_BAZEL_BUILD */ -#define GPR_PTHREAD_TLS 1 -#endif /* GRPC_BAZEL_BUILD */ -#define GPR_APPLE_PTHREAD_NAME 1 -#endif -#else /* __MAC_OS_X_VERSION_MIN_REQUIRED */ -#define GPR_CPU_POSIX 1 -/* TODO(vjpai): Remove the following conditional and use only GPR_GCC_TLS - when bazelbuild/bazel#4341 is fixed */ -#ifndef GRPC_BAZEL_BUILD -#define GPR_GCC_TLS 1 -#else /* GRPC_BAZEL_BUILD */ -#define GPR_PTHREAD_TLS 1 -#endif /* GRPC_BAZEL_BUILD */ -#endif -#define GPR_POSIX_CRASH_HANDLER 1 + #define GPR_PLATFORM_STRING "osx" + #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED + #if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 + #define GPR_CPU_IPHONE 1 + #define GPR_PTHREAD_TLS 1 + #else /* __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 */ + #define GPR_CPU_POSIX 1 + /* TODO(vjpai): there is a reported issue in bazel build for Mac where __thread + in a header is currently not working (bazelbuild/bazel#4341). Remove + the following conditional and use GPR_GCC_TLS when that is fixed */ + #ifndef GRPC_BAZEL_BUILD + #define GPR_GCC_TLS 1 + #else /* GRPC_BAZEL_BUILD */ + #define GPR_PTHREAD_TLS 1 + #endif /* GRPC_BAZEL_BUILD */ + #define GPR_APPLE_PTHREAD_NAME 1 + #endif + #else /* __MAC_OS_X_VERSION_MIN_REQUIRED */ + #define GPR_CPU_POSIX 1 + /* TODO(vjpai): Remove the following conditional and use only GPR_GCC_TLS + when bazelbuild/bazel#4341 is fixed */ + #ifndef GRPC_BAZEL_BUILD + #define GPR_GCC_TLS 1 + #else /* GRPC_BAZEL_BUILD */ + #define GPR_PTHREAD_TLS 1 + #endif /* GRPC_BAZEL_BUILD */ + #endif + #define GPR_POSIX_CRASH_HANDLER 1 #endif #define GPR_APPLE 1 #define GPR_GCC_ATOMIC 1 @@ -228,7 +229,6 @@ #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 #define GPR_GETPID_IN_UNISTD_H 1 -/* TODO(mxyan): Remove when CFStream becomes default */ #ifndef GRPC_CFSTREAM #define GPR_SUPPORT_CHANNELS_FROM_FD 1 #endif diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 084fbdeb491..5a6b13d75b0 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -121,6 +121,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Guarantees the code in {} block is invoked only once. See ref at: // https://developer.apple.com/documentation/objectivec/nsobject/1418639-initialize?language=objc if (self == [GRPCCall self]) { + setenv(kCFStreamVarName, "1", 1); grpc_init(); callFlags = [NSMutableDictionary dictionary]; } diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 5d2f1340daa..bc0ba2f2b75 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -15,6 +15,9 @@ GRPC_LOCAL_SRC = '../../..' InteropTestsLocalCleartext InteropTestsRemoteWithCronet UnitTests + InteropTestsRemoteCFStream + InteropTestsLocalSSLCFStream + InteropTestsLocalCleartextCFStream ).each do |target_name| target target_name do pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true @@ -37,27 +40,6 @@ GRPC_LOCAL_SRC = '../../..' end end -%w( - InteropTestsRemoteCFStream - InteropTestsLocalSSLCFStream - InteropTestsLocalCleartextCFStream -).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/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 => "RemoteTestClient", :inhibit_warnings => true - end -end - %w( CoreCronetEnd2EndTests CronetUnitTests @@ -118,11 +100,7 @@ post_install do |installer| # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void # function" warning config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO' - if target.name.include?('CFStream') - config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CFSTREAM=1' - else - config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1' - end + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1' end end diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 461e8b767ff..91726ab03da 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -179,19 +179,14 @@ ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS' # To save you from scrolling, this is the last part of the podspec. - ss.source_files = ${ruby_multiline_list(grpc_private_files(libs), 22)} + ss.source_files = ${ruby_multiline_list(grpc_private_files(libs) + cfstream_private_files(filegroups), 22)} - ss.private_header_files = ${ruby_multiline_list(grpc_private_headers(libs), 30)} + ss.private_header_files = ${ruby_multiline_list(grpc_private_headers(libs) + cfstream_private_headers(filegroups), 30)} end + # CFStream is now default. Leaving this subspec only for compatibility purpose. s.subspec 'CFStream-Implementation' do |ss| - ss.header_mappings_dir = '.' ss.dependency "#{s.name}/Implementation", version - ss.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1' - } - ss.source_files = ${ruby_multiline_list(cfstream_private_files(filegroups), 22)} - ss.private_header_files = ${ruby_multiline_list(cfstream_private_headers(filegroups), 30)} end s.subspec 'Cronet-Interface' do |ss| diff --git a/templates/gRPC-ProtoRPC.podspec.template b/templates/gRPC-ProtoRPC.podspec.template index 96966784f18..cfc4b60b2eb 100644 --- a/templates/gRPC-ProtoRPC.podspec.template +++ b/templates/gRPC-ProtoRPC.podspec.template @@ -54,12 +54,10 @@ ss.source_files = "#{src_dir}/*.{h,m}" end + + # CFStream is now default. Leaving this subspec only for compatibility purpose. s.subspec 'CFStream' do |ss| - ss.dependency 'gRPC/CFStream', version ss.dependency "#{s.name}/Main", version - ss.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1' - } end s.pod_target_xcconfig = { diff --git a/templates/gRPC.podspec.template b/templates/gRPC.podspec.template index a3190c2d8e6..c8054e1d1d0 100644 --- a/templates/gRPC.podspec.template +++ b/templates/gRPC.podspec.template @@ -65,14 +65,9 @@ ss.dependency 'gRPC-Core', version end - # This subspec is mutually exclusive with the `Main` subspec + # CFStream is now default. Leaving this subspec only for compatibility purpose. s.subspec 'CFStream' do |ss| - ss.dependency 'gRPC-Core/CFStream-Implementation', version ss.dependency "#{s.name}/Main", version - - ss.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1' - } end s.subspec 'GID' do |ss| From acf3a72e243a37b68f4c0da7e72d61a62127ba75 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Dec 2018 13:46:53 -0800 Subject: [PATCH 0659/2143] CFStream use serial dispatch queue --- src/core/lib/iomgr/cfstream_handle.cc | 98 ++++++++++++--------------- src/core/lib/iomgr/cfstream_handle.h | 2 + 2 files changed, 46 insertions(+), 54 deletions(-) diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index 827fd24831e..bb402f96cf5 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -52,62 +52,53 @@ CFStreamHandle* CFStreamHandle::CreateStreamHandle( void CFStreamHandle::ReadCallback(CFReadStreamRef stream, CFStreamEventType type, void* client_callback_info) { + grpc_core::ExecCtx exec_ctx; CFStreamHandle* handle = static_cast(client_callback_info); - CFSTREAM_HANDLE_REF(handle, "read callback"); - dispatch_async( - dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - grpc_core::ExecCtx exec_ctx; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_DEBUG, "CFStream ReadCallback (%p, %p, %lu, %p)", handle, - stream, type, client_callback_info); - } - switch (type) { - case kCFStreamEventOpenCompleted: - handle->open_event_.SetReady(); - break; - case kCFStreamEventHasBytesAvailable: - case kCFStreamEventEndEncountered: - handle->read_event_.SetReady(); - break; - case kCFStreamEventErrorOccurred: - handle->open_event_.SetReady(); - handle->read_event_.SetReady(); - break; - default: - GPR_UNREACHABLE_CODE(return ); - } - CFSTREAM_HANDLE_UNREF(handle, "read callback"); - }); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_DEBUG, "CFStream ReadCallback (%p, %p, %lu, %p)", handle, + stream, type, client_callback_info); + } + switch (type) { + case kCFStreamEventOpenCompleted: + handle->open_event_.SetReady(); + break; + case kCFStreamEventHasBytesAvailable: + case kCFStreamEventEndEncountered: + handle->read_event_.SetReady(); + break; + case kCFStreamEventErrorOccurred: + handle->open_event_.SetReady(); + handle->read_event_.SetReady(); + break; + default: + GPR_UNREACHABLE_CODE(return ); + } } void CFStreamHandle::WriteCallback(CFWriteStreamRef stream, CFStreamEventType type, void* clientCallBackInfo) { + grpc_core::ExecCtx exec_ctx; CFStreamHandle* handle = static_cast(clientCallBackInfo); - CFSTREAM_HANDLE_REF(handle, "write callback"); - dispatch_async( - dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - grpc_core::ExecCtx exec_ctx; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_DEBUG, "CFStream WriteCallback (%p, %p, %lu, %p)", handle, - stream, type, clientCallBackInfo); - } - switch (type) { - case kCFStreamEventOpenCompleted: - handle->open_event_.SetReady(); - break; - case kCFStreamEventCanAcceptBytes: - case kCFStreamEventEndEncountered: - handle->write_event_.SetReady(); - break; - case kCFStreamEventErrorOccurred: - handle->open_event_.SetReady(); - handle->write_event_.SetReady(); - break; - default: - GPR_UNREACHABLE_CODE(return ); - } - CFSTREAM_HANDLE_UNREF(handle, "write callback"); - }); + printf("** CFStreamHandle::WriteCallback\n"); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_DEBUG, "CFStream WriteCallback (%p, %p, %lu, %p)", handle, + stream, type, clientCallBackInfo); + } + switch (type) { + case kCFStreamEventOpenCompleted: + handle->open_event_.SetReady(); + break; + case kCFStreamEventCanAcceptBytes: + case kCFStreamEventEndEncountered: + handle->write_event_.SetReady(); + break; + case kCFStreamEventErrorOccurred: + handle->open_event_.SetReady(); + handle->write_event_.SetReady(); + break; + default: + GPR_UNREACHABLE_CODE(return ); + } } CFStreamHandle::CFStreamHandle(CFReadStreamRef read_stream, @@ -116,6 +107,7 @@ CFStreamHandle::CFStreamHandle(CFReadStreamRef read_stream, open_event_.InitEvent(); read_event_.InitEvent(); write_event_.InitEvent(); + dispatch_queue_ = dispatch_queue_create(nullptr, DISPATCH_QUEUE_SERIAL); CFStreamClientContext ctx = {0, static_cast(this), CFStreamHandle::Retain, CFStreamHandle::Release, nil}; @@ -129,10 +121,8 @@ CFStreamHandle::CFStreamHandle(CFReadStreamRef read_stream, kCFStreamEventOpenCompleted | kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, CFStreamHandle::WriteCallback, &ctx); - CFReadStreamScheduleWithRunLoop(read_stream, CFRunLoopGetMain(), - kCFRunLoopCommonModes); - CFWriteStreamScheduleWithRunLoop(write_stream, CFRunLoopGetMain(), - kCFRunLoopCommonModes); + CFReadStreamSetDispatchQueue(read_stream, dispatch_queue_); + CFWriteStreamSetDispatchQueue(write_stream, dispatch_queue_); } CFStreamHandle::~CFStreamHandle() { diff --git a/src/core/lib/iomgr/cfstream_handle.h b/src/core/lib/iomgr/cfstream_handle.h index 4258e72431c..93ec5f044bb 100644 --- a/src/core/lib/iomgr/cfstream_handle.h +++ b/src/core/lib/iomgr/cfstream_handle.h @@ -62,6 +62,8 @@ class CFStreamHandle final { grpc_core::LockfreeEvent read_event_; grpc_core::LockfreeEvent write_event_; + dispatch_queue_t dispatch_queue_; + gpr_refcount refcount_; }; From a7643b1f424aac7481a0f7db615cc24d36724736 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 27 Dec 2018 11:40:17 -0800 Subject: [PATCH 0660/2143] build projects --- gRPC-Core.podspec | 35 ++++++++++++++++------------------- gRPC-ProtoRPC.podspec | 6 ++---- gRPC.podspec | 7 +------ 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f873bc693bc..b5b8aef2225 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -846,7 +846,15 @@ Pod::Spec.new do |s| 'src/core/ext/filters/http/client_authority_filter.cc', 'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc', 'src/core/ext/filters/workarounds/workaround_utils.cc', - 'src/core/plugin_registry/grpc_plugin_registry.cc' + 'src/core/plugin_registry/grpc_plugin_registry.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', + 'src/core/lib/iomgr/endpoint_cfstream.cc', + 'src/core/lib/iomgr/error_cfstream.cc', + 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', + 'src/core/lib/iomgr/tcp_client_cfstream.cc', + 'src/core/lib/iomgr/cfstream_handle.h', + 'src/core/lib/iomgr/endpoint_cfstream.h', + 'src/core/lib/iomgr/error_cfstream.h' ss.private_header_files = 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', @@ -1148,28 +1156,17 @@ Pod::Spec.new do |s| 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', 'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h', - 'src/core/ext/filters/workarounds/workaround_utils.h' - end - - s.subspec 'CFStream-Implementation' do |ss| - ss.header_mappings_dir = '.' - ss.dependency "#{s.name}/Implementation", version - ss.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1' - } - ss.source_files = 'src/core/lib/iomgr/cfstream_handle.cc', - 'src/core/lib/iomgr/endpoint_cfstream.cc', - 'src/core/lib/iomgr/error_cfstream.cc', - 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', - 'src/core/lib/iomgr/tcp_client_cfstream.cc', - 'src/core/lib/iomgr/cfstream_handle.h', - 'src/core/lib/iomgr/endpoint_cfstream.h', - 'src/core/lib/iomgr/error_cfstream.h' - ss.private_header_files = 'src/core/lib/iomgr/cfstream_handle.h', + 'src/core/ext/filters/workarounds/workaround_utils.h', + 'src/core/lib/iomgr/cfstream_handle.h', 'src/core/lib/iomgr/endpoint_cfstream.h', 'src/core/lib/iomgr/error_cfstream.h' end + # CFStream is now default. Leaving this subspec only for compatibility purpose. + s.subspec 'CFStream-Implementation' do |ss| + ss.dependency "#{s.name}/Implementation", version + end + s.subspec 'Cronet-Interface' do |ss| ss.header_mappings_dir = 'include/grpc' ss.source_files = 'include/grpc/grpc_cronet.h' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 13fe3e0b9c0..d27df2d30b7 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -52,12 +52,10 @@ Pod::Spec.new do |s| ss.source_files = "#{src_dir}/*.{h,m}" end + + # CFStream is now default. Leaving this subspec only for compatibility purpose. s.subspec 'CFStream' do |ss| - ss.dependency 'gRPC/CFStream', version ss.dependency "#{s.name}/Main", version - ss.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1' - } end s.pod_target_xcconfig = { diff --git a/gRPC.podspec b/gRPC.podspec index 940a1ac6217..ddc32da6261 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -63,14 +63,9 @@ Pod::Spec.new do |s| ss.dependency 'gRPC-Core', version end - # This subspec is mutually exclusive with the `Main` subspec + # CFStream is now default. Leaving this subspec only for compatibility purpose. s.subspec 'CFStream' do |ss| - ss.dependency 'gRPC-Core/CFStream-Implementation', version ss.dependency "#{s.name}/Main", version - - ss.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1' - } end s.subspec 'GID' do |ss| From 4e3e46df2249bbd6ba8f3330c0a44ca508d0f35c Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 27 Dec 2018 11:53:54 -0800 Subject: [PATCH 0661/2143] fix test --- src/python/grpcio_tests/tests/health_check/BUILD.bazel | 1 + .../tests/health_check/_health_servicer_test.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/python/grpcio_tests/tests/health_check/BUILD.bazel b/src/python/grpcio_tests/tests/health_check/BUILD.bazel index 19e1e1b2e1e..77bc61aa30e 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/framework/common:common", ], imports = ["../../",], ) 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 bf90fa15c0e..35794987bc8 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 @@ -14,6 +14,7 @@ """Tests of grpc_health.v1.health.""" import threading +import time import unittest import grpc @@ -206,6 +207,11 @@ class HealthServicerTest(unittest.TestCase): 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()) From 80f005ee8fe33c21debbe0af1e976ff96d8bf0cf Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 27 Dec 2018 13:46:52 -0800 Subject: [PATCH 0662/2143] Remove debug info; clang-format --- BUILD | 28 +++------- include/grpc/impl/codegen/port_platform.h | 64 +++++++++++------------ src/core/lib/iomgr/cfstream_handle.cc | 1 - 3 files changed, 40 insertions(+), 53 deletions(-) diff --git a/BUILD b/BUILD index e3c765198b2..b8abce38072 100644 --- a/BUILD +++ b/BUILD @@ -706,12 +706,15 @@ grpc_cc_library( "src/core/lib/http/parser.cc", "src/core/lib/iomgr/buffer_list.cc", "src/core/lib/iomgr/call_combiner.cc", + "src/core/lib/iomgr/cfstream_handle.cc", "src/core/lib/iomgr/combiner.cc", "src/core/lib/iomgr/endpoint.cc", + "src/core/lib/iomgr/endpoint_cfstream.cc", "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_cfstream.cc", "src/core/lib/iomgr/ev_epoll1_linux.cc", "src/core/lib/iomgr/ev_epollex_linux.cc", "src/core/lib/iomgr/ev_poll_posix.cc", @@ -730,6 +733,7 @@ grpc_cc_library( "src/core/lib/iomgr/iomgr_custom.cc", "src/core/lib/iomgr/iomgr_internal.cc", "src/core/lib/iomgr/iomgr_posix.cc", + "src/core/lib/iomgr/iomgr_posix_cfstream.cc", "src/core/lib/iomgr/iomgr_windows.cc", "src/core/lib/iomgr/is_epollexclusive_available.cc", "src/core/lib/iomgr/load_file.cc", @@ -757,6 +761,7 @@ grpc_cc_library( "src/core/lib/iomgr/socket_utils_windows.cc", "src/core/lib/iomgr/socket_windows.cc", "src/core/lib/iomgr/tcp_client.cc", + "src/core/lib/iomgr/tcp_client_cfstream.cc", "src/core/lib/iomgr/tcp_client_custom.cc", "src/core/lib/iomgr/tcp_client_posix.cc", "src/core/lib/iomgr/tcp_client_windows.cc", @@ -858,12 +863,15 @@ grpc_cc_library( "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/cfstream_handle.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_cfstream.h", "src/core/lib/iomgr/endpoint_pair.h", "src/core/lib/iomgr/error.h", + "src/core/lib/iomgr/error_cfstream.h", "src/core/lib/iomgr/error_internal.h", "src/core/lib/iomgr/ev_epoll1_linux.h", "src/core/lib/iomgr/ev_epollex_linux.h", @@ -1018,26 +1026,6 @@ grpc_cc_library( ], ) -grpc_cc_library( - name = "grpc_cfstream", - srcs = [ - "src/core/lib/iomgr/cfstream_handle.cc", - "src/core/lib/iomgr/endpoint_cfstream.cc", - "src/core/lib/iomgr/error_cfstream.cc", - "src/core/lib/iomgr/iomgr_posix_cfstream.cc", - "src/core/lib/iomgr/tcp_client_cfstream.cc", - ], - hdrs = [ - "src/core/lib/iomgr/cfstream_handle.h", - "src/core/lib/iomgr/endpoint_cfstream.h", - "src/core/lib/iomgr/error_cfstream.h", - ], - deps = [ - ":gpr_base", - ":grpc_base", - ], -) - grpc_cc_library( name = "grpc_client_channel", srcs = [ diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 46d831395da..21253db01e4 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -185,39 +185,39 @@ #define _BSD_SOURCE #endif #if TARGET_OS_IPHONE - #define GPR_PLATFORM_STRING "ios" - #define GPR_CPU_IPHONE 1 - #define GPR_PTHREAD_TLS 1 - #define GRPC_CFSTREAM 1 +#define GPR_PLATFORM_STRING "ios" +#define GPR_CPU_IPHONE 1 +#define GPR_PTHREAD_TLS 1 +#define GRPC_CFSTREAM 1 #else /* TARGET_OS_IPHONE */ - #define GPR_PLATFORM_STRING "osx" - #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED - #if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 - #define GPR_CPU_IPHONE 1 - #define GPR_PTHREAD_TLS 1 - #else /* __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 */ - #define GPR_CPU_POSIX 1 - /* TODO(vjpai): there is a reported issue in bazel build for Mac where __thread - in a header is currently not working (bazelbuild/bazel#4341). Remove - the following conditional and use GPR_GCC_TLS when that is fixed */ - #ifndef GRPC_BAZEL_BUILD - #define GPR_GCC_TLS 1 - #else /* GRPC_BAZEL_BUILD */ - #define GPR_PTHREAD_TLS 1 - #endif /* GRPC_BAZEL_BUILD */ - #define GPR_APPLE_PTHREAD_NAME 1 - #endif - #else /* __MAC_OS_X_VERSION_MIN_REQUIRED */ - #define GPR_CPU_POSIX 1 - /* TODO(vjpai): Remove the following conditional and use only GPR_GCC_TLS - when bazelbuild/bazel#4341 is fixed */ - #ifndef GRPC_BAZEL_BUILD - #define GPR_GCC_TLS 1 - #else /* GRPC_BAZEL_BUILD */ - #define GPR_PTHREAD_TLS 1 - #endif /* GRPC_BAZEL_BUILD */ - #endif - #define GPR_POSIX_CRASH_HANDLER 1 +#define GPR_PLATFORM_STRING "osx" +#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED +#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 +#define GPR_CPU_IPHONE 1 +#define GPR_PTHREAD_TLS 1 +#else /* __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 */ +#define GPR_CPU_POSIX 1 +/* TODO(vjpai): there is a reported issue in bazel build for Mac where __thread + in a header is currently not working (bazelbuild/bazel#4341). Remove + the following conditional and use GPR_GCC_TLS when that is fixed */ +#ifndef GRPC_BAZEL_BUILD +#define GPR_GCC_TLS 1 +#else /* GRPC_BAZEL_BUILD */ +#define GPR_PTHREAD_TLS 1 +#endif /* GRPC_BAZEL_BUILD */ +#define GPR_APPLE_PTHREAD_NAME 1 +#endif +#else /* __MAC_OS_X_VERSION_MIN_REQUIRED */ +#define GPR_CPU_POSIX 1 +/* TODO(vjpai): Remove the following conditional and use only GPR_GCC_TLS + when bazelbuild/bazel#4341 is fixed */ +#ifndef GRPC_BAZEL_BUILD +#define GPR_GCC_TLS 1 +#else /* GRPC_BAZEL_BUILD */ +#define GPR_PTHREAD_TLS 1 +#endif /* GRPC_BAZEL_BUILD */ +#endif +#define GPR_POSIX_CRASH_HANDLER 1 #endif #define GPR_APPLE 1 #define GPR_GCC_ATOMIC 1 diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index bb402f96cf5..6cb9ca1a0d4 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -79,7 +79,6 @@ void CFStreamHandle::WriteCallback(CFWriteStreamRef stream, void* clientCallBackInfo) { grpc_core::ExecCtx exec_ctx; CFStreamHandle* handle = static_cast(clientCallBackInfo); - printf("** CFStreamHandle::WriteCallback\n"); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_DEBUG, "CFStream WriteCallback (%p, %p, %lu, %p)", handle, stream, type, clientCallBackInfo); From dd4830eae80143f5b0a9a3a1a024af4cf60e7d02 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 21 Dec 2018 13:44:20 -0800 Subject: [PATCH 0663/2143] Make gRPC version string available as grpc.__version__ --- doc/python/sphinx/grpc.rst | 5 ++++ src/python/grpcio/grpc/__init__.py | 5 ++++ src/python/grpcio_tests/tests/tests.json | 1 + .../grpcio_tests/tests/unit/BUILD.bazel | 1 + .../grpcio_tests/tests/unit/_version_test.py | 30 +++++++++++++++++++ 5 files changed, 42 insertions(+) create mode 100644 src/python/grpcio_tests/tests/unit/_version_test.py diff --git a/doc/python/sphinx/grpc.rst b/doc/python/sphinx/grpc.rst index bd2df9596b0..f534d25c639 100644 --- a/doc/python/sphinx/grpc.rst +++ b/doc/python/sphinx/grpc.rst @@ -19,6 +19,11 @@ Go to `gRPC Python Examples Date: Thu, 27 Dec 2018 15:21:12 -0800 Subject: [PATCH 0664/2143] Free grpc_channel_args after creation --- .../grpc/_cython/_cygrpc/arguments.pxd.pxi | 13 ++++--- .../grpc/_cython/_cygrpc/arguments.pyx.pxi | 35 +++++++++++-------- .../grpc/_cython/_cygrpc/channel.pyx.pxi | 9 +++-- .../grpc/_cython/_cygrpc/server.pxd.pxi | 1 - .../grpc/_cython/_cygrpc/server.pyx.pxi | 8 ++--- 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi index e0e068e4524..01b82374845 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi @@ -28,19 +28,22 @@ cdef tuple _wrap_grpc_arg(grpc_arg arg) cdef grpc_arg _unwrap_grpc_arg(tuple wrapped_arg) -cdef class _ArgumentProcessor: +cdef class _ChannelArg: cdef grpc_arg c_argument cdef void c(self, argument, grpc_arg_pointer_vtable *vtable, references) except * -cdef class _ArgumentsProcessor: +cdef class _ChannelArgs: cdef readonly tuple _arguments - cdef list _argument_processors + cdef list _channel_args cdef readonly list _references cdef grpc_channel_args _c_arguments - cdef grpc_channel_args *c(self, grpc_arg_pointer_vtable *vtable) except * - cdef un_c(self) + 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 b7a4277ff64..bf12871015d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi @@ -50,7 +50,7 @@ cdef grpc_arg _unwrap_grpc_arg(tuple wrapped_arg): return wrapped.arg -cdef class _ArgumentProcessor: +cdef class _ChannelArg: cdef void c(self, argument, grpc_arg_pointer_vtable *vtable, references) except *: key, value = argument @@ -82,27 +82,34 @@ cdef class _ArgumentProcessor: 'Expected int, bytes, or behavior, got {}'.format(type(value))) -cdef class _ArgumentsProcessor: +cdef class _ChannelArgs: def __cinit__(self, arguments): self._arguments = () if arguments is None else tuple(arguments) - self._argument_processors = [] + self._channel_args = [] self._references = [] + self._c_arguments.arguments = NULL - cdef grpc_channel_args *c(self, grpc_arg_pointer_vtable *vtable) except *: + 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: - return NULL - else: + if self._c_arguments.arguments_length != 0: self._c_arguments.arguments = gpr_malloc( self._c_arguments.arguments_length * sizeof(grpc_arg)) for index, argument in enumerate(self._arguments): - argument_processor = _ArgumentProcessor() - argument_processor.c(argument, vtable, self._references) - self._c_arguments.arguments[index] = argument_processor.c_argument - self._argument_processors.append(argument_processor) - return &self._c_arguments + channel_arg = _ChannelArg() + channel_arg.c(argument, vtable, self._references) + self._c_arguments.arguments[index] = channel_arg.c_argument + self._channel_args.append(channel_arg) - cdef un_c(self): - if self._arguments: + cdef grpc_channel_args *c_args(self) except *: + return &self._c_arguments + + 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/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index 135d224095e..70d4abb7308 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -423,16 +423,15 @@ cdef class Channel: self._vtable.copy = &_copy_pointer self._vtable.destroy = &_destroy_pointer self._vtable.cmp = &_compare_pointer - cdef _ArgumentsProcessor arguments_processor = _ArgumentsProcessor( - arguments) - cdef grpc_channel_args *c_arguments = arguments_processor.c(&self._vtable) + cdef _ChannelArgs channel_args = _ChannelArgs.from_args( + arguments, &self._vtable) if channel_credentials is None: self._state.c_channel = grpc_insecure_channel_create( - target, c_arguments, NULL) + target, channel_args.c_args(), NULL) else: c_channel_credentials = channel_credentials.c() self._state.c_channel = grpc_secure_channel_create( - c_channel_credentials, target, c_arguments, NULL) + 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)) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi index 52cfccb6779..4a6fbe0f96c 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi @@ -16,7 +16,6 @@ cdef class Server: cdef grpc_arg_pointer_vtable _vtable - cdef readonly _ArgumentsProcessor _arguments_processor cdef grpc_server *c_server cdef bint is_started # start has been called cdef bint is_shutting_down # shutdown has been called diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index e89e02b171e..d72648a35d0 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -29,11 +29,9 @@ cdef class Server: self._vtable.copy = &_copy_pointer self._vtable.destroy = &_destroy_pointer self._vtable.cmp = &_compare_pointer - cdef _ArgumentsProcessor arguments_processor = _ArgumentsProcessor( - arguments) - cdef grpc_channel_args *c_arguments = arguments_processor.c(&self._vtable) - self.c_server = grpc_server_create(c_arguments, NULL) - arguments_processor.un_c() + 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 From aecc5f7285faedec634c99aff0b48eea86d3861a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 28 Dec 2018 16:03:20 -0800 Subject: [PATCH 0665/2143] Add client interceptor test for bidi streaming hijacking interceptor --- .../client_interceptors_end2end_test.cc | 91 +++++++++++++++++++ test/cpp/end2end/interceptors_util.cc | 10 ++ test/cpp/end2end/interceptors_util.h | 3 + 3 files changed, 104 insertions(+) diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 8abf4eb3f49..ab387aa9144 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -270,6 +270,84 @@ class HijackingInterceptorMakesAnotherCallFactory } }; +class BidiStreamingRpcHijackingInterceptor : public experimental::Interceptor { + public: + BidiStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) { + info_ = info; + } + + virtual void Intercept(experimental::InterceptorBatchMethods* methods) { + bool hijack = false; + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { + CheckMetadata(*methods->GetSendInitialMetadata(), "testkey", "testvalue"); + hijack = true; + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + EchoRequest req; + auto* buffer = methods->GetSendMessage(); + auto copied_buffer = *buffer; + EXPECT_TRUE( + SerializationTraits::Deserialize(&copied_buffer, &req) + .ok()); + EXPECT_EQ(req.message().find("Hello"), 0); + msg = req.message(); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { + // Got nothing to do here for now + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_RECV_STATUS)) { + CheckMetadata(*methods->GetRecvTrailingMetadata(), "testkey", + "testvalue"); + auto* status = methods->GetRecvStatus(); + EXPECT_EQ(status->ok(), true); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { + EchoResponse* resp = + static_cast(methods->GetRecvMessage()); + resp->set_message(msg); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { + EXPECT_EQ(static_cast(methods->GetRecvMessage()) + ->message() + .find("Hello"), + 0); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { + auto* map = methods->GetRecvTrailingMetadata(); + // insert the metadata that we want + EXPECT_EQ(map->size(), static_cast(0)); + map->insert(std::make_pair("testkey", "testvalue")); + auto* status = methods->GetRecvStatus(); + *status = Status(StatusCode::OK, ""); + } + if (hijack) { + methods->Hijack(); + } else { + methods->Proceed(); + } + } + + private: + experimental::ClientRpcInfo* info_; + grpc::string msg; +}; + +class BidiStreamingRpcHijackingInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return new BidiStreamingRpcHijackingInterceptor(info); + } +}; + class LoggingInterceptor : public experimental::Interceptor { public: LoggingInterceptor(experimental::ClientRpcInfo* info) { info_ = info; } @@ -546,6 +624,19 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) { EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } +TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingHijackingTest) { + ChannelArguments args; + DummyInterceptor::Reset(); + std::vector> + creators; + creators.push_back( + std::unique_ptr( + new BidiStreamingRpcHijackingInterceptorFactory())); + auto channel = experimental::CreateCustomChannelWithInterceptors( + server_address_, InsecureChannelCredentials(), args, std::move(creators)); + MakeBidiStreamingCall(channel); +} + TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); diff --git a/test/cpp/end2end/interceptors_util.cc b/test/cpp/end2end/interceptors_util.cc index e0ad7d1526c..900f02b5f36 100644 --- a/test/cpp/end2end/interceptors_util.cc +++ b/test/cpp/end2end/interceptors_util.cc @@ -132,6 +132,16 @@ bool CheckMetadata(const std::multimap& map, return false; } +bool CheckMetadata(const std::multimap& map, + const string& key, const string& value) { + for (const auto& pair : map) { + if (pair.first == key && pair.second == value) { + return true; + } + } + return false; +} + std::vector> CreateDummyClientInterceptors() { std::vector> diff --git a/test/cpp/end2end/interceptors_util.h b/test/cpp/end2end/interceptors_util.h index 659e613d2eb..419845e5f61 100644 --- a/test/cpp/end2end/interceptors_util.h +++ b/test/cpp/end2end/interceptors_util.h @@ -165,6 +165,9 @@ void MakeCallbackCall(const std::shared_ptr& channel); bool CheckMetadata(const std::multimap& map, const string& key, const string& value); +bool CheckMetadata(const std::multimap& map, + const string& key, const string& value); + std::vector> CreateDummyClientInterceptors(); From 4aeba4252893755ff13b2cc0edfcc954c6d04a6b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 28 Dec 2018 17:27:38 -0800 Subject: [PATCH 0666/2143] Provide GetOriginalSendMessage for some APIs --- include/grpcpp/impl/codegen/call_op_set.h | 29 +++++++++++++++++-- include/grpcpp/impl/codegen/client_callback.h | 6 ++-- .../grpcpp/impl/codegen/client_unary_call.h | 2 +- include/grpcpp/impl/codegen/interceptor.h | 6 ++++ .../grpcpp/impl/codegen/interceptor_common.h | 16 +++++++++- include/grpcpp/impl/codegen/server_callback.h | 8 ++--- include/grpcpp/impl/codegen/sync_stream.h | 10 +++---- .../client_interceptors_end2end_test.cc | 5 ++++ 8 files changed, 66 insertions(+), 16 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index b2100c68b7f..ddee5280cb3 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -303,6 +303,18 @@ class CallOpSendMessage { template Status SendMessage(const M& message) GRPC_MUST_USE_RESULT; + /// Send \a message using \a options for the write. The \a options are cleared + /// after use. This form of SendMessage allows gRPC to reference \a message + /// beyond the lifetime of SendMessage. + template + Status SendMessage(const M* message, + WriteOptions options) GRPC_MUST_USE_RESULT; + + /// This form of SendMessage allows gRPC to reference \a message beyond the + /// lifetime of SendMessage. + template + Status SendMessage(const M* message) GRPC_MUST_USE_RESULT; + protected: void AddOp(grpc_op* ops, size_t* nops) { if (!send_buf_.Valid() || hijacked_) return; @@ -321,14 +333,14 @@ class CallOpSendMessage { if (!send_buf_.Valid()) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE); - interceptor_methods->SetSendMessage(&send_buf_); + interceptor_methods->SetSendMessage(&send_buf_, msg_); } void SetFinishInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { // The contents of the SendMessage value that was previously set // has had its references stolen by core's operations - interceptor_methods->SetSendMessage(nullptr); + interceptor_methods->SetSendMessage(nullptr, nullptr); } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { @@ -336,6 +348,7 @@ class CallOpSendMessage { } private: + const void* msg_ = nullptr; // The original non-serialized message bool hijacked_ = false; ByteBuffer send_buf_; WriteOptions write_options_; @@ -362,6 +375,18 @@ Status CallOpSendMessage::SendMessage(const M& message) { return SendMessage(message, WriteOptions()); } +template +Status CallOpSendMessage::SendMessage(const M* message, WriteOptions options) { + msg_ = message; + return SendMessage(*message, options); +} + +template +Status CallOpSendMessage::SendMessage(const M* message) { + msg_ = message; + return SendMessage(*message, WriteOptions()); +} + template class CallOpRecvMessage { public: diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 66cf9b7754c..f164db19ec7 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -73,7 +73,7 @@ class CallbackUnaryCallImpl { CallbackWithStatusTag(call.call(), on_completion, ops); // TODO(vjpai): Unify code with sync API as much as possible - Status s = ops->SendMessage(*request); + Status s = ops->SendMessage(request); if (!s.ok()) { tag->force_run(s); return; @@ -341,7 +341,7 @@ class ClientCallbackReaderWriterImpl start_corked_ = false; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*msg).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); if (options.is_last_message()) { options.set_buffer_hint(); @@ -650,7 +650,7 @@ class ClientCallbackWriterImpl start_corked_ = false; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*msg).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); if (options.is_last_message()) { options.set_buffer_hint(); diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index 5151839412b..f34da234824 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -57,7 +57,7 @@ class BlockingUnaryCallImpl { CallOpRecvInitialMetadata, CallOpRecvMessage, CallOpClientSendClose, CallOpClientRecvStatus> ops; - status_ = ops.SendMessage(request); + status_ = ops.SendMessage(&request); if (!status_.ok()) { return; } diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 46175cd73b8..a83d285d130 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -111,6 +111,12 @@ class InterceptorBatchMethods { /// A return value of nullptr indicates that this ByteBuffer is not valid. virtual ByteBuffer* GetSendMessage() = 0; + /// Returns a non-modifiable pointer to the original non-serialized form of + /// the message. 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. + virtual const void* GetOriginalSendMessage() = 0; + /// Returns a modifiable multimap of the initial metadata to be sent. Valid /// for PRE_SEND_INITIAL_METADATA interceptions. A value of nullptr indicates /// that this field is not valid. diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index d0aa23cb0a0..bf936368d4c 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -81,6 +81,8 @@ class InterceptorBatchMethodsImpl ByteBuffer* GetSendMessage() override { return send_message_; } + const void* GetOriginalSendMessage() override { return orig_send_message_; } + std::multimap* GetSendInitialMetadata() override { return send_initial_metadata_; } @@ -115,7 +117,10 @@ class InterceptorBatchMethodsImpl return recv_trailing_metadata_->map(); } - void SetSendMessage(ByteBuffer* buf) { send_message_ = buf; } + void SetSendMessage(ByteBuffer* buf, const void* msg) { + send_message_ = buf; + orig_send_message_ = msg; + } void SetSendInitialMetadata( std::multimap* metadata) { @@ -334,6 +339,7 @@ class InterceptorBatchMethodsImpl std::function callback_; ByteBuffer* send_message_ = nullptr; + const void* orig_send_message_ = nullptr; std::multimap* send_initial_metadata_; @@ -386,6 +392,14 @@ class CancelInterceptorBatchMethods return nullptr; } + const void* GetOriginalSendMessage() override { + GPR_CODEGEN_ASSERT( + false && + "It is illegal to call GetOriginalSendMessage on a method which " + "has a Cancel notification"); + return nullptr; + } + std::multimap* GetSendInitialMetadata() override { GPR_CODEGEN_ASSERT(false && "It is illegal to call GetSendInitialMetadata on a " diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 1854f6ef2f5..b28b7fd9315 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -642,7 +642,7 @@ class CallbackServerStreamingHandler : public MethodHandler { ctx_->sent_initial_metadata_ = true; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*resp, options).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(resp, options).ok()); call_.PerformOps(&write_ops_); } @@ -652,7 +652,7 @@ class CallbackServerStreamingHandler : public MethodHandler { // Don't send any message if the status is bad if (s.ok()) { // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(*resp, options).ok()); + GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(resp, options).ok()); } Finish(std::move(s)); } @@ -804,7 +804,7 @@ class CallbackBidiHandler : public MethodHandler { ctx_->sent_initial_metadata_ = true; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*resp, options).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(resp, options).ok()); call_.PerformOps(&write_ops_); } @@ -813,7 +813,7 @@ class CallbackBidiHandler : public MethodHandler { // Don't send any message if the status is bad if (s.ok()) { // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(*resp, options).ok()); + GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(resp, options).ok()); } Finish(std::move(s)); } diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index 6981076f04e..4645ea3e2f5 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -253,7 +253,7 @@ class ClientReader final : public ClientReaderInterface { ops.SendInitialMetadata(&context->send_initial_metadata_, context->initial_metadata_flags()); // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(ops.SendMessage(request).ok()); + GPR_CODEGEN_ASSERT(ops.SendMessage(&request).ok()); ops.ClientSendClose(); call_.PerformOps(&ops); cq_.Pluck(&ops); @@ -331,7 +331,7 @@ class ClientWriter : public ClientWriterInterface { context_->initial_metadata_flags()); context_->set_initial_metadata_corked(false); } - if (!ops.SendMessage(msg, options).ok()) { + if (!ops.SendMessage(&msg, options).ok()) { return false; } @@ -502,7 +502,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { context_->initial_metadata_flags()); context_->set_initial_metadata_corked(false); } - if (!ops.SendMessage(msg, options).ok()) { + if (!ops.SendMessage(&msg, options).ok()) { return false; } @@ -656,7 +656,7 @@ class ServerWriter final : public ServerWriterInterface { options.set_buffer_hint(); } - if (!ctx_->pending_ops_.SendMessage(msg, options).ok()) { + if (!ctx_->pending_ops_.SendMessage(&msg, options).ok()) { return false; } if (!ctx_->sent_initial_metadata_) { @@ -734,7 +734,7 @@ class ServerReaderWriterBody final { if (options.is_last_message()) { options.set_buffer_hint(); } - if (!ctx_->pending_ops_.SendMessage(msg, options).ok()) { + if (!ctx_->pending_ops_.SendMessage(&msg, options).ok()) { return false; } if (!ctx_->sent_initial_metadata_) { diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 8abf4eb3f49..3414ebe64e2 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -293,6 +293,11 @@ class LoggingInterceptor : public experimental::Interceptor { SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); EXPECT_TRUE(req.message().find("Hello") == 0); + EXPECT_EQ( + static_cast(methods->GetOriginalSendMessage()) + ->message() + .find("Hello"), + 0); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { From f0e960714e84a1893edc9c971eac6d1df21f3f8c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 2 Jan 2019 17:22:40 +0100 Subject: [PATCH 0667/2143] Revert "Revert "basic tcp_trace support for windows"" This reverts commit f438d72e6c5e5bd839a255322fb91c416822f629. --- src/core/lib/iomgr/tcp_windows.cc | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 4b5250803d1..aaf9fb4ea8a 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -42,6 +42,7 @@ #include "src/core/lib/iomgr/tcp_windows.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" #if defined(__MSYS__) && defined(GPR_ARCH_64) /* Nasty workaround for nasty bug when using the 64 bits msys compiler @@ -182,6 +183,10 @@ static void on_read(void* tcpp, grpc_error* error) { grpc_slice sub; grpc_winsocket_callback_info* info = &socket->read_info; + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p on_read", tcp); + } + GRPC_ERROR_REF(error); if (error == GRPC_ERROR_NONE) { @@ -194,7 +199,21 @@ static void on_read(void* tcpp, grpc_error* error) { if (info->bytes_transfered != 0 && !tcp->shutting_down) { sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); grpc_slice_buffer_add(tcp->read_slices, sub); + + if (grpc_tcp_trace.enabled()) { + size_t i; + for (i = 0; i < tcp->read_slices->count; i++) { + char* dump = grpc_dump_slice(tcp->read_slices->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); + } + } } else { + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p unref read_slice", tcp); + } grpc_slice_unref_internal(tcp->read_slice); error = tcp->shutting_down ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -219,6 +238,10 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, DWORD flags = 0; WSABUF buffer; + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p win_read", tcp); + } + if (tcp->shutting_down) { GRPC_CLOSURE_SCHED( cb, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -275,6 +298,10 @@ static void on_write(void* tcpp, grpc_error* error) { grpc_winsocket_callback_info* info = &handle->write_info; grpc_closure* cb; + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p on_write", tcp); + } + GRPC_ERROR_REF(error); gpr_mu_lock(&tcp->mu); @@ -308,6 +335,16 @@ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, WSABUF* buffers = local_buffers; size_t len; + if (grpc_tcp_trace.enabled()) { + size_t i; + for (i = 0; i < slices->count; i++) { + char* data = + grpc_dump_slice(slices->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); + } + } + if (tcp->shutting_down) { GRPC_CLOSURE_SCHED( cb, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( From 12aae4f7bbf996c121550e5934b6da9f52578ef7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 2 Jan 2019 17:23:00 +0100 Subject: [PATCH 0668/2143] Revert "Revert "better slice management for win_read"" This reverts commit a050ae8ddc3a64151b344fd1a4d438db9dea2acb. --- src/core/lib/iomgr/tcp_windows.cc | 57 ++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index aaf9fb4ea8a..86ee1010cf7 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -113,7 +113,10 @@ typedef struct grpc_tcp { grpc_closure* read_cb; grpc_closure* write_cb; - grpc_slice read_slice; + + /* garbage after the last read */ + grpc_slice_buffer last_read_buffer; + grpc_slice_buffer* write_slices; grpc_slice_buffer* read_slices; @@ -132,6 +135,7 @@ static void tcp_free(grpc_tcp* tcp) { grpc_winsocket_destroy(tcp->socket); gpr_mu_destroy(&tcp->mu); gpr_free(tcp->peer_string); + grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); if (tcp->shutting_down) GRPC_ERROR_UNREF(tcp->shutdown_error); gpr_free(tcp); @@ -180,7 +184,6 @@ static void on_read(void* tcpp, grpc_error* error) { grpc_tcp* tcp = (grpc_tcp*)tcpp; grpc_closure* cb = tcp->read_cb; grpc_winsocket* socket = tcp->socket; - grpc_slice sub; grpc_winsocket_callback_info* info = &socket->read_info; if (grpc_tcp_trace.enabled()) { @@ -194,11 +197,19 @@ static void on_read(void* tcpp, grpc_error* error) { char* utf8_message = gpr_format_message(info->wsa_error); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(utf8_message); gpr_free(utf8_message); - grpc_slice_unref_internal(tcp->read_slice); + grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); } else { if (info->bytes_transfered != 0 && !tcp->shutting_down) { - sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); - grpc_slice_buffer_add(tcp->read_slices, sub); + GPR_ASSERT((size_t)info->bytes_transfered <= tcp->read_slices->length); + if (static_cast(info->bytes_transfered) != + tcp->read_slices->length) { + grpc_slice_buffer_trim_end( + tcp->read_slices, + tcp->read_slices->length - + static_cast(info->bytes_transfered), + &tcp->last_read_buffer); + } + GPR_ASSERT((size_t)info->bytes_transfered == tcp->read_slices->length); if (grpc_tcp_trace.enabled()) { size_t i; @@ -214,7 +225,7 @@ static void on_read(void* tcpp, grpc_error* error) { if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p unref read_slice", tcp); } - grpc_slice_unref_internal(tcp->read_slice); + grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); error = tcp->shutting_down ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "TCP stream shutting down", &tcp->shutdown_error, 1) @@ -228,6 +239,8 @@ static void on_read(void* tcpp, grpc_error* error) { GRPC_CLOSURE_SCHED(cb, 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_tcp* tcp = (grpc_tcp*)ep; @@ -236,7 +249,8 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, int status; DWORD bytes_read = 0; DWORD flags = 0; - WSABUF buffer; + WSABUF buffers[MAX_WSABUF_COUNT]; + size_t i; if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p win_read", tcp); @@ -252,18 +266,27 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, tcp->read_cb = cb; tcp->read_slices = read_slices; grpc_slice_buffer_reset_and_unref_internal(read_slices); + grpc_slice_buffer_swap(read_slices, &tcp->last_read_buffer); - tcp->read_slice = GRPC_SLICE_MALLOC(8192); + if (tcp->read_slices->length < DEFAULT_TARGET_READ_SIZE / 2 && + tcp->read_slices->count < MAX_WSABUF_COUNT) { + // TODO(jtattermusch): slice should be allocated using resource quota + grpc_slice_buffer_add(tcp->read_slices, + GRPC_SLICE_MALLOC(DEFAULT_TARGET_READ_SIZE)); + } - buffer.len = (ULONG)GRPC_SLICE_LENGTH( - tcp->read_slice); // we know slice size fits in 32bit. - buffer.buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slice); + GPR_ASSERT(tcp->read_slices->count <= MAX_WSABUF_COUNT); + for (i = 0; i < tcp->read_slices->count; i++) { + buffers[i].len = (ULONG)GRPC_SLICE_LENGTH( + tcp->read_slices->slices[i]); // we know slice size fits in 32bit. + buffers[i].buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slices->slices[i]); + } TCP_REF(tcp, "read"); /* First let's try a synchronous, non-blocking read. */ - status = - WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, NULL, NULL); + status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count, + &bytes_read, &flags, NULL, NULL); info->wsa_error = status == 0 ? 0 : WSAGetLastError(); /* Did we get data immediately ? Yay. */ @@ -275,8 +298,8 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, /* Otherwise, let's retry, by queuing a read. */ memset(&tcp->socket->read_info.overlapped, 0, sizeof(OVERLAPPED)); - status = WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, - &info->overlapped, NULL); + status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count, + &bytes_read, &flags, &info->overlapped, NULL); if (status != 0) { int wsa_error = WSAGetLastError(); @@ -330,7 +353,7 @@ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, unsigned i; DWORD bytes_sent; int status; - WSABUF local_buffers[16]; + WSABUF local_buffers[MAX_WSABUF_COUNT]; WSABUF* allocated = NULL; WSABUF* buffers = local_buffers; size_t len; @@ -449,6 +472,7 @@ 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"); } @@ -500,6 +524,7 @@ grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket, GRPC_CLOSURE_INIT(&tcp->on_read, on_read, tcp, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&tcp->on_write, on_write, tcp, grpc_schedule_on_exec_ctx); 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); From 80e2022cbe117313c53fc89be388c213342a058f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 2 Jan 2019 17:20:03 +0100 Subject: [PATCH 0669/2143] use stderr buffering for "+trace" windows tests --- test/core/end2end/fixtures/h2_full+trace.cc | 9 +++++++++ test/core/end2end/fixtures/h2_sockpair+trace.cc | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc index 2bbad487013..ce8f6bf13a5 100644 --- a/test/core/end2end/fixtures/h2_full+trace.cc +++ b/test/core/end2end/fixtures/h2_full+trace.cc @@ -113,6 +113,15 @@ int main(int argc, char** argv) { g_fixture_slowdown_factor = 10; #endif +#ifdef GPR_WINDOWS + /* on Windows, writing logs to stderr is very slow + when stderr is redirected to a disk file. + The "trace" tests fixtures generates large amount + of logs, so setting a buffer for stderr prevents certain + test cases from timing out. */ + setvbuf(stderr, NULL, _IOLBF, 1024); +#endif + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc index 45f78b59642..4494d5c4746 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.cc +++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc @@ -140,6 +140,15 @@ int main(int argc, char** argv) { g_fixture_slowdown_factor = 10; #endif +#ifdef GPR_WINDOWS + /* on Windows, writing logs to stderr is very slow + when stderr is redirected to a disk file. + The "trace" tests fixtures generates large amount + of logs, so setting a buffer for stderr prevents certain + test cases from timing out. */ + setvbuf(stderr, NULL, _IOLBF, 1024); +#endif + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); From 9c5ca8365c650c8891ef222b43edb1514e7d36f3 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 2 Jan 2019 23:03:30 +0100 Subject: [PATCH 0670/2143] Revert "Implement a lock-free fast path for queue_call_request()" --- src/core/lib/surface/server.cc | 106 +++++++++++++-------------------- 1 file changed, 42 insertions(+), 64 deletions(-) diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 67b38e6f0c0..7ae6e51a5fb 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -194,13 +194,10 @@ struct call_data { }; struct request_matcher { - request_matcher(grpc_server* server); - ~request_matcher(); - grpc_server* server; - std::atomic pending_head{nullptr}; - call_data* pending_tail = nullptr; - gpr_locked_mpscq* requests_per_cq = nullptr; + call_data* pending_head; + call_data* pending_tail; + gpr_locked_mpscq* requests_per_cq; }; struct registered_method { @@ -349,30 +346,22 @@ static void channel_broadcaster_shutdown(channel_broadcaster* cb, * request_matcher */ -namespace { -request_matcher::request_matcher(grpc_server* server) : server(server) { - requests_per_cq = static_cast( - gpr_malloc(sizeof(*requests_per_cq) * server->cq_count)); - for (size_t i = 0; i < server->cq_count; i++) { - gpr_locked_mpscq_init(&requests_per_cq[i]); - } -} - -request_matcher::~request_matcher() { - for (size_t i = 0; i < server->cq_count; i++) { - GPR_ASSERT(gpr_locked_mpscq_pop(&requests_per_cq[i]) == nullptr); - gpr_locked_mpscq_destroy(&requests_per_cq[i]); - } - gpr_free(requests_per_cq); -} -} // namespace - static void request_matcher_init(request_matcher* rm, grpc_server* server) { - new (rm) request_matcher(server); + memset(rm, 0, sizeof(*rm)); + rm->server = server; + rm->requests_per_cq = static_cast( + gpr_malloc(sizeof(*rm->requests_per_cq) * server->cq_count)); + for (size_t i = 0; i < server->cq_count; i++) { + gpr_locked_mpscq_init(&rm->requests_per_cq[i]); + } } static void request_matcher_destroy(request_matcher* rm) { - rm->~request_matcher(); + for (size_t i = 0; i < rm->server->cq_count; i++) { + GPR_ASSERT(gpr_locked_mpscq_pop(&rm->requests_per_cq[i]) == nullptr); + gpr_locked_mpscq_destroy(&rm->requests_per_cq[i]); + } + gpr_free(rm->requests_per_cq); } static void kill_zombie(void* elem, grpc_error* error) { @@ -381,10 +370,9 @@ static void kill_zombie(void* elem, grpc_error* error) { } static void request_matcher_zombify_all_pending_calls(request_matcher* rm) { - call_data* calld; - while ((calld = rm->pending_head.load(std::memory_order_relaxed)) != - nullptr) { - rm->pending_head.store(calld->pending_next, std::memory_order_relaxed); + while (rm->pending_head) { + call_data* calld = rm->pending_head; + rm->pending_head = calld->pending_next; gpr_atm_no_barrier_store(&calld->state, ZOMBIED); GRPC_CLOSURE_INIT( &calld->kill_zombie_closure, kill_zombie, @@ -582,9 +570,8 @@ static void publish_new_rpc(void* arg, grpc_error* error) { } gpr_atm_no_barrier_store(&calld->state, PENDING); - if (rm->pending_head.load(std::memory_order_relaxed) == nullptr) { - rm->pending_head.store(calld, std::memory_order_relaxed); - rm->pending_tail = calld; + if (rm->pending_head == nullptr) { + rm->pending_tail = rm->pending_head = calld; } else { rm->pending_tail->pending_next = calld; rm->pending_tail = calld; @@ -1448,39 +1435,30 @@ static grpc_call_error queue_call_request(grpc_server* server, size_t cq_idx, rm = &rc->data.registered.method->matcher; break; } - - // Fast path: if there is no pending request to be processed, immediately - // return. - if (!gpr_locked_mpscq_push(&rm->requests_per_cq[cq_idx], &rc->request_link) || - // Note: We are reading the pending_head without holding the server's call - // mutex. Even if we read a non-null value here due to reordering, - // we will check it below again after grabbing the lock. - rm->pending_head.load(std::memory_order_relaxed) == nullptr) { - return GRPC_CALL_OK; - } - // Slow path: This was the first queued request and there are pendings: - // We need to lock and start matching calls. - gpr_mu_lock(&server->mu_call); - while ((calld = rm->pending_head.load(std::memory_order_relaxed)) != - nullptr) { - rc = reinterpret_cast( - gpr_locked_mpscq_pop(&rm->requests_per_cq[cq_idx])); - if (rc == nullptr) break; - rm->pending_head.store(calld->pending_next, std::memory_order_relaxed); - gpr_mu_unlock(&server->mu_call); - if (!gpr_atm_full_cas(&calld->state, PENDING, ACTIVATED)) { - // Zombied Call - GRPC_CLOSURE_INIT( - &calld->kill_zombie_closure, kill_zombie, - grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0), - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_SCHED(&calld->kill_zombie_closure, GRPC_ERROR_NONE); - } else { - publish_call(server, calld, cq_idx, rc); - } + if (gpr_locked_mpscq_push(&rm->requests_per_cq[cq_idx], &rc->request_link)) { + /* this was the first queued request: we need to lock and start + matching calls */ gpr_mu_lock(&server->mu_call); + while ((calld = rm->pending_head) != nullptr) { + rc = reinterpret_cast( + gpr_locked_mpscq_pop(&rm->requests_per_cq[cq_idx])); + if (rc == nullptr) break; + rm->pending_head = calld->pending_next; + gpr_mu_unlock(&server->mu_call); + if (!gpr_atm_full_cas(&calld->state, PENDING, ACTIVATED)) { + // Zombied Call + GRPC_CLOSURE_INIT( + &calld->kill_zombie_closure, kill_zombie, + grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0), + grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_SCHED(&calld->kill_zombie_closure, GRPC_ERROR_NONE); + } else { + publish_call(server, calld, cq_idx, rc); + } + gpr_mu_lock(&server->mu_call); + } + gpr_mu_unlock(&server->mu_call); } - gpr_mu_unlock(&server->mu_call); return GRPC_CALL_OK; } From 69e99a827555ce69cb796589189dab4fc6a9375f Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 2 Jan 2019 14:24:30 -0800 Subject: [PATCH 0671/2143] Add clang fallthrough annotation --- test/core/memory_usage/server.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index 7424797e6f5..c79d661a422 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -295,6 +295,7 @@ int main(int argc, char** argv) { /* fallthrough */ // no break here since we want to continue to case // FLING_SERVER_SEND_STATUS_SNAPSHOT to destroy the snapshot call + [[fallthrough]]; case FLING_SERVER_SEND_STATUS_SNAPSHOT: grpc_byte_buffer_destroy(payload_buffer); grpc_byte_buffer_destroy(terminal_buffer); From c6261f4b918a88f5b1fc5cd60e1e2b44e8f83a76 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 2 Jan 2019 14:46:52 -0800 Subject: [PATCH 0672/2143] Rename new SendMessage types to SendMessagePtr --- include/grpcpp/impl/codegen/call_op_set.h | 11 +++--- include/grpcpp/impl/codegen/client_callback.h | 8 ++--- .../grpcpp/impl/codegen/client_unary_call.h | 2 +- .../grpcpp/impl/codegen/method_handler_impl.h | 4 +-- include/grpcpp/impl/codegen/server_callback.h | 12 +++---- include/grpcpp/impl/codegen/sync_stream.h | 10 +++--- .../client_interceptors_end2end_test.cc | 6 ++-- .../server_interceptors_end2end_test.cc | 35 ++++++++++++++++++- 8 files changed, 61 insertions(+), 27 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index ddee5280cb3..310bea93ca7 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -307,13 +307,13 @@ class CallOpSendMessage { /// after use. This form of SendMessage allows gRPC to reference \a message /// beyond the lifetime of SendMessage. template - Status SendMessage(const M* message, - WriteOptions options) GRPC_MUST_USE_RESULT; + Status SendMessagePtr(const M* message, + WriteOptions options) GRPC_MUST_USE_RESULT; /// This form of SendMessage allows gRPC to reference \a message beyond the /// lifetime of SendMessage. template - Status SendMessage(const M* message) GRPC_MUST_USE_RESULT; + Status SendMessagePtr(const M* message) GRPC_MUST_USE_RESULT; protected: void AddOp(grpc_op* ops, size_t* nops) { @@ -376,13 +376,14 @@ Status CallOpSendMessage::SendMessage(const M& message) { } template -Status CallOpSendMessage::SendMessage(const M* message, WriteOptions options) { +Status CallOpSendMessage::SendMessagePtr(const M* message, + WriteOptions options) { msg_ = message; return SendMessage(*message, options); } template -Status CallOpSendMessage::SendMessage(const M* message) { +Status CallOpSendMessage::SendMessagePtr(const M* message) { msg_ = message; return SendMessage(*message, WriteOptions()); } diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index f164db19ec7..c20e8458106 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -73,7 +73,7 @@ class CallbackUnaryCallImpl { CallbackWithStatusTag(call.call(), on_completion, ops); // TODO(vjpai): Unify code with sync API as much as possible - Status s = ops->SendMessage(request); + Status s = ops->SendMessagePtr(request); if (!s.ok()) { tag->force_run(s); return; @@ -341,7 +341,7 @@ class ClientCallbackReaderWriterImpl start_corked_ = false; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg).ok()); if (options.is_last_message()) { options.set_buffer_hint(); @@ -524,7 +524,7 @@ class ClientCallbackReaderImpl : context_(context), call_(call), reactor_(reactor) { this->BindReactor(reactor); // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(start_ops_.SendMessage(*request).ok()); + GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok()); start_ops_.ClientSendClose(); } @@ -650,7 +650,7 @@ class ClientCallbackWriterImpl start_corked_ = false; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg).ok()); if (options.is_last_message()) { options.set_buffer_hint(); diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index f34da234824..b9f8e1663f1 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -57,7 +57,7 @@ class BlockingUnaryCallImpl { CallOpRecvInitialMetadata, CallOpRecvMessage, CallOpClientSendClose, CallOpClientRecvStatus> ops; - status_ = ops.SendMessage(&request); + status_ = ops.SendMessagePtr(&request); if (!status_.ok()) { return; } diff --git a/include/grpcpp/impl/codegen/method_handler_impl.h b/include/grpcpp/impl/codegen/method_handler_impl.h index dd53f975f68..094286294c2 100644 --- a/include/grpcpp/impl/codegen/method_handler_impl.h +++ b/include/grpcpp/impl/codegen/method_handler_impl.h @@ -79,7 +79,7 @@ class RpcMethodHandler : public MethodHandler { ops.set_compression_level(param.server_context->compression_level()); } if (status.ok()) { - status = ops.SendMessage(rsp); + status = ops.SendMessagePtr(&rsp); } ops.ServerSendStatus(¶m.server_context->trailing_metadata_, status); param.call->PerformOps(&ops); @@ -139,7 +139,7 @@ class ClientStreamingHandler : public MethodHandler { } } if (status.ok()) { - status = ops.SendMessage(rsp); + status = ops.SendMessagePtr(&rsp); } ops.ServerSendStatus(¶m.server_context->trailing_metadata_, status); param.call->PerformOps(&ops); diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index b28b7fd9315..a0e59215dd6 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -320,7 +320,7 @@ class CallbackUnaryHandler : public MethodHandler { // The response is dropped if the status is not OK. if (s.ok()) { finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_ops_.SendMessage(resp_)); + finish_ops_.SendMessagePtr(&resp_)); } else { finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); } @@ -449,7 +449,7 @@ class CallbackClientStreamingHandler : public MethodHandler { // The response is dropped if the status is not OK. if (s.ok()) { finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_ops_.SendMessage(resp_)); + finish_ops_.SendMessagePtr(&resp_)); } else { finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); } @@ -642,7 +642,7 @@ class CallbackServerStreamingHandler : public MethodHandler { ctx_->sent_initial_metadata_ = true; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(resp, options).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); call_.PerformOps(&write_ops_); } @@ -652,7 +652,7 @@ class CallbackServerStreamingHandler : public MethodHandler { // Don't send any message if the status is bad if (s.ok()) { // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(resp, options).ok()); + GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); } Finish(std::move(s)); } @@ -804,7 +804,7 @@ class CallbackBidiHandler : public MethodHandler { ctx_->sent_initial_metadata_ = true; } // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(resp, options).ok()); + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); call_.PerformOps(&write_ops_); } @@ -813,7 +813,7 @@ class CallbackBidiHandler : public MethodHandler { // Don't send any message if the status is bad if (s.ok()) { // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(resp, options).ok()); + GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); } Finish(std::move(s)); } diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index 4645ea3e2f5..d9edad42153 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -253,7 +253,7 @@ class ClientReader final : public ClientReaderInterface { ops.SendInitialMetadata(&context->send_initial_metadata_, context->initial_metadata_flags()); // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(ops.SendMessage(&request).ok()); + GPR_CODEGEN_ASSERT(ops.SendMessagePtr(&request).ok()); ops.ClientSendClose(); call_.PerformOps(&ops); cq_.Pluck(&ops); @@ -331,7 +331,7 @@ class ClientWriter : public ClientWriterInterface { context_->initial_metadata_flags()); context_->set_initial_metadata_corked(false); } - if (!ops.SendMessage(&msg, options).ok()) { + if (!ops.SendMessagePtr(&msg, options).ok()) { return false; } @@ -502,7 +502,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { context_->initial_metadata_flags()); context_->set_initial_metadata_corked(false); } - if (!ops.SendMessage(&msg, options).ok()) { + if (!ops.SendMessagePtr(&msg, options).ok()) { return false; } @@ -656,7 +656,7 @@ class ServerWriter final : public ServerWriterInterface { options.set_buffer_hint(); } - if (!ctx_->pending_ops_.SendMessage(&msg, options).ok()) { + if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { return false; } if (!ctx_->sent_initial_metadata_) { @@ -734,7 +734,7 @@ class ServerReaderWriterBody final { if (options.is_last_message()) { options.set_buffer_hint(); } - if (!ctx_->pending_ops_.SendMessage(&msg, options).ok()) { + if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { return false; } if (!ctx_->sent_initial_metadata_) { diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 3414ebe64e2..1ed1fb686dc 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -292,12 +292,12 @@ class LoggingInterceptor : public experimental::Interceptor { EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); - EXPECT_TRUE(req.message().find("Hello") == 0); + EXPECT_TRUE(req.message().find("Hello") == 0u); EXPECT_EQ( static_cast(methods->GetOriginalSendMessage()) ->message() .find("Hello"), - 0); + 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { @@ -313,7 +313,7 @@ class LoggingInterceptor : public experimental::Interceptor { experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { EchoResponse* resp = static_cast(methods->GetRecvMessage()); - EXPECT_TRUE(resp->message().find("Hello") == 0); + EXPECT_TRUE(resp->message().find("Hello") == 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_STATUS)) { diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 53d8c4dc960..28f51bb2fce 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -73,7 +73,7 @@ class LoggingInterceptor : public experimental::Interceptor { type == experimental::ServerRpcInfo::Type::BIDI_STREAMING)); } - virtual void Intercept(experimental::InterceptorBatchMethods* methods) { + void Intercept(experimental::InterceptorBatchMethods* methods) override { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { auto* map = methods->GetSendInitialMetadata(); @@ -142,6 +142,33 @@ class LoggingInterceptorFactory } }; +// Test if GetOriginalSendMessage works as expected +class GetOriginalSendMessageTester : public experimental::Interceptor { + public: + GetOriginalSendMessageTester(experimental::ServerRpcInfo* info) {} + + void Intercept(experimental::InterceptorBatchMethods* methods) override { + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + EXPECT_EQ( + static_cast(methods->GetOriginalSendMessage()) + ->message() + .find("Hello"), + 0u); + } + methods->Proceed(); + } +}; + +class GetOriginalSendMessageTesterFactory + : public experimental::ServerInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateServerInterceptor( + experimental::ServerRpcInfo* info) override { + return new GetOriginalSendMessageTester(info); + } +}; + void MakeBidiStreamingCall(const std::shared_ptr& channel) { auto stub = grpc::testing::EchoTestService::NewStub(channel); ClientContext ctx; @@ -176,6 +203,9 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { creators.push_back( std::unique_ptr( new LoggingInterceptorFactory())); + creators.push_back( + std::unique_ptr( + new GetOriginalSendMessageTesterFactory())); // Add 20 dummy interceptor factories and null interceptor factories for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( @@ -216,6 +246,9 @@ class ServerInterceptorsEnd2endSyncStreamingTest : public ::testing::Test { creators.push_back( std::unique_ptr( new LoggingInterceptorFactory())); + creators.push_back( + std::unique_ptr( + new GetOriginalSendMessageTesterFactory())); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); From 1f3829180c32c8c2ee1a3d546d6c2bcb3287e312 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 2 Jan 2019 15:52:42 -0800 Subject: [PATCH 0673/2143] Fix missing ConnectivityMonitor usage --- src/objective-c/GRPCClient/GRPCCall.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index b0412cddb09..83c6edc6e3f 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -841,6 +841,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self sendHeaders]; [self invokeCall]; + + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; + } } - (void)startWithWriteable:(id)writeable { From 3af464f29cb7701a432518a71b0615c47ba58077 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 3 Jan 2019 08:19:51 -0800 Subject: [PATCH 0674/2143] return targets to library --- test/core/memory_usage/BUILD | 6 +++--- test/core/memory_usage/server.cc | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/test/core/memory_usage/BUILD b/test/core/memory_usage/BUILD index dd185e6577b..38b088c75c7 100644 --- a/test/core/memory_usage/BUILD +++ b/test/core/memory_usage/BUILD @@ -12,13 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_test", "grpc_package") +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") grpc_package(name = "test/core/memory_usage") licenses(["notice"]) # Apache v2 -grpc_cc_binary( +grpc_cc_library( name = "memory_usage_client", testonly = 1, srcs = ["client.cc"], @@ -29,7 +29,7 @@ grpc_cc_binary( ], ) -grpc_cc_binary( +grpc_cc_library( name = "memory_usage_server", testonly = 1, srcs = ["server.cc"], diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index c79d661a422..7424797e6f5 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -295,7 +295,6 @@ int main(int argc, char** argv) { /* fallthrough */ // no break here since we want to continue to case // FLING_SERVER_SEND_STATUS_SNAPSHOT to destroy the snapshot call - [[fallthrough]]; case FLING_SERVER_SEND_STATUS_SNAPSHOT: grpc_byte_buffer_destroy(payload_buffer); grpc_byte_buffer_destroy(terminal_buffer); From 67f523ce13a3d6c8adf02530173679cf1dc0ddd6 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 28 Dec 2018 07:55:36 -0800 Subject: [PATCH 0675/2143] Add support for ruby 2.6.0 binary package builds, drop 2.1 and 2.0 binary package builds; pin bundler to 1.17.3 where necessary --- Rakefile | 6 +-- templates/tools/dockerfile/ruby_deps.include | 14 +++---- third_party/rake-compiler-dock/Dockerfile | 3 +- tools/distrib/build_ruby_environment_macos.sh | 2 +- .../distribtest/ruby_centos6_x64/Dockerfile | 15 +++++-- .../distribtest/ruby_centos7_x64/Dockerfile | 18 +++++++- .../distribtest/ruby_fedora20_x64/Dockerfile | 21 +++++++++- .../distribtest/ruby_fedora21_x64/Dockerfile | 19 ++++++++- .../ruby_jessie_x64_ruby_2_2/Dockerfile | 40 ++++++++++++++++++ .../ruby_jessie_x64_ruby_2_3/Dockerfile | 41 +++++++++++++++++++ .../ruby_jessie_x64_ruby_2_4/Dockerfile | 40 ++++++++++++++++++ .../ruby_jessie_x64_ruby_2_5/Dockerfile | 40 ++++++++++++++++++ .../Dockerfile | 14 +++---- .../grpc_artifact_linux_x64/Dockerfile | 2 +- .../grpc_artifact_linux_x86/Dockerfile | 2 +- .../interoptest/grpc_interop_ruby/Dockerfile | 14 +++---- .../grpc_interop_ruby/build_interop.sh | 2 +- .../test/ruby_jessie_x64/Dockerfile | 14 +++---- .../helper_scripts/prepare_build_macos_rc | 2 +- .../artifacts/distribtest_targets.py | 8 ++-- 20 files changed, 267 insertions(+), 50 deletions(-) create mode 100644 tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile create mode 100644 tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_3/Dockerfile create mode 100644 tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_4/Dockerfile create mode 100644 tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_5/Dockerfile rename tools/dockerfile/distribtest/{ruby_jessie_x64_ruby_2_0_0 => ruby_jessie_x64_ruby_2_6}/Dockerfile (73%) diff --git a/Rakefile b/Rakefile index 0068a3b8e4f..d604f7935b1 100755 --- a/Rakefile +++ b/Rakefile @@ -105,7 +105,7 @@ task 'dlls' do env_comp = "CC=#{opt[:cross]}-gcc " env_comp += "CXX=#{opt[:cross]}-g++ " env_comp += "LD=#{opt[:cross]}-gcc " - docker_for_windows "gem update --system --no-ri --no-doc && #{env} #{env_comp} make -j #{out} && #{opt[:cross]}-strip -x -S #{out} && cp #{out} #{opt[:out]}" + docker_for_windows "gem update --system --no-document && #{env} #{env_comp} make -j #{out} && #{opt[:cross]}-strip -x -S #{out} && cp #{out} #{opt[:out]}" end end @@ -124,10 +124,10 @@ task 'gem:native' do "invoked on macos with ruby #{RUBY_VERSION}. The ruby macos artifact " \ "build should be running on ruby 2.5." end - system "rake cross native gem RUBY_CC_VERSION=2.5.0:2.4.0:2.3.0:2.2.2:2.1.6:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}" + system "rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}" else Rake::Task['dlls'].execute - docker_for_windows "gem update --system --no-ri --no-doc && bundle && rake cross native gem RUBY_CC_VERSION=2.5.0:2.4.0:2.3.0:2.2.2:2.1.6:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}" + docker_for_windows "gem update --system --no-document && bundle && rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}" end end diff --git a/templates/tools/dockerfile/ruby_deps.include b/templates/tools/dockerfile/ruby_deps.include index a8ee3ec7dc6..c2d330988c6 100644 --- a/templates/tools/dockerfile/ruby_deps.include +++ b/templates/tools/dockerfile/ruby_deps.include @@ -2,13 +2,13 @@ # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.1" -RUN /bin/bash -l -c "rvm use --default ruby-2.1" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +# Install Ruby 2.5 +RUN /bin/bash -l -c "rvm install ruby-2.5" +RUN /bin/bash -l -c "rvm use --default ruby-2.5" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.5' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" diff --git a/third_party/rake-compiler-dock/Dockerfile b/third_party/rake-compiler-dock/Dockerfile index 06c721c39ba..44eddc82e80 100644 --- a/third_party/rake-compiler-dock/Dockerfile +++ b/third_party/rake-compiler-dock/Dockerfile @@ -1,8 +1,7 @@ -FROM larskanis/rake-compiler-dock:0.6.2 +FROM larskanis/rake-compiler-dock-mri:0.7.0 RUN find / -name rbconfig.rb | while read f ; do sed -i 's/0x0501/0x0600/' $f ; done RUN find / -name win32.h | while read f ; do sed -i 's/gettimeofday/rb_gettimeofday/' $f ; done -RUN sed -i 's/defined.__MINGW64__.$/1/' /usr/local/rake-compiler/ruby/i686-w64-mingw32/ruby-2.0.0-p645/include/ruby-2.0.0/ruby/win32.h RUN find / -name libwinpthread.dll.a | xargs rm RUN find / -name libwinpthread-1.dll | xargs rm RUN find / -name *msvcrt-ruby*.dll.a | while read f ; do n=`echo $f | sed s/.dll//` ; mv $f $n ; done diff --git a/tools/distrib/build_ruby_environment_macos.sh b/tools/distrib/build_ruby_environment_macos.sh index 9e3e3b46f80..c2c0dcde6bd 100644 --- a/tools/distrib/build_ruby_environment_macos.sh +++ b/tools/distrib/build_ruby_environment_macos.sh @@ -49,7 +49,7 @@ EOF MAKE="make -j8" -for v in 2.5.0 2.4.0 2.3.0 2.2.2 2.1.6 2.0.0-p645 ; do +for v in 2.6.0 2.5.0 2.4.0 2.3.0 2.2.2 ; do ccache -c rake -f "$CROSS_RUBY" cross-ruby VERSION="$v" HOST=x86_64-darwin11 MAKE="$MAKE" done diff --git a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile index c3d6e03f6a1..b53ffc22d4f 100644 --- a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile @@ -19,10 +19,19 @@ RUN yum install -y curl RUN yum install -y tar which # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 # Running the installation twice to work around docker issue when using overlay. # https://github.com/docker/docker/issues/10180 -RUN (curl -sSL https://get.rvm.io | bash -s stable --ruby) || (curl -sSL https://get.rvm.io | bash -s stable --ruby) +RUN (/bin/bash -l -c "rvm install ruby-2.2.10") || (/bin/bash -l -c "rvm install ruby-2.2.10") +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install --update bundler" diff --git a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile index 73207e4210d..72235bfba7f 100644 --- a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile @@ -14,6 +14,20 @@ FROM centos:7 -RUN yum install -y ruby +RUN yum update && yum install -y curl tar which -RUN gem install bundler +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 +RUN /bin/bash -l -c "rvm install ruby-2.2.10" +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" diff --git a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile index 200c5c28033..3d688a889f0 100644 --- a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile @@ -14,6 +14,23 @@ FROM fedora:20 -RUN yum clean all && yum update -y && yum install -y ruby findutils +# distro-sync and install openssl, per https://github.com/fedora-cloud/docker-brew-fedora/issues/19 +RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y openssl gnupg which findutils -RUN gem install bundler +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 +# Running the installation twice to work around docker issue when using overlay. +# https://github.com/docker/docker/issues/10180 +RUN (/bin/bash -l -c "rvm install ruby-2.2.10") || (/bin/bash -l -c "rvm install ruby-2.2.10") +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" diff --git a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile index e1177fd99af..8044adf15dc 100644 --- a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile @@ -19,6 +19,21 @@ FROM fedora:21 # https://github.com/docker/docker/issues/10180 RUN yum install -y yum-plugin-ovl -RUN yum clean all && yum update -y && yum install -y ruby findutils +# distro-sync and install openssl, per https://github.com/fedora-cloud/docker-brew-fedora/issues/19 +RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y openssl gnupg which findutils tar -RUN gem install bundler +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 +RUN /bin/bash -l -c "rvm install ruby-2.2.10" +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile new file mode 100644 index 00000000000..337fc3b5d8e --- /dev/null +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile @@ -0,0 +1,40 @@ +# 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 \ + curl \ + gcc && apt-get clean + +#================== +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 +RUN /bin/bash -l -c "rvm install ruby-2.2.10" +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_3/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_3/Dockerfile new file mode 100644 index 00000000000..9deff0661b7 --- /dev/null +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_3/Dockerfile @@ -0,0 +1,41 @@ +# 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 \ + curl \ + gcc && apt-get clean + +#================== +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem update --system" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_4/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_4/Dockerfile new file mode 100644 index 00000000000..55b1b1e731d --- /dev/null +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_4/Dockerfile @@ -0,0 +1,40 @@ +# 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 \ + curl \ + gcc && apt-get clean + +#================== +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.4 +RUN /bin/bash -l -c "rvm install ruby-2.4.5" +RUN /bin/bash -l -c "rvm use --default ruby-2.4.5" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.4.5' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_5/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_5/Dockerfile new file mode 100644 index 00000000000..bed4b3a93ef --- /dev/null +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_5/Dockerfile @@ -0,0 +1,40 @@ +# 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 \ + curl \ + gcc && apt-get clean + +#================== +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.5 +RUN /bin/bash -l -c "rvm install ruby-2.5.3" +RUN /bin/bash -l -c "rvm use --default ruby-2.5.3" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.5.3' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_0_0/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_6/Dockerfile similarity index 73% rename from tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_0_0/Dockerfile rename to tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_6/Dockerfile index ff43c92c9e5..af1839eba93 100644 --- a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_0_0/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_6/Dockerfile @@ -23,16 +23,16 @@ RUN apt-get update && apt-get install -y \ # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.0" -RUN /bin/bash -l -c "rvm use --default ruby-2.0" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +# Install Ruby 2.6 +RUN /bin/bash -l -c "rvm install ruby-2.6.0" +RUN /bin/bash -l -c "rvm use --default ruby-2.6.0" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.0' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.6.0' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile index 7ec061ebe58..e3e549f9874 100644 --- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile @@ -58,7 +58,7 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.1" RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-ri --no-rdoc" ################## diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile index f81d8e5ba02..ec4fcbae368 100644 --- a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile @@ -58,7 +58,7 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.1" RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-ri --no-rdoc" ################## # C# dependencies (needed to build grpc_csharp_ext) diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile index 97c146bb53a..1f6f03edd89 100644 --- a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile @@ -68,16 +68,16 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.1" -RUN /bin/bash -l -c "rvm use --default ruby-2.1" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +# Install Ruby 2.5 +RUN /bin/bash -l -c "rvm install ruby-2.5" +RUN /bin/bash -l -c "rvm use --default ruby-2.5" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.5' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh index b6b122ef0fd..67f66090ae9 100755 --- a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh @@ -27,7 +27,7 @@ ${name}') cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc -rvm --default use ruby-2.1 +rvm --default use ruby-2.5 # build Ruby interop client and server (cd src/ruby && gem update bundler && bundle && rake compile) diff --git a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile index 321b501de21..cf6a5b254f1 100644 --- a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile @@ -72,16 +72,16 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.1" -RUN /bin/bash -l -c "rvm use --default ruby-2.1" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +# Install Ruby 2.5 +RUN /bin/bash -l -c "rvm install ruby-2.5" +RUN /bin/bash -l -c "rvm use --default ruby-2.5" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.5' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index ce054ac2594..632db5ae145 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -42,7 +42,7 @@ source $HOME/.rvm/scripts/rvm set -e # rvm commands are very verbose time rvm install 2.5.0 rvm use 2.5.0 --default -time gem install bundler --no-ri --no-doc +time gem install bundler -v 1.17.3 --no-ri --no-doc time gem install cocoapods --version 1.3.1 --no-ri --no-doc time gem install rake-compiler --no-ri --no-doc rvm osx-ssl-certs status all diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py index e02f4bffcd4..fd68a4dc747 100644 --- a/tools/run_tests/artifacts/distribtest_targets.py +++ b/tools/run_tests/artifacts/distribtest_targets.py @@ -336,9 +336,11 @@ def targets(): PythonDistribTest('linux', 'x64', 'ubuntu1404', source=True), PythonDistribTest('linux', 'x64', 'ubuntu1604', source=True), RubyDistribTest('linux', 'x64', 'wheezy'), - RubyDistribTest('linux', 'x64', 'jessie'), - RubyDistribTest('linux', 'x86', 'jessie'), - RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_0_0'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_2'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_3'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_4'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_5'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_6'), RubyDistribTest('linux', 'x64', 'centos6'), RubyDistribTest('linux', 'x64', 'centos7'), RubyDistribTest('linux', 'x64', 'fedora20'), From 50c60f03ba84b4e1b1d31819a295ef4e1076907b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 3 Jan 2019 12:21:19 -0800 Subject: [PATCH 0676/2143] Rename GetSendMessage to GetSerializedSendMessage and GetOriginalSendMessage to GetSendMessage --- include/grpcpp/impl/codegen/interceptor.h | 4 +-- .../grpcpp/impl/codegen/interceptor_common.h | 8 +++--- .../client_interceptors_end2end_test.cc | 15 ++++++----- .../server_interceptors_end2end_test.cc | 25 +++++++++---------- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index a83d285d130..5a9a3a44e6e 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -109,13 +109,13 @@ class InterceptorBatchMethods { /// 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. - virtual ByteBuffer* GetSendMessage() = 0; + virtual ByteBuffer* GetSerializedSendMessage() = 0; /// Returns a non-modifiable pointer to the original non-serialized form of /// the message. 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. - virtual const void* GetOriginalSendMessage() = 0; + virtual const void* GetSendMessage() = 0; /// Returns a modifiable multimap of the initial metadata to be sent. Valid /// for PRE_SEND_INITIAL_METADATA interceptions. A value of nullptr indicates diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index bf936368d4c..4b7eaefee1b 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -79,9 +79,9 @@ class InterceptorBatchMethodsImpl hooks_[static_cast(type)] = true; } - ByteBuffer* GetSendMessage() override { return send_message_; } + ByteBuffer* GetSerializedSendMessage() override { return send_message_; } - const void* GetOriginalSendMessage() override { return orig_send_message_; } + const void* GetSendMessage() override { return orig_send_message_; } std::multimap* GetSendInitialMetadata() override { return send_initial_metadata_; @@ -385,14 +385,14 @@ class CancelInterceptorBatchMethods "Cancel notification"); } - ByteBuffer* GetSendMessage() override { + ByteBuffer* GetSerializedSendMessage() override { GPR_CODEGEN_ASSERT(false && "It is illegal to call GetSendMessage on a method which " "has a Cancel notification"); return nullptr; } - const void* GetOriginalSendMessage() override { + const void* GetSendMessage() override { GPR_CODEGEN_ASSERT( false && "It is illegal to call GetOriginalSendMessage on a method which " diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 1ed1fb686dc..3db709e956e 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -68,7 +68,7 @@ class HijackingInterceptor : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; - auto* buffer = methods->GetSendMessage(); + auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) @@ -173,7 +173,7 @@ class HijackingInterceptorMakesAnotherCall : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; - auto* buffer = methods->GetSendMessage(); + auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) @@ -287,17 +287,16 @@ class LoggingInterceptor : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; - auto* buffer = methods->GetSendMessage(); + auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); EXPECT_TRUE(req.message().find("Hello") == 0u); - EXPECT_EQ( - static_cast(methods->GetOriginalSendMessage()) - ->message() - .find("Hello"), - 0u); + EXPECT_EQ(static_cast(methods->GetSendMessage()) + ->message() + .find("Hello"), + 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 28f51bb2fce..09e855b0d01 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -83,7 +83,7 @@ class LoggingInterceptor : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; - auto* buffer = methods->GetSendMessage(); + auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) @@ -142,30 +142,29 @@ class LoggingInterceptorFactory } }; -// Test if GetOriginalSendMessage works as expected -class GetOriginalSendMessageTester : public experimental::Interceptor { +// Test if GetSendMessage works as expected +class GetSendMessageTester : public experimental::Interceptor { public: - GetOriginalSendMessageTester(experimental::ServerRpcInfo* info) {} + GetSendMessageTester(experimental::ServerRpcInfo* info) {} void Intercept(experimental::InterceptorBatchMethods* methods) override { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { - EXPECT_EQ( - static_cast(methods->GetOriginalSendMessage()) - ->message() - .find("Hello"), - 0u); + EXPECT_EQ(static_cast(methods->GetSendMessage()) + ->message() + .find("Hello"), + 0u); } methods->Proceed(); } }; -class GetOriginalSendMessageTesterFactory +class GetSendMessageTesterFactory : public experimental::ServerInterceptorFactoryInterface { public: virtual experimental::Interceptor* CreateServerInterceptor( experimental::ServerRpcInfo* info) override { - return new GetOriginalSendMessageTester(info); + return new GetSendMessageTester(info); } }; @@ -205,7 +204,7 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { new LoggingInterceptorFactory())); creators.push_back( std::unique_ptr( - new GetOriginalSendMessageTesterFactory())); + new GetSendMessageTesterFactory())); // Add 20 dummy interceptor factories and null interceptor factories for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( @@ -248,7 +247,7 @@ class ServerInterceptorsEnd2endSyncStreamingTest : public ::testing::Test { new LoggingInterceptorFactory())); creators.push_back( std::unique_ptr( - new GetOriginalSendMessageTesterFactory())); + new GetSendMessageTesterFactory())); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); From e894d78c35f4836567c75054fdeb044a3397385c Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Thu, 3 Jan 2019 18:18:48 +0000 Subject: [PATCH 0677/2143] Fix artifact dockerfiles rvm installation; keep bundler pinned --- tools/dockerfile/grpc_artifact_linux_x64/Dockerfile | 2 +- tools/dockerfile/grpc_artifact_linux_x86/Dockerfile | 2 +- tools/run_tests/artifacts/build_artifact_ruby.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile index e3e549f9874..f247cc9ca54 100644 --- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile @@ -49,7 +49,7 @@ RUN apt-get update && apt-get install -y \ # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable # Install Ruby 2.1 diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile index ec4fcbae368..e403f75b594 100644 --- a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile @@ -49,7 +49,7 @@ RUN apt-get update && apt-get install -y \ # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable # Install Ruby 2.1 diff --git a/tools/run_tests/artifacts/build_artifact_ruby.sh b/tools/run_tests/artifacts/build_artifact_ruby.sh index c910374376d..09423ce5391 100755 --- a/tools/run_tests/artifacts/build_artifact_ruby.sh +++ b/tools/run_tests/artifacts/build_artifact_ruby.sh @@ -38,7 +38,7 @@ fi set +ex rvm use default -gem install bundler --update +gem install bundler -v 1.17.3 tools/run_tests/helper_scripts/bundle_install_wrapper.sh From cab4774d95b9fa53f3cfe3bf58fb07dbc8f7650f Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 28 Dec 2018 15:54:43 -0800 Subject: [PATCH 0678/2143] Add a way to avoid if_nametoindex function for non-posix linux platforms that don't support it --- include/grpc/impl/codegen/port_platform.h | 4 ++++ src/core/lib/iomgr/grpc_if_nametoindex_posix.cc | 5 +++-- src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc | 5 +++-- src/core/lib/iomgr/port.h | 1 + 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 031c0c36aef..bd81635f58c 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -465,6 +465,10 @@ typedef unsigned __int64 uint64_t; #define GRPC_ARES 1 #endif +#ifndef GRPC_IF_NAMETOINDEX +#define GRPC_IF_NAMETOINDEX 1 +#endif + #ifndef GRPC_MUST_USE_RESULT #if defined(__GNUC__) && !defined(__MINGW32__) #define GRPC_MUST_USE_RESULT __attribute__((warn_unused_result)) diff --git a/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc b/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc index 8f9137455d2..f1ba20dcec7 100644 --- a/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc +++ b/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc @@ -20,7 +20,7 @@ #include "src/core/lib/iomgr/port.h" -#ifdef GRPC_POSIX_SOCKET +#if GRPC_IF_NAMETOINDEX == 1 && defined(GRPC_POSIX_SOCKET_IF_NAMETOINDEX) #include "src/core/lib/iomgr/grpc_if_nametoindex.h" @@ -38,4 +38,5 @@ uint32_t grpc_if_nametoindex(char* name) { return out; } -#endif /* GRPC_POSIX_SOCKET */ +#endif /* GRPC_IF_NAMETOINDEX == 1 && \ + defined(GRPC_POSIX_SOCKET_IF_NAMETOINDEX) */ diff --git a/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc b/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc index 1faaaa6e420..08644cccf3e 100644 --- a/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc +++ b/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc @@ -20,7 +20,7 @@ #include "src/core/lib/iomgr/port.h" -#ifndef GRPC_POSIX_SOCKET +#if GRPC_IF_NAMETOINDEX == 0 || !defined(GRPC_POSIX_SOCKET_IF_NAMETOINDEX) #include "src/core/lib/iomgr/grpc_if_nametoindex.h" @@ -34,4 +34,5 @@ uint32_t grpc_if_nametoindex(char* name) { return 0; } -#endif /* GRPC_POSIX_SOCKET */ +#endif /* GRPC_IF_NAMETOINDEX == 0 || \ + !defined(GRPC_POSIX_SOCKET_IF_NAMETOINDEX) */ diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index c8046b21dcd..7b6ca1bc0e1 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -184,6 +184,7 @@ #define GRPC_POSIX_SOCKET_EV_EPOLLEX 1 #define GRPC_POSIX_SOCKET_EV_POLL 1 #define GRPC_POSIX_SOCKET_EV_EPOLL1 1 +#define GRPC_POSIX_SOCKET_IF_NAMETOINDEX 1 #define GRPC_POSIX_SOCKET_IOMGR 1 #define GRPC_POSIX_SOCKET_RESOLVE_ADDRESS 1 #define GRPC_POSIX_SOCKET_SOCKADDR 1 From eedcea98335b518a8bea9f4c654713add86e6e9c Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Thu, 3 Jan 2019 14:06:52 -0800 Subject: [PATCH 0679/2143] 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 0680/2143] 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 ec2d03d409ebb65daa252e6c280e3bec4fe96b69 Mon Sep 17 00:00:00 2001 From: Sanjay Pujare Date: Thu, 3 Jan 2019 14:28:38 -0800 Subject: [PATCH 0681/2143] restore the newline --- tools/doxygen/Doxyfile.c++ | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 8c890f2ba3f..1ab3a394b96 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -2623,3 +2623,4 @@ GENERATE_LEGEND = YES # This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = YES + From d99f2f03074ef978b593ec0fdbe6295cd0235500 Mon Sep 17 00:00:00 2001 From: Sanjay Pujare Date: Thu, 3 Jan 2019 15:33:33 -0800 Subject: [PATCH 0682/2143] Bump version to v1.19.x --- BUILD | 4 ++-- build.yaml | 4 ++-- doc/g_stands_for.md | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/BUILD b/BUILD index e3c765198b2..cd23d9c91fa 100644 --- a/BUILD +++ b/BUILD @@ -64,11 +64,11 @@ config_setting( ) # This should be updated along with build.yaml -g_stands_for = "goose" +g_stands_for = "gold" core_version = "7.0.0-dev" -version = "1.18.0-dev" +version = "1.19.0-dev" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index a41decd84f7..4ccc452ed5b 100644 --- a/build.yaml +++ b/build.yaml @@ -13,8 +13,8 @@ settings: '#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: goose - version: 1.18.0-dev + g_stands_for: gold + version: 1.19.0-dev filegroups: - name: alts_proto headers: diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index 1e49b4d3f17..7bc8a003b5d 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -17,4 +17,5 @@ - 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) +- 1.19 'g' stands for ['gold'](https://github.com/grpc/grpc/tree/master) From 94d55876438a8178aae85ded57e3d04ff3f298c5 Mon Sep 17 00:00:00 2001 From: Sanjay Pujare Date: Thu, 3 Jan 2019 15:35:20 -0800 Subject: [PATCH 0683/2143] 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/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 | 4 ++-- 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 | 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 +- 32 files changed, 36 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48d3d11d238..7e4dddab5ba 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.19.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 b8a1c921862..ce56482a0df 100644 --- a/Makefile +++ b/Makefile @@ -438,8 +438,8 @@ Q = @ endif CORE_VERSION = 7.0.0-dev -CPP_VERSION = 1.18.0-dev -CSHARP_VERSION = 1.18.0-dev +CPP_VERSION = 1.19.0-dev +CSHARP_VERSION = 1.19.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 29a79dd47ab..e830958f799 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.18.0-dev' + # version = '1.19.0-dev' version = '0.0.6-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.18.0-dev' + grpc_version = '1.19.0-dev' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 240afbff7e6..7ddef6aa441 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.19.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 13fe3e0b9c0..7bf53799de8 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.19.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 e132ad41b40..34bec88c8b4 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.19.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 940a1ac6217..8e284866b3d 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.19.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 2632fcb276b..d86c204746c 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.18.0dev - 1.18.0dev + 1.19.0dev + 1.19.0dev beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 4829cc80a53..70d7580becb 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -25,4 +25,4 @@ const char* grpc_version_string(void) { return "7.0.0-dev"; } -const char* grpc_g_stands_for(void) { return "goose"; } +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 55da89e6c83..358131c7c4c 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.19.0-dev"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 4fffe4f6448..52ab2215ebe 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.19.0-dev 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 633880189ce..8f3be310ee7 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.18.0.0"; + public const string CurrentAssemblyFileVersion = "1.19.0.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.18.0-dev"; + public const string CurrentVersion = "1.19.0-dev"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 76d4f143901..fef1a43bb88 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.19.0-dev @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..6b66b941a8d 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.19.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 55ca6048bc3..659cfebbdc0 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.19.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 0be0e3c9a00..5e089fde316 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.19.0-dev" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index f2fd692070b..54f95ad16a8 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_OBJC_VERSION_STRING @"1.19.0-dev" #define GRPC_C_VERSION_STRING @"7.0.0-dev" diff --git a/src/php/composer.json b/src/php/composer.json index 9c298c0e851..75fab483f14 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.18.0", + "version": "1.19.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 1ddf90a667a..c85ee4d315b 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.19.0dev" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 7a9f173947a..dd9d436c3fe 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.19.0.dev0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 2e91818d2ca..8e2f4d30bbc 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.19.0.dev0' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 16356ea4020..5f3a894a2ae 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.19.0.dev0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 85fa762f7e8..4c2d434066e 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.19.0.dev0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index e62ab169a2f..6b88b2dfc50 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.19.0.dev0' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index e009843b94f..2e58eb3b26c 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.19.0.dev0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 7b4c1695faa..d4c5d94ecbe 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.19.0.dev0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 2fcd1ad617f..e1645ab1b86 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.19.0.dev0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index a4ed052d85e..3b7f62d9f55 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.19.0.dev' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 389fb70684b..2ad685a7eb3 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.19.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 29b2127960a..e5d9daef38f 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.19.0.dev0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 1ab3a394b96..b0415fd4f64 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.19.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 5f488d51940..6c31a467680 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.19.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 From a87d0fa8e27988075f956b1e3e4344eff068024c Mon Sep 17 00:00:00 2001 From: Sanjay Pujare Date: Thu, 3 Jan 2019 15:47:37 -0800 Subject: [PATCH 0684/2143] 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 0685/2143] 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 077cc271e55ddb881054ab69feaaabc6e0ef6d81 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 3 Jan 2019 15:54:21 -0800 Subject: [PATCH 0686/2143] Proposed Cronet fixes --- .../transport/cronet/transport/cronet_transport.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 349d8681d55..278ef5636e3 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -335,6 +335,9 @@ static void add_to_storage(struct stream_obj* s, /* add new op at the beginning of the linked list. The memory is freed in remove_from_storage */ op_and_state* new_op = grpc_core::New(s, *op); + // Pontential fix to crash on GPR_ASSERT(!curr->done) + // TODO (mxyan): check if this is indeed necessary. + new_op->done = false; gpr_mu_lock(&s->mu); storage->head = new_op; storage->num_pending_ops++; @@ -391,7 +394,7 @@ static void execute_from_storage(stream_obj* s) { gpr_mu_lock(&s->mu); for (struct op_and_state* curr = s->storage.head; curr != nullptr;) { CRONET_LOG(GPR_DEBUG, "calling op at %p. done = %d", curr, curr->done); - GPR_ASSERT(curr->done == 0); + GPR_ASSERT(!curr->done); enum e_op_result result = execute_stream_op(curr); CRONET_LOG(GPR_DEBUG, "execute_stream_op[%p] returns %s", curr, op_result_string(result)); @@ -400,13 +403,12 @@ static void execute_from_storage(stream_obj* s) { struct op_and_state* next = curr->next; remove_from_storage(s, curr); curr = next; - } - /* continue processing the same op if ACTION_TAKEN_WITHOUT_CALLBACK */ - if (result == NO_ACTION_POSSIBLE) { + } else if (result == NO_ACTION_POSSIBLE) { curr = curr->next; } else if (result == ACTION_TAKEN_WITH_CALLBACK) { + /* wait for the callback */ break; - } + } /* continue processing the same op if ACTION_TAKEN_WITHOUT_CALLBACK */ } gpr_mu_unlock(&s->mu); } From 04dfa7d7b2343fd63a2f40aea28608b5a4938a29 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 3 Jan 2019 16:02:29 -0800 Subject: [PATCH 0687/2143] clang-format --- src/core/ext/transport/cronet/transport/cronet_transport.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 278ef5636e3..ade88da4cb9 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -336,7 +336,7 @@ static void add_to_storage(struct stream_obj* s, in remove_from_storage */ op_and_state* new_op = grpc_core::New(s, *op); // Pontential fix to crash on GPR_ASSERT(!curr->done) - // TODO (mxyan): check if this is indeed necessary. + // TODO (mxyan): check if this is indeed necessary. new_op->done = false; gpr_mu_lock(&s->mu); storage->head = new_op; From 03431b4f696387e34d6c438069a42ce56e269f04 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 3 Jan 2019 16:18:01 -0800 Subject: [PATCH 0688/2143] Remove filters from subchannel args --- .../ext/filters/client_channel/subchannel.cc | 13 ------------- .../ext/filters/client_channel/subchannel.h | 5 ----- .../filters/client_channel/subchannel_index.cc | 17 ----------------- src/core/lib/surface/channel_init.h | 5 +++++ src/cpp/common/channel_filter.h | 5 +++++ 5 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 9077aa97539..3abacf68aeb 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -101,9 +101,6 @@ struct grpc_subchannel { keep the subchannel open */ gpr_atm ref_pair; - /** non-transport related channel filters */ - const grpc_channel_filter** filters; - size_t num_filters; /** channel arguments */ grpc_channel_args* args; @@ -384,7 +381,6 @@ static void subchannel_destroy(void* arg, grpc_error* error) { c->channelz_subchannel->MarkSubchannelDestroyed(); c->channelz_subchannel.reset(); } - gpr_free((void*)c->filters); c->health_check_service_name.reset(); grpc_channel_args_destroy(c->args); grpc_connectivity_state_destroy(&c->state_tracker); @@ -567,15 +563,6 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, gpr_atm_no_barrier_store(&c->ref_pair, 1 << INTERNAL_REF_BITS); c->connector = connector; grpc_connector_ref(c->connector); - c->num_filters = args->filter_count; - if (c->num_filters > 0) { - c->filters = static_cast( - gpr_malloc(sizeof(grpc_channel_filter*) * c->num_filters)); - memcpy((void*)c->filters, args->filters, - sizeof(grpc_channel_filter*) * c->num_filters); - } else { - c->filters = nullptr; - } c->pollset_set = grpc_pollset_set_create(); grpc_resolved_address* addr = static_cast(gpr_malloc(sizeof(*addr))); diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 14f87f2c68e..d0c0a672fa1 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -189,11 +189,6 @@ grpc_call_stack* grpc_subchannel_call_get_call_stack( struct grpc_subchannel_args { /* When updating this struct, also update subchannel_index.c */ - /** Channel filters for this channel - wrapped factories will likely - want to mutate this */ - const grpc_channel_filter** filters; - /** The number of filters in the above array */ - size_t filter_count; /** Channel arguments to be supplied to the newly created channel */ const grpc_channel_args* args; }; diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc index aa8441f17b0..0ae7898c5a4 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.cc +++ b/src/core/ext/filters/client_channel/subchannel_index.cc @@ -49,15 +49,6 @@ static grpc_subchannel_key* create_key( grpc_channel_args* (*copy_channel_args)(const grpc_channel_args* args)) { grpc_subchannel_key* k = static_cast(gpr_malloc(sizeof(*k))); - k->args.filter_count = args->filter_count; - if (k->args.filter_count > 0) { - k->args.filters = static_cast( - gpr_malloc(sizeof(*k->args.filters) * k->args.filter_count)); - memcpy(reinterpret_cast(k->args.filters), - args->filters, sizeof(*k->args.filters) * k->args.filter_count); - } else { - k->args.filters = nullptr; - } k->args.args = copy_channel_args(args->args); return k; } @@ -75,18 +66,10 @@ 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; - int c = GPR_ICMP(a->args.filter_count, b->args.filter_count); - if (c != 0) return c; - if (a->args.filter_count > 0) { - c = memcmp(a->args.filters, b->args.filters, - a->args.filter_count * sizeof(*a->args.filters)); - if (c != 0) return c; - } return grpc_channel_args_compare(a->args.args, b->args.args); } void grpc_subchannel_key_destroy(grpc_subchannel_key* k) { - gpr_free(reinterpret_cast(k->args.filters)); grpc_channel_args_destroy(const_cast(k->args.args)); gpr_free(k); } diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h index f01852473ba..d17a721606d 100644 --- a/src/core/lib/surface/channel_init.h +++ b/src/core/lib/surface/channel_init.h @@ -45,6 +45,11 @@ void grpc_channel_init_init(void); /// registration order (in the case of a tie). /// Stages are registered against one of the pre-determined channel stack /// types. +/// If the channel stack type is GRPC_CLIENT_SUBCHANNEL, the caller should +/// ensure that subchannels with different filter lists will always have +/// different channel args. This requires setting a channel arg in case the +/// registration function relies on some condition other than channel args to +/// decide whether to add a filter or not. void grpc_channel_init_register_stage(grpc_channel_stack_type type, int priority, grpc_channel_init_stage stage_fn, diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h index 5e569c97e68..1a3295fc80f 100644 --- a/src/cpp/common/channel_filter.h +++ b/src/cpp/common/channel_filter.h @@ -366,6 +366,11 @@ void ChannelFilterPluginShutdown(); /// The \a include_filter argument specifies a function that will be called /// to determine at run-time whether or not to add the filter. If the /// value is nullptr, the filter will be added unconditionally. +/// If the channel stack type is GRPC_CLIENT_SUBCHANNEL, the caller should +/// ensure that subchannels with different filter lists will always have +/// different channel args. This requires setting a channel arg in case the +/// registration function relies on some condition other than channel args to +/// decide whether to add a filter or not. template void RegisterChannelFilter( const char* name, grpc_channel_stack_type stack_type, int priority, From 4224384d398ee3ddd01c0b95f93f33bdd75e8fb2 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 3 Jan 2019 15:47:00 -0800 Subject: [PATCH 0689/2143] Modifying semantics for GetSendMessage and GetSerializedSendMessage. Also adding ModifySendMessage --- include/grpcpp/impl/codegen/call_op_set.h | 31 +++++--- include/grpcpp/impl/codegen/interceptor.h | 2 + .../grpcpp/impl/codegen/interceptor_common.h | 33 +++++++-- .../client_interceptors_end2end_test.cc | 8 +-- .../server_interceptors_end2end_test.cc | 71 +++++++++++++++---- 5 files changed, 115 insertions(+), 30 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 310bea93ca7..b9cf0b1db04 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -317,7 +317,10 @@ class CallOpSendMessage { protected: void AddOp(grpc_op* ops, size_t* nops) { - if (!send_buf_.Valid() || hijacked_) return; + if ((msg_ == nullptr && !send_buf_.Valid()) || hijacked_) return; + if (msg_ != nullptr) { + GPR_CODEGEN_ASSERT(serializer_(msg_).ok()); + } grpc_op* op = &ops[(*nops)++]; op->op = GRPC_OP_SEND_MESSAGE; op->flags = write_options_.flags(); @@ -330,17 +333,17 @@ class CallOpSendMessage { void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - if (!send_buf_.Valid()) return; + if (msg_ == nullptr && !send_buf_.Valid()) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE); - interceptor_methods->SetSendMessage(&send_buf_, msg_); + interceptor_methods->SetSendMessage(&send_buf_, &msg_, serializer_); } void SetFinishInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { // The contents of the SendMessage value that was previously set // has had its references stolen by core's operations - interceptor_methods->SetSendMessage(nullptr, nullptr); + interceptor_methods->SetSendMessage(nullptr, nullptr, nullptr); } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { @@ -352,6 +355,7 @@ class CallOpSendMessage { bool hijacked_ = false; ByteBuffer send_buf_; WriteOptions write_options_; + std::function serializer_; }; template @@ -362,12 +366,21 @@ Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) { // The void in the template parameter below should not be needed // (since it should be implicit) but is needed due to an observed // difference in behavior between clang and gcc for certain internal users - Status result = SerializationTraits::Serialize( - message, send_buf_.bbuf_ptr(), &own_buf); - if (!own_buf) { - send_buf_.Duplicate(); + serializer_ = [this](const void* message) { + bool own_buf; + send_buf_.Clear(); + Status result = SerializationTraits::Serialize( + *static_cast(message), send_buf_.bbuf_ptr(), &own_buf); + if (!own_buf) { + send_buf_.Duplicate(); + } + return result; + }; + // Serialize immediately only if we do not have access to the message pointer + if (msg_ == nullptr) { + return serializer_(&message); } - return result; + return Status::OK; } template diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 5a9a3a44e6e..edf3ab49f16 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -117,6 +117,8 @@ class InterceptorBatchMethods { /// only supported for sync and callback APIs at the present moment. virtual const void* GetSendMessage() = 0; + virtual void ModifySendMessage(const void* message) = 0; + /// Returns a modifiable multimap of the initial metadata to be sent. Valid /// for PRE_SEND_INITIAL_METADATA interceptions. A value of nullptr indicates /// that this field is not valid. diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 4b7eaefee1b..6fa6210dc36 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -79,9 +79,24 @@ class InterceptorBatchMethodsImpl hooks_[static_cast(type)] = true; } - ByteBuffer* GetSerializedSendMessage() override { return send_message_; } + ByteBuffer* GetSerializedSendMessage() override { + GPR_CODEGEN_ASSERT(orig_send_message_ != nullptr); + if (*orig_send_message_ != nullptr) { + GPR_CODEGEN_ASSERT(serializer_(*orig_send_message_).ok()); + *orig_send_message_ = nullptr; + } + return send_message_; + } - const void* GetSendMessage() override { return orig_send_message_; } + const void* GetSendMessage() override { + GPR_CODEGEN_ASSERT(orig_send_message_ != nullptr); + return *orig_send_message_; + } + + void ModifySendMessage(const void* message) override { + GPR_CODEGEN_ASSERT(orig_send_message_ != nullptr); + *orig_send_message_ = message; + } std::multimap* GetSendInitialMetadata() override { return send_initial_metadata_; @@ -117,9 +132,11 @@ class InterceptorBatchMethodsImpl return recv_trailing_metadata_->map(); } - void SetSendMessage(ByteBuffer* buf, const void* msg) { + void SetSendMessage(ByteBuffer* buf, const void** msg, + std::function serializer) { send_message_ = buf; orig_send_message_ = msg; + serializer_ = serializer; } void SetSendInitialMetadata( @@ -339,7 +356,8 @@ class InterceptorBatchMethodsImpl std::function callback_; ByteBuffer* send_message_ = nullptr; - const void* orig_send_message_ = nullptr; + const void** orig_send_message_ = nullptr; + std::function serializer_; std::multimap* send_initial_metadata_; @@ -400,6 +418,13 @@ class CancelInterceptorBatchMethods return nullptr; } + void ModifySendMessage(const void* message) override { + GPR_CODEGEN_ASSERT( + false && + "It is illegal to call ModifySendMessage on a method which " + "has a Cancel notification"); + } + std::multimap* GetSendInitialMetadata() override { GPR_CODEGEN_ASSERT(false && "It is illegal to call GetSendInitialMetadata on a " diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 3db709e956e..ea72c1eda88 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -287,16 +287,16 @@ class LoggingInterceptor : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; + EXPECT_EQ(static_cast(methods->GetSendMessage()) + ->message() + .find("Hello"), + 0u); auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); EXPECT_TRUE(req.message().find("Hello") == 0u); - EXPECT_EQ(static_cast(methods->GetSendMessage()) - ->message() - .find("Hello"), - 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 09e855b0d01..82f142ba913 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -142,29 +142,68 @@ class LoggingInterceptorFactory } }; -// Test if GetSendMessage works as expected -class GetSendMessageTester : public experimental::Interceptor { +// Test if SendMessage function family works as expected for sync/callback apis +class SyncSendMessageTester : public experimental::Interceptor { public: - GetSendMessageTester(experimental::ServerRpcInfo* info) {} + SyncSendMessageTester(experimental::ServerRpcInfo* info) {} void Intercept(experimental::InterceptorBatchMethods* methods) override { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { - EXPECT_EQ(static_cast(methods->GetSendMessage()) - ->message() - .find("Hello"), - 0u); + string old_msg = + static_cast(methods->GetSendMessage())->message(); + EXPECT_EQ(old_msg.find("Hello"), 0u); + new_msg_.set_message("World" + old_msg); + methods->ModifySendMessage(&new_msg_); } methods->Proceed(); } + + private: + EchoRequest new_msg_; }; -class GetSendMessageTesterFactory +class SyncSendMessageTesterFactory : public experimental::ServerInterceptorFactoryInterface { public: virtual experimental::Interceptor* CreateServerInterceptor( experimental::ServerRpcInfo* info) override { - return new GetSendMessageTester(info); + return new SyncSendMessageTester(info); + } +}; + +// Test if SendMessage function family works as expected for sync/callback apis +class SyncSendMessageVerifier : public experimental::Interceptor { + public: + SyncSendMessageVerifier(experimental::ServerRpcInfo* info) {} + + void Intercept(experimental::InterceptorBatchMethods* methods) override { + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + // Make sure that the changes made in SyncSendMessageTester persisted + string old_msg = + static_cast(methods->GetSendMessage())->message(); + EXPECT_EQ(old_msg.find("World"), 0u); + + // Remove the "World" part of the string that we added earlier + new_msg_.set_message(old_msg.erase(0, 5)); + methods->ModifySendMessage(&new_msg_); + + // LoggingInterceptor verifies that changes got reverted + } + methods->Proceed(); + } + + private: + EchoRequest new_msg_; +}; + +class SyncSendMessageVerifierFactory + : public experimental::ServerInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateServerInterceptor( + experimental::ServerRpcInfo* info) override { + return new SyncSendMessageVerifier(info); } }; @@ -201,10 +240,13 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { creators; creators.push_back( std::unique_ptr( - new LoggingInterceptorFactory())); + new SyncSendMessageTesterFactory())); creators.push_back( std::unique_ptr( - new GetSendMessageTesterFactory())); + new SyncSendMessageVerifierFactory())); + creators.push_back( + std::unique_ptr( + new LoggingInterceptorFactory())); // Add 20 dummy interceptor factories and null interceptor factories for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( @@ -244,10 +286,13 @@ class ServerInterceptorsEnd2endSyncStreamingTest : public ::testing::Test { creators; creators.push_back( std::unique_ptr( - new LoggingInterceptorFactory())); + new SyncSendMessageTesterFactory())); creators.push_back( std::unique_ptr( - new GetSendMessageTesterFactory())); + new SyncSendMessageVerifierFactory())); + creators.push_back( + std::unique_ptr( + new LoggingInterceptorFactory())); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); From df49204b975b898392655a4af5a0597d7b2ec850 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 3 Jan 2019 18:10:21 -0800 Subject: [PATCH 0690/2143] Remove unused variable --- include/grpcpp/impl/codegen/call_op_set.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index b9cf0b1db04..88c744a3fcf 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -361,7 +361,6 @@ class CallOpSendMessage { template Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) { write_options_ = options; - bool own_buf; // TODO(vjpai): Remove the void below when possible // The void in the template parameter below should not be needed // (since it should be implicit) but is needed due to an observed From 7eeda22d9ed2f9936ec5a2ad61076274dfb5282b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 3 Jan 2019 18:23:15 -0800 Subject: [PATCH 0691/2143] s/two/three --- include/grpcpp/impl/codegen/interceptor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 0ad257bcd6d..519c65c7178 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -46,7 +46,7 @@ namespace experimental { /// 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. enum class InterceptionHookPoints { - /// The first two in this list are for clients and servers + /// The first three in this list are for clients and servers PRE_SEND_INITIAL_METADATA, PRE_SEND_MESSAGE, POST_SEND_MESSAGE, From 2b4781ca526b0823fbea263a5c7b07fdf8abe41d Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 3 Jan 2019 18:32:10 -0800 Subject: [PATCH 0692/2143] Use Status() instead of Status::OK to avoid issues with codegen_test_minimal --- include/grpcpp/impl/codegen/call_op_set.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 88c744a3fcf..e8a4d389f17 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -379,7 +379,7 @@ Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) { if (msg_ == nullptr) { return serializer_(&message); } - return Status::OK; + return Status(); } template From c4ed5b33c4de7d239f9ee26e128e4ee26e677465 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Fri, 4 Jan 2019 09:21:17 +0000 Subject: [PATCH 0693/2143] 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 4cbdf08e61b2f168a42a8984b58126aebdb9097e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 4 Jan 2019 10:33:18 +0100 Subject: [PATCH 0694/2143] debug out of disk space in run_interop_matrix_tests.py --- tools/internal_ci/linux/grpc_interop_matrix.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/internal_ci/linux/grpc_interop_matrix.sh b/tools/internal_ci/linux/grpc_interop_matrix.sh index a5220ea087f..5f1f69db952 100755 --- a/tools/internal_ci/linux/grpc_interop_matrix.sh +++ b/tools/internal_ci/linux/grpc_interop_matrix.sh @@ -22,4 +22,15 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc -tools/interop_matrix/run_interop_matrix_tests.py $RUN_TESTS_FLAGS +# TODO(jtattermusch): Diagnose out of disk space problems. Remove once not needed. +df -h + +tools/interop_matrix/run_interop_matrix_tests.py $RUN_TESTS_FLAGS || FAILED="true" + +# TODO(jtattermusch): Diagnose out of disk space problems. Remove once not needed. +df -h + +if [ "$FAILED" != "" ] +then + exit 1 +fi From b0663e7e1ebb164982fc3ca95c453c4b4dad5964 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 4 Jan 2019 12:31:34 +0100 Subject: [PATCH 0695/2143] interop_matrix: reliable cleanup of interop docker images --- .../run_interop_matrix_tests.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index 6cf2a9b0365..d47b0ee0f7b 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -232,10 +232,13 @@ def _run_tests_for_lang(lang, runtime, images, xml_report_tree): images is a list of (, ) tuple. """ + skip_tests = False if not _pull_images_for_lang(lang, images): jobset.message( - 'FAILED', 'Image download failed. Exiting.', do_newline=True) - return 1 + 'FAILED', + 'Image download failed. Skipping tests for language "%s"' % lang, + do_newline=True) + skip_tests = True total_num_failures = 0 for release, image in images: @@ -246,17 +249,22 @@ def _run_tests_for_lang(lang, runtime, images, xml_report_tree): if not job_spec_list: jobset.message( 'FAILED', 'No test cases were found.', do_newline=True) - return 1 + total_num_failures += 1 + continue num_failures, resultset = jobset.run( job_spec_list, newline_on_success=True, add_env={'docker_image': image}, - maxjobs=args.jobs) + maxjobs=args.jobs, + skip_jobs=skip_tests) if args.bq_result_table and resultset: upload_test_results.upload_interop_results_to_bq( resultset, args.bq_result_table) - if num_failures: + if skip_tests: + jobset.message('FAILED', 'Tests were skipped', do_newline=True) + total_num_failures += 1 + elif num_failures: jobset.message('FAILED', 'Some tests failed', do_newline=True) total_num_failures += num_failures else: @@ -266,6 +274,8 @@ def _run_tests_for_lang(lang, runtime, images, xml_report_tree): 'grpc_interop_matrix', suite_name, str(uuid.uuid4())) + # cleanup all downloaded docker images + for _, image in images: if not args.keep: _cleanup_docker_image(image) From b4a926961abc9e29016b2ba30093f3925de10514 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 4 Jan 2019 09:40:18 -0800 Subject: [PATCH 0696/2143] Fix static analizer errors --- src/objective-c/GRPCClient/GRPCCallOptions.m | 11 ++++++++--- src/objective-c/GRPCClient/private/GRPCChannelPool.h | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index d3440ee6c07..e59a812bd85 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -160,7 +160,10 @@ static BOOL areObjectsEqual(id obj1, id obj2) { _timeout = timeout < 0 ? 0 : timeout; _oauth2AccessToken = [oauth2AccessToken copy]; _authTokenProvider = authTokenProvider; - _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; + _initialMetadata = + initialMetadata == nil + ? nil + : [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; _userAgentPrefix = [userAgentPrefix copy]; _responseSizeLimit = responseSizeLimit; _compressionAlgorithm = compressionAlgorithm; @@ -171,7 +174,9 @@ static BOOL areObjectsEqual(id obj1, id obj2) { _connectInitialBackoff = connectInitialBackoff < 0 ? 0 : connectInitialBackoff; _connectMaxBackoff = connectMaxBackoff < 0 ? 0 : connectMaxBackoff; _additionalChannelArgs = - [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; + additionalChannelArgs == nil + ? nil + : [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; _PEMRootCertificates = [PEMRootCertificates copy]; _PEMPrivateKey = [PEMPrivateKey copy]; _PEMCertificateChain = [PEMCertificateChain copy]; @@ -458,7 +463,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { - (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout { if (connectMinTimeout < 0) { - connectMinTimeout = 0; + _connectMinTimeout = 0; } else { _connectMinTimeout = connectMinTimeout; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h index d3a99ca8263..e00ee69e63a 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.h +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -88,7 +88,8 @@ NS_ASSUME_NONNULL_BEGIN /** * Return a channel with a particular configuration. The channel may be a cached channel. */ -- (GRPCPooledChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions; +- (nullable GRPCPooledChannel *)channelWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions; /** * Disconnect all channels in this pool. From a5ed3d245e448c1e0e0e28b93e5821aaa7a3e439 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 4 Jan 2019 11:17:35 -0800 Subject: [PATCH 0697/2143] Avoid unsigned signed comparison issues --- test/cpp/end2end/client_interceptors_end2end_test.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index ab387aa9144..fc75fdb290b 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -291,7 +291,7 @@ class BidiStreamingRpcHijackingInterceptor : public experimental::Interceptor { EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); - EXPECT_EQ(req.message().find("Hello"), 0); + EXPECT_EQ(req.message().find("Hello"), 0u); msg = req.message(); } if (methods->QueryInterceptionHookPoint( @@ -316,7 +316,7 @@ class BidiStreamingRpcHijackingInterceptor : public experimental::Interceptor { EXPECT_EQ(static_cast(methods->GetRecvMessage()) ->message() .find("Hello"), - 0); + 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { @@ -370,7 +370,7 @@ class LoggingInterceptor : public experimental::Interceptor { EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); - EXPECT_TRUE(req.message().find("Hello") == 0); + EXPECT_TRUE(req.message().find("Hello") == 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { @@ -386,7 +386,7 @@ class LoggingInterceptor : public experimental::Interceptor { experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { EchoResponse* resp = static_cast(methods->GetRecvMessage()); - EXPECT_TRUE(resp->message().find("Hello") == 0); + EXPECT_TRUE(resp->message().find("Hello") == 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_STATUS)) { From 9b9ef640278fd5d0c9a64c1b0c7182277bc35f53 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 4 Jan 2019 11:29:57 -0800 Subject: [PATCH 0698/2143] Add more information on the usage of FailHijackedRecvMessage --- include/grpcpp/impl/codegen/interceptor.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index a1cb80013da..cf92ce46b43 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -157,7 +157,9 @@ class InterceptorBatchMethods { /// list. virtual std::unique_ptr GetInterceptedChannel() = 0; - // On a hijacked RPC, an interceptor can decide to fail a RECV MESSAGE op. + /// On a hijacked RPC, an interceptor can decide to fail a PRE_RECV_MESSAGE + /// op. This would be a signal to the reader that there will be no more + /// messages, or the stream has failed or been cancelled. virtual void FailHijackedRecvMessage() = 0; }; From d79d2f1ca763d758b2d83a39a27c3e7e698e94a9 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 4 Jan 2019 13:59:19 -0800 Subject: [PATCH 0699/2143] Do not reload grpc in unit tests This can break subsequently run tests, including any which have already stored references to gRPC enums (such as grpc.StatusCode.OK). The subsequent tests will compare now be comparing the old enums to the reloaded enums, and they will not match. This causes errors in _metadata_code_details_test and a hang in _metadata_flags_test, when run in sequence locally after _logging_test. It's unclear why this has been working on Kokoro, but it is reproducible locally and is behavior that should be avoided. --- .../grpcio_tests/tests/unit/_logging_test.py | 110 +++++++++++------- 1 file changed, 65 insertions(+), 45 deletions(-) diff --git a/src/python/grpcio_tests/tests/unit/_logging_test.py b/src/python/grpcio_tests/tests/unit/_logging_test.py index 631b9de9db5..8ff127f5062 100644 --- a/src/python/grpcio_tests/tests/unit/_logging_test.py +++ b/src/python/grpcio_tests/tests/unit/_logging_test.py @@ -14,66 +14,86 @@ """Test of gRPC Python's interaction with the python logging module""" import unittest -import six -from six.moves import reload_module import logging import grpc -import functools +import subprocess import sys - -def patch_stderr(f): - - @functools.wraps(f) - def _impl(*args, **kwargs): - old_stderr = sys.stderr - sys.stderr = six.StringIO() - try: - f(*args, **kwargs) - finally: - sys.stderr = old_stderr - - return _impl - - -def isolated_logging(f): - - @functools.wraps(f) - def _impl(*args, **kwargs): - reload_module(logging) - reload_module(grpc) - try: - f(*args, **kwargs) - finally: - reload_module(logging) - - return _impl +INTERPRETER = sys.executable class LoggingTest(unittest.TestCase): - @isolated_logging def test_logger_not_occupied(self): - self.assertEqual(0, len(logging.getLogger().handlers)) + script = """if True: + import logging + + import grpc + + if len(logging.getLogger().handlers) != 0: + raise Exception('expected 0 logging handlers') + + """ + self._verifyScriptSucceeds(script) - @patch_stderr - @isolated_logging def test_handler_found(self): - self.assertEqual(0, len(sys.stderr.getvalue())) + script = """if True: + import logging + + import grpc + """ + out, err = self._verifyScriptSucceeds(script) + self.assertEqual(0, len(err), 'unexpected output to stderr') - @isolated_logging def test_can_configure_logger(self): - intended_stream = six.StringIO() - logging.basicConfig(stream=intended_stream) - self.assertEqual(1, len(logging.getLogger().handlers)) - self.assertIs(logging.getLogger().handlers[0].stream, intended_stream) + script = """if True: + import logging + import six + + import grpc + + + intended_stream = six.StringIO() + logging.basicConfig(stream=intended_stream) + + if len(logging.getLogger().handlers) != 1: + raise Exception('expected 1 logging handler') + + if logging.getLogger().handlers[0].stream is not intended_stream: + raise Exception('wrong handler stream') + + """ + self._verifyScriptSucceeds(script) - @isolated_logging def test_grpc_logger(self): - self.assertIn("grpc", logging.Logger.manager.loggerDict) - root_logger = logging.getLogger("grpc") - self.assertEqual(1, len(root_logger.handlers)) - self.assertIsInstance(root_logger.handlers[0], logging.NullHandler) + script = """if True: + import logging + + import grpc + + if "grpc" not in logging.Logger.manager.loggerDict: + raise Exception('grpc logger not found') + + root_logger = logging.getLogger("grpc") + if len(root_logger.handlers) != 1: + raise Exception('expected 1 root logger handler') + if not isinstance(root_logger.handlers[0], logging.NullHandler): + raise Exception('expected logging.NullHandler') + + """ + self._verifyScriptSucceeds(script) + + def _verifyScriptSucceeds(self, script): + process = subprocess.Popen( + [INTERPRETER, '-c', script], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out, err = process.communicate() + self.assertEqual( + 0, process.returncode, + 'process failed with exit code %d (stdout: %s, stderr: %s)' % + (process.returncode, out, err)) + return out, err if __name__ == '__main__': From 4b2086eecdb6fb97c1fa791c58f23c22acea74be Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 4 Jan 2019 14:12:11 -0800 Subject: [PATCH 0700/2143] restore cython flag value to default after test --- src/python/grpcio_tests/tests/unit/_cython/_fork_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py b/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py index aeb02458a7e..5a5dedd5f26 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py @@ -27,6 +27,7 @@ def _get_number_active_threads(): class ForkPosixTester(unittest.TestCase): def setUp(self): + self._saved_fork_support_flag = cygrpc._GRPC_ENABLE_FORK_SUPPORT cygrpc._GRPC_ENABLE_FORK_SUPPORT = True def testForkManagedThread(self): @@ -50,6 +51,9 @@ class ForkPosixTester(unittest.TestCase): thread.join() self.assertEqual(0, _get_number_active_threads()) + def tearDown(self): + cygrpc._GRPC_ENABLE_FORK_SUPPORT = self._saved_fork_support_flag + @unittest.skipUnless(os.name == 'nt', 'Windows-specific tests') class ForkWindowsTester(unittest.TestCase): From 814c858f3f2363a1ac59e137aa479a5b29ef0762 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 4 Jan 2019 18:45:01 -0800 Subject: [PATCH 0701/2143] 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 0d6e10e795e9c627368afebf7d877bc392cd78dd Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Mon, 7 Jan 2019 10:15:07 -0500 Subject: [PATCH 0702/2143] clang-format all the files. Whenever we run clang-format, gen_build_yaml.py and ServerServiceDefinitionExtensions.cs get modified by the script. Let's commit those changes so that these file remain unmodified after running the formatting script. --- .../Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs | 2 +- test/cpp/qps/gen_build_yaml.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs b/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs index 8987544f7f4..56ead8a6a15 100644 --- a/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs +++ b/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs @@ -76,4 +76,4 @@ namespace Grpc.Core.Interceptors return serverServiceDefinition; } } -} \ No newline at end of file +} diff --git a/test/cpp/qps/gen_build_yaml.py b/test/cpp/qps/gen_build_yaml.py index fb2caf5486a..8ca0dc6a620 100755 --- a/test/cpp/qps/gen_build_yaml.py +++ b/test/cpp/qps/gen_build_yaml.py @@ -131,4 +131,4 @@ def generate_yaml(): } -print(yaml.dump(generate_yaml())) \ No newline at end of file +print(yaml.dump(generate_yaml())) From 747608df379e0a06ccc5cea469455d80591ea430 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 17:16:04 +0100 Subject: [PATCH 0703/2143] add go1.11 interop image templates --- .../grpc_interop_go1.11/Dockerfile.template | 23 +++++++++++++++++++ .../build_interop.sh.template | 3 +++ 2 files changed, 26 insertions(+) create mode 100644 templates/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile.template create mode 100644 templates/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh.template diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile.template new file mode 100644 index 00000000000..4921d93f499 --- /dev/null +++ b/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile.template @@ -0,0 +1,23 @@ +%YAML 1.2 +--- | + # 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. + + FROM golang:1.11 + + <%include file="../../go_path.include"/> + <%include file="../../python_deps.include"/> + # Define the default command. + CMD ["bash"] + diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh.template b/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh.template new file mode 100644 index 00000000000..a08798b1d6b --- /dev/null +++ b/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh.template @@ -0,0 +1,3 @@ +%YAML 1.2 +--- | + <%include file="../../go_build_interop.sh.include"/> From bdee6308312376d28e762e49b3d7834c1e925d06 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Dec 2018 17:16:39 +0100 Subject: [PATCH 0704/2143] regenerate dockerimages --- .../grpc_interop_go1.11/Dockerfile | 36 +++++++++++++++++++ .../grpc_interop_go1.11/build_interop.sh | 33 +++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile create mode 100644 tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh diff --git a/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile new file mode 100644 index 00000000000..0892bc34599 --- /dev/null +++ b/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile @@ -0,0 +1,36 @@ +# 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. + +FROM golang:1.11 + +# Using login shell removes Go from path, so we add it. +RUN ln -s /usr/local/go/bin/go /usr/local/bin + +#==================== +# 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 + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh new file mode 100644 index 00000000000..b11ace3a4e7 --- /dev/null +++ b/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# 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. +# +# Builds Go interop server and client in a base image. +set -e + +# Clone just the grpc-go source code without any dependencies. +# We are cloning from a local git repo that contains the right revision +# to test instead of using "go get" to download from Github directly. +git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc + +# Get all gRPC Go dependencies +(cd src/google.golang.org/grpc && make deps && make testdeps) + +# copy service account keys if available +cp -r /var/local/jenkins/service_account $HOME || true + +# Build the interop client and server +(cd src/google.golang.org/grpc/interop/client && go install) +(cd src/google.golang.org/grpc/interop/server && go install) + From a13e77e14db90fd2b0a87ca151b4db0786f34ff6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 7 Jan 2019 11:47:33 -0500 Subject: [PATCH 0705/2143] interop_matrix: support skipping runtimes --- tools/interop_matrix/client_matrix.py | 83 +++++++++++++++---- tools/interop_matrix/create_matrix_images.py | 2 +- .../run_interop_matrix_tests.py | 15 ++-- 3 files changed, 76 insertions(+), 24 deletions(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index c0b08a59b26..3546d59c313 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -35,6 +35,18 @@ def get_release_tag_name(release_info): return release_info.keys()[0] +def get_runtimes_for_lang_release(lang, release): + """Get list of valid runtimes for given release of lang.""" + runtimes_to_skip = [] + # see if any the lang release has "skip_runtime" annotation. + for release_info in LANG_RELEASE_MATRIX[lang]: + if get_release_tag_name(release_info) == release: + if release_info[release] is not None: + runtimes_to_skip = release_info[release].get('skip_runtime', []) + break + return [runtime for runtime in LANG_RUNTIME_MATRIX[lang] if runtime not in runtimes_to_skip] + + def should_build_docker_interop_image_from_release_tag(lang): if lang in ['go', 'java', 'node']: return False @@ -44,7 +56,7 @@ def should_build_docker_interop_image_from_release_tag(lang): # Dictionary of runtimes per language LANG_RUNTIME_MATRIX = { 'cxx': ['cxx'], # This is actually debian8. - 'go': ['go1.7', 'go1.8'], + 'go': ['go1.7', 'go1.8', 'go1.11'], 'java': ['java_oracle8'], 'python': ['python'], 'node': ['node'], @@ -110,52 +122,89 @@ LANG_RELEASE_MATRIX = { ], 'go': [ { - 'v1.0.5': None + 'v1.0.5': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.2.1': None + 'v1.2.1': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.3.0': None + 'v1.3.0': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.4.2': None + 'v1.4.2': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.5.2': None + 'v1.5.2': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.6.0': None + 'v1.6.0': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.7.4': None + 'v1.7.4': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.8.2': None + 'v1.8.2': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.9.2': None + 'v1.9.2': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.10.1': None + 'v1.10.1': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.11.3': None + 'v1.11.3': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.12.2': None + 'v1.12.2': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.13.0': None + 'v1.13.0': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.14.0': None + 'v1.14.0': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.15.0': None + 'v1.15.0': { + 'skip_runtime': ['go1.11'] + } }, { - 'v1.16.0': None + 'v1.16.0': { + 'skip_runtime': ['go1.11'] + } + }, + { + 'v1.17.0': { + 'skip_runtime': ['go1.7', 'go1.8'] + } }, ], 'java': [ diff --git a/tools/interop_matrix/create_matrix_images.py b/tools/interop_matrix/create_matrix_images.py index c2568efba0f..cf61d462482 100755 --- a/tools/interop_matrix/create_matrix_images.py +++ b/tools/interop_matrix/create_matrix_images.py @@ -217,7 +217,7 @@ def build_all_images_for_release(lang, release): }.get(lang, 'GRPC_ROOT') env[var] = stack_base - for runtime in client_matrix.LANG_RUNTIME_MATRIX[lang]: + for runtime in client_matrix.get_runtimes_for_lang_release(lang, release): job = build_image_jobspec(runtime, env, release, stack_base) docker_images.append(job.tag) build_jobs.append(job) diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index 6cf2a9b0365..693996031e3 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -113,13 +113,16 @@ def _get_test_images_for_lang(lang, release_arg, image_path_prefix): return {} releases = [release_arg] - # Images tuples keyed by runtime. + # Image tuples keyed by runtime. images = {} - for runtime in client_matrix.LANG_RUNTIME_MATRIX[lang]: - image_path = '%s/grpc_interop_%s' % (image_path_prefix, runtime) - images[runtime] = [ - (tag, '%s:%s' % (image_path, tag)) for tag in releases - ] + for tag in releases: + for runtime in client_matrix.get_runtimes_for_lang_release(lang, tag): + image_name = '%s/grpc_interop_%s:%s' % (image_path_prefix, runtime, tag) + image_tuple = (tag, image_name) + + if not images.has_key(runtime): + images[runtime] = [] + images[runtime].append(image_tuple) return images From 7d1491d64c9b6279233c780d290c514a7040c1c7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 7 Jan 2019 09:23:35 -0800 Subject: [PATCH 0706/2143] Address reviewer comments --- include/grpcpp/impl/codegen/call_op_set.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index e8a4d389f17..ced0b2ff3e6 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -321,6 +321,7 @@ class CallOpSendMessage { if (msg_ != nullptr) { GPR_CODEGEN_ASSERT(serializer_(msg_).ok()); } + serializer_ = nullptr; grpc_op* op = &ops[(*nops)++]; op->op = GRPC_OP_SEND_MESSAGE; op->flags = write_options_.flags(); @@ -361,13 +362,13 @@ class CallOpSendMessage { template Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) { write_options_ = options; - // TODO(vjpai): Remove the void below when possible - // The void in the template parameter below should not be needed - // (since it should be implicit) but is needed due to an observed - // difference in behavior between clang and gcc for certain internal users serializer_ = [this](const void* message) { bool own_buf; send_buf_.Clear(); + // TODO(vjpai): Remove the void below when possible + // The void in the template parameter below should not be needed + // (since it should be implicit) but is needed due to an observed + // difference in behavior between clang and gcc for certain internal users Status result = SerializationTraits::Serialize( *static_cast(message), send_buf_.bbuf_ptr(), &own_buf); if (!own_buf) { From 2dc63f3d02efd2cb0ccea45248dd305e442c70d9 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 7 Jan 2019 19:08:02 +0100 Subject: [PATCH 0707/2143] yapf code --- tools/interop_matrix/client_matrix.py | 5 ++++- tools/interop_matrix/run_interop_matrix_tests.py | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 3546d59c313..4964fd61674 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -44,7 +44,10 @@ def get_runtimes_for_lang_release(lang, release): if release_info[release] is not None: runtimes_to_skip = release_info[release].get('skip_runtime', []) break - return [runtime for runtime in LANG_RUNTIME_MATRIX[lang] if runtime not in runtimes_to_skip] + return [ + runtime for runtime in LANG_RUNTIME_MATRIX[lang] + if runtime not in runtimes_to_skip + ] def should_build_docker_interop_image_from_release_tag(lang): diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index 693996031e3..d75cab90c25 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -117,7 +117,8 @@ def _get_test_images_for_lang(lang, release_arg, image_path_prefix): images = {} for tag in releases: for runtime in client_matrix.get_runtimes_for_lang_release(lang, tag): - image_name = '%s/grpc_interop_%s:%s' % (image_path_prefix, runtime, tag) + image_name = '%s/grpc_interop_%s:%s' % (image_path_prefix, runtime, + tag) image_tuple = (tag, image_name) if not images.has_key(runtime): From 5e10a3b037bcd20ab17428ccb765ba9464eb3644 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 21 Dec 2018 13:39:21 -0800 Subject: [PATCH 0708/2143] Make gRPC ObjC thread safety right --- src/objective-c/GRPCClient/GRPCCall.m | 364 ++++++++++-------- src/objective-c/RxLibrary/GRXBufferedPipe.m | 21 +- .../RxLibrary/GRXConcurrentWriteable.h | 4 +- .../RxLibrary/GRXConcurrentWriteable.m | 76 +--- .../RxLibrary/GRXForwardingWriter.m | 48 ++- .../RxLibrary/GRXImmediateSingleWriter.m | 30 +- src/objective-c/RxLibrary/GRXWriter.h | 4 +- 7 files changed, 277 insertions(+), 270 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 83c6edc6e3f..5ea1755c589 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -448,24 +448,30 @@ const char *kCFStreamVarName = "grpc_cfstream"; return; } NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; - switch (callSafety) { - case GRPCCallSafetyDefault: - callFlags[hostAndPath] = @0; - break; - case GRPCCallSafetyIdempotentRequest: - callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; - break; - case GRPCCallSafetyCacheableRequest: - callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; - break; - default: - break; + @synchronized (callFlags) { + switch (callSafety) { + case GRPCCallSafetyDefault: + callFlags[hostAndPath] = @0; + break; + case GRPCCallSafetyIdempotentRequest: + callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; + break; + case GRPCCallSafetyCacheableRequest: + callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; + break; + default: + break; + } } } + (uint32_t)callFlagsForHost:(NSString *)host path:(NSString *)path { NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; - return [callFlags[hostAndPath] intValue]; + uint32_t flags = 0; + @synchronized (callFlags) { + flags = [callFlags[hostAndPath] intValue]; + } + return flags; } // Designated initializer @@ -506,7 +512,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _callOptions = [callOptions copy]; // Serial queue to invoke the non-reentrant methods of the grpc_call object. - _callQueue = dispatch_queue_create("io.grpc.call", NULL); + _callQueue = dispatch_queue_create("io.grpc.call", DISPATCH_QUEUE_SERIAL); _requestWriter = requestWriter; @@ -523,53 +529,49 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)setResponseDispatchQueue:(dispatch_queue_t)queue { - if (_state != GRXWriterStateNotStarted) { - return; + @synchronized (self) { + if (_state != GRXWriterStateNotStarted) { + return; + } + _responseQueue = queue; } - _responseQueue = queue; } #pragma mark Finish - (void)finishWithError:(NSError *)errorOrNil { - @synchronized(self) { - _state = GRXWriterStateFinished; - } + GRXConcurrentWriteable *copiedResponseWriteable = nil; - // If there were still request messages coming, stop them. - @synchronized(_requestWriter) { - _requestWriter.state = GRXWriterStateFinished; + @synchronized(self) { + if (_state == GRXWriterStateFinished) { + return; + } + _state = GRXWriterStateFinished; + copiedResponseWriteable = _responseWriteable; + + // If the call isn't retained anywhere else, it can be deallocated now. + _retainSelf = nil; } if (errorOrNil) { - [_responseWriteable cancelWithError:errorOrNil]; + [copiedResponseWriteable cancelWithError:errorOrNil]; } else { - [_responseWriteable enqueueSuccessfulCompletion]; - } - - [GRPCConnectivityMonitor unregisterObserver:self]; - - // If the call isn't retained anywhere else, it can be deallocated now. - _retainSelf = nil; -} - -- (void)cancelCall { - // Can be called from any thread, any number of times. - @synchronized(self) { - [_wrappedCall cancel]; + [copiedResponseWriteable enqueueSuccessfulCompletion]; } + _requestWriter.state = GRXWriterStateFinished; } - (void)cancel { - @synchronized(self) { - [self cancelCall]; - self.isWaitingForToken = NO; + @synchronized (self) { + if (_state == GRXWriterStateFinished) { + return; + } + [self finishWithError:[NSError + errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]]; + [_wrappedCall cancel]; } - [self - maybeFinishWithError:[NSError - errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]]; } - (void)maybeFinishWithError:(NSError *)errorOrNil { @@ -609,21 +611,24 @@ const char *kCFStreamVarName = "grpc_cfstream"; // TODO(jcanizales): Rename to readResponseIfNotPaused. - (void)startNextRead { @synchronized(self) { - if (self.state == GRXWriterStatePaused) { + if (_state != GRXWriterStateStarted) { return; } } dispatch_async(_callQueue, ^{ __weak GRPCCall *weakSelf = self; - __weak GRXConcurrentWriteable *weakWriteable = self->_responseWriteable; [self startReadWithHandler:^(grpc_byte_buffer *message) { - __strong GRPCCall *strongSelf = weakSelf; - __strong GRXConcurrentWriteable *strongWriteable = weakWriteable; + NSLog(@"message received"); if (message == NULL) { // No more messages from the server return; } + __strong GRPCCall *strongSelf = weakSelf; + if (strongSelf == nil) { + grpc_byte_buffer_destroy(message); + return; + } NSData *data = [NSData grpc_dataWithByteBuffer:message]; grpc_byte_buffer_destroy(message); if (!data) { @@ -631,21 +636,25 @@ const char *kCFStreamVarName = "grpc_cfstream"; // don't want to throw, because the app shouldn't crash for a behavior // that's on the hands of any server to have. Instead we finish and ask // the server to cancel. - [strongSelf cancelCall]; - [strongSelf - maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeResourceExhausted - userInfo:@{ - NSLocalizedDescriptionKey : - @"Client does not have enough memory to " - @"hold the server response." - }]]; - return; + @synchronized (strongSelf) { + [strongSelf + finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeResourceExhausted + userInfo:@{ + NSLocalizedDescriptionKey : + @"Client does not have enough memory to " + @"hold the server response." + }]]; + [strongSelf->_wrappedCall cancel]; + } + } else { + @synchronized (strongSelf) { + [strongSelf->_responseWriteable enqueueValue:data + completionHandler:^{ + [strongSelf startNextRead]; + }]; + } } - [strongWriteable enqueueValue:data - completionHandler:^{ - [strongSelf startNextRead]; - }]; }]; }); } @@ -680,15 +689,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; } // TODO(jcanizales): Add error handlers for async failures - GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] - initWithMetadata:headers - flags:callSafetyFlags - handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA - if (!_unaryCall) { - [_wrappedCall startBatchWithOperations:@[ op ]]; - } else { - [_unaryOpBatch addObject:op]; - } + GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] initWithMetadata:headers + flags:callSafetyFlags + handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA + dispatch_async(_callQueue, ^{ + if (!self->_unaryCall) { + [self->_wrappedCall startBatchWithOperations:@[ op ]]; + } else { + [self->_unaryOpBatch addObject:op]; + } + }); } #pragma mark GRXWriteable implementation @@ -703,9 +713,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Resume the request writer. GRPCCall *strongSelf = weakSelf; if (strongSelf) { - @synchronized(strongSelf->_requestWriter) { - strongSelf->_requestWriter.state = GRXWriterStateStarted; - } + strongSelf->_requestWriter.state = GRXWriterStateStarted; } }; @@ -721,13 +729,17 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)writeValue:(id)value { - // TODO(jcanizales): Throw/assert if value isn't NSData. + NSAssert([value isKindOfClass:[NSData class]], @"value must be of type NSData"); + + @synchronized (self) { + if (_state == GRXWriterStateFinished) { + return; + } + } // Pause the input and only resume it when the C layer notifies us that writes // can proceed. - @synchronized(_requestWriter) { - _requestWriter.state = GRXWriterStatePaused; - } + _requestWriter.state = GRXWriterStatePaused; dispatch_async(_callQueue, ^{ // Write error is not processed here. It is handled by op batch of GRPC_OP_RECV_STATUS_ON_CLIENT @@ -752,6 +764,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self cancel]; } else { dispatch_async(_callQueue, ^{ + // EOS error is not processed here. It is handled by op batch of GRPC_OP_RECV_STATUS_ON_CLIENT [self finishRequestWithErrorHandler:nil]; }); @@ -766,17 +779,20 @@ const char *kCFStreamVarName = "grpc_cfstream"; // The second one (completionHandler), whenever the RPC finishes for any reason. - (void)invokeCallWithHeadersHandler:(void (^)(NSDictionary *))headersHandler completionHandler:(void (^)(NSError *, NSDictionary *))completionHandler { - // TODO(jcanizales): Add error handlers for async failures - [_wrappedCall - startBatchWithOperations:@[ [[GRPCOpRecvMetadata alloc] initWithHandler:headersHandler] ]]; - [_wrappedCall - startBatchWithOperations:@[ [[GRPCOpRecvStatus alloc] initWithHandler:completionHandler] ]]; + dispatch_async(_callQueue, ^{ + // TODO(jcanizales): Add error handlers for async failures + [self->_wrappedCall + startBatchWithOperations:@[ [[GRPCOpRecvMetadata alloc] initWithHandler:headersHandler] ]]; + [self->_wrappedCall + startBatchWithOperations:@[ [[GRPCOpRecvStatus alloc] initWithHandler:completionHandler] ]]; + }); } - (void)invokeCall { __weak GRPCCall *weakSelf = self; [self invokeCallWithHeadersHandler:^(NSDictionary *headers) { // Response headers received. + NSLog(@"response received"); __strong GRPCCall *strongSelf = weakSelf; if (strongSelf) { strongSelf.responseHeaders = headers; @@ -784,6 +800,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } } completionHandler:^(NSError *error, NSDictionary *trailers) { + NSLog(@"completion received"); __strong GRPCCall *strongSelf = weakSelf; if (strongSelf) { strongSelf.responseTrailers = trailers; @@ -794,112 +811,113 @@ const char *kCFStreamVarName = "grpc_cfstream"; [userInfo addEntriesFromDictionary:error.userInfo]; } userInfo[kGRPCTrailersKey] = strongSelf.responseTrailers; - // TODO(jcanizales): The C gRPC library doesn't guarantee that the headers block will be - // called before this one, so an error might end up with trailers but no headers. We - // shouldn't call finishWithError until ater both blocks are called. It is also when - // this is done that we can provide a merged view of response headers and trailers in a - // thread-safe way. - if (strongSelf.responseHeaders) { - userInfo[kGRPCHeadersKey] = strongSelf.responseHeaders; - } + // Since gRPC core does not guarantee the headers block being called before this block, + // responseHeaders might be nil. + userInfo[kGRPCHeadersKey] = strongSelf.responseHeaders; error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; } - [strongSelf maybeFinishWithError:error]; + [strongSelf finishWithError:error]; } }]; - // Now that the RPC has been initiated, request writes can start. - @synchronized(_requestWriter) { - [_requestWriter startWithWriteable:self]; - } } #pragma mark GRXWriter implementation +// Lock acquired inside startWithWriteable: - (void)startCallWithWriteable:(id)writeable { - _responseWriteable = - [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; + @synchronized (self) { + if (_state == GRXWriterStateFinished) { + return; + } - GRPCPooledChannel *channel = - [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; - GRPCWrappedCall *wrappedCall = [channel wrappedCallWithPath:_path - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:_callOptions]; + _responseWriteable = + [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; - if (wrappedCall == nil) { - [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeUnavailable - userInfo:@{ - NSLocalizedDescriptionKey : - @"Failed to create call or channel." - }]]; - return; + GRPCPooledChannel *channel = + [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; + _wrappedCall = [channel wrappedCallWithPath:_path + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:_callOptions]; + + if (_wrappedCall == nil) { + [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; + return; + } + + [self sendHeaders]; + [self invokeCall]; + + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; + } } - @synchronized(self) { - _wrappedCall = wrappedCall; - } - - [self sendHeaders]; - [self invokeCall]; - - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; - } + // Now that the RPC has been initiated, request writes can start. + [_requestWriter startWithWriteable:self]; } - (void)startWithWriteable:(id)writeable { + id tokenProvider = nil; @synchronized(self) { _state = GRXWriterStateStarted; - } - // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled). - // This makes RPCs in which the call isn't externally retained possible (as long as it is started - // before being autoreleased). - // Care is taken not to retain self strongly in any of the blocks used in this implementation, so - // that the life of the instance is determined by this retain cycle. - _retainSelf = self; + // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled). + // This makes RPCs in which the call isn't externally retained possible (as long as it is started + // before being autoreleased). + // Care is taken not to retain self strongly in any of the blocks used in this implementation, so + // that the life of the instance is determined by this retain cycle. + _retainSelf = self; - if (_callOptions == nil) { - GRPCMutableCallOptions *callOptions = [[GRPCHost callOptionsForHost:_host] mutableCopy]; - if (_serverName.length != 0) { - callOptions.serverAuthority = _serverName; - } - if (_timeout > 0) { - callOptions.timeout = _timeout; - } - uint32_t callFlags = [GRPCCall callFlagsForHost:_host path:_path]; - if (callFlags != 0) { - if (callFlags == GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) { - _callSafety = GRPCCallSafetyIdempotentRequest; - } else if (callFlags == GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) { - _callSafety = GRPCCallSafetyCacheableRequest; + if (_callOptions == nil) { + GRPCMutableCallOptions *callOptions = [[GRPCHost callOptionsForHost:_host] mutableCopy]; + if (_serverName.length != 0) { + callOptions.serverAuthority = _serverName; } + if (_timeout > 0) { + callOptions.timeout = _timeout; + } + uint32_t callFlags = [GRPCCall callFlagsForHost:_host path:_path]; + if (callFlags != 0) { + if (callFlags == GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) { + _callSafety = GRPCCallSafetyIdempotentRequest; + } else if (callFlags == GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) { + _callSafety = GRPCCallSafetyCacheableRequest; + } + } + + id tokenProvider = self.tokenProvider; + if (tokenProvider != nil) { + callOptions.authTokenProvider = tokenProvider; + } + _callOptions = callOptions; } - id tokenProvider = self.tokenProvider; - if (tokenProvider != nil) { - callOptions.authTokenProvider = tokenProvider; - } - _callOptions = callOptions; + NSAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, + @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); + + tokenProvider = _callOptions.authTokenProvider; } - NSAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, - @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); - if (_callOptions.authTokenProvider != nil) { - @synchronized(self) { - self.isWaitingForToken = YES; - } - [_callOptions.authTokenProvider getTokenWithHandler:^(NSString *token) { - @synchronized(self) { - if (self.isWaitingForToken) { - if (token) { - self->_fetchedOauth2AccessToken = [token copy]; + if (tokenProvider != nil) { + __weak typeof(self) weakSelf = self; + [tokenProvider getTokenWithHandler:^(NSString *token) { + __strong typeof(self) strongSelf = weakSelf; + if (strongSelf) { + @synchronized(strongSelf) { + if (strongSelf->_state == GRXWriterStateNotStarted) { + if (token) { + strongSelf->_fetchedOauth2AccessToken = [token copy]; + } } - [self startCallWithWriteable:writeable]; - self.isWaitingForToken = NO; } + [strongSelf startCallWithWriteable:writeable]; } }]; } else { @@ -938,16 +956,20 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)connectivityChanged:(NSNotification *)note { - // Cancel underlying call upon this notification + // Cancel underlying call upon this notification. + + // Retain because connectivity manager only keeps weak reference to GRPCCall. __strong GRPCCall *strongSelf = self; if (strongSelf) { - [self cancelCall]; - [self - maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeUnavailable - userInfo:@{ - NSLocalizedDescriptionKey : @"Connectivity lost." - }]]; + @synchronized (strongSelf) { + [_wrappedCall cancel]; + [strongSelf + finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : @"Connectivity lost." + }]]; + } } } diff --git a/src/objective-c/RxLibrary/GRXBufferedPipe.m b/src/objective-c/RxLibrary/GRXBufferedPipe.m index 546d46cba32..d0064a5cfaf 100644 --- a/src/objective-c/RxLibrary/GRXBufferedPipe.m +++ b/src/objective-c/RxLibrary/GRXBufferedPipe.m @@ -51,16 +51,22 @@ // We need a copy, so that it doesn't mutate before it's written at the other end of the pipe. value = [value copy]; } - __weak GRXBufferedPipe *weakSelf = self; dispatch_async(_writeQueue, ^(void) { - [weakSelf.writeable writeValue:value]; + @synchronized (self) { + if (self->_state == GRXWriterStateFinished) { + return; + } + [self.writeable writeValue:value]; + } }); } - (void)writesFinishedWithError:(NSError *)errorOrNil { - __weak GRXBufferedPipe *weakSelf = self; dispatch_async(_writeQueue, ^{ - [weakSelf finishWithError:errorOrNil]; + if (self->_state == GRXWriterStateFinished) { + return; + } + [self finishWithError:errorOrNil]; }); } @@ -100,14 +106,15 @@ } - (void)startWithWriteable:(id)writeable { - self.writeable = writeable; - _state = GRXWriterStateStarted; + @synchronized (self) { + self.writeable = writeable; + _state = GRXWriterStateStarted; + } dispatch_resume(_writeQueue); } - (void)finishWithError:(NSError *)errorOrNil { [self.writeable writesFinishedWithError:errorOrNil]; - self.state = GRXWriterStateFinished; } - (void)dealloc { diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h index abb831e6fb4..606f5dea954 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h @@ -23,9 +23,9 @@ /** * This is a thread-safe wrapper over a GRXWriteable instance. It lets one enqueue calls to a - * GRXWriteable instance for the main thread, guaranteeing that writesFinishedWithError: is the last + * GRXWriteable instance for the thread user provided, guaranteeing that writesFinishedWithError: is the last * message sent to it (no matter what messages are sent to the wrapper, in what order, nor from - * which thread). It also guarantees that, if cancelWithError: is called from the main thread (e.g. + * which thread). It also guarantees that, if cancelWithError: is called (e.g. * by the app cancelling the writes), no further messages are sent to the writeable except * writesFinishedWithError:. * diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index 81ccc3fbcea..229d592f484 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -41,6 +41,7 @@ if (self = [super init]) { _writeableQueue = queue; _writeable = writeable; + _alreadyFinished = NO; } return self; } @@ -51,78 +52,43 @@ - (void)enqueueValue:(id)value completionHandler:(void (^)(void))handler { dispatch_async(_writeableQueue, ^{ - // We're racing a possible cancellation performed by another thread. To turn all already- - // enqueued messages into noops, cancellation nillifies the writeable property. If we get it - // before it's nil, we won the race. - id writeable = self.writeable; - if (writeable) { - [writeable writeValue:value]; - handler(); + if (self->_alreadyFinished) { + return; } + + [self.writeable writeValue:value]; + handler(); }); } - (void)enqueueSuccessfulCompletion { - __weak typeof(self) weakSelf = self; dispatch_async(_writeableQueue, ^{ - typeof(self) strongSelf = weakSelf; - if (strongSelf) { - BOOL finished = NO; - @synchronized(strongSelf) { - if (!strongSelf->_alreadyFinished) { - strongSelf->_alreadyFinished = YES; - } else { - finished = YES; - } - } - if (!finished) { - // Cancellation is now impossible. None of the other three blocks can run concurrently with - // this one. - [strongSelf.writeable writesFinishedWithError:nil]; - // Skip any possible message to the wrapped writeable enqueued after this one. - strongSelf.writeable = nil; - } + if (self->_alreadyFinished) { + return; } + [self.writeable writesFinishedWithError:nil]; + // Skip any possible message to the wrapped writeable enqueued after this one. + self.writeable = nil; }); } - (void)cancelWithError:(NSError *)error { - NSAssert(error, @"For a successful completion, use enqueueSuccessfulCompletion."); - BOOL finished = NO; - @synchronized(self) { - if (!_alreadyFinished) { - _alreadyFinished = YES; - } else { - finished = YES; + NSAssert(error != nil, @"For a successful completion, use enqueueSuccessfulCompletion."); + dispatch_async(_writeableQueue, ^{ + if (self->_alreadyFinished) { + return; } - } - if (!finished) { - // Skip any of the still-enqueued messages to the wrapped writeable. We use the atomic setter to - // nillify writeable because we might be running concurrently with the blocks in - // _writeableQueue, and assignment with ARC isn't atomic. - id writeable = self.writeable; + [self.writeable writesFinishedWithError:error]; self.writeable = nil; - - dispatch_async(_writeableQueue, ^{ - [writeable writesFinishedWithError:error]; - }); - } + }); } - (void)cancelSilently { - BOOL finished = NO; - @synchronized(self) { - if (!_alreadyFinished) { - _alreadyFinished = YES; - } else { - finished = YES; + dispatch_async(_writeableQueue, ^{ + if (self->_alreadyFinished) { + return; } - } - if (!finished) { - // Skip any of the still-enqueued messages to the wrapped writeable. We use the atomic setter to - // nillify writeable because we might be running concurrently with the blocks in - // _writeableQueue, and assignment with ARC isn't atomic. self.writeable = nil; - } + }); } @end diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.m b/src/objective-c/RxLibrary/GRXForwardingWriter.m index 3e522ef24e0..376c196b4f3 100644 --- a/src/objective-c/RxLibrary/GRXForwardingWriter.m +++ b/src/objective-c/RxLibrary/GRXForwardingWriter.m @@ -54,23 +54,19 @@ [writeable writesFinishedWithError:errorOrNil]; } -// This is used to stop the input writer. It nillifies our reference to it -// to release it. -- (void)finishInput { - GRXWriter *writer = _writer; - _writer = nil; - writer.state = GRXWriterStateFinished; -} - #pragma mark GRXWriteable implementation - (void)writeValue:(id)value { - [_writeable writeValue:value]; + @synchronized (self) { + [_writeable writeValue:value]; + } } - (void)writesFinishedWithError:(NSError *)errorOrNil { - _writer = nil; - [self finishOutputWithError:errorOrNil]; + @synchronized (self) { + _writer = nil; + [self finishOutputWithError:errorOrNil]; + } } #pragma mark GRXWriter implementation @@ -80,22 +76,38 @@ } - (void)setState:(GRXWriterState)state { + GRXWriter *copiedWriter = nil; if (state == GRXWriterStateFinished) { - _writeable = nil; - [self finishInput]; + @synchronized (self) { + _writeable = nil; + copiedWriter = _writer; + _writer = nil; + } + copiedWriter.state = GRXWriterStateFinished; } else { - _writer.state = state; + @synchronized (self) { + copiedWriter = _writer; + } + copiedWriter.state = state; } } - (void)startWithWriteable:(id)writeable { - _writeable = writeable; - [_writer startWithWriteable:self]; + GRXWriter *copiedWriter = nil; + @synchronized (self) { + _writeable = writeable; + copiedWriter = _writer; + } + [copiedWriter startWithWriteable:self]; } - (void)finishWithError:(NSError *)errorOrNil { - [self finishOutputWithError:errorOrNil]; - [self finishInput]; + GRXWriter *copiedWriter = nil; + @synchronized (self) { + [self finishOutputWithError:errorOrNil]; + copiedWriter = _writer; + } + copiedWriter.state = GRXWriterStateFinished; } @end diff --git a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m index 3126ae4bd16..eadad6c3b65 100644 --- a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m +++ b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m @@ -20,7 +20,6 @@ @implementation GRXImmediateSingleWriter { id _value; - id _writeable; } @synthesize state = _state; @@ -38,17 +37,16 @@ } - (void)startWithWriteable:(id)writeable { - _state = GRXWriterStateStarted; - _writeable = writeable; - [writeable writeValue:_value]; - [self finish]; -} - -- (void)finish { - _state = GRXWriterStateFinished; - _value = nil; - id writeable = _writeable; - _writeable = nil; + id copiedValue = nil; + @synchronized (self) { + if (_state != GRXWriterStateNotStarted) { + return; + } + copiedValue = _value; + _value = nil; + _state = GRXWriterStateFinished; + } + [writeable writeValue:copiedValue]; [writeable writesFinishedWithError:nil]; } @@ -65,9 +63,11 @@ // the original \a map function returns a new Writer of another type. So we // need to override this function here. - (GRXWriter *)map:(id (^)(id))map { - // Since _value is available when creating the object, we can simply - // apply the map and store the output. - _value = map(_value); + @synchronized (self) { + // Since _value is available when creating the object, we can simply + // apply the map and store the output. + _value = map(_value); + } return self; } diff --git a/src/objective-c/RxLibrary/GRXWriter.h b/src/objective-c/RxLibrary/GRXWriter.h index 5d99583a928..ac1f7b9c4cf 100644 --- a/src/objective-c/RxLibrary/GRXWriter.h +++ b/src/objective-c/RxLibrary/GRXWriter.h @@ -80,9 +80,9 @@ typedef NS_ENUM(NSInteger, GRXWriterState) { * This property can be used to query the current state of the writer, which determines how it might * currently use its writeable. Some state transitions can be triggered by setting this property to * the corresponding value, and that's useful for advanced use cases like pausing an writer. For - * more details, see the documentation of the enum further down. + * more details, see the documentation of the enum further down. The property is thread safe. */ -@property(nonatomic) GRXWriterState state; +@property(atomic) GRXWriterState state; /** * Transition to the Started state, and start sending messages to the writeable (a reference to it From 03232ba46fba25465341b5e9632344f102f9df83 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 21 Dec 2018 16:21:18 -0800 Subject: [PATCH 0709/2143] Polish comments and correct concurrent writeable behavior --- src/objective-c/RxLibrary/GRXBufferedPipe.h | 3 +-- .../RxLibrary/GRXConcurrentWriteable.h | 13 +++++++------ .../RxLibrary/GRXConcurrentWriteable.m | 18 +++++++++++++----- .../RxLibrary/GRXForwardingWriter.h | 6 +----- .../RxLibrary/GRXImmediateSingleWriter.h | 2 ++ 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/objective-c/RxLibrary/GRXBufferedPipe.h b/src/objective-c/RxLibrary/GRXBufferedPipe.h index a871ea895aa..ae08cc315bb 100644 --- a/src/objective-c/RxLibrary/GRXBufferedPipe.h +++ b/src/objective-c/RxLibrary/GRXBufferedPipe.h @@ -36,8 +36,7 @@ * crash. If you want to react to flow control signals to prevent that, instead of using this class * you can implement an object that conforms to GRXWriter. * - * Thread-safety: - * The methods of an object of this class should not be called concurrently from different threads. + * Thread-safety: the methods of this class are thread-safe. */ @interface GRXBufferedPipe : GRXWriter diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h index 606f5dea954..55468b3c07a 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h @@ -43,21 +43,22 @@ - (instancetype)initWithWriteable:(id)writeable; /** - * Enqueues writeValue: to be sent to the writeable in the main thread. - * The passed handler is invoked from the main thread after writeValue: returns. + * Enqueues writeValue: to be sent to the writeable from the designated dispatch queue. + * The passed handler is invoked from designated dispatch queue after writeValue: returns. */ - (void)enqueueValue:(id)value completionHandler:(void (^)(void))handler; /** - * Enqueues writesFinishedWithError:nil to be sent to the writeable in the main thread. After that - * message is sent to the writeable, all other methods of this object are effectively noops. + * Enqueues writesFinishedWithError:nil to be sent to the writeable in the designated dispatch + * queue. After that message is sent to the writeable, all other methods of this object are + * effectively noops. */ - (void)enqueueSuccessfulCompletion; /** * If the writeable has not yet received a writesFinishedWithError: message, this will enqueue one - * to be sent to it in the main thread, and cancel all other pending messages to the writeable - * enqueued by this object (both past and future). + * to be sent to it in the designated dispatch queue, and cancel all other pending messages to the + * writeable enqueued by this object (both past and future). * The error argument cannot be nil. */ - (void)cancelWithError:(NSError *)error; diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index 229d592f484..d9d0e8c31e4 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -63,8 +63,10 @@ - (void)enqueueSuccessfulCompletion { dispatch_async(_writeableQueue, ^{ - if (self->_alreadyFinished) { - return; + @synchronized (self) { + if (self->_alreadyFinished) { + return; + } } [self.writeable writesFinishedWithError:nil]; // Skip any possible message to the wrapped writeable enqueued after this one. @@ -74,10 +76,14 @@ - (void)cancelWithError:(NSError *)error { NSAssert(error != nil, @"For a successful completion, use enqueueSuccessfulCompletion."); - dispatch_async(_writeableQueue, ^{ + @synchronized (self) { if (self->_alreadyFinished) { return; } + } + dispatch_async(_writeableQueue, ^{ + // If enqueueSuccessfulCompletion is already issued, self.writeable is nil and the following + // line is no-op. [self.writeable writesFinishedWithError:error]; self.writeable = nil; }); @@ -85,8 +91,10 @@ - (void)cancelSilently { dispatch_async(_writeableQueue, ^{ - if (self->_alreadyFinished) { - return; + @synchronized (self) { + if (self->_alreadyFinished) { + return; + } } self.writeable = nil; }); diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.h b/src/objective-c/RxLibrary/GRXForwardingWriter.h index 3814ff8831c..00366b64162 100644 --- a/src/objective-c/RxLibrary/GRXForwardingWriter.h +++ b/src/objective-c/RxLibrary/GRXForwardingWriter.h @@ -25,11 +25,7 @@ * input writer, and for classes that represent objects with input and * output sequences of values, like an RPC. * - * Thread-safety: - * All messages sent to this object need to be serialized. When it is started, the writer it wraps - * is started in the same thread. Manual state changes are propagated to the wrapped writer in the - * same thread too. Importantly, all messages the wrapped writer sends to its writeable need to be - * serialized with any message sent to this object. + * Thread-safety: the methods of this class are thread safe. */ @interface GRXForwardingWriter : GRXWriter - (instancetype)initWithWriter:(GRXWriter *)writer NS_DESIGNATED_INITIALIZER; diff --git a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h index 601abdc6b90..2fa38b3dcea 100644 --- a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h +++ b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h @@ -23,6 +23,8 @@ /** * Utility to construct GRXWriter instances from values that are immediately available when * required. + * + * Thread safety: the methods of this class are thread safe. */ @interface GRXImmediateSingleWriter : GRXImmediateWriter From 3cdc0db838626ab1d186a4980125bc3e6219c0e0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 2 Jan 2019 15:59:19 -0800 Subject: [PATCH 0710/2143] clang-format --- src/objective-c/GRPCClient/GRPCCall.m | 77 ++++++++++--------- src/objective-c/RxLibrary/GRXBufferedPipe.m | 4 +- .../RxLibrary/GRXConcurrentWriteable.h | 8 +- .../RxLibrary/GRXConcurrentWriteable.m | 6 +- .../RxLibrary/GRXForwardingWriter.m | 12 +-- .../RxLibrary/GRXImmediateSingleWriter.m | 4 +- 6 files changed, 56 insertions(+), 55 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 5ea1755c589..c18dfae6351 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -448,7 +448,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; return; } NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; - @synchronized (callFlags) { + @synchronized(callFlags) { switch (callSafety) { case GRPCCallSafetyDefault: callFlags[hostAndPath] = @0; @@ -468,7 +468,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; + (uint32_t)callFlagsForHost:(NSString *)host path:(NSString *)path { NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; uint32_t flags = 0; - @synchronized (callFlags) { + @synchronized(callFlags) { flags = [callFlags[hostAndPath] intValue]; } return flags; @@ -529,7 +529,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)setResponseDispatchQueue:(dispatch_queue_t)queue { - @synchronized (self) { + @synchronized(self) { if (_state != GRXWriterStateNotStarted) { return; } @@ -562,14 +562,14 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)cancel { - @synchronized (self) { + @synchronized(self) { if (_state == GRXWriterStateFinished) { return; } [self finishWithError:[NSError - errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]]; + errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]]; [_wrappedCall cancel]; } } @@ -636,19 +636,19 @@ const char *kCFStreamVarName = "grpc_cfstream"; // don't want to throw, because the app shouldn't crash for a behavior // that's on the hands of any server to have. Instead we finish and ask // the server to cancel. - @synchronized (strongSelf) { + @synchronized(strongSelf) { [strongSelf - finishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeResourceExhausted - userInfo:@{ - NSLocalizedDescriptionKey : - @"Client does not have enough memory to " - @"hold the server response." - }]]; + finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeResourceExhausted + userInfo:@{ + NSLocalizedDescriptionKey : + @"Client does not have enough memory to " + @"hold the server response." + }]]; [strongSelf->_wrappedCall cancel]; } } else { - @synchronized (strongSelf) { + @synchronized(strongSelf) { [strongSelf->_responseWriteable enqueueValue:data completionHandler:^{ [strongSelf startNextRead]; @@ -689,9 +689,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; } // TODO(jcanizales): Add error handlers for async failures - GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] initWithMetadata:headers - flags:callSafetyFlags - handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA + GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] + initWithMetadata:headers + flags:callSafetyFlags + handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA dispatch_async(_callQueue, ^{ if (!self->_unaryCall) { [self->_wrappedCall startBatchWithOperations:@[ op ]]; @@ -731,7 +732,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeValue:(id)value { NSAssert([value isKindOfClass:[NSData class]], @"value must be of type NSData"); - @synchronized (self) { + @synchronized(self) { if (_state == GRXWriterStateFinished) { return; } @@ -782,9 +783,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_async(_callQueue, ^{ // TODO(jcanizales): Add error handlers for async failures [self->_wrappedCall - startBatchWithOperations:@[ [[GRPCOpRecvMetadata alloc] initWithHandler:headersHandler] ]]; + startBatchWithOperations:@[ [[GRPCOpRecvMetadata alloc] initWithHandler:headersHandler] ]]; [self->_wrappedCall - startBatchWithOperations:@[ [[GRPCOpRecvStatus alloc] initWithHandler:completionHandler] ]]; + startBatchWithOperations:@[ [[GRPCOpRecvStatus alloc] initWithHandler:completionHandler] ]]; }); } @@ -825,16 +826,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Lock acquired inside startWithWriteable: - (void)startCallWithWriteable:(id)writeable { - @synchronized (self) { + @synchronized(self) { if (_state == GRXWriterStateFinished) { return; } _responseWriteable = - [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; + [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; GRPCPooledChannel *channel = - [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; + [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; _wrappedCall = [channel wrappedCallWithPath:_path completionQueue:[GRPCCompletionQueue completionQueue] callOptions:_callOptions]; @@ -843,9 +844,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{ - NSLocalizedDescriptionKey : - @"Failed to create call or channel." - }]]; + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; return; } @@ -869,10 +870,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; _state = GRXWriterStateStarted; // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled). - // This makes RPCs in which the call isn't externally retained possible (as long as it is started - // before being autoreleased). - // Care is taken not to retain self strongly in any of the blocks used in this implementation, so - // that the life of the instance is determined by this retain cycle. + // This makes RPCs in which the call isn't externally retained possible (as long as it is + // started before being autoreleased). Care is taken not to retain self strongly in any of the + // blocks used in this implementation, so that the life of the instance is determined by this + // retain cycle. _retainSelf = self; if (_callOptions == nil) { @@ -961,14 +962,14 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Retain because connectivity manager only keeps weak reference to GRPCCall. __strong GRPCCall *strongSelf = self; if (strongSelf) { - @synchronized (strongSelf) { + @synchronized(strongSelf) { [_wrappedCall cancel]; [strongSelf - finishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeUnavailable - userInfo:@{ - NSLocalizedDescriptionKey : @"Connectivity lost." - }]]; + finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : @"Connectivity lost." + }]]; } } } diff --git a/src/objective-c/RxLibrary/GRXBufferedPipe.m b/src/objective-c/RxLibrary/GRXBufferedPipe.m index d0064a5cfaf..74e2f03da6c 100644 --- a/src/objective-c/RxLibrary/GRXBufferedPipe.m +++ b/src/objective-c/RxLibrary/GRXBufferedPipe.m @@ -52,7 +52,7 @@ value = [value copy]; } dispatch_async(_writeQueue, ^(void) { - @synchronized (self) { + @synchronized(self) { if (self->_state == GRXWriterStateFinished) { return; } @@ -106,7 +106,7 @@ } - (void)startWithWriteable:(id)writeable { - @synchronized (self) { + @synchronized(self) { self.writeable = writeable; _state = GRXWriterStateStarted; } diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h index 55468b3c07a..5beca9d41e3 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h @@ -23,10 +23,10 @@ /** * This is a thread-safe wrapper over a GRXWriteable instance. It lets one enqueue calls to a - * GRXWriteable instance for the thread user provided, guaranteeing that writesFinishedWithError: is the last - * message sent to it (no matter what messages are sent to the wrapper, in what order, nor from - * which thread). It also guarantees that, if cancelWithError: is called (e.g. - * by the app cancelling the writes), no further messages are sent to the writeable except + * GRXWriteable instance for the thread user provided, guaranteeing that writesFinishedWithError: is + * the last message sent to it (no matter what messages are sent to the wrapper, in what order, nor + * from which thread). It also guarantees that, if cancelWithError: is called (e.g. by the app + * cancelling the writes), no further messages are sent to the writeable except * writesFinishedWithError:. * * TODO(jcanizales): Let the user specify another queue for the writeable callbacks. diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index d9d0e8c31e4..e50cdf240d1 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -63,7 +63,7 @@ - (void)enqueueSuccessfulCompletion { dispatch_async(_writeableQueue, ^{ - @synchronized (self) { + @synchronized(self) { if (self->_alreadyFinished) { return; } @@ -76,7 +76,7 @@ - (void)cancelWithError:(NSError *)error { NSAssert(error != nil, @"For a successful completion, use enqueueSuccessfulCompletion."); - @synchronized (self) { + @synchronized(self) { if (self->_alreadyFinished) { return; } @@ -91,7 +91,7 @@ - (void)cancelSilently { dispatch_async(_writeableQueue, ^{ - @synchronized (self) { + @synchronized(self) { if (self->_alreadyFinished) { return; } diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.m b/src/objective-c/RxLibrary/GRXForwardingWriter.m index 376c196b4f3..f5ed603698d 100644 --- a/src/objective-c/RxLibrary/GRXForwardingWriter.m +++ b/src/objective-c/RxLibrary/GRXForwardingWriter.m @@ -57,13 +57,13 @@ #pragma mark GRXWriteable implementation - (void)writeValue:(id)value { - @synchronized (self) { + @synchronized(self) { [_writeable writeValue:value]; } } - (void)writesFinishedWithError:(NSError *)errorOrNil { - @synchronized (self) { + @synchronized(self) { _writer = nil; [self finishOutputWithError:errorOrNil]; } @@ -78,14 +78,14 @@ - (void)setState:(GRXWriterState)state { GRXWriter *copiedWriter = nil; if (state == GRXWriterStateFinished) { - @synchronized (self) { + @synchronized(self) { _writeable = nil; copiedWriter = _writer; _writer = nil; } copiedWriter.state = GRXWriterStateFinished; } else { - @synchronized (self) { + @synchronized(self) { copiedWriter = _writer; } copiedWriter.state = state; @@ -94,7 +94,7 @@ - (void)startWithWriteable:(id)writeable { GRXWriter *copiedWriter = nil; - @synchronized (self) { + @synchronized(self) { _writeable = writeable; copiedWriter = _writer; } @@ -103,7 +103,7 @@ - (void)finishWithError:(NSError *)errorOrNil { GRXWriter *copiedWriter = nil; - @synchronized (self) { + @synchronized(self) { [self finishOutputWithError:errorOrNil]; copiedWriter = _writer; } diff --git a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m index eadad6c3b65..079c11b94fb 100644 --- a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m +++ b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m @@ -38,7 +38,7 @@ - (void)startWithWriteable:(id)writeable { id copiedValue = nil; - @synchronized (self) { + @synchronized(self) { if (_state != GRXWriterStateNotStarted) { return; } @@ -63,7 +63,7 @@ // the original \a map function returns a new Writer of another type. So we // need to override this function here. - (GRXWriter *)map:(id (^)(id))map { - @synchronized (self) { + @synchronized(self) { // Since _value is available when creating the object, we can simply // apply the map and store the output. _value = map(_value); From 0d931d9c8f2fedd264bd519abc343627fb42a36c Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 7 Jan 2019 13:41:02 -0800 Subject: [PATCH 0711/2143] 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 34d77aae5ec26063e2eb5dc4b47ba4dce90c7136 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 7 Jan 2019 14:12:03 -0800 Subject: [PATCH 0712/2143] Always nullify serializer to free memory --- include/grpcpp/impl/codegen/call_op_set.h | 2 +- include/grpcpp/impl/codegen/interceptor_common.h | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 2c34082ebb1..880c62344b8 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -324,8 +324,8 @@ class CallOpSendMessage { } if (msg_ != nullptr) { GPR_CODEGEN_ASSERT(serializer_(msg_).ok()); - serializer_ = nullptr; } + serializer_ = nullptr; grpc_op* op = &ops[(*nops)++]; op->op = GRPC_OP_SEND_MESSAGE; op->flags = write_options_.flags(); diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 33e46389b3d..09721343ffa 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -98,9 +98,7 @@ class InterceptorBatchMethodsImpl *orig_send_message_ = message; } - bool GetSendMessageStatus() override { - return !*fail_send_message_; - } + bool GetSendMessageStatus() override { return !*fail_send_message_; } std::multimap* GetSendInitialMetadata() override { return send_initial_metadata_; From d7650a841b8acac747b5a8d12502a46ec0e4a54c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 7 Jan 2019 16:51:08 -0800 Subject: [PATCH 0713/2143] Bug fix for GRXConcurrentWriter --- .../RxLibrary/GRXConcurrentWriteable.m | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index e50cdf240d1..7cc2101a55f 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -27,8 +27,15 @@ @implementation GRXConcurrentWriteable { dispatch_queue_t _writeableQueue; - // This ensures that writesFinishedWithError: is only sent once to the writeable. + + // This ivar ensures that writesFinishedWithError: is only sent once to the writeable. Protected + // by _writeableQueue. BOOL _alreadyFinished; + + // This ivar ensures that a cancelWithError: call prevents further values to be sent to + // self.writeable. It must support manipulation outside of _writeableQueue and thus needs to be + // protected by self lock. + BOOL _cancelled; } - (instancetype)init { @@ -42,6 +49,7 @@ _writeableQueue = queue; _writeable = writeable; _alreadyFinished = NO; + _cancelled = NO; } return self; } @@ -56,6 +64,12 @@ return; } + @synchronized (self) { + if (self->_cancelled) { + return; + } + } + [self.writeable writeValue:value]; handler(); }); @@ -63,13 +77,18 @@ - (void)enqueueSuccessfulCompletion { dispatch_async(_writeableQueue, ^{ - @synchronized(self) { - if (self->_alreadyFinished) { + if (self->_alreadyFinished) { + return; + } + @synchronized (self) { + if (self->_cancelled) { return; } } [self.writeable writesFinishedWithError:nil]; + // Skip any possible message to the wrapped writeable enqueued after this one. + self->_alreadyFinished = YES; self.writeable = nil; }); } @@ -77,14 +96,17 @@ - (void)cancelWithError:(NSError *)error { NSAssert(error != nil, @"For a successful completion, use enqueueSuccessfulCompletion."); @synchronized(self) { - if (self->_alreadyFinished) { - return; - } + self->_cancelled = YES; } dispatch_async(_writeableQueue, ^{ - // If enqueueSuccessfulCompletion is already issued, self.writeable is nil and the following - // line is no-op. + if (self->_alreadyFinished) { + // a cancel or a successful completion is already issued + return; + } [self.writeable writesFinishedWithError:error]; + + // Skip any possible message to the wrapped writeable enqueued after this one. + self->_alreadyFinished = YES; self.writeable = nil; }); } From cf303c3ee7d4b4364650ca6fdecbaafdca117497 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 7 Jan 2019 16:51:23 -0800 Subject: [PATCH 0714/2143] Deadlock fix for GRPCCall --- src/objective-c/GRPCClient/GRPCCall.m | 47 ++++++++++----------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index c18dfae6351..714c7dbbc26 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -539,26 +539,24 @@ const char *kCFStreamVarName = "grpc_cfstream"; #pragma mark Finish +// This function should support being called within a @synchronized(self) block in another function +// Should not manipulate _requestWriter for deadlock prevention. - (void)finishWithError:(NSError *)errorOrNil { - GRXConcurrentWriteable *copiedResponseWriteable = nil; - @synchronized(self) { if (_state == GRXWriterStateFinished) { return; } _state = GRXWriterStateFinished; - copiedResponseWriteable = _responseWriteable; + + if (errorOrNil) { + [_responseWriteable cancelWithError:errorOrNil]; + } else { + [_responseWriteable enqueueSuccessfulCompletion]; + } // If the call isn't retained anywhere else, it can be deallocated now. _retainSelf = nil; } - - if (errorOrNil) { - [copiedResponseWriteable cancelWithError:errorOrNil]; - } else { - [copiedResponseWriteable enqueueSuccessfulCompletion]; - } - _requestWriter.state = GRXWriterStateFinished; } - (void)cancel { @@ -572,19 +570,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]]; [_wrappedCall cancel]; } -} - -- (void)maybeFinishWithError:(NSError *)errorOrNil { - BOOL toFinish = NO; - @synchronized(self) { - if (_finished == NO) { - _finished = YES; - toFinish = YES; - } - } - if (toFinish == YES) { - [self finishWithError:errorOrNil]; - } + _requestWriter.state = GRXWriterStateFinished; } - (void)dealloc { @@ -647,6 +633,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; }]]; [strongSelf->_wrappedCall cancel]; } + strongSelf->_requestWriter.state = GRXWriterStateFinished; } else { @synchronized(strongSelf) { [strongSelf->_responseWriteable enqueueValue:data @@ -818,6 +805,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; } [strongSelf finishWithError:error]; + strongSelf->_requestWriter.state = GRXWriterStateFinished; } }]; } @@ -841,12 +829,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; callOptions:_callOptions]; if (_wrappedCall == nil) { - [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeUnavailable - userInfo:@{ - NSLocalizedDescriptionKey : - @"Failed to create call or channel." - }]]; + [self finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; return; } @@ -971,6 +959,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; NSLocalizedDescriptionKey : @"Connectivity lost." }]]; } + strongSelf->_requestWriter.state = GRXWriterStateFinished; } } From 8b55c6a8714e7c4422adc8e7e105588397b707ba Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 7 Jan 2019 16:54:37 -0800 Subject: [PATCH 0715/2143] clang-format --- src/objective-c/GRPCClient/GRPCCall.m | 6 +++--- src/objective-c/RxLibrary/GRXConcurrentWriteable.m | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 714c7dbbc26..20703f548e4 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -832,9 +832,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self finishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{ - NSLocalizedDescriptionKey : - @"Failed to create call or channel." - }]]; + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; return; } diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index 7cc2101a55f..d8491d2aed5 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -64,10 +64,10 @@ return; } - @synchronized (self) { - if (self->_cancelled) { - return; - } + @synchronized(self) { + if (self->_cancelled) { + return; + } } [self.writeable writeValue:value]; @@ -80,7 +80,7 @@ if (self->_alreadyFinished) { return; } - @synchronized (self) { + @synchronized(self) { if (self->_cancelled) { return; } From b35b449166e1c18c180701725b8ba97ab98994e0 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 7 Jan 2019 17:17:01 -0800 Subject: [PATCH 0716/2143] Update docs according to #17630 --- include/grpcpp/impl/codegen/call_op_set.h | 3 ++- include/grpcpp/impl/codegen/interceptor.h | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 880c62344b8..c0de5ed6025 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -400,8 +400,9 @@ Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) { }; // Serialize immediately only if we do not have access to the message pointer if (msg_ == nullptr) { - return serializer_(&message); + Status result = serializer_(&message); serializer_ = nullptr; + return result; } return Status(); } diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index d749d8578ae..5dea796a3b7 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -112,12 +112,17 @@ class InterceptorBatchMethods { /// A return value of nullptr indicates that this ByteBuffer is not valid. virtual ByteBuffer* GetSerializedSendMessage() = 0; - /// Returns a non-modifiable pointer to the original non-serialized form of - /// the message. Valid for PRE_SEND_MESSAGE interceptions. A return value of + /// 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. 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. virtual void ModifySendMessage(const void* message) = 0; /// Checks whether the SEND MESSAGE op succeeded. Valid for POST_SEND_MESSAGE From 361acdbed1805dd9f313deb4bc92dbd5e8612a7b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 7 Jan 2019 17:33:16 -0800 Subject: [PATCH 0717/2143] Use the WriteOptions in Client Callback API --- include/grpcpp/impl/codegen/client_callback.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index c20e8458106..52bcea99706 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -340,13 +340,13 @@ class ClientCallbackReaderWriterImpl context_->initial_metadata_flags()); start_corked_ = false; } - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg).ok()); if (options.is_last_message()) { options.set_buffer_hint(); write_ops_.ClientSendClose(); } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); callbacks_outstanding_++; if (started_) { call_.PerformOps(&write_ops_); @@ -649,13 +649,13 @@ class ClientCallbackWriterImpl context_->initial_metadata_flags()); start_corked_ = false; } - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg).ok()); if (options.is_last_message()) { options.set_buffer_hint(); write_ops_.ClientSendClose(); } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); callbacks_outstanding_++; if (started_) { call_.PerformOps(&write_ops_); From 832e5f06c305b88d3ac662fd19f2c1985e664403 Mon Sep 17 00:00:00 2001 From: Christopher Warrington Date: Mon, 7 Jan 2019 17:30:46 -0800 Subject: [PATCH 0718/2143] Fix typos in comments --- include/grpc/impl/codegen/grpc_types.h | 2 +- src/ruby/ext/grpc/rb_channel.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 610548b5f36..5d577eb8557 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -163,7 +163,7 @@ typedef struct { /** Maximum time that a channel may exist. Int valued, milliseconds. * INT_MAX means unlimited. */ #define GRPC_ARG_MAX_CONNECTION_AGE_MS "grpc.max_connection_age_ms" -/** Grace period after the chennel reaches its max age. Int valued, +/** Grace period after the channel reaches its max age. Int valued, milliseconds. INT_MAX means unlimited. */ #define GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS "grpc.max_connection_age_grace_ms" /** Enable/disable support for per-message compression. Defaults to 1, unless diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index 6d4b2293a24..2e570b8e87c 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -153,7 +153,7 @@ static void grpc_rb_channel_free(void* p) { if (ch->bg_wrapped != NULL) { /* assumption made here: it's ok to directly gpr_mu_lock the global - * connection polling mutex becuse we're in a finalizer, + * connection polling mutex because we're in a finalizer, * and we can count on this thread to not be interrupted or * yield the gil. */ grpc_rb_channel_safe_destroy(ch->bg_wrapped); @@ -292,7 +292,7 @@ static void* get_state_without_gil(void* arg) { Indicates the current state of the channel, whose value is one of the constants defined in GRPC::Core::ConnectivityStates. - It also tries to connect if the chennel is idle in the second form. */ + It also tries to connect if the channel is idle in the second form. */ static VALUE grpc_rb_channel_get_connectivity_state(int argc, VALUE* argv, VALUE self) { VALUE try_to_connect_param = Qfalse; @@ -327,7 +327,7 @@ static void* wait_for_watch_state_op_complete_without_gvl(void* arg) { void* success = (void*)0; gpr_mu_lock(&global_connection_polling_mu); - // its unsafe to do a "watch" after "channel polling abort" because the cq has + // it's unsafe to do a "watch" after "channel polling abort" because the cq has // been shut down. if (abort_channel_polling || stack->bg_wrapped->channel_destroyed) { gpr_mu_unlock(&global_connection_polling_mu); From 11eff929e24cae59ed21c2f3a0bde22a6dbe0d91 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 7 Jan 2019 18:22:50 -0800 Subject: [PATCH 0719/2143] Avoid the thread jump in server callback APIs. Add a utility function in iomgr to check whether the caller thread is a worker for any background poller, and keep grpc combiner from offloading closures to the default executor if the current thread is a worker for any background poller. --- src/core/lib/iomgr/combiner.cc | 9 ++++++++- src/core/lib/iomgr/ev_epoll1_linux.cc | 3 +++ src/core/lib/iomgr/ev_epollex_linux.cc | 3 +++ src/core/lib/iomgr/ev_poll_posix.cc | 3 +++ src/core/lib/iomgr/ev_posix.cc | 4 ++++ src/core/lib/iomgr/ev_posix.h | 4 ++++ src/core/lib/iomgr/iomgr.cc | 4 ++++ src/core/lib/iomgr/iomgr.h | 3 +++ src/core/lib/iomgr/iomgr_custom.cc | 6 +++++- src/core/lib/iomgr/iomgr_internal.cc | 4 ++++ src/core/lib/iomgr/iomgr_internal.h | 4 ++++ src/core/lib/iomgr/iomgr_posix.cc | 7 ++++++- src/core/lib/iomgr/iomgr_posix_cfstream.cc | 7 ++++++- src/core/lib/iomgr/iomgr_windows.cc | 7 ++++++- test/cpp/microbenchmarks/bm_cq_multiple_threads.cc | 1 + 15 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/core/lib/iomgr/combiner.cc b/src/core/lib/iomgr/combiner.cc index 7c0062eb4ec..402f8904eae 100644 --- a/src/core/lib/iomgr/combiner.cc +++ b/src/core/lib/iomgr/combiner.cc @@ -29,6 +29,7 @@ #include "src/core/lib/debug/stats.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/profiling/timers.h" grpc_core::DebugOnlyTraceFlag grpc_combiner_trace(false, "combiner"); @@ -228,8 +229,14 @@ bool grpc_combiner_continue_exec_ctx() { grpc_core::ExecCtx::Get()->IsReadyToFinish(), lock->time_to_execute_final_list)); + // offload only if all the following conditions are true: + // 1. the combiner is contended and has more than one closure to execute + // 2. the current execution context needs to finish as soon as possible + // 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_executor_is_threaded() && + !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 // picked up on the executor diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index 4b8c891e9b0..9eb4c089d86 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -1242,6 +1242,8 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag, * Event engine binding */ +static bool is_any_background_poller_thread(void) { return false; } + static void shutdown_background_closure(void) {} static void shutdown_engine(void) { @@ -1287,6 +1289,7 @@ static const grpc_event_engine_vtable vtable = { pollset_set_add_fd, pollset_set_del_fd, + is_any_background_poller_thread, shutdown_background_closure, shutdown_engine, }; diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index 7a4870db785..0a0891013af 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -1604,6 +1604,8 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag, * Event engine binding */ +static bool is_any_background_poller_thread(void) { return false; } + static void shutdown_background_closure(void) {} static void shutdown_engine(void) { @@ -1644,6 +1646,7 @@ static const grpc_event_engine_vtable vtable = { pollset_set_add_fd, pollset_set_del_fd, + is_any_background_poller_thread, shutdown_background_closure, shutdown_engine, }; diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc index 67cbfbbd021..c479206410b 100644 --- a/src/core/lib/iomgr/ev_poll_posix.cc +++ b/src/core/lib/iomgr/ev_poll_posix.cc @@ -1782,6 +1782,8 @@ static void global_cv_fd_table_shutdown() { * event engine binding */ +static bool is_any_background_poller_thread(void) { return false; } + static void shutdown_background_closure(void) {} static void shutdown_engine(void) { @@ -1828,6 +1830,7 @@ static const grpc_event_engine_vtable vtable = { pollset_set_add_fd, pollset_set_del_fd, + is_any_background_poller_thread, shutdown_background_closure, shutdown_engine, }; diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 32d1b6c43ef..fb2e70eee49 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -399,6 +399,10 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) { g_event_engine->pollset_set_del_fd(pollset_set, fd); } +bool grpc_is_any_background_poller_thread(void) { + return g_event_engine->is_any_background_poller_thread(); +} + 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 812c7a0f0f8..94ac9fdba6f 100644 --- a/src/core/lib/iomgr/ev_posix.h +++ b/src/core/lib/iomgr/ev_posix.h @@ -80,6 +80,7 @@ typedef struct grpc_event_engine_vtable { void (*pollset_set_add_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd); void (*pollset_set_del_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd); + bool (*is_any_background_poller_thread)(void); void (*shutdown_background_closure)(void); void (*shutdown_engine)(void); } grpc_event_engine_vtable; @@ -181,6 +182,9 @@ void grpc_pollset_add_fd(grpc_pollset* pollset, struct grpc_fd* fd); void grpc_pollset_set_add_fd(grpc_pollset_set* pollset_set, grpc_fd* fd); 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(); + /* Shut down all the closures registered in the background poller. */ void grpc_shutdown_background_closure(); diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index eb29973514f..a4921468578 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -161,6 +161,10 @@ void grpc_iomgr_shutdown_background_closure() { grpc_iomgr_platform_shutdown_background_closure(); } +bool grpc_iomgr_is_any_background_poller_thread() { + return grpc_iomgr_platform_is_any_background_poller_thread(); +} + 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 8ea9289e068..6261aa550c3 100644 --- a/src/core/lib/iomgr/iomgr.h +++ b/src/core/lib/iomgr/iomgr.h @@ -39,6 +39,9 @@ void grpc_iomgr_shutdown(); * background poller. */ void grpc_iomgr_shutdown_background_closure(); +/** Returns true if the caller is a worker thread for any background poller. */ +bool grpc_iomgr_is_any_background_poller_thread(); + /* 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 4b112c9097f..e1cd8f73104 100644 --- a/src/core/lib/iomgr/iomgr_custom.cc +++ b/src/core/lib/iomgr/iomgr_custom.cc @@ -41,10 +41,14 @@ static void iomgr_platform_init(void) { static void iomgr_platform_flush(void) {} static void iomgr_platform_shutdown(void) { grpc_pollset_global_shutdown(); } static void iomgr_platform_shutdown_background_closure(void) {} +static bool iomgr_platform_is_any_background_poller_thread(void) { + return false; +} static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, - iomgr_platform_shutdown_background_closure}; + iomgr_platform_shutdown_background_closure, + iomgr_platform_is_any_background_poller_thread}; 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 b6c9211865d..e68b1cf5812 100644 --- a/src/core/lib/iomgr/iomgr_internal.cc +++ b/src/core/lib/iomgr/iomgr_internal.cc @@ -45,3 +45,7 @@ void grpc_iomgr_platform_shutdown() { iomgr_platform_vtable->shutdown(); } void grpc_iomgr_platform_shutdown_background_closure() { iomgr_platform_vtable->shutdown_background_closure(); } + +bool grpc_iomgr_platform_is_any_background_poller_thread() { + return iomgr_platform_vtable->is_any_background_poller_thread(); +} diff --git a/src/core/lib/iomgr/iomgr_internal.h b/src/core/lib/iomgr/iomgr_internal.h index bca7409907f..2250ad9a18c 100644 --- a/src/core/lib/iomgr/iomgr_internal.h +++ b/src/core/lib/iomgr/iomgr_internal.h @@ -36,6 +36,7 @@ typedef struct grpc_iomgr_platform_vtable { void (*flush)(void); void (*shutdown)(void); void (*shutdown_background_closure)(void); + bool (*is_any_background_poller_thread)(void); } grpc_iomgr_platform_vtable; void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name); @@ -56,6 +57,9 @@ 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 */ +bool grpc_iomgr_platform_is_any_background_poller_thread(void); + 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 9386adf060d..278c8de6886 100644 --- a/src/core/lib/iomgr/iomgr_posix.cc +++ b/src/core/lib/iomgr/iomgr_posix.cc @@ -55,9 +55,14 @@ static void iomgr_platform_shutdown_background_closure(void) { grpc_shutdown_background_closure(); } +static bool iomgr_platform_is_any_background_poller_thread(void) { + return grpc_is_any_background_poller_thread(); +} + static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, - iomgr_platform_shutdown_background_closure}; + iomgr_platform_shutdown_background_closure, + iomgr_platform_is_any_background_poller_thread}; 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 552ef4309c8..462ac41fcde 100644 --- a/src/core/lib/iomgr/iomgr_posix_cfstream.cc +++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc @@ -58,9 +58,14 @@ static void iomgr_platform_shutdown_background_closure(void) { grpc_shutdown_background_closure(); } +static bool iomgr_platform_is_any_background_poller_thread(void) { + return grpc_is_any_background_poller_thread(); +} + static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, - iomgr_platform_shutdown_background_closure}; + iomgr_platform_shutdown_background_closure, + iomgr_platform_is_any_background_poller_thread}; 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 24ef0dba7b4..0579e16aa76 100644 --- a/src/core/lib/iomgr/iomgr_windows.cc +++ b/src/core/lib/iomgr/iomgr_windows.cc @@ -73,9 +73,14 @@ static void iomgr_platform_shutdown(void) { static void iomgr_platform_shutdown_background_closure(void) {} +static bool iomgr_platform_is_any_background_poller_thread(void) { + return false; +} + static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, - iomgr_platform_shutdown_background_closure}; + iomgr_platform_shutdown_background_closure, + iomgr_platform_is_any_background_poller_thread}; 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 dca97c85b19..7aa197b5979 100644 --- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc +++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc @@ -94,6 +94,7 @@ static const grpc_event_engine_vtable* init_engine_vtable(bool) { g_vtable.pollset_destroy = pollset_destroy; g_vtable.pollset_work = pollset_work; g_vtable.pollset_kick = pollset_kick; + g_vtable.is_any_background_poller_thread = [] { return false; }; g_vtable.shutdown_background_closure = [] {}; g_vtable.shutdown_engine = [] {}; From 5a6c984d3ab6084a092173a6c19eb52c5aae8414 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 8 Jan 2019 16:06:38 +0100 Subject: [PATCH 0720/2143] clang format code --- src/ruby/ext/grpc/rb_channel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index 2e570b8e87c..5bde962f788 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -327,8 +327,8 @@ static void* wait_for_watch_state_op_complete_without_gvl(void* arg) { void* success = (void*)0; gpr_mu_lock(&global_connection_polling_mu); - // it's unsafe to do a "watch" after "channel polling abort" because the cq has - // been shut down. + // it's unsafe to do a "watch" after "channel polling abort" because the cq + // has been shut down. if (abort_channel_polling || stack->bg_wrapped->channel_destroyed) { gpr_mu_unlock(&global_connection_polling_mu); return (void*)0; From b8a542cd234d32c8da7cb8474e26c9c21f3c9581 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 8 Jan 2019 09:20:15 -0800 Subject: [PATCH 0721/2143] 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 0722/2143] 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 0723/2143] 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 da4ab59b0d2e136ec82038cf5f0e3f2ec8fb19f5 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 8 Jan 2019 11:44:33 -0800 Subject: [PATCH 0724/2143] Remove state_watcher from subchannel --- src/core/ext/filters/client_channel/subchannel.cc | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 3abacf68aeb..dff213efc6b 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -64,18 +64,6 @@ #define GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS 120 #define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2 -namespace { -struct state_watcher { - grpc_closure closure; - grpc_subchannel* subchannel; - grpc_connectivity_state connectivity_state; - grpc_connectivity_state last_connectivity_state; - grpc_core::OrphanablePtr health_check_client; - grpc_closure health_check_closure; - grpc_connectivity_state health_state; -}; -} // namespace - typedef struct external_state_watcher { grpc_subchannel* subchannel; grpc_pollset_set* pollset_set; From 0c4c2de427399fe260aeaa2140638825fa43f26b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 8 Jan 2019 11:45:02 -0800 Subject: [PATCH 0725/2143] Clean up code --- src/objective-c/GRPCClient/GRPCCall.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 20703f548e4..bc48f1aa1b3 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -467,11 +467,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; + (uint32_t)callFlagsForHost:(NSString *)host path:(NSString *)path { NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; - uint32_t flags = 0; @synchronized(callFlags) { - flags = [callFlags[hostAndPath] intValue]; + return [callFlags[hostAndPath] intValue]; } - return flags; } // Designated initializer From f52dd290e20ec57780255f90ed1f985ee7df63b8 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 8 Jan 2019 13:41:08 +0100 Subject: [PATCH 0726/2143] improve readme.md --- tools/interop_matrix/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index db84d9b454c..6676f5d470c 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -1,6 +1,6 @@ # Overview -This directory contains scripts that facilitate building and running gRPC tests for combinations of language/runtimes (known as matrix). +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 5aa166eb2d8f98d83b016581abc36321b821f29f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 8 Jan 2019 13:44:13 +0100 Subject: [PATCH 0727/2143] interop_matrix: refactor LANG_RELEASE_MATRIX --- tools/interop_matrix/client_matrix.py | 654 +++++------------- tools/interop_matrix/create_matrix_images.py | 16 +- .../run_interop_matrix_tests.py | 7 +- 3 files changed, 196 insertions(+), 481 deletions(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 4964fd61674..12051e70a0b 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -15,6 +15,8 @@ # Defines languages, runtimes and releases for backward compatibility testing +from collections import OrderedDict + def get_github_repo(lang): return { @@ -27,23 +29,16 @@ def get_github_repo(lang): def get_release_tags(lang): - return map(lambda r: get_release_tag_name(r), LANG_RELEASE_MATRIX[lang]) - - -def get_release_tag_name(release_info): - assert len(release_info.keys()) == 1 - return release_info.keys()[0] + """Returns list of known releases for given language.""" + return list(LANG_RELEASE_MATRIX[lang].keys()) def get_runtimes_for_lang_release(lang, release): """Get list of valid runtimes for given release of lang.""" runtimes_to_skip = [] - # see if any the lang release has "skip_runtime" annotation. - for release_info in LANG_RELEASE_MATRIX[lang]: - if get_release_tag_name(release_info) == release: - if release_info[release] is not None: - runtimes_to_skip = release_info[release].get('skip_runtime', []) - break + release_info = LANG_RELEASE_MATRIX[lang][release] + if release_info: + runtimes_to_skip = release_info.skip_runtime return [ runtime for runtime in LANG_RUNTIME_MATRIX[lang] if runtime not in runtimes_to_skip @@ -51,6 +46,9 @@ def get_runtimes_for_lang_release(lang, release): def should_build_docker_interop_image_from_release_tag(lang): + # All dockerfile definitions live in grpc/grpc repository. + # For language that have a separate repo, we need to use + # dockerfile definitions from head of grpc/grpc. if lang in ['go', 'java', 'node']: return False return True @@ -68,465 +66,183 @@ LANG_RUNTIME_MATRIX = { 'csharp': ['csharp', 'csharpcoreclr'], } + +class ReleaseInfo: + """Info about a single release of a language""" + + def __init__(self, patch=[], skip_runtime=[], testcases_file=None): + self.patch = patch + self.skip_runtime = skip_runtime + self.testcases_file = None + + # Dictionary of known releases for given language. LANG_RELEASE_MATRIX = { - 'cxx': [ - { - 'v1.0.1': None - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - { - 'v1.17.1': None - }, - ], - 'go': [ - { - 'v1.0.5': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.2.1': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.3.0': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.4.2': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.5.2': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.6.0': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.7.4': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.8.2': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.9.2': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.10.1': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.11.3': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.12.2': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.13.0': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.14.0': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.15.0': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.16.0': { - 'skip_runtime': ['go1.11'] - } - }, - { - 'v1.17.0': { - 'skip_runtime': ['go1.7', 'go1.8'] - } - }, - ], - 'java': [ - { - 'v1.0.3': None - }, - { - 'v1.1.2': None - }, - { - 'v1.2.0': None - }, - { - 'v1.3.1': None - }, - { - 'v1.4.0': None - }, - { - 'v1.5.0': None - }, - { - 'v1.6.1': None - }, - { - 'v1.7.0': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.0': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.1': None - }, - { - 'v1.14.0': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.1': None - }, - { - 'v1.17.1': None - }, - ], - 'python': [ - { - 'v1.0.x': None - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.1': None # first python 1.8 release is 1.8.1 - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - { - 'v1.17.1': None - }, - ], - 'node': [ - { - 'v1.0.1': None - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, + 'cxx': + 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.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()), + ]), + 'go': + OrderedDict([ + ('v1.0.5', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.2.1', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.3.0', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.4.2', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.5.2', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.6.0', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.7.4', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.8.2', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.9.2', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.10.1', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.11.3', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.12.2', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.13.0', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.14.0', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.15.0', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.16.0', ReleaseInfo(skip_runtime=['go1.11'])), + ('v1.17.0', ReleaseInfo(skip_runtime=['go1.7', 'go1.8'])), + ]), + 'java': + OrderedDict([ + ('v1.0.3', ReleaseInfo()), + ('v1.1.2', ReleaseInfo()), + ('v1.2.0', ReleaseInfo()), + ('v1.3.1', ReleaseInfo()), + ('v1.4.0', ReleaseInfo()), + ('v1.5.0', ReleaseInfo()), + ('v1.6.1', ReleaseInfo()), + ('v1.7.0', ReleaseInfo()), + ('v1.8.0', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.1', ReleaseInfo()), + ('v1.11.0', ReleaseInfo()), + ('v1.12.0', ReleaseInfo()), + ('v1.13.1', ReleaseInfo()), + ('v1.14.0', ReleaseInfo()), + ('v1.15.0', ReleaseInfo()), + ('v1.16.1', ReleaseInfo()), + ('v1.17.1', ReleaseInfo()), + ]), + '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()), + ]), + '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()), # TODO: https://github.com/grpc/grpc-node/issues/235. - #{ - # 'v1.7.2': None - #}, - { - 'v1.8.4': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.0': None - }, - { - 'v1.11.3': None - }, - { - 'v1.12.4': None - }, - ], - 'ruby': [ - { - 'v1.0.1': { - 'patch': [ - 'tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile', - 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', - ] - } - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - { - 'v1.17.1': None - }, - ], - 'php': [ - { - 'v1.0.1': None - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - { - 'v1.17.1': None - }, - ], - 'csharp': [ - { - 'v1.0.1': { - 'patch': [ - 'tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile', - 'tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile', - ] - } - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - { - 'v1.17.1': None - }, - ], + # ('v1.7.2', ReleaseInfo()), + ('v1.8.4', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.0', ReleaseInfo()), + ('v1.11.3', ReleaseInfo()), + ('v1.12.4', ReleaseInfo()), + ]), + 'ruby': + OrderedDict([ + ('v1.0.1', + ReleaseInfo(patch=[ + 'tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile', + 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', + ])), + ('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()), + ]), + 'php': + 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.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()), + ]), + '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()), + ]), } # This matrix lists the version of testcases to use for a release. As new @@ -535,6 +251,8 @@ LANG_RELEASE_MATRIX = { # 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', diff --git a/tools/interop_matrix/create_matrix_images.py b/tools/interop_matrix/create_matrix_images.py index cf61d462482..31a0e1c7ba6 100755 --- a/tools/interop_matrix/create_matrix_images.py +++ b/tools/interop_matrix/create_matrix_images.py @@ -39,10 +39,9 @@ _LANGUAGES = client_matrix.LANG_RUNTIME_MATRIX.keys() # All gRPC release tags, flattened, deduped and sorted. _RELEASES = sorted( list( - set( - client_matrix.get_release_tag_name(info) - for lang in client_matrix.LANG_RELEASE_MATRIX.values() - for info in lang))) + set(release + for release_dict in client_matrix.LANG_RELEASE_MATRIX.values() + for release in release_dict.keys()))) # Destination directory inside docker image to keep extra info from build time. _BUILD_INFO = '/var/local/build_info' @@ -260,11 +259,10 @@ atexit.register(cleanup) def maybe_apply_patches_on_git_tag(stack_base, lang, release): files_to_patch = [] - for release_info in client_matrix.LANG_RELEASE_MATRIX[lang]: - if client_matrix.get_release_tag_name(release_info) == release: - if release_info[release] is not None: - files_to_patch = release_info[release].get('patch') - break + + release_info = client_matrix.LANG_RELEASE_MATRIX[lang][release] + if release_info: + files_to_patch = release_info.patch if not files_to_patch: return patch_file_relative_path = 'patches/%s_%s/git_repo.patch' % (lang, release) diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index dabb4865237..c855de3b1e8 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -44,10 +44,9 @@ _LANGUAGES = client_matrix.LANG_RUNTIME_MATRIX.keys() # All gRPC release tags, flattened, deduped and sorted. _RELEASES = sorted( list( - set( - client_matrix.get_release_tag_name(info) - for lang in client_matrix.LANG_RELEASE_MATRIX.values() - for info in lang))) + set(release + for release_dict in client_matrix.LANG_RELEASE_MATRIX.values() + for release in release_dict.keys()))) argp = argparse.ArgumentParser(description='Run interop tests.') argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int) From 1287cd34eacbc5597bb6c2cdbf7f8d1e8a426509 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 8 Jan 2019 21:10:34 +0100 Subject: [PATCH 0728/2143] make tcp_server_posix_test pass on foundry --- test/core/iomgr/tcp_server_posix_test.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/core/iomgr/tcp_server_posix_test.cc b/test/core/iomgr/tcp_server_posix_test.cc index 2c66cdec77f..81e26b20cd8 100644 --- a/test/core/iomgr/tcp_server_posix_test.cc +++ b/test/core/iomgr/tcp_server_posix_test.cc @@ -439,6 +439,11 @@ int main(int argc, char** argv) { static_cast(gpr_zalloc(sizeof(*dst_addrs))); grpc::testing::TestEnvironment env(argc, argv); grpc_init(); + // wait a few seconds to make sure IPv6 link-local addresses can be bound + // if we are running under docker container that has just started. + // See https://github.com/moby/moby/issues/38491 + // See https://github.com/grpc/grpc/issues/15610 + gpr_sleep_until(grpc_timeout_seconds_to_deadline(4)); { grpc_core::ExecCtx exec_ctx; g_pollset = static_cast(gpr_zalloc(grpc_pollset_size())); From 7850704d644e41c03ee41a7b6a7aad24b75e4a1d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 8 Jan 2019 21:14:00 +0100 Subject: [PATCH 0729/2143] reenable tcp_server_posix_test on Foundry --- test/core/iomgr/BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index e920ceacf00..fa59f215887 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -237,7 +237,6 @@ grpc_cc_test( name = "tcp_server_posix_test", srcs = ["tcp_server_posix_test.cc"], language = "C++", - tags = ["manual"], # TODO(adelez): Remove once this works on Foundry. deps = [ "//:gpr", "//:grpc", From 21446eb35afb8a9a13ed65081f331cb056d383fb Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 8 Jan 2019 14:19:43 -0800 Subject: [PATCH 0730/2143] 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 46a872864cfa3b3e81bbb650d6fd01e8a775c1b5 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 12 Oct 2018 11:56:29 -0700 Subject: [PATCH 0731/2143] Turn on c-ares as the default resolver --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 2 +- .../cpp/naming/resolver_component_tests_defs.include | 1 - .../client_channel/resolvers/dns_resolver_test.cc | 11 +++++++---- test/cpp/naming/resolver_component_tests_runner.py | 1 - 4 files changed, 8 insertions(+), 7 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 abacd0c960d..fba20000ef6 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 @@ -472,7 +472,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 && 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 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 571746abe86..6f153cc9bf6 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -22,6 +22,8 @@ #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/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/combiner.h" #include "test/core/util/test_config.h" @@ -72,12 +74,13 @@ int main(int argc, char** argv) { test_succeeds(dns, "dns:10.2.1.1:1234"); test_succeeds(dns, "dns:www.google.com"); test_succeeds(dns, "dns:///www.google.com"); - if (grpc_resolve_address == grpc_resolve_address_ares) { - test_succeeds(dns, "dns://8.8.8.8/8.8.8.8:8888"); - } else { + char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); + 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"); } - + gpr_free(resolver_env); { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index 1873eec35bd..950a9d4897e 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 0ec937207431a8512e3820d2da808693e2a21a48 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Mon, 17 Dec 2018 13:32:57 -0800 Subject: [PATCH 0732/2143] Multiple test timeout 5x --- test/core/surface/concurrent_connectivity_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/surface/concurrent_connectivity_test.cc b/test/core/surface/concurrent_connectivity_test.cc index f606e89ac8d..b201568f482 100644 --- a/test/core/surface/concurrent_connectivity_test.cc +++ b/test/core/surface/concurrent_connectivity_test.cc @@ -44,7 +44,7 @@ #define NUM_OUTER_LOOPS 10 #define NUM_INNER_LOOPS 10 #define DELAY_MILLIS 10 -#define POLL_MILLIS 3000 +#define POLL_MILLIS 15000 #define NUM_OUTER_LOOPS_SHORT_TIMEOUTS 10 #define NUM_INNER_LOOPS_SHORT_TIMEOUTS 100 From 23677bd827f6e749b4a3e2bec73eea40dece565e Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 8 Jan 2019 17:41:23 -0800 Subject: [PATCH 0733/2143] Remove subchannel args --- .../client_channel/client_channel_factory.cc | 2 +- .../client_channel/client_channel_factory.h | 4 +- .../lb_policy/subchannel_list.h | 5 +-- .../ext/filters/client_channel/subchannel.cc | 11 +++-- .../ext/filters/client_channel/subchannel.h | 10 +---- .../client_channel/subchannel_index.cc | 15 +++---- .../filters/client_channel/subchannel_index.h | 3 +- .../chttp2/client/insecure/channel_create.cc | 10 ++--- .../client/secure/secure_channel_create.cc | 44 +++++++------------ test/cpp/microbenchmarks/bm_call_create.cc | 2 +- 10 files changed, 40 insertions(+), 66 deletions(-) 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 172e9f03c73..130bbe04180 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.cc +++ b/src/core/ext/filters/client_channel/client_channel_factory.cc @@ -30,7 +30,7 @@ void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory) { } grpc_subchannel* grpc_client_channel_factory_create_subchannel( - grpc_client_channel_factory* factory, const grpc_subchannel_args* args) { + 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 601ec46b2a5..91dec12282f 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.h +++ b/src/core/ext/filters/client_channel/client_channel_factory.h @@ -49,7 +49,7 @@ 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_subchannel_args* args); + const grpc_channel_args* args); grpc_channel* (*create_client_channel)(grpc_client_channel_factory* factory, const char* target, grpc_client_channel_type type, @@ -61,7 +61,7 @@ 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_client_channel_factory* factory, const grpc_subchannel_args* args); + grpc_client_channel_factory* factory, const grpc_channel_args* args); /** Create a new grpc_channel */ grpc_channel* grpc_client_channel_factory_create_channel( 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 6f31a643c1d..1d0ecbe3f64 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 @@ -509,12 +509,10 @@ SubchannelList::SubchannelList( GRPC_ARG_SERVER_ADDRESS_LIST, GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. - grpc_subchannel_args sc_args; 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()); - memset(&sc_args, 0, sizeof(grpc_subchannel_args)); InlinedVector args_to_add; args_to_add.emplace_back( grpc_create_subchannel_address_arg(&addresses[i].address())); @@ -527,9 +525,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[0].value.string); - sc_args.args = new_args; grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel( - client_channel_factory, &sc_args); + 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/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index dff213efc6b..640a052e91e 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -537,7 +537,7 @@ struct HealthCheckParams { } // namespace grpc_core grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, - const grpc_subchannel_args* args) { + const grpc_channel_args* args) { grpc_subchannel_key* key = grpc_subchannel_key_create(args); grpc_subchannel* c = grpc_subchannel_index_find(key); if (c) { @@ -554,11 +554,10 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, c->pollset_set = grpc_pollset_set_create(); grpc_resolved_address* addr = static_cast(gpr_malloc(sizeof(*addr))); - grpc_get_subchannel_address_arg(args->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->args, &new_address, - &new_args)) { + if (grpc_proxy_mappers_map_address(addr, args, &new_address, &new_args)) { GPR_ASSERT(new_address != nullptr); gpr_free(addr); addr = new_address; @@ -567,7 +566,7 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, grpc_arg new_arg = grpc_create_subchannel_address_arg(addr); gpr_free(addr); c->args = grpc_channel_args_copy_and_add_and_remove( - new_args != nullptr ? new_args : args->args, keys_to_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); @@ -580,7 +579,7 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, grpc_connectivity_state_init(&c->state_and_health_tracker, GRPC_CHANNEL_IDLE, "subchannel"); grpc_core::BackOff::Options backoff_options; - parse_args_for_backoff_values(args->args, &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); diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index d0c0a672fa1..8c994c64f50 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -38,7 +38,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_args grpc_subchannel_args; typedef struct grpc_subchannel_key grpc_subchannel_key; #ifndef NDEBUG @@ -186,16 +185,9 @@ void grpc_subchannel_call_set_cleanup_closure( grpc_call_stack* grpc_subchannel_call_get_call_stack( grpc_subchannel_call* subchannel_call); -struct grpc_subchannel_args { - /* When updating this struct, also update subchannel_index.c */ - - /** Channel arguments to be supplied to the newly created channel */ - const grpc_channel_args* args; -}; - /** create a subchannel given a connector */ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, - const grpc_subchannel_args* args); + const grpc_channel_args* args); /// Sets \a addr from \a args. void grpc_get_subchannel_address_arg(const grpc_channel_args* args, diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc index 0ae7898c5a4..d0ceda8312c 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.cc +++ b/src/core/ext/filters/client_channel/subchannel_index.cc @@ -39,38 +39,37 @@ static gpr_mu g_mu; static gpr_refcount g_refcount; struct grpc_subchannel_key { - grpc_subchannel_args args; + grpc_channel_args* args; }; static bool g_force_creation = false; static grpc_subchannel_key* create_key( - const grpc_subchannel_args* args, + 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.args = copy_channel_args(args->args); + k->args = copy_channel_args(args); return k; } -grpc_subchannel_key* grpc_subchannel_key_create( - const grpc_subchannel_args* args) { +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); + return create_key(k->args, grpc_channel_args_copy); } 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.args, b->args.args); + return grpc_channel_args_compare(a->args, b->args); } void grpc_subchannel_key_destroy(grpc_subchannel_key* k) { - grpc_channel_args_destroy(const_cast(k->args.args)); + grpc_channel_args_destroy(k->args); gpr_free(k); } diff --git a/src/core/ext/filters/client_channel/subchannel_index.h b/src/core/ext/filters/client_channel/subchannel_index.h index c135613d26b..429634bd54c 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.h +++ b/src/core/ext/filters/client_channel/subchannel_index.h @@ -27,8 +27,7 @@ shared amongst channels */ /** Create a key that can be used to uniquely identify a subchannel */ -grpc_subchannel_key* grpc_subchannel_key_create( - const grpc_subchannel_args* args); +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); 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 e6c8c382607..a5bf1bf21d4 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -40,14 +40,12 @@ static void client_channel_factory_unref( grpc_client_channel_factory* cc_factory) {} static grpc_subchannel* client_channel_factory_create_subchannel( - grpc_client_channel_factory* cc_factory, const grpc_subchannel_args* args) { - grpc_subchannel_args final_sc_args; - memcpy(&final_sc_args, args, sizeof(*args)); - final_sc_args.args = grpc_default_authority_add_if_not_present(args->args); + 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, &final_sc_args); + grpc_subchannel* s = grpc_subchannel_create(connector, new_args); grpc_connector_unref(connector); - grpc_channel_args_destroy(const_cast(final_sc_args.args)); + 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 9612698e967..ddd538faa80 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 @@ -46,10 +46,10 @@ static void client_channel_factory_ref( static void client_channel_factory_unref( grpc_client_channel_factory* cc_factory) {} -static grpc_subchannel_args* get_secure_naming_subchannel_args( - const grpc_subchannel_args* args) { +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->args); + grpc_channel_credentials_find_in_args(args); if (channel_credentials == nullptr) { gpr_log(GPR_ERROR, "Can't create subchannel: channel credentials missing for secure " @@ -57,7 +57,7 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( return nullptr; } // Make sure security connector does not already exist in args. - if (grpc_security_connector_find_in_args(args->args) != nullptr) { + if (grpc_security_connector_find_in_args(args) != nullptr) { gpr_log(GPR_ERROR, "Can't create subchannel: security connector already present in " "channel args."); @@ -65,19 +65,18 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( } // To which address are we connecting? By default, use the server URI. const grpc_arg* server_uri_arg = - grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI); + 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->args); + 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_get_subchannel_address_uri_arg(args->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); @@ -100,15 +99,14 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( } grpc_arg args_to_add[2]; size_t num_args_to_add = 0; - if (grpc_channel_args_find(args->args, GRPC_ARG_DEFAULT_AUTHORITY) == - nullptr) { + 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, args_to_add, num_args_to_add); + 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; @@ -137,29 +135,21 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( grpc_channel_args_destroy(new_args_from_connector); } grpc_channel_args_destroy(args_with_authority); - grpc_subchannel_args* final_sc_args = - static_cast(gpr_malloc(sizeof(*final_sc_args))); - memcpy(final_sc_args, args, sizeof(*args)); - final_sc_args->args = new_args; - return final_sc_args; + return new_args; } static grpc_subchannel* client_channel_factory_create_subchannel( - grpc_client_channel_factory* cc_factory, const grpc_subchannel_args* args) { - grpc_subchannel_args* subchannel_args = - get_secure_naming_subchannel_args(args); - if (subchannel_args == nullptr) { - gpr_log( - GPR_ERROR, - "Failed to create subchannel arguments during subchannel creation."); + 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_subchannel* s = grpc_subchannel_create(connector, subchannel_args); + grpc_subchannel* s = grpc_subchannel_create(connector, new_args); grpc_connector_unref(connector); - grpc_channel_args_destroy( - const_cast(subchannel_args->args)); - gpr_free(subchannel_args); + grpc_channel_args_destroy(new_args); return s; } diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 8d12606434b..125b1ce5c4e 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -326,7 +326,7 @@ class FakeClientChannelFactory : public grpc_client_channel_factory { 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_subchannel_args* args) { + const grpc_channel_args* args) { return nullptr; } static grpc_channel* CreateClientChannel(grpc_client_channel_factory* factory, From a9ce1e05296aefd0213ef42f8bbe01b60a8a3384 Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Wed, 9 Jan 2019 08:45:09 -0700 Subject: [PATCH 0734/2143] 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 d4fa274bf2994276341e47920aa46e7a009b4d10 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 9 Jan 2019 09:38:47 -0800 Subject: [PATCH 0735/2143] address comments --- src/objective-c/GRPCClient/GRPCCall.m | 4 ---- src/objective-c/RxLibrary/GRXConcurrentWriteable.m | 6 ++---- src/objective-c/RxLibrary/GRXWriter.h | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index bc48f1aa1b3..c0d10cacc14 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -425,9 +425,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; // queue dispatch_queue_t _responseQueue; - // Whether the call is finished. If it is, should not call finishWithError again. - BOOL _finished; - // The OAuth2 token fetched from a token provider. NSString *_fetchedOauth2AccessToken; } @@ -750,7 +747,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self cancel]; } else { dispatch_async(_callQueue, ^{ - // EOS error is not processed here. It is handled by op batch of GRPC_OP_RECV_STATUS_ON_CLIENT [self finishRequestWithErrorHandler:nil]; }); diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index d8491d2aed5..115195463de 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -113,10 +113,8 @@ - (void)cancelSilently { dispatch_async(_writeableQueue, ^{ - @synchronized(self) { - if (self->_alreadyFinished) { - return; - } + if (self->_alreadyFinished) { + return; } self.writeable = nil; }); diff --git a/src/objective-c/RxLibrary/GRXWriter.h b/src/objective-c/RxLibrary/GRXWriter.h index ac1f7b9c4cf..df4c80c28dd 100644 --- a/src/objective-c/RxLibrary/GRXWriter.h +++ b/src/objective-c/RxLibrary/GRXWriter.h @@ -82,7 +82,7 @@ typedef NS_ENUM(NSInteger, GRXWriterState) { * the corresponding value, and that's useful for advanced use cases like pausing an writer. For * more details, see the documentation of the enum further down. The property is thread safe. */ -@property(atomic) GRXWriterState state; +@property GRXWriterState state; /** * Transition to the Started state, and start sending messages to the writeable (a reference to it From ca5c0a83664068dc0691166c0438e664a95a58ac Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 9 Jan 2019 09:43:14 -0800 Subject: [PATCH 0736/2143] Switch to absolute import --- src/python/grpcio/grpc/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 70d7618e056..8613bc501f1 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -24,7 +24,7 @@ from grpc._cython import cygrpc as _cygrpc logging.getLogger(__name__).addHandler(logging.NullHandler()) try: - from ._grpcio_metadata import __version__ + from grpc._grpcio_metadata import __version__ except ImportError: __version__ = "dev0" From 025cb9b1e712ad215b9180d9a74c2c71ce870ac2 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 9 Jan 2019 10:33:48 -0800 Subject: [PATCH 0737/2143] 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 1c91bcceb06d4cbb06f775d03bda7a86cb19615d Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 9 Jan 2019 10:33:48 -0800 Subject: [PATCH 0738/2143] 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 0739/2143] 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 eda9742bbdb4899c6661509981abab729a7044e8 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 9 Jan 2019 10:57:53 -0800 Subject: [PATCH 0740/2143] updated bazel and RBE instance versions --- third_party/toolchains/BUILD | 12 ++++++------ tools/remote_build/rbe_common.bazelrc | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index e213461acc9..2499d1c788c 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -20,17 +20,17 @@ package(default_visibility = ["//visibility:public"]) # Update every time when a new container is released. alias( name = "rbe_ubuntu1604", - actual = ":rbe_ubuntu1604_r342117", + actual = ":rbe_ubuntu1604_r346485", ) alias( name = "rbe_ubuntu1604_large", - actual = ":rbe_ubuntu1604_r342117_large", + actual = ":rbe_ubuntu1604_r346485_large", ) -# RBE Ubuntu16_04 r342117 +# RBE Ubuntu16_04 r346485 platform( - name = "rbe_ubuntu1604_r342117", + name = "rbe_ubuntu1604_r346485", constraint_values = [ "@bazel_tools//platforms:x86_64", "@bazel_tools//platforms:linux", @@ -51,9 +51,9 @@ platform( """, ) -# RBE Ubuntu16_04 r342117 large +# RBE Ubuntu16_04 r346485 large platform( - name = "rbe_ubuntu1604_r342117_large", + name = "rbe_ubuntu1604_r346485_large", constraint_values = [ "@bazel_tools//platforms:x86_64", "@bazel_tools//platforms:linux", diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index aa3ddb050cd..8cf17a30860 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -18,7 +18,7 @@ startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 -build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain +build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.20.0/default:toolchain build --extra_toolchains=//third_party/toolchains:cc-toolchain-clang-x86_64-default # Use custom execution platforms defined in third_party/toolchains build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large @@ -61,9 +61,9 @@ build:msan --cxxopt=--stdlib=libc++ # setting LD_LIBRARY_PATH is necessary # to avoid "libc++.so.1: cannot open shared object file" build:msan --action_env=LD_LIBRARY_PATH=/usr/local/lib -build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain +build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.20.0/default:toolchain # override the config-agnostic crosstool_top -build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/msan:toolchain +build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.20.0/msan:toolchain # thread sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific @@ -79,7 +79,7 @@ build:ubsan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:ubsan --test_timeout=3600 # override the config-agnostic crosstool_top ---crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.1/bazel_0.16.1/ubsan:toolchain +--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.1/bazel_0.20.0/ubsan:toolchain # TODO(jtattermusch): remove this once Foundry adds the env to the docker image. # ubsan needs symbolizer to work properly, otherwise the suppression file doesn't work # and we get test failures. From 95dc9c1110d83c42dea668d6d8729b920caa400c Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 9 Jan 2019 11:21:29 -0800 Subject: [PATCH 0741/2143] updated repo for bazel --- bazel/grpc_deps.bzl | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 3eacd2b0475..ea66fa80999 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -93,17 +93,17 @@ def grpc_deps(): native.bind( name = "opencensus-trace", - actual = "@io_opencensus_cpp//opencensus/trace:trace" + actual = "@io_opencensus_cpp//opencensus/trace:trace", ) native.bind( name = "opencensus-stats", - actual = "@io_opencensus_cpp//opencensus/stats:stats" + actual = "@io_opencensus_cpp//opencensus/stats:stats", ) native.bind( name = "opencensus-stats-test", - actual = "@io_opencensus_cpp//opencensus/stats:test_utils" + actual = "@io_opencensus_cpp//opencensus/stats:test_utils", ) if "boringssl" not in native.existing_rules(): @@ -177,16 +177,16 @@ def grpc_deps(): if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): http_archive( name = "com_github_bazelbuild_bazeltoolchains", - strip_prefix = "bazel-toolchains-280edaa6f93623074513d2b426068de42e62ea4d", + strip_prefix = "bazel-toolchains-35bfb70728dedc936a370e551294f2fc9c02b7d5", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/280edaa6f93623074513d2b426068de42e62ea4d.tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/280edaa6f93623074513d2b426068de42e62ea4d.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/35bfb70728dedc936a370e551294f2fc9c02b7d5.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/35bfb70728dedc936a370e551294f2fc9c02b7d5.tar.gz", ], sha256 = "50c9df51f80cdf9ff8f2bc27620c155526b9ba67be95e8a686f32ff8898a06e2", ) if "io_opencensus_cpp" not in native.existing_rules(): - http_archive( + http_archive( name = "io_opencensus_cpp", strip_prefix = "opencensus-cpp-fdf0f308b1631bb4a942e32ba5d22536a6170274", url = "https://github.com/census-instrumentation/opencensus-cpp/archive/fdf0f308b1631bb4a942e32ba5d22536a6170274.tar.gz", @@ -199,7 +199,6 @@ def grpc_deps(): url = "https://github.com/google/upb/archive/9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3.tar.gz", ) - # TODO: move some dependencies from "grpc_deps" here? def grpc_test_only_deps(): """Internal, not intended for use by packages that are consuming grpc. From b2ac318566bcdcdd0a8306af5030e62025d6666a Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 9 Jan 2019 11:25:05 -0800 Subject: [PATCH 0742/2143] updated repo for bazel to latest version --- 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 ea66fa80999..8eb60d13d4f 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -177,12 +177,12 @@ def grpc_deps(): if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): http_archive( name = "com_github_bazelbuild_bazeltoolchains", - strip_prefix = "bazel-toolchains-35bfb70728dedc936a370e551294f2fc9c02b7d5", + strip_prefix = "bazel-toolchains-37419a124bdb9af2fec5b99a973d359b6b899b61 ", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/35bfb70728dedc936a370e551294f2fc9c02b7d5.tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/35bfb70728dedc936a370e551294f2fc9c02b7d5.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61 .tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61 .tar.gz", ], - sha256 = "50c9df51f80cdf9ff8f2bc27620c155526b9ba67be95e8a686f32ff8898a06e2", + sha256 = "ee854b5de299138c1f4a2edb5573d22b21d975acfc7aa938f36d30b49ef97498", ) if "io_opencensus_cpp" not in native.existing_rules(): From 56268e092719860491de0d2b1da44d7a7d7fcb2c Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 9 Jan 2019 11:32:18 -0800 Subject: [PATCH 0743/2143] fixed typo on hash --- bazel/grpc_deps.bzl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 8eb60d13d4f..450928828c2 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -177,10 +177,10 @@ def grpc_deps(): if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): http_archive( name = "com_github_bazelbuild_bazeltoolchains", - strip_prefix = "bazel-toolchains-37419a124bdb9af2fec5b99a973d359b6b899b61 ", + strip_prefix = "bazel-toolchains-37419a124bdb9af2fec5b99a973d359b6b899b61", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61 .tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61 .tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/37419a124bdb9af2fec5b99a973d359b6b899b61.tar.gz", ], sha256 = "ee854b5de299138c1f4a2edb5573d22b21d975acfc7aa938f36d30b49ef97498", ) From 3dafee1e51813beff7b5947702772f1d22a06ed5 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 9 Jan 2019 11:55:57 -0800 Subject: [PATCH 0744/2143] bumped bazel version for internal CI --- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index 4d7d4271d61..863b43a1728 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -23,7 +23,7 @@ cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321 # Download bazel temp_dir="$(mktemp -d)" -wget -q https://github.com/bazelbuild/bazel/releases/download/0.17.1/bazel-0.17.1-linux-x86_64 -O "${temp_dir}/bazel" +wget -q https://github.com/bazelbuild/bazel/releases/download/0.20.0/bazel-0.20.0-linux-x86_64 -O "${temp_dir}/bazel" chmod 755 "${temp_dir}/bazel" export PATH="${temp_dir}:${PATH}" # This should show ${temp_dir}/bazel From 9f85ead667121f5c74fe232e7908ab774131e1e2 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 9 Jan 2019 12:06:24 -0800 Subject: [PATCH 0745/2143] Add new proto in examples --- examples/BUILD | 5 +++++ examples/protos/keyvaluestore.proto | 33 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 examples/protos/keyvaluestore.proto diff --git a/examples/BUILD b/examples/BUILD index c4f25d0de9f..b6cb9d48d3c 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -38,6 +38,11 @@ grpc_proto_library( srcs = ["protos/route_guide.proto"], ) +grpc_proto_library( + name = "keyvaluestore", + srcs = ["protos/keyvaluestore.proto"], +) + cc_binary( name = "greeter_client", srcs = ["cpp/helloworld/greeter_client.cc"], diff --git a/examples/protos/keyvaluestore.proto b/examples/protos/keyvaluestore.proto new file mode 100644 index 00000000000..06b516a1501 --- /dev/null +++ b/examples/protos/keyvaluestore.proto @@ -0,0 +1,33 @@ +// 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. + +syntax = "proto3"; + +package keyvaluestore; + +// Key value store service definition. +service KeyValueStore { + // Provides a value for each key reques + rpc GetValues (stream Key) returns (stream Value) {} +} + +// The request message containing the key +message Key { + string key = 1; +} + +// The response message containing the greetings +message Value { + string value = 1; +} From 4f11b9650099212b9bb3c01b6b73e977a20c2c8e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 16:35:35 +0100 Subject: [PATCH 0746/2143] stop testing older releases with go1.7: 1.8 should be enough --- tools/interop_matrix/README.md | 4 ++-- tools/interop_matrix/client_matrix.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index 6676f5d470c..531bef82b8e 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -42,10 +42,10 @@ For more details on each step, refer to sections below. - The output for all the test cases is recorded in a junit style xml file (default to 'report.xml'). ## Instructions for running test cases against a GCR image manually -- Download docker image from GCR. For example: `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_go1.7:master`. +- Download docker image from GCR. For example: `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_go1.8:master`. - Run test cases by specifying `docker_image` variable inline with the test case script created above. For example: - - `docker_image=gcr.io/grpc-testing/grpc_interop_go1.7:master ./testcases/go__master` will run go__master test cases against `go1.7` with gRPC release `master` docker image in GCR. + - `docker_image=gcr.io/grpc-testing/grpc_interop_go1.8:master ./testcases/go__master` will run go__master test cases against `go1.8` with gRPC release `master` docker image in GCR. Note: - File path starting with `tools/` or `template/` are relative to the grpc repo root dir. File path starting with `./` are relative to current directory (`tools/interop_matrix`). diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 12051e70a0b..9a7c90acd32 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -57,7 +57,7 @@ def should_build_docker_interop_image_from_release_tag(lang): # Dictionary of runtimes per language LANG_RUNTIME_MATRIX = { 'cxx': ['cxx'], # This is actually debian8. - 'go': ['go1.7', 'go1.8', 'go1.11'], + 'go': ['go1.8', 'go1.11'], 'java': ['java_oracle8'], 'python': ['python'], 'node': ['node'], @@ -116,7 +116,7 @@ LANG_RELEASE_MATRIX = { ('v1.14.0', ReleaseInfo(skip_runtime=['go1.11'])), ('v1.15.0', ReleaseInfo(skip_runtime=['go1.11'])), ('v1.16.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.17.0', ReleaseInfo(skip_runtime=['go1.7', 'go1.8'])), + ('v1.17.0', ReleaseInfo(skip_runtime=['go1.8'])), ]), 'java': OrderedDict([ From bd5e15608d217e7a5efcaac73dc45f7d1be28a21 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 16:44:43 +0100 Subject: [PATCH 0747/2143] minor doc updates --- tools/interop_matrix/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index 531bef82b8e..5a8965757ee 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -11,8 +11,8 @@ We have continuous nightly test setup to test gRPC backward compatibility betwee - Build new client docker image(s). For example, for C and wrapper languages release `v1.9.9`, do - `tools/interop_matrix/create_matrix_images.py --git_checkout --release=v1.9.9 --upload_images --language cxx csharp python ruby php` - Verify that the new docker image was built successfully and uploaded to GCR. For example, - - `gcloud beta container images list --repository gcr.io/grpc-testing` shows image repos. - - `gcloud beta container images list-tags gcr.io/grpc-testing/grpc_interop_java_oracle8` should show an image entry with tag `v1.9.9`. + - `gcloud container images list --repository gcr.io/grpc-testing` lists available images. + - `gcloud container images list-tags gcr.io/grpc-testing/grpc_interop_java_oracle8` should show an image entry with tag `v1.9.9`. - Verify the just-created docker client image would pass backward compatibility test (it should). For example, - `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_java_oracle8:v1.9.9` followed by - `docker_image=gcr.io/grpc-testing/grpc_interop_java_oracle8:v1.9.9 tools/interop_matrix/testcases/java__master` From 2a997c66eada4015912230a482d3b898ec526800 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 16:51:51 +0100 Subject: [PATCH 0748/2143] allow creating images for non-yet-listed releases --- tools/interop_matrix/client_matrix.py | 2 +- tools/interop_matrix/create_matrix_images.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 9a7c90acd32..ec499a98b61 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -36,7 +36,7 @@ def get_release_tags(lang): def get_runtimes_for_lang_release(lang, release): """Get list of valid runtimes for given release of lang.""" runtimes_to_skip = [] - release_info = LANG_RELEASE_MATRIX[lang][release] + release_info = LANG_RELEASE_MATRIX[lang].get(release) if release_info: runtimes_to_skip = release_info.skip_runtime return [ diff --git a/tools/interop_matrix/create_matrix_images.py b/tools/interop_matrix/create_matrix_images.py index 31a0e1c7ba6..28dc4be0f4d 100755 --- a/tools/interop_matrix/create_matrix_images.py +++ b/tools/interop_matrix/create_matrix_images.py @@ -260,7 +260,7 @@ atexit.register(cleanup) def maybe_apply_patches_on_git_tag(stack_base, lang, release): files_to_patch = [] - release_info = client_matrix.LANG_RELEASE_MATRIX[lang][release] + release_info = client_matrix.LANG_RELEASE_MATRIX[lang].get(release) if release_info: files_to_patch = release_info.patch if not files_to_patch: From 0d1743b3cc2a24dc2a17fb8e87e2fc8795d44585 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 17:11:54 +0100 Subject: [PATCH 0749/2143] having GCR images with ":master" tag is an antipattern. --- tools/interop_matrix/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index 5a8965757ee..a2c3189bbd6 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -42,10 +42,10 @@ For more details on each step, refer to sections below. - The output for all the test cases is recorded in a junit style xml file (default to 'report.xml'). ## Instructions for running test cases against a GCR image manually -- Download docker image from GCR. For example: `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_go1.8:master`. +- Download docker image from GCR. For example: `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_go1.8:v1.16.0`. - Run test cases by specifying `docker_image` variable inline with the test case script created above. For example: - - `docker_image=gcr.io/grpc-testing/grpc_interop_go1.8:master ./testcases/go__master` will run go__master test cases against `go1.8` with gRPC release `master` docker image in GCR. + - `docker_image=gcr.io/grpc-testing/grpc_interop_go1.8:v1.16.0 ./testcases/go__master` will run go__master test cases against `go1.8` with gRPC release `v1.16.0` docker image in GCR. Note: - File path starting with `tools/` or `template/` are relative to the grpc repo root dir. File path starting with `./` are relative to current directory (`tools/interop_matrix`). From b2044fdd6f8a74cbd489affee7f195b82bb15aac Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 17:22:09 +0100 Subject: [PATCH 0750/2143] remove confusing remarks from interop_matrix README.md --- tools/interop_matrix/README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index a2c3189bbd6..ecd71be7f87 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -13,6 +13,7 @@ We have continuous nightly test setup to test gRPC backward compatibility betwee - Verify that the new docker image was built successfully and uploaded to GCR. For example, - `gcloud container images list --repository gcr.io/grpc-testing` lists available images. - `gcloud container images list-tags gcr.io/grpc-testing/grpc_interop_java_oracle8` should show an image entry with tag `v1.9.9`. + - images can also be viewed in https://pantheon.corp.google.com/gcr/images/grpc-testing?project=grpc-testing - Verify the just-created docker client image would pass backward compatibility test (it should). For example, - `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_java_oracle8:v1.9.9` followed by - `docker_image=gcr.io/grpc-testing/grpc_interop_java_oracle8:v1.9.9 tools/interop_matrix/testcases/java__master` @@ -20,13 +21,11 @@ We have continuous nightly test setup to test gRPC backward compatibility betwee - (Optional) clean up the tmp directory to where grpc source is cloned at `/export/hda3/tmp/grpc_matrix/`. For more details on each step, refer to sections below. -## Instructions for adding new language/runtimes* +## Instructions for adding new language/runtimes - Create new `Dockerfile.template`, `build_interop.sh.template` for the language/runtime under `template/tools/dockerfile/`. - Run `tools/buildgen/generate_projects.sh` to create corresponding files under `tools/dockerfile/`. - Add language/runtimes to `client_matrix.py` following existing language/runtimes examples. -- Run `tools/interop_matrix/create_matrix_images.py` which will build and upload images to GCR. Unless you are also building images for a gRPC release, make sure not to set `--release` (the default release 'master' is used for testing). - -*: Please delete your docker images at https://pantheon.corp.google.com/gcr/images/grpc-testing?project=grpc-testing afterwards. Permissions to access GrpcTesting project is required for this step. +- Run `tools/interop_matrix/create_matrix_images.py` which will build (and upload) images to GCR. ## Instructions for creating new test cases - Create test cases by running `LANG= [RELEASE=] ./create_testcases.sh`. For example, @@ -39,7 +38,7 @@ For more details on each step, refer to sections below. - `--release` specifies a git release tag. Defaults to `--release=all`. Make sure the GCR images with the tag have been created using `create_matrix_images.py` above. - `--language` specifies a language. Defaults to `--language=all`. For example, To test all languages for all gRPC releases across all runtimes, do `tools/interop_matrix/run_interop_matrix_test.py --release=all`. -- The output for all the test cases is recorded in a junit style xml file (default to 'report.xml'). +- The output for all the test cases is recorded in a junit style xml file (defaults to 'report.xml'). ## Instructions for running test cases against a GCR image manually - Download docker image from GCR. For example: `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_go1.8:v1.16.0`. From 905cd6a3151269fd2c3ad8577fbce5431d8f791b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 18:10:06 +0100 Subject: [PATCH 0751/2143] invert the strategy test runtimes are being selected per release --- tools/interop_matrix/client_matrix.py | 53 ++++++++++++++------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index ec499a98b61..655c7c7b6bf 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -35,14 +35,15 @@ def get_release_tags(lang): def get_runtimes_for_lang_release(lang, release): """Get list of valid runtimes for given release of lang.""" - runtimes_to_skip = [] + runtimes = list(LANG_RUNTIME_MATRIX[lang]) release_info = LANG_RELEASE_MATRIX[lang].get(release) - if release_info: - runtimes_to_skip = release_info.skip_runtime - return [ - runtime for runtime in LANG_RUNTIME_MATRIX[lang] - if runtime not in runtimes_to_skip - ] + if release_info and release_info.runtime_subset: + runtimes = list(release_info.runtime_subset) + + # check that all selected runtimes are valid for given language + for runtime in runtimes: + assert runtime in LANG_RUNTIME_MATRIX[lang] + return runtimes def should_build_docker_interop_image_from_release_tag(lang): @@ -70,9 +71,9 @@ LANG_RUNTIME_MATRIX = { class ReleaseInfo: """Info about a single release of a language""" - def __init__(self, patch=[], skip_runtime=[], testcases_file=None): + def __init__(self, patch=[], runtime_subset=[], testcases_file=None): self.patch = patch - self.skip_runtime = skip_runtime + self.runtime_subset = runtime_subset self.testcases_file = None @@ -100,23 +101,23 @@ LANG_RELEASE_MATRIX = { ]), 'go': OrderedDict([ - ('v1.0.5', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.2.1', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.3.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.4.2', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.5.2', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.6.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.7.4', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.8.2', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.9.2', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.10.1', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.11.3', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.12.2', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.13.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.14.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.15.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.16.0', ReleaseInfo(skip_runtime=['go1.11'])), - ('v1.17.0', ReleaseInfo(skip_runtime=['go1.8'])), + ('v1.0.5', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.2.1', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.3.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.4.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.5.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.6.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.7.4', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.8.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.9.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.10.1', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.11.3', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.12.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.13.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.14.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.15.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.16.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.17.0', ReleaseInfo(runtime_subset=['go1.11'])), ]), 'java': OrderedDict([ From 7df3475a9f74839c63702773e9f4a7e4278ea600 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 9 Jan 2019 14:36:23 -0800 Subject: [PATCH 0752/2143] 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 0753/2143] 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 93e84947dfa3c3af2fdaaf5af0c6d6c93dd4e9fc Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 9 Jan 2019 14:58:50 -0800 Subject: [PATCH 0754/2143] Reviewer comments --- examples/protos/keyvaluestore.proto | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/protos/keyvaluestore.proto b/examples/protos/keyvaluestore.proto index 06b516a1501..9b5e53d8135 100644 --- a/examples/protos/keyvaluestore.proto +++ b/examples/protos/keyvaluestore.proto @@ -18,16 +18,16 @@ package keyvaluestore; // Key value store service definition. service KeyValueStore { - // Provides a value for each key reques - rpc GetValues (stream Key) returns (stream Value) {} + // Provides a value for each key request + rpc GetValues (stream Request) returns (stream Response) {} } // The request message containing the key -message Key { +message Request { string key = 1; } -// The response message containing the greetings -message Value { +// The response message containing the value associated with the key +message Response { string value = 1; } From 121e04bc1e44bb684d464be6788f1c0a065b1116 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 9 Jan 2019 15:22:05 -0800 Subject: [PATCH 0755/2143] address comments 2 --- src/objective-c/GRPCClient/GRPCCall.m | 1 - src/objective-c/RxLibrary/GRXForwardingWriter.m | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index c0d10cacc14..e8fae09a1f8 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -56,7 +56,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Make them read-write. @property(atomic, strong) NSDictionary *responseHeaders; @property(atomic, strong) NSDictionary *responseTrailers; -@property(atomic) BOOL isWaitingForToken; - (instancetype)initWithHost:(NSString *)host path:(NSString *)path diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.m b/src/objective-c/RxLibrary/GRXForwardingWriter.m index f5ed603698d..27ac0acdfff 100644 --- a/src/objective-c/RxLibrary/GRXForwardingWriter.m +++ b/src/objective-c/RxLibrary/GRXForwardingWriter.m @@ -72,7 +72,11 @@ #pragma mark GRXWriter implementation - (GRXWriterState)state { - return _writer ? _writer.state : GRXWriterStateFinished; + GRXWriter *copiedWriter; + @synchronized(self) { + copiedWriter = _writer; + } + return copiedWriter ? copiedWriter.state : GRXWriterStateFinished; } - (void)setState:(GRXWriterState)state { @@ -106,6 +110,7 @@ @synchronized(self) { [self finishOutputWithError:errorOrNil]; copiedWriter = _writer; + _writer = nil; } copiedWriter.state = GRXWriterStateFinished; } From de902e18b7db2cd93deff87a17d76ced99a2305a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 9 Jan 2019 16:03:29 -0800 Subject: [PATCH 0756/2143] Reviewer comments --- examples/protos/keyvaluestore.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/protos/keyvaluestore.proto b/examples/protos/keyvaluestore.proto index 9b5e53d8135..74ad57e0297 100644 --- a/examples/protos/keyvaluestore.proto +++ b/examples/protos/keyvaluestore.proto @@ -16,7 +16,7 @@ syntax = "proto3"; package keyvaluestore; -// Key value store service definition. +// A simple key-value storage service service KeyValueStore { // Provides a value for each key request rpc GetValues (stream Request) returns (stream Response) {} From 38f0fa394b1d75772a37aac2829a51a037d3271f Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 9 Jan 2019 17:01:07 -0800 Subject: [PATCH 0757/2143] Attempt to fix homebrew installation problem --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 632db5ae145..5b6b2569393 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -38,6 +38,8 @@ if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then 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 source $HOME/.rvm/scripts/rvm set -e # rvm commands are very verbose time rvm install 2.5.0 From c059946a75cab05a38dfb0c93afdbc0ee824d3a3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 9 Jan 2019 18:26:22 -0800 Subject: [PATCH 0758/2143] Fix bug where remote host's trailing slash is not removed, causing name resolution failure --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index a323f0490c8..60a33eda824 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -236,6 +236,12 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; return nil; } + // remove trailing slash of hostname + NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:host]]; + if (hostURL.host && hostURL.port == nil) { + host = [hostURL.host stringByAppendingString:@":443"]; + } + GRPCPooledChannel *pooledChannel = nil; GRPCChannelConfiguration *configuration = [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; From 7a814e2597fbda08e06034717324d8e5b423b93a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Jan 2019 11:50:14 +0100 Subject: [PATCH 0759/2143] fix build with bazel 0.21 --- 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 3eacd2b0475..ba0d72a266d 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-48cb18e5c419ddd23d9badcfe4e9df7bde1979b2", - url = "https://github.com/google/protobuf/archive/48cb18e5c419ddd23d9badcfe4e9df7bde1979b2.tar.gz", + strip_prefix = "protobuf-66dc42d891a4fc8e9190c524fd67961688a37bbe", + url = "https://github.com/google/protobuf/archive/66dc42d891a4fc8e9190c524fd67961688a37bbe.tar.gz", ) if "com_github_nanopb_nanopb" not in native.existing_rules(): From 8cd7178afb2cde1e9203c2edd4668f04210484b9 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 10 Jan 2019 09:26:44 -0800 Subject: [PATCH 0760/2143] 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 5eed6d9d58b96e4d14d2cb9423656c90f572b57c Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 10 Jan 2019 10:23:43 -0800 Subject: [PATCH 0761/2143] fixed version on toolchain --- third_party/toolchains/BUILD | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 2499d1c788c..a1bee7f1f68 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -74,14 +74,12 @@ platform( """, ) -# This target is auto-generated from release/cpp.tpl and should not be -# modified directly. toolchain( name = "cc-toolchain-clang-x86_64-default", exec_compatible_with = [ ], target_compatible_with = [ ], - toolchain = "@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:cc-compiler-k8", + toolchain = "@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.20.0/default:cc-compiler-k8", toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", ) From d6e2b336702fff194ec8d6208f2fe8e8b028672c Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 10 Jan 2019 10:31:16 -0800 Subject: [PATCH 0762/2143] 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 0763/2143] 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 0764/2143] 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 7a5a9544ef9afb8456e5241741ceb387153bfb38 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 9 Jan 2019 14:56:42 -0800 Subject: [PATCH 0765/2143] Add a naive client server implementation --- examples/BUILD | 14 +++ .../cpp/keyvaluestore/caching_interceptor.cc | 0 examples/cpp/keyvaluestore/client.cc | 85 ++++++++++++++++ examples/cpp/keyvaluestore/server.cc | 99 +++++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 examples/cpp/keyvaluestore/caching_interceptor.cc create mode 100644 examples/cpp/keyvaluestore/client.cc create mode 100644 examples/cpp/keyvaluestore/server.cc diff --git a/examples/BUILD b/examples/BUILD index b6cb9d48d3c..4fee663bd9e 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -98,3 +98,17 @@ cc_binary( defines = ["BAZEL_BUILD"], deps = [":helloworld", "//:grpc++"], ) + +cc_binary( + name = "keyvaluestore_client", + srcs = ["cpp/keyvaluestore/client.cc"], + defines = ["BAZEL_BUILD"], + deps = [":keyvaluestore", "//:grpc++"], +) + +cc_binary( + name = "keyvaluestore_server", + srcs = ["cpp/keyvaluestore/server.cc"], + defines = ["BAZEL_BUILD"], + deps = [":keyvaluestore", "//:grpc++"], +) \ No newline at end of file diff --git a/examples/cpp/keyvaluestore/caching_interceptor.cc b/examples/cpp/keyvaluestore/caching_interceptor.cc new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/cpp/keyvaluestore/client.cc b/examples/cpp/keyvaluestore/client.cc new file mode 100644 index 00000000000..9f5fa37cb1e --- /dev/null +++ b/examples/cpp/keyvaluestore/client.cc @@ -0,0 +1,85 @@ +/* + * + * 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/keyvaluestore.grpc.pb.h" +#else +#include "keyvaluestore.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using keyvaluestore::Request; +using keyvaluestore::Response; +using keyvaluestore::KeyValueStore; + +class KeyValueStoreClient { + public: + KeyValueStoreClient(std::shared_ptr channel) + : stub_(KeyValueStore::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + void GetValues(const std::vector& keys) { + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + auto stream = stub_->GetValues(&context); + for (const auto& key:keys) { + // Data we are sending to the server. + Request request; + request.set_key(key); + stream->Write(request); + + Response response; + stream->Read(&response); + std::cout << key << " : " << response.value() << "\n"; + } + stream->WritesDone(); + Status status = stream->Finish(); + if(!status.ok()) { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + std::cout << "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // 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"}; + client.GetValues(keys); + + return 0; +} diff --git a/examples/cpp/keyvaluestore/server.cc b/examples/cpp/keyvaluestore/server.cc new file mode 100644 index 00000000000..75d30eb1f88 --- /dev/null +++ b/examples/cpp/keyvaluestore/server.cc @@ -0,0 +1,99 @@ +/* + * + * 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/keyvaluestore.grpc.pb.h" +#else +#include "keyvaluestore.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::ServerReaderWriter; +using grpc::Status; +using keyvaluestore::Request; +using keyvaluestore::Response; +using keyvaluestore::KeyValueStore; + +struct kv_pair { + const char* key; + const char* value; +}; + +static const kv_pair kvs_map[] = { + {"key1", "value1"}, + {"key2", "value2"}, + {"key3", "value3"}, + {"key4", "value4"}, + {"key5", "value5"}, +}; + +const char * get_value_from_map(const char* key) { + for(size_t i = 0; i < sizeof(kvs_map) / sizeof(kv_pair); ++i) { + if(strcmp(key, kvs_map[i].key) == 0) { + return kvs_map[i].value; + } + } + return nullptr; +} + +// Logic and data behind the server's behavior. +class KeyValueStoreServiceImpl final : public KeyValueStore::Service { + Status GetValues(ServerContext* context, ServerReaderWriter *stream) override { + Request request; + while(stream->Read(&request)) { + Response response; + response.set_value(get_value_from_map(request.key().c_str())); + stream->Write(response); + } + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + KeyValueStoreServiceImpl service; + + ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} From f1e9306c702ee83f4808597212824301d3a909a5 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 10 Jan 2019 13:22:37 -0800 Subject: [PATCH 0766/2143] return empty string instead of nullptr --- examples/cpp/keyvaluestore/server.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cpp/keyvaluestore/server.cc b/examples/cpp/keyvaluestore/server.cc index 75d30eb1f88..8dc8752edab 100644 --- a/examples/cpp/keyvaluestore/server.cc +++ b/examples/cpp/keyvaluestore/server.cc @@ -57,7 +57,7 @@ const char * get_value_from_map(const char* key) { return kvs_map[i].value; } } - return nullptr; + return ""; } // Logic and data behind the server's behavior. From c01e866a88beee6143f19fa243b85d5792c36cae Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 10 Jan 2019 13:25:57 -0800 Subject: [PATCH 0767/2143] better documentation --- examples/cpp/keyvaluestore/client.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/cpp/keyvaluestore/client.cc b/examples/cpp/keyvaluestore/client.cc index 9f5fa37cb1e..cdf353fafd1 100644 --- a/examples/cpp/keyvaluestore/client.cc +++ b/examples/cpp/keyvaluestore/client.cc @@ -41,19 +41,19 @@ class KeyValueStoreClient { KeyValueStoreClient(std::shared_ptr channel) : stub_(KeyValueStore::NewStub(channel)) {} - // Assembles the client's payload, sends it and presents the response back - // from the server. + // Requests each key in the vector and displays the value as a pair void GetValues(const std::vector& keys) { // Context for the client. It could be used to convey extra information to // the server and/or tweak certain RPC behaviors. ClientContext context; auto stream = stub_->GetValues(&context); for (const auto& key:keys) { - // Data we are sending to the server. + // Key we are sending to the server. Request request; request.set_key(key); stream->Write(request); + // Get the value for the sent key Response response; stream->Read(&response); std::cout << key << " : " << response.value() << "\n"; From aa5950936923437b45dbe75f5d981033ec00a2f9 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 10 Jan 2019 14:13:43 -0800 Subject: [PATCH 0768/2143] Reviewer comments --- examples/cpp/keyvaluestore/caching_interceptor.cc | 0 examples/cpp/keyvaluestore/client.cc | 3 ++- examples/cpp/keyvaluestore/server.cc | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) delete mode 100644 examples/cpp/keyvaluestore/caching_interceptor.cc diff --git a/examples/cpp/keyvaluestore/caching_interceptor.cc b/examples/cpp/keyvaluestore/caching_interceptor.cc deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/examples/cpp/keyvaluestore/client.cc b/examples/cpp/keyvaluestore/client.cc index cdf353fafd1..e956a165734 100644 --- a/examples/cpp/keyvaluestore/client.cc +++ b/examples/cpp/keyvaluestore/client.cc @@ -41,7 +41,8 @@ class KeyValueStoreClient { KeyValueStoreClient(std::shared_ptr channel) : stub_(KeyValueStore::NewStub(channel)) {} - // Requests each key in the vector and displays the value as a pair + // Requests each key in the vector and displays the key and its corresponding + // value as a pair void GetValues(const std::vector& keys) { // Context for the client. It could be used to convey extra information to // the server and/or tweak certain RPC behaviors. diff --git a/examples/cpp/keyvaluestore/server.cc b/examples/cpp/keyvaluestore/server.cc index 8dc8752edab..515a1ba4c9b 100644 --- a/examples/cpp/keyvaluestore/server.cc +++ b/examples/cpp/keyvaluestore/server.cc @@ -81,7 +81,7 @@ void RunServer() { // Listen on the given address without any authentication mechanism. builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); // Register "service" as the instance through which we'll communicate with - // clients. In this case it corresponds to an *synchronous* service. + // clients. In this case, it corresponds to an *synchronous* service. builder.RegisterService(&service); // Finally assemble the server. std::unique_ptr server(builder.BuildAndStart()); From b72bb30126b8baf8b8140266bad2009e6d3c4ded Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 10 Jan 2019 14:18:24 -0800 Subject: [PATCH 0769/2143] Clang format --- examples/cpp/keyvaluestore/client.cc | 8 ++++---- examples/cpp/keyvaluestore/server.cc | 20 +++++++++----------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/examples/cpp/keyvaluestore/client.cc b/examples/cpp/keyvaluestore/client.cc index e956a165734..17e407c273b 100644 --- a/examples/cpp/keyvaluestore/client.cc +++ b/examples/cpp/keyvaluestore/client.cc @@ -32,9 +32,9 @@ using grpc::Channel; using grpc::ClientContext; using grpc::Status; +using keyvaluestore::KeyValueStore; using keyvaluestore::Request; using keyvaluestore::Response; -using keyvaluestore::KeyValueStore; class KeyValueStoreClient { public: @@ -48,7 +48,7 @@ class KeyValueStoreClient { // the server and/or tweak certain RPC behaviors. ClientContext context; auto stream = stub_->GetValues(&context); - for (const auto& key:keys) { + for (const auto& key : keys) { // Key we are sending to the server. Request request; request.set_key(key); @@ -61,7 +61,7 @@ class KeyValueStoreClient { } stream->WritesDone(); Status status = stream->Finish(); - if(!status.ok()) { + if (!status.ok()) { std::cout << status.error_code() << ": " << status.error_message() << std::endl; std::cout << "RPC failed"; @@ -79,7 +79,7 @@ int main(int argc, char** argv) { // (use of InsecureChannelCredentials()). KeyValueStoreClient client(grpc::CreateChannel( "localhost:50051", grpc::InsecureChannelCredentials())); - std::vector keys = {"key1", "key2", "key3", "key4", "key5"}; + std::vector keys = {"key1", "key2", "key3", "key4", "key5"}; client.GetValues(keys); return 0; diff --git a/examples/cpp/keyvaluestore/server.cc b/examples/cpp/keyvaluestore/server.cc index 515a1ba4c9b..e75da9c62d1 100644 --- a/examples/cpp/keyvaluestore/server.cc +++ b/examples/cpp/keyvaluestore/server.cc @@ -34,9 +34,9 @@ using grpc::ServerBuilder; using grpc::ServerContext; using grpc::ServerReaderWriter; using grpc::Status; +using keyvaluestore::KeyValueStore; using keyvaluestore::Request; using keyvaluestore::Response; -using keyvaluestore::KeyValueStore; struct kv_pair { const char* key; @@ -44,16 +44,13 @@ struct kv_pair { }; static const kv_pair kvs_map[] = { - {"key1", "value1"}, - {"key2", "value2"}, - {"key3", "value3"}, - {"key4", "value4"}, - {"key5", "value5"}, + {"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}, + {"key4", "value4"}, {"key5", "value5"}, }; -const char * get_value_from_map(const char* key) { - for(size_t i = 0; i < sizeof(kvs_map) / sizeof(kv_pair); ++i) { - if(strcmp(key, kvs_map[i].key) == 0) { +const char* get_value_from_map(const char* key) { + for (size_t i = 0; i < sizeof(kvs_map) / sizeof(kv_pair); ++i) { + if (strcmp(key, kvs_map[i].key) == 0) { return kvs_map[i].value; } } @@ -62,9 +59,10 @@ const char * get_value_from_map(const char* key) { // Logic and data behind the server's behavior. class KeyValueStoreServiceImpl final : public KeyValueStore::Service { - Status GetValues(ServerContext* context, ServerReaderWriter *stream) override { + Status GetValues(ServerContext* context, + ServerReaderWriter* stream) override { Request request; - while(stream->Read(&request)) { + while (stream->Read(&request)) { Response response; response.set_value(get_value_from_map(request.key().c_str())); stream->Write(response); From 6e94552a306e9cfcff834e39bc833bcb8055e6fe Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 10 Jan 2019 17:00:49 -0800 Subject: [PATCH 0770/2143] 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 0771/2143] 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 f36a6e9aeff37b7d14c29e817b9b573359aa5cf5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 10 Jan 2019 18:04:36 -0800 Subject: [PATCH 0772/2143] Eliminate compiler warning --- src/compiler/objective_c_generator.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc index af5398ec683..e806f46d814 100644 --- a/src/compiler/objective_c_generator.cc +++ b/src/compiler/objective_c_generator.cc @@ -353,20 +353,23 @@ void PrintMethodImplementations(Printer* printer, printer.Print(vars, "@implementation $service_class$\n\n" + "#pragma clang diagnostic push\n" + "#pragma clang diagnostic ignored " + "\"-Wobjc-designated-initializers\"\n\n" "// Designated initializer\n" "- (instancetype)initWithHost:(NSString *)host " "callOptions:(GRPCCallOptions *_Nullable)callOptions {\n" - " self = [super initWithHost:host\n" + " return [super initWithHost:host\n" " packageName:@\"$package$\"\n" " serviceName:@\"$service_name$\"\n" " callOptions:callOptions];\n" - " return self;\n" "}\n\n" "- (instancetype)initWithHost:(NSString *)host {\n" " return [super initWithHost:host\n" " packageName:@\"$package$\"\n" " serviceName:@\"$service_name$\"];\n" - "}\n\n"); + "}\n\n" + "#pragma clang diagnostic pop\n\n"); printer.Print( "// Override superclass initializer to disallow different" @@ -375,6 +378,12 @@ void PrintMethodImplementations(Printer* printer, " packageName:(NSString *)packageName\n" " serviceName:(NSString *)serviceName {\n" " return [self initWithHost:host];\n" + "}\n\n" + "- (instancetype)initWithHost:(NSString *)host\n" + " packageName:(NSString *)packageName\n" + " serviceName:(NSString *)serviceName\n" + " callOptions:(GRPCCallOptions *)callOptions {\n" + " return [self initWithHost:host callOptions:callOptions];\n" "}\n\n"); printer.Print( From b12dd1be055d81a68d535cc052aac804734453df Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Thu, 10 Jan 2019 22:12:03 -0800 Subject: [PATCH 0773/2143] Fix GrpcCodegen initialization Initializing GrpcCodegen as a global static variable is problematic because it is possible for it to get destructed before the last instance of `GrpcLibraryCodegen` gets destructed and leaves the program dealing with a dangling pointer (imagine a scenario where another thread is using gRPC resources and the main thread tries to join it in an object's destructor after main ends and CoreCodegen is destructed.) In fact, Google style guide explicitly forbids non-trivially-destructible global variables of static storage duration for this and other reasons and the solution in this commit is among the recommended workarounds referenced in https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables --- include/grpcpp/impl/grpc_library.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/grpcpp/impl/grpc_library.h b/include/grpcpp/impl/grpc_library.h index d1f3ff1297b..3711c098790 100644 --- a/include/grpcpp/impl/grpc_library.h +++ b/include/grpcpp/impl/grpc_library.h @@ -35,18 +35,17 @@ class GrpcLibrary final : public GrpcLibraryInterface { void shutdown() override { grpc_shutdown(); } }; -static GrpcLibrary g_gli; -static CoreCodegen g_core_codegen; - /// Instantiating this class ensures the proper initialization of gRPC. class GrpcLibraryInitializer final { public: GrpcLibraryInitializer() { if (grpc::g_glip == nullptr) { - grpc::g_glip = &g_gli; + static auto* const g_gli = new GrpcLibrary(); + grpc::g_glip = g_gli; } if (grpc::g_core_codegen_interface == nullptr) { - grpc::g_core_codegen_interface = &g_core_codegen; + static auto* const g_core_codegen = new CoreCodegen(); + grpc::g_core_codegen_interface = g_core_codegen; } } From 371b987bf41af61488f19e57fc0d2a1c612d35c8 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 11 Jan 2019 09:54:16 -0800 Subject: [PATCH 0774/2143] Revert turning c-ares on by default --- .../client_channel/resolver/dns/c_ares/dns_resolver_ares.cc | 2 +- templates/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(+), 2 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 fba20000ef6..abacd0c960d 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 @@ -472,7 +472,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 || 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 950a9d4897e..1873eec35bd 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 95965f71d3e99f6baa4a237e0a7046d51cd0441f Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 11 Jan 2019 10:40:20 -0800 Subject: [PATCH 0775/2143] 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 4d391b64e12bb14fc894f5699884c1b029e9078c Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 11 Jan 2019 13:35:02 -0800 Subject: [PATCH 0776/2143] 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 09f72a105763c38acc059f826fadcdfc85f1ac50 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 11 Jan 2019 13:35:02 -0800 Subject: [PATCH 0777/2143] 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 0778/2143] 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 0779/2143] 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 0780/2143] 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 0781/2143] 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 0782/2143] 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 0783/2143] 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 0784/2143] 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 0785/2143] 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 0786/2143] 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 0787/2143] 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 0788/2143] 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 0789/2143] 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 0790/2143] 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 0791/2143] 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 0792/2143] 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 0793/2143] 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 0794/2143] 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 0795/2143] 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 0796/2143] 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 0797/2143] 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 0798/2143] 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 0799/2143] 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 0800/2143] 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 0801/2143] 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 0802/2143] 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 0803/2143] 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 0804/2143] 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 0805/2143] 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 0806/2143] 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 0807/2143] 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 0808/2143] 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 0809/2143] 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 0810/2143] 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 0811/2143] 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 0812/2143] 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 0813/2143] 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 0814/2143] 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 0815/2143] 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 0816/2143] 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 0817/2143] 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 0818/2143] 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 0819/2143] 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 0820/2143] 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 0821/2143] 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 0822/2143] 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 0823/2143] 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 0824/2143] 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 0825/2143] 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 0826/2143] 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 0827/2143] 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 0828/2143] 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 0829/2143] 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 0830/2143] 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 0831/2143] 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 0832/2143] 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 0833/2143] 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 0834/2143] 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 0835/2143] 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 0836/2143] 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 0837/2143] 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 0838/2143] 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 0839/2143] 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 0840/2143] /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 0841/2143] 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 0842/2143] 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 0843/2143] 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 0844/2143] 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 0845/2143] 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 0846/2143] 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 0847/2143] 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 0848/2143] 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 0849/2143] 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 0850/2143] 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 0851/2143] 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 0852/2143] 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 0853/2143] 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 0854/2143] 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 0855/2143] 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 0856/2143] 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 0857/2143] 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 0858/2143] 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 0859/2143] 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 0860/2143] 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 0861/2143] 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 0862/2143] 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 0863/2143] 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 0864/2143] 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 0865/2143] 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 0866/2143] 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 0867/2143] 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 0868/2143] 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 0869/2143] 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 0870/2143] 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 0871/2143] 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 0872/2143] 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 0873/2143] 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 0874/2143] 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 0875/2143] 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 0876/2143] 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 0877/2143] 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 0878/2143] 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 0879/2143] 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 0880/2143] 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 0881/2143] 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 0882/2143] 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 0883/2143] 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 0884/2143] 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 0885/2143] 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 0886/2143] 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 0887/2143] 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 0888/2143] 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 0889/2143] 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 0890/2143] 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 0891/2143] 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 0892/2143] 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 0893/2143] 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 0894/2143] 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 0895/2143] 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 0896/2143] 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 0897/2143] 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 0898/2143] 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 0899/2143] 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 0900/2143] 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 0901/2143] 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 0902/2143] 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 0903/2143] 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 0904/2143] 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 0905/2143] 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 0906/2143] 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 0907/2143] 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 0908/2143] 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 0909/2143] 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 0910/2143] 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 0911/2143] 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 0912/2143] 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 0913/2143] 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 0914/2143] 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 0915/2143] 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 0916/2143] 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 0917/2143] 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 0918/2143] 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 0919/2143] 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 0920/2143] 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 0921/2143] 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 0922/2143] 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 0923/2143] 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 0924/2143] 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 0925/2143] 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 0926/2143] 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 0927/2143] 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 0928/2143] 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 0929/2143] 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 0930/2143] 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 0931/2143] 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 0932/2143] 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 0933/2143] 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 0934/2143] 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 0935/2143] 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 0936/2143] 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 0937/2143] 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 0938/2143] 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 0939/2143] 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 0940/2143] 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 0941/2143] 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 0942/2143] 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 0943/2143] 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 0944/2143] 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 0945/2143] 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 0946/2143] 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 0947/2143] 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 0948/2143] 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 0949/2143] 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 0950/2143] 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 0951/2143] 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 0952/2143] 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 0953/2143] 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 0954/2143] 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 0955/2143] 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 0956/2143] 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 0957/2143] 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 0958/2143] 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 0959/2143] 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 0960/2143] 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 0961/2143] 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 0962/2143] 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 0963/2143] 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 0964/2143] 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 0965/2143] 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 0966/2143] 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 0967/2143] 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 0968/2143] 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 0969/2143] 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 0970/2143] 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 0971/2143] 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 0972/2143] 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 0973/2143] 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 0974/2143] 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 0975/2143] 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 0976/2143] 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 0977/2143] 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 0978/2143] 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 0979/2143] 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 0980/2143] 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 0981/2143] 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 0982/2143] 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 0983/2143] 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 0984/2143] 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 0985/2143] 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 0986/2143] 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 0987/2143] 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 0988/2143] 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 0989/2143] 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 0990/2143] 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 0991/2143] 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 0992/2143] 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 0993/2143] 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 e21f172d075e12949b9adf5e1411fae4582bf5fa Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 29 Jan 2019 18:15:21 -0800 Subject: [PATCH 0994/2143] Implement flow control in Objective-C --- src/objective-c/GRPCClient/GRPCCall.h | 4 + src/objective-c/GRPCClient/GRPCCall.m | 119 +++++++-- src/objective-c/GRPCClient/GRPCCallOptions.h | 16 ++ src/objective-c/GRPCClient/GRPCCallOptions.m | 16 ++ src/objective-c/ProtoRPC/ProtoRPC.h | 8 + src/objective-c/ProtoRPC/ProtoRPC.m | 22 ++ src/objective-c/tests/APIv2Tests/APIv2Tests.m | 241 +++++++++++++++++- src/objective-c/tests/InteropTests.m | 86 ++++++- 8 files changed, 494 insertions(+), 18 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 6669067fbff..aab6ecc4445 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -183,6 +183,8 @@ extern NSString *const kGRPCTrailersKey; - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; +- (void)didWriteData; + @end /** @@ -263,6 +265,8 @@ extern NSString *const kGRPCTrailersKey; */ - (void)finish; +- (void)receiveNextMessage; + /** * Get a copy of the original call options. */ diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 74a1b47ba6c..e70aa5caba0 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -63,6 +63,15 @@ const char *kCFStreamVarName = "grpc_cfstream"; requestsWriter:(GRXWriter *)requestsWriter callOptions:(GRPCCallOptions *)callOptions; +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + callSafety:(GRPCCallSafety)safety + requestsWriter:(GRXWriter *)requestsWriter + callOptions:(GRPCCallOptions *)callOptions + writeDone:(void (^)(void))writeDone; + +- (void)receiveNextMessage; + @end @implementation GRPCRequestOptions @@ -190,7 +199,14 @@ const char *kCFStreamVarName = "grpc_cfstream"; path:_requestOptions.path callSafety:_requestOptions.safety requestsWriter:_pipe - callOptions:_callOptions]; + callOptions:_callOptions + writeDone:^{ + @synchronized(self) { + if (self->_handler) { + [self issueDidWriteData]; + } + } + }]; if (_callOptions.initialMetadata) { [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata]; } @@ -363,6 +379,28 @@ const char *kCFStreamVarName = "grpc_cfstream"; } } +- (void)issueDidWriteData { + @synchronized(self) { + if (_callOptions.enableFlowControl && [_handler respondsToSelector:@selector(didWriteData)]) { + dispatch_async(_dispatchQueue, ^{ + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + }; + [copiedHandler didWriteData]; + }); + } + } +} + +- (void)receiveNextMessage { + GRPCCall *copiedCall = nil; + @synchronized(self) { + copiedCall = _call; + } + [copiedCall receiveNextMessage]; +} + @end // The following methods of a C gRPC call object aren't reentrant, and thus @@ -426,6 +464,15 @@ const char *kCFStreamVarName = "grpc_cfstream"; // The OAuth2 token fetched from a token provider. NSString *_fetchedOauth2AccessToken; + + // The callback to be called when a write message op is done. + void (^_writeDone)(void); + + // Indicate a read request to core is pending. + BOOL _pendingCoreRead; + + // Indicate a read message request from user. + BOOL _pendingReceiveNextMessage; } @synthesize state = _state; @@ -482,12 +529,26 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithHost:(NSString *)host path:(NSString *)path callSafety:(GRPCCallSafety)safety - requestsWriter:(GRXWriter *)requestWriter + requestsWriter:(GRXWriter *)requestsWriter callOptions:(GRPCCallOptions *)callOptions { + return [self initWithHost:host + path:path + callSafety:safety + requestsWriter:requestsWriter + callOptions:callOptions + writeDone:nil]; +} + +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + callSafety:(GRPCCallSafety)safety + requestsWriter:(GRXWriter *)requestsWriter + callOptions:(GRPCCallOptions *)callOptions + writeDone:(void (^)(void))writeDone { // Purposely using pointer rather than length (host.length == 0) for backwards compatibility. NSAssert(host != nil && path != nil, @"Neither host nor path can be nil."); NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); - NSAssert(requestWriter.state == GRXWriterStateNotStarted, + NSAssert(requestsWriter.state == GRXWriterStateNotStarted, @"The requests writer can't be already started."); if (!host || !path) { return nil; @@ -495,7 +556,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (safety > GRPCCallSafetyCacheableRequest) { return nil; } - if (requestWriter.state != GRXWriterStateNotStarted) { + if (requestsWriter.state != GRXWriterStateNotStarted) { return nil; } @@ -508,16 +569,20 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Serial queue to invoke the non-reentrant methods of the grpc_call object. _callQueue = dispatch_queue_create("io.grpc.call", DISPATCH_QUEUE_SERIAL); - _requestWriter = requestWriter; - + _requestWriter = requestsWriter; _requestHeaders = [[GRPCRequestHeaders alloc] initWithCall:self]; + _writeDone = writeDone; - if ([requestWriter isKindOfClass:[GRXImmediateSingleWriter class]]) { + if ([requestsWriter isKindOfClass:[GRXImmediateSingleWriter class]]) { _unaryCall = YES; _unaryOpBatch = [NSMutableArray arrayWithCapacity:kMaxClientBatch]; } _responseQueue = dispatch_get_main_queue(); + + // do not start a read until initial metadata is received + _pendingReceiveNextMessage = NO; + _pendingCoreRead = YES; } return self; } @@ -589,25 +654,28 @@ const char *kCFStreamVarName = "grpc_cfstream"; // If the call is currently paused, this is a noop. Restarting the call will invoke this // method. // TODO(jcanizales): Rename to readResponseIfNotPaused. -- (void)startNextRead { +- (void)maybeStartNextRead { @synchronized(self) { if (_state != GRXWriterStateStarted) { return; } + if (_callOptions.enableFlowControl && (_pendingCoreRead || !_pendingReceiveNextMessage)) { + return; + } } dispatch_async(_callQueue, ^{ __weak GRPCCall *weakSelf = self; [self startReadWithHandler:^(grpc_byte_buffer *message) { - if (message == NULL) { - // No more messages from the server - return; - } __strong GRPCCall *strongSelf = weakSelf; if (strongSelf == nil) { grpc_byte_buffer_destroy(message); return; } + if (message == NULL) { + // No more messages from the server + return; + } NSData *data = [NSData grpc_dataWithByteBuffer:message]; grpc_byte_buffer_destroy(message); if (!data) { @@ -616,6 +684,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // that's on the hands of any server to have. Instead we finish and ask // the server to cancel. @synchronized(strongSelf) { + strongSelf->_pendingReceiveNextMessage = NO; [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeResourceExhausted @@ -631,7 +700,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(strongSelf) { [strongSelf->_responseWriteable enqueueValue:data completionHandler:^{ - [strongSelf startNextRead]; + strongSelf->_pendingCoreRead = NO; + [strongSelf maybeStartNextRead]; }]; } } @@ -682,6 +752,17 @@ const char *kCFStreamVarName = "grpc_cfstream"; }); } +- (void)receiveNextMessage { + @synchronized(self) { + // Duplicate invocation of this method. Return + if (_pendingReceiveNextMessage) { + return; + } + _pendingReceiveNextMessage = YES; + [self maybeStartNextRead]; + } +} + #pragma mark GRXWriteable implementation // Only called from the call queue. The error handler will be called from the @@ -695,6 +776,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; GRPCCall *strongSelf = weakSelf; if (strongSelf) { strongSelf->_requestWriter.state = GRXWriterStateStarted; + if (strongSelf->_writeDone) { + strongSelf->_writeDone(); + } } }; @@ -774,8 +858,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Response headers received. __strong GRPCCall *strongSelf = weakSelf; if (strongSelf) { - strongSelf.responseHeaders = headers; - [strongSelf startNextRead]; + @synchronized(self) { + strongSelf.responseHeaders = headers; + strongSelf->_pendingCoreRead = NO; + [strongSelf maybeStartNextRead]; + } } } completionHandler:^(NSError *error, NSDictionary *trailers) { @@ -929,7 +1016,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; case GRXWriterStateStarted: if (_state == GRXWriterStatePaused) { _state = newState; - [self startNextRead]; + [self maybeStartNextRead]; } return; case GRXWriterStateNotStarted: diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index b5bf4c9eb6c..17abdc3fabf 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -90,6 +90,14 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { */ @property(readonly) NSTimeInterval timeout; +/** + * Enable flow control of a gRPC call. The option is default to NO. If set to YES, writeData: method + * should only be called at most once before a didWriteData callback is issued, and + * receiveNextMessage: must be called each time before gRPC call issues a didReceiveMessage + * callback. + */ +@property(readonly) BOOL enableFlowControl; + // OAuth2 parameters. Users of gRPC may specify one of the following two parameters. /** @@ -232,6 +240,14 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { */ @property(readwrite) NSTimeInterval timeout; +/** + * Enable flow control of a gRPC call. The option is default to NO. If set to YES, writeData: method + * should only be called at most once before a didWriteData callback is issued, and + * receiveNextMessage: must be called each time before gRPC call issues a didReceiveMessage + * callback. + */ +@property(readwrite) BOOL enableFlowControl; + // OAuth2 parameters. Users of gRPC may specify one of the following two parameters. /** diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index e59a812bd85..bb533488ec3 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -22,6 +22,7 @@ // The default values for the call options. static NSString *const kDefaultServerAuthority = nil; static const NSTimeInterval kDefaultTimeout = 0; +static const BOOL kDefaultEnableFlowControl = NO; static NSDictionary *const kDefaultInitialMetadata = nil; static NSString *const kDefaultUserAgentPrefix = nil; static const NSUInteger kDefaultResponseSizeLimit = 0; @@ -59,6 +60,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { @protected NSString *_serverAuthority; NSTimeInterval _timeout; + BOOL _enableFlowControl; NSString *_oauth2AccessToken; id _authTokenProvider; NSDictionary *_initialMetadata; @@ -84,6 +86,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { @synthesize serverAuthority = _serverAuthority; @synthesize timeout = _timeout; +@synthesize enableFlowControl = _enableFlowControl; @synthesize oauth2AccessToken = _oauth2AccessToken; @synthesize authTokenProvider = _authTokenProvider; @synthesize initialMetadata = _initialMetadata; @@ -109,6 +112,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { - (instancetype)init { return [self initWithServerAuthority:kDefaultServerAuthority timeout:kDefaultTimeout + enableFlowControl:kDefaultEnableFlowControl oauth2AccessToken:kDefaultOauth2AccessToken authTokenProvider:kDefaultAuthTokenProvider initialMetadata:kDefaultInitialMetadata @@ -134,6 +138,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { - (instancetype)initWithServerAuthority:(NSString *)serverAuthority timeout:(NSTimeInterval)timeout + enableFlowControl:(BOOL)enableFlowControl oauth2AccessToken:(NSString *)oauth2AccessToken authTokenProvider:(id)authTokenProvider initialMetadata:(NSDictionary *)initialMetadata @@ -158,6 +163,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { if ((self = [super init])) { _serverAuthority = [serverAuthority copy]; _timeout = timeout < 0 ? 0 : timeout; + _enableFlowControl = enableFlowControl; _oauth2AccessToken = [oauth2AccessToken copy]; _authTokenProvider = authTokenProvider; _initialMetadata = @@ -193,6 +199,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { GRPCCallOptions *newOptions = [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority timeout:_timeout + enableFlowControl:_enableFlowControl oauth2AccessToken:_oauth2AccessToken authTokenProvider:_authTokenProvider initialMetadata:_initialMetadata @@ -221,6 +228,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] initWithServerAuthority:[_serverAuthority copy] timeout:_timeout + enableFlowControl:_enableFlowControl oauth2AccessToken:[_oauth2AccessToken copy] authTokenProvider:_authTokenProvider initialMetadata:[[NSDictionary alloc] initWithDictionary:_initialMetadata @@ -301,6 +309,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { @dynamic serverAuthority; @dynamic timeout; +@dynamic enableFlowControl; @dynamic oauth2AccessToken; @dynamic authTokenProvider; @dynamic initialMetadata; @@ -326,6 +335,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { - (instancetype)init { return [self initWithServerAuthority:kDefaultServerAuthority timeout:kDefaultTimeout + enableFlowControl:kDefaultEnableFlowControl oauth2AccessToken:kDefaultOauth2AccessToken authTokenProvider:kDefaultAuthTokenProvider initialMetadata:kDefaultInitialMetadata @@ -353,6 +363,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { GRPCCallOptions *newOptions = [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority timeout:_timeout + enableFlowControl:_enableFlowControl oauth2AccessToken:_oauth2AccessToken authTokenProvider:_authTokenProvider initialMetadata:_initialMetadata @@ -381,6 +392,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority timeout:_timeout + enableFlowControl:_enableFlowControl oauth2AccessToken:_oauth2AccessToken authTokenProvider:_authTokenProvider initialMetadata:_initialMetadata @@ -417,6 +429,10 @@ static BOOL areObjectsEqual(id obj1, id obj2) { } } +- (void)setEnableFlowControl:(BOOL)enableFlowControl { + _enableFlowControl = enableFlowControl; +} + - (void)setOauth2AccessToken:(NSString *)oauth2AccessToken { _oauth2AccessToken = [oauth2AccessToken copy]; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 8ce3421cc17..19294763fc1 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -57,6 +57,12 @@ NS_ASSUME_NONNULL_BEGIN - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; +/** + * Issued when a write action is completed. To get a correct flow control behavior, the user of a + * call should not make more than one writeMessage: call before receiving this callback. + */ +- (void)didWriteMessage; + @end /** A unary-request RPC call with Protobuf. */ @@ -130,6 +136,8 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)finish; +- (void)receiveNextMessage; + @end NS_ASSUME_NONNULL_END diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 0ab96a5ba2b..e7a56b0f285 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -197,6 +197,14 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing [copiedCall finish]; } +- (void)receiveNextMessage { + GRPCCall2 *copiedCall; + @synchronized(self) { + copiedCall = _call; + } + [copiedCall receiveNextMessage]; +} + - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { @synchronized(self) { if (initialMetadata != nil && @@ -260,6 +268,20 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } } +- (void)didWriteData { + @synchronized(self) { + if ([_handler respondsToSelector:@selector(didWriteMessage)]) { + dispatch_async(_dispatchQueue, ^{ + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + } + [copiedHandler didWriteMessage]; + }); + } + } +} + - (dispatch_queue_t)dispatchQueue { return _dispatchQueue; } diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index ca7bf472830..6509b79b822 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -44,6 +44,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod; static const int kSimpleDataLength = 100; static const NSTimeInterval kTestTimeout = 16; +static const NSTimeInterval kInvertedTimeout = 2; // Reveal the _class ivar for testing access @interface GRPCCall2 () { @@ -56,6 +57,11 @@ static const NSTimeInterval kTestTimeout = 16; // Convenience class to use blocks as callbacks @interface ClientTestsBlockCallbacks : NSObject +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeDataCallback:(void (^)(void))writeDataCallback; + - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback messageCallback:(void (^)(id))messageCallback closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; @@ -66,21 +72,33 @@ static const NSTimeInterval kTestTimeout = 16; void (^_initialMetadataCallback)(NSDictionary *); void (^_messageCallback)(id); void (^_closeCallback)(NSDictionary *, NSError *); + void (^_writeDataCallback)(void); dispatch_queue_t _dispatchQueue; } - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeDataCallback:(void (^)(void))writeDataCallback { if ((self = [super init])) { _initialMetadataCallback = initialMetadataCallback; _messageCallback = messageCallback; _closeCallback = closeCallback; + _writeDataCallback = writeDataCallback; _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } return self; } +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + return [self initWithInitialMetadataCallback:initialMetadataCallback + messageCallback:messageCallback + closeCallback:closeCallback + writeDataCallback:nil]; +} + - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { if (self->_initialMetadataCallback) { self->_initialMetadataCallback(initialMetadata); @@ -99,6 +117,12 @@ static const NSTimeInterval kTestTimeout = 16; } } +- (void)didWriteData { + if (self->_writeDataCallback) { + self->_writeDataCallback(); + } +} + - (dispatch_queue_t)dispatchQueue { return _dispatchQueue; } @@ -475,4 +499,219 @@ static const NSTimeInterval kTestTimeout = 16; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } +- (void)testWriteFlowControl { + __weak XCTestExpectation *expectWriteData = + [self expectationWithDescription:@"Reported write data"]; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.enableFlowControl = YES; + GRPCCall2 *call = + [[GRPCCall2 alloc] initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:nil + writeDataCallback:^{ + [expectWriteData fulfill]; + }] + callOptions:options]; + + [call start]; + [call receiveNextMessage]; + [call writeData:[request data]]; + + // Wait for 3 seconds and make sure we do not receive the response + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; + + [call finish]; +} + +- (void)testReadFlowControl { + __weak __block XCTestExpectation *expectBlockedMessage = + [self expectationWithDescription:@"Message not delivered without recvNextMessage"]; + __weak __block XCTestExpectation *expectPassedMessage = nil; + __weak __block XCTestExpectation *expectBlockedClose = + [self expectationWithDescription:@"Call not closed with pending message"]; + __weak __block XCTestExpectation *expectPassedClose = nil; + expectBlockedMessage.inverted = YES; + expectBlockedClose.inverted = YES; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.enableFlowControl = YES; + __block int unblocked = NO; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *message) { + if (!unblocked) { + [expectBlockedMessage fulfill]; + } else { + [expectPassedMessage fulfill]; + } + } + closeCallback:^(NSDictionary *trailers, NSError *error) { + if (!unblocked) { + [expectBlockedClose fulfill]; + } else { + [expectPassedClose fulfill]; + } + }] + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + // Wait to make sure we do not receive the response + [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil]; + + expectPassedMessage = + [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; + expectPassedClose = [self expectationWithDescription:@"Close delivered after receiveNextMessage"]; + + unblocked = YES; + [call receiveNextMessage]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testReadFlowControlReadyBeforeStart { + __weak XCTestExpectation *expectBlockedMessage = + [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; + expectBlockedMessage.inverted = YES; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.enableFlowControl = YES; + __block BOOL closed = NO; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(NSData *message) { + [expectBlockedMessage fulfill]; + XCTAssertFalse(closed); + } + closeCallback:nil] + callOptions:options]; + + [call receiveNextMessage]; + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil]; +} + +- (void)testReadFlowControlReadyAfterStart { + __weak XCTestExpectation *expectPassedMessage = + [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; + __weak XCTestExpectation *expectPassedClose = + [self expectationWithDescription:@"Close delivered with receiveNextMessage"]; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.enableFlowControl = YES; + __block BOOL closed = NO; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *message) { + [expectPassedMessage fulfill]; + XCTAssertFalse(closed); + } + closeCallback:^(NSDictionary *trailers, NSError *error) { + closed = YES; + [expectPassedClose fulfill]; + }] + callOptions:options]; + + [call start]; + [call receiveNextMessage]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testReadFlowControlNonBlockingFailure { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.enableFlowControl = YES; + options.transportType = GRPCTransportTypeInsecure; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.payload.body = [NSMutableData dataWithLength:options.responseSizeLimit]; + + RMTEchoStatus *status = [RMTEchoStatus message]; + status.code = 2; + status.message = @"test"; + request.responseStatus = status; + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + XCTFail(@"Received unexpected message"); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, @"Expecting non-nil error"); + XCTAssertEqual(error.code, 2); + [completion fulfill]; + }] + callOptions:options]; + [call writeData:[request data]]; + [call start]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + @end diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 717dfd81f7d..3387c3c443c 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -77,6 +77,11 @@ BOOL isRemoteInteropTest(NSString *host) { // Convenience class to use blocks as callbacks @interface InteropTestsBlockCallbacks : NSObject +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeMessageCallback:(void (^)(void))writeMessageCallback; + - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback messageCallback:(void (^)(id))messageCallback closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; @@ -87,21 +92,33 @@ BOOL isRemoteInteropTest(NSString *host) { void (^_initialMetadataCallback)(NSDictionary *); void (^_messageCallback)(id); void (^_closeCallback)(NSDictionary *, NSError *); + void (^_writeMessageCallback)(void); dispatch_queue_t _dispatchQueue; } - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeMessageCallback:(void (^)(void))writeMessageCallback { if ((self = [super init])) { _initialMetadataCallback = initialMetadataCallback; _messageCallback = messageCallback; _closeCallback = closeCallback; + _writeMessageCallback = writeMessageCallback; _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } return self; } +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + return [self initWithInitialMetadataCallback:initialMetadataCallback + messageCallback:messageCallback + closeCallback:closeCallback + writeMessageCallback:nil]; +} + - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); @@ -120,6 +137,12 @@ BOOL isRemoteInteropTest(NSString *host) { } } +- (void)didWriteMessage { + if (_writeMessageCallback) { + _writeMessageCallback(); + } +} + - (dispatch_queue_t)dispatchQueue { return _dispatchQueue; } @@ -570,6 +593,67 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testPingPongRPCWithFlowControl { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPongWithV2API"]; + + NSArray *requests = @[ @27182, @8, @1828, @45904 ]; + NSArray *responses = @[ @31415, @9, @2653, @58979 ]; + + __block int index = 0; + + id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + options.enableFlowControl = YES; + __block BOOL canWriteData = NO; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertLessThan(index, 4, + @"More than 4 responses received."); + id expected = [RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]]; + XCTAssertEqualObjects(message, expected); + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + XCTAssertTrue(canWriteData); + canWriteData = NO; + [call writeMessage:request]; + [call receiveNextMessage]; + } else { + [call finish]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, + @"Finished with unexpected error: %@", + error); + XCTAssertEqual(index, 4, + @"Received %i responses instead of 4.", + index); + [expectation fulfill]; + } + writeMessageCallback:^{ + canWriteData = YES; + }] + callOptions:options]; + [call start]; + [call receiveNextMessage]; + [call writeMessage:request]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testEmptyStreamRPC { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"]; From 474a931036d40d85eb8b91120f806c81ac1cb1ef Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 6 Feb 2019 10:28:40 +0100 Subject: [PATCH 0995/2143] 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 0996/2143] 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 0997/2143] 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 0998/2143] 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 0999/2143] 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 1000/2143] 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 1001/2143] 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 1002/2143] 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 1003/2143] 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 1004/2143] 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 1005/2143] 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 1006/2143] 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 1007/2143] 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 1008/2143] 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 1009/2143] 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 1010/2143] 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 1011/2143] 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 1012/2143] 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 1013/2143] 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 1014/2143] 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 1015/2143] 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 1016/2143] 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 1017/2143] 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 1018/2143] 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 1019/2143] 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 1020/2143] 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 1021/2143] 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 1022/2143] 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 1023/2143] 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 1024/2143] 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 1025/2143] 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 1026/2143] 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 1027/2143] 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 1028/2143] 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 1029/2143] 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 1030/2143] 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 1031/2143] 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 1032/2143] 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 1033/2143] 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 1034/2143] 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 1035/2143] 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 1036/2143] 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 1037/2143] 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 1038/2143] 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 1039/2143] 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 1040/2143] 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 1041/2143] 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 1042/2143] 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 1043/2143] 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 1044/2143] 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 1045/2143] 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 1046/2143] 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 1047/2143] 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 1048/2143] 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 1049/2143] 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 1050/2143] 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 1051/2143] 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 1052/2143] 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 1053/2143] 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 1054/2143] 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 1055/2143] 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 1056/2143] 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 1057/2143] 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 1058/2143] 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 1059/2143] 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 1060/2143] 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 1061/2143] 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 1062/2143] 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 1063/2143] 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 1064/2143] 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 1065/2143] 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 1066/2143] 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 1067/2143] 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 1068/2143] 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 1069/2143] 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 1070/2143] 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 1071/2143] 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 1072/2143] 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 1073/2143] 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 1074/2143] 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 1075/2143] 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 1076/2143] 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 1077/2143] 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 1078/2143] 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 1079/2143] 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 1080/2143] 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 1081/2143] 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 1082/2143] 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 1083/2143] 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 1084/2143] 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 1085/2143] 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 1086/2143] 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 1087/2143] 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 1088/2143] 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 1089/2143] 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 1090/2143] 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 1091/2143] 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 1092/2143] 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 1093/2143] 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 1094/2143] 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 1095/2143] 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 1096/2143] 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 1097/2143] 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 1098/2143] 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 1099/2143] 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 1100/2143] 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 1101/2143] 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 1102/2143] 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 1103/2143] 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 1104/2143] 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 1105/2143] 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 1106/2143] 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 48773405dd0468ce8a5dca921f0df0360acb80bc Mon Sep 17 00:00:00 2001 From: prettyboy Date: Thu, 14 Feb 2019 20:57:35 +0300 Subject: [PATCH 1107/2143] Pass WSA_FLAG_NO_HANDLE_INHERIT flags to the WSASocketA() to avoid handle leaking on the Windows in case of using CreateProcess() on the server --- src/core/lib/iomgr/tcp_server_windows.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc index b01afdcc9db..67e4f33d44d 100644 --- a/src/core/lib/iomgr/tcp_server_windows.cc +++ b/src/core/lib/iomgr/tcp_server_windows.cc @@ -255,7 +255,7 @@ static grpc_error* start_accept_locked(grpc_tcp_listener* port) { } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; @@ -493,7 +493,7 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s, } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto done; From 1898e1be256fe4796f2ba6f0b9e2bf7b774f460a Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 14 Feb 2019 10:39:47 -0800 Subject: [PATCH 1108/2143] 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 12b0db3e57d52d6cc98b7518907a3f7fa582138b Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 14 Feb 2019 20:01:14 +0100 Subject: [PATCH 1109/2143] Folding CompletionQueue and ServerCompletionQueue. --- include/grpcpp/channel_impl.h | 12 +- include/grpcpp/generic/generic_stub.h | 1 - include/grpcpp/impl/codegen/async_stream.h | 2 - .../grpcpp/impl/codegen/async_unary_call.h | 1 - include/grpcpp/impl/codegen/call.h | 14 +- include/grpcpp/impl/codegen/call_op_set.h | 1 - .../grpcpp/impl/codegen/channel_interface.h | 15 +- include/grpcpp/impl/codegen/client_callback.h | 1 - include/grpcpp/impl/codegen/client_context.h | 2 +- .../grpcpp/impl/codegen/client_unary_call.h | 2 - .../grpcpp/impl/codegen/completion_queue.h | 382 +--------------- .../impl/codegen/completion_queue_impl.h | 417 ++++++++++++++++++ .../grpcpp/impl/codegen/intercepted_channel.h | 10 +- include/grpcpp/impl/codegen/server_context.h | 7 +- .../grpcpp/impl/codegen/server_interface.h | 51 +-- include/grpcpp/impl/codegen/service_type.h | 2 - include/grpcpp/server_builder.h | 12 +- src/compiler/cpp_generator.cc | 4 +- src/cpp/common/completion_queue_cc.cc | 8 +- 19 files changed, 498 insertions(+), 446 deletions(-) create mode 100644 include/grpcpp/impl/codegen/completion_queue_impl.h diff --git a/include/grpcpp/channel_impl.h b/include/grpcpp/channel_impl.h index ea90e5b8f7b..9ce41d92790 100644 --- a/include/grpcpp/channel_impl.h +++ b/include/grpcpp/channel_impl.h @@ -33,6 +33,8 @@ struct grpc_channel; namespace grpc_impl { +class CompletionQueue; + namespace experimental { /// Resets the channel's connection backoff. /// TODO(roth): Once we see whether this proves useful, either create a gRFC @@ -76,22 +78,22 @@ class Channel final : public ::grpc::ChannelInterface, ::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq) override; + 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; + CompletionQueue* cq, void* tag) override; bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) override; - ::grpc::CompletionQueue* CallbackCQ() override; + CompletionQueue* CallbackCQ() override; ::grpc::internal::Call CreateCallInternal( const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq, size_t interceptor_pos) override; + CompletionQueue* cq, size_t interceptor_pos) override; const grpc::string host_; grpc_channel* const c_channel_; // owned @@ -103,7 +105,7 @@ class Channel final : public ::grpc::ChannelInterface, // 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; + CompletionQueue* callback_cq_ = nullptr; std::vector< std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> diff --git a/include/grpcpp/generic/generic_stub.h b/include/grpcpp/generic/generic_stub.h index eb014184e4a..f449f1baab4 100644 --- a/include/grpcpp/generic/generic_stub.h +++ b/include/grpcpp/generic/generic_stub.h @@ -29,7 +29,6 @@ namespace grpc { -class CompletionQueue; typedef ClientAsyncReaderWriter GenericClientAsyncReaderWriter; typedef ClientAsyncResponseReader GenericClientAsyncResponseReader; diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index bfb2df4f232..721fc7e56d6 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -28,8 +28,6 @@ namespace grpc { -class CompletionQueue; - namespace internal { /// Common interface for all client side asynchronous streaming. class ClientAsyncStreamingInterface { diff --git a/include/grpcpp/impl/codegen/async_unary_call.h b/include/grpcpp/impl/codegen/async_unary_call.h index 89dcb124189..4b97cf29018 100644 --- a/include/grpcpp/impl/codegen/async_unary_call.h +++ b/include/grpcpp/impl/codegen/async_unary_call.h @@ -29,7 +29,6 @@ namespace grpc { -class CompletionQueue; extern CoreCodegenInterface* g_core_codegen_interface; /// An interface relevant for async client side unary RPCs (which send diff --git a/include/grpcpp/impl/codegen/call.h b/include/grpcpp/impl/codegen/call.h index c040c30dd9d..eefa4a7f9cd 100644 --- a/include/grpcpp/impl/codegen/call.h +++ b/include/grpcpp/impl/codegen/call.h @@ -21,9 +21,11 @@ #include #include -namespace grpc { +namespace grpc_impl { class CompletionQueue; +} +namespace grpc { namespace experimental { class ClientRpcInfo; class ServerRpcInfo; @@ -41,13 +43,13 @@ class Call final { call_(nullptr), max_receive_message_size_(-1) {} /** call is owned by the caller */ - Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq) + Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq) : call_hook_(call_hook), cq_(cq), call_(call), max_receive_message_size_(-1) {} - Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq, + Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq, experimental::ClientRpcInfo* rpc_info) : call_hook_(call_hook), cq_(cq), @@ -55,7 +57,7 @@ class Call final { max_receive_message_size_(-1), client_rpc_info_(rpc_info) {} - Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq, + Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq, int max_receive_message_size, experimental::ServerRpcInfo* rpc_info) : call_hook_(call_hook), cq_(cq), @@ -68,7 +70,7 @@ class Call final { } grpc_call* call() const { return call_; } - CompletionQueue* cq() const { return cq_; } + ::grpc_impl::CompletionQueue* cq() const { return cq_; } int max_receive_message_size() const { return max_receive_message_size_; } @@ -82,7 +84,7 @@ class Call final { private: CallHook* call_hook_; - CompletionQueue* cq_; + ::grpc_impl::CompletionQueue* cq_; grpc_call* call_; int max_receive_message_size_; experimental::ClientRpcInfo* client_rpc_info_ = nullptr; diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 4ca87a99fca..d810625b3e4 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -48,7 +48,6 @@ namespace grpc { -class CompletionQueue; extern CoreCodegenInterface* g_core_codegen_interface; namespace internal { diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h index 5353f5feaa6..17a18efaf7b 100644 --- a/include/grpcpp/impl/codegen/channel_interface.h +++ b/include/grpcpp/impl/codegen/channel_interface.h @@ -24,10 +24,13 @@ #include #include +namespace grpc_impl { +class CompletionQueue; +} + namespace grpc { class ChannelInterface; class ClientContext; -class CompletionQueue; template class ClientReader; @@ -73,7 +76,7 @@ class ChannelInterface { /// deadline expires. \a GetState needs to called to get the current state. template void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline, - CompletionQueue* cq, void* tag) { + ::grpc_impl::CompletionQueue* cq, void* tag) { TimePoint deadline_tp(deadline); NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag); } @@ -125,13 +128,13 @@ class ChannelInterface { friend class ::grpc::internal::InterceptedChannel; virtual internal::Call CreateCall(const internal::RpcMethod& method, ClientContext* context, - CompletionQueue* cq) = 0; + ::grpc_impl::CompletionQueue* cq) = 0; virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops, internal::Call* call) = 0; virtual void* RegisterMethod(const char* method) = 0; virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline, - CompletionQueue* cq, void* tag) = 0; + ::grpc_impl::CompletionQueue* cq, void* tag) = 0; virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) = 0; @@ -144,7 +147,7 @@ class ChannelInterface { // change (even though this is private and non-API) virtual internal::Call CreateCallInternal(const internal::RpcMethod& method, ClientContext* context, - CompletionQueue* cq, + ::grpc_impl::CompletionQueue* cq, size_t interceptor_pos) { return internal::Call(); } @@ -157,7 +160,7 @@ class ChannelInterface { // Returns nullptr (rather than being pure) since this is a post-1.0 method // and adding a new pure method to an interface would be a breaking change // (even though this is private and non-API) - virtual CompletionQueue* CallbackCQ() { return nullptr; } + virtual ::grpc_impl::CompletionQueue* CallbackCQ() { return nullptr; } }; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 6a0d0948cc6..f0ea62a7849 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -36,7 +36,6 @@ class Channel; namespace grpc { class ClientContext; -class CompletionQueue; namespace internal { class RpcMethod; diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index e6579b5b7a7..c291c7adfd3 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -59,12 +59,12 @@ struct grpc_call; namespace grpc_impl { class Channel; + } namespace grpc { class ChannelInterface; -class CompletionQueue; class CallCredentials; class ClientContext; diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index b9f8e1663f1..e0f692b1783 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -27,9 +27,7 @@ namespace grpc { -class Channel; class ClientContext; -class CompletionQueue; namespace internal { class RpcMethod; diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 79a2805cb5f..00f773acf48 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -32,387 +32,13 @@ #ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H #define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H -#include -#include -#include -#include -#include -#include - -struct grpc_completion_queue; - -namespace grpc_impl { - -class Channel; -} +#include namespace grpc { -template -class ClientReader; -template -class ClientWriter; -template -class ClientReaderWriter; -template -class ServerReader; -template -class ServerWriter; -namespace internal { -template -class ServerReaderWriterBody; -} // namespace internal +typedef ::grpc_impl::CompletionQueue CompletionQueue; +typedef ::grpc_impl::ServerCompletionQueue ServerCompletionQueue; -class ChannelInterface; -class ClientContext; -class CompletionQueue; -class Server; -class ServerBuilder; -class ServerContext; -class ServerInterface; - -namespace internal { -class CompletionQueueTag; -class RpcMethod; -template -class RpcMethodHandler; -template -class ClientStreamingHandler; -template -class ServerStreamingHandler; -template -class BidiStreamingHandler; -template -class TemplatedBidiStreamingHandler; -template -class ErrorMethodHandler; -template -class BlockingUnaryCallImpl; -template -class CallOpSet; -} // namespace internal - -extern CoreCodegenInterface* g_core_codegen_interface; - -/// A thin wrapper around \ref grpc_completion_queue (see \ref -/// src/core/lib/surface/completion_queue.h). -/// See \ref doc/cpp/perf_notes.md for notes on best practices for high -/// performance servers. -class CompletionQueue : private GrpcLibraryCodegen { - public: - /// Default constructor. Implicitly creates a \a grpc_completion_queue - /// instance. - CompletionQueue() - : CompletionQueue(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING, - nullptr}) {} - - /// Wrap \a take, taking ownership of the instance. - /// - /// \param take The completion queue instance to wrap. Ownership is taken. - explicit CompletionQueue(grpc_completion_queue* take); - - /// Destructor. Destroys the owned wrapped completion queue / instance. - ~CompletionQueue() { - g_core_codegen_interface->grpc_completion_queue_destroy(cq_); - } - - /// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT. - enum NextStatus { - SHUTDOWN, ///< The completion queue has been shutdown and fully-drained - GOT_EVENT, ///< Got a new event; \a tag will be filled in with its - ///< associated value; \a ok indicating its success. - TIMEOUT ///< deadline was reached. - }; - - /// Read from the queue, blocking until an event is available or the queue is - /// shutting down. - /// - /// \param tag [out] Updated to point to the read event's tag. - /// \param ok [out] true if read a successful event, false otherwise. - /// - /// Note that each tag sent to the completion queue (through RPC operations - /// or alarms) will be delivered out of the completion queue by a call to - /// Next (or a related method), regardless of whether the operation succeeded - /// or not. Success here means that this operation completed in the normal - /// valid manner. - /// - /// Server-side RPC request: \a ok indicates that the RPC has indeed - /// been started. If it is false, the server has been Shutdown - /// before this particular call got matched to an incoming RPC. - /// - /// Client-side StartCall/RPC invocation: \a ok indicates that the RPC is - /// going to go to the wire. If it is false, it not going to the wire. This - /// would happen if the channel is either permanently broken or - /// transiently broken but with the fail-fast option. (Note that async unary - /// RPCs don't post a CQ tag at this point, nor do client-streaming - /// or bidi-streaming RPCs that have the initial metadata corked option set.) - /// - /// Client-side Write, Client-side WritesDone, Server-side Write, - /// Server-side Finish, Server-side SendInitialMetadata (which is - /// typically included in Write or Finish when not done explicitly): - /// \a ok means that the data/metadata/status/etc is going to go to the - /// wire. If it is false, it not going to the wire because the call - /// is already dead (i.e., canceled, deadline expired, other side - /// dropped the channel, etc). - /// - /// Client-side Read, Server-side Read, Client-side - /// RecvInitialMetadata (which is typically included in Read if not - /// done explicitly): \a ok indicates whether there is a valid message - /// that got read. If not, you know that there are certainly no more - /// messages that can ever be read from this stream. For the client-side - /// operations, this only happens because the call is dead. For the - /// server-sider operation, though, this could happen because the client - /// has done a WritesDone already. - /// - /// Client-side Finish: \a ok should always be true - /// - /// Server-side AsyncNotifyWhenDone: \a ok should always be true - /// - /// Alarm: \a ok is true if it expired, false if it was canceled - /// - /// \return true if got an event, false if the queue is fully drained and - /// shut down. - bool Next(void** tag, bool* ok) { - return (AsyncNextInternal(tag, ok, - g_core_codegen_interface->gpr_inf_future( - GPR_CLOCK_REALTIME)) != SHUTDOWN); - } - - /// Read from the queue, blocking up to \a deadline (or the queue's shutdown). - /// Both \a tag and \a ok are updated upon success (if an event is available - /// within the \a deadline). A \a tag points to an arbitrary location usually - /// employed to uniquely identify an event. - /// - /// \param tag [out] Upon sucess, updated to point to the event's tag. - /// \param ok [out] Upon sucess, true if a successful event, false otherwise - /// See documentation for CompletionQueue::Next for explanation of ok - /// \param deadline [in] How long to block in wait for an event. - /// - /// \return The type of event read. - template - NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) { - TimePoint deadline_tp(deadline); - return AsyncNextInternal(tag, ok, deadline_tp.raw_time()); - } - - /// EXPERIMENTAL - /// First executes \a F, then reads from the queue, blocking up to - /// \a deadline (or the queue's shutdown). - /// Both \a tag and \a ok are updated upon success (if an event is available - /// within the \a deadline). A \a tag points to an arbitrary location usually - /// employed to uniquely identify an event. - /// - /// \param f [in] Function to execute before calling AsyncNext on this queue. - /// \param tag [out] Upon sucess, updated to point to the event's tag. - /// \param ok [out] Upon sucess, true if read a regular event, false - /// otherwise. - /// \param deadline [in] How long to block in wait for an event. - /// - /// \return The type of event read. - template - NextStatus DoThenAsyncNext(F&& f, void** tag, bool* ok, const T& deadline) { - CompletionQueueTLSCache cache = CompletionQueueTLSCache(this); - f(); - if (cache.Flush(tag, ok)) { - return GOT_EVENT; - } else { - return AsyncNext(tag, ok, deadline); - } - } - - /// Request the shutdown of the queue. - /// - /// \warning This method must be called at some point if this completion queue - /// is accessed with Next or AsyncNext. \a Next will not return false - /// until this method has been called and all pending tags have been drained. - /// (Likewise for \a AsyncNext returning \a NextStatus::SHUTDOWN .) - /// Only once either one of these methods does that (that is, once the queue - /// has been \em drained) can an instance of this class be destroyed. - /// Also note that applications must ensure that no work is enqueued on this - /// completion queue after this method is called. - void Shutdown(); - - /// Returns a \em raw pointer to the underlying \a grpc_completion_queue - /// instance. - /// - /// \warning Remember that the returned instance is owned. No transfer of - /// owership is performed. - grpc_completion_queue* cq() { return cq_; } - - protected: - /// Private constructor of CompletionQueue only visible to friend classes - CompletionQueue(const grpc_completion_queue_attributes& attributes) { - cq_ = g_core_codegen_interface->grpc_completion_queue_create( - g_core_codegen_interface->grpc_completion_queue_factory_lookup( - &attributes), - &attributes, NULL); - InitialAvalanching(); // reserve this for the future shutdown - } - - private: - // Friend synchronous wrappers so that they can access Pluck(), which is - // a semi-private API geared towards the synchronous implementation. - template - friend class ::grpc::ClientReader; - template - friend class ::grpc::ClientWriter; - template - friend class ::grpc::ClientReaderWriter; - template - friend class ::grpc::ServerReader; - template - friend class ::grpc::ServerWriter; - template - friend class ::grpc::internal::ServerReaderWriterBody; - template - friend class ::grpc::internal::RpcMethodHandler; - template - friend class ::grpc::internal::ClientStreamingHandler; - template - friend class ::grpc::internal::ServerStreamingHandler; - template - friend class ::grpc::internal::TemplatedBidiStreamingHandler; - template - friend class ::grpc::internal::ErrorMethodHandler; - friend class ::grpc::Server; - friend class ::grpc::ServerContext; - friend class ::grpc::ServerInterface; - template - friend class ::grpc::internal::BlockingUnaryCallImpl; - - // Friends that need access to constructor for callback CQ - friend class ::grpc_impl::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 - /// initialized, it must be flushed on the same thread. - class CompletionQueueTLSCache { - public: - CompletionQueueTLSCache(CompletionQueue* cq); - ~CompletionQueueTLSCache(); - bool Flush(void** tag, bool* ok); - - private: - CompletionQueue* cq_; - bool flushed_; - }; - - NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline); - - /// Wraps \a grpc_completion_queue_pluck. - /// \warning Must not be mixed with calls to \a Next. - bool Pluck(internal::CompletionQueueTag* tag) { - auto deadline = - g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME); - while (true) { - auto ev = g_core_codegen_interface->grpc_completion_queue_pluck( - cq_, tag, deadline, nullptr); - bool ok = ev.success != 0; - void* ignored = tag; - if (tag->FinalizeResult(&ignored, &ok)) { - GPR_CODEGEN_ASSERT(ignored == tag); - return ok; - } - } - } - - /// Performs a single polling pluck on \a tag. - /// \warning Must not be mixed with calls to \a Next. - /// - /// TODO: sreek - This calls tag->FinalizeResult() even if the cq_ is already - /// shutdown. This is most likely a bug and if it is a bug, then change this - /// implementation to simple call the other TryPluck function with a zero - /// timeout. i.e: - /// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME)) - void TryPluck(internal::CompletionQueueTag* tag) { - auto deadline = g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME); - auto ev = g_core_codegen_interface->grpc_completion_queue_pluck( - cq_, tag, deadline, nullptr); - if (ev.type == GRPC_QUEUE_TIMEOUT) return; - bool ok = ev.success != 0; - void* ignored = tag; - // the tag must be swallowed if using TryPluck - GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok)); - } - - /// Performs a single polling pluck on \a tag. Calls tag->FinalizeResult if - /// the pluck() was successful and returned the tag. - /// - /// This exects tag->FinalizeResult (if called) to return 'false' i.e expects - /// that the tag is internal not something that is returned to the user. - void TryPluck(internal::CompletionQueueTag* tag, gpr_timespec deadline) { - auto ev = g_core_codegen_interface->grpc_completion_queue_pluck( - cq_, tag, deadline, nullptr); - if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) { - return; - } - - bool ok = ev.success != 0; - void* ignored = tag; - GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok)); - } - - /// Manage state of avalanching operations : completion queue tags that - /// trigger other completion queue operations. The underlying core completion - /// queue should not really shutdown until all avalanching operations have - /// been finalized. Note that we maintain the requirement that an avalanche - /// registration must take place before CQ shutdown (which must be maintained - /// elsehwere) - void InitialAvalanching() { - gpr_atm_rel_store(&avalanches_in_flight_, static_cast(1)); - } - void RegisterAvalanching() { - gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, - static_cast(1)); - } - 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 - - gpr_atm avalanches_in_flight_; -}; - -/// A specific type of completion queue used by the processing of notifications -/// by servers. Instantiated by \a ServerBuilder. -class ServerCompletionQueue : public CompletionQueue { - public: - bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; } - - protected: - /// Default constructor - ServerCompletionQueue() : polling_type_(GRPC_CQ_DEFAULT_POLLING) {} - - private: - /// \param completion_type indicates whether this is a NEXT or CALLBACK - /// completion queue. - /// \param polling_type Informs the GRPC library about the type of polling - /// allowed on this completion queue. See grpc_cq_polling_type's description - /// in grpc_types.h for more details. - /// \param shutdown_cb is the shutdown callback used for CALLBACK api queues - ServerCompletionQueue(grpc_cq_completion_type completion_type, - grpc_cq_polling_type polling_type, - grpc_experimental_completion_queue_functor* shutdown_cb) - : CompletionQueue(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, completion_type, polling_type, - shutdown_cb}), - polling_type_(polling_type) {} - - grpc_cq_polling_type polling_type_; - friend class ServerBuilder; - friend class Server; -}; - -} // namespace grpc +} #endif // GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H diff --git a/include/grpcpp/impl/codegen/completion_queue_impl.h b/include/grpcpp/impl/codegen/completion_queue_impl.h new file mode 100644 index 00000000000..b87a1e62158 --- /dev/null +++ b/include/grpcpp/impl/codegen/completion_queue_impl.h @@ -0,0 +1,417 @@ +/* + * + * 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. + * + */ + +/// A completion queue implements a concurrent producer-consumer queue, with +/// two main API-exposed methods: \a Next and \a AsyncNext. These +/// methods are the essential component of the gRPC C++ asynchronous API. +/// There is also a \a Shutdown method to indicate that a given completion queue +/// will no longer have regular events. This must be called before the +/// completion queue is destroyed. +/// All completion queue APIs are thread-safe and may be used concurrently with +/// any other completion queue API invocation; it is acceptable to have +/// multiple threads calling \a Next or \a AsyncNext on the same or different +/// completion queues, or to call these methods concurrently with a \a Shutdown +/// elsewhere. +/// \remark{All other API calls on completion queue should be completed before +/// a completion queue destructor is called.} +#ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H +#define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H + +#include +#include +#include +#include +#include +#include + +struct grpc_completion_queue; + +namespace grpc { + +template +class ClientReader; +template +class ClientWriter; +template +class ClientReaderWriter; +template +class ServerReader; +template +class ServerWriter; +namespace internal { +template +class ServerReaderWriterBody; +} // namespace internal + +class ChannelInterface; +class ClientContext; +class Server; +class ServerBuilder; +class ServerContext; +class ServerInterface; + +namespace internal { +class CompletionQueueTag; +class RpcMethod; +template +class RpcMethodHandler; +template +class ClientStreamingHandler; +template +class ServerStreamingHandler; +template +class BidiStreamingHandler; +template +class TemplatedBidiStreamingHandler; +template +class ErrorMethodHandler; +template +class BlockingUnaryCallImpl; +template +class CallOpSet; +} // namespace internal + +extern CoreCodegenInterface* g_core_codegen_interface; + +} // namespace grpc + +namespace grpc_impl { +class Channel; + +/// A thin wrapper around \ref grpc_completion_queue (see \ref +/// src/core/lib/surface/completion_queue.h). +/// See \ref doc/cpp/perf_notes.md for notes on best practices for high +/// performance servers. +class CompletionQueue : private ::grpc::GrpcLibraryCodegen { + public: + /// Default constructor. Implicitly creates a \a grpc_completion_queue + /// instance. + CompletionQueue() + : CompletionQueue(grpc_completion_queue_attributes{ + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING, + nullptr}) {} + + /// Wrap \a take, taking ownership of the instance. + /// + /// \param take The completion queue instance to wrap. Ownership is taken. + explicit CompletionQueue(grpc_completion_queue* take); + + /// Destructor. Destroys the owned wrapped completion queue / instance. + ~CompletionQueue() { + ::grpc::g_core_codegen_interface->grpc_completion_queue_destroy(cq_); + } + + /// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT. + enum NextStatus { + SHUTDOWN, ///< The completion queue has been shutdown and fully-drained + GOT_EVENT, ///< Got a new event; \a tag will be filled in with its + ///< associated value; \a ok indicating its success. + TIMEOUT ///< deadline was reached. + }; + + /// Read from the queue, blocking until an event is available or the queue is + /// shutting down. + /// + /// \param tag [out] Updated to point to the read event's tag. + /// \param ok [out] true if read a successful event, false otherwise. + /// + /// Note that each tag sent to the completion queue (through RPC operations + /// or alarms) will be delivered out of the completion queue by a call to + /// Next (or a related method), regardless of whether the operation succeeded + /// or not. Success here means that this operation completed in the normal + /// valid manner. + /// + /// Server-side RPC request: \a ok indicates that the RPC has indeed + /// been started. If it is false, the server has been Shutdown + /// before this particular call got matched to an incoming RPC. + /// + /// Client-side StartCall/RPC invocation: \a ok indicates that the RPC is + /// going to go to the wire. If it is false, it not going to the wire. This + /// would happen if the channel is either permanently broken or + /// transiently broken but with the fail-fast option. (Note that async unary + /// RPCs don't post a CQ tag at this point, nor do client-streaming + /// or bidi-streaming RPCs that have the initial metadata corked option set.) + /// + /// Client-side Write, Client-side WritesDone, Server-side Write, + /// Server-side Finish, Server-side SendInitialMetadata (which is + /// typically included in Write or Finish when not done explicitly): + /// \a ok means that the data/metadata/status/etc is going to go to the + /// wire. If it is false, it not going to the wire because the call + /// is already dead (i.e., canceled, deadline expired, other side + /// dropped the channel, etc). + /// + /// Client-side Read, Server-side Read, Client-side + /// RecvInitialMetadata (which is typically included in Read if not + /// done explicitly): \a ok indicates whether there is a valid message + /// that got read. If not, you know that there are certainly no more + /// messages that can ever be read from this stream. For the client-side + /// operations, this only happens because the call is dead. For the + /// server-sider operation, though, this could happen because the client + /// has done a WritesDone already. + /// + /// Client-side Finish: \a ok should always be true + /// + /// Server-side AsyncNotifyWhenDone: \a ok should always be true + /// + /// Alarm: \a ok is true if it expired, false if it was canceled + /// + /// \return true if got an event, false if the queue is fully drained and + /// shut down. + bool Next(void** tag, bool* ok) { + return (AsyncNextInternal(tag, ok, + ::grpc::g_core_codegen_interface->gpr_inf_future( + GPR_CLOCK_REALTIME)) != SHUTDOWN); + } + + /// Read from the queue, blocking up to \a deadline (or the queue's shutdown). + /// Both \a tag and \a ok are updated upon success (if an event is available + /// within the \a deadline). A \a tag points to an arbitrary location usually + /// employed to uniquely identify an event. + /// + /// \param tag [out] Upon sucess, updated to point to the event's tag. + /// \param ok [out] Upon sucess, true if a successful event, false otherwise + /// See documentation for CompletionQueue::Next for explanation of ok + /// \param deadline [in] How long to block in wait for an event. + /// + /// \return The type of event read. + template + NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) { + ::grpc::TimePoint deadline_tp(deadline); + return AsyncNextInternal(tag, ok, deadline_tp.raw_time()); + } + + /// EXPERIMENTAL + /// First executes \a F, then reads from the queue, blocking up to + /// \a deadline (or the queue's shutdown). + /// Both \a tag and \a ok are updated upon success (if an event is available + /// within the \a deadline). A \a tag points to an arbitrary location usually + /// employed to uniquely identify an event. + /// + /// \param f [in] Function to execute before calling AsyncNext on this queue. + /// \param tag [out] Upon sucess, updated to point to the event's tag. + /// \param ok [out] Upon sucess, true if read a regular event, false + /// otherwise. + /// \param deadline [in] How long to block in wait for an event. + /// + /// \return The type of event read. + template + NextStatus DoThenAsyncNext(F&& f, void** tag, bool* ok, const T& deadline) { + CompletionQueueTLSCache cache = CompletionQueueTLSCache(this); + f(); + if (cache.Flush(tag, ok)) { + return GOT_EVENT; + } else { + return AsyncNext(tag, ok, deadline); + } + } + + /// Request the shutdown of the queue. + /// + /// \warning This method must be called at some point if this completion queue + /// is accessed with Next or AsyncNext. \a Next will not return false + /// until this method has been called and all pending tags have been drained. + /// (Likewise for \a AsyncNext returning \a NextStatus::SHUTDOWN .) + /// Only once either one of these methods does that (that is, once the queue + /// has been \em drained) can an instance of this class be destroyed. + /// Also note that applications must ensure that no work is enqueued on this + /// completion queue after this method is called. + void Shutdown(); + + /// Returns a \em raw pointer to the underlying \a grpc_completion_queue + /// instance. + /// + /// \warning Remember that the returned instance is owned. No transfer of + /// owership is performed. + grpc_completion_queue* cq() { return cq_; } + + protected: + /// Private constructor of CompletionQueue only visible to friend classes + CompletionQueue(const grpc_completion_queue_attributes& attributes) { + cq_ = ::grpc::g_core_codegen_interface->grpc_completion_queue_create( + ::grpc::g_core_codegen_interface->grpc_completion_queue_factory_lookup( + &attributes), + &attributes, NULL); + InitialAvalanching(); // reserve this for the future shutdown + } + + private: + // Friend synchronous wrappers so that they can access Pluck(), which is + // a semi-private API geared towards the synchronous implementation. + template + friend class ::grpc::ClientReader; + template + friend class ::grpc::ClientWriter; + template + friend class ::grpc::ClientReaderWriter; + template + friend class ::grpc::ServerReader; + template + friend class ::grpc::ServerWriter; + template + friend class ::grpc::internal::ServerReaderWriterBody; + template + friend class ::grpc::internal::RpcMethodHandler; + template + friend class ::grpc::internal::ClientStreamingHandler; + template + friend class ::grpc::internal::ServerStreamingHandler; + template + friend class ::grpc::internal::TemplatedBidiStreamingHandler; + template <::grpc::StatusCode code> + friend class ::grpc::internal::ErrorMethodHandler; + friend class ::grpc::Server; + friend class ::grpc::ServerContext; + friend class ::grpc::ServerInterface; + template + friend class ::grpc::internal::BlockingUnaryCallImpl; + + // Friends that need access to constructor for callback CQ + friend class ::grpc_impl::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 + /// initialized, it must be flushed on the same thread. + class CompletionQueueTLSCache { + public: + CompletionQueueTLSCache(CompletionQueue* cq); + ~CompletionQueueTLSCache(); + bool Flush(void** tag, bool* ok); + + private: + CompletionQueue* cq_; + bool flushed_; + }; + + NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline); + + /// Wraps \a grpc_completion_queue_pluck. + /// \warning Must not be mixed with calls to \a Next. + bool Pluck(::grpc::internal::CompletionQueueTag* tag) { + auto deadline = + ::grpc::g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME); + while (true) { + auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck( + cq_, tag, deadline, nullptr); + bool ok = ev.success != 0; + void* ignored = tag; + if (tag->FinalizeResult(&ignored, &ok)) { + GPR_CODEGEN_ASSERT(ignored == tag); + return ok; + } + } + } + + /// Performs a single polling pluck on \a tag. + /// \warning Must not be mixed with calls to \a Next. + /// + /// TODO: sreek - This calls tag->FinalizeResult() even if the cq_ is already + /// shutdown. This is most likely a bug and if it is a bug, then change this + /// implementation to simple call the other TryPluck function with a zero + /// timeout. i.e: + /// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME)) + void TryPluck(::grpc::internal::CompletionQueueTag* tag) { + auto deadline = ::grpc::g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME); + auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck( + cq_, tag, deadline, nullptr); + if (ev.type == GRPC_QUEUE_TIMEOUT) return; + bool ok = ev.success != 0; + void* ignored = tag; + // the tag must be swallowed if using TryPluck + GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok)); + } + + /// Performs a single polling pluck on \a tag. Calls tag->FinalizeResult if + /// the pluck() was successful and returned the tag. + /// + /// This exects tag->FinalizeResult (if called) to return 'false' i.e expects + /// that the tag is internal not something that is returned to the user. + void TryPluck(::grpc::internal::CompletionQueueTag* tag, gpr_timespec deadline) { + auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck( + cq_, tag, deadline, nullptr); + if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) { + return; + } + + bool ok = ev.success != 0; + void* ignored = tag; + GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok)); + } + + /// Manage state of avalanching operations : completion queue tags that + /// trigger other completion queue operations. The underlying core completion + /// queue should not really shutdown until all avalanching operations have + /// been finalized. Note that we maintain the requirement that an avalanche + /// registration must take place before CQ shutdown (which must be maintained + /// elsehwere) + void InitialAvalanching() { + gpr_atm_rel_store(&avalanches_in_flight_, static_cast(1)); + } + void RegisterAvalanching() { + gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, + static_cast(1)); + } + void CompleteAvalanching() { + if (gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, + static_cast(-1)) == 1) { + ::grpc::g_core_codegen_interface->grpc_completion_queue_shutdown(cq_); + } + } + + grpc_completion_queue* cq_; // owned + + gpr_atm avalanches_in_flight_; +}; + +/// A specific type of completion queue used by the processing of notifications +/// by servers. Instantiated by \a ServerBuilder. +class ServerCompletionQueue : public CompletionQueue { + public: + bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; } + + protected: + /// Default constructor + ServerCompletionQueue() : polling_type_(GRPC_CQ_DEFAULT_POLLING) {} + + private: + /// \param completion_type indicates whether this is a NEXT or CALLBACK + /// completion queue. + /// \param polling_type Informs the GRPC library about the type of polling + /// allowed on this completion queue. See grpc_cq_polling_type's description + /// in grpc_types.h for more details. + /// \param shutdown_cb is the shutdown callback used for CALLBACK api queues + ServerCompletionQueue(grpc_cq_completion_type completion_type, + grpc_cq_polling_type polling_type, + grpc_experimental_completion_queue_functor* shutdown_cb) + : CompletionQueue(grpc_completion_queue_attributes{ + GRPC_CQ_CURRENT_VERSION, completion_type, polling_type, + shutdown_cb}), + polling_type_(polling_type) {} + + grpc_cq_polling_type polling_type_; + friend class ::grpc::ServerBuilder; + friend class ::grpc::Server; +}; + +} // namespace grpc + +#endif // GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H diff --git a/include/grpcpp/impl/codegen/intercepted_channel.h b/include/grpcpp/impl/codegen/intercepted_channel.h index 5255a6d1472..62cdc518410 100644 --- a/include/grpcpp/impl/codegen/intercepted_channel.h +++ b/include/grpcpp/impl/codegen/intercepted_channel.h @@ -21,6 +21,10 @@ #include +namespace grpc_impl { +class CompletionQueue; +} + namespace grpc { namespace internal { @@ -46,7 +50,7 @@ class InterceptedChannel : public ChannelInterface { : channel_(channel), interceptor_pos_(pos) {} Call CreateCall(const RpcMethod& method, ClientContext* context, - CompletionQueue* cq) override { + ::grpc_impl::CompletionQueue* cq) override { return channel_->CreateCallInternal(method, context, cq, interceptor_pos_); } @@ -58,7 +62,7 @@ class InterceptedChannel : public ChannelInterface { } void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline, CompletionQueue* cq, + gpr_timespec deadline, ::grpc_impl::CompletionQueue* cq, void* tag) override { return channel_->NotifyOnStateChangeImpl(last_observed, deadline, cq, tag); } @@ -67,7 +71,7 @@ class InterceptedChannel : public ChannelInterface { return channel_->WaitForStateChangeImpl(last_observed, deadline); } - CompletionQueue* CallbackCQ() override { return channel_->CallbackCQ(); } + ::grpc_impl::CompletionQueue* CallbackCQ() override { return channel_->CallbackCQ(); } ChannelInterface* channel_; size_t interceptor_pos_; diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index affe61b547b..4c8ab688e33 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -41,6 +41,10 @@ struct grpc_metadata; struct grpc_call; struct census_context; +namespace grpc_impl { +class CompletionQueue; +} + namespace grpc { class ClientContext; template @@ -82,7 +86,6 @@ class Call; class ServerReactor; } // namespace internal -class CompletionQueue; class Server; class ServerInterface; @@ -346,7 +349,7 @@ class ServerContext { gpr_timespec deadline_; grpc_call* call_; - CompletionQueue* cq_; + ::grpc_impl::CompletionQueue* cq_; bool sent_initial_metadata_; mutable std::shared_ptr auth_context_; mutable internal::MetadataMap client_metadata_; diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index b056643269a..18e40ad6d9f 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -30,13 +30,14 @@ namespace grpc_impl { class Channel; +class CompletionQueue; +class ServerCompletionQueue; } namespace grpc { class AsyncGenericService; class GenericServerContext; -class ServerCompletionQueue; class ServerContext; class ServerCredentials; class Service; @@ -138,7 +139,7 @@ class ServerInterface : public internal::CallHook { /// caller is required to keep all completion queues live until the server is /// destroyed. /// \param num_cqs How many completion queues does \a cqs hold. - virtual void Start(ServerCompletionQueue** cqs, size_t num_cqs) = 0; + virtual void Start(::grpc_impl::ServerCompletionQueue** cqs, size_t num_cqs) = 0; virtual void ShutdownInternal(gpr_timespec deadline) = 0; @@ -153,8 +154,8 @@ class ServerInterface : public internal::CallHook { public: BaseAsyncRequest(ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag, bool delete_on_finalize); virtual ~BaseAsyncRequest(); @@ -167,8 +168,8 @@ class ServerInterface : public internal::CallHook { ServerInterface* const server_; ServerContext* const context_; internal::ServerAsyncStreamingInterface* const stream_; - CompletionQueue* const call_cq_; - ServerCompletionQueue* const notification_cq_; + ::grpc_impl::CompletionQueue* const call_cq_; + ::grpc_impl::ServerCompletionQueue* const notification_cq_; void* const tag_; const bool delete_on_finalize_; grpc_call* call_; @@ -182,8 +183,8 @@ class ServerInterface : public internal::CallHook { public: RegisteredAsyncRequest(ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag, const char* name, internal::RpcMethod::RpcType type); virtual bool FinalizeResult(void** tag, bool* status) override { @@ -191,7 +192,7 @@ class ServerInterface : public internal::CallHook { if (done_intercepting_) { return BaseAsyncRequest::FinalizeResult(tag, status); } - call_wrapper_ = internal::Call( + call_wrapper_ = ::grpc::internal::Call( call_, server_, call_cq_, server_->max_receive_message_size(), context_->set_server_rpc_info(name_, type_, *server_->interceptor_creators())); @@ -200,7 +201,7 @@ class ServerInterface : public internal::CallHook { protected: void IssueRequest(void* registered_method, grpc_byte_buffer** payload, - ServerCompletionQueue* notification_cq); + ::grpc_impl::ServerCompletionQueue* notification_cq); const char* name_; const internal::RpcMethod::RpcType type_; }; @@ -210,8 +211,8 @@ class ServerInterface : public internal::CallHook { NoPayloadAsyncRequest(internal::RpcServiceMethod* registered_method, ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) : RegisteredAsyncRequest( server, context, stream, call_cq, notification_cq, tag, registered_method->name(), registered_method->method_type()) { @@ -227,8 +228,8 @@ class ServerInterface : public internal::CallHook { PayloadAsyncRequest(internal::RpcServiceMethod* registered_method, ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag, Message* request) : RegisteredAsyncRequest( server, context, stream, call_cq, notification_cq, tag, @@ -284,9 +285,9 @@ class ServerInterface : public internal::CallHook { ServerInterface* const server_; ServerContext* const context_; internal::ServerAsyncStreamingInterface* const stream_; - CompletionQueue* const call_cq_; + ::grpc_impl::CompletionQueue* const call_cq_; - ServerCompletionQueue* const notification_cq_; + ::grpc_impl::ServerCompletionQueue* const notification_cq_; void* const tag_; Message* const request_; ByteBuffer payload_; @@ -296,8 +297,8 @@ class ServerInterface : public internal::CallHook { public: GenericAsyncRequest(ServerInterface* server, GenericServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag, bool delete_on_finalize); bool FinalizeResult(void** tag, bool* status) override; @@ -310,8 +311,8 @@ class ServerInterface : public internal::CallHook { void RequestAsyncCall(internal::RpcServiceMethod* method, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag, Message* message) { GPR_CODEGEN_ASSERT(method); new PayloadAsyncRequest(method, this, context, stream, call_cq, @@ -321,8 +322,8 @@ class ServerInterface : public internal::CallHook { void RequestAsyncCall(internal::RpcServiceMethod* method, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) { + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { GPR_CODEGEN_ASSERT(method); new NoPayloadAsyncRequest(method, this, context, stream, call_cq, notification_cq, tag); @@ -330,8 +331,8 @@ class ServerInterface : public internal::CallHook { void RequestAsyncGenericCall(GenericServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { new GenericAsyncRequest(this, context, stream, call_cq, notification_cq, tag, true); @@ -357,7 +358,7 @@ class ServerInterface : public internal::CallHook { // Returns nullptr (rather than being pure) since this is a post-1.0 method // and adding a new pure method to an interface would be a breaking change // (even though this is private and non-API) - virtual CompletionQueue* CallbackCQ() { return nullptr; } + virtual ::grpc_impl::CompletionQueue* CallbackCQ() { return nullptr; } }; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/service_type.h b/include/grpcpp/impl/codegen/service_type.h index 332a04c294f..5325b80b0fd 100644 --- a/include/grpcpp/impl/codegen/service_type.h +++ b/include/grpcpp/impl/codegen/service_type.h @@ -28,10 +28,8 @@ namespace grpc { -class CompletionQueue; class Server; class ServerInterface; -class ServerCompletionQueue; class ServerContext; namespace internal { diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 028b8cffaa7..73524c3a7e6 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -35,13 +35,17 @@ struct grpc_resource_quota; +namespace grpc_impl { + +class ServerCompletionQueue; + +} + namespace grpc { class AsyncGenericService; class ResourceQuota; -class CompletionQueue; class Server; -class ServerCompletionQueue; class ServerCredentials; class Service; @@ -123,7 +127,7 @@ class ServerBuilder { /// 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( + std::unique_ptr<::grpc_impl::ServerCompletionQueue> AddCompletionQueue( bool is_frequently_polled = true); ////////////////////////////////////////////////////////////////////////////// @@ -306,7 +310,7 @@ class ServerBuilder { SyncServerSettings sync_server_settings_; /// List of completion queues added via \a AddCompletionQueue method. - std::vector cqs_; + std::vector<::grpc_impl::ServerCompletionQueue*> cqs_; std::shared_ptr creds_; std::vector> plugins_; diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index e98abdd082a..72cd5a2dcbe 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -147,10 +147,10 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, 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 ServerCompletionQueue;\n"); + printer->Print(vars, "} // namespace grpc_impl\n\n"); + printer->Print(vars, "namespace grpc {\n"); printer->Print(vars, "class ServerContext;\n"); printer->Print(vars, "} // namespace grpc\n\n"); diff --git a/src/cpp/common/completion_queue_cc.cc b/src/cpp/common/completion_queue_cc.cc index 4bb3bcbd8b6..d1d0f8ab23c 100644 --- a/src/cpp/common/completion_queue_cc.cc +++ b/src/cpp/common/completion_queue_cc.cc @@ -24,9 +24,9 @@ #include #include -namespace grpc { +namespace grpc_impl { -static internal::GrpcLibraryInitializer g_gli_initializer; +static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer; // 'CompletionQueue' constructor can safely call GrpcLibraryCodegen(false) here // i.e not have GrpcLibraryCodegen call grpc_init(). This is because, to create @@ -52,7 +52,7 @@ CompletionQueue::NextStatus CompletionQueue::AsyncNextInternal( case GRPC_QUEUE_SHUTDOWN: return SHUTDOWN; case GRPC_OP_COMPLETE: - auto core_cq_tag = static_cast(ev.tag); + auto core_cq_tag = static_cast<::grpc::internal::CompletionQueueTag*>(ev.tag); *ok = ev.success != 0; *tag = core_cq_tag; if (core_cq_tag->FinalizeResult(tag, ok)) { @@ -79,7 +79,7 @@ bool CompletionQueue::CompletionQueueTLSCache::Flush(void** tag, bool* ok) { flushed_ = true; if (grpc_completion_queue_thread_local_cache_flush(cq_->cq_, &res_tag, &res)) { - auto core_cq_tag = static_cast(res_tag); + auto core_cq_tag = static_cast<::grpc::internal::CompletionQueueTag*>(res_tag); *ok = res == 1; if (core_cq_tag->FinalizeResult(tag, ok)) { return true; From 5847c3a87a7fd85da1ed9326c4fc5f4c56518ec7 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 14 Feb 2019 20:05:59 +0100 Subject: [PATCH 1110/2143] Reformat. --- include/grpcpp/channel_impl.h | 4 +- .../grpcpp/impl/codegen/channel_interface.h | 3 +- include/grpcpp/impl/codegen/client_context.h | 1 - .../grpcpp/impl/codegen/completion_queue.h | 2 +- .../impl/codegen/completion_queue_impl.h | 8 ++-- .../grpcpp/impl/codegen/intercepted_channel.h | 7 +++- .../grpcpp/impl/codegen/server_interface.h | 42 ++++++++++--------- include/grpcpp/server_builder.h | 1 - src/cpp/common/completion_queue_cc.cc | 8 ++-- 9 files changed, 43 insertions(+), 33 deletions(-) diff --git a/include/grpcpp/channel_impl.h b/include/grpcpp/channel_impl.h index 9ce41d92790..c6adf7a9605 100644 --- a/include/grpcpp/channel_impl.h +++ b/include/grpcpp/channel_impl.h @@ -84,8 +84,8 @@ class Channel final : public ::grpc::ChannelInterface, void* RegisterMethod(const char* method) override; void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline, - CompletionQueue* cq, void* tag) override; + gpr_timespec deadline, CompletionQueue* cq, + void* tag) override; bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) override; diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h index 17a18efaf7b..faa5e41cef9 100644 --- a/include/grpcpp/impl/codegen/channel_interface.h +++ b/include/grpcpp/impl/codegen/channel_interface.h @@ -134,7 +134,8 @@ class ChannelInterface { virtual void* RegisterMethod(const char* method) = 0; virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline, - ::grpc_impl::CompletionQueue* cq, void* tag) = 0; + ::grpc_impl::CompletionQueue* cq, + void* tag) = 0; virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) = 0; diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index c291c7adfd3..6d1d03ec1f8 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 { diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 00f773acf48..edd1c2e97c8 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -39,6 +39,6 @@ namespace grpc { typedef ::grpc_impl::CompletionQueue CompletionQueue; typedef ::grpc_impl::ServerCompletionQueue ServerCompletionQueue; -} +} // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H diff --git a/include/grpcpp/impl/codegen/completion_queue_impl.h b/include/grpcpp/impl/codegen/completion_queue_impl.h index b87a1e62158..df2d01b3394 100644 --- a/include/grpcpp/impl/codegen/completion_queue_impl.h +++ b/include/grpcpp/impl/codegen/completion_queue_impl.h @@ -330,7 +330,8 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen { /// timeout. i.e: /// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME)) void TryPluck(::grpc::internal::CompletionQueueTag* tag) { - auto deadline = ::grpc::g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME); + auto deadline = + ::grpc::g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME); auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck( cq_, tag, deadline, nullptr); if (ev.type == GRPC_QUEUE_TIMEOUT) return; @@ -345,7 +346,8 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen { /// /// This exects tag->FinalizeResult (if called) to return 'false' i.e expects /// that the tag is internal not something that is returned to the user. - void TryPluck(::grpc::internal::CompletionQueueTag* tag, gpr_timespec deadline) { + void TryPluck(::grpc::internal::CompletionQueueTag* tag, + gpr_timespec deadline) { auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck( cq_, tag, deadline, nullptr); if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) { @@ -412,6 +414,6 @@ class ServerCompletionQueue : public CompletionQueue { friend class ::grpc::Server; }; -} // namespace grpc +} // namespace grpc_impl #endif // GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H diff --git a/include/grpcpp/impl/codegen/intercepted_channel.h b/include/grpcpp/impl/codegen/intercepted_channel.h index 62cdc518410..cd0fcc06753 100644 --- a/include/grpcpp/impl/codegen/intercepted_channel.h +++ b/include/grpcpp/impl/codegen/intercepted_channel.h @@ -62,7 +62,8 @@ class InterceptedChannel : public ChannelInterface { } void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline, ::grpc_impl::CompletionQueue* cq, + gpr_timespec deadline, + ::grpc_impl::CompletionQueue* cq, void* tag) override { return channel_->NotifyOnStateChangeImpl(last_observed, deadline, cq, tag); } @@ -71,7 +72,9 @@ class InterceptedChannel : public ChannelInterface { return channel_->WaitForStateChangeImpl(last_observed, deadline); } - ::grpc_impl::CompletionQueue* CallbackCQ() override { return channel_->CallbackCQ(); } + ::grpc_impl::CompletionQueue* CallbackCQ() override { + return channel_->CallbackCQ(); + } ChannelInterface* channel_; size_t interceptor_pos_; diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index 18e40ad6d9f..c3b8f8b3f3d 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -32,7 +32,7 @@ namespace grpc_impl { class Channel; class CompletionQueue; class ServerCompletionQueue; -} +} // namespace grpc_impl namespace grpc { @@ -139,7 +139,8 @@ class ServerInterface : public internal::CallHook { /// caller is required to keep all completion queues live until the server is /// destroyed. /// \param num_cqs How many completion queues does \a cqs hold. - virtual void Start(::grpc_impl::ServerCompletionQueue** cqs, size_t num_cqs) = 0; + virtual void Start(::grpc_impl::ServerCompletionQueue** cqs, + size_t num_cqs) = 0; virtual void ShutdownInternal(gpr_timespec deadline) = 0; @@ -155,8 +156,8 @@ class ServerInterface : public internal::CallHook { BaseAsyncRequest(ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, ::grpc_impl::CompletionQueue* call_cq, - ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag, - bool delete_on_finalize); + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, bool delete_on_finalize); virtual ~BaseAsyncRequest(); bool FinalizeResult(void** tag, bool* status) override; @@ -184,8 +185,9 @@ class ServerInterface : public internal::CallHook { RegisteredAsyncRequest(ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, ::grpc_impl::CompletionQueue* call_cq, - ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag, - const char* name, internal::RpcMethod::RpcType type); + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, const char* name, + internal::RpcMethod::RpcType type); virtual bool FinalizeResult(void** tag, bool* status) override { /* If we are done intercepting, then there is nothing more for us to do */ @@ -212,7 +214,8 @@ class ServerInterface : public internal::CallHook { ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, ::grpc_impl::CompletionQueue* call_cq, - ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag) : RegisteredAsyncRequest( server, context, stream, call_cq, notification_cq, tag, registered_method->name(), registered_method->method_type()) { @@ -229,8 +232,8 @@ class ServerInterface : public internal::CallHook { ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, ::grpc_impl::CompletionQueue* call_cq, - ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag, - Message* request) + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, Message* request) : RegisteredAsyncRequest( server, context, stream, call_cq, notification_cq, tag, registered_method->name(), registered_method->method_type()), @@ -298,8 +301,8 @@ class ServerInterface : public internal::CallHook { GenericAsyncRequest(ServerInterface* server, GenericServerContext* context, internal::ServerAsyncStreamingInterface* stream, ::grpc_impl::CompletionQueue* call_cq, - ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag, - bool delete_on_finalize); + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, bool delete_on_finalize); bool FinalizeResult(void** tag, bool* status) override; @@ -312,8 +315,8 @@ class ServerInterface : public internal::CallHook { ServerContext* context, internal::ServerAsyncStreamingInterface* stream, ::grpc_impl::CompletionQueue* call_cq, - ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag, - Message* message) { + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, Message* message) { GPR_CODEGEN_ASSERT(method); new PayloadAsyncRequest(method, this, context, stream, call_cq, notification_cq, tag, message); @@ -323,17 +326,18 @@ class ServerInterface : public internal::CallHook { ServerContext* context, internal::ServerAsyncStreamingInterface* stream, ::grpc_impl::CompletionQueue* call_cq, - ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag) { GPR_CODEGEN_ASSERT(method); new NoPayloadAsyncRequest(method, this, context, stream, call_cq, notification_cq, tag); } - void RequestAsyncGenericCall(GenericServerContext* context, - internal::ServerAsyncStreamingInterface* stream, - ::grpc_impl::CompletionQueue* call_cq, - ::grpc_impl::ServerCompletionQueue* notification_cq, - void* tag) { + void RequestAsyncGenericCall( + GenericServerContext* context, + internal::ServerAsyncStreamingInterface* stream, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { new GenericAsyncRequest(this, context, stream, call_cq, notification_cq, tag, true); } diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 73524c3a7e6..ae37ce55fbd 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -38,7 +38,6 @@ struct grpc_resource_quota; namespace grpc_impl { class ServerCompletionQueue; - } namespace grpc { diff --git a/src/cpp/common/completion_queue_cc.cc b/src/cpp/common/completion_queue_cc.cc index d1d0f8ab23c..43c2eee96f8 100644 --- a/src/cpp/common/completion_queue_cc.cc +++ b/src/cpp/common/completion_queue_cc.cc @@ -52,7 +52,8 @@ CompletionQueue::NextStatus CompletionQueue::AsyncNextInternal( case GRPC_QUEUE_SHUTDOWN: return SHUTDOWN; case GRPC_OP_COMPLETE: - auto core_cq_tag = static_cast<::grpc::internal::CompletionQueueTag*>(ev.tag); + auto core_cq_tag = + static_cast<::grpc::internal::CompletionQueueTag*>(ev.tag); *ok = ev.success != 0; *tag = core_cq_tag; if (core_cq_tag->FinalizeResult(tag, ok)) { @@ -79,7 +80,8 @@ bool CompletionQueue::CompletionQueueTLSCache::Flush(void** tag, bool* ok) { flushed_ = true; if (grpc_completion_queue_thread_local_cache_flush(cq_->cq_, &res_tag, &res)) { - auto core_cq_tag = static_cast<::grpc::internal::CompletionQueueTag*>(res_tag); + auto core_cq_tag = + static_cast<::grpc::internal::CompletionQueueTag*>(res_tag); *ok = res == 1; if (core_cq_tag->FinalizeResult(tag, ok)) { return true; @@ -88,4 +90,4 @@ bool CompletionQueue::CompletionQueueTLSCache::Flush(void** tag, bool* ok) { return false; } -} // namespace grpc +} // namespace grpc_impl From 7eb4fee9125c65abe77e82f498925abd8706399d Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 14 Feb 2019 20:07:21 +0100 Subject: [PATCH 1111/2143] Regenerate golden file. --- test/cpp/codegen/compiler_test_golden | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index de71dcd5cb1..881bae3d6dc 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -42,11 +42,11 @@ namespace grpc_impl { class Channel; +class CompletionQueue; +class ServerCompletionQueue; } // namespace grpc_impl namespace grpc { -class CompletionQueue; -class ServerCompletionQueue; class ServerContext; } // namespace grpc From 5428bdeb8388abc5a9601a298c20924730cd245f Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 14 Feb 2019 11:09:55 -0800 Subject: [PATCH 1112/2143] 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 035442b0863984bc0a77599b326fea8a00975d5f Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 14 Feb 2019 21:40:31 +0100 Subject: [PATCH 1113/2143] Fixing header guard. --- include/grpcpp/impl/codegen/completion_queue_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/completion_queue_impl.h b/include/grpcpp/impl/codegen/completion_queue_impl.h index df2d01b3394..0a4b2100454 100644 --- a/include/grpcpp/impl/codegen/completion_queue_impl.h +++ b/include/grpcpp/impl/codegen/completion_queue_impl.h @@ -416,4 +416,4 @@ class ServerCompletionQueue : public CompletionQueue { } // namespace grpc_impl -#endif // GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H +#endif // GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H From ad1a34f9046199018b8edf755cc71f7f6deb81fc Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 14 Feb 2019 21:55:20 +0100 Subject: [PATCH 1114/2143] Adding new header to build files. --- BUILD | 1 + CMakeLists.txt | 5 +++++ Makefile | 5 +++++ 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, 17 insertions(+) diff --git a/BUILD b/BUILD index 7986c156ed2..a2e133f8d7d 100644 --- a/BUILD +++ b/BUILD @@ -2122,6 +2122,7 @@ grpc_cc_library( "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_impl.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", "include/grpcpp/impl/codegen/config.h", "include/grpcpp/impl/codegen/core_codegen_interface.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 41f6ad0ee6d..92735b6c9a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3138,6 +3138,7 @@ foreach(_hdr 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_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h @@ -3730,6 +3731,7 @@ foreach(_hdr 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_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h @@ -4153,6 +4155,7 @@ foreach(_hdr 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_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h @@ -4348,6 +4351,7 @@ foreach(_hdr 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_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h @@ -4686,6 +4690,7 @@ foreach(_hdr 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_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h diff --git a/Makefile b/Makefile index 721ef768003..ac04814fd74 100644 --- a/Makefile +++ b/Makefile @@ -5544,6 +5544,7 @@ PUBLIC_HEADERS_CXX += \ 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_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ @@ -6145,6 +6146,7 @@ PUBLIC_HEADERS_CXX += \ 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_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ @@ -6547,6 +6549,7 @@ PUBLIC_HEADERS_CXX += \ 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_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ @@ -6714,6 +6717,7 @@ PUBLIC_HEADERS_CXX += \ 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_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ @@ -7058,6 +7062,7 @@ PUBLIC_HEADERS_CXX += \ 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_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ diff --git a/build.yaml b/build.yaml index 3b0f3e11b2a..4c56cabf03e 100644 --- a/build.yaml +++ b/build.yaml @@ -1246,6 +1246,7 @@ filegroups: - 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_impl.h - include/grpcpp/impl/codegen/completion_queue_tag.h - include/grpcpp/impl/codegen/config.h - include/grpcpp/impl/codegen/core_codegen_interface.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index fd5edbe744e..d98b80556c5 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -148,6 +148,7 @@ Pod::Spec.new do |s| '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_impl.h', 'include/grpcpp/impl/codegen/completion_queue_tag.h', 'include/grpcpp/impl/codegen/config.h', 'include/grpcpp/impl/codegen/core_codegen_interface.h', diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index cbc601921e1..27a3b6e168a 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -955,6 +955,7 @@ 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_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/config_protobuf.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index a20e2a8d9bf..33f9e4f42da 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -956,6 +956,7 @@ 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_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/config_protobuf.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8f87daad295..79645366729 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11164,6 +11164,7 @@ "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_impl.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", "include/grpcpp/impl/codegen/config.h", "include/grpcpp/impl/codegen/core_codegen_interface.h", @@ -11240,6 +11241,7 @@ "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_impl.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", "include/grpcpp/impl/codegen/config.h", "include/grpcpp/impl/codegen/core_codegen_interface.h", From 4d0b1236092eb1e2484b771420eae79ef380904e Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 14 Feb 2019 13:52:43 -0800 Subject: [PATCH 1115/2143] 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 1116/2143] 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 1117/2143] 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 1118/2143] 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 1119/2143] 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 1120/2143] 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 1121/2143] 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 1122/2143] 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 1123/2143] 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 1124/2143] 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 1125/2143] 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 1126/2143] 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 1127/2143] 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 1128/2143] 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 1129/2143] 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 1130/2143] 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 1131/2143] 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 1132/2143] 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 1133/2143] 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 1134/2143] 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 1135/2143] 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 1136/2143] 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 1137/2143] 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 1138/2143] 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 1139/2143] 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 1140/2143] 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 1141/2143] 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 1142/2143] 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 1143/2143] 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 1144/2143] 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 1145/2143] 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 1146/2143] 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 1147/2143] 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 1148/2143] 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 1149/2143] 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 1150/2143] 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 1151/2143] 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 1152/2143] 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 1153/2143] 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 1154/2143] 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 1155/2143] 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 1156/2143] "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 2fd2ee2289f2c0b1bdc66687d7d98124c405b8b9 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 18 Feb 2019 14:09:27 +0100 Subject: [PATCH 1157/2143] test C# on .NET core by default too --- tools/run_tests/run_tests_matrix.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index d93add00cd2..785dff36eab 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -197,6 +197,7 @@ def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS): inner_jobs=inner_jobs, timeout_seconds=_CPP_RUNTESTS_TIMEOUT) + # C# tests on .NET desktop/mono test_jobs += _generate_jobs( languages=['csharp'], configs=['dbg', 'opt'], @@ -204,6 +205,16 @@ def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS): labels=['basictests', 'multilang'], extra_args=extra_args, inner_jobs=inner_jobs) + # C# tests on .NET core + test_jobs += _generate_jobs( + languages=['csharp'], + configs=['dbg', 'opt'], + platforms=['linux', 'macos', 'windows'], + arch='default', + compiler='coreclr', + labels=['basictests', 'multilang'], + extra_args=extra_args, + inner_jobs=inner_jobs) test_jobs += _generate_jobs( languages=['python'], @@ -392,16 +403,6 @@ def _create_portability_test_jobs(extra_args=[], extra_args=extra_args, inner_jobs=inner_jobs) - test_jobs += _generate_jobs( - languages=['csharp'], - configs=['dbg'], - platforms=['linux'], - arch='default', - compiler='coreclr', - labels=['portability', 'multilang'], - extra_args=extra_args, - inner_jobs=inner_jobs) - test_jobs += _generate_jobs( languages=['c'], configs=['dbg'], From 0f794e1e3c9f629a0bc7309eca5480469eaac98c Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Sat, 16 Feb 2019 03:54:46 +0000 Subject: [PATCH 1158/2143] 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 1159/2143] 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 1160/2143] 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 1161/2143] 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 1162/2143] 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 1163/2143] 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 1164/2143] 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 1165/2143] 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 1166/2143] 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 1167/2143] 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 1168/2143] 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 1169/2143] 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 1170/2143] 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 1171/2143] 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 1172/2143] 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 1173/2143] 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 1174/2143] 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 1175/2143] 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 1176/2143] 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 1177/2143] 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 1178/2143] 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 1179/2143] 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 1180/2143] 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 1181/2143] 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 1182/2143] 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 1183/2143] 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 1184/2143] 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 1185/2143] 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 1186/2143] 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 1187/2143] 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 1188/2143] 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 1189/2143] 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 1190/2143] 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 1191/2143] 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 1192/2143] 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 1193/2143] 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 1194/2143] 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 1195/2143] 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 1196/2143] 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 1197/2143] 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 1198/2143] 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 1199/2143] 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 1200/2143] 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 1201/2143] 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 1202/2143] 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 1203/2143] 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 76e9d1add7555378c204eb0475e9b4ac1c8f2816 Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Thu, 21 Feb 2019 19:20:34 +0300 Subject: [PATCH 1204/2143] Set WSA_FLAG_NO_HANDLE_INHERIT flag wherever the WSASocket is used. Check WSA_FLAG_NO_HANDLE_INHERIT is supported. --- .../dns/c_ares/grpc_ares_ev_driver_windows.cc | 2 +- src/core/lib/iomgr/endpoint_pair_windows.cc | 8 +++---- src/core/lib/iomgr/socket_windows.cc | 21 +++++++++++++++++++ src/core/lib/iomgr/socket_windows.h | 9 ++++++++ src/core/lib/iomgr/tcp_client_windows.cc | 4 ++-- src/core/lib/iomgr/tcp_server_windows.cc | 4 ++-- test/cpp/naming/resolver_component_test.cc | 4 ++-- 7 files changed, 41 insertions(+), 11 deletions(-) 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..dedc77aae97 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 @@ -442,7 +442,7 @@ class SockToPolledFdMap { */ static ares_socket_t Socket(int af, int type, int protocol, void* user_data) { SockToPolledFdMap* map = static_cast(user_data); - SOCKET s = WSASocket(af, type, protocol, nullptr, 0, WSA_FLAG_OVERLAPPED); + SOCKET s = grpc_create_wsa_socket(af, type, protocol, nullptr, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (s == INVALID_SOCKET) { return s; } diff --git a/src/core/lib/iomgr/endpoint_pair_windows.cc b/src/core/lib/iomgr/endpoint_pair_windows.cc index 177331d6812..842a4ff877b 100644 --- a/src/core/lib/iomgr/endpoint_pair_windows.cc +++ b/src/core/lib/iomgr/endpoint_pair_windows.cc @@ -40,8 +40,8 @@ static void create_sockets(SOCKET sv[2]) { SOCKADDR_IN addr; int addr_len = sizeof(addr); - lst_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + lst_sock = grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); GPR_ASSERT(lst_sock != INVALID_SOCKET); memset(&addr, 0, sizeof(addr)); @@ -53,8 +53,8 @@ static void create_sockets(SOCKET sv[2]) { GPR_ASSERT(getsockname(lst_sock, (grpc_sockaddr*)&addr, &addr_len) != SOCKET_ERROR); - cli_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + cli_sock = grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); GPR_ASSERT(cli_sock != INVALID_SOCKET); GPR_ASSERT(WSAConnect(cli_sock, (grpc_sockaddr*)&addr, addr_len, NULL, NULL, diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 999c6646ad4..19013c76b3e 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -181,4 +181,25 @@ int grpc_ipv6_loopback_available(void) { return g_ipv6_loopback_available; } +SOCKET grpc_create_wsa_socket(int family, + int type, + int protocol, + LPWSAPROTOCOL_INFOA protocol_info, + GROUP group, + DWORD flags) { + bool is_wsa_no_handle_inherit_set = flags & WSA_FLAG_NO_HANDLE_INHERIT; + if (!g_is_wsa_no_handle_inherit_supported && is_wsa_no_handle_inherit_set) { + flags ^= WSA_FLAG_NO_HANDLE_INHERIT; + } + SOCKET sock = WSASocket(family, type, protocol, protocol_info, group, flags); + /* WSA_FLAG_NO_HANDLE_INHERIT may be not supported on the older Windows versions, see + https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx + for details. */ + if (sock == INVALID_SOCKET && is_wsa_no_handle_inherit_set) { + g_is_wsa_no_handle_inherit_supported = false; + sock = WSASocket(family, type, protocol, protocol_info, group, flags ^ WSA_FLAG_NO_HANDLE_INHERIT); + } + return sock; +} + #endif /* GRPC_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 46d7d583560..0eb8a2271f5 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -114,6 +114,15 @@ void grpc_socket_become_ready(grpc_winsocket* winsocket, The value is probed once, and cached for the life of the process. */ int grpc_ipv6_loopback_available(void); +static bool g_is_wsa_no_handle_inherit_supported = true; + +SOCKET grpc_create_wsa_socket(int family, + int type, + int protocol, + LPWSAPROTOCOL_INFOA protocol_info, + GROUP group, + DWORD flags); + #endif #endif /* GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H */ diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc index e5b5502597e..881f7670610 100644 --- a/src/core/lib/iomgr/tcp_client_windows.cc +++ b/src/core/lib/iomgr/tcp_client_windows.cc @@ -147,8 +147,8 @@ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint, addr = &addr6_v4mapped; } - sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + sock = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc index 67e4f33d44d..9c398ebc8a5 100644 --- a/src/core/lib/iomgr/tcp_server_windows.cc +++ b/src/core/lib/iomgr/tcp_server_windows.cc @@ -254,7 +254,7 @@ static grpc_error* start_accept_locked(grpc_tcp_listener* port) { return GRPC_ERROR_NONE; } - sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + sock = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); @@ -492,7 +492,7 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s, addr = &wildcard; } - sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + sock = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 9532529e45d..072504f4e38 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -279,8 +279,8 @@ void OpenAndCloseSocketsStressLoop(int dummy_port, gpr_event* done_ev) { } std::vector sockets; for (size_t i = 0; i < 50; i++) { - SOCKET s = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0, - WSA_FLAG_OVERLAPPED); + SOCKET s = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); ASSERT_TRUE(s != BAD_SOCKET_RETURN_VAL) << "Failed to create TCP ipv6 socket"; gpr_log(GPR_DEBUG, "Opened socket: %d", s); From 39f562e2b78c4b0dfc68f4f7aadafcc0d20b76dd Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Thu, 21 Feb 2019 19:27:09 +0300 Subject: [PATCH 1205/2143] Define WSA_FLAG_NO_HANDLE_INHERIT if it's not defined --- src/core/lib/iomgr/socket_windows.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 0eb8a2271f5..25b347d1efa 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -32,6 +32,10 @@ #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/iomgr_internal.h" +#ifndef WSA_FLAG_NO_HANDLE_INHERIT +#define WSA_FLAG_NO_HANDLE_INHERIT 0x80 +#endif + /* This holds the data for an outstanding read or write on a socket. The mutex to protect the concurrent access to that data is the one inside the winsocket wrapper. */ From b74044a67d2e4f911cc68395eeadf1c5f6b013fc Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Thu, 21 Feb 2019 19:47:38 +0300 Subject: [PATCH 1206/2143] Use LPWSAPROTOCOL_INFO instead of LPWSAPROTOCOL_INFOA --- src/core/lib/iomgr/socket_windows.cc | 2 +- src/core/lib/iomgr/socket_windows.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 19013c76b3e..7b0f43bb170 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -184,7 +184,7 @@ int grpc_ipv6_loopback_available(void) { SOCKET grpc_create_wsa_socket(int family, int type, int protocol, - LPWSAPROTOCOL_INFOA protocol_info, + LPWSAPROTOCOL_INFO protocol_info, GROUP group, DWORD flags) { bool is_wsa_no_handle_inherit_set = flags & WSA_FLAG_NO_HANDLE_INHERIT; diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 25b347d1efa..987325eef71 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -123,7 +123,7 @@ static bool g_is_wsa_no_handle_inherit_supported = true; SOCKET grpc_create_wsa_socket(int family, int type, int protocol, - LPWSAPROTOCOL_INFOA protocol_info, + LPWSAPROTOCOL_INFO protocol_info, GROUP group, DWORD flags); From 330e0f3ba8770ffceb1b7e7d34d7cd7b6896c913 Mon Sep 17 00:00:00 2001 From: Tony Allevato Date: Thu, 21 Feb 2019 09:52:17 -0800 Subject: [PATCH 1207/2143] 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 1208/2143] 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 1209/2143] 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 1210/2143] 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 1211/2143] 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 1212/2143] 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 1213/2143] 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 1214/2143] 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 1215/2143] 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 1216/2143] 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 1217/2143] 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 1218/2143] 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 1219/2143] 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 1220/2143] 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 1221/2143] 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 1222/2143] 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 1223/2143] 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 1224/2143] 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 1225/2143] 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 1226/2143] 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 1227/2143] 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 1228/2143] 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 1229/2143] 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 1230/2143] 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 1231/2143] 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 1232/2143] 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 1233/2143] 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 1234/2143] 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 1235/2143] 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 1236/2143] 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 1237/2143] 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 bc7203e37156410b8cf2341013a36fc3f33c5ee7 Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Mon, 25 Feb 2019 12:19:41 +0300 Subject: [PATCH 1238/2143] Fixed style --- .../dns/c_ares/grpc_ares_ev_driver_windows.cc | 4 +++- src/core/lib/iomgr/endpoint_pair_windows.cc | 10 ++++++---- src/core/lib/iomgr/socket_windows.cc | 13 ++++++------- src/core/lib/iomgr/socket_windows.h | 7 ++----- src/core/lib/iomgr/tcp_client_windows.cc | 5 +++-- src/core/lib/iomgr/tcp_server_windows.cc | 10 ++++++---- test/cpp/naming/resolver_component_test.cc | 5 +++-- 7 files changed, 29 insertions(+), 25 deletions(-) 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 dedc77aae97..5d77fb761f3 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 @@ -442,7 +442,9 @@ class SockToPolledFdMap { */ static ares_socket_t Socket(int af, int type, int protocol, void* user_data) { SockToPolledFdMap* map = static_cast(user_data); - SOCKET s = grpc_create_wsa_socket(af, type, protocol, nullptr, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + SOCKET s = grpc_create_wsa_socket( + af, type, protocol, nullptr, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (s == INVALID_SOCKET) { return s; } diff --git a/src/core/lib/iomgr/endpoint_pair_windows.cc b/src/core/lib/iomgr/endpoint_pair_windows.cc index 842a4ff877b..b914e1c6660 100644 --- a/src/core/lib/iomgr/endpoint_pair_windows.cc +++ b/src/core/lib/iomgr/endpoint_pair_windows.cc @@ -40,8 +40,9 @@ static void create_sockets(SOCKET sv[2]) { SOCKADDR_IN addr; int addr_len = sizeof(addr); - lst_sock = grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + lst_sock = + grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); GPR_ASSERT(lst_sock != INVALID_SOCKET); memset(&addr, 0, sizeof(addr)); @@ -53,8 +54,9 @@ static void create_sockets(SOCKET sv[2]) { GPR_ASSERT(getsockname(lst_sock, (grpc_sockaddr*)&addr, &addr_len) != SOCKET_ERROR); - cli_sock = grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + cli_sock = + grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); GPR_ASSERT(cli_sock != INVALID_SOCKET); GPR_ASSERT(WSAConnect(cli_sock, (grpc_sockaddr*)&addr, addr_len, NULL, NULL, diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 7b0f43bb170..f55fe674f15 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -181,23 +181,22 @@ int grpc_ipv6_loopback_available(void) { return g_ipv6_loopback_available; } -SOCKET grpc_create_wsa_socket(int family, - int type, - int protocol, - LPWSAPROTOCOL_INFO protocol_info, - GROUP group, +SOCKET grpc_create_wsa_socket(int family, int type, int protocol, + LPWSAPROTOCOL_INFO protocol_info, GROUP group, DWORD flags) { bool is_wsa_no_handle_inherit_set = flags & WSA_FLAG_NO_HANDLE_INHERIT; if (!g_is_wsa_no_handle_inherit_supported && is_wsa_no_handle_inherit_set) { flags ^= WSA_FLAG_NO_HANDLE_INHERIT; } SOCKET sock = WSASocket(family, type, protocol, protocol_info, group, flags); - /* WSA_FLAG_NO_HANDLE_INHERIT may be not supported on the older Windows versions, see + /* WSA_FLAG_NO_HANDLE_INHERIT may be not supported on the older Windows + versions, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx for details. */ if (sock == INVALID_SOCKET && is_wsa_no_handle_inherit_set) { g_is_wsa_no_handle_inherit_supported = false; - sock = WSASocket(family, type, protocol, protocol_info, group, flags ^ WSA_FLAG_NO_HANDLE_INHERIT); + sock = WSASocket(family, type, protocol, protocol_info, group, + flags ^ WSA_FLAG_NO_HANDLE_INHERIT); } return sock; } diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 987325eef71..79c5c8fbee3 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -120,11 +120,8 @@ int grpc_ipv6_loopback_available(void); static bool g_is_wsa_no_handle_inherit_supported = true; -SOCKET grpc_create_wsa_socket(int family, - int type, - int protocol, - LPWSAPROTOCOL_INFO protocol_info, - GROUP group, +SOCKET grpc_create_wsa_socket(int family, int type, int protocol, + LPWSAPROTOCOL_INFO protocol_info, GROUP group, DWORD flags); #endif diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc index 881f7670610..5b15ee2c4e6 100644 --- a/src/core/lib/iomgr/tcp_client_windows.cc +++ b/src/core/lib/iomgr/tcp_client_windows.cc @@ -147,8 +147,9 @@ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint, addr = &addr6_v4mapped; } - sock = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + sock = + grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc index 9c398ebc8a5..db4bb84092b 100644 --- a/src/core/lib/iomgr/tcp_server_windows.cc +++ b/src/core/lib/iomgr/tcp_server_windows.cc @@ -254,8 +254,9 @@ static grpc_error* start_accept_locked(grpc_tcp_listener* port) { return GRPC_ERROR_NONE; } - sock = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + sock = + grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; @@ -492,8 +493,9 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s, addr = &wildcard; } - sock = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + sock = + grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto done; diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 072504f4e38..43a9a066266 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -279,8 +279,9 @@ void OpenAndCloseSocketsStressLoop(int dummy_port, gpr_event* done_ev) { } std::vector sockets; for (size_t i = 0; i < 50; i++) { - SOCKET s = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + SOCKET s = grpc_create_wsa_socket( + AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); ASSERT_TRUE(s != BAD_SOCKET_RETURN_VAL) << "Failed to create TCP ipv6 socket"; gpr_log(GPR_DEBUG, "Opened socket: %d", s); From 60f060e0785ede3a292bf740de9594e3b4edb30f Mon Sep 17 00:00:00 2001 From: Michael Behr Date: Thu, 14 Feb 2019 16:51:04 -0500 Subject: [PATCH 1239/2143] 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 1240/2143] 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 1241/2143] 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 1242/2143] 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 1243/2143] 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 1244/2143] 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 1245/2143] 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 1246/2143] 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 1247/2143] 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 1248/2143] 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 1249/2143] 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 1250/2143] 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 1251/2143] 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 1252/2143] 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 1253/2143] 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 1254/2143] 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 1255/2143] 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 1256/2143] 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 1257/2143] 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 1258/2143] 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 1259/2143] 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 1260/2143] 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 0b96d0f71103023b15940893c3f249f36f2d9595 Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Tue, 26 Feb 2019 12:13:18 +0300 Subject: [PATCH 1261/2143] Check once that WSA_FLAG_NO_HANDLE_INHERIT is supported --- .../dns/c_ares/grpc_ares_ev_driver_windows.cc | 4 +--- src/core/lib/iomgr/endpoint_pair_windows.cc | 10 ++++----- src/core/lib/iomgr/iomgr_windows.cc | 1 + src/core/lib/iomgr/socket_windows.cc | 21 +++++++------------ src/core/lib/iomgr/socket_windows.h | 6 ++---- src/core/lib/iomgr/tcp_client_windows.cc | 5 ++--- src/core/lib/iomgr/tcp_server_windows.cc | 10 ++++----- 7 files changed, 22 insertions(+), 35 deletions(-) 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 5d77fb761f3..5cd988ec1d7 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 @@ -442,9 +442,7 @@ class SockToPolledFdMap { */ static ares_socket_t Socket(int af, int type, int protocol, void* user_data) { SockToPolledFdMap* map = static_cast(user_data); - SOCKET s = grpc_create_wsa_socket( - af, type, protocol, nullptr, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + SOCKET s = WSASocket(af, type, protocol, nullptr, 0, grpc_wsa_socket_flags); if (s == INVALID_SOCKET) { return s; } diff --git a/src/core/lib/iomgr/endpoint_pair_windows.cc b/src/core/lib/iomgr/endpoint_pair_windows.cc index b914e1c6660..ee6a617f61f 100644 --- a/src/core/lib/iomgr/endpoint_pair_windows.cc +++ b/src/core/lib/iomgr/endpoint_pair_windows.cc @@ -40,9 +40,8 @@ static void create_sockets(SOCKET sv[2]) { SOCKADDR_IN addr; int addr_len = sizeof(addr); - lst_sock = - grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + lst_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + grpc_wsa_socket_flags); GPR_ASSERT(lst_sock != INVALID_SOCKET); memset(&addr, 0, sizeof(addr)); @@ -54,9 +53,8 @@ static void create_sockets(SOCKET sv[2]) { GPR_ASSERT(getsockname(lst_sock, (grpc_sockaddr*)&addr, &addr_len) != SOCKET_ERROR); - cli_sock = - grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + cli_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + grpc_wsa_socket_flags); GPR_ASSERT(cli_sock != INVALID_SOCKET); GPR_ASSERT(WSAConnect(cli_sock, (grpc_sockaddr*)&addr, addr_len, NULL, NULL, diff --git a/src/core/lib/iomgr/iomgr_windows.cc b/src/core/lib/iomgr/iomgr_windows.cc index e517a6caee4..0e897dafb16 100644 --- a/src/core/lib/iomgr/iomgr_windows.cc +++ b/src/core/lib/iomgr/iomgr_windows.cc @@ -61,6 +61,7 @@ static void iomgr_platform_init(void) { winsock_init(); grpc_iocp_init(); grpc_pollset_global_init(); + grpc_wsa_socket_flags_init(); } static void iomgr_platform_flush(void) { grpc_iocp_flush(); } diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index f55fe674f15..9e5c579c60d 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -181,24 +181,19 @@ int grpc_ipv6_loopback_available(void) { return g_ipv6_loopback_available; } -SOCKET grpc_create_wsa_socket(int family, int type, int protocol, - LPWSAPROTOCOL_INFO protocol_info, GROUP group, - DWORD flags) { - bool is_wsa_no_handle_inherit_set = flags & WSA_FLAG_NO_HANDLE_INHERIT; - if (!g_is_wsa_no_handle_inherit_supported && is_wsa_no_handle_inherit_set) { - flags ^= WSA_FLAG_NO_HANDLE_INHERIT; - } - SOCKET sock = WSASocket(family, type, protocol, protocol_info, group, flags); +void grpc_wsa_socket_flags_init() { + grpc_wsa_socket_flags = WSA_FLAG_OVERLAPPED; /* WSA_FLAG_NO_HANDLE_INHERIT may be not supported on the older Windows versions, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx for details. */ - if (sock == INVALID_SOCKET && is_wsa_no_handle_inherit_set) { - g_is_wsa_no_handle_inherit_supported = false; - sock = WSASocket(family, type, protocol, protocol_info, group, - flags ^ WSA_FLAG_NO_HANDLE_INHERIT); + SOCKET sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, 0, NULL, + grpc_wsa_socket_flags & WSA_FLAG_NO_HANDLE_INHERIT); + if (sock != INVALID_SOCKET) { + /* Windows 7, Windows 2008 R2 with SP1 or later */ + grpc_wsa_socket_flags &= WSA_FLAG_NO_HANDLE_INHERIT; + closesocket(sock); } - return sock; } #endif /* GRPC_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 79c5c8fbee3..0cf70f39a10 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -118,11 +118,9 @@ void grpc_socket_become_ready(grpc_winsocket* winsocket, The value is probed once, and cached for the life of the process. */ int grpc_ipv6_loopback_available(void); -static bool g_is_wsa_no_handle_inherit_supported = true; +static DWORD grpc_wsa_socket_flags = 0; -SOCKET grpc_create_wsa_socket(int family, int type, int protocol, - LPWSAPROTOCOL_INFO protocol_info, GROUP group, - DWORD flags); +void grpc_wsa_socket_flags_init(); #endif diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc index 5b15ee2c4e6..147edf4ffe4 100644 --- a/src/core/lib/iomgr/tcp_client_windows.cc +++ b/src/core/lib/iomgr/tcp_client_windows.cc @@ -147,9 +147,8 @@ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint, addr = &addr6_v4mapped; } - sock = - grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + grpc_wsa_socket_flags); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc index db4bb84092b..5e0217a5d36 100644 --- a/src/core/lib/iomgr/tcp_server_windows.cc +++ b/src/core/lib/iomgr/tcp_server_windows.cc @@ -254,9 +254,8 @@ static grpc_error* start_accept_locked(grpc_tcp_listener* port) { return GRPC_ERROR_NONE; } - sock = - grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + grpc_wsa_socket_flags); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; @@ -493,9 +492,8 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s, addr = &wildcard; } - sock = - grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + grpc_wsa_socket_flags); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto done; From 7d1e2015395922ea8d62740466eb95c10483e0ac Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Tue, 26 Feb 2019 12:16:53 +0300 Subject: [PATCH 1262/2143] Use grpc_wsa_socket_flags in the test/cpp/naming/resolver_component_test.cc --- test/cpp/naming/resolver_component_test.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 43a9a066266..7410a0e6597 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -279,9 +279,8 @@ void OpenAndCloseSocketsStressLoop(int dummy_port, gpr_event* done_ev) { } std::vector sockets; for (size_t i = 0; i < 50; i++) { - SOCKET s = grpc_create_wsa_socket( - AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + SOCKET s = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, + nullptr, 0, grpc_wsa_socket_flags); ASSERT_TRUE(s != BAD_SOCKET_RETURN_VAL) << "Failed to create TCP ipv6 socket"; gpr_log(GPR_DEBUG, "Opened socket: %d", s); From 8232d698207899d656ace9a27edf921a441db82b Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Tue, 26 Feb 2019 12:32:55 +0300 Subject: [PATCH 1263/2143] Reverted changes in the test/cpp/naming/resolver_component_test.cc --- test/cpp/naming/resolver_component_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 7410a0e6597..9532529e45d 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -279,8 +279,8 @@ void OpenAndCloseSocketsStressLoop(int dummy_port, gpr_event* done_ev) { } std::vector sockets; for (size_t i = 0; i < 50; i++) { - SOCKET s = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, - nullptr, 0, grpc_wsa_socket_flags); + SOCKET s = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0, + WSA_FLAG_OVERLAPPED); ASSERT_TRUE(s != BAD_SOCKET_RETURN_VAL) << "Failed to create TCP ipv6 socket"; gpr_log(GPR_DEBUG, "Opened socket: %d", s); From 6e07d04c928ea1b23742a0662cceabef5a1ae107 Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Tue, 26 Feb 2019 13:48:28 +0300 Subject: [PATCH 1264/2143] Fixed silly error --- src/core/lib/iomgr/socket_windows.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 9e5c579c60d..1794b162223 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -188,10 +188,10 @@ void grpc_wsa_socket_flags_init() { https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx for details. */ SOCKET sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, 0, NULL, - grpc_wsa_socket_flags & WSA_FLAG_NO_HANDLE_INHERIT); + grpc_wsa_socket_flags | WSA_FLAG_NO_HANDLE_INHERIT); if (sock != INVALID_SOCKET) { /* Windows 7, Windows 2008 R2 with SP1 or later */ - grpc_wsa_socket_flags &= WSA_FLAG_NO_HANDLE_INHERIT; + grpc_wsa_socket_flags |= WSA_FLAG_NO_HANDLE_INHERIT; closesocket(sock); } } From 2eb25c871e41b730e44360a8055b3d4a2e3cffb9 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 26 Feb 2019 03:08:06 -0800 Subject: [PATCH 1265/2143] 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 6698cf87b389420794390ca7d5c3327f06cbf1aa Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Tue, 26 Feb 2019 15:41:11 +0300 Subject: [PATCH 1266/2143] Single instances of the grpc_wsa_socket_flags --- src/core/lib/iomgr/socket_windows.cc | 2 ++ src/core/lib/iomgr/socket_windows.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 1794b162223..9b9b745829e 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -39,6 +39,8 @@ #include "src/core/lib/iomgr/sockaddr_windows.h" #include "src/core/lib/iomgr/socket_windows.h" +DWORD grpc_wsa_socket_flags; + grpc_winsocket* grpc_winsocket_create(SOCKET socket, const char* name) { char* final_name; grpc_winsocket* r = (grpc_winsocket*)gpr_malloc(sizeof(grpc_winsocket)); diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 0cf70f39a10..9a5caef9f52 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -118,7 +118,7 @@ void grpc_socket_become_ready(grpc_winsocket* winsocket, The value is probed once, and cached for the life of the process. */ int grpc_ipv6_loopback_available(void); -static DWORD grpc_wsa_socket_flags = 0; +extern DWORD grpc_wsa_socket_flags; void grpc_wsa_socket_flags_init(); From 715e18fbef7da80a60dc26c37e4bd6a95c4f11c0 Mon Sep 17 00:00:00 2001 From: tzik Date: Tue, 26 Feb 2019 22:05:42 +0900 Subject: [PATCH 1267/2143] 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 1268/2143] 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 1269/2143] 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 1270/2143] 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 1271/2143] 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 1272/2143] 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 1273/2143] 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 1274/2143] 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 1275/2143] 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 1276/2143] 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 1277/2143] 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 1278/2143] 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 1279/2143] 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 1280/2143] 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 1281/2143] 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 1282/2143] 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 1283/2143] 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 1284/2143] 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 1285/2143] 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 1286/2143] 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 1287/2143] 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 1288/2143] 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 1289/2143] 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 1290/2143] 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 91ad8884975b334fab848b626fb28de6355fc608 Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Wed, 27 Feb 2019 16:53:23 -0800 Subject: [PATCH 1291/2143] Revert "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, 258 insertions(+), 161 deletions(-) create mode 100644 include/grpcpp/channel_impl.h diff --git a/BUILD b/BUILD index 24c1fb31ced..be2261b825c 100644 --- a/BUILD +++ b/BUILD @@ -216,6 +216,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 1bab5e6cba2..41b7ce683eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2998,6 +2998,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 @@ -3589,6 +3590,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 @@ -4544,6 +4546,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 a2789e40431..65fb0479bf6 100644 --- a/Makefile +++ b/Makefile @@ -5419,6 +5419,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 \ @@ -6019,6 +6020,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 \ @@ -6931,6 +6933,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 c18630ecdd3..8f6b03ae322 100644 --- a/build.yaml +++ b/build.yaml @@ -1339,6 +1339,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 0f3888975c9..9fb40d752a9 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -82,6 +82,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/include/grpcpp/channel.h b/include/grpcpp/channel.h index ee833960698..05a45680916 100644 --- a/include/grpcpp/channel.h +++ b/include/grpcpp/channel.h @@ -19,96 +19,16 @@ #ifndef GRPCPP_CHANNEL_H #define GRPCPP_CHANNEL_H -#include -#include - -#include -#include -#include -#include -#include -#include - -struct grpc_channel; +#include 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..ea90e5b8f7b --- /dev/null +++ b/include/grpcpp/channel_impl.h @@ -0,0 +1,115 @@ +/* + * + * 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 0b2631014a2..7b287f0a3ad 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..e6579b5b7a7 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -56,9 +56,13 @@ struct census_context; struct grpc_call; -namespace grpc { +namespace grpc_impl { class Channel; +} + +namespace grpc { + class ChannelInterface; class CompletionQueue; class CallCredentials; @@ -391,7 +395,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 +427,8 @@ 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 e36a9da79d2..1096b7a2b5d 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -26,10 +26,14 @@ #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 4812f0253d4..79a2805cb5f 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -41,6 +41,11 @@ struct grpc_completion_queue; +namespace grpc_impl { + +class Channel; +} + namespace grpc { template @@ -58,7 +63,6 @@ template class ServerReaderWriterBody; } // namespace internal -class Channel; class ChannelInterface; class ClientContext; class CompletionQueue; @@ -278,7 +282,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; // 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 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 dfea3900048..e8b1544b2c2 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -32,9 +32,13 @@ struct grpc_call; +namespace grpc_impl { + +class Channel; +} + namespace grpc { class ChannelArguments; -class Channel; class SecureChannelCredentials; class CallCredentials; class SecureCallCredentials; @@ -42,7 +46,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 +74,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 +88,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 248f20452a5..159a94c0c81 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -27,6 +27,7 @@ #include #include +#include #include #include #include diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 96e9ab8dcfb..6b53b3f64ce 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..b4bb1b41a21 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -49,14 +49,18 @@ #include "src/core/lib/profiling/timers.h" #include "src/core/lib/surface/completion_queue.h" -namespace grpc { +void grpc::experimental::ChannelResetConnectionBackoff( + ::grpc::Channel* channel) { + grpc_impl::experimental::ChannelResetConnectionBackoff(channel); +} -static internal::GrpcLibraryInitializer g_gli_initializer; -Channel::Channel( - const grpc::string& host, grpc_channel* channel, - std::vector< - std::unique_ptr> - interceptor_creators) +namespace grpc_impl { + +static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer; +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(); @@ -72,7 +76,8 @@ 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,10 +115,9 @@ void ChannelResetConnectionBackoff(Channel* channel) { } // namespace experimental -internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, - ClientContext* context, - 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) { @@ -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}); @@ -252,4 +256,4 @@ CompletionQueue* Channel::CallbackCQ() { 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 efb59c71a8c..b3c52acd5f6 100644 --- a/src/cpp/client/client_context.cc +++ b/src/cpp/client/client_context.cc @@ -30,6 +30,11 @@ #include #include +namespace grpc_impl { + +class Channel; +} + namespace grpc { class DefaultGlobalClientCallbacks final @@ -82,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& 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.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..77fd00fb3fe 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::vector> interceptor_creators) { return std::shared_ptr( new Channel(host, c_channel, std::move(interceptor_creators))); } -} // namespace grpc + +} // namespace grpc_impl diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h index a90c92c518d..7dab6473a9c 100644 --- a/src/cpp/client/create_channel_internal.h +++ b/src/cpp/client/create_channel_internal.h @@ -26,15 +26,16 @@ 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::vector> interceptor_creators); -} // namespace grpc +} // namespace grpc_impl #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 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/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), 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..5db4af143b4 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -27,6 +27,11 @@ #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 +42,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 7eb0f2372b6..17b6bc897c8 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 CreateChannelInternal( + return ::grpc_impl::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 CreateChannelInternal( + return ::grpc_impl::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 7f9fd29026e..9202585535b 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"; diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index e57650fe5b7..52ff5a3d79d 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..f94f0ac30a2 100644 --- a/test/cpp/util/create_test_channel.h +++ b/test/cpp/util/create_test_channel.h @@ -23,8 +23,12 @@ #include -namespace grpc { +namespace grpc_impl { + class Channel; +} + +namespace grpc { namespace testing { @@ -32,31 +36,31 @@ 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); diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 9f17a25298a..cbc601921e1 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 664a6b3acfe..2d761199047 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 95b6ae65008..4bec0074ae7 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11363,6 +11363,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", @@ -11472,6 +11473,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 9644e588f6ef011ec8e0d6f58d5c2cdb04eb0f03 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Wed, 27 Feb 2019 23:01:24 -0800 Subject: [PATCH 1292/2143] 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 1293/2143] 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 1294/2143] 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 1295/2143] 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 1296/2143] 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 1297/2143] 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 1298/2143] 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 1299/2143] 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 1300/2143] 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 1301/2143] 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 1302/2143] 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 1303/2143] 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 1304/2143] 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 1305/2143] 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 1306/2143] 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 1307/2143] 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 1308/2143] 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 1309/2143] 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 1310/2143] 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 1311/2143] 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 1312/2143] 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 1313/2143] 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 1314/2143] 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 1315/2143] 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 1316/2143] 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 1317/2143] 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 1318/2143] 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 1319/2143] 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 1320/2143] 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 1321/2143] 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 1322/2143] 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 1323/2143] 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 1324/2143] 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 1325/2143] 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 1326/2143] 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 1327/2143] 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 1328/2143] 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 1329/2143] 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 1330/2143] 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 1331/2143] 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 1332/2143] 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 1333/2143] 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 1334/2143] 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 1335/2143] 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 1336/2143] 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 1337/2143] 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 1338/2143] 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 1339/2143] 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 1340/2143] 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 1341/2143] 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 1342/2143] 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 1343/2143] 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 1344/2143] 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 1345/2143] 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 1346/2143] 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 1347/2143] 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 1348/2143] 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 1349/2143] 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 1350/2143] 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 1351/2143] 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 1352/2143] 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 1353/2143] 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 1354/2143] 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 1355/2143] 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 1356/2143] 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 1357/2143] 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 1358/2143] 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 1359/2143] 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 1360/2143] 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 1361/2143] 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 1362/2143] 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 1363/2143] 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 1364/2143] 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 1365/2143] 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 1366/2143] 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 1367/2143] 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 1368/2143] 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 1369/2143] 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 1370/2143] 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 1371/2143] 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 1372/2143] 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 1373/2143] 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 1374/2143] 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 1375/2143] 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 1376/2143] 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 1377/2143] 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 1378/2143] 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 1379/2143] 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 1380/2143] 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 1381/2143] 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 1382/2143] 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 1383/2143] 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 1384/2143] 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 1385/2143] 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 1386/2143] 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 1387/2143] 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 1388/2143] 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 1389/2143] 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 1390/2143] 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 1391/2143] 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 1392/2143] 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 1393/2143] 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 1394/2143] 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 1395/2143] 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 1396/2143] 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 1397/2143] 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 1398/2143] 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 1399/2143] 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 1400/2143] 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 1401/2143] 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 1402/2143] 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 1403/2143] 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 1404/2143] 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 1405/2143] 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 1406/2143] 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 1407/2143] 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 1408/2143] 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 1409/2143] 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 1410/2143] 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 1411/2143] 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 1412/2143] 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 1413/2143] 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 b3254101418d2c733380f532a0e80da6e3042194 Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Tue, 12 Mar 2019 18:17:09 +0300 Subject: [PATCH 1414/2143] Added grpc_get_default_wsa_socket_flags() --- .../resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc | 3 ++- src/core/lib/iomgr/endpoint_pair_windows.cc | 4 ++-- src/core/lib/iomgr/socket_windows.cc | 4 +++- src/core/lib/iomgr/socket_windows.h | 2 ++ src/core/lib/iomgr/tcp_client_windows.cc | 2 +- src/core/lib/iomgr/tcp_server_windows.cc | 4 ++-- 6 files changed, 12 insertions(+), 7 deletions(-) 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 5cd988ec1d7..69a206ba847 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 @@ -442,7 +442,8 @@ class SockToPolledFdMap { */ static ares_socket_t Socket(int af, int type, int protocol, void* user_data) { SockToPolledFdMap* map = static_cast(user_data); - SOCKET s = WSASocket(af, type, protocol, nullptr, 0, grpc_wsa_socket_flags); + SOCKET s = WSASocket(af, type, protocol, nullptr, 0, + grpc_get_default_wsa_socket_flags()); if (s == INVALID_SOCKET) { return s; } diff --git a/src/core/lib/iomgr/endpoint_pair_windows.cc b/src/core/lib/iomgr/endpoint_pair_windows.cc index ee6a617f61f..9962809a27b 100644 --- a/src/core/lib/iomgr/endpoint_pair_windows.cc +++ b/src/core/lib/iomgr/endpoint_pair_windows.cc @@ -41,7 +41,7 @@ static void create_sockets(SOCKET sv[2]) { int addr_len = sizeof(addr); lst_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - grpc_wsa_socket_flags); + grpc_get_default_wsa_socket_flags()); GPR_ASSERT(lst_sock != INVALID_SOCKET); memset(&addr, 0, sizeof(addr)); @@ -54,7 +54,7 @@ static void create_sockets(SOCKET sv[2]) { SOCKET_ERROR); cli_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - grpc_wsa_socket_flags); + grpc_get_default_wsa_socket_flags()); GPR_ASSERT(cli_sock != INVALID_SOCKET); GPR_ASSERT(WSAConnect(cli_sock, (grpc_sockaddr*)&addr, addr_len, NULL, NULL, diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 9b9b745829e..2026c95062f 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -183,13 +183,15 @@ int grpc_ipv6_loopback_available(void) { return g_ipv6_loopback_available; } +DWORD grpc_get_default_wsa_socket_flags() { return grpc_wsa_socket_flags; } + void grpc_wsa_socket_flags_init() { grpc_wsa_socket_flags = WSA_FLAG_OVERLAPPED; /* WSA_FLAG_NO_HANDLE_INHERIT may be not supported on the older Windows versions, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx for details. */ - SOCKET sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, 0, NULL, + SOCKET sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, grpc_wsa_socket_flags | WSA_FLAG_NO_HANDLE_INHERIT); if (sock != INVALID_SOCKET) { /* Windows 7, Windows 2008 R2 with SP1 or later */ diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 9a5caef9f52..32b88880569 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -122,6 +122,8 @@ extern DWORD grpc_wsa_socket_flags; void grpc_wsa_socket_flags_init(); +DWORD grpc_get_default_wsa_socket_flags(); + #endif #endif /* GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H */ diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc index 147edf4ffe4..264af452618 100644 --- a/src/core/lib/iomgr/tcp_client_windows.cc +++ b/src/core/lib/iomgr/tcp_client_windows.cc @@ -148,7 +148,7 @@ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint, } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - grpc_wsa_socket_flags); + grpc_get_default_wsa_socket_flags()); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc index 5e0217a5d36..7ac423440e2 100644 --- a/src/core/lib/iomgr/tcp_server_windows.cc +++ b/src/core/lib/iomgr/tcp_server_windows.cc @@ -255,7 +255,7 @@ static grpc_error* start_accept_locked(grpc_tcp_listener* port) { } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - grpc_wsa_socket_flags); + grpc_get_default_wsa_socket_flags()); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; @@ -493,7 +493,7 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s, } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - grpc_wsa_socket_flags); + grpc_get_default_wsa_socket_flags()); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto done; From 2a50960b4c874e90d9d32c53e9a642c0869e1b80 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 12 Mar 2019 08:37:07 -0700 Subject: [PATCH 1415/2143] 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 1416/2143] 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 1417/2143] 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 1418/2143] 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 1419/2143] 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 1420/2143] 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 1421/2143] 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 82c6e012d85626eac14baaa1b7cef2f1bbb0492c Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 12 Mar 2019 14:01:05 -0700 Subject: [PATCH 1422/2143] Revert "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, 122 insertions(+), 53 deletions(-) create mode 100644 include/grpcpp/resource_quota_impl.h diff --git a/BUILD b/BUILD index 4bf387cec3a..191661fdd9a 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 7ccda85b125..40719422aa8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3014,6 +3014,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 @@ -3604,6 +3605,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 @@ -4559,6 +4561,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 91516de9a27..f47184b3436 100644 --- a/Makefile +++ b/Makefile @@ -5438,6 +5438,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 \ @@ -6037,6 +6038,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 \ @@ -6949,6 +6951,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 02ecaa221e6..cfd6cdb18a4 100644 --- a/build.yaml +++ b/build.yaml @@ -1360,6 +1360,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 e755b7aa602..2d50f28ff2a 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 498e5b7bb31..4c00f021d11 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; @@ -186,7 +190,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 cd0e516d9a3..f60c77dc8d6 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 (*)()>* @@ -164,7 +169,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 c0078bf2764..4c1ba9d4f9d 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 7a72a885336..96fa00e387e 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11391,6 +11391,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", @@ -11500,6 +11501,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 c792aae3286454a0fd035dc8f8d79da02c2a9a63 Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Wed, 13 Mar 2019 10:29:41 +0300 Subject: [PATCH 1423/2143] Removed grpc_wsa_socket_flags variable from the header, renamed to s_wsa_socket_flags --- src/core/lib/iomgr/socket_windows.cc | 10 +++++----- src/core/lib/iomgr/socket_windows.h | 2 -- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 2026c95062f..c87cfa8e831 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -39,7 +39,7 @@ #include "src/core/lib/iomgr/sockaddr_windows.h" #include "src/core/lib/iomgr/socket_windows.h" -DWORD grpc_wsa_socket_flags; +static DWORD s_wsa_socket_flags; grpc_winsocket* grpc_winsocket_create(SOCKET socket, const char* name) { char* final_name; @@ -183,19 +183,19 @@ int grpc_ipv6_loopback_available(void) { return g_ipv6_loopback_available; } -DWORD grpc_get_default_wsa_socket_flags() { return grpc_wsa_socket_flags; } +DWORD grpc_get_default_wsa_socket_flags() { return s_wsa_socket_flags; } void grpc_wsa_socket_flags_init() { - grpc_wsa_socket_flags = WSA_FLAG_OVERLAPPED; + s_wsa_socket_flags = WSA_FLAG_OVERLAPPED; /* WSA_FLAG_NO_HANDLE_INHERIT may be not supported on the older Windows versions, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx for details. */ SOCKET sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - grpc_wsa_socket_flags | WSA_FLAG_NO_HANDLE_INHERIT); + s_wsa_socket_flags | WSA_FLAG_NO_HANDLE_INHERIT); if (sock != INVALID_SOCKET) { /* Windows 7, Windows 2008 R2 with SP1 or later */ - grpc_wsa_socket_flags |= WSA_FLAG_NO_HANDLE_INHERIT; + s_wsa_socket_flags |= WSA_FLAG_NO_HANDLE_INHERIT; closesocket(sock); } } diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 32b88880569..5fed6909e6f 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -118,8 +118,6 @@ void grpc_socket_become_ready(grpc_winsocket* winsocket, The value is probed once, and cached for the life of the process. */ int grpc_ipv6_loopback_available(void); -extern DWORD grpc_wsa_socket_flags; - void grpc_wsa_socket_flags_init(); DWORD grpc_get_default_wsa_socket_flags(); From fac3ec2563fc1174e9c9f3ade4c2d10a9878020d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 13 Mar 2019 11:53:06 +0100 Subject: [PATCH 1424/2143] 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 1425/2143] 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 1426/2143] 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 1427/2143] 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 1428/2143] 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 1429/2143] 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 1430/2143] 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 1431/2143] 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 1432/2143] 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 1433/2143] 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 1434/2143] 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 1435/2143] 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 1436/2143] 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 1437/2143] 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 1438/2143] 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 1439/2143] 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 1440/2143] 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 d8d8bec7c8a254b1f8bc152b71b0b1c2b41bfe3f Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 1 Mar 2019 13:32:36 -0800 Subject: [PATCH 1441/2143] Moving ::grpc::ResourceQuota to ::grpc_impl::ResouceQuota This change moves ResourceQuota class fron grpc namespace to grpc_impl namespace. Signed-off-by: Karthik Ravi Shankar --- 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 | 8 ++- include/grpcpp/support/channel_arguments.h | 8 ++- src/cpp/common/channel_arguments.cc | 2 +- src/cpp/common/resource_quota_cc.cc | 2 +- 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 | 2 +- 16 files changed, 117 insertions(+), 51 deletions(-) create mode 100644 include/grpcpp/resource_quota_impl.h diff --git a/BUILD b/BUILD index 0b6fff354f4..e60ce691443 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 0030c9eb9af..614fd2efca1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3014,6 +3014,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 @@ -3604,6 +3605,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 @@ -4563,6 +4565,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 5a31d648b32..7ad32e1291f 100644 --- a/Makefile +++ b/Makefile @@ -5438,6 +5438,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 \ @@ -6037,6 +6038,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 \ @@ -6949,6 +6951,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 d8322b176b7..82e652878bd 100644 --- a/build.yaml +++ b/build.yaml @@ -1360,6 +1360,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 e755b7aa602..2d50f28ff2a 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 498e5b7bb31..662581a40bb 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; @@ -186,7 +190,7 @@ 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..e0014977cff 100644 --- a/include/grpcpp/support/channel_arguments.h +++ b/include/grpcpp/support/channel_arguments.h @@ -26,12 +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, @@ -83,7 +87,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..bbf42fd1f3e 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)) {} diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index cd0e516d9a3..f60c77dc8d6 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 (*)()>* @@ -164,7 +169,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..8f20de7e714 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -27,7 +27,7 @@ #include #include #include -#include +//#include #include #include #include From 7f6ed9267f5ff146ca2554afdcdebe9395e9e81b Mon Sep 17 00:00:00 2001 From: Michael Behr Date: Thu, 14 Mar 2019 15:27:15 -0400 Subject: [PATCH 1442/2143] 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 1443/2143] 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 90edf47fe938886c18dbfac447991a6f252124be Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 14 Mar 2019 14:26:25 -0700 Subject: [PATCH 1444/2143] Move server_posix from grpc to grpc_impl namespace --- BUILD | 1 + CMakeLists.txt | 3 ++ Makefile | 3 ++ include/grpcpp/server_builder.h | 3 +- include/grpcpp/server_posix.h | 20 +---------- include/grpcpp/server_posix_impl.h | 42 ++++++++++++++++++++++ include/grpcpp/support/channel_arguments.h | 1 - src/cpp/common/resource_quota_cc.cc | 2 +- 8 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 include/grpcpp/server_posix_impl.h diff --git a/BUILD b/BUILD index e60ce691443..9070a66c978 100644 --- a/BUILD +++ b/BUILD @@ -250,6 +250,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/server_builder.h", "include/grpcpp/server_context.h", "include/grpcpp/server_posix.h", + "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 614fd2efca1..a49a5b1f938 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3023,6 +3023,7 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_context.h include/grpcpp/server_posix.h + include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h @@ -3614,6 +3615,7 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_context.h include/grpcpp/server_posix.h + include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h @@ -4574,6 +4576,7 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_context.h include/grpcpp/server_posix.h + include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h diff --git a/Makefile b/Makefile index 7ad32e1291f..f65ce2addf0 100644 --- a/Makefile +++ b/Makefile @@ -5447,6 +5447,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ + include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ @@ -6047,6 +6048,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ + include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ @@ -6960,6 +6962,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ + include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 662581a40bb..4c00f021d11 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -190,7 +190,8 @@ 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 ::grpc_impl::ResourceQuota& resource_quota); ServerBuilder& SetOption(std::unique_ptr option); diff --git a/include/grpcpp/server_posix.h b/include/grpcpp/server_posix.h index ef3ee01a5c6..7b46967a8ba 100644 --- a/include/grpcpp/server_posix.h +++ b/include/grpcpp/server_posix.h @@ -19,24 +19,6 @@ #ifndef GRPCPP_SERVER_POSIX_H #define GRPCPP_SERVER_POSIX_H -#include - -#include -#include - -namespace grpc { - -#ifdef GPR_SUPPORT_CHANNELS_FROM_FD - -/// Add a new client to a \a Server communicating over the given -/// file descriptor. -/// -/// \param server The server to add the client to. -/// \param fd The file descriptor representing a socket. -void AddInsecureChannelFromFd(Server* server, int fd); - -#endif // GPR_SUPPORT_CHANNELS_FROM_FD - -} // namespace grpc +#include #endif // GRPCPP_SERVER_POSIX_H diff --git a/include/grpcpp/server_posix_impl.h b/include/grpcpp/server_posix_impl.h new file mode 100644 index 00000000000..c29af271fe9 --- /dev/null +++ b/include/grpcpp/server_posix_impl.h @@ -0,0 +1,42 @@ +/* + * + * 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_SERVER_POSIX_IMPL_H +#define GRPCPP_SERVER_POSIX_IMPL_H + +#include + +#include +#include + +namespace grpc_impl { + +#ifdef GPR_SUPPORT_CHANNELS_FROM_FD + +/// Add a new client to a \a Server communicating over the given +/// file descriptor. +/// +/// \param server The server to add the client to. +/// \param fd The file descriptor representing a socket. +void AddInsecureChannelFromFd(grpc::Server* server, int fd); + +#endif // GPR_SUPPORT_CHANNELS_FROM_FD + +} // namespace grpc + +#endif // GRPCPP_SERVER_POSIX_IMPL_H diff --git a/include/grpcpp/support/channel_arguments.h b/include/grpcpp/support/channel_arguments.h index e0014977cff..48ae4246462 100644 --- a/include/grpcpp/support/channel_arguments.h +++ b/include/grpcpp/support/channel_arguments.h @@ -36,7 +36,6 @@ namespace testing { class ChannelArgumentsTest; } // namespace testing - /// 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. diff --git a/src/cpp/common/resource_quota_cc.cc b/src/cpp/common/resource_quota_cc.cc index bbf42fd1f3e..4fab2975d89 100644 --- a/src/cpp/common/resource_quota_cc.cc +++ b/src/cpp/common/resource_quota_cc.cc @@ -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 From b017c801b683d47160bdb3f98c19124fcbd1fc0a Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Thu, 14 Mar 2019 15:24:48 -0700 Subject: [PATCH 1445/2143] 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 1446/2143] 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 1447/2143] 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 2c574381037816ee8bdf90fe388c3f6c7ba27506 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 14 Mar 2019 17:07:36 -0700 Subject: [PATCH 1448/2143] Fix errors from tests --- CMakeLists.txt | 3 --- Makefile | 3 --- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + tools/run_tests/generated/sources_and_headers.json | 2 ++ 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a49a5b1f938..614fd2efca1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3023,7 +3023,6 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_context.h include/grpcpp/server_posix.h - include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h @@ -3615,7 +3614,6 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_context.h include/grpcpp/server_posix.h - include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h @@ -4576,7 +4574,6 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_context.h include/grpcpp/server_posix.h - include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h diff --git a/Makefile b/Makefile index f65ce2addf0..7ad32e1291f 100644 --- a/Makefile +++ b/Makefile @@ -5447,7 +5447,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ - include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ @@ -6048,7 +6047,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ - include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ @@ -6962,7 +6960,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ - include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ 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 c0078bf2764..4c1ba9d4f9d 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 8adde9ec602..bcf2cf4f5ec 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11411,6 +11411,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", @@ -11520,6 +11521,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 ec78d0f56913fde14995b21515a525882e175602 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 14 Mar 2019 19:51:09 -0700 Subject: [PATCH 1449/2143] 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 49164c8aebb464b39c110832b8afbdf8172fea01 Mon Sep 17 00:00:00 2001 From: Adam Lemmon Date: Fri, 15 Mar 2019 09:45:30 -0600 Subject: [PATCH 1450/2143] Update Channel.cs Simple spelling or wording fixes to make comments read more cleanly --- src/csharp/Grpc.Core/Channel.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs index 7ce929dfa31..97f79b0fb4f 100644 --- a/src/csharp/Grpc.Core/Channel.cs +++ b/src/csharp/Grpc.Core/Channel.cs @@ -59,7 +59,7 @@ namespace Grpc.Core /// /// Creates a channel that connects to a specific host. - /// Port will default to 80 for an unsecure channel and to 443 for a secure channel. + /// Port will default to 80 for an unsecure channel or to 443 for a secure channel. /// /// Target of the channel. /// Credentials to secure the channel. @@ -112,7 +112,7 @@ namespace Grpc.Core /// /// Gets current connectivity state of this channel. - /// After channel is has been shutdown, ChannelState.Shutdown will be returned. + /// After channel has been shutdown, ChannelState.Shutdown will be returned. /// public ChannelState State { @@ -132,7 +132,7 @@ namespace Grpc.Core /// /// Returned tasks completes once channel state has become different from /// given lastObservedState. - /// If deadline is reached or and error occurs, returned task is cancelled. + /// If deadline is reached or an error occurs, returned task is cancelled. /// public async Task WaitForStateChangedAsync(ChannelState lastObservedState, DateTime? deadline = null) { From cf6a31176137984d3335ad72273333491dc25153 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 15 Mar 2019 17:15:20 +0100 Subject: [PATCH 1451/2143] 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 1452/2143] 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 1453/2143] 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 f66b6547959e1964932872e15498042156ee8c08 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 11:30:23 -0700 Subject: [PATCH 1454/2143] Revert "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, 114 insertions(+), 75 deletions(-) create mode 100644 include/grpcpp/opencensus_impl.h diff --git a/BUILD b/BUILD index 835edbfb48f..afeacf0239a 100644 --- a/BUILD +++ b/BUILD @@ -2283,6 +2283,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..d7e3c81a955 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_impl namespace grpc { using ::opencensus::stats::Aggregation; @@ -71,21 +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() { 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 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 e9ad9e90b35138259d2749a58c89f169380a5146 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 15 Mar 2019 11:41:57 -0700 Subject: [PATCH 1455/2143] 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 f570c5ce7e8b0e237b5ad047b22ef39f62c1a990 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 11:43:28 -0700 Subject: [PATCH 1456/2143] Make changes for making opencensus API visible from gRPC namespace --- include/grpcpp/opencensus.h | 15 +++++++++++++++ .../filters/census/stats_plugin_end2end_test.cc | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/grpcpp/opencensus.h b/include/grpcpp/opencensus.h index 3b170336834..14c6add1d9e 100644 --- a/include/grpcpp/opencensus.h +++ b/include/grpcpp/opencensus.h @@ -21,4 +21,19 @@ #include "grpcpp/opencensus_impl.h" +namespace grpc { + +static inline void RegisterOpenCensusPlugin() { + ::grpc_impl::RegisterOpenCensusPlugin(); +} +static inline void RegisterOpenCensusViewsForExport() { + ::grpc_impl::RegisterOpenCensusViewsForExport(); +} +static inline ::opencensus::trace::Span GetSpanFromServerContext( + ServerContext* context) { + return ::grpc_impl::GetSpanFromServerContext(context); +} + +} // namespace grpc + #endif // GRPCPP_OPENCENSUS_H 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..1b40ca42254 100644 --- a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc +++ b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc @@ -25,6 +25,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" #include "include/grpc++/grpc++.h" +#include "include/grpcpp/opencensus.h" #include "opencensus/stats/stats.h" #include "opencensus/stats/testing/test_utils.h" #include "src/cpp/ext/filters/census/grpc_plugin.h" @@ -58,7 +59,7 @@ class EchoServer final : public EchoTestService::Service { class StatsPluginEnd2EndTest : public ::testing::Test { protected: - static void SetUpTestCase() { grpc_impl::RegisterOpenCensusPlugin(); } + static void SetUpTestCase() { grpc::RegisterOpenCensusPlugin(); } void SetUp() { // Set up a synchronous server on a different thread to avoid the asynch From c3ecc618672631c36db5a204b94fc6b259bda191 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 15 Mar 2019 11:48:10 -0700 Subject: [PATCH 1457/2143] 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 1458/2143] 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 1459/2143] 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 29bcbb24c284a28b89ae52592926807ef090fcf2 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 14 Mar 2019 14:53:10 -0700 Subject: [PATCH 1460/2143] Moving create_channel from grpc to grpc_impl --- BUILD | 1 + CMakeLists.txt | 3 ++ Makefile | 3 ++ build.yaml | 1 + gRPC-C++.podspec | 1 + include/grpcpp/create_channel.h | 59 +-------------------- include/grpcpp/create_channel_impl.h | 79 ++++++++++++++++++++++++++++ 7 files changed, 90 insertions(+), 57 deletions(-) create mode 100644 include/grpcpp/create_channel_impl.h diff --git a/BUILD b/BUILD index 835edbfb48f..a8824d8f650 100644 --- a/BUILD +++ b/BUILD @@ -219,6 +219,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", + "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", "include/grpcpp/ext/health_check_service_server_builder_option.h", "include/grpcpp/generic/async_generic_service.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 2308582c2f4..98ac1ea7752 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2999,6 +2999,7 @@ foreach(_hdr include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h + include/grpcpp/create_channel_impl.h include/grpcpp/create_channel_posix.h include/grpcpp/ext/health_check_service_server_builder_option.h include/grpcpp/generic/async_generic_service.h @@ -3589,6 +3590,7 @@ foreach(_hdr include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h + include/grpcpp/create_channel_impl.h include/grpcpp/create_channel_posix.h include/grpcpp/ext/health_check_service_server_builder_option.h include/grpcpp/generic/async_generic_service.h @@ -4548,6 +4550,7 @@ foreach(_hdr include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h + include/grpcpp/create_channel_impl.h include/grpcpp/create_channel_posix.h include/grpcpp/ext/health_check_service_server_builder_option.h include/grpcpp/generic/async_generic_service.h diff --git a/Makefile b/Makefile index 69a2abbc8ca..5f1f297457c 100644 --- a/Makefile +++ b/Makefile @@ -5424,6 +5424,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ + include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ @@ -6023,6 +6024,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ + include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ @@ -6935,6 +6937,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ + include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ diff --git a/build.yaml b/build.yaml index 34b271f58de..fe430652c90 100644 --- a/build.yaml +++ b/build.yaml @@ -1344,6 +1344,7 @@ filegroups: - include/grpcpp/client_context.h - include/grpcpp/completion_queue.h - include/grpcpp/create_channel.h + - include/grpcpp/create_channel_impl.h - include/grpcpp/create_channel_posix.h - include/grpcpp/ext/health_check_service_server_builder_option.h - include/grpcpp/generic/async_generic_service.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 5a850bc8438..1766342285a 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -85,6 +85,7 @@ Pod::Spec.new do |s| 'include/grpcpp/client_context.h', 'include/grpcpp/completion_queue.h', 'include/grpcpp/create_channel.h', + 'include/grpcpp/create_channel_impl.h', 'include/grpcpp/create_channel_posix.h', 'include/grpcpp/ext/health_check_service_server_builder_option.h', 'include/grpcpp/generic/async_generic_service.h', diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index e8a2a70581d..40d4717071a 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -1,6 +1,6 @@ /* * - * 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. @@ -19,61 +19,6 @@ #ifndef GRPCPP_CREATE_CHANNEL_H #define GRPCPP_CREATE_CHANNEL_H -#include - -#include -#include -#include -#include -#include - -namespace grpc { - -/// Create a new \a Channel pointing to \a target. -/// -/// \param target The URI of the endpoint to connect to. -/// \param creds Credentials to use for the created channel. If it does not -/// hold an object or is invalid, a lame channel (one on which all operations -/// fail) is returned. -std::shared_ptr CreateChannel( - const grpc::string& target, - const std::shared_ptr& creds); - -/// Create a new \em custom \a Channel pointing to \a target. -/// -/// \warning For advanced use and testing ONLY. Override default channel -/// arguments only if necessary. -/// -/// \param target The URI of the endpoint to connect to. -/// \param creds Credentials to use for the created channel. If it does not -/// hold an object or is invalid, a lame channel (one on which all operations -/// fail) is returned. -/// \param args Options for channel creation. -std::shared_ptr CreateCustomChannel( - const grpc::string& target, - const std::shared_ptr& creds, - const ChannelArguments& args); - -namespace experimental { -/// Create a new \em custom \a Channel pointing to \a target with \a -/// interceptors being invoked per call. -/// -/// \warning For advanced use and testing ONLY. Override default channel -/// arguments only if necessary. -/// -/// \param target The URI of the endpoint to connect to. -/// \param creds Credentials to use for the created channel. If it does not -/// hold an object or is invalid, a lame channel (one on which all operations -/// fail) is returned. -/// \param args Options for channel creation. -std::shared_ptr CreateCustomChannelWithInterceptors( - const grpc::string& target, - const std::shared_ptr& creds, - const ChannelArguments& args, - std::vector< - std::unique_ptr> - interceptor_creators); -} // namespace experimental -} // namespace grpc +#include #endif // GRPCPP_CREATE_CHANNEL_H diff --git a/include/grpcpp/create_channel_impl.h b/include/grpcpp/create_channel_impl.h new file mode 100644 index 00000000000..9eaeb7c17f6 --- /dev/null +++ b/include/grpcpp/create_channel_impl.h @@ -0,0 +1,79 @@ +/* + * + * 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_CREATE_CHANNEL_IMPL_H +#define GRPCPP_CREATE_CHANNEL_IMPL_H + +#include + +#include +#include +#include +#include +#include + +namespace grpc_impl { + +/// Create a new \a Channel pointing to \a target. +/// +/// \param target The URI of the endpoint to connect to. +/// \param creds Credentials to use for the created channel. If it does not +/// hold an object or is invalid, a lame channel (one on which all operations +/// fail) is returned. +std::shared_ptr CreateChannel( + const grpc::string& target, + const std::shared_ptr& creds); + +/// Create a new \em custom \a Channel pointing to \a target. +/// +/// \warning For advanced use and testing ONLY. Override default channel +/// arguments only if necessary. +/// +/// \param target The URI of the endpoint to connect to. +/// \param creds Credentials to use for the created channel. If it does not +/// hold an object or is invalid, a lame channel (one on which all operations +/// fail) is returned. +/// \param args Options for channel creation. +std::shared_ptr CreateCustomChannel( + const grpc::string& target, + const std::shared_ptr& creds, + const ChannelArguments& args); + +namespace experimental { +/// Create a new \em custom \a Channel pointing to \a target with \a +/// interceptors being invoked per call. +/// +/// \warning For advanced use and testing ONLY. Override default channel +/// arguments only if necessary. +/// +/// \param target The URI of the endpoint to connect to. +/// \param creds Credentials to use for the created channel. If it does not +/// hold an object or is invalid, a lame channel (one on which all operations +/// fail) is returned. +/// \param args Options for channel creation. +std::shared_ptr CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr& creds, + const ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators); +} // namespace experimental +} // namespace grpc_impl + +#endif // GRPCPP_CREATE_CHANNEL_IMPL_H From 78fc00f0ce9ac0228861ea8dcb344ce80d21fe92 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Fri, 15 Mar 2019 13:16:18 -0700 Subject: [PATCH 1461/2143] 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 4a0c3b848f4bc8c50d03971f627c28675a766243 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 14 Mar 2019 22:24:01 -0700 Subject: [PATCH 1462/2143] Fix broken tests --- examples/BUILD | 2 +- include/grpcpp/create_channel.h | 30 +++++++++++++++++++++ include/grpcpp/create_channel_impl.h | 18 ++++++------- include/grpcpp/security/credentials.h | 31 ++++++++++++++-------- src/cpp/client/create_channel.cc | 38 ++++++++++++++------------- 5 files changed, 80 insertions(+), 39 deletions(-) diff --git a/examples/BUILD b/examples/BUILD index 0a1ca94a649..c67c582964a 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -112,4 +112,4 @@ cc_binary( srcs = ["cpp/keyvaluestore/server.cc"], defines = ["BAZEL_BUILD"], deps = [":keyvaluestore", "//:grpc++"], -) \ No newline at end of file +) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index 40d4717071a..7d92716b773 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -21,4 +21,34 @@ #include +namespace grpc { + +static inline std::shared_ptr CreateChannel( + const grpc::string& target, + const std::shared_ptr& creds) { + return ::grpc_impl::CreateChannel(target, creds); +} + +static inline std::shared_ptr CreateCustomChannel( + const grpc::string& target, + const std::shared_ptr& creds, + const ChannelArguments& args) { + return ::grpc_impl::CreateCustomChannel(target, creds, args); +} + +namespace experimental { + +static inline std::shared_ptr CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr& creds, + const ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators) { + return ::grpc_impl::experimental::CreateCustomChannelWithInterceptors(target, creds, args, std::move(interceptor_creators)); +} + +} // namespace experimental +} // namespace grpc + #endif // GRPCPP_CREATE_CHANNEL_H diff --git a/include/grpcpp/create_channel_impl.h b/include/grpcpp/create_channel_impl.h index 9eaeb7c17f6..214a537a3cb 100644 --- a/include/grpcpp/create_channel_impl.h +++ b/include/grpcpp/create_channel_impl.h @@ -35,9 +35,9 @@ namespace grpc_impl { /// \param creds Credentials to use for the created channel. If it does not /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. -std::shared_ptr CreateChannel( +std::shared_ptr CreateChannel( const grpc::string& target, - const std::shared_ptr& creds); + const std::shared_ptr& creds); /// Create a new \em custom \a Channel pointing to \a target. /// @@ -49,10 +49,10 @@ std::shared_ptr CreateChannel( /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannel( +std::shared_ptr CreateCustomChannel( const grpc::string& target, - const std::shared_ptr& creds, - const ChannelArguments& args); + const std::shared_ptr& creds, + const grpc::ChannelArguments& args); namespace experimental { /// Create a new \em custom \a Channel pointing to \a target with \a @@ -66,12 +66,12 @@ namespace experimental { /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannelWithInterceptors( +std::shared_ptr CreateCustomChannelWithInterceptors( const grpc::string& target, - const std::shared_ptr& creds, - const ChannelArguments& args, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators); } // namespace experimental } // namespace grpc_impl diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index dfea3900048..f17e295975a 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -33,23 +33,32 @@ struct grpc_call; namespace grpc { -class ChannelArguments; -class Channel; -class SecureChannelCredentials; -class CallCredentials; -class SecureCallCredentials; +class CallCredentials; +class ChannelArguments; class ChannelCredentials; +} +namespace grpc_impl { +std::shared_ptr CreateCustomChannel( + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args); namespace experimental { -std::shared_ptr CreateCustomChannelWithInterceptors( +std::shared_ptr CreateCustomChannelWithInterceptors( const grpc::string& target, - const std::shared_ptr& creds, - const ChannelArguments& args, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators); } // namespace experimental +} // namespace grpc_impl +namespace grpc { +class Channel; +class SecureChannelCredentials; +class SecureCallCredentials; + /// A channel credentials object encapsulates all the state needed by a client /// to authenticate with a server for a given channel. @@ -70,13 +79,13 @@ class ChannelCredentials : private GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr CreateCustomChannel( + friend std::shared_ptr grpc_impl::CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args); friend std::shared_ptr - experimental::CreateCustomChannelWithInterceptors( + grpc_impl::experimental::CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args, diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 457daa674c7..4a4298684cb 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -19,34 +19,36 @@ #include #include -#include +#include #include #include #include "src/cpp/client/create_channel_internal.h" namespace grpc { -class ChannelArguments; -std::shared_ptr CreateChannel( +class ChannelArguments; +} +namespace grpc_impl { +std::shared_ptr CreateChannel( const grpc::string& target, - const std::shared_ptr& creds) { - return CreateCustomChannel(target, creds, ChannelArguments()); + const std::shared_ptr& creds) { + return CreateCustomChannel(target, creds, grpc::ChannelArguments()); } -std::shared_ptr CreateCustomChannel( +std::shared_ptr CreateCustomChannel( const grpc::string& target, - const std::shared_ptr& creds, - const ChannelArguments& args) { - GrpcLibraryCodegen init_lib; // We need to call init in case of a bad creds. + const std::shared_ptr& creds, + const grpc::ChannelArguments& args) { + grpc::GrpcLibraryCodegen init_lib; // We need to call init in case of a bad creds. return creds ? creds->CreateChannel(target, args) - : CreateChannelInternal( + : grpc::CreateChannelInternal( "", grpc_lame_client_channel_create( nullptr, GRPC_STATUS_INVALID_ARGUMENT, "Invalid credentials."), std::vector>()); + grpc::experimental::ClientInterceptorFactoryInterface>>()); } namespace experimental { @@ -61,23 +63,23 @@ namespace experimental { /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannelWithInterceptors( +std::shared_ptr CreateCustomChannelWithInterceptors( const grpc::string& target, - const std::shared_ptr& creds, - const ChannelArguments& args, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators) { return creds ? creds->CreateChannelWithInterceptors( target, args, std::move(interceptor_creators)) - : CreateChannelInternal( + : grpc::CreateChannelInternal( "", grpc_lame_client_channel_create( nullptr, GRPC_STATUS_INVALID_ARGUMENT, "Invalid credentials."), std::vector>()); + grpc::experimental::ClientInterceptorFactoryInterface>>()); } } // namespace experimental -} // namespace grpc +} // namespace grpc_impl From c02034eb96c29e27dccda249a6cc180e8f48668c Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 14 Mar 2019 19:17:14 -0700 Subject: [PATCH 1463/2143] 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 1464/2143] 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 1465/2143] 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 1466/2143] 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 2772f519e63ee42e2d151aa202f13e4b649ad673 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 14:28:32 -0700 Subject: [PATCH 1467/2143] Fix errors from presubmit scripts. --- include/grpcpp/create_channel.h | 9 +++++---- include/grpcpp/security/credentials.h | 9 ++++----- src/cpp/client/create_channel.cc | 9 ++++++--- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + tools/run_tests/generated/sources_and_headers.json | 2 ++ 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index 7d92716b773..6d444be9803 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -42,13 +42,14 @@ static inline std::shared_ptr CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args, - std::vector< + std::vector< std::unique_ptr> interceptor_creators) { - return ::grpc_impl::experimental::CreateCustomChannelWithInterceptors(target, creds, args, std::move(interceptor_creators)); + return ::grpc_impl::experimental::CreateCustomChannelWithInterceptors( + target, creds, args, std::move(interceptor_creators)); } -} // namespace experimental -} // namespace grpc +} // namespace experimental +} // namespace grpc #endif // GRPCPP_CREATE_CHANNEL_H diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index f17e295975a..f6a1c62b668 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -37,12 +37,12 @@ namespace grpc { class CallCredentials; class ChannelArguments; class ChannelCredentials; -} +} // namespace grpc namespace grpc_impl { std::shared_ptr CreateCustomChannel( - const grpc::string& target, - const std::shared_ptr& creds, - const grpc::ChannelArguments& args); + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args); namespace experimental { std::shared_ptr CreateCustomChannelWithInterceptors( @@ -59,7 +59,6 @@ class Channel; class SecureChannelCredentials; class SecureCallCredentials; - /// A channel credentials object encapsulates all the state needed by a client /// to authenticate with a server for a given channel. /// It can make various assertions, e.g., about the client’s identity, role diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 4a4298684cb..9426a4e7f6e 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -40,7 +40,8 @@ std::shared_ptr CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args) { - grpc::GrpcLibraryCodegen init_lib; // We need to call init in case of a bad creds. + grpc::GrpcLibraryCodegen + init_lib; // We need to call init in case of a bad creds. return creds ? creds->CreateChannel(target, args) : grpc::CreateChannelInternal( "", @@ -48,7 +49,8 @@ std::shared_ptr CreateCustomChannel( nullptr, GRPC_STATUS_INVALID_ARGUMENT, "Invalid credentials."), std::vector>()); + grpc::experimental:: + ClientInterceptorFactoryInterface>>()); } namespace experimental { @@ -78,7 +80,8 @@ std::shared_ptr CreateCustomChannelWithInterceptors( nullptr, GRPC_STATUS_INVALID_ARGUMENT, "Invalid credentials."), std::vector>()); + grpc::experimental:: + ClientInterceptorFactoryInterface>>()); } } // namespace experimental diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 9f17a25298a..a4f7803304d 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -930,6 +930,7 @@ include/grpcpp/channel.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ +include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c0078bf2764..cb10f98bbd5 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -931,6 +931,7 @@ include/grpcpp/channel.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ +include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 2d427804d07..cb1810da31a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11414,6 +11414,7 @@ "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", + "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", "include/grpcpp/ext/health_check_service_server_builder_option.h", "include/grpcpp/generic/async_generic_service.h", @@ -11523,6 +11524,7 @@ "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", + "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", "include/grpcpp/ext/health_check_service_server_builder_option.h", "include/grpcpp/generic/async_generic_service.h", From 84cb531b72cd7f355a493b4eaa460afb7defea0f Mon Sep 17 00:00:00 2001 From: Moses Koledoye Date: Fri, 15 Mar 2019 22:23:52 +0000 Subject: [PATCH 1468/2143] 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 1469/2143] 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 1470/2143] 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 5906b86119bf7f9234fe2b174c6bd897fc7cd8da Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 16:08:24 -0700 Subject: [PATCH 1471/2143] Fix tests to use grpc namespace --- 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 + 4 files changed, 1 insertion(+), 15 deletions(-) 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 From 48ce4ca939181b46e5893618711e391fe94828b9 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 14 Feb 2019 16:52:15 -0800 Subject: [PATCH 1472/2143] 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 0692dcc16aefa821fe96935836456a64e40986d9 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 16:33:11 -0700 Subject: [PATCH 1473/2143] Fix tests namespaces --- 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 - 4 files changed, 16 deletions(-) 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 8f20de7e714..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 From 2a8f3f79abcb5628991605b2c9a442e4ced18fea Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 17:08:58 -0700 Subject: [PATCH 1474/2143] Fix more namespace stuff --- test/cpp/microbenchmarks/bm_opencensus_plugin.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_opencensus_plugin.cc b/test/cpp/microbenchmarks/bm_opencensus_plugin.cc index d23c4f0573f..c3fa6f3031a 100644 --- a/test/cpp/microbenchmarks/bm_opencensus_plugin.cc +++ b/test/cpp/microbenchmarks/bm_opencensus_plugin.cc @@ -23,6 +23,7 @@ #include "absl/base/call_once.h" #include "absl/strings/str_cat.h" #include "include/grpc++/grpc++.h" +#include "include/grpcpp/opencensus.h" #include "opencensus/stats/stats.h" #include "src/cpp/ext/filters/census/grpc_plugin.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" @@ -30,7 +31,7 @@ absl::once_flag once; void RegisterOnce() { - absl::call_once(once, grpc_impl::RegisterOpenCensusPlugin); + absl::call_once(once, grpc::RegisterOpenCensusPlugin); } class EchoServer final : public grpc::testing::EchoTestService::Service { @@ -101,7 +102,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 4c3b577650590afcdcfd57e72b9b5faa67c6f7a8 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 15 Mar 2019 17:42:50 -0700 Subject: [PATCH 1475/2143] 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 1476/2143] 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 1477/2143] 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 c08e5bee404b46b37f9d3356b1ec8730371f7b0d Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Sun, 17 Mar 2019 22:15:21 -0700 Subject: [PATCH 1478/2143] Fix make errors --- include/grpcpp/security/credentials.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index f6a1c62b668..159a6f0c908 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -81,15 +81,15 @@ class ChannelCredentials : private GrpcLibraryCodegen { friend std::shared_ptr grpc_impl::CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, - const ChannelArguments& args); + const grpc::ChannelArguments& args); friend std::shared_ptr grpc_impl::experimental::CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, - const ChannelArguments& args, + const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators); virtual std::shared_ptr CreateChannel( From 472613c3bc71dafb1afd489bc10bea81837dd3c8 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 18 Mar 2019 14:20:31 +0100 Subject: [PATCH 1479/2143] 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 1480/2143] 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 1481/2143] 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 1482/2143] 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 1483/2143] 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 1061604a018ab706661f482ba9e6af44cc5cd34a Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 18 Mar 2019 10:06:10 -0700 Subject: [PATCH 1484/2143] Fix clang_format_code.sh errors --- include/grpcpp/security/credentials.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 159a6f0c908..34d2e2ea463 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -88,8 +88,8 @@ class ChannelCredentials : private GrpcLibraryCodegen { const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args, - std::vector< - std::unique_ptr> + std::vector> interceptor_creators); virtual std::shared_ptr CreateChannel( From 6c9951680e86d565b286130c7fa3ad5443140b37 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 18 Mar 2019 10:40:27 -0700 Subject: [PATCH 1485/2143] 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 1486/2143] 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 1487/2143] 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 1488/2143] 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 1489/2143] 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 1490/2143] 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 e9593285a81a7bbabb6f436467df1a2127b7c3c2 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 18 Mar 2019 13:20:42 -0700 Subject: [PATCH 1491/2143] Move LoadReportingServiceServerBuilderOption from grpc to grpc_impl --- BUILD | 1 + include/grpcpp/ext/server_load_reporting.h | 26 +++------ .../grpcpp/ext/server_load_reporting_impl.h | 53 +++++++++++++++++++ ...reporting_service_server_builder_option.cc | 6 +-- src/cpp/server/load_reporter/util.cc | 4 +- 5 files changed, 65 insertions(+), 25 deletions(-) create mode 100644 include/grpcpp/ext/server_load_reporting_impl.h diff --git a/BUILD b/BUILD index 835edbfb48f..ce448f1d2a8 100644 --- a/BUILD +++ b/BUILD @@ -1475,6 +1475,7 @@ grpc_cc_library( language = "c++", public_hdrs = [ "include/grpcpp/ext/server_load_reporting.h", + "include/grpcpp/ext/server_load_reporting_impl.h", ], deps = [ "lb_server_load_reporting_filter", diff --git a/include/grpcpp/ext/server_load_reporting.h b/include/grpcpp/ext/server_load_reporting.h index 939569c19aa..462c995b263 100644 --- a/include/grpcpp/ext/server_load_reporting.h +++ b/include/grpcpp/ext/server_load_reporting.h @@ -19,32 +19,18 @@ #ifndef GRPCPP_EXT_SERVER_LOAD_REPORTING_H #define GRPCPP_EXT_SERVER_LOAD_REPORTING_H -#include - -#include -#include -#include -#include +#include namespace grpc { namespace load_reporter { namespace experimental { -// The ServerBuilderOption to enable server-side load reporting feature. To -// enable the feature, please make sure the binary builds with the -// grpcpp_server_load_reporting library and set this option in the -// ServerBuilder. -class LoadReportingServiceServerBuilderOption : public ServerBuilderOption { - public: - void UpdateArguments(::grpc::ChannelArguments* args) override; - void UpdatePlugins(std::vector>* - plugins) override; -}; +typedef ::grpc_impl::load_reporter::experimental::LoadReportingServiceServerBuilderOption LoadReportingServiceServerBuilderOption; -// Adds the load reporting cost with \a cost_name and \a cost_value in the -// trailing metadata of the server context. -void AddLoadReportingCost(grpc::ServerContext* ctx, - const grpc::string& cost_name, double cost_value); +static inline void AddLoadReportingCost(grpc::ServerContext* ctx, + const grpc::string& cost_name, double cost_value) { + ::grpc_impl::load_reporter::experimental::AddLoadReportingCost(ctx, cost_name, cost_value); +} } // namespace experimental } // namespace load_reporter diff --git a/include/grpcpp/ext/server_load_reporting_impl.h b/include/grpcpp/ext/server_load_reporting_impl.h new file mode 100644 index 00000000000..20343a56f33 --- /dev/null +++ b/include/grpcpp/ext/server_load_reporting_impl.h @@ -0,0 +1,53 @@ +/* + * + * 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 GRPCPP_EXT_SERVER_LOAD_REPORTING_IMPL_H +#define GRPCPP_EXT_SERVER_LOAD_REPORTING_IMPL_H + +#include + +#include +#include +#include +#include + +namespace grpc_impl { +namespace load_reporter { +namespace experimental { + +// The ServerBuilderOption to enable server-side load reporting feature. To +// enable the feature, please make sure the binary builds with the +// grpcpp_server_load_reporting library and set this option in the +// ServerBuilder. +class LoadReportingServiceServerBuilderOption : public grpc::ServerBuilderOption { + public: + void UpdateArguments(::grpc::ChannelArguments* args) override; + void UpdatePlugins(std::vector>* + plugins) override; +}; + +// Adds the load reporting cost with \a cost_name and \a cost_value in the +// trailing metadata of the server context. +void AddLoadReportingCost(grpc::ServerContext* ctx, + const grpc::string& cost_name, double cost_value); + +} // namespace experimental +} // namespace load_reporter +} // namespace grpc + +#endif // GRPCPP_EXT_SERVER_LOAD_REPORTING_IMPL_H diff --git a/src/cpp/server/load_reporter/load_reporting_service_server_builder_option.cc b/src/cpp/server/load_reporter/load_reporting_service_server_builder_option.cc index 81cf6ac562d..320b1c9b5f9 100644 --- a/src/cpp/server/load_reporter/load_reporting_service_server_builder_option.cc +++ b/src/cpp/server/load_reporter/load_reporting_service_server_builder_option.cc @@ -22,7 +22,7 @@ #include "src/cpp/server/load_reporter/load_reporting_service_server_builder_plugin.h" -namespace grpc { +namespace grpc_impl { namespace load_reporter { namespace experimental { @@ -33,9 +33,9 @@ void LoadReportingServiceServerBuilderOption::UpdateArguments( void LoadReportingServiceServerBuilderOption::UpdatePlugins( std::vector>* plugins) { - plugins->emplace_back(new LoadReportingServiceServerBuilderPlugin()); + plugins->emplace_back(new grpc::load_reporter::LoadReportingServiceServerBuilderPlugin()); } } // namespace experimental } // namespace load_reporter -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/load_reporter/util.cc b/src/cpp/server/load_reporter/util.cc index 89bdf57049c..b69705a6994 100644 --- a/src/cpp/server/load_reporter/util.cc +++ b/src/cpp/server/load_reporter/util.cc @@ -24,7 +24,7 @@ #include -namespace grpc { +namespace grpc_impl { namespace load_reporter { namespace experimental { @@ -44,4 +44,4 @@ void AddLoadReportingCost(grpc::ServerContext* ctx, } // namespace experimental } // namespace load_reporter -} // namespace grpc +} // namespace grpc_impl From 233d3e27ff0f7fe1cc8ad5a3e9c271123e4f0bc3 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 18 Mar 2019 11:45:14 -0700 Subject: [PATCH 1492/2143] 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 1493/2143] 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 1494/2143] 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 1495/2143] 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 1496/2143] 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 1497/2143] 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 1498/2143] 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 1499/2143] 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 1500/2143] 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 1501/2143] 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 1502/2143] 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 1503/2143] 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 1504/2143] 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 1d357572cf1d33d6529ff74bbaf84aafc9cc2ed7 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 19 Mar 2019 10:43:02 -0700 Subject: [PATCH 1505/2143] Revert "Moving ::grpc::ResourceQuota to ::grpc_impl::ResouceQuota" This reverts commit d8d8bec7c8a254b1f8bc152b71b0b1c2b41bfe3f. --- 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 | 2 +- src/cpp/server/server_builder.cc | 7 +-- test/cpp/qps/server_async.cc | 1 + 13 files changed, 52 insertions(+), 102 deletions(-) delete mode 100644 include/grpcpp/resource_quota_impl.h diff --git a/BUILD b/BUILD index 9070a66c978..d80ffd9d459 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 614fd2efca1..0030c9eb9af 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 @@ -4565,7 +4563,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 7ad32e1291f..5a31d648b32 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 82e652878bd..d8322b176b7 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..1ed92d7396d 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)) {} 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/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 From f58aed2d060440c17adeadbdd24632461730e5ed Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 19 Mar 2019 10:50:53 -0700 Subject: [PATCH 1506/2143] Make changes to server_posix to expose method outside --- include/grpcpp/server_posix.h | 12 ++++++++++++ src/cpp/common/resource_quota_cc.cc | 2 +- src/cpp/server/server_posix.cc | 6 +++--- tools/doxygen/Doxyfile.c++ | 1 - tools/doxygen/Doxyfile.c++.internal | 1 - tools/run_tests/generated/sources_and_headers.json | 2 -- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/include/grpcpp/server_posix.h b/include/grpcpp/server_posix.h index 7b46967a8ba..3d209cbc14f 100644 --- a/include/grpcpp/server_posix.h +++ b/include/grpcpp/server_posix.h @@ -21,4 +21,16 @@ #include +namespace grpc { + +#ifdef GPR_SUPPORT_CHANNELS_FROM_FD + +static inline void AddInsecureChannelFromFd(Server* server, int fd) { + ::grpc_impl::AddInsecureChannelFromFd(server, fd); +} + +#endif // GPR_SUPPORT_CHANNELS_FROM_FD + +} // namespace grpc + #endif // GRPCPP_SERVER_POSIX_H diff --git a/src/cpp/common/resource_quota_cc.cc b/src/cpp/common/resource_quota_cc.cc index 1ed92d7396d..276e5f79548 100644 --- a/src/cpp/common/resource_quota_cc.cc +++ b/src/cpp/common/resource_quota_cc.cc @@ -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_posix.cc b/src/cpp/server/server_posix.cc index 7c221ed036a..7b77e24bc0e 100644 --- a/src/cpp/server/server_posix.cc +++ b/src/cpp/server/server_posix.cc @@ -20,14 +20,14 @@ #include -namespace grpc { +namespace grpc_impl { #ifdef GPR_SUPPORT_CHANNELS_FROM_FD -void AddInsecureChannelFromFd(Server* server, int fd) { +void AddInsecureChannelFromFd(grpc::Server* server, int fd) { grpc_server_add_insecure_channel_from_fd(server->c_server(), nullptr, fd); } #endif // GPR_SUPPORT_CHANNELS_FROM_FD -} // namespace grpc +} // namespace grpc_impl 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 bcf2cf4f5ec..8adde9ec602 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11411,7 +11411,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", @@ -11521,7 +11520,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 271807df79b2f2dc7c7b6d18367f52fb6d906d78 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Tue, 19 Mar 2019 11:16:24 -0700 Subject: [PATCH 1507/2143] 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 1508/2143] 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 526bf39f89322012b9da7d93de09c4b8ca7dfa7e Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 19 Mar 2019 12:27:22 -0700 Subject: [PATCH 1509/2143] Fold GenericStub from grpc_impl to grpc --- BUILD | 1 + CMakeLists.txt | 3 + Makefile | 3 + build.yaml | 1 + gRPC-C++.podspec | 1 + include/grpcpp/generic/generic_stub.h | 73 +------------ include/grpcpp/generic/generic_stub_impl.h | 103 ++++++++++++++++++ src/cpp/client/generic_stub.cc | 82 ++++++++------ tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + .../generated/sources_and_headers.json | 2 + 11 files changed, 165 insertions(+), 106 deletions(-) create mode 100644 include/grpcpp/generic/generic_stub_impl.h diff --git a/BUILD b/BUILD index 9e052dcf0c2..1cc84247ab7 100644 --- a/BUILD +++ b/BUILD @@ -223,6 +223,7 @@ GRPCXX_PUBLIC_HDRS = [ "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/generic/generic_stub_impl.h", "include/grpcpp/grpcpp.h", "include/grpcpp/health_check_service_interface.h", "include/grpcpp/impl/call.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 2308582c2f4..545d3b01e66 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3003,6 +3003,7 @@ foreach(_hdr 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/generic/generic_stub_impl.h include/grpcpp/grpcpp.h include/grpcpp/health_check_service_interface.h include/grpcpp/impl/call.h @@ -3593,6 +3594,7 @@ foreach(_hdr 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/generic/generic_stub_impl.h include/grpcpp/grpcpp.h include/grpcpp/health_check_service_interface.h include/grpcpp/impl/call.h @@ -4552,6 +4554,7 @@ foreach(_hdr 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/generic/generic_stub_impl.h include/grpcpp/grpcpp.h include/grpcpp/health_check_service_interface.h include/grpcpp/impl/call.h diff --git a/Makefile b/Makefile index 69a2abbc8ca..d5ca0a7f546 100644 --- a/Makefile +++ b/Makefile @@ -5428,6 +5428,7 @@ PUBLIC_HEADERS_CXX += \ 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/generic/generic_stub_impl.h \ include/grpcpp/grpcpp.h \ include/grpcpp/health_check_service_interface.h \ include/grpcpp/impl/call.h \ @@ -6027,6 +6028,7 @@ PUBLIC_HEADERS_CXX += \ 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/generic/generic_stub_impl.h \ include/grpcpp/grpcpp.h \ include/grpcpp/health_check_service_interface.h \ include/grpcpp/impl/call.h \ @@ -6939,6 +6941,7 @@ PUBLIC_HEADERS_CXX += \ 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/generic/generic_stub_impl.h \ include/grpcpp/grpcpp.h \ include/grpcpp/health_check_service_interface.h \ include/grpcpp/impl/call.h \ diff --git a/build.yaml b/build.yaml index 34b271f58de..d81dbd3fc51 100644 --- a/build.yaml +++ b/build.yaml @@ -1348,6 +1348,7 @@ filegroups: - 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/generic/generic_stub_impl.h - include/grpcpp/grpcpp.h - include/grpcpp/health_check_service_interface.h - include/grpcpp/impl/call.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 5a850bc8438..0aee981b5f9 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -89,6 +89,7 @@ Pod::Spec.new do |s| '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/generic/generic_stub_impl.h', 'include/grpcpp/grpcpp.h', 'include/grpcpp/health_check_service_interface.h', 'include/grpcpp/impl/call.h', diff --git a/include/grpcpp/generic/generic_stub.h b/include/grpcpp/generic/generic_stub.h index eb014184e4a..f4c4664f53c 100644 --- a/include/grpcpp/generic/generic_stub.h +++ b/include/grpcpp/generic/generic_stub.h @@ -19,80 +19,11 @@ #ifndef GRPCPP_GENERIC_GENERIC_STUB_H #define GRPCPP_GENERIC_GENERIC_STUB_H -#include - -#include -#include -#include -#include -#include +#include namespace grpc { -class CompletionQueue; -typedef ClientAsyncReaderWriter - GenericClientAsyncReaderWriter; -typedef ClientAsyncResponseReader GenericClientAsyncResponseReader; - -/// Generic stubs provide a type-unsafe interface to call gRPC methods -/// by name. -class GenericStub final { - public: - explicit GenericStub(std::shared_ptr channel) - : channel_(channel) {} - - /// Setup a call to a named method \a method using \a context, but don't - /// start it. Let it be started explicitly with StartCall and a tag. - /// The return value only indicates whether or not registration of the call - /// succeeded (i.e. the call won't proceed if the return value is nullptr). - std::unique_ptr PrepareCall( - ClientContext* context, const grpc::string& method, CompletionQueue* cq); - - /// Setup a unary call to a named method \a method using \a context, and don't - /// start it. Let it be started explicitly with StartCall. - /// The return value only indicates whether or not registration of the call - /// succeeded (i.e. the call won't proceed if the return value is nullptr). - std::unique_ptr PrepareUnaryCall( - ClientContext* context, const grpc::string& method, - const ByteBuffer& request, CompletionQueue* cq); - - /// DEPRECATED for multi-threaded use - /// Begin a call to a named method \a method using \a context. - /// A tag \a tag will be delivered to \a cq when the call has been started - /// (i.e, initial metadata has been sent). - /// The return value only indicates whether or not registration of the call - /// succeeded (i.e. the call won't proceed if the return value is nullptr). - std::unique_ptr Call( - ClientContext* context, const grpc::string& method, CompletionQueue* cq, - void* tag); - - /// NOTE: class experimental_type is not part of the public API of this class - /// TODO(vjpai): Move these contents to the public API of GenericStub when - /// they are no longer experimental - class experimental_type { - public: - explicit experimental_type(GenericStub* stub) : stub_(stub) {} - - void UnaryCall(ClientContext* context, const grpc::string& method, - const ByteBuffer* request, ByteBuffer* response, - std::function on_completion); - - void PrepareBidiStreamingCall( - ClientContext* context, const grpc::string& method, - experimental::ClientBidiReactor* reactor); - - private: - GenericStub* stub_; - }; - - /// 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); } - - private: - std::shared_ptr channel_; -}; +typedef ::grpc_impl::GenericStub GenericStub; } // namespace grpc diff --git a/include/grpcpp/generic/generic_stub_impl.h b/include/grpcpp/generic/generic_stub_impl.h new file mode 100644 index 00000000000..5c8a8798969 --- /dev/null +++ b/include/grpcpp/generic/generic_stub_impl.h @@ -0,0 +1,103 @@ +/* + * + * 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_GENERIC_GENERIC_STUB_IMPL_H +#define GRPCPP_GENERIC_GENERIC_STUB_IMPL_H + +#include + +#include +#include +#include +#include +#include + +namespace grpc { + +class CompletionQueue; +typedef ClientAsyncReaderWriter + GenericClientAsyncReaderWriter; +typedef ClientAsyncResponseReader GenericClientAsyncResponseReader; +} // namespace grpc +namespace grpc_impl { + +/// Generic stubs provide a type-unsafe interface to call gRPC methods +/// by name. +class GenericStub final { + public: + explicit GenericStub(std::shared_ptr channel) + : channel_(channel) {} + + /// Setup a call to a named method \a method using \a context, but don't + /// start it. Let it be started explicitly with StartCall and a tag. + /// The return value only indicates whether or not registration of the call + /// succeeded (i.e. the call won't proceed if the return value is nullptr). + std::unique_ptr PrepareCall( + grpc::ClientContext* context, const grpc::string& method, + grpc::CompletionQueue* cq); + + /// Setup a unary call to a named method \a method using \a context, and don't + /// start it. Let it be started explicitly with StartCall. + /// The return value only indicates whether or not registration of the call + /// succeeded (i.e. the call won't proceed if the return value is nullptr). + std::unique_ptr PrepareUnaryCall( + grpc::ClientContext* context, const grpc::string& method, + const grpc::ByteBuffer& request, grpc::CompletionQueue* cq); + + /// DEPRECATED for multi-threaded use + /// Begin a call to a named method \a method using \a context. + /// A tag \a tag will be delivered to \a cq when the call has been started + /// (i.e, initial metadata has been sent). + /// The return value only indicates whether or not registration of the call + /// succeeded (i.e. the call won't proceed if the return value is nullptr). + std::unique_ptr Call( + grpc::ClientContext* context, const grpc::string& method, + grpc::CompletionQueue* cq, void* tag); + + /// NOTE: class experimental_type is not part of the public API of this class + /// TODO(vjpai): Move these contents to the public API of GenericStub when + /// they are no longer experimental + class experimental_type { + public: + explicit experimental_type(GenericStub* stub) : stub_(stub) {} + + void UnaryCall(grpc::ClientContext* context, const grpc::string& method, + const grpc::ByteBuffer* request, grpc::ByteBuffer* response, + std::function on_completion); + + void PrepareBidiStreamingCall( + grpc::ClientContext* context, const grpc::string& method, + grpc::experimental::ClientBidiReactor* reactor); + + private: + GenericStub* stub_; + }; + + /// 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); } + + private: + std::shared_ptr channel_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_GENERIC_GENERIC_STUB_IMPL_H diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc index f61c1b5317b..41631c794f2 100644 --- a/src/cpp/client/generic_stub.cc +++ b/src/cpp/client/generic_stub.cc @@ -22,63 +22,75 @@ #include #include -namespace grpc { +namespace grpc_impl { namespace { -std::unique_ptr CallInternal( - ChannelInterface* channel, ClientContext* context, - const grpc::string& method, CompletionQueue* cq, bool start, void* tag) { - return std::unique_ptr( - internal::ClientAsyncReaderWriterFactory::Create( - channel, cq, - internal::RpcMethod(method.c_str(), - internal::RpcMethod::BIDI_STREAMING), - context, start, tag)); +std::unique_ptr CallInternal( + grpc::ChannelInterface* channel, grpc::ClientContext* context, + const grpc::string& method, grpc::CompletionQueue* cq, bool start, + void* tag) { + return std::unique_ptr( + grpc::internal::ClientAsyncReaderWriterFactory:: + Create(channel, cq, + grpc::internal::RpcMethod( + method.c_str(), grpc::internal::RpcMethod::BIDI_STREAMING), + context, start, tag)); } } // namespace // begin a call to a named method -std::unique_ptr GenericStub::Call( - ClientContext* context, const grpc::string& method, CompletionQueue* cq, - void* tag) { +std::unique_ptr GenericStub::Call( + grpc::ClientContext* context, const grpc::string& method, + grpc::CompletionQueue* cq, void* tag) { return CallInternal(channel_.get(), context, method, cq, true, tag); } // setup a call to a named method -std::unique_ptr GenericStub::PrepareCall( - ClientContext* context, const grpc::string& method, CompletionQueue* cq) { +std::unique_ptr GenericStub::PrepareCall( + grpc::ClientContext* context, const grpc::string& method, + grpc::CompletionQueue* cq) { return CallInternal(channel_.get(), context, method, cq, false, nullptr); } // setup a unary call to a named method -std::unique_ptr GenericStub::PrepareUnaryCall( - ClientContext* context, const grpc::string& method, - const ByteBuffer& request, CompletionQueue* cq) { - return std::unique_ptr( - internal::ClientAsyncResponseReaderFactory::Create( - channel_.get(), cq, - internal::RpcMethod(method.c_str(), internal::RpcMethod::NORMAL_RPC), - context, request, false)); +std::unique_ptr +GenericStub::PrepareUnaryCall(grpc::ClientContext* context, + const grpc::string& method, + const grpc::ByteBuffer& request, + grpc::CompletionQueue* cq) { + return std::unique_ptr( + grpc::internal::ClientAsyncResponseReaderFactory< + grpc::ByteBuffer>::Create(channel_.get(), cq, + grpc::internal::RpcMethod( + method.c_str(), + grpc::internal::RpcMethod::NORMAL_RPC), + context, request, false)); } void GenericStub::experimental_type::UnaryCall( - ClientContext* context, const grpc::string& method, - const ByteBuffer* request, ByteBuffer* response, - std::function on_completion) { - internal::CallbackUnaryCall( + grpc::ClientContext* context, const grpc::string& method, + const grpc::ByteBuffer* request, grpc::ByteBuffer* response, + std::function on_completion) { + grpc::internal::CallbackUnaryCall( stub_->channel_.get(), - internal::RpcMethod(method.c_str(), internal::RpcMethod::NORMAL_RPC), + grpc::internal::RpcMethod(method.c_str(), + grpc::internal::RpcMethod::NORMAL_RPC), context, request, response, std::move(on_completion)); } void GenericStub::experimental_type::PrepareBidiStreamingCall( - ClientContext* context, const grpc::string& method, - experimental::ClientBidiReactor* reactor) { - internal::ClientCallbackReaderWriterFactory::Create( - stub_->channel_.get(), - internal::RpcMethod(method.c_str(), internal::RpcMethod::BIDI_STREAMING), - context, reactor); + grpc::ClientContext* context, const grpc::string& method, + grpc::experimental::ClientBidiReactor* + reactor) { + grpc::internal::ClientCallbackReaderWriterFactory< + grpc::ByteBuffer, + grpc::ByteBuffer>::Create(stub_->channel_.get(), + grpc::internal::RpcMethod( + method.c_str(), + grpc::internal::RpcMethod::BIDI_STREAMING), + context, reactor); } -} // namespace grpc +} // namespace grpc_impl diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 9f17a25298a..fd6e35aa6ff 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -934,6 +934,7 @@ 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/generic/generic_stub_impl.h \ include/grpcpp/grpcpp.h \ include/grpcpp/health_check_service_interface.h \ include/grpcpp/impl/call.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c0078bf2764..ee01a0b0295 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -935,6 +935,7 @@ 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/generic/generic_stub_impl.h \ include/grpcpp/grpcpp.h \ include/grpcpp/health_check_service_interface.h \ include/grpcpp/impl/call.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 2d427804d07..9d3172f5dcf 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11418,6 +11418,7 @@ "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/generic/generic_stub_impl.h", "include/grpcpp/grpcpp.h", "include/grpcpp/health_check_service_interface.h", "include/grpcpp/impl/call.h", @@ -11527,6 +11528,7 @@ "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/generic/generic_stub_impl.h", "include/grpcpp/grpcpp.h", "include/grpcpp/health_check_service_interface.h", "include/grpcpp/impl/call.h", From d684ddc7e3091b8b5205b0cadbd786bd5f37487d Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 19 Mar 2019 12:49:42 -0700 Subject: [PATCH 1510/2143] Fold AuthMetadataProcessor into grpc_impl from grpc --- BUILD | 1 + build.yaml | 1 + .../grpcpp/security/auth_metadata_processor.h | 37 +---------- .../security/auth_metadata_processor_impl.h | 61 +++++++++++++++++++ 4 files changed, 66 insertions(+), 34 deletions(-) create mode 100644 include/grpcpp/security/auth_metadata_processor_impl.h diff --git a/BUILD b/BUILD index 9e052dcf0c2..21691b19c31 100644 --- a/BUILD +++ b/BUILD @@ -243,6 +243,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/resource_quota.h", "include/grpcpp/security/auth_context.h", "include/grpcpp/security/auth_metadata_processor.h", + "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", "include/grpcpp/security/server_credentials.h", "include/grpcpp/server.h", diff --git a/build.yaml b/build.yaml index 34b271f58de..23736cddf31 100644 --- a/build.yaml +++ b/build.yaml @@ -1366,6 +1366,7 @@ filegroups: - include/grpcpp/resource_quota.h - include/grpcpp/security/auth_context.h - include/grpcpp/security/auth_metadata_processor.h + - include/grpcpp/security/auth_metadata_processor_impl.h - include/grpcpp/security/credentials.h - include/grpcpp/security/server_credentials.h - include/grpcpp/server.h diff --git a/include/grpcpp/security/auth_metadata_processor.h b/include/grpcpp/security/auth_metadata_processor.h index 30e24c9f0bc..1b66b72b967 100644 --- a/include/grpcpp/security/auth_metadata_processor.h +++ b/include/grpcpp/security/auth_metadata_processor.h @@ -1,6 +1,6 @@ /* * - * 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. @@ -19,42 +19,11 @@ #ifndef GRPCPP_SECURITY_AUTH_METADATA_PROCESSOR_H #define GRPCPP_SECURITY_AUTH_METADATA_PROCESSOR_H -#include - -#include -#include -#include +#include namespace grpc { -/// Interface allowing custom server-side authorization based on credentials -/// encoded in metadata. Objects of this type can be passed to -/// \a ServerCredentials::SetAuthMetadataProcessor(). -class AuthMetadataProcessor { - public: - typedef std::multimap InputMetadata; - typedef std::multimap OutputMetadata; - - virtual ~AuthMetadataProcessor() {} - - /// If this method returns true, the \a Process function will be scheduled in - /// a different thread from the one processing the call. - virtual bool IsBlocking() const { return true; } - - /// context is read/write: it contains the properties of the channel peer and - /// it is the job of the Process method to augment it with properties derived - /// from the passed-in auth_metadata. - /// consumed_auth_metadata needs to be filled with metadata that has been - /// consumed by the processor and will be removed from the call. - /// response_metadata is the metadata that will be sent as part of the - /// response. - /// If the return value is not Status::OK, the rpc call will be aborted with - /// the error code and error message sent back to the client. - virtual Status Process(const InputMetadata& auth_metadata, - AuthContext* context, - OutputMetadata* consumed_auth_metadata, - OutputMetadata* response_metadata) = 0; -}; +typedef ::grpc_impl::AuthMetadataProcessor AuthMetadataProcessor; } // namespace grpc diff --git a/include/grpcpp/security/auth_metadata_processor_impl.h b/include/grpcpp/security/auth_metadata_processor_impl.h new file mode 100644 index 00000000000..ae454200622 --- /dev/null +++ b/include/grpcpp/security/auth_metadata_processor_impl.h @@ -0,0 +1,61 @@ +/* + * + * 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_SECURITY_AUTH_METADATA_PROCESSOR_IMPL_H +#define GRPCPP_SECURITY_AUTH_METADATA_PROCESSOR_IMPL_H + +#include + +#include +#include +#include + +namespace grpc_impl { + +/// Interface allowing custom server-side authorization based on credentials +/// encoded in metadata. Objects of this type can be passed to +/// \a ServerCredentials::SetAuthMetadataProcessor(). +class AuthMetadataProcessor { + public: + typedef std::multimap InputMetadata; + typedef std::multimap OutputMetadata; + + virtual ~AuthMetadataProcessor() {} + + /// If this method returns true, the \a Process function will be scheduled in + /// a different thread from the one processing the call. + virtual bool IsBlocking() const { return true; } + + /// context is read/write: it contains the properties of the channel peer and + /// it is the job of the Process method to augment it with properties derived + /// from the passed-in auth_metadata. + /// consumed_auth_metadata needs to be filled with metadata that has been + /// consumed by the processor and will be removed from the call. + /// response_metadata is the metadata that will be sent as part of the + /// response. + /// If the return value is not Status::OK, the rpc call will be aborted with + /// the error code and error message sent back to the client. + virtual grpc::Status Process(const InputMetadata& auth_metadata, + grpc::AuthContext* context, + OutputMetadata* consumed_auth_metadata, + OutputMetadata* response_metadata) = 0; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_SECURITY_AUTH_METADATA_PROCESSOR_IMPL_H From 1dbaf5f4df2d31012ae8cac5dcfb08655f61866a Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 19 Mar 2019 14:13:05 -0700 Subject: [PATCH 1511/2143] 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 1512/2143] 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 1513/2143] 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 1514/2143] 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 1515/2143] 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 9c7a0c01ed6158535ae7d05c9ad4a13b6bfe1b9a Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 20 Mar 2019 05:15:25 +0100 Subject: [PATCH 1516/2143] Taking care of a last few memsets. --- .../health/health_check_client.cc | 4 --- .../google_default_credentials.cc | 1 - src/core/lib/transport/transport.cc | 1 - src/core/lib/transport/transport.h | 33 ++++++++++--------- 4 files changed, 17 insertions(+), 22 deletions(-) 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..84a7f35ed30 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 @@ -349,7 +349,6 @@ void HealthCheckClient::CallState::StartCall() { return; } // Initialize payload and batch. - memset(&batch_, 0, sizeof(batch_)); payload_.context = context_; batch_.payload = &payload_; // on_complete callback takes ref, handled manually. @@ -401,8 +400,6 @@ void HealthCheckClient::CallState::StartCall() { // Start batch. StartBatch(&batch_); // Initialize recv_trailing_metadata batch. - memset(&recv_trailing_metadata_batch_, 0, - sizeof(recv_trailing_metadata_batch_)); recv_trailing_metadata_batch_.payload = &payload_; // Add recv_trailing_metadata op. grpc_metadata_batch_init(&recv_trailing_metadata_); @@ -507,7 +504,6 @@ void HealthCheckClient::CallState::DoneReadingRecvMessage(grpc_error* error) { // This re-uses the ref we're holding. // Note: Can't just reuse batch_ here, since we don't know that all // callbacks from the original batch have completed yet. - memset(&recv_message_batch_, 0, sizeof(recv_message_batch_)); recv_message_batch_.payload = &payload_; payload_.recv_message.recv_message = &recv_message_; payload_.recv_message.recv_message_ready = GRPC_CLOSURE_INIT( 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 b6a79c1030e..adc76cb1740 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 @@ -172,7 +172,6 @@ static int is_metadata_server_reachable() { detector.pollent = grpc_polling_entity_create_from_pollset(pollset); detector.is_done = 0; detector.success = 0; - memset(&detector.response, 0, sizeof(detector.response)); memset(&request, 0, sizeof(grpc_httpcli_request)); request.host = (char*)GRPC_COMPUTE_ENGINE_DETECTION_HOST; request.http.path = (char*)"/"; diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index 8be0b91b654..3fc089676ea 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -261,7 +261,6 @@ grpc_transport_op* grpc_make_transport_op(grpc_closure* on_complete) { GRPC_CLOSURE_INIT(&op->outer_on_complete, destroy_made_transport_op, op, grpc_schedule_on_exec_ctx); op->inner_on_complete = on_complete; - memset(&op->op, 0, sizeof(op->op)); op->op.on_consumed = &op->outer_on_complete; return &op->op; } diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 5ce568834e9..8631a1af81f 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; @@ -272,40 +273,40 @@ struct grpc_transport_stream_op_batch_payload { /** Transport op: a set of operations to perform on a transport as a whole */ typedef struct grpc_transport_op { /** Called when processing of this op is done. */ - grpc_closure* on_consumed; + grpc_closure* on_consumed = nullptr; /** connectivity monitoring - set connectivity_state to NULL to unsubscribe */ - grpc_closure* on_connectivity_state_change; - grpc_connectivity_state* connectivity_state; + grpc_closure* on_connectivity_state_change = nullptr; + grpc_connectivity_state* connectivity_state = nullptr; /** should the transport be disconnected * Error contract: the transport that gets this op must cause * disconnect_with_error to be unref'ed after processing it */ - grpc_error* disconnect_with_error; + grpc_error* disconnect_with_error = nullptr; /** what should the goaway contain? * Error contract: the transport that gets this op must cause * goaway_error to be unref'ed after processing it */ - grpc_error* goaway_error; + grpc_error* goaway_error = nullptr; /** set the callback for accepting new streams; this is a permanent callback, unlike the other one-shot closures. If true, the callback is set to set_accept_stream_fn, with its user_data argument set to set_accept_stream_user_data */ - bool set_accept_stream; + bool set_accept_stream = false; void (*set_accept_stream_fn)(void* user_data, grpc_transport* transport, - const void* server_data); - void* set_accept_stream_user_data; + const void* server_data) = nullptr; + void* set_accept_stream_user_data = nullptr; /** add this transport to a pollset */ - grpc_pollset* bind_pollset; + grpc_pollset* bind_pollset = nullptr; /** add this transport to a pollset_set */ - grpc_pollset_set* bind_pollset_set; + grpc_pollset_set* bind_pollset_set = nullptr; /** send a ping, if either on_initiate or on_ack is not NULL */ struct { /** Ping may be delayed by the transport, on_initiate callback will be called when the ping is actually being sent. */ - grpc_closure* on_initiate; + grpc_closure* on_initiate = nullptr; /** Called when the ping ack is received */ - grpc_closure* on_ack; + grpc_closure* on_ack = nullptr; } send_ping; // If true, will reset the channel's connection backoff. - bool reset_connect_backoff; + bool reset_connect_backoff = false; /*************************************************************************** * remaining fields are initialized and used at the discretion of the From e6cae04e5f77f2f5f113fc9cc6a5e7b09ede644e Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 20 Mar 2019 10:44:07 -0400 Subject: [PATCH 1517/2143] 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 54171e276fc74286cba80ae18021bc414d4caf61 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 20 Mar 2019 10:00:34 -0700 Subject: [PATCH 1518/2143] Fold server credentials from grpc to grpc_impl namespace --- BUILD | 1 + .../grpcpp/impl/codegen/server_interface.h | 7 +- include/grpcpp/security/server_credentials.h | 92 ++++----------- .../grpcpp/security/server_credentials_impl.h | 110 ++++++++++++++++++ include/grpcpp/server_builder.h | 11 +- src/cpp/server/insecure_server_credentials.cc | 6 +- src/cpp/server/secure_server_credentials.cc | 14 ++- src/cpp/server/secure_server_credentials.h | 19 ++- src/cpp/server/server_credentials.cc | 4 +- test/cpp/util/grpc_tool_test.cc | 2 +- test/cpp/util/test_credentials_provider.cc | 2 +- 11 files changed, 175 insertions(+), 93 deletions(-) create mode 100644 include/grpcpp/security/server_credentials_impl.h diff --git a/BUILD b/BUILD index 9e052dcf0c2..e0b8060cca1 100644 --- a/BUILD +++ b/BUILD @@ -245,6 +245,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/credentials.h", "include/grpcpp/security/server_credentials.h", + "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", "include/grpcpp/server_builder.h", "include/grpcpp/server_context.h", diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index f599e037fd5..a0b0a580979 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -28,6 +28,10 @@ #include #include +namespace grpc_impl { + +class ServerCredentials; +} namespace grpc { class AsyncGenericService; @@ -35,7 +39,6 @@ class Channel; class GenericServerContext; class ServerCompletionQueue; class ServerContext; -class ServerCredentials; class Service; extern CoreCodegenInterface* g_core_codegen_interface; @@ -150,7 +153,7 @@ class ServerInterface : public internal::CallHook { /// /// \warning It's an error to call this method on an already started server. virtual int AddListeningPort(const grpc::string& addr, - ServerCredentials* creds) = 0; + grpc_impl::ServerCredentials* creds) = 0; /// Start the server. /// diff --git a/include/grpcpp/security/server_credentials.h b/include/grpcpp/security/server_credentials.h index bd00a0a1737..f1318b6fb0d 100644 --- a/include/grpcpp/security/server_credentials.h +++ b/include/grpcpp/security/server_credentials.h @@ -1,6 +1,6 @@ /* * - * 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. @@ -19,87 +19,35 @@ #ifndef GRPCPP_SECURITY_SERVER_CREDENTIALS_H #define GRPCPP_SECURITY_SERVER_CREDENTIALS_H -#include -#include - -#include -#include -#include - -struct grpc_server; +#include namespace grpc { -class Server; -/// Wrapper around \a grpc_server_credentials, a way to authenticate a server. -class ServerCredentials { - public: - virtual ~ServerCredentials(); +typedef ::grpc_impl::ServerCredentials ServerCredentials; +typedef ::grpc_impl::SslServerCredentialsOptions SslServerCredentialsOptions; - /// This method is not thread-safe and has to be called before the server is - /// started. The last call to this function wins. - virtual void SetAuthMetadataProcessor( - const std::shared_ptr& processor) = 0; +static inline std::shared_ptr SslServerCredentials( + const SslServerCredentialsOptions& options) { + return ::grpc_impl::SslServerCredentials(options); +} - private: - friend class ::grpc::Server; - - /// Tries to bind \a server to the given \a addr (eg, localhost:1234, - /// 192.168.1.1:31416, [::1]:27182, etc.) - /// - /// \return bound port number on sucess, 0 on failure. - // TODO(dgq): the "port" part seems to be a misnomer. - virtual int AddPortToServer(const grpc::string& addr, - grpc_server* server) = 0; -}; - -/// Options to create ServerCredentials with SSL -struct SslServerCredentialsOptions { - /// \warning Deprecated - SslServerCredentialsOptions() - : force_client_auth(false), - client_certificate_request(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE) {} - SslServerCredentialsOptions( - grpc_ssl_client_certificate_request_type request_type) - : force_client_auth(false), client_certificate_request(request_type) {} - - struct PemKeyCertPair { - grpc::string private_key; - grpc::string cert_chain; - }; - grpc::string pem_root_certs; - std::vector pem_key_cert_pairs; - /// \warning Deprecated - bool force_client_auth; - - /// If both \a force_client_auth and \a client_certificate_request - /// fields are set, \a force_client_auth takes effect, i.e. - /// \a REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY - /// will be enforced. - grpc_ssl_client_certificate_request_type client_certificate_request; -}; - -/// Builds SSL ServerCredentials given SSL specific options -std::shared_ptr SslServerCredentials( - const SslServerCredentialsOptions& options); - -/// Builds insecure server credentials. -std::shared_ptr InsecureServerCredentials(); +static inline std::shared_ptr InsecureServerCredentials() { + return ::grpc_impl::InsecureServerCredentials(); +} namespace experimental { -/// Options to create ServerCredentials with ALTS -struct AltsServerCredentialsOptions { - /// Add fields if needed. -}; +typedef ::grpc_impl::experimental::AltsServerCredentialsOptions AltsServerCredentialsOptions; -/// Builds ALTS ServerCredentials given ALTS specific options -std::shared_ptr AltsServerCredentials( - const AltsServerCredentialsOptions& options); +static inline std::shared_ptr AltsServerCredentials( + const AltsServerCredentialsOptions& options) { + return ::grpc_impl::experimental::AltsServerCredentials(options); +} -/// Builds Local ServerCredentials. -std::shared_ptr LocalServerCredentials( - grpc_local_connect_type type); +static inline std::shared_ptr LocalServerCredentials( + grpc_local_connect_type type) { + return ::grpc_impl::experimental::LocalServerCredentials(type); +} } // namespace experimental } // namespace grpc diff --git a/include/grpcpp/security/server_credentials_impl.h b/include/grpcpp/security/server_credentials_impl.h new file mode 100644 index 00000000000..f78de305f26 --- /dev/null +++ b/include/grpcpp/security/server_credentials_impl.h @@ -0,0 +1,110 @@ +/* + * + * 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_SECURITY_SERVER_CREDENTIALS_IMPL_H +#define GRPCPP_SECURITY_SERVER_CREDENTIALS_IMPL_H + +#include +#include + +#include +#include +#include + +struct grpc_server; + +namespace grpc { + +class Server; +} // namespace grpc +namespace grpc_impl { + +/// Wrapper around \a grpc_server_credentials, a way to authenticate a server. +class ServerCredentials { + public: + virtual ~ServerCredentials(); + + /// This method is not thread-safe and has to be called before the server is + /// started. The last call to this function wins. + virtual void SetAuthMetadataProcessor( + const std::shared_ptr& processor) = 0; + + private: + friend class ::grpc::Server; + + /// Tries to bind \a server to the given \a addr (eg, localhost:1234, + /// 192.168.1.1:31416, [::1]:27182, etc.) + /// + /// \return bound port number on sucess, 0 on failure. + // TODO(dgq): the "port" part seems to be a misnomer. + virtual int AddPortToServer(const grpc::string& addr, + grpc_server* server) = 0; +}; + +/// Options to create ServerCredentials with SSL +struct SslServerCredentialsOptions { + /// \warning Deprecated + SslServerCredentialsOptions() + : force_client_auth(false), + client_certificate_request(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE) {} + SslServerCredentialsOptions( + grpc_ssl_client_certificate_request_type request_type) + : force_client_auth(false), client_certificate_request(request_type) {} + + struct PemKeyCertPair { + grpc::string private_key; + grpc::string cert_chain; + }; + grpc::string pem_root_certs; + std::vector pem_key_cert_pairs; + /// \warning Deprecated + bool force_client_auth; + + /// If both \a force_client_auth and \a client_certificate_request + /// fields are set, \a force_client_auth takes effect, i.e. + /// \a REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY + /// will be enforced. + grpc_ssl_client_certificate_request_type client_certificate_request; +}; + +/// Builds SSL ServerCredentials given SSL specific options +std::shared_ptr SslServerCredentials( + const SslServerCredentialsOptions& options); + +/// Builds insecure server credentials. +std::shared_ptr InsecureServerCredentials(); + +namespace experimental { + +/// Options to create ServerCredentials with ALTS +struct AltsServerCredentialsOptions { + /// Add fields if needed. +}; + +/// Builds ALTS ServerCredentials given ALTS specific options +std::shared_ptr AltsServerCredentials( + const AltsServerCredentialsOptions& options); + +/// Builds Local ServerCredentials. +std::shared_ptr LocalServerCredentials( + grpc_local_connect_type type); + +} // namespace experimental +} // namespace grpc_impl + +#endif // GRPCPP_SECURITY_SERVER_CREDENTIALS_IMPL_H diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 498e5b7bb31..d657c7151f8 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -35,6 +35,10 @@ struct grpc_resource_quota; +namespace grpc_impl { + +class ServerCredentials; +} namespace grpc { class AsyncGenericService; @@ -42,7 +46,6 @@ class ResourceQuota; class CompletionQueue; class Server; class ServerCompletionQueue; -class ServerCredentials; class Service; namespace testing { @@ -94,7 +97,7 @@ class ServerBuilder { /// 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, + std::shared_ptr creds, int* selected_port = nullptr); /// Add a completion queue for handling asynchronous services. @@ -247,7 +250,7 @@ class ServerBuilder { /// Experimental, to be deprecated struct Port { grpc::string addr; - std::shared_ptr creds; + std::shared_ptr creds; int* selected_port; }; @@ -315,7 +318,7 @@ class ServerBuilder { /// List of completion queues added via \a AddCompletionQueue method. std::vector cqs_; - std::shared_ptr creds_; + std::shared_ptr creds_; std::vector> plugins_; grpc_resource_quota* resource_quota_; AsyncGenericService* generic_service_{nullptr}; diff --git a/src/cpp/server/insecure_server_credentials.cc b/src/cpp/server/insecure_server_credentials.cc index 7d749ddca4d..e4623ececef 100644 --- a/src/cpp/server/insecure_server_credentials.cc +++ b/src/cpp/server/insecure_server_credentials.cc @@ -21,7 +21,7 @@ #include #include -namespace grpc { +namespace grpc_impl { namespace { class InsecureServerCredentialsImpl final : public ServerCredentials { public: @@ -29,7 +29,7 @@ class InsecureServerCredentialsImpl final : public ServerCredentials { return grpc_server_add_insecure_http2_port(server, addr.c_str()); } void SetAuthMetadataProcessor( - const std::shared_ptr& processor) override { + const std::shared_ptr& processor) override { (void)processor; GPR_ASSERT(0); // Should not be called on InsecureServerCredentials. } @@ -41,4 +41,4 @@ std::shared_ptr InsecureServerCredentials() { new InsecureServerCredentialsImpl()); } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc index 453e76eb25d..fc23ba25d6f 100644 --- a/src/cpp/server/secure_server_credentials.cc +++ b/src/cpp/server/secure_server_credentials.cc @@ -93,17 +93,21 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor( status.error_message().c_str()); } +} // namespace grpc + +namespace grpc_impl { + int SecureServerCredentials::AddPortToServer(const grpc::string& addr, grpc_server* server) { return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_); } void SecureServerCredentials::SetAuthMetadataProcessor( - const std::shared_ptr& processor) { - auto* wrapper = new AuthMetadataProcessorAyncWrapper(processor); + const std::shared_ptr& processor) { + auto* wrapper = new grpc::AuthMetadataProcessorAyncWrapper(processor); grpc_server_credentials_set_auth_metadata_processor( - creds_, {AuthMetadataProcessorAyncWrapper::Process, - AuthMetadataProcessorAyncWrapper::Destroy, wrapper}); + creds_, {grpc::AuthMetadataProcessorAyncWrapper::Process, + grpc::AuthMetadataProcessorAyncWrapper::Destroy, wrapper}); } std::shared_ptr SslServerCredentials( @@ -147,4 +151,4 @@ std::shared_ptr LocalServerCredentials( } } // namespace experimental -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/secure_server_credentials.h b/src/cpp/server/secure_server_credentials.h index 8a81af2f591..3c7fbe13336 100644 --- a/src/cpp/server/secure_server_credentials.h +++ b/src/cpp/server/secure_server_credentials.h @@ -27,8 +27,15 @@ #include "src/cpp/server/thread_pool_interface.h" +namespace grpc_impl { + +class SecureServerCredentials; +} // namespace grpc_impl + namespace grpc { +typedef ::grpc_impl::SecureServerCredentials SecureServerCredentials; + class AuthMetadataProcessorAyncWrapper final { public: static void Destroy(void* wrapper); @@ -49,6 +56,10 @@ class AuthMetadataProcessorAyncWrapper final { std::shared_ptr processor_; }; +} // namespace grpc + +namespace grpc_impl { + class SecureServerCredentials final : public ServerCredentials { public: explicit SecureServerCredentials(grpc_server_credentials* creds) @@ -60,13 +71,15 @@ class SecureServerCredentials final : public ServerCredentials { int AddPortToServer(const grpc::string& addr, grpc_server* server) override; void SetAuthMetadataProcessor( - const std::shared_ptr& processor) override; + const std::shared_ptr& processor) override; private: grpc_server_credentials* creds_; - std::unique_ptr processor_; + std::unique_ptr processor_; }; -} // namespace grpc +} // namespace grpc_impl + + #endif // GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H diff --git a/src/cpp/server/server_credentials.cc b/src/cpp/server/server_credentials.cc index c3b3a8b3793..7478d06e94e 100644 --- a/src/cpp/server/server_credentials.cc +++ b/src/cpp/server/server_credentials.cc @@ -16,9 +16,9 @@ * */ -#include +#include -namespace grpc { +namespace grpc_impl { ServerCredentials::~ServerCredentials() {} diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index 57cdbeb7b76..5707e6b85fa 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -246,7 +246,7 @@ class GrpcToolTest : public ::testing::Test { SslServerCredentialsOptions ssl_opts; ssl_opts.pem_root_certs = ""; ssl_opts.pem_key_cert_pairs.push_back(pkcp); - creds = SslServerCredentials(ssl_opts); + creds = grpc::SslServerCredentials(ssl_opts); } else { creds = InsecureServerCredentials(); } diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc index 0cf75f1e5f1..f08b0c2294b 100644 --- a/test/cpp/util/test_credentials_provider.cc +++ b/test/cpp/util/test_credentials_provider.cc @@ -91,7 +91,7 @@ class DefaultCredentialsProvider : public CredentialsProvider { SslServerCredentialsOptions ssl_opts; ssl_opts.pem_root_certs = ""; ssl_opts.pem_key_cert_pairs.push_back(pkcp); - return SslServerCredentials(ssl_opts); + return grpc::SslServerCredentials(ssl_opts); } else { std::unique_lock lock(mu_); auto it(std::find(added_secure_type_names_.begin(), From ca69f911a77deb00186abc2cdf2e659c9b0f7d8c Mon Sep 17 00:00:00 2001 From: Arjun Date: Tue, 19 Mar 2019 18:07:27 -0700 Subject: [PATCH 1519/2143] 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 6da0ca442142855bc2cacdeed4ed307b5650dbea Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 20 Mar 2019 10:38:03 -0700 Subject: [PATCH 1520/2143] Bring ChannelArguments to grpc_impl from grpc --- BUILD | 1 + include/grpcpp/impl/server_builder_plugin.h | 7 +- include/grpcpp/security/credentials.h | 2 +- include/grpcpp/support/channel_arguments.h | 122 +------------- .../grpcpp/support/channel_arguments_impl.h | 152 ++++++++++++++++++ src/cpp/client/create_channel.cc | 1 - src/cpp/common/channel_arguments.cc | 6 +- src/cpp/common/secure_channel_arguments.cc | 4 +- 8 files changed, 166 insertions(+), 129 deletions(-) create mode 100644 include/grpcpp/support/channel_arguments_impl.h diff --git a/BUILD b/BUILD index 9e052dcf0c2..3a16d6cc921 100644 --- a/BUILD +++ b/BUILD @@ -253,6 +253,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h index 39450b42d56..a6d8902970f 100644 --- a/include/grpcpp/impl/server_builder_plugin.h +++ b/include/grpcpp/impl/server_builder_plugin.h @@ -23,11 +23,14 @@ #include +namespace grpc_impl { + +class ChannelArguments; +} // namespace grpc_impl namespace grpc { class ServerBuilder; class ServerInitializer; -class ChannelArguments; /// This interface is meant for internal usage only. Implementations of this /// interface should add themselves to a \a ServerBuilder instance through the @@ -55,7 +58,7 @@ class ServerBuilderPlugin { /// UpdateChannelArguments will be called in ServerBuilder::BuildAndStart(), /// before the Server instance is created. - virtual void UpdateChannelArguments(ChannelArguments* args) {} + virtual void UpdateChannelArguments(grpc_impl::ChannelArguments* args) {} virtual bool has_sync_methods() const { return false; } virtual bool has_async_methods() const { return false; } diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index dfea3900048..0fe4e9faa88 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -27,13 +27,13 @@ #include #include #include +#include #include #include struct grpc_call; namespace grpc { -class ChannelArguments; class Channel; class SecureChannelCredentials; class CallCredentials; diff --git a/include/grpcpp/support/channel_arguments.h b/include/grpcpp/support/channel_arguments.h index 217929d4aca..46e0180cb11 100644 --- a/include/grpcpp/support/channel_arguments.h +++ b/include/grpcpp/support/channel_arguments.h @@ -19,129 +19,11 @@ #ifndef GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_H #define GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_H -#include -#include - -#include -#include -#include +#include 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. -class ChannelArguments { - public: - ChannelArguments(); - ~ChannelArguments(); - - ChannelArguments(const ChannelArguments& other); - ChannelArguments& operator=(ChannelArguments other) { - Swap(other); - return *this; - } - - void Swap(ChannelArguments& other); - - /// Dump arguments in this instance to \a channel_args. Does not take - /// ownership of \a channel_args. - /// - /// Note that the underlying arguments are shared. Changes made to either \a - /// channel_args or this instance would be reflected on both. - void SetChannelArgs(grpc_channel_args* channel_args) const; - - // gRPC specific channel argument setters - /// Set target name override for SSL host name checking. This option is for - /// testing only and should never be used in production. - void SetSslTargetNameOverride(const grpc::string& name); - // TODO(yangg) add flow control options - /// Set the compression algorithm for the channel. - void SetCompressionAlgorithm(grpc_compression_algorithm algorithm); - - /// Set the grpclb fallback timeout (in ms) for the channel. If this amount - /// of time has passed but we have not gotten any non-empty \a serverlist from - /// the balancer, we will fall back to use the backend address(es) returned by - /// the resolver. - void SetGrpclbFallbackTimeout(int fallback_timeout); - - /// For client channel's, the socket mutator operates on - /// "channel" sockets. For server's, the socket mutator operates - /// only on "listen" sockets. - /// TODO(apolcyn): allow socket mutators to also operate - /// on server "channel" sockets, and adjust the socket mutator - /// object to be more speficic about which type of socket - /// it should operate on. - void SetSocketMutator(grpc_socket_mutator* mutator); - - /// Set the string to prepend to the user agent. - 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); - - /// Set the max receive and send message sizes. - void SetMaxReceiveMessageSize(int size); - void SetMaxSendMessageSize(int size); - - /// Set LB policy name. - /// Note that if the name resolver returns only balancer addresses, the - /// grpclb LB policy will be used, regardless of what is specified here. - void SetLoadBalancingPolicyName(const grpc::string& lb_policy_name); - - /// Set service config in JSON form. - /// Primarily meant for use in unit tests. - void SetServiceConfigJSON(const grpc::string& service_config_json); - - // Generic channel argument setters. Only for advanced use cases. - /// Set an integer argument \a value under \a key. - void SetInt(const grpc::string& key, int value); - - // Generic channel argument setter. Only for advanced use cases. - /// Set a pointer argument \a value under \a key. Owership is not transferred. - void SetPointer(const grpc::string& key, void* value); - - void SetPointerWithVtable(const grpc::string& key, void* value, - const grpc_arg_pointer_vtable* vtable); - - /// Set a textual argument \a value under \a key. - void SetString(const grpc::string& key, const grpc::string& value); - - /// Return (by value) a C \a grpc_channel_args structure which points to - /// arguments owned by this \a ChannelArguments instance - grpc_channel_args c_channel_args() const { - grpc_channel_args out; - out.num_args = args_.size(); - out.args = args_.empty() ? NULL : const_cast(&args_[0]); - return out; - } - - private: - friend class SecureChannelCredentials; - friend class testing::ChannelArgumentsTest; - - /// Default pointer argument operations. - struct PointerVtableMembers { - static void* Copy(void* in) { return in; } - static void Destroy(void* in) {} - static int Compare(void* a, void* b) { - if (a < b) return -1; - if (a > b) return 1; - return 0; - } - }; - - // Returns empty string when it is not set. - grpc::string GetSslTargetNameOverride() const; - - std::vector args_; - std::list strings_; -}; +typedef ::grpc_impl::ChannelArguments ChannelArguments; } // namespace grpc diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h new file mode 100644 index 00000000000..1e1340e716d --- /dev/null +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -0,0 +1,152 @@ +/* + * + * 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_SUPPORT_CHANNEL_ARGUMENTS_IMPL_H +#define GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_IMPL_H + +#include +#include + +#include +#include +#include + +namespace grpc { +namespace testing { +class ChannelArgumentsTest; +} // namespace testing + +class ResourceQuota; +class SecureChannelCredentials; +} // namespace grpc + +namespace grpc_impl { + +/// 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. +class ChannelArguments { + public: + ChannelArguments(); + ~ChannelArguments(); + + ChannelArguments(const ChannelArguments& other); + ChannelArguments& operator=(ChannelArguments other) { + Swap(other); + return *this; + } + + void Swap(ChannelArguments& other); + + /// Dump arguments in this instance to \a channel_args. Does not take + /// ownership of \a channel_args. + /// + /// Note that the underlying arguments are shared. Changes made to either \a + /// channel_args or this instance would be reflected on both. + void SetChannelArgs(grpc_channel_args* channel_args) const; + + // gRPC specific channel argument setters + /// Set target name override for SSL host name checking. This option is for + /// testing only and should never be used in production. + void SetSslTargetNameOverride(const grpc::string& name); + // TODO(yangg) add flow control options + /// Set the compression algorithm for the channel. + void SetCompressionAlgorithm(grpc_compression_algorithm algorithm); + + /// Set the grpclb fallback timeout (in ms) for the channel. If this amount + /// of time has passed but we have not gotten any non-empty \a serverlist from + /// the balancer, we will fall back to use the backend address(es) returned by + /// the resolver. + void SetGrpclbFallbackTimeout(int fallback_timeout); + + /// For client channel's, the socket mutator operates on + /// "channel" sockets. For server's, the socket mutator operates + /// only on "listen" sockets. + /// TODO(apolcyn): allow socket mutators to also operate + /// on server "channel" sockets, and adjust the socket mutator + /// object to be more speficic about which type of socket + /// it should operate on. + void SetSocketMutator(grpc_socket_mutator* mutator); + + /// Set the string to prepend to the user agent. + void SetUserAgentPrefix(const grpc::string& user_agent_prefix); + + /// Set the buffer pool to be attached to the constructed channel. + void SetResourceQuota(const grpc::ResourceQuota& resource_quota); + + /// Set the max receive and send message sizes. + void SetMaxReceiveMessageSize(int size); + void SetMaxSendMessageSize(int size); + + /// Set LB policy name. + /// Note that if the name resolver returns only balancer addresses, the + /// grpclb LB policy will be used, regardless of what is specified here. + void SetLoadBalancingPolicyName(const grpc::string& lb_policy_name); + + /// Set service config in JSON form. + /// Primarily meant for use in unit tests. + void SetServiceConfigJSON(const grpc::string& service_config_json); + + // Generic channel argument setters. Only for advanced use cases. + /// Set an integer argument \a value under \a key. + void SetInt(const grpc::string& key, int value); + + // Generic channel argument setter. Only for advanced use cases. + /// Set a pointer argument \a value under \a key. Owership is not transferred. + void SetPointer(const grpc::string& key, void* value); + + void SetPointerWithVtable(const grpc::string& key, void* value, + const grpc_arg_pointer_vtable* vtable); + + /// Set a textual argument \a value under \a key. + void SetString(const grpc::string& key, const grpc::string& value); + + /// Return (by value) a C \a grpc_channel_args structure which points to + /// arguments owned by this \a ChannelArguments instance + grpc_channel_args c_channel_args() const { + grpc_channel_args out; + out.num_args = args_.size(); + out.args = args_.empty() ? NULL : const_cast(&args_[0]); + return out; + } + + private: + friend class grpc::SecureChannelCredentials; + friend class grpc::testing::ChannelArgumentsTest; + + /// Default pointer argument operations. + struct PointerVtableMembers { + static void* Copy(void* in) { return in; } + static void Destroy(void* in) {} + static int Compare(void* a, void* b) { + if (a < b) return -1; + if (a > b) return 1; + return 0; + } + }; + + // Returns empty string when it is not set. + grpc::string GetSslTargetNameOverride() const; + + std::vector args_; + std::list strings_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_IMPL_H diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 457daa674c7..3d8e83937eb 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -26,7 +26,6 @@ #include "src/cpp/client/create_channel_internal.h" namespace grpc { -class ChannelArguments; std::shared_ptr CreateChannel( const grpc::string& target, diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index 214d72f853f..ba7be1c1026 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -27,11 +27,11 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/socket_mutator.h" -namespace grpc { +namespace grpc_impl { ChannelArguments::ChannelArguments() { // This will be ignored if used on the server side. - SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, "grpc-c++/" + Version()); + SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, "grpc-c++/" + grpc::Version()); } ChannelArguments::ChannelArguments(const ChannelArguments& other) @@ -215,4 +215,4 @@ void ChannelArguments::SetChannelArgs(grpc_channel_args* channel_args) const { } } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/common/secure_channel_arguments.cc b/src/cpp/common/secure_channel_arguments.cc index 2fb8ea44fbc..e5d03cd2378 100644 --- a/src/cpp/common/secure_channel_arguments.cc +++ b/src/cpp/common/secure_channel_arguments.cc @@ -21,7 +21,7 @@ #include #include "src/core/lib/channel/channel_args.h" -namespace grpc { +namespace grpc_impl { void ChannelArguments::SetSslTargetNameOverride(const grpc::string& name) { SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, name); @@ -36,4 +36,4 @@ grpc::string ChannelArguments::GetSslTargetNameOverride() const { return ""; } -} // namespace grpc +} // namespace grpc_impl From a4a5c43a6f3e10f541bd733321130b9828d29ad0 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 20 Mar 2019 10:45:57 -0700 Subject: [PATCH 1521/2143] 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 338b4cb5c9fb20383a0c0ea48bcc08a883a72385 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 20 Mar 2019 11:17:46 -0700 Subject: [PATCH 1522/2143] Fold ErrorDetails into grpc_impl from grpc --- BUILD | 1 + include/grpcpp/support/error_details.h | 20 ++++----- include/grpcpp/support/error_details_impl.h | 48 +++++++++++++++++++++ src/cpp/util/error_details.cc | 30 +++++++------ 4 files changed, 74 insertions(+), 25 deletions(-) create mode 100644 include/grpcpp/support/error_details_impl.h diff --git a/BUILD b/BUILD index 9e052dcf0c2..992c27fe75c 100644 --- a/BUILD +++ b/BUILD @@ -395,6 +395,7 @@ grpc_cc_library( hdrs = [ "include/grpc++/support/error_details.h", "include/grpcpp/support/error_details.h", + "include/grpcpp/support/error_details_impl.h", ], language = "c++", standalone = True, diff --git a/include/grpcpp/support/error_details.h b/include/grpcpp/support/error_details.h index 84931d98f18..07bc750db5c 100644 --- a/include/grpcpp/support/error_details.h +++ b/include/grpcpp/support/error_details.h @@ -19,7 +19,7 @@ #ifndef GRPCPP_SUPPORT_ERROR_DETAILS_H #define GRPCPP_SUPPORT_ERROR_DETAILS_H -#include +#include namespace google { namespace rpc { @@ -29,17 +29,15 @@ class Status; namespace grpc { -/// Map a \a grpc::Status to a \a google::rpc::Status. -/// The given \a to object will be cleared. -/// On success, returns status with OK. -/// Returns status with \a INVALID_ARGUMENT, if failed to deserialize. -/// Returns status with \a FAILED_PRECONDITION, if \a to is nullptr. -Status ExtractErrorDetails(const Status& from, ::google::rpc::Status* to); +static inline Status ExtractErrorDetails(const Status& from, + ::google::rpc::Status* to) { + return ::grpc_impl::ExtractErrorDetails(from, to); +} -/// Map \a google::rpc::Status to a \a grpc::Status. -/// Returns OK on success. -/// Returns status with \a FAILED_PRECONDITION if \a to is nullptr. -Status SetErrorDetails(const ::google::rpc::Status& from, Status* to); +static inline Status SetErrorDetails(const ::google::rpc::Status& from, + Status* to) { + return ::grpc_impl::SetErrorDetails(from, to); +} } // namespace grpc diff --git a/include/grpcpp/support/error_details_impl.h b/include/grpcpp/support/error_details_impl.h new file mode 100644 index 00000000000..daa630c1c3e --- /dev/null +++ b/include/grpcpp/support/error_details_impl.h @@ -0,0 +1,48 @@ +/* + * + * 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 GRPCPP_SUPPORT_ERROR_DETAILS__IMPL_H +#define GRPCPP_SUPPORT_ERROR_DETAILS_IMPL_H + +#include + +namespace google { +namespace rpc { +class Status; +} // namespace rpc +} // namespace google + +namespace grpc_impl { + +/// Map a \a grpc::Status to a \a google::rpc::Status. +/// The given \a to object will be cleared. +/// On success, returns status with OK. +/// Returns status with \a INVALID_ARGUMENT, if failed to deserialize. +/// Returns status with \a FAILED_PRECONDITION, if \a to is nullptr. +grpc::Status ExtractErrorDetails(const grpc::Status& from, + ::google::rpc::Status* to); + +/// Map \a google::rpc::Status to a \a grpc::Status. +/// Returns OK on success. +/// Returns status with \a FAILED_PRECONDITION if \a to is nullptr. +grpc::Status SetErrorDetails(const ::google::rpc::Status& from, + grpc::Status* to); + +} // namespace grpc_impl + +#endif // GRPCPP_SUPPORT_ERROR_DETAILS_IMPL_H diff --git a/src/cpp/util/error_details.cc b/src/cpp/util/error_details.cc index 42c887aed73..a1aafcbdc6e 100644 --- a/src/cpp/util/error_details.cc +++ b/src/cpp/util/error_details.cc @@ -20,29 +20,31 @@ #include "src/proto/grpc/status/status.pb.h" -namespace grpc { +namespace grpc_impl { -Status ExtractErrorDetails(const Status& from, ::google::rpc::Status* to) { +grpc::Status ExtractErrorDetails(const grpc::Status& from, + ::google::rpc::Status* to) { if (to == nullptr) { - return Status(StatusCode::FAILED_PRECONDITION, ""); + return grpc::Status(grpc::StatusCode::FAILED_PRECONDITION, ""); } if (!to->ParseFromString(from.error_details())) { - return Status(StatusCode::INVALID_ARGUMENT, ""); + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, ""); } - return Status::OK; + return grpc::Status::OK; } -Status SetErrorDetails(const ::google::rpc::Status& from, Status* to) { +grpc::Status SetErrorDetails(const ::google::rpc::Status& from, + grpc::Status* to) { if (to == nullptr) { - return Status(StatusCode::FAILED_PRECONDITION, ""); + return grpc::Status(grpc::StatusCode::FAILED_PRECONDITION, ""); } - StatusCode code = StatusCode::UNKNOWN; - if (from.code() >= StatusCode::OK && - from.code() <= StatusCode::UNAUTHENTICATED) { - code = static_cast(from.code()); + grpc::StatusCode code = grpc::StatusCode::UNKNOWN; + if (from.code() >= grpc::StatusCode::OK && + from.code() <= grpc::StatusCode::UNAUTHENTICATED) { + code = static_cast(from.code()); } - *to = Status(code, from.message(), from.SerializeAsString()); - return Status::OK; + *to = grpc::Status(code, from.message(), from.SerializeAsString()); + return grpc::Status::OK; } -} // namespace grpc +} // namespace grpc_impl From 3de283c665387a569b139d589c2409d51ceafee8 Mon Sep 17 00:00:00 2001 From: Jared Hance Date: Wed, 20 Mar 2019 10:23:22 -0700 Subject: [PATCH 1523/2143] 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 04af168cf852236f71d08f34d45442725567b9c6 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 20 Mar 2019 13:05:36 -0700 Subject: [PATCH 1524/2143] Move Server into grpc_impl from grpc --- BUILD | 1 + .../impl/codegen/async_generic_service.h | 10 +- include/grpcpp/impl/codegen/async_stream.h | 2 +- .../grpcpp/impl/codegen/completion_queue.h | 9 +- include/grpcpp/impl/codegen/server_context.h | 7 +- include/grpcpp/impl/codegen/service_type.h | 7 +- include/grpcpp/impl/server_initializer.h | 5 +- include/grpcpp/security/server_credentials.h | 7 +- include/grpcpp/server.h | 325 +-- include/grpcpp/server_builder.h | 7 +- include/grpcpp/server_impl.h | 353 +++ src/cpp/server/server_cc.cc | 2110 +++++++++-------- test/cpp/util/metrics_server.h | 2 + 13 files changed, 1452 insertions(+), 1393 deletions(-) create mode 100644 include/grpcpp/server_impl.h diff --git a/BUILD b/BUILD index 9e052dcf0c2..ee6e4fce32d 100644 --- a/BUILD +++ b/BUILD @@ -246,6 +246,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/security/credentials.h", "include/grpcpp/security/server_credentials.h", "include/grpcpp/server.h", + "include/grpcpp/server_impl.h", "include/grpcpp/server_builder.h", "include/grpcpp/server_context.h", "include/grpcpp/server_posix.h", diff --git a/include/grpcpp/impl/codegen/async_generic_service.h b/include/grpcpp/impl/codegen/async_generic_service.h index 46489b135d7..4e680bb1c76 100644 --- a/include/grpcpp/impl/codegen/async_generic_service.h +++ b/include/grpcpp/impl/codegen/async_generic_service.h @@ -39,7 +39,7 @@ class GenericServerContext final : public ServerContext { const grpc::string& host() const { return host_; } private: - friend class Server; + friend class grpc_impl::Server; friend class ServerInterface; void Clear() { @@ -79,8 +79,8 @@ class AsyncGenericService final { ServerCompletionQueue* notification_cq, void* tag); private: - friend class Server; - Server* server_; + friend class grpc_impl::Server; + grpc_impl::Server* server_; }; namespace experimental { @@ -117,14 +117,14 @@ class CallbackGenericService { } private: - friend class ::grpc::Server; + friend class ::grpc_impl::Server; internal::CallbackBidiHandler* Handler() { return new internal::CallbackBidiHandler( [this] { return CreateReactor(); }); } - Server* server_{nullptr}; + grpc_impl::Server* server_{nullptr}; }; } // namespace experimental } // namespace grpc diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index bfb2df4f232..e12923ea02c 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -1099,7 +1099,7 @@ class ServerAsyncReaderWriter final } private: - friend class ::grpc::Server; + friend class ::grpc_impl::Server; void BindCall(::grpc::internal::Call* call) override { call_ = *call; } diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 4812f0253d4..559b7b7fe47 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 Server; +} // namespace grpc_impl namespace grpc { template @@ -62,7 +66,6 @@ class Channel; class ChannelInterface; class ClientContext; class CompletionQueue; -class Server; class ServerBuilder; class ServerContext; class ServerInterface; @@ -271,7 +274,7 @@ class CompletionQueue : private GrpcLibraryCodegen { friend class ::grpc::internal::TemplatedBidiStreamingHandler; template friend class ::grpc::internal::ErrorMethodHandler; - friend class ::grpc::Server; + friend class ::grpc_impl::Server; friend class ::grpc::ServerContext; friend class ::grpc::ServerInterface; template @@ -406,7 +409,7 @@ class ServerCompletionQueue : public CompletionQueue { grpc_cq_polling_type polling_type_; friend class ServerBuilder; - friend class Server; + friend class grpc_impl::Server; }; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index 591a9ff9549..c2959d95de7 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -41,11 +41,14 @@ struct grpc_metadata; struct grpc_call; struct census_context; +namespace grpc_impl { + +class Server; +} // namespace grpc_impl namespace grpc { class ClientContext; class GenericServerContext; class CompletionQueue; -class Server; class ServerInterface; template class ServerAsyncReader; @@ -269,7 +272,7 @@ class ServerContext { friend class ::grpc::testing::InteropServerContextInspector; friend class ::grpc::testing::ServerContextTestSpouse; friend class ::grpc::ServerInterface; - friend class ::grpc::Server; + friend class ::grpc_impl::Server; template friend class ::grpc::ServerAsyncReader; template diff --git a/include/grpcpp/impl/codegen/service_type.h b/include/grpcpp/impl/codegen/service_type.h index 332a04c294f..7ac482c19d7 100644 --- a/include/grpcpp/impl/codegen/service_type.h +++ b/include/grpcpp/impl/codegen/service_type.h @@ -26,10 +26,13 @@ #include #include +namespace grpc_impl { + +class Server; +} // namespace grpc_impl namespace grpc { class CompletionQueue; -class Server; class ServerInterface; class ServerCompletionQueue; class ServerContext; @@ -228,7 +231,7 @@ class Service { } private: - friend class Server; + friend class grpc_impl::Server; friend class ServerInterface; ServerInterface* server_; std::vector> methods_; diff --git a/include/grpcpp/impl/server_initializer.h b/include/grpcpp/impl/server_initializer.h index f949fabfe6f..bd18ee04927 100644 --- a/include/grpcpp/impl/server_initializer.h +++ b/include/grpcpp/impl/server_initializer.h @@ -24,9 +24,12 @@ #include -namespace grpc { +namespace grpc_impl { class Server; +} // namespace grpc_impl +namespace grpc { + class Service; class ServerInitializer { diff --git a/include/grpcpp/security/server_credentials.h b/include/grpcpp/security/server_credentials.h index bd00a0a1737..a519caf9913 100644 --- a/include/grpcpp/security/server_credentials.h +++ b/include/grpcpp/security/server_credentials.h @@ -28,8 +28,11 @@ struct grpc_server; -namespace grpc { +namespace grpc_impl { + class Server; +} // namespace grpc_impl +namespace grpc { /// Wrapper around \a grpc_server_credentials, a way to authenticate a server. class ServerCredentials { @@ -42,7 +45,7 @@ class ServerCredentials { const std::shared_ptr& processor) = 0; private: - friend class ::grpc::Server; + friend class ::grpc_impl::Server; /// Tries to bind \a server to the given \a addr (eg, localhost:1234, /// 192.168.1.1:31416, [::1]:27182, etc.) diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index f5c99f22df2..3de2aba0b59 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -1,6 +1,6 @@ /* * - * 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. @@ -19,330 +19,11 @@ #ifndef GRPCPP_SERVER_H #define GRPCPP_SERVER_H -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct grpc_server; +#include namespace grpc { -class AsyncGenericService; -class HealthCheckServiceInterface; -class ServerContext; -class ServerInitializer; - -/// Represents a gRPC server. -/// -/// Use a \a grpc::ServerBuilder to create, configure, and start -/// \a Server instances. -class Server : public ServerInterface, private GrpcLibraryCodegen { - public: - ~Server(); - - /// Block until the server shuts down. - /// - /// \warning The server must be either shutting down or some other thread must - /// call \a Shutdown for this function to ever return. - void Wait() override; - - /// Global callbacks are a set of hooks that are called when server - /// events occur. \a SetGlobalCallbacks method is used to register - /// the hooks with gRPC. Note that - /// the \a GlobalCallbacks instance will be shared among all - /// \a Server instances in an application and can be set exactly - /// once per application. - class GlobalCallbacks { - public: - virtual ~GlobalCallbacks() {} - /// Called before server is created. - virtual void UpdateArguments(ChannelArguments* args) {} - /// Called before application callback for each synchronous server request - virtual void PreSynchronousRequest(ServerContext* context) = 0; - /// Called after application callback for each synchronous server request - virtual void PostSynchronousRequest(ServerContext* context) = 0; - /// Called before server is started. - virtual void PreServerStart(Server* server) {} - /// Called after a server port is added. - virtual void AddPort(Server* server, const grpc::string& addr, - ServerCredentials* creds, int port) {} - }; - /// Set the global callback object. Can only be called once per application. - /// Does not take ownership of callbacks, and expects the pointed to object - /// to be alive until all server objects in the process have been destroyed. - /// The same \a GlobalCallbacks object will be used throughout the - /// application and is shared among all \a Server objects. - static void SetGlobalCallbacks(GlobalCallbacks* callbacks); - - /// Returns a \em raw pointer to the underlying \a grpc_server instance. - /// EXPERIMENTAL: for internal/test use only - grpc_server* c_server(); - - /// Returns the health check service. - HealthCheckServiceInterface* GetHealthCheckService() const { - return health_check_service_.get(); - } - - /// Establish a channel for in-process communication - std::shared_ptr InProcessChannel(const ChannelArguments& args); - - /// 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(Server* server) : server_(server) {} - - /// Establish a channel for in-process communication with client - /// interceptors - std::shared_ptr InProcessChannelWithInterceptors( - const ChannelArguments& args, - std::vector< - std::unique_ptr> - interceptor_creators); - - private: - Server* server_; - }; - - /// 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: - /// Register a service. This call does not take ownership of the service. - /// The service must exist for the lifetime of the Server instance. - bool RegisterService(const grpc::string* host, Service* service) override; - - /// Try binding the server to the given \a addr endpoint - /// (port, and optionally including IP address to bind to). - /// - /// It can be invoked multiple times. Should be used before - /// starting the server. - /// - /// \param addr The address to try to bind to the server (eg, localhost:1234, - /// 192.168.1.1:31416, [::1]:27182, etc.). - /// \param creds The credentials associated with the server. - /// - /// \return bound port number on success, 0 on failure. - /// - /// \warning It is an error to call this method on an already started server. - int AddListeningPort(const grpc::string& addr, - ServerCredentials* creds) override; - - /// NOTE: This is *NOT* a public API. The server constructors are supposed to - /// be used by \a ServerBuilder class only. The constructor will be made - /// 'private' very soon. - /// - /// Server constructors. To be used by \a ServerBuilder only. - /// - /// \param max_message_size Maximum message length that the channel can - /// receive. - /// - /// \param args The channel args - /// - /// \param sync_server_cqs The completion queues to use if the server is a - /// synchronous server (or a hybrid server). The server polls for new RPCs on - /// these queues - /// - /// \param min_pollers The minimum number of polling threads per server - /// completion queue (in param sync_server_cqs) to use for listening to - /// incoming requests (used only in case of sync server) - /// - /// \param max_pollers The maximum number of polling threads per server - /// completion queue (in param sync_server_cqs) to use for listening to - /// incoming requests (used only in case of sync server) - /// - /// \param sync_cq_timeout_msec The timeout to use when calling AsyncNext() on - /// server completion queues passed via sync_server_cqs param. - Server(int max_message_size, ChannelArguments* args, - std::shared_ptr>> - sync_server_cqs, - int min_pollers, int max_pollers, int sync_cq_timeout_msec, - grpc_resource_quota* server_rq = nullptr, - std::vector< - std::unique_ptr> - interceptor_creators = std::vector>()); - - /// Start the server. - /// - /// \param cqs Completion queues for handling asynchronous services. The - /// caller is required to keep all completion queues live until the server is - /// destroyed. - /// \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_; } - - private: - std::vector>* - interceptor_creators() override { - return &interceptor_creators_; - } - - friend class AsyncGenericService; - friend class ServerBuilder; - friend class ServerInitializer; - - class SyncRequest; - class CallbackRequestBase; - template - class CallbackRequest; - class UnimplementedAsyncRequest; - class UnimplementedAsyncResponse; - - /// SyncRequestThreadManager is an implementation of ThreadManager. This class - /// is responsible for polling for incoming RPCs and calling the RPC handlers. - /// This is only used in case of a Sync server (i.e a server exposing a sync - /// interface) - class SyncRequestThreadManager; - - /// Register a generic service. This call does not take ownership of the - /// 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; - - void ShutdownInternal(gpr_timespec deadline) override; - - int max_receive_message_size() const override { - return max_receive_message_size_; - } - - CompletionQueue* CallbackCQ() override; - - ServerInitializer* initializer(); - - // A vector of interceptor factory objects. - // This should be destroyed after health_check_service_ and this requirement - // is satisfied by declaring interceptor_creators_ before - // health_check_service_. (C++ mandates that member objects be destroyed in - // the reverse order of initialization.) - std::vector> - interceptor_creators_; - - const int max_receive_message_size_; - - /// The following completion queues are ONLY used in case of Sync API - /// i.e. if the server has any services with sync methods. The server uses - /// these completion queues to poll for new RPCs - std::shared_ptr>> - sync_server_cqs_; - - /// List of \a ThreadManager instances (one for each cq in - /// the \a sync_server_cqs) - std::vector> sync_req_mgrs_; - - // 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_; - - // For registering experimental callback generic service; remove when that - // method longer experimental - experimental_registration_type experimental_registration_{this}; - - // Server status - std::mutex mu_; - bool started_; - bool shutdown_; - bool shutdown_notified_; // Was notify called on the shutdown_cv_ - - 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 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}; - - std::shared_ptr global_callbacks_; - - std::vector services_; - bool has_async_generic_service_{false}; - bool has_callback_generic_service_{false}; - - // Pointer to the wrapped grpc_server. - grpc_server* server_; - - std::unique_ptr server_initializer_; - - 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_; - - // 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 - // shutdown callback tag (invoked when the CQ is fully shutdown). - // It is protected by mu_ - CompletionQueue* callback_cq_ = nullptr; -}; +typedef ::grpc_impl::Server Server; } // namespace grpc diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 498e5b7bb31..aaa8197e966 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -35,12 +35,15 @@ struct grpc_resource_quota; +namespace grpc_impl { + +class Server; +} // namespace grpc_impl namespace grpc { class AsyncGenericService; class ResourceQuota; class CompletionQueue; -class Server; class ServerCompletionQueue; class ServerCredentials; class Service; @@ -70,7 +73,7 @@ class ServerBuilder { /// traffic (via AddListeningPort) /// 3. [for async api only] completion queues have been added via /// AddCompletionQueue - virtual std::unique_ptr BuildAndStart(); + 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 diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h new file mode 100644 index 00000000000..d27723a01fe --- /dev/null +++ b/include/grpcpp/server_impl.h @@ -0,0 +1,353 @@ +/* + * + * 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_SERVER_IMPL_H +#define GRPCPP_SERVER_IMPL_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct grpc_server; + +namespace grpc { + +class AsyncGenericService; +class HealthCheckServiceInterface; +class ServerContext; +class ServerInitializer; + +} // namespace grpc + +namespace grpc_impl { + +/// Represents a gRPC server. +/// +/// Use a \a grpc::ServerBuilder to create, configure, and start +/// \a Server instances. +class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { + public: + ~Server(); + + /// Block until the server shuts down. + /// + /// \warning The server must be either shutting down or some other thread must + /// call \a Shutdown for this function to ever return. + void Wait() override; + + /// Global callbacks are a set of hooks that are called when server + /// events occur. \a SetGlobalCallbacks method is used to register + /// the hooks with gRPC. Note that + /// the \a GlobalCallbacks instance will be shared among all + /// \a Server instances in an application and can be set exactly + /// once per application. + class GlobalCallbacks { + public: + virtual ~GlobalCallbacks() {} + /// Called before server is created. + virtual void UpdateArguments(grpc::ChannelArguments* args) {} + /// Called before application callback for each synchronous server request + virtual void PreSynchronousRequest(grpc::ServerContext* context) = 0; + /// Called after application callback for each synchronous server request + virtual void PostSynchronousRequest(grpc::ServerContext* context) = 0; + /// Called before server is started. + virtual void PreServerStart(Server* server) {} + /// Called after a server port is added. + virtual void AddPort(Server* server, const grpc::string& addr, + grpc::ServerCredentials* creds, int port) {} + }; + /// Set the global callback object. Can only be called once per application. + /// Does not take ownership of callbacks, and expects the pointed to object + /// to be alive until all server objects in the process have been destroyed. + /// The same \a GlobalCallbacks object will be used throughout the + /// application and is shared among all \a Server objects. + static void SetGlobalCallbacks(GlobalCallbacks* callbacks); + + /// Returns a \em raw pointer to the underlying \a grpc_server instance. + /// EXPERIMENTAL: for internal/test use only + grpc_server* c_server(); + + /// Returns the health check service. + grpc::HealthCheckServiceInterface* GetHealthCheckService() const { + return health_check_service_.get(); + } + + /// Establish a channel for in-process communication + std::shared_ptr InProcessChannel(const grpc::ChannelArguments& args); + + /// 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(Server* server) : server_(server) {} + + /// Establish a channel for in-process communication with client + /// interceptors + std::shared_ptr InProcessChannelWithInterceptors( + const grpc::ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators); + + private: + Server* server_; + }; + + /// 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: + /// Register a service. This call does not take ownership of the service. + /// The service must exist for the lifetime of the Server instance. + bool RegisterService(const grpc::string* host, grpc::Service* service) override; + + /// Try binding the server to the given \a addr endpoint + /// (port, and optionally including IP address to bind to). + /// + /// It can be invoked multiple times. Should be used before + /// starting the server. + /// + /// \param addr The address to try to bind to the server (eg, localhost:1234, + /// 192.168.1.1:31416, [::1]:27182, etc.). + /// \param creds The credentials associated with the server. + /// + /// \return bound port number on success, 0 on failure. + /// + /// \warning It is an error to call this method on an already started server. + int AddListeningPort(const grpc::string& addr, + grpc::ServerCredentials* creds) override; + + /// NOTE: This is *NOT* a public API. The server constructors are supposed to + /// be used by \a ServerBuilder class only. The constructor will be made + /// 'private' very soon. + /// + /// Server constructors. To be used by \a ServerBuilder only. + /// + /// \param max_message_size Maximum message length that the channel can + /// receive. + /// + /// \param args The channel args + /// + /// \param sync_server_cqs The completion queues to use if the server is a + /// synchronous server (or a hybrid server). The server polls for new RPCs on + /// these queues + /// + /// \param min_pollers The minimum number of polling threads per server + /// completion queue (in param sync_server_cqs) to use for listening to + /// incoming requests (used only in case of sync server) + /// + /// \param max_pollers The maximum number of polling threads per server + /// completion queue (in param sync_server_cqs) to use for listening to + /// incoming requests (used only in case of sync server) + /// + /// \param sync_cq_timeout_msec The timeout to use when calling AsyncNext() on + /// server completion queues passed via sync_server_cqs param. + Server(int max_message_size, grpc::ChannelArguments* args, + std::shared_ptr>> + sync_server_cqs, + int min_pollers, int max_pollers, int sync_cq_timeout_msec, + grpc_resource_quota* server_rq = nullptr, + std::vector< + std::unique_ptr> + interceptor_creators = std::vector>()); + + /// Start the server. + /// + /// \param cqs Completion queues for handling asynchronous services. The + /// caller is required to keep all completion queues live until the server is + /// destroyed. + /// \param num_cqs How many completion queues does \a cqs hold. + void Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) override; + + grpc_server* server() override { return server_; } + + private: + std::vector>* + interceptor_creators() override { + return &interceptor_creators_; + } + + friend class grpc::AsyncGenericService; + friend class grpc::ServerBuilder; + friend class grpc::ServerInitializer; + + class SyncRequest; + class CallbackRequestBase; + template + class CallbackRequest; + class UnimplementedAsyncRequest; + class UnimplementedAsyncResponse; + + /// SyncRequestThreadManager is an implementation of ThreadManager. This class + /// is responsible for polling for incoming RPCs and calling the RPC handlers. + /// This is only used in case of a Sync server (i.e a server exposing a sync + /// interface) + class SyncRequestThreadManager; + + /// Register a generic service. This call does not take ownership of the + /// service. The service must exist for the lifetime of the Server instance. + void RegisterAsyncGenericService(grpc::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( + grpc::experimental::CallbackGenericService* service) override { + server_->RegisterCallbackGenericService(service); + } + + private: + Server* server_; + }; + + /// TODO(vjpai): Mark this override when experimental type above is deleted + void RegisterCallbackGenericService( + grpc::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(grpc::internal::CallOpSetInterface* ops, + grpc::internal::Call* call) override; + + void ShutdownInternal(gpr_timespec deadline) override; + + int max_receive_message_size() const override { + return max_receive_message_size_; + } + + grpc::CompletionQueue* CallbackCQ() override; + + grpc::ServerInitializer* initializer(); + + // A vector of interceptor factory objects. + // This should be destroyed after health_check_service_ and this requirement + // is satisfied by declaring interceptor_creators_ before + // health_check_service_. (C++ mandates that member objects be destroyed in + // the reverse order of initialization.) + std::vector> + interceptor_creators_; + + const int max_receive_message_size_; + + /// The following completion queues are ONLY used in case of Sync API + /// i.e. if the server has any services with sync methods. The server uses + /// these completion queues to poll for new RPCs + std::shared_ptr>> + sync_server_cqs_; + + /// List of \a ThreadManager instances (one for each cq in + /// the \a sync_server_cqs) + std::vector> sync_req_mgrs_; + + // 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_; + + // For registering experimental callback generic service; remove when that + // method longer experimental + experimental_registration_type experimental_registration_{this}; + + // Server status + std::mutex mu_; + bool started_; + bool shutdown_; + bool shutdown_notified_; // Was notify called on the shutdown_cv_ + + 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 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}; + + std::shared_ptr global_callbacks_; + + std::vector services_; + bool has_async_generic_service_{false}; + bool has_callback_generic_service_{false}; + + // Pointer to the wrapped grpc_server. + grpc_server* server_; + + std::unique_ptr server_initializer_; + + 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_; + + // 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 + // shutdown callback tag (invoked when the CQ is fully shutdown). + // It is protected by mu_ + grpc::CompletionQueue* callback_cq_ = nullptr; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_SERVER_IMPL_H diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 26e84f1aed4..74d89ff18fc 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -106,1029 +106,6 @@ class UnimplementedAsyncRequestContext { } // namespace -/// Use private inheritance rather than composition only to establish order -/// of construction, since the public base class should be constructed after the -/// elements belonging to the private base class are constructed. This is not -/// possible using true composition. -class Server::UnimplementedAsyncRequest final - : private UnimplementedAsyncRequestContext, - public GenericAsyncRequest { - public: - UnimplementedAsyncRequest(Server* server, ServerCompletionQueue* cq) - : GenericAsyncRequest(server, &server_context_, &generic_stream_, cq, cq, - nullptr, false), - server_(server), - cq_(cq) {} - - bool FinalizeResult(void** tag, bool* status) override; - - ServerContext* context() { return &server_context_; } - GenericServerAsyncReaderWriter* stream() { return &generic_stream_; } - - private: - Server* const server_; - ServerCompletionQueue* const cq_; -}; - -/// UnimplementedAsyncResponse should not post user-visible completions to the -/// C++ completion queue, but is generated as a CQ event by the core -class Server::UnimplementedAsyncResponse final - : public internal::CallOpSet { - public: - UnimplementedAsyncResponse(UnimplementedAsyncRequest* request); - ~UnimplementedAsyncResponse() { delete request_; } - - bool FinalizeResult(void** tag, bool* status) override { - if (internal::CallOpSet< - internal::CallOpSendInitialMetadata, - internal::CallOpServerSendStatus>::FinalizeResult(tag, status)) { - delete this; - } else { - // The tag was swallowed due to interception. We will see it again. - } - return false; - } - - private: - UnimplementedAsyncRequest* const request_; -}; - -class Server::SyncRequest final : public internal::CompletionQueueTag { - public: - SyncRequest(internal::RpcServiceMethod* method, void* method_tag) - : method_(method), - method_tag_(method_tag), - in_flight_(false), - has_request_payload_( - method->method_type() == internal::RpcMethod::NORMAL_RPC || - method->method_type() == internal::RpcMethod::SERVER_STREAMING), - call_details_(nullptr), - cq_(nullptr) { - grpc_metadata_array_init(&request_metadata_); - } - - ~SyncRequest() { - if (call_details_) { - delete call_details_; - } - grpc_metadata_array_destroy(&request_metadata_); - } - - void SetupRequest() { cq_ = grpc_completion_queue_create_for_pluck(nullptr); } - - void TeardownRequest() { - grpc_completion_queue_destroy(cq_); - cq_ = nullptr; - } - - void Request(grpc_server* server, grpc_completion_queue* notify_cq) { - GPR_ASSERT(cq_ && !in_flight_); - in_flight_ = true; - if (method_tag_) { - if (grpc_server_request_registered_call( - server, method_tag_, &call_, &deadline_, &request_metadata_, - has_request_payload_ ? &request_payload_ : nullptr, cq_, - notify_cq, this) != GRPC_CALL_OK) { - TeardownRequest(); - return; - } - } else { - if (!call_details_) { - call_details_ = new grpc_call_details; - grpc_call_details_init(call_details_); - } - if (grpc_server_request_call(server, &call_, call_details_, - &request_metadata_, cq_, notify_cq, - this) != GRPC_CALL_OK) { - TeardownRequest(); - return; - } - } - } - - void PostShutdownCleanup() { - if (call_) { - grpc_call_unref(call_); - call_ = nullptr; - } - if (cq_) { - grpc_completion_queue_destroy(cq_); - cq_ = nullptr; - } - } - - bool FinalizeResult(void** tag, bool* status) override { - if (!*status) { - grpc_completion_queue_destroy(cq_); - cq_ = nullptr; - } - if (call_details_) { - deadline_ = call_details_->deadline; - grpc_call_details_destroy(call_details_); - grpc_call_details_init(call_details_); - } - return true; - } - - // The CallData class represents a call that is "active" as opposed - // to just being requested. It wraps and takes ownership of the cq from - // the call request - class CallData final { - public: - explicit CallData(Server* server, SyncRequest* mrd) - : cq_(mrd->cq_), - ctx_(mrd->deadline_, &mrd->request_metadata_), - has_request_payload_(mrd->has_request_payload_), - request_payload_(has_request_payload_ ? mrd->request_payload_ - : nullptr), - request_(nullptr), - method_(mrd->method_), - call_( - mrd->call_, server, &cq_, server->max_receive_message_size(), - ctx_.set_server_rpc_info(method_->name(), method_->method_type(), - server->interceptor_creators_)), - server_(server), - global_callbacks_(nullptr), - resources_(false) { - ctx_.set_call(mrd->call_); - ctx_.cq_ = &cq_; - GPR_ASSERT(mrd->in_flight_); - mrd->in_flight_ = false; - mrd->request_metadata_.count = 0; - } - - ~CallData() { - if (has_request_payload_ && request_payload_) { - grpc_byte_buffer_destroy(request_payload_); - } - } - - void Run(const std::shared_ptr& global_callbacks, - bool resources) { - global_callbacks_ = global_callbacks; - resources_ = resources; - - interceptor_methods_.SetCall(&call_); - interceptor_methods_.SetReverse(); - // Set interception point for RECV INITIAL METADATA - interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA); - interceptor_methods_.SetRecvInitialMetadata(&ctx_.client_metadata_); - - if (has_request_payload_) { - // Set interception point for RECV MESSAGE - auto* handler = resources_ ? method_->handler() - : server_->resource_exhausted_handler_.get(); - request_ = handler->Deserialize(call_.call(), request_payload_, - &request_status_); - - request_payload_ = nullptr; - interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_MESSAGE); - interceptor_methods_.SetRecvMessage(request_, nullptr); - } - - if (interceptor_methods_.RunInterceptors( - [this]() { ContinueRunAfterInterception(); })) { - ContinueRunAfterInterception(); - } else { - // There were interceptors to be run, so ContinueRunAfterInterception - // will be run when interceptors are done. - } - } - - void ContinueRunAfterInterception() { - { - ctx_.BeginCompletionOp(&call_, nullptr, nullptr); - global_callbacks_->PreSynchronousRequest(&ctx_); - auto* handler = resources_ ? method_->handler() - : server_->resource_exhausted_handler_.get(); - handler->RunHandler(internal::MethodHandler::HandlerParameter( - &call_, &ctx_, request_, request_status_, nullptr)); - request_ = nullptr; - global_callbacks_->PostSynchronousRequest(&ctx_); - - cq_.Shutdown(); - - internal::CompletionQueueTag* op_tag = ctx_.GetCompletionOpTag(); - cq_.TryPluck(op_tag, gpr_inf_future(GPR_CLOCK_REALTIME)); - - /* Ensure the cq_ is shutdown */ - DummyTag ignored_tag; - GPR_ASSERT(cq_.Pluck(&ignored_tag) == false); - } - delete this; - } - - private: - CompletionQueue cq_; - ServerContext ctx_; - const bool has_request_payload_; - grpc_byte_buffer* request_payload_; - void* request_; - Status request_status_; - internal::RpcServiceMethod* const method_; - internal::Call call_; - Server* server_; - std::shared_ptr global_callbacks_; - bool resources_; - internal::InterceptorBatchMethodsImpl interceptor_methods_; - }; - - private: - internal::RpcServiceMethod* const method_; - void* const method_tag_; - bool in_flight_; - const bool has_request_payload_; - grpc_call* call_; - grpc_call_details* call_details_; - gpr_timespec deadline_; - grpc_metadata_array request_metadata_; - grpc_byte_buffer* request_payload_; - grpc_completion_queue* cq_; -}; - -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"); - - // 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), - method_index_(method_idx), - method_(method), - method_tag_(method_tag), - has_request_payload_( - 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_++; - Setup(); - } - - ~CallbackRequest() { - Clear(); - - // 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() override { - if (method_tag_) { - if (GRPC_CALL_OK != - grpc_server_request_registered_call( - server_->c_server(), method_tag_, &call_, &deadline_, - &request_metadata_, - has_request_payload_ ? &request_payload_ : nullptr, cq_->cq(), - cq_->cq(), static_cast(&tag_))) { - return false; - } - } else { - if (!call_details_) { - call_details_ = new grpc_call_details; - grpc_call_details_init(call_details_); - } - if (grpc_server_request_call(server_->c_server(), &call_, call_details_, - &request_metadata_, cq_->cq(), cq_->cq(), - static_cast(&tag_)) != GRPC_CALL_OK) { - return false; - } - } - return true; - } - - // 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) { - functor_run = &CallbackCallTag::StaticRun; - } - - // force_run can not be performed on a tag if operations using this tag - // have been sent to PerformOpsOnCall. It is intended for error conditions - // that are detected before the operations are internally processed. - void force_run(bool ok) { Run(ok); } - - private: - Server::CallbackRequest* req_; - internal::Call* call_; - - static void StaticRun(grpc_experimental_completion_queue_functor* cb, - int ok) { - static_cast(cb)->Run(static_cast(ok)); - } - void Run(bool ok) { - void* ignored = req_; - bool new_ok = ok; - GPR_ASSERT(!req_->FinalizeResult(&ignored, &new_ok)); - GPR_ASSERT(ignored == req_); - - int count = - static_cast(gpr_atm_no_barrier_fetch_add( - &req_->server_ - ->callback_unmatched_reqs_count_[req_->method_index_], - -1)) - - 1; - if (!ok) { - // The call has been shutdown. - // Delete its contents to free up the request. - 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. - 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_); - if (!new_req->Request()) { - // 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_], - -1); - delete new_req; - } - } - - // Bind the call, deadline, and metadata from what we got - req_->ctx_.set_call(req_->call_); - req_->ctx_.cq_ = req_->cq_; - req_->ctx_.BindDeadlineAndMetadata(req_->deadline_, - &req_->request_metadata_); - req_->request_metadata_.count = 0; - - // 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_ != nullptr) - ? req_->method_->method_type() - : internal::RpcMethod::BIDI_STREAMING, - req_->server_->interceptor_creators_)); - - req_->interceptor_methods_.SetCall(call_); - req_->interceptor_methods_.SetReverse(); - // Set interception point for RECV INITIAL METADATA - req_->interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA); - req_->interceptor_methods_.SetRecvInitialMetadata( - &req_->ctx_.client_metadata_); - - if (req_->has_request_payload_) { - // Set interception point for RECV MESSAGE - req_->request_ = req_->method_->handler()->Deserialize( - req_->call_, req_->request_payload_, &req_->request_status_); - req_->request_payload_ = nullptr; - req_->interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_MESSAGE); - req_->interceptor_methods_.SetRecvMessage(req_->request_, nullptr); - } - - if (req_->interceptor_methods_.RunInterceptors( - [this] { ContinueRunAfterInterception(); })) { - ContinueRunAfterInterception(); - } else { - // There were interceptors to be run, so ContinueRunAfterInterception - // will be run when interceptors are done. - } - } - void ContinueRunAfterInterception() { - 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_; - } - })); - } - }; - - void Clear() { - if (call_details_) { - delete call_details_; - call_details_ = nullptr; - } - grpc_metadata_array_destroy(&request_metadata_); - if (has_request_payload_ && request_payload_) { - grpc_byte_buffer_destroy(request_payload_); - } - ctx_.Clear(); - interceptor_methods_.ClearState(); - } - - void Setup() { - gpr_atm_no_barrier_fetch_add( - &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; - request_ = nullptr; - request_status_ = Status(); - } - - Server* const server_; - const size_t method_index_; - internal::RpcServiceMethod* const method_; - void* const method_tag_; - const bool has_request_payload_; - grpc_byte_buffer* request_payload_; - void* request_; - Status request_status_; - grpc_call_details* call_details_ = nullptr; - grpc_call* call_; - gpr_timespec deadline_; - grpc_metadata_array request_metadata_; - CompletionQueue* cq_; - CallbackCallTag tag_; - 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 -class Server::SyncRequestThreadManager : public ThreadManager { - public: - SyncRequestThreadManager(Server* server, CompletionQueue* server_cq, - std::shared_ptr global_callbacks, - grpc_resource_quota* rq, int min_pollers, - int max_pollers, int cq_timeout_msec) - : ThreadManager("SyncServer", rq, min_pollers, max_pollers), - server_(server), - server_cq_(server_cq), - cq_timeout_msec_(cq_timeout_msec), - global_callbacks_(std::move(global_callbacks)) {} - - WorkStatus PollForWork(void** tag, bool* ok) override { - *tag = nullptr; - // TODO(ctiller): workaround for GPR_TIMESPAN based deadlines not working - // right now - gpr_timespec deadline = - gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis(cq_timeout_msec_, GPR_TIMESPAN)); - - switch (server_cq_->AsyncNext(tag, ok, deadline)) { - case CompletionQueue::TIMEOUT: - return TIMEOUT; - case CompletionQueue::SHUTDOWN: - return SHUTDOWN; - case CompletionQueue::GOT_EVENT: - return WORK_FOUND; - } - - GPR_UNREACHABLE_CODE(return TIMEOUT); - } - - void DoWork(void* tag, bool ok, bool resources) override { - SyncRequest* sync_req = static_cast(tag); - - if (!sync_req) { - // No tag. Nothing to work on. This is an unlikley scenario and possibly a - // bug in RPC Manager implementation. - gpr_log(GPR_ERROR, "Sync server. DoWork() was called with NULL tag"); - return; - } - - if (ok) { - // Calldata takes ownership of the completion queue and interceptors - // inside sync_req - auto* cd = new SyncRequest::CallData(server_, sync_req); - // Prepare for the next request - if (!IsShutdown()) { - sync_req->SetupRequest(); // Create new completion queue for sync_req - sync_req->Request(server_->c_server(), server_cq_->cq()); - } - - GPR_TIMER_SCOPE("cd.Run()", 0); - cd->Run(global_callbacks_, resources); - } - // TODO (sreek) If ok is false here (which it isn't in case of - // grpc_request_registered_call), we should still re-queue the request - // object - } - - void AddSyncMethod(internal::RpcServiceMethod* method, void* tag) { - sync_requests_.emplace_back(new SyncRequest(method, tag)); - } - - void AddUnknownSyncMethod() { - if (!sync_requests_.empty()) { - unknown_method_.reset(new internal::RpcServiceMethod( - "unknown", internal::RpcMethod::BIDI_STREAMING, - new internal::UnknownMethodHandler)); - sync_requests_.emplace_back( - new SyncRequest(unknown_method_.get(), nullptr)); - } - } - - void Shutdown() override { - ThreadManager::Shutdown(); - server_cq_->Shutdown(); - } - - void Wait() override { - ThreadManager::Wait(); - // Drain any pending items from the queue - void* tag; - bool ok; - while (server_cq_->Next(&tag, &ok)) { - if (ok) { - // If a request was pulled off the queue, it means that the thread - // handling the request added it to the completion queue after shutdown - // was called - because the thread had already started and checked the - // shutdown flag before shutdown was called. In this case, we simply - // clean it up here, *after* calling wait on all the worker threads, at - // which point we are certain no in-flight requests will add more to the - // queue. This fixes an intermittent memory leak on shutdown. - SyncRequest* sync_req = static_cast(tag); - sync_req->PostShutdownCleanup(); - } - } - } - - void Start() { - if (!sync_requests_.empty()) { - for (auto m = sync_requests_.begin(); m != sync_requests_.end(); m++) { - (*m)->SetupRequest(); - (*m)->Request(server_->c_server(), server_cq_->cq()); - } - - Initialize(); // ThreadManager's Initialize() - } - } - - private: - Server* server_; - CompletionQueue* server_cq_; - int cq_timeout_msec_; - std::vector> sync_requests_; - std::unique_ptr unknown_method_; - std::shared_ptr global_callbacks_; -}; - -static internal::GrpcLibraryInitializer g_gli_initializer; -Server::Server( - int max_receive_message_size, ChannelArguments* args, - std::shared_ptr>> - sync_server_cqs, - int min_pollers, int max_pollers, int sync_cq_timeout_msec, - grpc_resource_quota* server_rq, - std::vector< - std::unique_ptr> - interceptor_creators) - : interceptor_creators_(std::move(interceptor_creators)), - max_receive_message_size_(max_receive_message_size), - sync_server_cqs_(std::move(sync_server_cqs)), - started_(false), - shutdown_(false), - shutdown_notified_(false), - server_(nullptr), - server_initializer_(new ServerInitializer(this)), - health_check_service_disabled_(false) { - g_gli_initializer.summon(); - gpr_once_init(&g_once_init_callbacks, InitGlobalCallbacks); - global_callbacks_ = g_callbacks; - global_callbacks_->UpdateArguments(args); - - if (sync_server_cqs_ != nullptr) { - bool default_rq_created = false; - if (server_rq == nullptr) { - server_rq = grpc_resource_quota_create("SyncServer-default-rq"); - grpc_resource_quota_set_max_threads(server_rq, - DEFAULT_MAX_SYNC_SERVER_THREADS); - default_rq_created = true; - } - - for (const auto& it : *sync_server_cqs_) { - sync_req_mgrs_.emplace_back(new SyncRequestThreadManager( - this, it.get(), global_callbacks_, server_rq, min_pollers, - max_pollers, sync_cq_timeout_msec)); - } - - if (default_rq_created) { - grpc_resource_quota_unref(server_rq); - } - } - - grpc_channel_args channel_args; - args->SetChannelArgs(&channel_args); - - for (size_t i = 0; i < channel_args.num_args; i++) { - if (0 == - strcmp(channel_args.args[i].key, kHealthCheckServiceInterfaceArg)) { - if (channel_args.args[i].value.pointer.p == nullptr) { - health_check_service_disabled_ = true; - } else { - health_check_service_.reset(static_cast( - channel_args.args[i].value.pointer.p)); - } - break; - } - } - - server_ = grpc_server_create(&channel_args, nullptr); -} - -Server::~Server() { - { - std::unique_lock lock(mu_); - if (callback_cq_ != nullptr) { - callback_cq_->Shutdown(); - } - if (started_ && !shutdown_) { - lock.unlock(); - Shutdown(); - } else if (!started_) { - // Shutdown the completion queues - for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { - (*it)->Shutdown(); - } - } - } - - grpc_server_destroy(server_); - 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(gpr_atm_no_barrier_load(&per_method_count)) == - 0); - } -} - -void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) { - GPR_ASSERT(!g_callbacks); - GPR_ASSERT(callbacks); - g_callbacks.reset(callbacks); -} - -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( - "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr), - std::vector< - std::unique_ptr>()); -} - -std::shared_ptr -Server::experimental_type::InProcessChannelWithInterceptors( - const ChannelArguments& args, - std::vector< - std::unique_ptr> - interceptor_creators) { - grpc_channel_args channel_args = args.c_channel_args(); - return CreateChannelInternal( - "inproc", - grpc_inproc_channel_create(server_->server_, &channel_args, nullptr), - std::move(interceptor_creators)); -} - -static grpc_server_register_method_payload_handling PayloadHandlingForMethod( - internal::RpcServiceMethod* method) { - switch (method->method_type()) { - case internal::RpcMethod::NORMAL_RPC: - case internal::RpcMethod::SERVER_STREAMING: - return GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER; - case internal::RpcMethod::CLIENT_STREAMING: - case internal::RpcMethod::BIDI_STREAMING: - return GRPC_SRM_PAYLOAD_NONE; - } - GPR_UNREACHABLE_CODE(return GRPC_SRM_PAYLOAD_NONE;); -} - -bool Server::RegisterService(const grpc::string* host, Service* service) { - bool has_async_methods = service->has_async_methods(); - if (has_async_methods) { - GPR_ASSERT(service->server_ == nullptr && - "Can only register an asynchronous service against one server."); - service->server_ = this; - } - - 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. - continue; - } - - internal::RpcServiceMethod* method = it->get(); - void* method_registration_tag = grpc_server_register_method( - server_, method->name(), host ? host->c_str() : nullptr, - PayloadHandlingForMethod(method), 0); - if (method_registration_tag == nullptr) { - gpr_log(GPR_DEBUG, "Attempt to register %s multiple times", - method->name()); - return false; - } - - if (method->handler() == nullptr) { // Async method without handler - method->set_server_tag(method_registration_tag); - } else if (method->api_type() == - internal::RpcServiceMethod::ApiType::SYNC) { - for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { - (*it)->AddSyncMethod(method, method_registration_tag); - } - } else { - // a callback method. Register at least some callback requests - 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, method, method_registration_tag)); - } - // Enqueue it so that it will be Request'ed later after all request - // matchers are created at core server startup - } - - method_name = method->name(); - } - - // Parse service name. - if (method_name != nullptr) { - std::stringstream ss(method_name); - grpc::string service_name; - if (std::getline(ss, service_name, '/') && - std::getline(ss, service_name, '/')) { - services_.push_back(service_name); - } - } - return true; -} - -void Server::RegisterAsyncGenericService(AsyncGenericService* service) { - GPR_ASSERT(service->server_ == nullptr && - "Can only register an async generic service against one server."); - service->server_ = this; - 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, - ServerCredentials* creds) { - GPR_ASSERT(!started_); - int port = creds->AddPortToServer(addr, server_); - global_callbacks_->AddPort(this, addr, creds, port); - return port; -} - -void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { - GPR_ASSERT(!started_); - global_callbacks_->PreServerStart(this); - started_ = true; - - // Only create default health check service when user did not provide an - // explicit one. - ServerCompletionQueue* health_check_cq = nullptr; - DefaultHealthCheckService::HealthCheckServiceImpl* - default_health_check_service_impl = nullptr; - if (health_check_service_ == nullptr && !health_check_service_disabled_ && - DefaultHealthCheckServiceEnabled()) { - auto* default_hc_service = new DefaultHealthCheckService; - health_check_service_.reset(default_hc_service); - // We create a non-polling CQ to avoid impacting application - // performance. This ensures that we don't introduce thread hops - // for application requests that wind up on this CQ, which is polled - // in its own thread. - health_check_cq = - new ServerCompletionQueue(GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING, nullptr); - grpc_server_register_completion_queue(server_, health_check_cq->cq(), - nullptr); - default_health_check_service_impl = - default_hc_service->GetHealthCheckService( - std::unique_ptr(health_check_cq)); - 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_) { - for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { - (*it)->AddUnknownSyncMethod(); - } - - for (size_t i = 0; i < num_cqs; i++) { - if (cqs[i]->IsFrequentlyPolled()) { - new UnimplementedAsyncRequest(this, cqs[i]); - } - } - if (health_check_cq != nullptr) { - new UnimplementedAsyncRequest(this, health_check_cq); - } - } - - // If this server has any support for synchronous methods (has any sync - // server CQs), make sure that we have a ResourceExhausted handler - // to deal with the case of thread exhaustion - if (sync_server_cqs_ != nullptr && !sync_server_cqs_->empty()) { - resource_exhausted_handler_.reset(new internal::ResourceExhaustedHandler); - } - - for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { - (*it)->Start(); - } - - 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(); - } -} - -void Server::ShutdownInternal(gpr_timespec deadline) { - std::unique_lock lock(mu_); - 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() { - std::unique_lock lock(mu_); - while (started_ && !shutdown_notified_) { - shutdown_cv_.wait(lock); - } -} - -void Server::PerformOpsOnCall(internal::CallOpSetInterface* ops, - internal::Call* call) { - ops->FillOps(call); -} - ServerInterface::BaseAsyncRequest::BaseAsyncRequest( ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, @@ -1272,32 +249,6 @@ bool ServerInterface::GenericAsyncRequest::FinalizeResult(void** tag, return BaseAsyncRequest::FinalizeResult(tag, status); } -bool Server::UnimplementedAsyncRequest::FinalizeResult(void** tag, - bool* status) { - if (GenericAsyncRequest::FinalizeResult(tag, status)) { - // We either had no interceptors run or we are done intercepting - if (*status) { - new UnimplementedAsyncRequest(server_, cq_); - new UnimplementedAsyncResponse(this); - } else { - delete this; - } - } else { - // The tag was swallowed due to interception. We will see it again. - } - return false; -} - -Server::UnimplementedAsyncResponse::UnimplementedAsyncResponse( - UnimplementedAsyncRequest* request) - : request_(request) { - Status status(StatusCode::UNIMPLEMENTED, ""); - internal::UnknownMethodHandler::FillOps(request_->context(), this); - request_->stream()->call_.PerformOps(this); -} - -ServerInitializer* Server::initializer() { return server_initializer_.get(); } - namespace { class ShutdownCallback : public grpc_experimental_completion_queue_functor { public: @@ -1319,13 +270,1066 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { }; } // namespace -CompletionQueue* Server::CallbackCQ() { +} // namespace grpc + +namespace grpc_impl { + +/// Use private inheritance rather than composition only to establish order +/// of construction, since the public base class should be constructed after the +/// elements belonging to the private base class are constructed. This is not +/// possible using true composition. +class Server::UnimplementedAsyncRequest final + : private grpc::UnimplementedAsyncRequestContext, + public GenericAsyncRequest { + public: + UnimplementedAsyncRequest(Server* server, grpc::ServerCompletionQueue* cq) + : GenericAsyncRequest(server, &server_context_, &generic_stream_, cq, cq, + nullptr, false), + server_(server), + cq_(cq) {} + + bool FinalizeResult(void** tag, bool* status) override; + + grpc::ServerContext* context() { return &server_context_; } + grpc::GenericServerAsyncReaderWriter* stream() { return &generic_stream_; } + + private: + Server* const server_; + grpc::ServerCompletionQueue* const cq_; +}; + +/// UnimplementedAsyncResponse should not post user-visible completions to the +/// C++ completion queue, but is generated as a CQ event by the core +class Server::UnimplementedAsyncResponse final + : public grpc::internal::CallOpSet { + public: + UnimplementedAsyncResponse(UnimplementedAsyncRequest* request); + ~UnimplementedAsyncResponse() { delete request_; } + + bool FinalizeResult(void** tag, bool* status) override { + if (grpc::internal::CallOpSet< + grpc::internal::CallOpSendInitialMetadata, + grpc::internal::CallOpServerSendStatus>::FinalizeResult(tag, status)) { + delete this; + } else { + // The tag was swallowed due to interception. We will see it again. + } + return false; + } + + private: + UnimplementedAsyncRequest* const request_; +}; + +class Server::SyncRequest final : public grpc::internal::CompletionQueueTag { + public: + SyncRequest(grpc::internal::RpcServiceMethod* method, void* method_tag) + : method_(method), + method_tag_(method_tag), + in_flight_(false), + has_request_payload_( + method->method_type() == grpc::internal::RpcMethod::NORMAL_RPC || + method->method_type() == grpc::internal::RpcMethod::SERVER_STREAMING), + call_details_(nullptr), + cq_(nullptr) { + grpc_metadata_array_init(&request_metadata_); + } + + ~SyncRequest() { + if (call_details_) { + delete call_details_; + } + grpc_metadata_array_destroy(&request_metadata_); + } + + void SetupRequest() { cq_ = grpc_completion_queue_create_for_pluck(nullptr); } + + void TeardownRequest() { + grpc_completion_queue_destroy(cq_); + cq_ = nullptr; + } + + void Request(grpc_server* server, grpc_completion_queue* notify_cq) { + GPR_ASSERT(cq_ && !in_flight_); + in_flight_ = true; + if (method_tag_) { + if (grpc_server_request_registered_call( + server, method_tag_, &call_, &deadline_, &request_metadata_, + has_request_payload_ ? &request_payload_ : nullptr, cq_, + notify_cq, this) != GRPC_CALL_OK) { + TeardownRequest(); + return; + } + } else { + if (!call_details_) { + call_details_ = new grpc_call_details; + grpc_call_details_init(call_details_); + } + if (grpc_server_request_call(server, &call_, call_details_, + &request_metadata_, cq_, notify_cq, + this) != GRPC_CALL_OK) { + TeardownRequest(); + return; + } + } + } + + void PostShutdownCleanup() { + if (call_) { + grpc_call_unref(call_); + call_ = nullptr; + } + if (cq_) { + grpc_completion_queue_destroy(cq_); + cq_ = nullptr; + } + } + + bool FinalizeResult(void** tag, bool* status) override { + if (!*status) { + grpc_completion_queue_destroy(cq_); + cq_ = nullptr; + } + if (call_details_) { + deadline_ = call_details_->deadline; + grpc_call_details_destroy(call_details_); + grpc_call_details_init(call_details_); + } + return true; + } + + // The CallData class represents a call that is "active" as opposed + // to just being requested. It wraps and takes ownership of the cq from + // the call request + class CallData final { + public: + explicit CallData(Server* server, SyncRequest* mrd) + : cq_(mrd->cq_), + ctx_(mrd->deadline_, &mrd->request_metadata_), + has_request_payload_(mrd->has_request_payload_), + request_payload_(has_request_payload_ ? mrd->request_payload_ + : nullptr), + request_(nullptr), + method_(mrd->method_), + call_( + mrd->call_, server, &cq_, server->max_receive_message_size(), + ctx_.set_server_rpc_info(method_->name(), method_->method_type(), + server->interceptor_creators_)), + server_(server), + global_callbacks_(nullptr), + resources_(false) { + ctx_.set_call(mrd->call_); + ctx_.cq_ = &cq_; + GPR_ASSERT(mrd->in_flight_); + mrd->in_flight_ = false; + mrd->request_metadata_.count = 0; + } + + ~CallData() { + if (has_request_payload_ && request_payload_) { + grpc_byte_buffer_destroy(request_payload_); + } + } + + void Run(const std::shared_ptr& global_callbacks, + bool resources) { + global_callbacks_ = global_callbacks; + resources_ = resources; + + interceptor_methods_.SetCall(&call_); + interceptor_methods_.SetReverse(); + // Set interception point for RECV INITIAL METADATA + interceptor_methods_.AddInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA); + interceptor_methods_.SetRecvInitialMetadata(&ctx_.client_metadata_); + + if (has_request_payload_) { + // Set interception point for RECV MESSAGE + auto* handler = resources_ ? method_->handler() + : server_->resource_exhausted_handler_.get(); + request_ = handler->Deserialize(call_.call(), request_payload_, + &request_status_); + + request_payload_ = nullptr; + interceptor_methods_.AddInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::POST_RECV_MESSAGE); + interceptor_methods_.SetRecvMessage(request_, nullptr); + } + + if (interceptor_methods_.RunInterceptors( + [this]() { ContinueRunAfterInterception(); })) { + ContinueRunAfterInterception(); + } else { + // There were interceptors to be run, so ContinueRunAfterInterception + // will be run when interceptors are done. + } + } + + void ContinueRunAfterInterception() { + { + ctx_.BeginCompletionOp(&call_, nullptr, nullptr); + global_callbacks_->PreSynchronousRequest(&ctx_); + auto* handler = resources_ ? method_->handler() + : server_->resource_exhausted_handler_.get(); + handler->RunHandler(grpc::internal::MethodHandler::HandlerParameter( + &call_, &ctx_, request_, request_status_, nullptr)); + request_ = nullptr; + global_callbacks_->PostSynchronousRequest(&ctx_); + + cq_.Shutdown(); + + grpc::internal::CompletionQueueTag* op_tag = ctx_.GetCompletionOpTag(); + cq_.TryPluck(op_tag, gpr_inf_future(GPR_CLOCK_REALTIME)); + + /* Ensure the cq_ is shutdown */ + grpc::DummyTag ignored_tag; + GPR_ASSERT(cq_.Pluck(&ignored_tag) == false); + } + delete this; + } + + private: + grpc::CompletionQueue cq_; + grpc::ServerContext ctx_; + const bool has_request_payload_; + grpc_byte_buffer* request_payload_; + void* request_; + grpc::Status request_status_; + grpc::internal::RpcServiceMethod* const method_; + grpc::internal::Call call_; + Server* server_; + std::shared_ptr global_callbacks_; + bool resources_; + grpc::internal::InterceptorBatchMethodsImpl interceptor_methods_; + }; + + private: + grpc::internal::RpcServiceMethod* const method_; + void* const method_tag_; + bool in_flight_; + const bool has_request_payload_; + grpc_call* call_; + grpc_call_details* call_details_; + gpr_timespec deadline_; + grpc_metadata_array request_metadata_; + grpc_byte_buffer* request_payload_; + grpc_completion_queue* cq_; +}; + +class Server::CallbackRequestBase : public grpc::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"); + + // 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, + grpc::internal::RpcServiceMethod* method, void* method_tag) + : server_(server), + method_index_(method_idx), + method_(method), + method_tag_(method_tag), + has_request_payload_( + method_ != nullptr && + (method->method_type() == grpc::internal::RpcMethod::NORMAL_RPC || + method->method_type() == grpc::internal::RpcMethod::SERVER_STREAMING)), + cq_(server->CallbackCQ()), + tag_(this) { + server_->callback_reqs_outstanding_++; + Setup(); + } + + ~CallbackRequest() { + Clear(); + + // 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() override { + if (method_tag_) { + if (GRPC_CALL_OK != + grpc_server_request_registered_call( + server_->c_server(), method_tag_, &call_, &deadline_, + &request_metadata_, + has_request_payload_ ? &request_payload_ : nullptr, cq_->cq(), + cq_->cq(), static_cast(&tag_))) { + return false; + } + } else { + if (!call_details_) { + call_details_ = new grpc_call_details; + grpc_call_details_init(call_details_); + } + if (grpc_server_request_call(server_->c_server(), &call_, call_details_, + &request_metadata_, cq_->cq(), cq_->cq(), + static_cast(&tag_)) != GRPC_CALL_OK) { + return false; + } + } + return true; + } + + // 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) { + functor_run = &CallbackCallTag::StaticRun; + } + + // force_run can not be performed on a tag if operations using this tag + // have been sent to PerformOpsOnCall. It is intended for error conditions + // that are detected before the operations are internally processed. + void force_run(bool ok) { Run(ok); } + + private: + Server::CallbackRequest* req_; + grpc::internal::Call* call_; + + static void StaticRun(grpc_experimental_completion_queue_functor* cb, + int ok) { + static_cast(cb)->Run(static_cast(ok)); + } + void Run(bool ok) { + void* ignored = req_; + bool new_ok = ok; + GPR_ASSERT(!req_->FinalizeResult(&ignored, &new_ok)); + GPR_ASSERT(ignored == req_); + + int count = + static_cast(gpr_atm_no_barrier_fetch_add( + &req_->server_ + ->callback_unmatched_reqs_count_[req_->method_index_], + -1)) - + 1; + if (!ok) { + // The call has been shutdown. + // Delete its contents to free up the request. + 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. + 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_); + if (!new_req->Request()) { + // 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_], + -1); + delete new_req; + } + } + + // Bind the call, deadline, and metadata from what we got + req_->ctx_.set_call(req_->call_); + req_->ctx_.cq_ = req_->cq_; + req_->ctx_.BindDeadlineAndMetadata(req_->deadline_, + &req_->request_metadata_); + req_->request_metadata_.count = 0; + + // Create a C++ Call to control the underlying core call + call_ = new (grpc_call_arena_alloc(req_->call_, sizeof(grpc::internal::Call))) + grpc::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() + : grpc::internal::RpcMethod::BIDI_STREAMING, + req_->server_->interceptor_creators_)); + + req_->interceptor_methods_.SetCall(call_); + req_->interceptor_methods_.SetReverse(); + // Set interception point for RECV INITIAL METADATA + req_->interceptor_methods_.AddInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA); + req_->interceptor_methods_.SetRecvInitialMetadata( + &req_->ctx_.client_metadata_); + + if (req_->has_request_payload_) { + // Set interception point for RECV MESSAGE + req_->request_ = req_->method_->handler()->Deserialize( + req_->call_, req_->request_payload_, &req_->request_status_); + req_->request_payload_ = nullptr; + req_->interceptor_methods_.AddInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::POST_RECV_MESSAGE); + req_->interceptor_methods_.SetRecvMessage(req_->request_, nullptr); + } + + if (req_->interceptor_methods_.RunInterceptors( + [this] { ContinueRunAfterInterception(); })) { + ContinueRunAfterInterception(); + } else { + // There were interceptors to be run, so ContinueRunAfterInterception + // will be run when interceptors are done. + } + } + void ContinueRunAfterInterception() { + auto* handler = (req_->method_ != nullptr) + ? req_->method_->handler() + : req_->server_->generic_handler_.get(); + handler->RunHandler(grpc::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_; + } + })); + } + }; + + void Clear() { + if (call_details_) { + delete call_details_; + call_details_ = nullptr; + } + grpc_metadata_array_destroy(&request_metadata_); + if (has_request_payload_ && request_payload_) { + grpc_byte_buffer_destroy(request_payload_); + } + ctx_.Clear(); + interceptor_methods_.ClearState(); + } + + void Setup() { + gpr_atm_no_barrier_fetch_add( + &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; + request_ = nullptr; + request_status_ = grpc::Status(); + } + + Server* const server_; + const size_t method_index_; + grpc::internal::RpcServiceMethod* const method_; + void* const method_tag_; + const bool has_request_payload_; + grpc_byte_buffer* request_payload_; + void* request_; + grpc::Status request_status_; + grpc_call_details* call_details_ = nullptr; + grpc_call* call_; + gpr_timespec deadline_; + grpc_metadata_array request_metadata_; + grpc::CompletionQueue* cq_; + CallbackCallTag tag_; + ServerContextType ctx_; + grpc::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_ = grpc::StringFromCopiedSlice(call_details_->method); + ctx_.host_ = grpc::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 +class Server::SyncRequestThreadManager : public grpc::ThreadManager { + public: + SyncRequestThreadManager(Server* server, grpc::CompletionQueue* server_cq, + std::shared_ptr global_callbacks, + grpc_resource_quota* rq, int min_pollers, + int max_pollers, int cq_timeout_msec) + : ThreadManager("SyncServer", rq, min_pollers, max_pollers), + server_(server), + server_cq_(server_cq), + cq_timeout_msec_(cq_timeout_msec), + global_callbacks_(std::move(global_callbacks)) {} + + WorkStatus PollForWork(void** tag, bool* ok) override { + *tag = nullptr; + // TODO(ctiller): workaround for GPR_TIMESPAN based deadlines not working + // right now + gpr_timespec deadline = + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis(cq_timeout_msec_, GPR_TIMESPAN)); + + switch (server_cq_->AsyncNext(tag, ok, deadline)) { + case grpc::CompletionQueue::TIMEOUT: + return TIMEOUT; + case grpc::CompletionQueue::SHUTDOWN: + return SHUTDOWN; + case grpc::CompletionQueue::GOT_EVENT: + return WORK_FOUND; + } + + GPR_UNREACHABLE_CODE(return TIMEOUT); + } + + void DoWork(void* tag, bool ok, bool resources) override { + SyncRequest* sync_req = static_cast(tag); + + if (!sync_req) { + // No tag. Nothing to work on. This is an unlikley scenario and possibly a + // bug in RPC Manager implementation. + gpr_log(GPR_ERROR, "Sync server. DoWork() was called with NULL tag"); + return; + } + + if (ok) { + // Calldata takes ownership of the completion queue and interceptors + // inside sync_req + auto* cd = new SyncRequest::CallData(server_, sync_req); + // Prepare for the next request + if (!IsShutdown()) { + sync_req->SetupRequest(); // Create new completion queue for sync_req + sync_req->Request(server_->c_server(), server_cq_->cq()); + } + + GPR_TIMER_SCOPE("cd.Run()", 0); + cd->Run(global_callbacks_, resources); + } + // TODO (sreek) If ok is false here (which it isn't in case of + // grpc_request_registered_call), we should still re-queue the request + // object + } + + void AddSyncMethod(grpc::internal::RpcServiceMethod* method, void* tag) { + sync_requests_.emplace_back(new SyncRequest(method, tag)); + } + + void AddUnknownSyncMethod() { + if (!sync_requests_.empty()) { + unknown_method_.reset(new grpc::internal::RpcServiceMethod( + "unknown", grpc::internal::RpcMethod::BIDI_STREAMING, + new grpc::internal::UnknownMethodHandler)); + sync_requests_.emplace_back( + new SyncRequest(unknown_method_.get(), nullptr)); + } + } + + void Shutdown() override { + ThreadManager::Shutdown(); + server_cq_->Shutdown(); + } + + void Wait() override { + ThreadManager::Wait(); + // Drain any pending items from the queue + void* tag; + bool ok; + while (server_cq_->Next(&tag, &ok)) { + if (ok) { + // If a request was pulled off the queue, it means that the thread + // handling the request added it to the completion queue after shutdown + // was called - because the thread had already started and checked the + // shutdown flag before shutdown was called. In this case, we simply + // clean it up here, *after* calling wait on all the worker threads, at + // which point we are certain no in-flight requests will add more to the + // queue. This fixes an intermittent memory leak on shutdown. + SyncRequest* sync_req = static_cast(tag); + sync_req->PostShutdownCleanup(); + } + } + } + + void Start() { + if (!sync_requests_.empty()) { + for (auto m = sync_requests_.begin(); m != sync_requests_.end(); m++) { + (*m)->SetupRequest(); + (*m)->Request(server_->c_server(), server_cq_->cq()); + } + + Initialize(); // ThreadManager's Initialize() + } + } + + private: + Server* server_; + grpc::CompletionQueue* server_cq_; + int cq_timeout_msec_; + std::vector> sync_requests_; + std::unique_ptr unknown_method_; + std::shared_ptr global_callbacks_; +}; + +static grpc::internal::GrpcLibraryInitializer g_gli_initializer; +Server::Server( + int max_receive_message_size, grpc::ChannelArguments* args, + std::shared_ptr>> + sync_server_cqs, + int min_pollers, int max_pollers, int sync_cq_timeout_msec, + grpc_resource_quota* server_rq, + std::vector< + std::unique_ptr> + interceptor_creators) + : interceptor_creators_(std::move(interceptor_creators)), + max_receive_message_size_(max_receive_message_size), + sync_server_cqs_(std::move(sync_server_cqs)), + started_(false), + shutdown_(false), + shutdown_notified_(false), + server_(nullptr), + server_initializer_(new grpc::ServerInitializer(this)), + health_check_service_disabled_(false) { + g_gli_initializer.summon(); + gpr_once_init(&grpc::g_once_init_callbacks, grpc::InitGlobalCallbacks); + global_callbacks_ = grpc::g_callbacks; + global_callbacks_->UpdateArguments(args); + + if (sync_server_cqs_ != nullptr) { + bool default_rq_created = false; + if (server_rq == nullptr) { + server_rq = grpc_resource_quota_create("SyncServer-default-rq"); + grpc_resource_quota_set_max_threads(server_rq, + DEFAULT_MAX_SYNC_SERVER_THREADS); + default_rq_created = true; + } + + for (const auto& it : *sync_server_cqs_) { + sync_req_mgrs_.emplace_back(new SyncRequestThreadManager( + this, it.get(), global_callbacks_, server_rq, min_pollers, + max_pollers, sync_cq_timeout_msec)); + } + + if (default_rq_created) { + grpc_resource_quota_unref(server_rq); + } + } + + grpc_channel_args channel_args; + args->SetChannelArgs(&channel_args); + + for (size_t i = 0; i < channel_args.num_args; i++) { + if (0 == + strcmp(channel_args.args[i].key, grpc::kHealthCheckServiceInterfaceArg)) { + if (channel_args.args[i].value.pointer.p == nullptr) { + health_check_service_disabled_ = true; + } else { + health_check_service_.reset(static_cast( + channel_args.args[i].value.pointer.p)); + } + break; + } + } + + server_ = grpc_server_create(&channel_args, nullptr); +} + +Server::~Server() { + { + std::unique_lock lock(mu_); + if (callback_cq_ != nullptr) { + callback_cq_->Shutdown(); + } + if (started_ && !shutdown_) { + lock.unlock(); + Shutdown(); + } else if (!started_) { + // Shutdown the completion queues + for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { + (*it)->Shutdown(); + } + } + } + + grpc_server_destroy(server_); + 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(gpr_atm_no_barrier_load(&per_method_count)) == + 0); + } +} + +void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) { + GPR_ASSERT(!grpc::g_callbacks); + GPR_ASSERT(callbacks); + grpc::g_callbacks.reset(callbacks); +} + +grpc_server* Server::c_server() { return server_; } + +std::shared_ptr Server::InProcessChannel( + const grpc::ChannelArguments& args) { + grpc_channel_args channel_args = args.c_channel_args(); + return grpc::CreateChannelInternal( + "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr), + std::vector< + std::unique_ptr>()); +} + +std::shared_ptr +Server::experimental_type::InProcessChannelWithInterceptors( + const grpc::ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators) { + grpc_channel_args channel_args = args.c_channel_args(); + return grpc::CreateChannelInternal( + "inproc", + grpc_inproc_channel_create(server_->server_, &channel_args, nullptr), + std::move(interceptor_creators)); +} + +static grpc_server_register_method_payload_handling PayloadHandlingForMethod( + grpc::internal::RpcServiceMethod* method) { + switch (method->method_type()) { + case grpc::internal::RpcMethod::NORMAL_RPC: + case grpc::internal::RpcMethod::SERVER_STREAMING: + return GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER; + case grpc::internal::RpcMethod::CLIENT_STREAMING: + case grpc::internal::RpcMethod::BIDI_STREAMING: + return GRPC_SRM_PAYLOAD_NONE; + } + GPR_UNREACHABLE_CODE(return GRPC_SRM_PAYLOAD_NONE;); +} + +bool Server::RegisterService(const grpc::string* host, grpc::Service* service) { + bool has_async_methods = service->has_async_methods(); + if (has_async_methods) { + GPR_ASSERT(service->server_ == nullptr && + "Can only register an asynchronous service against one server."); + service->server_ = this; + } + + 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. + continue; + } + + grpc::internal::RpcServiceMethod* method = it->get(); + void* method_registration_tag = grpc_server_register_method( + server_, method->name(), host ? host->c_str() : nullptr, + PayloadHandlingForMethod(method), 0); + if (method_registration_tag == nullptr) { + gpr_log(GPR_DEBUG, "Attempt to register %s multiple times", + method->name()); + return false; + } + + if (method->handler() == nullptr) { // Async method without handler + method->set_server_tag(method_registration_tag); + } else if (method->api_type() == + grpc::internal::RpcServiceMethod::ApiType::SYNC) { + for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { + (*it)->AddSyncMethod(method, method_registration_tag); + } + } else { + // a callback method. Register at least some callback requests + 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, method, method_registration_tag)); + } + // Enqueue it so that it will be Request'ed later after all request + // matchers are created at core server startup + } + + method_name = method->name(); + } + + // Parse service name. + if (method_name != nullptr) { + std::stringstream ss(method_name); + grpc::string service_name; + if (std::getline(ss, service_name, '/') && + std::getline(ss, service_name, '/')) { + services_.push_back(service_name); + } + } + return true; +} + +void Server::RegisterAsyncGenericService(grpc::AsyncGenericService* service) { + GPR_ASSERT(service->server_ == nullptr && + "Can only register an async generic service against one server."); + service->server_ = this; + has_async_generic_service_ = true; +} + +void Server::RegisterCallbackGenericService( + grpc::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, + grpc::ServerCredentials* creds) { + GPR_ASSERT(!started_); + int port = creds->AddPortToServer(addr, server_); + global_callbacks_->AddPort(this, addr, creds, port); + return port; +} + +void Server::Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) { + GPR_ASSERT(!started_); + global_callbacks_->PreServerStart(this); + started_ = true; + + // Only create default health check service when user did not provide an + // explicit one. + grpc::ServerCompletionQueue* health_check_cq = nullptr; + grpc::DefaultHealthCheckService::HealthCheckServiceImpl* + default_health_check_service_impl = nullptr; + if (health_check_service_ == nullptr && !health_check_service_disabled_ && + grpc::DefaultHealthCheckServiceEnabled()) { + auto* default_hc_service = new grpc::DefaultHealthCheckService; + health_check_service_.reset(default_hc_service); + // We create a non-polling CQ to avoid impacting application + // performance. This ensures that we don't introduce thread hops + // for application requests that wind up on this CQ, which is polled + // in its own thread. + health_check_cq = + new grpc::ServerCompletionQueue(GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING, nullptr); + grpc_server_register_completion_queue(server_, health_check_cq->cq(), + nullptr); + default_health_check_service_impl = + default_hc_service->GetHealthCheckService( + std::unique_ptr(health_check_cq)); + 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 grpc::experimental::CallbackGenericService); + RegisterCallbackGenericService(unimplemented_service_.get()); + } + + grpc_server_start(server_); + + if (!has_async_generic_service_ && !has_callback_generic_service_) { + for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { + (*it)->AddUnknownSyncMethod(); + } + + for (size_t i = 0; i < num_cqs; i++) { + if (cqs[i]->IsFrequentlyPolled()) { + new UnimplementedAsyncRequest(this, cqs[i]); + } + } + if (health_check_cq != nullptr) { + new UnimplementedAsyncRequest(this, health_check_cq); + } + } + + // If this server has any support for synchronous methods (has any sync + // server CQs), make sure that we have a ResourceExhausted handler + // to deal with the case of thread exhaustion + if (sync_server_cqs_ != nullptr && !sync_server_cqs_->empty()) { + resource_exhausted_handler_.reset(new grpc::internal::ResourceExhaustedHandler); + } + + for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { + (*it)->Start(); + } + + 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(); + } +} + +void Server::ShutdownInternal(gpr_timespec deadline) { + std::unique_lock lock(mu_); + if (shutdown_) { + return; + } + + shutdown_ = true; + + /// The completion queue to use for server shutdown completion notification + grpc::CompletionQueue shutdown_cq; + grpc::ShutdownTag shutdown_tag; // Dummy shutdown tag + grpc_server_shutdown_and_notify(server_, shutdown_cq.cq(), &shutdown_tag); + + shutdown_cq.Shutdown(); + + void* tag; + bool ok; + grpc::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 == grpc::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() { + std::unique_lock lock(mu_); + while (started_ && !shutdown_notified_) { + shutdown_cv_.wait(lock); + } +} + +void Server::PerformOpsOnCall(grpc::internal::CallOpSetInterface* ops, + grpc::internal::Call* call) { + ops->FillOps(call); +} + +bool Server::UnimplementedAsyncRequest::FinalizeResult(void** tag, + bool* status) { + if (GenericAsyncRequest::FinalizeResult(tag, status)) { + // We either had no interceptors run or we are done intercepting + if (*status) { + new UnimplementedAsyncRequest(server_, cq_); + new UnimplementedAsyncResponse(this); + } else { + delete this; + } + } else { + // The tag was swallowed due to interception. We will see it again. + } + return false; +} + +Server::UnimplementedAsyncResponse::UnimplementedAsyncResponse( + UnimplementedAsyncRequest* request) + : request_(request) { + grpc::Status status(grpc::StatusCode::UNIMPLEMENTED, ""); + grpc::internal::UnknownMethodHandler::FillOps(request_->context(), this); + request_->stream()->call_.PerformOps(this); +} + +grpc::ServerInitializer* Server::initializer() { return server_initializer_.get(); } + +grpc::CompletionQueue* Server::CallbackCQ() { // TODO(vjpai): Consider using a single global CQ for the default CQ // if there is no explicit per-server CQ registered std::lock_guard l(mu_); if (callback_cq_ == nullptr) { - auto* shutdown_callback = new ShutdownCallback; - callback_cq_ = new CompletionQueue(grpc_completion_queue_attributes{ + auto* shutdown_callback = new grpc::ShutdownCallback; + callback_cq_ = new grpc::CompletionQueue(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING, shutdown_callback}); @@ -1335,4 +1339,4 @@ CompletionQueue* Server::CallbackCQ() { return callback_cq_; } -} // namespace grpc +} // namespace grpc_impl diff --git a/test/cpp/util/metrics_server.h b/test/cpp/util/metrics_server.h index 2d6ddf08043..08f6034c28e 100644 --- a/test/cpp/util/metrics_server.h +++ b/test/cpp/util/metrics_server.h @@ -21,6 +21,8 @@ #include #include +#include + #include "src/proto/grpc/testing/metrics.grpc.pb.h" #include "src/proto/grpc/testing/metrics.pb.h" From 3ddcbb2aceda52529888006e35b4189454b018fa Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 20 Mar 2019 14:34:34 -0700 Subject: [PATCH 1525/2143] 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 1526/2143] 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 1527/2143] 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 3f3f1772221302d708ecf79ea641c2ea24ecbb6d Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 20 Mar 2019 16:08:53 -0700 Subject: [PATCH 1528/2143] Fix route guide example --- examples/cpp/route_guide/route_guide_server.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/cpp/route_guide/route_guide_server.cc b/examples/cpp/route_guide/route_guide_server.cc index 5867c167128..7217bb2f8ac 100644 --- a/examples/cpp/route_guide/route_guide_server.cc +++ b/examples/cpp/route_guide/route_guide_server.cc @@ -147,24 +147,25 @@ class RouteGuideImpl final : public RouteGuide::Service { Status RouteChat(ServerContext* context, ServerReaderWriter* stream) override { - std::vector received_notes; RouteNote note; while (stream->Read(¬e)) { - for (const RouteNote& n : received_notes) { + std::unique_lock lock(mu_); + for (const RouteNote& n : received_notes_) { if (n.location().latitude() == note.location().latitude() && n.location().longitude() == note.location().longitude()) { stream->Write(n); } } - received_notes.push_back(note); + received_notes_.push_back(note); } return Status::OK; } private: - std::vector feature_list_; + std::mutex mu_; + std::vector received_notes_; }; void RunServer(const std::string& db_path) { From 3a8e9bd46559ec1fed44c9bf16cf0918706f4dbf Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 20 Mar 2019 16:41:12 -0700 Subject: [PATCH 1529/2143] 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 1530/2143] 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 1531/2143] 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 1532/2143] 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 1533/2143] 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 1534/2143] 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 1535/2143] 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 1536/2143] 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 303416080c447dae8729e1ffbe78a366f1f88a71 Mon Sep 17 00:00:00 2001 From: Thibaut Le Guilly Date: Tue, 9 Oct 2018 17:10:22 +0900 Subject: [PATCH 1537/2143] Provide access to verify_peer_callback from C# --- src/csharp/Grpc.Core/ChannelCredentials.cs | 69 +++++++++++++++++-- .../Internal/ChannelCredentialsSafeHandle.cs | 12 +++- .../Internal/NativeMethods.Generated.cs | 6 +- src/csharp/Grpc.Core/VerifyPeerContext.cs | 30 ++++++++ .../SslCredentialsTest.cs | 43 +++++++++++- src/csharp/ext/grpc_csharp_ext.c | 41 +++++++++-- .../Grpc.Core/Internal/native_methods.include | 2 +- 7 files changed, 184 insertions(+), 19 deletions(-) create mode 100644 src/csharp/Grpc.Core/VerifyPeerContext.cs diff --git a/src/csharp/Grpc.Core/ChannelCredentials.cs b/src/csharp/Grpc.Core/ChannelCredentials.cs index 3ce32f31b76..103a594bb06 100644 --- a/src/csharp/Grpc.Core/ChannelCredentials.cs +++ b/src/csharp/Grpc.Core/ChannelCredentials.cs @@ -18,9 +18,11 @@ using System; using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading.Tasks; using Grpc.Core.Internal; +using Grpc.Core.Logging; using Grpc.Core.Utils; namespace Grpc.Core @@ -104,20 +106,36 @@ namespace Grpc.Core } } + /// + /// Callback invoked with the expected targetHost and the peer's certificate. + /// If false is returned by this callback then it is treated as a + /// verification failure. Invocation of the callback is blocking, so any + /// implementation should be light-weight. + /// + /// The associated with the callback + /// true if verification succeeded, false otherwise. + /// Note: experimental API that can change or be removed without any prior notice. + public delegate bool VerifyPeerCallback(VerifyPeerContext context); + /// /// Client-side SSL credentials. /// public sealed class SslCredentials : ChannelCredentials { + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType(); + readonly string rootCertificates; readonly KeyCertificatePair keyCertificatePair; + readonly VerifyPeerCallback verifyPeerCallback; + readonly VerifyPeerCallbackInternal verifyPeerCallbackInternal; + readonly GCHandle gcHandle; /// /// Creates client-side SSL credentials loaded from /// disk file pointed to by the GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment variable. /// If that fails, gets the roots certificates from a well known place on disk. /// - public SslCredentials() : this(null, null) + public SslCredentials() : this(null, null, null) { } @@ -125,19 +143,37 @@ namespace Grpc.Core /// Creates client-side SSL credentials from /// a string containing PEM encoded root certificates. /// - public SslCredentials(string rootCertificates) : this(rootCertificates, null) + public SslCredentials(string rootCertificates) : this(rootCertificates, null, null) { } - + /// /// Creates client-side SSL credentials. /// /// string containing PEM encoded server root certificates. /// a key certificate pair. - public SslCredentials(string rootCertificates, KeyCertificatePair keyCertificatePair) + public SslCredentials(string rootCertificates, KeyCertificatePair keyCertificatePair) : + this(rootCertificates, keyCertificatePair, null) + { + } + + /// + /// Creates client-side SSL credentials. + /// + /// string containing PEM encoded server root certificates. + /// a key certificate pair. + /// a callback to verify peer's target name and certificate. + /// Note: experimental API that can change or be removed without any prior notice. + public SslCredentials(string rootCertificates, KeyCertificatePair keyCertificatePair, VerifyPeerCallback verifyPeerCallback) { this.rootCertificates = rootCertificates; this.keyCertificatePair = keyCertificatePair; + if (verifyPeerCallback != null) + { + this.verifyPeerCallback = verifyPeerCallback; + this.verifyPeerCallbackInternal = this.VerifyPeerCallbackHandler; + gcHandle = GCHandle.Alloc(verifyPeerCallbackInternal); + } } /// @@ -171,7 +207,30 @@ namespace Grpc.Core internal override ChannelCredentialsSafeHandle CreateNativeCredentials() { - return ChannelCredentialsSafeHandle.CreateSslCredentials(rootCertificates, keyCertificatePair); + return ChannelCredentialsSafeHandle.CreateSslCredentials(rootCertificates, keyCertificatePair, this.verifyPeerCallbackInternal); + } + + private int VerifyPeerCallbackHandler(IntPtr host, IntPtr pem, IntPtr userData, bool isDestroy) + { + if (isDestroy) + { + this.gcHandle.Free(); + return 0; + } + + try + { + var context = new VerifyPeerContext(Marshal.PtrToStringAnsi(host), Marshal.PtrToStringAnsi(pem)); + + return this.verifyPeerCallback(context) ? 0 : 1; + } + catch (Exception e) + { + // eat the exception, we must not throw when inside callback from native code. + Logger.Error(e, "Exception occurred while invoking verify peer callback handler."); + // Return validation failure in case of exception. + return 1; + } } } diff --git a/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs index 11b5d2cc3f6..5e336673153 100644 --- a/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs @@ -20,6 +20,12 @@ using System.Threading.Tasks; namespace Grpc.Core.Internal { + internal delegate int VerifyPeerCallbackInternal( + IntPtr targetHost, + IntPtr targetPem, + IntPtr userData, + bool isDestroy); + /// /// grpc_channel_credentials from grpc/grpc_security.h /// @@ -38,15 +44,15 @@ namespace Grpc.Core.Internal return creds; } - public static ChannelCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, KeyCertificatePair keyCertPair) + public static ChannelCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, KeyCertificatePair keyCertPair, VerifyPeerCallbackInternal verifyPeerCallback) { if (keyCertPair != null) { - return Native.grpcsharp_ssl_credentials_create(pemRootCerts, keyCertPair.CertificateChain, keyCertPair.PrivateKey); + return Native.grpcsharp_ssl_credentials_create(pemRootCerts, keyCertPair.CertificateChain, keyCertPair.PrivateKey, verifyPeerCallback); } else { - return Native.grpcsharp_ssl_credentials_create(pemRootCerts, null, null); + return Native.grpcsharp_ssl_credentials_create(pemRootCerts, null, null, verifyPeerCallback); } } diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs index b7b9a12d8a3..e09b9813f79 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs @@ -482,7 +482,7 @@ namespace Grpc.Core.Internal public delegate void grpcsharp_channel_args_set_integer_delegate(ChannelArgsSafeHandle args, UIntPtr index, string key, int value); public delegate void grpcsharp_channel_args_destroy_delegate(IntPtr args); public delegate void grpcsharp_override_default_ssl_roots_delegate(string pemRootCerts); - public delegate ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create_delegate(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey); + public delegate ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create_delegate(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, VerifyPeerCallbackInternal verifyPeerCallback); public delegate ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create_delegate(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds); public delegate void grpcsharp_channel_credentials_release_delegate(IntPtr credentials); public delegate ChannelSafeHandle grpcsharp_insecure_channel_create_delegate(string target, ChannelArgsSafeHandle channelArgs); @@ -676,7 +676,7 @@ namespace Grpc.Core.Internal public static extern void grpcsharp_override_default_ssl_roots(string pemRootCerts); [DllImport(ImportName)] - public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey); + public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, VerifyPeerCallbackInternal verifyPeerCallback); [DllImport(ImportName)] public static extern ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds); @@ -972,7 +972,7 @@ namespace Grpc.Core.Internal public static extern void grpcsharp_override_default_ssl_roots(string pemRootCerts); [DllImport(ImportName)] - public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey); + public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, VerifyPeerCallbackInternal verifyPeerCallback); [DllImport(ImportName)] public static extern ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds); diff --git a/src/csharp/Grpc.Core/VerifyPeerContext.cs b/src/csharp/Grpc.Core/VerifyPeerContext.cs new file mode 100644 index 00000000000..b48984b093c --- /dev/null +++ b/src/csharp/Grpc.Core/VerifyPeerContext.cs @@ -0,0 +1,30 @@ +namespace Grpc.Core +{ + /// + /// Verification context for VerifyPeerCallback. + /// Note: experimental API that can change or be removed without any prior notice. + /// + public class VerifyPeerContext + { + /// + /// Initializes a new instance of the class. + /// + /// string containing the host name of the peer. + /// string containing PEM encoded certificate of the peer. + internal VerifyPeerContext(string targetHost, string targetPem) + { + this.TargetHost = targetHost; + this.TargetPem = targetPem; + } + + /// + /// String containing the host name of the peer. + /// + public string TargetHost { get; } + + /// + /// string containing PEM encoded certificate of the peer. + /// + public string TargetPem { get; } + } +} diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs index b3c47c2d8d3..818ac6d1adc 100644 --- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs @@ -44,17 +44,23 @@ namespace Grpc.IntegrationTesting string rootCert; KeyCertificatePair keyCertPair; + string certChain; + List options; + bool isHostEqual; + bool isPemEqual; public void InitClientAndServer(bool clientAddKeyCertPair, SslClientCertificateRequestType clientCertRequestType) { rootCert = File.ReadAllText(TestCredentials.ClientCertAuthorityPath); + certChain = File.ReadAllText(TestCredentials.ServerCertChainPath); + certChain = certChain.Replace("\r", string.Empty); keyCertPair = new KeyCertificatePair( - File.ReadAllText(TestCredentials.ServerCertChainPath), + certChain, File.ReadAllText(TestCredentials.ServerPrivateKeyPath)); var serverCredentials = new SslServerCredentials(new[] { keyCertPair }, rootCert, clientCertRequestType); - var clientCredentials = clientAddKeyCertPair ? new SslCredentials(rootCert, keyCertPair) : new SslCredentials(rootCert); + var clientCredentials = clientAddKeyCertPair ? new SslCredentials(rootCert, keyCertPair, context => this.VerifyPeerCallback(context, true)) : new SslCredentials(rootCert); // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) @@ -64,7 +70,7 @@ namespace Grpc.IntegrationTesting }; server.Start(); - var options = new List + options = new List { new ChannelOption(ChannelOptions.SslTargetNameOverride, TestCredentials.DefaultHostOverride) }; @@ -210,6 +216,37 @@ namespace Grpc.IntegrationTesting Assert.AreEqual(12345, response.AggregatedPayloadSize); } + [Test] + public void VerifyPeerCallbackTest() + { + InitClientAndServer(true, SslClientCertificateRequestType.RequestAndRequireAndVerify); + + // Force GC collection to verify that the VerifyPeerCallback is not collected. If + // it gets collected, this test will hang. + GC.Collect(); + + client.UnaryCall(new SimpleRequest { ResponseSize = 10 }); + Assert.IsTrue(isHostEqual); + Assert.IsTrue(isPemEqual); + } + + [Test] + public void VerifyPeerCallbackFailTest() + { + InitClientAndServer(true, SslClientCertificateRequestType.RequestAndRequireAndVerify); + var clientCredentials = new SslCredentials(rootCert, keyCertPair, context => this.VerifyPeerCallback(context, false)); + var failingChannel = new Channel(Host, server.Ports.Single().BoundPort, clientCredentials, options); + var failingClient = new TestService.TestServiceClient(failingChannel); + Assert.Throws(() => failingClient.UnaryCall(new SimpleRequest { ResponseSize = 10 })); + } + + private bool VerifyPeerCallback(VerifyPeerContext context, bool returnValue) + { + isHostEqual = TestCredentials.DefaultHostOverride == context.TargetHost; + isPemEqual = certChain == context.TargetPem; + return returnValue; + } + private class SslCredentialsTestServiceImpl : TestService.TestServiceBase { public override Task UnaryCall(SimpleRequest request, ServerCallContext context) diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index dc690a6a608..5f80d3417a5 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -927,20 +927,53 @@ grpcsharp_override_default_ssl_roots(const char* pem_root_certs) { grpc_set_ssl_roots_override_callback(override_ssl_roots_handler); } +typedef int(GPR_CALLTYPE* grpcsharp_verify_peer_func)(const char* target_host, + const char* target_pem, + void* userdata, + int32_t isDestroy); + +static void grpcsharp_verify_peer_destroy_handler(void* userdata) { + grpcsharp_verify_peer_func callback = + (grpcsharp_verify_peer_func)(intptr_t)userdata; + callback(NULL, NULL, NULL, 1); +} + +static int grpcsharp_verify_peer_handler(const char* target_host, + const char* target_pem, + void* userdata) { + grpcsharp_verify_peer_func callback = + (grpcsharp_verify_peer_func)(intptr_t)userdata; + return callback(target_host, target_pem, NULL, 0); +} + + GPR_EXPORT grpc_channel_credentials* GPR_CALLTYPE grpcsharp_ssl_credentials_create(const char* pem_root_certs, const char* key_cert_pair_cert_chain, - const char* key_cert_pair_private_key) { + const char* key_cert_pair_private_key, + grpcsharp_verify_peer_func verify_peer_func) { grpc_ssl_pem_key_cert_pair key_cert_pair; + verify_peer_options verify_options; + verify_peer_options* p_verify_options = NULL; + if (verify_peer_func != NULL) { + verify_options.verify_peer_callback_userdata = + (void*)(intptr_t)verify_peer_func; + verify_options.verify_peer_destruct = + grpcsharp_verify_peer_destroy_handler; + verify_options.verify_peer_callback = grpcsharp_verify_peer_handler; + p_verify_options = &verify_options; + } + if (key_cert_pair_cert_chain || key_cert_pair_private_key) { key_cert_pair.cert_chain = key_cert_pair_cert_chain; key_cert_pair.private_key = key_cert_pair_private_key; - return grpc_ssl_credentials_create(pem_root_certs, &key_cert_pair, NULL, - NULL); + return grpc_ssl_credentials_create(pem_root_certs, &key_cert_pair, + p_verify_options, NULL); } else { GPR_ASSERT(!key_cert_pair_cert_chain); GPR_ASSERT(!key_cert_pair_private_key); - return grpc_ssl_credentials_create(pem_root_certs, NULL, NULL, NULL); + return grpc_ssl_credentials_create(pem_root_certs, NULL, p_verify_options, + NULL); } } diff --git a/templates/src/csharp/Grpc.Core/Internal/native_methods.include b/templates/src/csharp/Grpc.Core/Internal/native_methods.include index b7a8e285488..4cb71730529 100644 --- a/templates/src/csharp/Grpc.Core/Internal/native_methods.include +++ b/templates/src/csharp/Grpc.Core/Internal/native_methods.include @@ -44,7 +44,7 @@ native_method_signatures = [ '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_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, VerifyPeerCallbackInternal verifyPeerCallback)', '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)', From 9a41671cb10e645dd490fdf3d3b7c7345e105d81 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 21 Mar 2019 14:22:06 -0700 Subject: [PATCH 1538/2143] Remove grpc:: from API to ensure general availability --- test/cpp/ext/filters/census/stats_plugin_end2end_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1b40ca42254..0638c3343e6 100644 --- a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc +++ b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc @@ -59,7 +59,7 @@ class EchoServer final : public EchoTestService::Service { class StatsPluginEnd2EndTest : public ::testing::Test { protected: - static void SetUpTestCase() { grpc::RegisterOpenCensusPlugin(); } + static void SetUpTestCase() { RegisterOpenCensusPlugin(); } void SetUp() { // Set up a synchronous server on a different thread to avoid the asynch From 0a5113093689d0d4101a876566f9a1381846cdba Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Thu, 21 Mar 2019 15:35:29 -0700 Subject: [PATCH 1539/2143] 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 1540/2143] 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 1541/2143] 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 1542/2143] 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 4260fe1147240cd8ceb6bc4a2c292f6a1e5e9c96 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 21 Mar 2019 17:51:28 -0700 Subject: [PATCH 1543/2143] More fixes --- src/cpp/ext/filters/census/grpc_plugin.h | 7 ++----- test/cpp/microbenchmarks/bm_opencensus_plugin.cc | 7 +++++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cpp/ext/filters/census/grpc_plugin.h b/src/cpp/ext/filters/census/grpc_plugin.h index 209fad139ce..993faae0a94 100644 --- a/src/cpp/ext/filters/census/grpc_plugin.h +++ b/src/cpp/ext/filters/census/grpc_plugin.h @@ -22,14 +22,11 @@ #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 { - -class ServerContext; -} namespace grpc { +class ServerContext; // The tag keys set when recording RPC stats. ::opencensus::stats::TagKey ClientMethodTagKey(); diff --git a/test/cpp/microbenchmarks/bm_opencensus_plugin.cc b/test/cpp/microbenchmarks/bm_opencensus_plugin.cc index c3fa6f3031a..0b376c0a0c3 100644 --- a/test/cpp/microbenchmarks/bm_opencensus_plugin.cc +++ b/test/cpp/microbenchmarks/bm_opencensus_plugin.cc @@ -29,9 +29,12 @@ #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/cpp/microbenchmarks/helpers.h" +using ::grpc::RegisterOpenCensusPlugin; +using ::grpc::RegisterOpenCensusViewsForExport; + absl::once_flag once; void RegisterOnce() { - absl::call_once(once, grpc::RegisterOpenCensusPlugin); + absl::call_once(once, RegisterOpenCensusPlugin); } class EchoServer final : public grpc::testing::EchoTestService::Service { @@ -102,7 +105,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(); + RegisterOpenCensusViewsForExport(); EchoServerThread server; std::unique_ptr stub = From d93959853f45d7e0725030a3ca6bd9f341ba6255 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 21 Mar 2019 18:00:48 -0700 Subject: [PATCH 1544/2143] Enabled Windows Bazel build for cpp tests --- bazel/BUILD | 13 ++++++++ bazel/grpc_build_system.bzl | 31 ++++++++++++++++--- test/core/bad_connection/BUILD | 1 + test/core/client_channel/BUILD | 1 + test/core/end2end/generate_tests.bzl | 23 +++++++++++--- 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 + .../cpp/thread_manager/thread_manager_test.cc | 3 +- tools/remote_build/README.md | 6 ++++ tools/remote_build/windows.bazelrc | 3 ++ 18 files changed, 113 insertions(+), 11 deletions(-) create mode 100644 tools/remote_build/windows.bazelrc diff --git a/bazel/BUILD b/bazel/BUILD index 32402892cc3..4b581709f20 100644 --- a/bazel/BUILD +++ b/bazel/BUILD @@ -29,3 +29,16 @@ cc_grpc_library( proto_only = True, deps = [], ) + +environment(name = "windows_msvc") + +environment(name = "non_windows_msvc") + +environment_group( + name = "os", + defaults = [":non_windows_msvc"], + environments = [ + ":non_windows_msvc", + ":windows_msvc", + ], +) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 2a09022c64c..a2f3c200fa7 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"] +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"]) @@ -117,6 +124,7 @@ def grpc_cc_library( ], alwayslink = alwayslink, data = data, + tags = tags, ) def grpc_proto_plugin(name, srcs = [], deps = []): @@ -159,9 +167,23 @@ 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: - native.cc_test(testonly = True, tags = ["manual"], **args) + native.cc_test( + testonly = True, + tags = (["manual"] if not is_msvc() else tags), + name = name, + srcs = srcs, + args = args["args"], + data = data, + deps = deps + _get_external_deps(external_deps), + copts = copts, + linkopts = if_not_windows(["-pthread"]), + size = size, + timeout = timeout, + exec_compatible_with = exec_compatible_with, + ) for poller in POLLERS: native.sh_test( name = name + "@poller=" + poller, @@ -175,13 +197,13 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data poller, "$(location %s)" % name, ] + args["args"], - tags = tags, + tags = tags if is_msvc() else tags + ["no_windows"], exec_compatible_with = exec_compatible_with, ) 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"] @@ -195,6 +217,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/test/core/bad_connection/BUILD b/test/core/bad_connection/BUILD index 8ada933e796..82b38ccc469 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 = ["no_windows"], ) diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD index 57e5191af4c..68a71632daf 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 = ["no_windows"], ) grpc_cc_test( diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 79c079bcc73..8020780a909 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"] @@ -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, ) @@ -120,10 +122,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), @@ -152,6 +155,7 @@ END2END_NOSEC_FIXTURES = { dns_resolver = False, _platforms = ["linux", "mac", "posix"], secure = False, + supports_msvc = False, ), } @@ -453,6 +457,16 @@ def grpc_end2end_nosec_tests(): continue if topt.secure: continue + native.sh_test( + name = "%s_nosec_test@%s" % (f, t), + data = [":%s_nosec_test" % f], + srcs = ["end2end_test.sh"], + args = [ + "$(location %s_nosec_test)" % f, + t, + ], + tags = ["no_windows"], + ) for poller in POLLERS: native.sh_test( name = "%s_nosec_test@%s@poller=%s" % (f, t, poller), @@ -463,4 +477,5 @@ def grpc_end2end_nosec_tests(): t, poller, ], + tags = ["no_windows"], ) diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 5e4338aee37..1aefa0ab224 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 = ["no_windows"], ) grpc_cc_test( @@ -92,6 +93,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -103,6 +105,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -139,6 +142,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -153,6 +157,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -214,6 +219,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -225,6 +231,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -237,6 +244,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -259,6 +267,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -303,4 +312,5 @@ 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 01699b26add..b67c1995ff7 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 = ["no_windows"], ) grpc_cc_test( diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 998ba8e1e4e..707a628148e 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 = ["no_windows"], ) grpc_cc_test( @@ -633,6 +634,7 @@ 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 f36494d98db..6cf4719c17b 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 = ["no_windows"], ) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 70b4000780c..6e844a6dc62 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 = ["no_windows"], ) grpc_cc_binary( @@ -52,6 +53,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_closure.cc"], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -59,6 +61,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_alarm.cc"], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -66,6 +69,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_arena.cc"], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -73,6 +77,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_byte_buffer.cc"], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -80,6 +85,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_channel.cc"], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -87,6 +93,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_call_create.cc"], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -94,6 +101,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_cq.cc"], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -101,6 +109,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_cq_multiple_threads.cc"], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -108,6 +117,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_error.cc"], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_library( @@ -117,6 +127,7 @@ grpc_cc_library( "fullstack_streaming_ping_pong.h", ], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -126,6 +137,7 @@ grpc_cc_binary( "bm_fullstack_streaming_ping_pong.cc", ], deps = [":fullstack_streaming_ping_pong_h"], + tags = ["no_windows"], ) grpc_cc_library( @@ -144,6 +156,7 @@ grpc_cc_binary( "bm_fullstack_streaming_pump.cc", ], deps = [":fullstack_streaming_pump_h"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -151,6 +164,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_fullstack_trickle.cc"], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_library( @@ -169,6 +183,7 @@ grpc_cc_binary( "bm_fullstack_unary_ping_pong.cc", ], deps = [":fullstack_unary_ping_pong_h"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -176,6 +191,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_metadata.cc"], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -183,6 +199,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_chttp2_hpack.cc"], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -202,4 +219,5 @@ 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 f36021560c1..589176762e6 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 = ["no_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 = ["no_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 = ["no_windows"], ) diff --git a/test/cpp/performance/BUILD b/test/cpp/performance/BUILD index 4fe95d5905e..6068c33f95f 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 = ["no_windows"], ) diff --git a/test/cpp/qps/qps_benchmark_script.bzl b/test/cpp/qps/qps_benchmark_script.bzl index 855caa0d37c..b4767ec8e09 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", + "no_windows", ], ) diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD index 050b83f5c4f..a4811031691 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 = ["no_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 = ["no_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 = ["no_windows"], ) diff --git a/test/cpp/server/load_reporter/BUILD b/test/cpp/server/load_reporter/BUILD index 8d876c56d29..db5c93263ad 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 = ["no_windows"], ) grpc_cc_test( diff --git a/test/cpp/thread_manager/thread_manager_test.cc b/test/cpp/thread_manager/thread_manager_test.cc index 99de5a3e010..ee7252bf78d 100644 --- a/test/cpp/thread_manager/thread_manager_test.cc +++ b/test/cpp/thread_manager/thread_manager_test.cc @@ -21,13 +21,12 @@ #include #include -#include #include #include #include -#include "src/cpp/thread_manager/thread_manager.h" #include "test/cpp/util/test_config.h" +#include "src/cpp/thread_manager/thread_manager.h" namespace grpc { 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 new file mode 100644 index 00000000000..70575372d02 --- /dev/null +++ b/tools/remote_build/windows.bazelrc @@ -0,0 +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 From ecfc107f32d659e6a90b280b8dcce31586410536 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 21 Mar 2019 18:40:00 -0700 Subject: [PATCH 1545/2143] Make more changes to remove grpc qualifier from tests --- include/grpcpp/security/server_credentials.h | 27 ++++++++++++++++- .../grpcpp/security/server_credentials_impl.h | 29 ++----------------- src/cpp/server/secure_server_credentials.cc | 2 +- test/cpp/util/grpc_tool_test.cc | 2 +- test/cpp/util/test_credentials_provider.cc | 3 +- 5 files changed, 32 insertions(+), 31 deletions(-) diff --git a/include/grpcpp/security/server_credentials.h b/include/grpcpp/security/server_credentials.h index f1318b6fb0d..484671ea63d 100644 --- a/include/grpcpp/security/server_credentials.h +++ b/include/grpcpp/security/server_credentials.h @@ -24,7 +24,32 @@ namespace grpc { typedef ::grpc_impl::ServerCredentials ServerCredentials; -typedef ::grpc_impl::SslServerCredentialsOptions SslServerCredentialsOptions; + +/// Options to create ServerCredentials with SSL +struct SslServerCredentialsOptions { + /// \warning Deprecated + SslServerCredentialsOptions() + : force_client_auth(false), + client_certificate_request(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE) {} + SslServerCredentialsOptions( + grpc_ssl_client_certificate_request_type request_type) + : force_client_auth(false), client_certificate_request(request_type) {} + + struct PemKeyCertPair { + grpc::string private_key; + grpc::string cert_chain; + }; + grpc::string pem_root_certs; + std::vector pem_key_cert_pairs; + /// \warning Deprecated + bool force_client_auth; + + /// If both \a force_client_auth and \a client_certificate_request + /// fields are set, \a force_client_auth takes effect, i.e. + /// \a REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY + /// will be enforced. + grpc_ssl_client_certificate_request_type client_certificate_request; +}; static inline std::shared_ptr SslServerCredentials( const SslServerCredentialsOptions& options) { diff --git a/include/grpcpp/security/server_credentials_impl.h b/include/grpcpp/security/server_credentials_impl.h index f78de305f26..dbd194e402a 100644 --- a/include/grpcpp/security/server_credentials_impl.h +++ b/include/grpcpp/security/server_credentials_impl.h @@ -31,6 +31,7 @@ struct grpc_server; namespace grpc { class Server; +struct SslServerCredentialsOptions; } // namespace grpc namespace grpc_impl { @@ -56,35 +57,9 @@ class ServerCredentials { grpc_server* server) = 0; }; -/// Options to create ServerCredentials with SSL -struct SslServerCredentialsOptions { - /// \warning Deprecated - SslServerCredentialsOptions() - : force_client_auth(false), - client_certificate_request(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE) {} - SslServerCredentialsOptions( - grpc_ssl_client_certificate_request_type request_type) - : force_client_auth(false), client_certificate_request(request_type) {} - - struct PemKeyCertPair { - grpc::string private_key; - grpc::string cert_chain; - }; - grpc::string pem_root_certs; - std::vector pem_key_cert_pairs; - /// \warning Deprecated - bool force_client_auth; - - /// If both \a force_client_auth and \a client_certificate_request - /// fields are set, \a force_client_auth takes effect, i.e. - /// \a REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY - /// will be enforced. - grpc_ssl_client_certificate_request_type client_certificate_request; -}; - /// Builds SSL ServerCredentials given SSL specific options std::shared_ptr SslServerCredentials( - const SslServerCredentialsOptions& options); + const grpc::SslServerCredentialsOptions& options); /// Builds insecure server credentials. std::shared_ptr InsecureServerCredentials(); diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc index fc23ba25d6f..f2219fb2972 100644 --- a/src/cpp/server/secure_server_credentials.cc +++ b/src/cpp/server/secure_server_credentials.cc @@ -111,7 +111,7 @@ void SecureServerCredentials::SetAuthMetadataProcessor( } std::shared_ptr SslServerCredentials( - const SslServerCredentialsOptions& options) { + const grpc::SslServerCredentialsOptions& options) { std::vector pem_key_cert_pairs; for (auto key_cert_pair = options.pem_key_cert_pairs.begin(); key_cert_pair != options.pem_key_cert_pairs.end(); key_cert_pair++) { diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index 5707e6b85fa..57cdbeb7b76 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -246,7 +246,7 @@ class GrpcToolTest : public ::testing::Test { SslServerCredentialsOptions ssl_opts; ssl_opts.pem_root_certs = ""; ssl_opts.pem_key_cert_pairs.push_back(pkcp); - creds = grpc::SslServerCredentials(ssl_opts); + creds = SslServerCredentials(ssl_opts); } else { creds = InsecureServerCredentials(); } diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc index f08b0c2294b..49688e5cf9b 100644 --- a/test/cpp/util/test_credentials_provider.cc +++ b/test/cpp/util/test_credentials_provider.cc @@ -24,6 +24,7 @@ #include #include +#include #include "test/core/end2end/data/ssl_test_data.h" @@ -91,7 +92,7 @@ class DefaultCredentialsProvider : public CredentialsProvider { SslServerCredentialsOptions ssl_opts; ssl_opts.pem_root_certs = ""; ssl_opts.pem_key_cert_pairs.push_back(pkcp); - return grpc::SslServerCredentials(ssl_opts); + return SslServerCredentials(ssl_opts); } else { std::unique_lock lock(mu_); auto it(std::find(added_secure_type_names_.begin(), From cbb70f534b417d6826e3c501be8fdb8ad5b4ae4a Mon Sep 17 00:00:00 2001 From: kkm Date: Fri, 22 Mar 2019 00:46:52 -0700 Subject: [PATCH 1546/2143] 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 1547/2143] 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 1548/2143] 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 1549/2143] 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 1550/2143] 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 1551/2143] 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 1552/2143] 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 f26ef91c98c6f3c917b3eaec0f388b2c13c85c77 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 22 Mar 2019 08:26:10 -0700 Subject: [PATCH 1553/2143] Convert external connectivity watcher to C++. --- .../filters/client_channel/client_channel.cc | 320 ++++++++++-------- 1 file changed, 180 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 891df3baf6b..b6a9e83d33b 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -50,6 +50,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" @@ -91,7 +92,53 @@ grpc_core::TraceFlag grpc_client_channel_routing_trace( * CHANNEL-WIDE FUNCTIONS */ -struct external_connectivity_watcher; +// Forward declaration. +typedef struct client_channel_channel_data channel_data; + +namespace grpc_core { +namespace { + +class ExternalConnectivityWatcher { + public: + class WatcherList { + public: + WatcherList() { gpr_mu_init(&mu_); } + ~WatcherList() { gpr_mu_destroy(&mu_); } + + int size() const; + ExternalConnectivityWatcher* Lookup(grpc_closure* on_complete) const; + void Append(ExternalConnectivityWatcher* watcher); + void Remove(ExternalConnectivityWatcher* watcher); + + private: + // head_ is guarded by its own mutex, since the size of the list needs + // to be grabbed immediately without polling on a CQ. + mutable gpr_mu mu_; + ExternalConnectivityWatcher* head_ = nullptr; + }; + + ExternalConnectivityWatcher(channel_data* chand, grpc_polling_entity pollent, + grpc_connectivity_state* state, + grpc_closure* on_complete, + grpc_closure* watcher_timer_init); + + ~ExternalConnectivityWatcher(); + + private: + static void OnExternalWatchCompleteLocked(void* arg, grpc_error* error); + static void WatchConnectivityStateLocked(void* arg, grpc_error* ignored); + + channel_data* chand_; + grpc_polling_entity pollent_; + grpc_connectivity_state* state_; + grpc_closure* on_complete_; + grpc_closure* watcher_timer_init_; + grpc_closure my_closure_; + ExternalConnectivityWatcher* next_ = nullptr; +}; + +} // namespace +} // namespace grpc_core struct QueuedPick { LoadBalancingPolicy::PickArgs pick; @@ -99,7 +146,7 @@ struct QueuedPick { QueuedPick* next = nullptr; }; -typedef struct client_channel_channel_data { +struct client_channel_channel_data { bool deadline_checking_enabled; bool enable_retries; size_t per_rpc_retry_buffer_size; @@ -139,11 +186,10 @@ typedef struct client_channel_channel_data { 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; + grpc_core::ManualConstructor< + grpc_core::ExternalConnectivityWatcher::WatcherList> + external_connectivity_watcher_list; +}; // Forward declarations. static void start_pick_locked(void* arg, grpc_error* ignored); @@ -191,6 +237,124 @@ static void set_connectivity_state_and_picker_locked( namespace grpc_core { namespace { +// +// ExternalConnectivityWatcher::WatcherList +// + +int ExternalConnectivityWatcher::WatcherList::size() const { + MutexLock lock(&mu_); + int count = 0; + for (ExternalConnectivityWatcher* w = head_; w != nullptr; w = w->next_) { + ++count; + } + return count; +} + +ExternalConnectivityWatcher* ExternalConnectivityWatcher::WatcherList::Lookup( + grpc_closure* on_complete) const { + MutexLock lock(&mu_); + ExternalConnectivityWatcher* w = head_; + while (w != nullptr && w->on_complete_ != on_complete) { + w = w->next_; + } + return w; +} + +void ExternalConnectivityWatcher::WatcherList::Append( + ExternalConnectivityWatcher* watcher) { + GPR_ASSERT(!Lookup(watcher->on_complete_)); + MutexLock lock(&mu_); + GPR_ASSERT(watcher->next_ == nullptr); + watcher->next_ = head_; + head_ = watcher; +} + +void ExternalConnectivityWatcher::WatcherList::Remove( + ExternalConnectivityWatcher* watcher) { + MutexLock lock(&mu_); + if (watcher == head_) { + head_ = watcher->next_; + return; + } + for (ExternalConnectivityWatcher* w = head_; w != nullptr; w = w->next_) { + if (w->next_ == watcher) { + w->next_ = w->next_->next_; + return; + } + } + GPR_UNREACHABLE_CODE(return ); +} + +// +// ExternalConnectivityWatcher +// + +ExternalConnectivityWatcher::ExternalConnectivityWatcher( + channel_data* chand, grpc_polling_entity pollent, + grpc_connectivity_state* state, grpc_closure* on_complete, + grpc_closure* watcher_timer_init) + : chand_(chand), + pollent_(pollent), + state_(state), + on_complete_(on_complete), + watcher_timer_init_(watcher_timer_init) { + grpc_polling_entity_add_to_pollset_set(&pollent_, chand_->interested_parties); + GRPC_CHANNEL_STACK_REF(chand_->owning_stack, "ExternalConnectivityWatcher"); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_INIT(&my_closure_, WatchConnectivityStateLocked, this, + grpc_combiner_scheduler(chand_->combiner)), + GRPC_ERROR_NONE); +} + +ExternalConnectivityWatcher::~ExternalConnectivityWatcher() { + grpc_polling_entity_del_from_pollset_set(&pollent_, + chand_->interested_parties); + GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack, "ExternalConnectivityWatcher"); +} + +void ExternalConnectivityWatcher::OnExternalWatchCompleteLocked( + void* arg, grpc_error* error) { + ExternalConnectivityWatcher* self = + static_cast(arg); + grpc_closure* on_complete = self->on_complete_; + self->chand_->external_connectivity_watcher_list->Remove(self); + Delete(self); + GRPC_CLOSURE_SCHED(on_complete, GRPC_ERROR_REF(error)); +} + +void ExternalConnectivityWatcher::WatchConnectivityStateLocked( + void* arg, grpc_error* ignored) { + ExternalConnectivityWatcher* self = + static_cast(arg); + if (self->state_ == nullptr) { + // Handle cancellation. + GPR_ASSERT(self->watcher_timer_init_ == nullptr); + ExternalConnectivityWatcher* found = + self->chand_->external_connectivity_watcher_list->Lookup( + self->on_complete_); + if (found != nullptr) { + GPR_ASSERT(found->on_complete_ == self->on_complete_); + grpc_connectivity_state_notify_on_state_change( + &found->chand_->state_tracker, nullptr, &found->my_closure_); + } + Delete(self); + return; + } + // New watcher. + self->chand_->external_connectivity_watcher_list->Append(self); + // This assumes that the closure is scheduled on the ExecCtx scheduler + // and that GRPC_CLOSURE_RUN would run the closure immediately. + GRPC_CLOSURE_RUN(self->watcher_timer_init_, GRPC_ERROR_NONE); + GRPC_CLOSURE_INIT(&self->my_closure_, OnExternalWatchCompleteLocked, self, + grpc_combiner_scheduler(self->chand_->combiner)); + grpc_connectivity_state_notify_on_state_change( + &self->chand_->state_tracker, self->state_, &self->my_closure_); +} + +// +// ClientChannelControlHelper +// + class ClientChannelControlHelper : public LoadBalancingPolicy::ChannelControlHelper { public: @@ -402,12 +566,7 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, "client_channel"); chand->disconnect_error = GRPC_ERROR_NONE; gpr_mu_init(&chand->info_mu); - gpr_mu_init(&chand->external_connectivity_watcher_list_mu); - - gpr_mu_lock(&chand->external_connectivity_watcher_list_mu); - chand->external_connectivity_watcher_list_head = nullptr; - gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); - + chand->external_connectivity_watcher_list.Init(); chand->owning_stack = args->channel_stack; chand->deadline_checking_enabled = grpc_deadline_checking_enabled(args->channel_args); @@ -515,7 +674,7 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { 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); + chand->external_connectivity_watcher_list.Destroy(); } /************************************************************************* @@ -2875,6 +3034,10 @@ const grpc_channel_filter grpc_client_channel_filter = { "client-channel", }; +// +// functions exported to the rest of core +// + void grpc_client_channel_set_channelz_node( grpc_channel_element* elem, grpc_core::channelz::ClientChannelNode* node) { channel_data* chand = static_cast(elem->channel_data); @@ -2914,120 +3077,10 @@ grpc_connectivity_state grpc_client_channel_check_connectivity_state( return out; } -typedef struct external_connectivity_watcher { - channel_data* chand; - grpc_polling_entity pollent; - grpc_closure* on_complete; - grpc_closure* watcher_timer_init; - grpc_connectivity_state* state; - grpc_closure my_closure; - struct external_connectivity_watcher* next; -} external_connectivity_watcher; - -static external_connectivity_watcher* lookup_external_connectivity_watcher( - channel_data* chand, grpc_closure* on_complete) { - gpr_mu_lock(&chand->external_connectivity_watcher_list_mu); - external_connectivity_watcher* w = - chand->external_connectivity_watcher_list_head; - while (w != nullptr && w->on_complete != on_complete) { - w = w->next; - } - gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); - return w; -} - -static void external_connectivity_watcher_list_append( - channel_data* chand, external_connectivity_watcher* w) { - GPR_ASSERT(!lookup_external_connectivity_watcher(chand, w->on_complete)); - - gpr_mu_lock(&w->chand->external_connectivity_watcher_list_mu); - GPR_ASSERT(!w->next); - w->next = chand->external_connectivity_watcher_list_head; - chand->external_connectivity_watcher_list_head = w; - gpr_mu_unlock(&w->chand->external_connectivity_watcher_list_mu); -} - -static void external_connectivity_watcher_list_remove( - channel_data* chand, external_connectivity_watcher* to_remove) { - GPR_ASSERT( - lookup_external_connectivity_watcher(chand, to_remove->on_complete)); - gpr_mu_lock(&chand->external_connectivity_watcher_list_mu); - if (to_remove == chand->external_connectivity_watcher_list_head) { - chand->external_connectivity_watcher_list_head = to_remove->next; - gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); - return; - } - external_connectivity_watcher* w = - chand->external_connectivity_watcher_list_head; - while (w != nullptr) { - if (w->next == to_remove) { - w->next = w->next->next; - gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); - return; - } - w = w->next; - } - GPR_UNREACHABLE_CODE(return ); -} - int grpc_client_channel_num_external_connectivity_watchers( grpc_channel_element* elem) { channel_data* chand = static_cast(elem->channel_data); - int count = 0; - - gpr_mu_lock(&chand->external_connectivity_watcher_list_mu); - external_connectivity_watcher* w = - chand->external_connectivity_watcher_list_head; - while (w != nullptr) { - count++; - w = w->next; - } - gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); - - return count; -} - -static void on_external_watch_complete_locked(void* arg, grpc_error* error) { - external_connectivity_watcher* w = - static_cast(arg); - grpc_closure* follow_up = w->on_complete; - grpc_polling_entity_del_from_pollset_set(&w->pollent, - w->chand->interested_parties); - GRPC_CHANNEL_STACK_UNREF(w->chand->owning_stack, - "external_connectivity_watcher"); - external_connectivity_watcher_list_remove(w->chand, w); - gpr_free(w); - GRPC_CLOSURE_SCHED(follow_up, GRPC_ERROR_REF(error)); -} - -static void watch_connectivity_state_locked(void* arg, - grpc_error* error_ignored) { - external_connectivity_watcher* w = - static_cast(arg); - external_connectivity_watcher* found = nullptr; - if (w->state != nullptr) { - external_connectivity_watcher_list_append(w->chand, w); - // An assumption is being made that the closure is scheduled on the exec ctx - // scheduler and that GRPC_CLOSURE_RUN would run the closure immediately. - 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); - } 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); - } - grpc_polling_entity_del_from_pollset_set(&w->pollent, - w->chand->interested_parties); - GRPC_CHANNEL_STACK_UNREF(w->chand->owning_stack, - "external_connectivity_watcher"); - gpr_free(w); - } + return chand->external_connectivity_watcher_list->size(); } void grpc_client_channel_watch_connectivity_state( @@ -3035,21 +3088,8 @@ void grpc_client_channel_watch_connectivity_state( grpc_connectivity_state* state, grpc_closure* closure, grpc_closure* watcher_timer_init) { channel_data* chand = static_cast(elem->channel_data); - external_connectivity_watcher* w = - static_cast(gpr_zalloc(sizeof(*w))); - w->chand = chand; - w->pollent = pollent; - w->on_complete = closure; - w->state = state; - w->watcher_timer_init = watcher_timer_init; - grpc_polling_entity_add_to_pollset_set(&w->pollent, - chand->interested_parties); - GRPC_CHANNEL_STACK_REF(w->chand->owning_stack, - "external_connectivity_watcher"); - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_INIT(&w->my_closure, watch_connectivity_state_locked, w, - grpc_combiner_scheduler(chand->combiner)), - GRPC_ERROR_NONE); + grpc_core::New( + chand, pollent, state, closure, watcher_timer_init); } grpc_core::RefCountedPtr From 61431be32b89b6b1857b525b01b66e6aaede7018 Mon Sep 17 00:00:00 2001 From: billfeng327 Date: Fri, 22 Mar 2019 10:22:59 -0700 Subject: [PATCH 1554/2143] skipping upb on windows --- BUILD | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/BUILD b/BUILD index 9e052dcf0c2..41ab64193ae 100644 --- a/BUILD +++ b/BUILD @@ -2334,7 +2334,8 @@ grpc_cc_library( ":google_api_upb", ":proto_gen_validate_upb", ":envoy_type_upb", - ] + ], + tags = ["no_windows"], ) grpc_cc_library( @@ -2354,7 +2355,8 @@ grpc_cc_library( deps = [ ":google_api_upb", ":proto_gen_validate_upb" - ] + ], + tags = ["no_windows"], ) grpc_cc_library( @@ -2373,7 +2375,8 @@ grpc_cc_library( ], deps = [ ":google_api_upb", - ] + ], + tags = ["no_windows"], ) grpc_cc_library( @@ -2404,6 +2407,7 @@ grpc_cc_library( external_deps = [ "upb_lib", ], + tags = ["no_windows"], ) grpc_generate_one_off_targets() From 1a09899d3e5c8f7e489a25d92ff0e5f6ae00ec81 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 22 Mar 2019 11:18:39 -0700 Subject: [PATCH 1555/2143] reverted change on thread manager test --- test/cpp/thread_manager/thread_manager_test.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/cpp/thread_manager/thread_manager_test.cc b/test/cpp/thread_manager/thread_manager_test.cc index ee7252bf78d..99de5a3e010 100644 --- a/test/cpp/thread_manager/thread_manager_test.cc +++ b/test/cpp/thread_manager/thread_manager_test.cc @@ -21,12 +21,13 @@ #include #include +#include #include #include #include -#include "test/cpp/util/test_config.h" #include "src/cpp/thread_manager/thread_manager.h" +#include "test/cpp/util/test_config.h" namespace grpc { From d7e5cb70febcdc3f0ec267e2d5b01dc3e152c1d6 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 22 Mar 2019 11:27:24 -0700 Subject: [PATCH 1556/2143] flipped logic for is_msvc() --- bazel/grpc_build_system.bzl | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index a2f3c200fa7..ca87428f375 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -167,22 +167,12 @@ 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: native.cc_test( testonly = True, - tags = (["manual"] if not is_msvc() else tags), - name = name, - srcs = srcs, - args = args["args"], - data = data, - deps = deps + _get_external_deps(external_deps), - copts = copts, - linkopts = if_not_windows(["-pthread"]), - size = size, - timeout = timeout, - exec_compatible_with = exec_compatible_with, + tags = (["manual"] if is_msvc() else tags), + **args ) for poller in POLLERS: native.sh_test( @@ -197,11 +187,11 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data poller, "$(location %s)" % name, ] + args["args"], - tags = tags if is_msvc() else tags + ["no_windows"], + tags = (tags + ["no_windows"]) if is_msvc() else tags, exec_compatible_with = exec_compatible_with, ) else: - native.cc_test(**args) + native.cc_test(tags = tags, **args) def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = [], tags = []): copts = [] From d16597ab73708b683d6d3b37f0213d343678865b Mon Sep 17 00:00:00 2001 From: billfeng327 Date: Fri, 22 Mar 2019 14:33:37 -0700 Subject: [PATCH 1557/2143] corrected Bazel target generation logic for Windows --- bazel/grpc_build_system.bzl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index ca87428f375..c5eb9ec8bf3 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -169,9 +169,11 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data "exec_compatible_with": exec_compatible_with, } if uses_polling: + # Only run targets with pollers for non-MSVC + # Only run targets without pollers for MSVC native.cc_test( testonly = True, - tags = (["manual"] if is_msvc() else tags), + tags = tags if is_msvc() else ["manual"], **args ) for poller in POLLERS: From be014d005d01575fabd2cb0b580633253025e26f Mon Sep 17 00:00:00 2001 From: Doug Fawley Date: Fri, 22 Mar 2019 14:43:50 -0700 Subject: [PATCH 1558/2143] Misconfigured non-gRPC, HTTP/2 clients can sometimes connect to gRPC servers. Today, these clients will receive an HTTP status 200 (OK) with a trailer that gRPC clients would be able to interpret as an error, but non-gRPC clients would interpret as a success. In Go and Java, this will have a grpc-status of UNKNOWN due to an unexpected content-type header. In C, the content-type header is currently ignored, but a grpc-status of UNAVAILABLE will be returned if a handler for that method is not registered (which is likely in this scenario). This change updates the gRPC HTTP/2 spec to recommend returning HTTP status 400 (Bad Request) to interoperate better with non-gRPC clients. Note that we should not do any enforcement on user-agent, as the spec specifically says "the protocol does not require a user-agent to function". --- doc/PROTOCOL-HTTP2.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/PROTOCOL-HTTP2.md b/doc/PROTOCOL-HTTP2.md index a354dad8636..6b4d85db30a 100644 --- a/doc/PROTOCOL-HTTP2.md +++ b/doc/PROTOCOL-HTTP2.md @@ -61,6 +61,8 @@ the form shown above. If **Timeout** is omitted a server should assume an infinite timeout. Client implementations are free to send a default minimum timeout based on their deployment requirements. +If **Content-Type** does not begin with "application/grpc", gRPC servers SHOULD respond with HTTP status of 400 (Bad Request). This will prevent other HTTP/2 clients from interpreting a gRPC error response, which uses status 200 (OK), as successful. + **Custom-Metadata** is an arbitrary set of key-value pairs defined by the application layer. Header names starting with "grpc-" but not listed here are reserved for future GRPC use and should not be used by applications as **Custom-Metadata**. Note that HTTP2 does not allow arbitrary octet sequences for header values so binary header values must be encoded using Base64 as per https://tools.ietf.org/html/rfc4648#section-4. Implementations MUST accept padded and un-padded values and should emit un-padded values. Applications define binary headers by having their names end with "-bin". Runtime libraries use this suffix to detect binary headers and properly apply base64 encoding & decoding as headers are sent and received. @@ -255,5 +257,3 @@ to be used. * **Service-Name** → ?( {_proto package name_} "." ) {_service name_} * **Message-Type** → {_fully qualified proto message name_} * **Content-Type** → "application/grpc+proto" - - From c9e1a71c8e104a575135a8a4b1a4dc7d4aee1234 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 22 Mar 2019 16:05:04 -0700 Subject: [PATCH 1559/2143] 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 1560/2143] 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 1561/2143] 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 1562/2143] 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 1563/2143] 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 1564/2143] 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 f00508e9ce9411e8d02ed444b37ccb15a9a3e10c Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Mon, 25 Mar 2019 09:16:09 +1300 Subject: [PATCH 1565/2143] Add BindServiceAttribute --- src/compiler/csharp_generator.cc | 3 ++ .../Grpc.Core.Api/BindServiceAttribute.cs | 48 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 src/csharp/Grpc.Core.Api/BindServiceAttribute.cs diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index ac0af336f93..c0f6a21c3e0 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -382,6 +382,9 @@ void GenerateServerClass(Printer* out, const ServiceDescriptor* service) { "/// Base class for server-side implementations of " "$servicename$\n", "servicename", GetServiceClassName(service)); + out->Print( + "[grpc::BindService(typeof($classname$), nameof($classname$.BindService))]\n", + "classname", GetServiceClassName(service)); out->Print("public abstract partial class $name$\n", "name", GetServerClassName(service)); out->Print("{\n"); diff --git a/src/csharp/Grpc.Core.Api/BindServiceAttribute.cs b/src/csharp/Grpc.Core.Api/BindServiceAttribute.cs new file mode 100644 index 00000000000..e53f1878b18 --- /dev/null +++ b/src/csharp/Grpc.Core.Api/BindServiceAttribute.cs @@ -0,0 +1,48 @@ +#region Copyright notice and license +// 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. +#endregion + +using System; + +namespace Grpc.Core +{ + /// + /// Defines the location of the service bind method for a gRPC service. + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] + public class BindServiceAttribute : Attribute + { + /// + /// Initializes a new instance of the class. + /// + /// The type the service bind method is defined on. + /// The name of the service bind method. + public BindServiceAttribute(Type bindType, string bindMethodName) + { + BindType = bindType; + BindMethodName = bindMethodName; + } + + /// + /// Gets the type the service bind method is defined on. + /// + public Type BindType { get; } + + /// + /// Gets the name of the service bind method. + /// + public string BindMethodName { get; } + } +} From 688ad6373b8e17e91bd951f69d676a68f3ee8acc Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Mon, 25 Mar 2019 10:44:31 +1300 Subject: [PATCH 1566/2143] 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 1567/2143] 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 31ce7a32bb6ab98c4582db21671b7c335724cf29 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Mon, 25 Mar 2019 18:39:09 +1300 Subject: [PATCH 1568/2143] PR feedback --- src/compiler/csharp_generator.cc | 3 ++- src/csharp/Grpc.Core.Api/BindServiceAttribute.cs | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index c0f6a21c3e0..97098714590 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -383,7 +383,8 @@ void GenerateServerClass(Printer* out, const ServiceDescriptor* service) { "$servicename$\n", "servicename", GetServiceClassName(service)); out->Print( - "[grpc::BindService(typeof($classname$), nameof($classname$.BindService))]\n", + "[grpc::BindService(typeof($classname$), " + "nameof($classname$.BindService))]\n", "classname", GetServiceClassName(service)); out->Print("public abstract partial class $name$\n", "name", GetServerClassName(service)); diff --git a/src/csharp/Grpc.Core.Api/BindServiceAttribute.cs b/src/csharp/Grpc.Core.Api/BindServiceAttribute.cs index e53f1878b18..d4ac6a10570 100644 --- a/src/csharp/Grpc.Core.Api/BindServiceAttribute.cs +++ b/src/csharp/Grpc.Core.Api/BindServiceAttribute.cs @@ -19,7 +19,12 @@ using System; namespace Grpc.Core { /// - /// Defines the location of the service bind method for a gRPC service. + /// Specifies the location of the service bind method for a gRPC service. + /// The bind method is typically generated code and is used to register a service's + /// methods with the server on startup. + /// + /// The bind method signature takes a and an optional + /// instance of the service base class, e.g. static void BindService(ServiceBinderBase, GreeterService). /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] public class BindServiceAttribute : Attribute From aa61b5361bae4c67d68b3e334eb4c1532607901d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 25 Mar 2019 12:10:18 -0400 Subject: [PATCH 1569/2143] dont use nameof --- src/compiler/csharp_generator.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index 97098714590..682ce59efbf 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -384,7 +384,7 @@ void GenerateServerClass(Printer* out, const ServiceDescriptor* service) { "servicename", GetServiceClassName(service)); out->Print( "[grpc::BindService(typeof($classname$), " - "nameof($classname$.BindService))]\n", + "\"BindService\")]\n", "classname", GetServiceClassName(service)); out->Print("public abstract partial class $name$\n", "name", GetServerClassName(service)); From 30cc99d42cedece1362e9b0c519aecda3116c984 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 25 Mar 2019 10:43:10 -0700 Subject: [PATCH 1570/2143] Add Python example for error handling --- examples/python/errors/README.md | 96 +++++++++++++ .../python/errors/error_handling_client.py | 50 +++++++ .../python/errors/error_handling_server.py | 81 +++++++++++ examples/python/errors/helloworld_pb2.py | 134 ++++++++++++++++++ examples/python/errors/helloworld_pb2_grpc.py | 46 ++++++ 5 files changed, 407 insertions(+) create mode 100644 examples/python/errors/README.md create mode 100644 examples/python/errors/error_handling_client.py create mode 100644 examples/python/errors/error_handling_server.py create mode 100644 examples/python/errors/helloworld_pb2.py create mode 100644 examples/python/errors/helloworld_pb2_grpc.py diff --git a/examples/python/errors/README.md b/examples/python/errors/README.md new file mode 100644 index 00000000000..226f0e4a281 --- /dev/null +++ b/examples/python/errors/README.md @@ -0,0 +1,96 @@ +# gRPC Python Error Handling Example + +The goal of this example is sending error status from server that is more complicated than a code and detail string. + +The definition for an RPC method in proto files contains request message and response message. There are many error states that can be shared across RPC methods (e.g. stack trace, insufficient quota). Using a different path to handle error will make the code more maintainable. + +Ideally, the final status of an RPC should be described in the trailing headers of HTTP2, and gRPC Python provides helper functions in `grpcio-status` package to assist the packing and unpacking of error status. + +### Definition of Status Proto + +```proto +// The `Status` type defines a logical error model that is suitable for different +// programming environments, including REST APIs and RPC APIs. It is used by +// [gRPC](https://github.com/grpc). The error model is designed to be: +// +// - Simple to use and understand for most users +// - Flexible enough to meet unexpected needs +// +// # Overview +// +// The `Status` message contains three pieces of data: error code, error message, +// and error details. The error code should be an enum value of +// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed. The +// error message should be a developer-facing English message that helps +// developers *understand* and *resolve* the error. If a localized user-facing +// error message is needed, put the localized message in the error details or +// localize it in the client. The optional error details may contain arbitrary +// information about the error. There is a predefined set of error detail types +// in the package `google.rpc` that can be used for common error conditions. +// +// # Language mapping +// +// The `Status` message is the logical representation of the error model, but it +// is not necessarily the actual wire format. When the `Status` message is +// exposed in different client libraries and different wire protocols, it can be +// mapped differently. For example, it will likely be mapped to some exceptions +// in Java, but more likely mapped to some error codes in C. +// +// # Other uses +// +// The error model and the `Status` message can be used in a variety of +// environments, either with or without APIs, to provide a +// consistent developer experience across different environments. +// +// Example uses of this error model include: +// +// - Partial errors. If a service needs to return partial errors to the client, +// it may embed the `Status` in the normal response to indicate the partial +// errors. +// +// - Workflow errors. A typical workflow has multiple steps. Each step may +// have a `Status` message for error reporting. +// +// - Batch operations. If a client uses batch request and batch response, the +// `Status` message should be used directly inside batch response, one for +// each error sub-response. +// +// - Asynchronous operations. If an API call embeds asynchronous operation +// results in its response, the status of those operations should be +// represented directly using the `Status` message. +// +// - Logging. If some API errors are stored in logs, the message `Status` could +// be used directly after any stripping needed for security/privacy reasons. +message Status { + // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. + int32 code = 1; + + // A developer-facing error message, which should be in English. Any + // user-facing error message should be localized and sent in the + // [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. + string message = 2; + + // A list of messages that carry the error details. There is a common set of + // message types for APIs to use. + repeated google.protobuf.Any details = 3; +} +``` + +### Usage of Well-Known-Proto `Any` + +Please check [ProtoBuf Document: Any](https://developers.google.com/protocol-buffers/docs/reference/python-generated#any) + +```Python +any_message.Pack(message) +any_message.Unpack(message) +assert any_message.Is(message.DESCRIPTOR) +``` + +### Common Protos + +These protos are defined by Google Cloud API. Most error cases are covered in `error_dettails.proto`, but you may provide any custom error detail proto you want. + +Please refer to: +* [code.proto](https://github.com/googleapis/api-common-protos/blob/master/google/rpc/code.proto). +* [status.proto](https://github.com/googleapis/api-common-protos/blob/master/google/rpc/status.proto). +* [error_details.proto](https://github.com/googleapis/api-common-protos/blob/master/google/rpc/error_details.proto). diff --git a/examples/python/errors/error_handling_client.py b/examples/python/errors/error_handling_client.py new file mode 100644 index 00000000000..22a865a89bf --- /dev/null +++ b/examples/python/errors/error_handling_client.py @@ -0,0 +1,50 @@ +# 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 example handles rich error status in client-side.""" + +from __future__ import print_function +import logging + +import grpc +from grpc_status import rpc_status +from google.rpc import error_details_pb2 + +import helloworld_pb2 +import helloworld_pb2_grpc + + +def run(): + # NOTE(gRPC Python Team): .close() is possible on a channel and should be + # used in circumstances in which the with statement does not fit the needs + # of the code. + with grpc.insecure_channel('localhost:50051') as channel: + stub = helloworld_pb2_grpc.GreeterStub(channel) + try: + response = stub.SayHello(helloworld_pb2.HelloRequest(name='Alice')) + print('Call success:', response.message) + except grpc.RpcError as rpc_error: + print('Call failure:', rpc_error) + status = rpc_status.from_call(rpc_error) + for detail in status.details: + if detail.Is(error_details_pb2.QuotaFailure.DESCRIPTOR): + info = error_details_pb2.QuotaFailure() + detail.Unpack(info) + print('Quota failure:', info) + else: + print('Unexpected failure:', detail) + + +if __name__ == '__main__': + logging.basicConfig() + run() diff --git a/examples/python/errors/error_handling_server.py b/examples/python/errors/error_handling_server.py new file mode 100644 index 00000000000..c782f7d1a2d --- /dev/null +++ b/examples/python/errors/error_handling_server.py @@ -0,0 +1,81 @@ +# 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 example sends out rich error status from server-side.""" + +from concurrent import futures +import time +import logging +import threading + +import grpc +from grpc_status import rpc_status + +from google.protobuf import any_pb2 +from google.rpc import code_pb2, status_pb2, error_details_pb2 + +import helloworld_pb2 +import helloworld_pb2_grpc + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +def create_greet_limit_exceed_error_status(name): + detail = any_pb2.Any() + detail.Pack( + error_details_pb2.QuotaFailure( + violations=[ + error_details_pb2.QuotaFailure.Violation( + subject="name:%s" % name, + description="Limit one greeting per person", + ) + ],)) + return status_pb2.Status( + code=code_pb2.RESOURCE_EXHAUSTED, + message='Request limit exceeded.', + details=[detail], + ) + + +class LimitedGreeter(helloworld_pb2_grpc.GreeterServicer): + + def __init__(self): + self._lock = threading.RLock() + self._greeted = set() + + def SayHello(self, request, context): + with self._lock: + if request.name in self._greeted: + rich_status = create_greet_limit_exceed_error_status( + request.name) + context.abort_with_status(rpc_status.to_status(rich_status)) + else: + self._greeted.add(request.name) + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def serve(): + server = grpc.server(futures.ThreadPoolExecutor()) + helloworld_pb2_grpc.add_GreeterServicer_to_server(LimitedGreeter(), server) + server.add_insecure_port('[::]:50051') + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop(None) + + +if __name__ == '__main__': + logging.basicConfig() + serve() diff --git a/examples/python/errors/helloworld_pb2.py b/examples/python/errors/helloworld_pb2.py new file mode 100644 index 00000000000..e18ab9acc7a --- /dev/null +++ b/examples/python/errors/helloworld_pb2.py @@ -0,0 +1,134 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: helloworld.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 +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='helloworld.proto', + package='helloworld', + syntax='proto3', + serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3') +) + + + + +_HELLOREQUEST = _descriptor.Descriptor( + name='HelloRequest', + full_name='helloworld.HelloRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='helloworld.HelloRequest.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=32, + serialized_end=60, +) + + +_HELLOREPLY = _descriptor.Descriptor( + name='HelloReply', + full_name='helloworld.HelloReply', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='helloworld.HelloReply.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=62, + serialized_end=91, +) + +DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST +DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict( + DESCRIPTOR = _HELLOREQUEST, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloRequest) + )) +_sym_db.RegisterMessage(HelloRequest) + +HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict( + DESCRIPTOR = _HELLOREPLY, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloReply) + )) +_sym_db.RegisterMessage(HelloReply) + + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW')) + +_GREETER = _descriptor.ServiceDescriptor( + name='Greeter', + full_name='helloworld.Greeter', + file=DESCRIPTOR, + index=0, + options=None, + serialized_start=93, + serialized_end=166, + methods=[ + _descriptor.MethodDescriptor( + name='SayHello', + full_name='helloworld.Greeter.SayHello', + index=0, + containing_service=None, + input_type=_HELLOREQUEST, + output_type=_HELLOREPLY, + options=None, + ), +]) +_sym_db.RegisterServiceDescriptor(_GREETER) + +DESCRIPTOR.services_by_name['Greeter'] = _GREETER + +# @@protoc_insertion_point(module_scope) diff --git a/examples/python/errors/helloworld_pb2_grpc.py b/examples/python/errors/helloworld_pb2_grpc.py new file mode 100644 index 00000000000..18e07d16797 --- /dev/null +++ b/examples/python/errors/helloworld_pb2_grpc.py @@ -0,0 +1,46 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +import grpc + +import helloworld_pb2 as helloworld__pb2 + + +class GreeterStub(object): + """The greeting service definition. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.SayHello = channel.unary_unary( + '/helloworld.Greeter/SayHello', + request_serializer=helloworld__pb2.HelloRequest.SerializeToString, + response_deserializer=helloworld__pb2.HelloReply.FromString, + ) + + +class GreeterServicer(object): + """The greeting service definition. + """ + + def SayHello(self, request, context): + """Sends a greeting + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_GreeterServicer_to_server(servicer, server): + rpc_method_handlers = { + 'SayHello': grpc.unary_unary_rpc_method_handler( + servicer.SayHello, + request_deserializer=helloworld__pb2.HelloRequest.FromString, + response_serializer=helloworld__pb2.HelloReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'helloworld.Greeter', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) From 7a38ddfab4610526c5c58d83a37b0a0463ad65cb Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 25 Mar 2019 13:56:21 -0400 Subject: [PATCH 1571/2143] run src/csharp/generate_protos.sh --- src/csharp/Grpc.Examples/MathGrpc.cs | 1 + src/csharp/Grpc.HealthCheck/HealthGrpc.cs | 1 + src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs | 1 + src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs | 1 + src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs | 1 + .../Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs | 1 + src/csharp/Grpc.IntegrationTesting/TestGrpc.cs | 3 +++ src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs | 1 + src/csharp/Grpc.Reflection/ReflectionGrpc.cs | 1 + 9 files changed, 11 insertions(+) diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs index ba6824dd8e2..8315b2be82e 100644 --- a/src/csharp/Grpc.Examples/MathGrpc.cs +++ b/src/csharp/Grpc.Examples/MathGrpc.cs @@ -67,6 +67,7 @@ namespace Math { } /// Base class for server-side implementations of Math + [grpc::BindService(typeof(Math), "BindService")] public abstract partial class MathBase { /// diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs index 3edec5a37f8..bc7ae6cedf1 100644 --- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs +++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs @@ -54,6 +54,7 @@ namespace Grpc.Health.V1 { } /// Base class for server-side implementations of Health + [grpc::BindService(typeof(Health), "BindService")] public abstract partial class HealthBase { /// diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs index 09691d28716..00821bb41bd 100644 --- a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs @@ -74,6 +74,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of BenchmarkService + [grpc::BindService(typeof(BenchmarkService), "BindService")] public abstract partial class BenchmarkServiceBase { /// diff --git a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs index bfa3348f6a0..20f415f72de 100644 --- a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs @@ -39,6 +39,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of EmptyService + [grpc::BindService(typeof(EmptyService), "BindService")] public abstract partial class EmptyServiceBase { } diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs index 27746c07641..6e59d1eb6c1 100644 --- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs @@ -58,6 +58,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of MetricsService + [grpc::BindService(typeof(MetricsService), "BindService")] public abstract partial class MetricsServiceBase { /// diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs index f92ae8e974b..b86dfbf7ec9 100644 --- a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs @@ -46,6 +46,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of ReportQpsScenarioService + [grpc::BindService(typeof(ReportQpsScenarioService), "BindService")] public abstract partial class ReportQpsScenarioServiceBase { /// diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs index d47b5fe0d4b..c4aa5249ab9 100644 --- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs @@ -105,6 +105,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of TestService + [grpc::BindService(typeof(TestService), "BindService")] public abstract partial class TestServiceBase { /// @@ -580,6 +581,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of UnimplementedService + [grpc::BindService(typeof(UnimplementedService), "BindService")] public abstract partial class UnimplementedServiceBase { /// @@ -719,6 +721,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of ReconnectService + [grpc::BindService(typeof(ReconnectService), "BindService")] public abstract partial class ReconnectServiceBase { public virtual global::System.Threading.Tasks.Task Start(global::Grpc.Testing.ReconnectParams request, grpc::ServerCallContext context) diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs index f7dd2eecf2e..5c079a5ec43 100644 --- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs @@ -72,6 +72,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of WorkerService + [grpc::BindService(typeof(WorkerService), "BindService")] public abstract partial class WorkerServiceBase { /// diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs index 500738205a7..768879bd2a1 100644 --- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs +++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs @@ -46,6 +46,7 @@ namespace Grpc.Reflection.V1Alpha { } /// Base class for server-side implementations of ServerReflection + [grpc::BindService(typeof(ServerReflection), "BindService")] public abstract partial class ServerReflectionBase { /// From 8ef8d912a74e16f17d458c85a33fa54b4c07a4bb Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 25 Mar 2019 11:51:14 -0700 Subject: [PATCH 1572/2143] 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 f527cfbbac29a88e5a3a89a49a0338f5e7e9e256 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 25 Mar 2019 12:24:11 -0700 Subject: [PATCH 1573/2143] Adopt review's advice * Add a unit test * Integrate with Bazel * Polish README.md --- examples/protos/BUILD.bazel | 25 ++++ examples/python/errors/BUILD.bazel | 54 +++++++ examples/python/errors/README.md | 29 ++-- .../{error_handling_client.py => client.py} | 40 +++--- examples/python/errors/helloworld_pb2.py | 134 ------------------ examples/python/errors/helloworld_pb2_grpc.py | 46 ------ .../{error_handling_server.py => server.py} | 21 ++- .../test/_error_handling_example_test.py | 54 +++++++ src/python/grpcio_tests/tests/BUILD.bazel | 1 + 9 files changed, 192 insertions(+), 212 deletions(-) create mode 100644 examples/protos/BUILD.bazel create mode 100644 examples/python/errors/BUILD.bazel rename examples/python/errors/{error_handling_client.py => client.py} (57%) delete mode 100644 examples/python/errors/helloworld_pb2.py delete mode 100644 examples/python/errors/helloworld_pb2_grpc.py rename examples/python/errors/{error_handling_server.py => server.py} (86%) create mode 100644 examples/python/errors/test/_error_handling_example_test.py diff --git a/examples/protos/BUILD.bazel b/examples/protos/BUILD.bazel new file mode 100644 index 00000000000..197274e034c --- /dev/null +++ b/examples/protos/BUILD.bazel @@ -0,0 +1,25 @@ +# 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") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") + +package(default_visibility = ["//visibility:public"]) + +py_proto_library( + name = "py_helloworld_proto", + protos = ["helloworld.proto",], + with_grpc = True, + deps = [requirement('protobuf'),], +) diff --git a/examples/python/errors/BUILD.bazel b/examples/python/errors/BUILD.bazel new file mode 100644 index 00000000000..a2c3534f9bd --- /dev/null +++ b/examples/python/errors/BUILD.bazel @@ -0,0 +1,54 @@ +# 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") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") + +py_library( + name = "client", + testonly = 1, + srcs = ["client.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_status/grpc_status:grpc_status", + "//examples/protos:py_helloworld_proto", + requirement('googleapis-common-protos'), + ], +) + +py_library( + name = "server", + testonly = 1, + srcs = ["server.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_status/grpc_status:grpc_status", + "//examples/protos:py_helloworld_proto", + ] + select({ + "//conditions:default": [requirement("futures")], + "//:python3": [], + }), +) + +py_test( + name = "test/_error_handling_example_test", + srcs = ["test/_error_handling_example_test.py"], + data = [ + ":client", + ":server", + "//src/python/grpcio_tests/tests:bazel_namespace_package_hack", + ], + size = "small", + imports = ["../../../src/python/grpcio_status",], +) diff --git a/examples/python/errors/README.md b/examples/python/errors/README.md index 226f0e4a281..3c53690b99c 100644 --- a/examples/python/errors/README.md +++ b/examples/python/errors/README.md @@ -6,8 +6,27 @@ The definition for an RPC method in proto files contains request message and res Ideally, the final status of an RPC should be described in the trailing headers of HTTP2, and gRPC Python provides helper functions in `grpcio-status` package to assist the packing and unpacking of error status. + +### Requirement +``` +grpcio>=1.18.0 +grpcio-status>=1.18.0 +googleapis-common-protos>=1.5.5 +``` + + +### Error Detail Proto + +You may provide any custom proto message as error detail in your implementation. Here are protos are defined by Google Cloud Library Team: + +* [code.proto](https://github.com/googleapis/api-common-protos/blob/master/google/rpc/code.proto) contains definition of RPC error codes. +* [error_details.proto](https://github.com/googleapis/api-common-protos/blob/master/google/rpc/error_details.proto) contains definitions of common error details. + + ### Definition of Status Proto +Here is the definition of Status proto. For full text, please see [status.proto](https://github.com/googleapis/api-common-protos/blob/master/google/rpc/status.proto). + ```proto // The `Status` type defines a logical error model that is suitable for different // programming environments, including REST APIs and RPC APIs. It is used by @@ -76,6 +95,7 @@ message Status { } ``` + ### Usage of Well-Known-Proto `Any` Please check [ProtoBuf Document: Any](https://developers.google.com/protocol-buffers/docs/reference/python-generated#any) @@ -85,12 +105,3 @@ any_message.Pack(message) any_message.Unpack(message) assert any_message.Is(message.DESCRIPTOR) ``` - -### Common Protos - -These protos are defined by Google Cloud API. Most error cases are covered in `error_dettails.proto`, but you may provide any custom error detail proto you want. - -Please refer to: -* [code.proto](https://github.com/googleapis/api-common-protos/blob/master/google/rpc/code.proto). -* [status.proto](https://github.com/googleapis/api-common-protos/blob/master/google/rpc/status.proto). -* [error_details.proto](https://github.com/googleapis/api-common-protos/blob/master/google/rpc/error_details.proto). diff --git a/examples/python/errors/error_handling_client.py b/examples/python/errors/client.py similarity index 57% rename from examples/python/errors/error_handling_client.py rename to examples/python/errors/client.py index 22a865a89bf..a79b8fce1bd 100644 --- a/examples/python/errors/error_handling_client.py +++ b/examples/python/errors/client.py @@ -20,31 +20,37 @@ import grpc from grpc_status import rpc_status from google.rpc import error_details_pb2 -import helloworld_pb2 -import helloworld_pb2_grpc +from examples.protos import helloworld_pb2 +from examples.protos import helloworld_pb2_grpc + +_LOGGER = logging.getLogger(__name__) -def run(): +def process(stub): + try: + response = stub.SayHello(helloworld_pb2.HelloRequest(name='Alice')) + _LOGGER.info('Call success: %s', response.message) + except grpc.RpcError as rpc_error: + _LOGGER.error('Call failure: %s', rpc_error) + status = rpc_status.from_call(rpc_error) + for detail in status.details: + if detail.Is(error_details_pb2.QuotaFailure.DESCRIPTOR): + info = error_details_pb2.QuotaFailure() + detail.Unpack(info) + _LOGGER.error('Quota failure: %s', info) + else: + raise RuntimeError('Unexpected failure: %s' % detail) + + +def main(): # NOTE(gRPC Python Team): .close() is possible on a channel and should be # used in circumstances in which the with statement does not fit the needs # of the code. with grpc.insecure_channel('localhost:50051') as channel: stub = helloworld_pb2_grpc.GreeterStub(channel) - try: - response = stub.SayHello(helloworld_pb2.HelloRequest(name='Alice')) - print('Call success:', response.message) - except grpc.RpcError as rpc_error: - print('Call failure:', rpc_error) - status = rpc_status.from_call(rpc_error) - for detail in status.details: - if detail.Is(error_details_pb2.QuotaFailure.DESCRIPTOR): - info = error_details_pb2.QuotaFailure() - detail.Unpack(info) - print('Quota failure:', info) - else: - print('Unexpected failure:', detail) + process(stub) if __name__ == '__main__': logging.basicConfig() - run() + main() diff --git a/examples/python/errors/helloworld_pb2.py b/examples/python/errors/helloworld_pb2.py deleted file mode 100644 index e18ab9acc7a..00000000000 --- a/examples/python/errors/helloworld_pb2.py +++ /dev/null @@ -1,134 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: helloworld.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 -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='helloworld.proto', - package='helloworld', - syntax='proto3', - serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3') -) - - - - -_HELLOREQUEST = _descriptor.Descriptor( - name='HelloRequest', - full_name='helloworld.HelloRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='helloworld.HelloRequest.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=32, - serialized_end=60, -) - - -_HELLOREPLY = _descriptor.Descriptor( - name='HelloReply', - full_name='helloworld.HelloReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='message', full_name='helloworld.HelloReply.message', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=62, - serialized_end=91, -) - -DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST -DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict( - DESCRIPTOR = _HELLOREQUEST, - __module__ = 'helloworld_pb2' - # @@protoc_insertion_point(class_scope:helloworld.HelloRequest) - )) -_sym_db.RegisterMessage(HelloRequest) - -HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict( - DESCRIPTOR = _HELLOREPLY, - __module__ = 'helloworld_pb2' - # @@protoc_insertion_point(class_scope:helloworld.HelloReply) - )) -_sym_db.RegisterMessage(HelloReply) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW')) - -_GREETER = _descriptor.ServiceDescriptor( - name='Greeter', - full_name='helloworld.Greeter', - file=DESCRIPTOR, - index=0, - options=None, - serialized_start=93, - serialized_end=166, - methods=[ - _descriptor.MethodDescriptor( - name='SayHello', - full_name='helloworld.Greeter.SayHello', - index=0, - containing_service=None, - input_type=_HELLOREQUEST, - output_type=_HELLOREPLY, - options=None, - ), -]) -_sym_db.RegisterServiceDescriptor(_GREETER) - -DESCRIPTOR.services_by_name['Greeter'] = _GREETER - -# @@protoc_insertion_point(module_scope) diff --git a/examples/python/errors/helloworld_pb2_grpc.py b/examples/python/errors/helloworld_pb2_grpc.py deleted file mode 100644 index 18e07d16797..00000000000 --- a/examples/python/errors/helloworld_pb2_grpc.py +++ /dev/null @@ -1,46 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - -import helloworld_pb2 as helloworld__pb2 - - -class GreeterStub(object): - """The greeting service definition. - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.SayHello = channel.unary_unary( - '/helloworld.Greeter/SayHello', - request_serializer=helloworld__pb2.HelloRequest.SerializeToString, - response_deserializer=helloworld__pb2.HelloReply.FromString, - ) - - -class GreeterServicer(object): - """The greeting service definition. - """ - - def SayHello(self, request, context): - """Sends a greeting - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_GreeterServicer_to_server(servicer, server): - rpc_method_handlers = { - 'SayHello': grpc.unary_unary_rpc_method_handler( - servicer.SayHello, - request_deserializer=helloworld__pb2.HelloRequest.FromString, - response_serializer=helloworld__pb2.HelloReply.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'helloworld.Greeter', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) diff --git a/examples/python/errors/error_handling_server.py b/examples/python/errors/server.py similarity index 86% rename from examples/python/errors/error_handling_server.py rename to examples/python/errors/server.py index c782f7d1a2d..f49586b848a 100644 --- a/examples/python/errors/error_handling_server.py +++ b/examples/python/errors/server.py @@ -24,8 +24,8 @@ from grpc_status import rpc_status from google.protobuf import any_pb2 from google.rpc import code_pb2, status_pb2, error_details_pb2 -import helloworld_pb2 -import helloworld_pb2_grpc +from examples.protos import helloworld_pb2 +from examples.protos import helloworld_pb2_grpc _ONE_DAY_IN_SECONDS = 60 * 60 * 24 @@ -36,7 +36,7 @@ def create_greet_limit_exceed_error_status(name): error_details_pb2.QuotaFailure( violations=[ error_details_pb2.QuotaFailure.Violation( - subject="name:%s" % name, + subject="name: %s" % name, description="Limit one greeting per person", ) ],)) @@ -64,10 +64,14 @@ class LimitedGreeter(helloworld_pb2_grpc.GreeterServicer): return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) -def serve(): +def create_server(server_address): server = grpc.server(futures.ThreadPoolExecutor()) helloworld_pb2_grpc.add_GreeterServicer_to_server(LimitedGreeter(), server) - server.add_insecure_port('[::]:50051') + port = server.add_insecure_port(server_address) + return server, port + + +def serve(server): server.start() try: while True: @@ -76,6 +80,11 @@ def serve(): server.stop(None) +def main(): + server, unused_port = create_server('[::]:50051') + serve(server) + + if __name__ == '__main__': logging.basicConfig() - serve() + main() diff --git a/examples/python/errors/test/_error_handling_example_test.py b/examples/python/errors/test/_error_handling_example_test.py new file mode 100644 index 00000000000..da7f58a002e --- /dev/null +++ b/examples/python/errors/test/_error_handling_example_test.py @@ -0,0 +1,54 @@ +# 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. +"""Tests of the error handling example.""" + +import unittest +import logging + +import grpc + +from examples.protos import helloworld_pb2_grpc +from examples.python.errors import client as error_handling_client +from examples.python.errors import server as error_handling_server + +# 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 + + +class ErrorHandlingExampleTest(unittest.TestCase): + + def setUp(self): + self._server, port = error_handling_server.create_server('[::]:0') + self._server.start() + self._channel = grpc.insecure_channel('localhost:%d' % port) + + def tearDown(self): + self._channel.close() + self._server.stop(None) + + def test_error_handling_example(self): + stub = helloworld_pb2_grpc.GreeterStub(self._channel) + error_handling_client.process(stub) + error_handling_client.process(stub) + # No unhandled exception raised, test passed! + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/BUILD.bazel b/src/python/grpcio_tests/tests/BUILD.bazel index b908ab85173..b2b36ad10f3 100644 --- a/src/python/grpcio_tests/tests/BUILD.bazel +++ b/src/python/grpcio_tests/tests/BUILD.bazel @@ -4,5 +4,6 @@ py_library( visibility = [ "//src/python/grpcio_tests/tests/status:__subpackages__", "//src/python/grpcio_tests/tests/interop:__subpackages__", + "//examples/python/errors:__subpackages__", ], ) From 7771290fcd3b682e8b90ef5337895d96bc68eb68 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 25 Mar 2019 12:38:20 -0700 Subject: [PATCH 1574/2143] Pin the proto definitions to a specific commit --- examples/python/errors/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/python/errors/README.md b/examples/python/errors/README.md index 3c53690b99c..2cfc26a93b0 100644 --- a/examples/python/errors/README.md +++ b/examples/python/errors/README.md @@ -19,13 +19,13 @@ googleapis-common-protos>=1.5.5 You may provide any custom proto message as error detail in your implementation. Here are protos are defined by Google Cloud Library Team: -* [code.proto](https://github.com/googleapis/api-common-protos/blob/master/google/rpc/code.proto) contains definition of RPC error codes. -* [error_details.proto](https://github.com/googleapis/api-common-protos/blob/master/google/rpc/error_details.proto) contains definitions of common error details. +* [code.proto]([https://github.com/googleapis/api-common-protos/blob/master/google/rpc/code.proto](https://github.com/googleapis/api-common-protos/blob/87185dfffad4afa5a33a8c153f0e1ea53b4f85dc/google/rpc/code.proto)) contains definition of RPC error codes. +* [error_details.proto]([https://github.com/googleapis/api-common-protos/blob/master/google/rpc/error_details.proto](https://github.com/googleapis/api-common-protos/blob/87185dfffad4afa5a33a8c153f0e1ea53b4f85dc/google/rpc/error_details.proto)) contains definitions of common error details. ### Definition of Status Proto -Here is the definition of Status proto. For full text, please see [status.proto](https://github.com/googleapis/api-common-protos/blob/master/google/rpc/status.proto). +Here is the definition of Status proto. For full text, please see [status.proto](https://github.com/googleapis/api-common-protos/blob/87185dfffad4afa5a33a8c153f0e1ea53b4f85dc/google/rpc/status.proto). ```proto // The `Status` type defines a logical error model that is suitable for different From 5d0a5714264cf21063760c9bc8d3f2953dba8673 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 25 Mar 2019 12:41:20 -0700 Subject: [PATCH 1575/2143] 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 1576/2143] 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 1577/2143] 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 1578/2143] 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 1579/2143] 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 d7429dbb4ab257d5cb7c5ba86e20b24a12657293 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 25 Mar 2019 14:18:35 -0700 Subject: [PATCH 1580/2143] Fix the proto rules conflict --- examples/BUILD | 9 +++++++++ examples/protos/BUILD.bazel | 25 ------------------------- examples/python/errors/BUILD.bazel | 5 ++--- 3 files changed, 11 insertions(+), 28 deletions(-) delete mode 100644 examples/protos/BUILD.bazel diff --git a/examples/BUILD b/examples/BUILD index 0a1ca94a649..5e08b6cdec6 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -16,7 +16,9 @@ licenses(["notice"]) # 3-clause BSD package(default_visibility = ["//visibility:public"]) +load("@grpc_python_dependencies//:requirements.bzl", "requirement") load("//bazel:grpc_build_system.bzl", "grpc_proto_library") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") grpc_proto_library( name = "auth_sample", @@ -43,6 +45,13 @@ grpc_proto_library( srcs = ["protos/keyvaluestore.proto"], ) +py_proto_library( + name = "py_helloworld", + protos = ["protos/helloworld.proto"], + with_grpc = True, + deps = [requirement('protobuf'),], +) + cc_binary( name = "greeter_client", srcs = ["cpp/helloworld/greeter_client.cc"], diff --git a/examples/protos/BUILD.bazel b/examples/protos/BUILD.bazel deleted file mode 100644 index 197274e034c..00000000000 --- a/examples/protos/BUILD.bazel +++ /dev/null @@ -1,25 +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. - -load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") - -package(default_visibility = ["//visibility:public"]) - -py_proto_library( - name = "py_helloworld_proto", - protos = ["helloworld.proto",], - with_grpc = True, - deps = [requirement('protobuf'),], -) diff --git a/examples/python/errors/BUILD.bazel b/examples/python/errors/BUILD.bazel index a2c3534f9bd..0b56e76ee4d 100644 --- a/examples/python/errors/BUILD.bazel +++ b/examples/python/errors/BUILD.bazel @@ -13,7 +13,6 @@ # limitations under the License. load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") py_library( name = "client", @@ -22,7 +21,7 @@ py_library( deps = [ "//src/python/grpcio/grpc:grpcio", "//src/python/grpcio_status/grpc_status:grpc_status", - "//examples/protos:py_helloworld_proto", + "//examples:py_helloworld", requirement('googleapis-common-protos'), ], ) @@ -34,7 +33,7 @@ py_library( deps = [ "//src/python/grpcio/grpc:grpcio", "//src/python/grpcio_status/grpc_status:grpc_status", - "//examples/protos:py_helloworld_proto", + "//examples:py_helloworld", ] + select({ "//conditions:default": [requirement("futures")], "//:python3": [], From 621840900fefd93ab9bab5678db4c798ba1cec32 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 25 Mar 2019 14:24:11 -0700 Subject: [PATCH 1581/2143] 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 1582/2143] 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 b3d907dce965f4e6635bbefbcf0a983e7c4094c5 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 25 Mar 2019 14:41:39 -0700 Subject: [PATCH 1583/2143] Explicitly depend on :grpcio --- examples/python/errors/BUILD.bazel | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/python/errors/BUILD.bazel b/examples/python/errors/BUILD.bazel index 0b56e76ee4d..1ef36a06471 100644 --- a/examples/python/errors/BUILD.bazel +++ b/examples/python/errors/BUILD.bazel @@ -46,6 +46,8 @@ py_test( data = [ ":client", ":server", + "//src/python/grpcio/grpc:grpcio", + "//examples:py_helloworld", "//src/python/grpcio_tests/tests:bazel_namespace_package_hack", ], size = "small", From ecb3dec651b997ed8dcfbecff9856283ceb05920 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Mon, 25 Mar 2019 14:54:29 -0700 Subject: [PATCH 1584/2143] 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 1585/2143] 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 1586/2143] 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 4e0923e802afe412e369937fde35c44e96f9014f Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 25 Mar 2019 15:49:22 -0700 Subject: [PATCH 1587/2143] Fix errors from clang_format_code.sh --- test/cpp/microbenchmarks/bm_opencensus_plugin.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_opencensus_plugin.cc b/test/cpp/microbenchmarks/bm_opencensus_plugin.cc index 0b376c0a0c3..4f4884bef9b 100644 --- a/test/cpp/microbenchmarks/bm_opencensus_plugin.cc +++ b/test/cpp/microbenchmarks/bm_opencensus_plugin.cc @@ -33,9 +33,7 @@ using ::grpc::RegisterOpenCensusPlugin; using ::grpc::RegisterOpenCensusViewsForExport; absl::once_flag once; -void RegisterOnce() { - absl::call_once(once, RegisterOpenCensusPlugin); -} +void RegisterOnce() { absl::call_once(once, RegisterOpenCensusPlugin); } class EchoServer final : public grpc::testing::EchoTestService::Service { grpc::Status Echo(grpc::ServerContext* context, From e27ddbc87e8511ce23371190644fb36f8977656c Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 14 Mar 2019 14:10:26 -0700 Subject: [PATCH 1588/2143] Move ::grpc::HealthCheckServiceInterface to ::grpc_impl namespace --- BUILD | 1 + CMakeLists.txt | 3 + Makefile | 3 + build.yaml | 1 + gRPC-C++.podspec | 1 + .../grpcpp/health_check_service_interface.h | 31 +---------- .../health_check_service_interface_impl.h | 55 +++++++++++++++++++ include/grpcpp/server.h | 9 ++- src/cpp/server/server_cc.cc | 2 +- 9 files changed, 74 insertions(+), 32 deletions(-) create mode 100644 include/grpcpp/health_check_service_interface_impl.h diff --git a/BUILD b/BUILD index 12687c799ef..7be9f5adaf5 100644 --- a/BUILD +++ b/BUILD @@ -225,6 +225,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/generic/generic_stub.h", "include/grpcpp/grpcpp.h", "include/grpcpp/health_check_service_interface.h", + "include/grpcpp/health_check_service_interface_impl.h", "include/grpcpp/impl/call.h", "include/grpcpp/impl/channel_argument_option.h", "include/grpcpp/impl/client_unary_call.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index d39c1941a74..8a730469c81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3005,6 +3005,7 @@ foreach(_hdr include/grpcpp/generic/generic_stub.h include/grpcpp/grpcpp.h include/grpcpp/health_check_service_interface.h + include/grpcpp/health_check_service_interface_impl.h include/grpcpp/impl/call.h include/grpcpp/impl/channel_argument_option.h include/grpcpp/impl/client_unary_call.h @@ -3596,6 +3597,7 @@ foreach(_hdr include/grpcpp/generic/generic_stub.h include/grpcpp/grpcpp.h include/grpcpp/health_check_service_interface.h + include/grpcpp/health_check_service_interface_impl.h include/grpcpp/impl/call.h include/grpcpp/impl/channel_argument_option.h include/grpcpp/impl/client_unary_call.h @@ -4559,6 +4561,7 @@ foreach(_hdr include/grpcpp/generic/generic_stub.h include/grpcpp/grpcpp.h include/grpcpp/health_check_service_interface.h + include/grpcpp/health_check_service_interface_impl.h include/grpcpp/impl/call.h include/grpcpp/impl/channel_argument_option.h include/grpcpp/impl/client_unary_call.h diff --git a/Makefile b/Makefile index 85e621f87bb..04c1885974a 100644 --- a/Makefile +++ b/Makefile @@ -5332,6 +5332,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/generic/generic_stub.h \ include/grpcpp/grpcpp.h \ include/grpcpp/health_check_service_interface.h \ + include/grpcpp/health_check_service_interface_impl.h \ include/grpcpp/impl/call.h \ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ @@ -5931,6 +5932,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/generic/generic_stub.h \ include/grpcpp/grpcpp.h \ include/grpcpp/health_check_service_interface.h \ + include/grpcpp/health_check_service_interface_impl.h \ include/grpcpp/impl/call.h \ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ @@ -6843,6 +6845,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/generic/generic_stub.h \ include/grpcpp/grpcpp.h \ include/grpcpp/health_check_service_interface.h \ + include/grpcpp/health_check_service_interface_impl.h \ include/grpcpp/impl/call.h \ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ diff --git a/build.yaml b/build.yaml index 34b271f58de..28ecec5f979 100644 --- a/build.yaml +++ b/build.yaml @@ -1350,6 +1350,7 @@ filegroups: - include/grpcpp/generic/generic_stub.h - include/grpcpp/grpcpp.h - include/grpcpp/health_check_service_interface.h + - include/grpcpp/health_check_service_interface_impl.h - include/grpcpp/impl/call.h - include/grpcpp/impl/channel_argument_option.h - include/grpcpp/impl/client_unary_call.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 5a850bc8438..2a74bfdb533 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -91,6 +91,7 @@ Pod::Spec.new do |s| 'include/grpcpp/generic/generic_stub.h', 'include/grpcpp/grpcpp.h', 'include/grpcpp/health_check_service_interface.h', + 'include/grpcpp/health_check_service_interface_impl.h', 'include/grpcpp/impl/call.h', 'include/grpcpp/impl/channel_argument_option.h', 'include/grpcpp/impl/client_unary_call.h', diff --git a/include/grpcpp/health_check_service_interface.h b/include/grpcpp/health_check_service_interface.h index dfd4c3983af..6dde0951768 100644 --- a/include/grpcpp/health_check_service_interface.h +++ b/include/grpcpp/health_check_service_interface.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,39 +19,14 @@ #ifndef GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_H #define GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_H -#include +#include namespace grpc { const char kHealthCheckServiceInterfaceArg[] = "grpc.health_check_service_interface"; -/// The gRPC server uses this interface to expose the health checking service -/// without depending on protobuf. -class HealthCheckServiceInterface { - public: - virtual ~HealthCheckServiceInterface() {} - - /// Set or change the serving status of the given \a service_name. - virtual void SetServingStatus(const grpc::string& service_name, - bool serving) = 0; - /// Apply to all registered service names. - virtual void SetServingStatus(bool serving) = 0; - - /// Set all registered service names to not serving and prevent future - /// state changes. - virtual void Shutdown() {} -}; - -/// Enable/disable the default health checking service. This applies to all C++ -/// servers created afterwards. For each server, user can override the default -/// with a HealthCheckServiceServerBuilderOption. -/// NOT thread safe. -void EnableDefaultHealthCheckService(bool enable); - -/// Returns whether the default health checking service is enabled. -/// NOT thread safe. -bool DefaultHealthCheckServiceEnabled(); +typedef ::grpc_impl::HealthCheckServiceInterface HealthCheckServiceInterface; } // namespace grpc diff --git a/include/grpcpp/health_check_service_interface_impl.h b/include/grpcpp/health_check_service_interface_impl.h new file mode 100644 index 00000000000..025dadb4e59 --- /dev/null +++ b/include/grpcpp/health_check_service_interface_impl.h @@ -0,0 +1,55 @@ +/* + * + * 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_HEALTH_CHECK_SERVICE_INTERFACE_IMPL_H +#define GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_IMPL_H + +#include + +namespace grpc_impl { + +/// The gRPC server uses this interface to expose the health checking service +/// without depending on protobuf. +class HealthCheckServiceInterface { + public: + virtual ~HealthCheckServiceInterface() {} + + /// Set or change the serving status of the given \a service_name. + virtual void SetServingStatus(const grpc::string& service_name, + bool serving) = 0; + /// Apply to all registered service names. + virtual void SetServingStatus(bool serving) = 0; + + /// Set all registered service names to not serving and prevent future + /// state changes. + virtual void Shutdown() {} +}; + +/// Enable/disable the default health checking service. This applies to all C++ +/// servers created afterwards. For each server, user can override the default +/// with a HealthCheckServiceServerBuilderOption. +/// NOT thread safe. +void EnableDefaultHealthCheckService(bool enable); + +/// Returns whether the default health checking service is enabled. +/// NOT thread safe. +bool DefaultHealthCheckServiceEnabled(); + +} // namespace grpc_impl + +#endif // GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_IMPL_H diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index f5c99f22df2..3bbd8a2b3e2 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -40,10 +40,13 @@ struct grpc_server; +namespace grpc_impl { + +class HealthCheckServiceInterface; +} namespace grpc { class AsyncGenericService; -class HealthCheckServiceInterface; class ServerContext; class ServerInitializer; @@ -94,7 +97,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { grpc_server* c_server(); /// Returns the health check service. - HealthCheckServiceInterface* GetHealthCheckService() const { + grpc_impl::HealthCheckServiceInterface* GetHealthCheckService() const { return health_check_service_.get(); } @@ -323,7 +326,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { std::unique_ptr server_initializer_; - std::unique_ptr health_check_service_; + std::unique_ptr health_check_service_; bool health_check_service_disabled_; // When appropriate, use a default callback generic service to handle diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 26e84f1aed4..616b4738bc2 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -987,7 +987,7 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { DefaultHealthCheckService::HealthCheckServiceImpl* default_health_check_service_impl = nullptr; if (health_check_service_ == nullptr && !health_check_service_disabled_ && - DefaultHealthCheckServiceEnabled()) { + grpc_impl::DefaultHealthCheckServiceEnabled()) { auto* default_hc_service = new DefaultHealthCheckService; health_check_service_.reset(default_hc_service); // We create a non-polling CQ to avoid impacting application From b25f6da3f01f8480109528148517ce3019b1b61c Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 14 Mar 2019 17:00:34 -0700 Subject: [PATCH 1589/2143] Make changes to fix test failures --- include/grpcpp/server.h | 1 + .../health/default_health_check_service.h | 2 +- src/cpp/server/health/health_check_service.cc | 6 ++--- src/cpp/server/server_cc.cc | 2 +- test/cpp/end2end/client_lb_end2end_test.cc | 8 +++--- .../end2end/health_service_end2end_test.cc | 26 +++++++++---------- 6 files changed, 23 insertions(+), 22 deletions(-) diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 3bbd8a2b3e2..6638b098954 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h index 9551cd2e2cf..0ed8a45bb3f 100644 --- a/src/cpp/server/health/default_health_check_service.h +++ b/src/cpp/server/health/default_health_check_service.h @@ -37,7 +37,7 @@ namespace grpc { // Default implementation of HealthCheckServiceInterface. Server will create and // own it. -class DefaultHealthCheckService final : public HealthCheckServiceInterface { +class DefaultHealthCheckService final : public grpc_impl::HealthCheckServiceInterface { public: enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING }; diff --git a/src/cpp/server/health/health_check_service.cc b/src/cpp/server/health/health_check_service.cc index a0fa2d62f58..ca0b49a1ae8 100644 --- a/src/cpp/server/health/health_check_service.cc +++ b/src/cpp/server/health/health_check_service.cc @@ -16,9 +16,9 @@ * */ -#include +#include -namespace grpc { +namespace grpc_impl { namespace { bool g_grpc_default_health_check_service_enabled = false; } // namespace @@ -31,4 +31,4 @@ void EnableDefaultHealthCheckService(bool enable) { g_grpc_default_health_check_service_enabled = enable; } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 616b4738bc2..589440d6660 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -802,7 +802,7 @@ Server::Server( if (channel_args.args[i].value.pointer.p == nullptr) { health_check_service_disabled_ = true; } else { - health_check_service_.reset(static_cast( + health_check_service_.reset(static_cast( channel_args.args[i].value.pointer.p)); } break; diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 3cd06e9e28c..6856883c2af 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -1242,7 +1242,7 @@ TEST_F(ClientLbEnd2endTest, } TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthChecking) { - EnableDefaultHealthCheckService(true); + grpc_impl::EnableDefaultHealthCheckService(true); // Start servers. const int kNumServers = 3; StartServers(kNumServers); @@ -1311,11 +1311,11 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthChecking) { EXPECT_TRUE(WaitForChannelNotReady(channel.get())); CheckRpcSendFailure(stub); // Clean up. - EnableDefaultHealthCheckService(false); + grpc_impl::EnableDefaultHealthCheckService(false); } TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { - EnableDefaultHealthCheckService(true); + grpc_impl::EnableDefaultHealthCheckService(true); // Start server. const int kNumServers = 1; StartServers(kNumServers); @@ -1341,7 +1341,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1)); CheckRpcSendOk(stub2, DEBUG_LOCATION); // Clean up. - EnableDefaultHealthCheckService(false); + grpc_impl::EnableDefaultHealthCheckService(false); } class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index b96ff53a3ea..c36d6e4d296 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -285,8 +285,8 @@ class HealthServiceEnd2endTest : public ::testing::Test { }; TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceDisabled) { - EnableDefaultHealthCheckService(false); - EXPECT_FALSE(DefaultHealthCheckServiceEnabled()); + grpc_impl::EnableDefaultHealthCheckService(false); + EXPECT_FALSE(grpc_impl::DefaultHealthCheckServiceEnabled()); SetUpServer(true, false, false, nullptr); HealthCheckServiceInterface* default_service = server_->GetHealthCheckService(); @@ -298,8 +298,8 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceDisabled) { } TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { - EnableDefaultHealthCheckService(true); - EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); + grpc_impl::EnableDefaultHealthCheckService(true); + EXPECT_TRUE(grpc_impl::DefaultHealthCheckServiceEnabled()); SetUpServer(true, false, false, nullptr); VerifyHealthCheckService(); VerifyHealthCheckServiceStreaming(); @@ -311,19 +311,19 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { } TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceShutdown) { - EnableDefaultHealthCheckService(true); - EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); + grpc_impl::EnableDefaultHealthCheckService(true); + EXPECT_TRUE(grpc_impl::DefaultHealthCheckServiceEnabled()); SetUpServer(true, false, false, nullptr); VerifyHealthCheckServiceShutdown(); } // Provide an empty service to disable the default service. TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) { - EnableDefaultHealthCheckService(true); - EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); + grpc_impl::EnableDefaultHealthCheckService(true); + EXPECT_TRUE(grpc_impl::DefaultHealthCheckServiceEnabled()); std::unique_ptr empty_service; SetUpServer(true, false, true, std::move(empty_service)); - HealthCheckServiceInterface* service = server_->GetHealthCheckService(); + grpc_impl::HealthCheckServiceInterface* service = server_->GetHealthCheckService(); EXPECT_TRUE(service == nullptr); ResetStubs(); @@ -333,8 +333,8 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) { // Provide an explicit override of health checking service interface. TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) { - EnableDefaultHealthCheckService(true); - EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); + grpc_impl::EnableDefaultHealthCheckService(true); + EXPECT_TRUE(grpc_impl::DefaultHealthCheckServiceEnabled()); std::unique_ptr override_service( new CustomHealthCheckService(&health_check_service_impl_)); HealthCheckServiceInterface* underlying_service = override_service.get(); @@ -349,8 +349,8 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) { } TEST_F(HealthServiceEnd2endTest, ExplicitlyHealthServiceShutdown) { - EnableDefaultHealthCheckService(true); - EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); + grpc_impl::EnableDefaultHealthCheckService(true); + EXPECT_TRUE(grpc_impl::DefaultHealthCheckServiceEnabled()); std::unique_ptr override_service( new CustomHealthCheckService(&health_check_service_impl_)); HealthCheckServiceInterface* underlying_service = override_service.get(); From a5814f89b611b1ec3e50942168010e0083320ad1 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 14:23:00 -0700 Subject: [PATCH 1590/2143] Fix errors from tools/buildgen/generate_projects.sh --- 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..796bc99672a 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -936,6 +936,7 @@ 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/health_check_service_interface_impl.h \ include/grpcpp/impl/call.h \ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c0078bf2764..cdd5be33d7e 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -937,6 +937,7 @@ 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/health_check_service_interface_impl.h \ include/grpcpp/impl/call.h \ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 501e53560ab..e1e0dfb1a87 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10069,6 +10069,7 @@ "include/grpcpp/generic/generic_stub.h", "include/grpcpp/grpcpp.h", "include/grpcpp/health_check_service_interface.h", + "include/grpcpp/health_check_service_interface_impl.h", "include/grpcpp/impl/call.h", "include/grpcpp/impl/channel_argument_option.h", "include/grpcpp/impl/client_unary_call.h", @@ -10178,6 +10179,7 @@ "include/grpcpp/generic/generic_stub.h", "include/grpcpp/grpcpp.h", "include/grpcpp/health_check_service_interface.h", + "include/grpcpp/health_check_service_interface_impl.h", "include/grpcpp/impl/call.h", "include/grpcpp/impl/channel_argument_option.h", "include/grpcpp/impl/client_unary_call.h", From 92bde3922f635d0354df2cc7177a210a4a8157d1 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 16:16:53 -0700 Subject: [PATCH 1591/2143] Fix tests to use grpc namespace. --- .../grpcpp/health_check_service_interface.h | 9 +++++++ test/cpp/end2end/client_lb_end2end_test.cc | 8 +++---- .../end2end/health_service_end2end_test.cc | 24 +++++++++---------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/grpcpp/health_check_service_interface.h b/include/grpcpp/health_check_service_interface.h index 6dde0951768..13286728438 100644 --- a/include/grpcpp/health_check_service_interface.h +++ b/include/grpcpp/health_check_service_interface.h @@ -28,6 +28,15 @@ const char kHealthCheckServiceInterfaceArg[] = typedef ::grpc_impl::HealthCheckServiceInterface HealthCheckServiceInterface; +static inline void EnableDefaultHealthCheckService(bool enable) { + ::grpc_impl::EnableDefaultHealthCheckService(enable); +} + +static inline bool DefaultHealthCheckServiceEnabled() { + return ::grpc_impl::DefaultHealthCheckServiceEnabled(); +} + + } // namespace grpc #endif // GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_H diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 6856883c2af..3cd06e9e28c 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -1242,7 +1242,7 @@ TEST_F(ClientLbEnd2endTest, } TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthChecking) { - grpc_impl::EnableDefaultHealthCheckService(true); + EnableDefaultHealthCheckService(true); // Start servers. const int kNumServers = 3; StartServers(kNumServers); @@ -1311,11 +1311,11 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthChecking) { EXPECT_TRUE(WaitForChannelNotReady(channel.get())); CheckRpcSendFailure(stub); // Clean up. - grpc_impl::EnableDefaultHealthCheckService(false); + EnableDefaultHealthCheckService(false); } TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { - grpc_impl::EnableDefaultHealthCheckService(true); + EnableDefaultHealthCheckService(true); // Start server. const int kNumServers = 1; StartServers(kNumServers); @@ -1341,7 +1341,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1)); CheckRpcSendOk(stub2, DEBUG_LOCATION); // Clean up. - grpc_impl::EnableDefaultHealthCheckService(false); + EnableDefaultHealthCheckService(false); } class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index c36d6e4d296..a3a04b121c2 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -285,8 +285,8 @@ class HealthServiceEnd2endTest : public ::testing::Test { }; TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceDisabled) { - grpc_impl::EnableDefaultHealthCheckService(false); - EXPECT_FALSE(grpc_impl::DefaultHealthCheckServiceEnabled()); + EnableDefaultHealthCheckService(false); + EXPECT_FALSE(DefaultHealthCheckServiceEnabled()); SetUpServer(true, false, false, nullptr); HealthCheckServiceInterface* default_service = server_->GetHealthCheckService(); @@ -298,8 +298,8 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceDisabled) { } TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { - grpc_impl::EnableDefaultHealthCheckService(true); - EXPECT_TRUE(grpc_impl::DefaultHealthCheckServiceEnabled()); + EnableDefaultHealthCheckService(true); + EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); SetUpServer(true, false, false, nullptr); VerifyHealthCheckService(); VerifyHealthCheckServiceStreaming(); @@ -311,16 +311,16 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { } TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceShutdown) { - grpc_impl::EnableDefaultHealthCheckService(true); - EXPECT_TRUE(grpc_impl::DefaultHealthCheckServiceEnabled()); + EnableDefaultHealthCheckService(true); + EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); SetUpServer(true, false, false, nullptr); VerifyHealthCheckServiceShutdown(); } // Provide an empty service to disable the default service. TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) { - grpc_impl::EnableDefaultHealthCheckService(true); - EXPECT_TRUE(grpc_impl::DefaultHealthCheckServiceEnabled()); + EnableDefaultHealthCheckService(true); + EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); std::unique_ptr empty_service; SetUpServer(true, false, true, std::move(empty_service)); grpc_impl::HealthCheckServiceInterface* service = server_->GetHealthCheckService(); @@ -333,8 +333,8 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) { // Provide an explicit override of health checking service interface. TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) { - grpc_impl::EnableDefaultHealthCheckService(true); - EXPECT_TRUE(grpc_impl::DefaultHealthCheckServiceEnabled()); + EnableDefaultHealthCheckService(true); + EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); std::unique_ptr override_service( new CustomHealthCheckService(&health_check_service_impl_)); HealthCheckServiceInterface* underlying_service = override_service.get(); @@ -349,8 +349,8 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) { } TEST_F(HealthServiceEnd2endTest, ExplicitlyHealthServiceShutdown) { - grpc_impl::EnableDefaultHealthCheckService(true); - EXPECT_TRUE(grpc_impl::DefaultHealthCheckServiceEnabled()); + EnableDefaultHealthCheckService(true); + EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); std::unique_ptr override_service( new CustomHealthCheckService(&health_check_service_impl_)); HealthCheckServiceInterface* underlying_service = override_service.get(); From 8dbaa13f52bbbe2418a62ee87d8495d0a49e6d6e Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 16:25:16 -0700 Subject: [PATCH 1592/2143] Fix more grpc namespace issues --- include/grpcpp/server.h | 8 ++------ src/cpp/server/health/default_health_check_service.h | 2 +- src/cpp/server/server_cc.cc | 4 ++-- test/cpp/end2end/health_service_end2end_test.cc | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 6638b098954..48a0da173ac 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -41,10 +41,6 @@ struct grpc_server; -namespace grpc_impl { - -class HealthCheckServiceInterface; -} namespace grpc { class AsyncGenericService; @@ -98,7 +94,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { grpc_server* c_server(); /// Returns the health check service. - grpc_impl::HealthCheckServiceInterface* GetHealthCheckService() const { + HealthCheckServiceInterface* GetHealthCheckService() const { return health_check_service_.get(); } @@ -327,7 +323,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { std::unique_ptr server_initializer_; - std::unique_ptr health_check_service_; + std::unique_ptr health_check_service_; bool health_check_service_disabled_; // When appropriate, use a default callback generic service to handle diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h index 0ed8a45bb3f..9551cd2e2cf 100644 --- a/src/cpp/server/health/default_health_check_service.h +++ b/src/cpp/server/health/default_health_check_service.h @@ -37,7 +37,7 @@ namespace grpc { // Default implementation of HealthCheckServiceInterface. Server will create and // own it. -class DefaultHealthCheckService final : public grpc_impl::HealthCheckServiceInterface { +class DefaultHealthCheckService final : public HealthCheckServiceInterface { public: enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING }; diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 589440d6660..26e84f1aed4 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -802,7 +802,7 @@ Server::Server( if (channel_args.args[i].value.pointer.p == nullptr) { health_check_service_disabled_ = true; } else { - health_check_service_.reset(static_cast( + health_check_service_.reset(static_cast( channel_args.args[i].value.pointer.p)); } break; @@ -987,7 +987,7 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { DefaultHealthCheckService::HealthCheckServiceImpl* default_health_check_service_impl = nullptr; if (health_check_service_ == nullptr && !health_check_service_disabled_ && - grpc_impl::DefaultHealthCheckServiceEnabled()) { + DefaultHealthCheckServiceEnabled()) { auto* default_hc_service = new DefaultHealthCheckService; health_check_service_.reset(default_hc_service); // We create a non-polling CQ to avoid impacting application diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index a3a04b121c2..b96ff53a3ea 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -323,7 +323,7 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) { EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); std::unique_ptr empty_service; SetUpServer(true, false, true, std::move(empty_service)); - grpc_impl::HealthCheckServiceInterface* service = server_->GetHealthCheckService(); + HealthCheckServiceInterface* service = server_->GetHealthCheckService(); EXPECT_TRUE(service == nullptr); ResetStubs(); From 35e793d23a94614ad3439ad93688da1c3cbe6471 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 16:27:43 -0700 Subject: [PATCH 1593/2143] Fix more more tests. --- include/grpcpp/server.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 48a0da173ac..3284565be67 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -44,6 +44,7 @@ struct grpc_server; namespace grpc { class AsyncGenericService; +class HealthCheckServiceInterface; class ServerContext; class ServerInitializer; From 6e5587b1653dd57232cc764bd5bece81f5fdc2f6 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 17:17:10 -0700 Subject: [PATCH 1594/2143] Fix build issues. --- include/grpcpp/server.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 3284565be67..48a0da173ac 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -44,7 +44,6 @@ struct grpc_server; namespace grpc { class AsyncGenericService; -class HealthCheckServiceInterface; class ServerContext; class ServerInitializer; From d204654836b0639b9af9ded4e2c852cc276c6679 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 25 Mar 2019 15:51:28 -0700 Subject: [PATCH 1595/2143] Fix errors from clang_format_code.sh --- include/grpcpp/health_check_service_interface.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/grpcpp/health_check_service_interface.h b/include/grpcpp/health_check_service_interface.h index 13286728438..a51b0d18bba 100644 --- a/include/grpcpp/health_check_service_interface.h +++ b/include/grpcpp/health_check_service_interface.h @@ -36,7 +36,6 @@ static inline bool DefaultHealthCheckServiceEnabled() { return ::grpc_impl::DefaultHealthCheckServiceEnabled(); } - } // namespace grpc #endif // GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_H From d23753ca46469d23aca93ffe1fad658c9742cc72 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 14 Mar 2019 14:40:49 -0700 Subject: [PATCH 1596/2143] Move create_channel_posix from grpc to grpc_impl namespace --- BUILD | 1 + CMakeLists.txt | 3 + Makefile | 3 + build.yaml | 1 + include/grpcpp/create_channel_posix.h | 49 +-------------- include/grpcpp/create_channel_posix_impl.h | 69 ++++++++++++++++++++++ 6 files changed, 79 insertions(+), 47 deletions(-) create mode 100644 include/grpcpp/create_channel_posix_impl.h diff --git a/BUILD b/BUILD index 12687c799ef..5e654421418 100644 --- a/BUILD +++ b/BUILD @@ -220,6 +220,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", "include/grpcpp/create_channel_posix.h", + "include/grpcpp/create_channel_posix_impl.h", "include/grpcpp/ext/health_check_service_server_builder_option.h", "include/grpcpp/generic/async_generic_service.h", "include/grpcpp/generic/generic_stub.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index d39c1941a74..89634db6796 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3000,6 +3000,7 @@ foreach(_hdr include/grpcpp/completion_queue.h include/grpcpp/create_channel.h include/grpcpp/create_channel_posix.h + include/grpcpp/create_channel_posix_impl.h include/grpcpp/ext/health_check_service_server_builder_option.h include/grpcpp/generic/async_generic_service.h include/grpcpp/generic/generic_stub.h @@ -3591,6 +3592,7 @@ foreach(_hdr include/grpcpp/completion_queue.h include/grpcpp/create_channel.h include/grpcpp/create_channel_posix.h + include/grpcpp/create_channel_posix_impl.h include/grpcpp/ext/health_check_service_server_builder_option.h include/grpcpp/generic/async_generic_service.h include/grpcpp/generic/generic_stub.h @@ -4554,6 +4556,7 @@ foreach(_hdr include/grpcpp/completion_queue.h include/grpcpp/create_channel.h include/grpcpp/create_channel_posix.h + include/grpcpp/create_channel_posix_impl.h include/grpcpp/ext/health_check_service_server_builder_option.h include/grpcpp/generic/async_generic_service.h include/grpcpp/generic/generic_stub.h diff --git a/Makefile b/Makefile index 85e621f87bb..04d3133eb7f 100644 --- a/Makefile +++ b/Makefile @@ -5327,6 +5327,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ include/grpcpp/create_channel_posix.h \ + include/grpcpp/create_channel_posix_impl.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ include/grpcpp/generic/generic_stub.h \ @@ -5926,6 +5927,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ include/grpcpp/create_channel_posix.h \ + include/grpcpp/create_channel_posix_impl.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ include/grpcpp/generic/generic_stub.h \ @@ -6838,6 +6840,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ include/grpcpp/create_channel_posix.h \ + include/grpcpp/create_channel_posix_impl.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ include/grpcpp/generic/generic_stub.h \ diff --git a/build.yaml b/build.yaml index 34b271f58de..19edebe12a0 100644 --- a/build.yaml +++ b/build.yaml @@ -1345,6 +1345,7 @@ filegroups: - include/grpcpp/completion_queue.h - include/grpcpp/create_channel.h - include/grpcpp/create_channel_posix.h + - include/grpcpp/create_channel_posix_impl.h - include/grpcpp/ext/health_check_service_server_builder_option.h - include/grpcpp/generic/async_generic_service.h - include/grpcpp/generic/generic_stub.h diff --git a/include/grpcpp/create_channel_posix.h b/include/grpcpp/create_channel_posix.h index 808514041b8..d86f92d831b 100644 --- a/include/grpcpp/create_channel_posix.h +++ b/include/grpcpp/create_channel_posix.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,51 +19,6 @@ #ifndef GRPCPP_CREATE_CHANNEL_POSIX_H #define GRPCPP_CREATE_CHANNEL_POSIX_H -#include - -#include -#include -#include - -namespace grpc { - -#ifdef GPR_SUPPORT_CHANNELS_FROM_FD - -/// Create a new \a Channel communicating over the given file descriptor. -/// -/// \param target The name of the target. -/// \param fd The file descriptor representing a socket. -std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, - int fd); - -/// Create a new \a Channel communicating over given file descriptor with custom -/// channel arguments. -/// -/// \param target The name of the target. -/// \param fd The file descriptor representing a socket. -/// \param args Options for channel creation. -std::shared_ptr CreateCustomInsecureChannelFromFd( - const grpc::string& target, int fd, const ChannelArguments& args); - -namespace experimental { - -/// Create a new \a Channel communicating over given file descriptor with custom -/// channel arguments. -/// -/// \param target The name of the target. -/// \param fd The file descriptor representing a socket. -/// \param args Options for channel creation. -/// \param interceptor_creators Vector of interceptor factory objects. -std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( - const grpc::string& target, int fd, const ChannelArguments& args, - std::unique_ptr>> - interceptor_creators); - -} // namespace experimental - -#endif // GPR_SUPPORT_CHANNELS_FROM_FD - -} // namespace grpc +#include #endif // GRPCPP_CREATE_CHANNEL_POSIX_H diff --git a/include/grpcpp/create_channel_posix_impl.h b/include/grpcpp/create_channel_posix_impl.h new file mode 100644 index 00000000000..053f20ca286 --- /dev/null +++ b/include/grpcpp/create_channel_posix_impl.h @@ -0,0 +1,69 @@ +/* + * + * 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_CREATE_CHANNEL_POSIX_IMPL_H +#define GRPCPP_CREATE_CHANNEL_POSIX_IMPL_H + +#include + +#include +#include +#include + +namespace grpc_impl { + +#ifdef GPR_SUPPORT_CHANNELS_FROM_FD + +/// Create a new \a Channel communicating over the given file descriptor. +/// +/// \param target The name of the target. +/// \param fd The file descriptor representing a socket. +std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, + int fd); + +/// Create a new \a Channel communicating over given file descriptor with custom +/// channel arguments. +/// +/// \param target The name of the target. +/// \param fd The file descriptor representing a socket. +/// \param args Options for channel creation. +std::shared_ptr CreateCustomInsecureChannelFromFd( + const grpc::string& target, int fd, const ChannelArguments& args); + +namespace experimental { + +/// Create a new \a Channel communicating over given file descriptor with custom +/// channel arguments. +/// +/// \param target The name of the target. +/// \param fd The file descriptor representing a socket. +/// \param args Options for channel creation. +/// \param interceptor_creators Vector of interceptor factory objects. +std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( + const grpc::string& target, int fd, const ChannelArguments& args, + std::unique_ptr>> + interceptor_creators); + +} // namespace experimental + +#endif // GPR_SUPPORT_CHANNELS_FROM_FD + +} // namespace grpc_impl + +#endif // GRPCPP_CREATE_CHANNEL_POSIX_IMPL_H From 6ffbfaac83a27b270fc41b03459ac25d2d23cb40 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 14 Mar 2019 17:12:54 -0700 Subject: [PATCH 1597/2143] Fix errors from tests --- gRPC-C++.podspec | 1 + tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + tools/run_tests/generated/sources_and_headers.json | 2 ++ 4 files changed, 5 insertions(+) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 5a850bc8438..0ed19a9b03c 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -86,6 +86,7 @@ Pod::Spec.new do |s| 'include/grpcpp/completion_queue.h', 'include/grpcpp/create_channel.h', 'include/grpcpp/create_channel_posix.h', + 'include/grpcpp/create_channel_posix_impl.h', 'include/grpcpp/ext/health_check_service_server_builder_option.h', 'include/grpcpp/generic/async_generic_service.h', 'include/grpcpp/generic/generic_stub.h', diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 9f17a25298a..a5d74126212 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -931,6 +931,7 @@ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ include/grpcpp/create_channel_posix.h \ +include/grpcpp/create_channel_posix_impl.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ include/grpcpp/generic/generic_stub.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c0078bf2764..b56b0380088 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -932,6 +932,7 @@ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ include/grpcpp/create_channel_posix.h \ +include/grpcpp/create_channel_posix_impl.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ include/grpcpp/generic/generic_stub.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 501e53560ab..5c22d32b02d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10064,6 +10064,7 @@ "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", "include/grpcpp/create_channel_posix.h", + "include/grpcpp/create_channel_posix_impl.h", "include/grpcpp/ext/health_check_service_server_builder_option.h", "include/grpcpp/generic/async_generic_service.h", "include/grpcpp/generic/generic_stub.h", @@ -10173,6 +10174,7 @@ "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", "include/grpcpp/create_channel_posix.h", + "include/grpcpp/create_channel_posix_impl.h", "include/grpcpp/ext/health_check_service_server_builder_option.h", "include/grpcpp/generic/async_generic_service.h", "include/grpcpp/generic/generic_stub.h", From 49773cbe9a525aa6c2fbda4fa81eef519b2e2a40 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 16:44:39 -0700 Subject: [PATCH 1598/2143] Fix namespace to grpc --- include/grpcpp/create_channel_posix.h | 33 +++++++++++++++++++++- include/grpcpp/create_channel_posix_impl.h | 12 ++++---- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/include/grpcpp/create_channel_posix.h b/include/grpcpp/create_channel_posix.h index d86f92d831b..0e0b352259e 100644 --- a/include/grpcpp/create_channel_posix.h +++ b/include/grpcpp/create_channel_posix.h @@ -19,6 +19,37 @@ #ifndef GRPCPP_CREATE_CHANNEL_POSIX_H #define GRPCPP_CREATE_CHANNEL_POSIX_H -#include +#include + +namespace grpc { + +#ifdef GPR_SUPPORT_CHANNELS_FROM_FD + +static inline std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, + int fd) { + return ::grpc_impl::CreateInsecureChannelFromFd(target, fd); +} + +static inline std::shared_ptr CreateCustomInsecureChannelFromFd( + const grpc::string& target, int fd, const ChannelArguments& args) { + return ::grpc_impl::CreateCustomInsecureChannelFromFd(target, fd, args); +} + +namespace experimental { + +static inline std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( + const grpc::string& target, int fd, const ChannelArguments& args, + std::unique_ptr>> + interceptor_creators) { + return CreateCustomInsecureChannelWithInterceptorsFromFd(target, fd, args, std::move(interceptor_creators)); +} + +} // namespace experimental + +#endif // GPR_SUPPORT_CHANNELS_FROM_FD + +} // namespace grpc + #endif // GRPCPP_CREATE_CHANNEL_POSIX_H diff --git a/include/grpcpp/create_channel_posix_impl.h b/include/grpcpp/create_channel_posix_impl.h index 053f20ca286..7fccfa1c78d 100644 --- a/include/grpcpp/create_channel_posix_impl.h +++ b/include/grpcpp/create_channel_posix_impl.h @@ -33,7 +33,7 @@ namespace grpc_impl { /// /// \param target The name of the target. /// \param fd The file descriptor representing a socket. -std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, +std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, int fd); /// Create a new \a Channel communicating over given file descriptor with custom @@ -42,8 +42,8 @@ std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, /// \param target The name of the target. /// \param fd The file descriptor representing a socket. /// \param args Options for channel creation. -std::shared_ptr CreateCustomInsecureChannelFromFd( - const grpc::string& target, int fd, const ChannelArguments& args); +std::shared_ptr CreateCustomInsecureChannelFromFd( + const grpc::string& target, int fd, const grpc::ChannelArguments& args); namespace experimental { @@ -54,10 +54,10 @@ namespace experimental { /// \param fd The file descriptor representing a socket. /// \param args Options for channel creation. /// \param interceptor_creators Vector of interceptor factory objects. -std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( - const grpc::string& target, int fd, const ChannelArguments& args, +std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( + const grpc::string& target, int fd, const grpc::ChannelArguments& args, std::unique_ptr>> + std::unique_ptr>> interceptor_creators); } // namespace experimental From 392554e3410e0a4792586e3a97e1b072405d847e Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 17:19:28 -0700 Subject: [PATCH 1599/2143] Fixing clang_tidy_format.sh issues. --- include/grpcpp/create_channel_posix.h | 11 ++++++----- include/grpcpp/create_channel_posix_impl.h | 7 ++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/grpcpp/create_channel_posix.h b/include/grpcpp/create_channel_posix.h index 0e0b352259e..a8c25187b6e 100644 --- a/include/grpcpp/create_channel_posix.h +++ b/include/grpcpp/create_channel_posix.h @@ -25,8 +25,8 @@ namespace grpc { #ifdef GPR_SUPPORT_CHANNELS_FROM_FD -static inline std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, - int fd) { +static inline std::shared_ptr CreateInsecureChannelFromFd( + const grpc::string& target, int fd) { return ::grpc_impl::CreateInsecureChannelFromFd(target, fd); } @@ -37,12 +37,14 @@ static inline std::shared_ptr CreateCustomInsecureChannelFromFd( namespace experimental { -static inline std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( +static inline std::shared_ptr +CreateCustomInsecureChannelWithInterceptorsFromFd( const grpc::string& target, int fd, const ChannelArguments& args, std::unique_ptr>> interceptor_creators) { - return CreateCustomInsecureChannelWithInterceptorsFromFd(target, fd, args, std::move(interceptor_creators)); + return CreateCustomInsecureChannelWithInterceptorsFromFd( + target, fd, args, std::move(interceptor_creators)); } } // namespace experimental @@ -51,5 +53,4 @@ static inline std::shared_ptr CreateCustomInsecureChannelWithIntercepto } // namespace grpc - #endif // GRPCPP_CREATE_CHANNEL_POSIX_H diff --git a/include/grpcpp/create_channel_posix_impl.h b/include/grpcpp/create_channel_posix_impl.h index 7fccfa1c78d..5c11120611a 100644 --- a/include/grpcpp/create_channel_posix_impl.h +++ b/include/grpcpp/create_channel_posix_impl.h @@ -33,8 +33,8 @@ namespace grpc_impl { /// /// \param target The name of the target. /// \param fd The file descriptor representing a socket. -std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, - int fd); +std::shared_ptr CreateInsecureChannelFromFd( + const grpc::string& target, int fd); /// Create a new \a Channel communicating over given file descriptor with custom /// channel arguments. @@ -54,7 +54,8 @@ namespace experimental { /// \param fd The file descriptor representing a socket. /// \param args Options for channel creation. /// \param interceptor_creators Vector of interceptor factory objects. -std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( +std::shared_ptr +CreateCustomInsecureChannelWithInterceptorsFromFd( const grpc::string& target, int fd, const grpc::ChannelArguments& args, std::unique_ptr>> From 130962490bbcf77e048e39fa17dbbc3d54e7f415 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 19 Mar 2019 11:40:42 -0700 Subject: [PATCH 1600/2143] Make changes to fix test failures --- include/grpcpp/create_channel_posix.h | 2 +- src/cpp/client/create_channel_posix.cc | 32 +++++++++++++------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/include/grpcpp/create_channel_posix.h b/include/grpcpp/create_channel_posix.h index a8c25187b6e..8fee2f8f0dd 100644 --- a/include/grpcpp/create_channel_posix.h +++ b/include/grpcpp/create_channel_posix.h @@ -43,7 +43,7 @@ CreateCustomInsecureChannelWithInterceptorsFromFd( std::unique_ptr>> interceptor_creators) { - return CreateCustomInsecureChannelWithInterceptorsFromFd( + return ::grpc_impl::experimental::CreateCustomInsecureChannelWithInterceptorsFromFd( target, fd, args, std::move(interceptor_creators)); } diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index 3affc1ef391..9a55ebc3ec6 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -24,45 +24,45 @@ #include "src/cpp/client/create_channel_internal.h" -namespace grpc { +namespace grpc_impl { #ifdef GPR_SUPPORT_CHANNELS_FROM_FD -std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, +std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, int fd) { - internal::GrpcLibrary init_lib; + grpc::internal::GrpcLibrary init_lib; init_lib.init(); - return CreateChannelInternal( + return grpc::CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr), std::vector< - std::unique_ptr>()); + std::unique_ptr>()); } -std::shared_ptr CreateCustomInsecureChannelFromFd( - const grpc::string& target, int fd, const ChannelArguments& args) { - internal::GrpcLibrary init_lib; +std::shared_ptr CreateCustomInsecureChannelFromFd( + const grpc::string& target, int fd, const grpc::ChannelArguments& args) { + grpc::internal::GrpcLibrary init_lib; init_lib.init(); grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return grpc::CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), std::vector< - std::unique_ptr>()); + std::unique_ptr>()); } namespace experimental { -std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( - const grpc::string& target, int fd, const ChannelArguments& args, +std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( + const grpc::string& target, int fd, const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators) { - internal::GrpcLibrary init_lib; + grpc::internal::GrpcLibrary init_lib; init_lib.init(); grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return grpc::CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), std::move(interceptor_creators)); @@ -72,4 +72,4 @@ std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( #endif // GPR_SUPPORT_CHANNELS_FROM_FD -} // namespace grpc +} // namespace grpc_impl From 4b0175f2c8e857010f3d201a14b660b78ebd6a17 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 25 Mar 2019 15:53:22 -0700 Subject: [PATCH 1601/2143] Fix errors from clang_format_code.sh --- include/grpcpp/create_channel_posix.h | 5 +++-- src/cpp/client/create_channel_posix.cc | 15 ++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/include/grpcpp/create_channel_posix.h b/include/grpcpp/create_channel_posix.h index 8fee2f8f0dd..b8a1f5e5c46 100644 --- a/include/grpcpp/create_channel_posix.h +++ b/include/grpcpp/create_channel_posix.h @@ -43,8 +43,9 @@ CreateCustomInsecureChannelWithInterceptorsFromFd( std::unique_ptr>> interceptor_creators) { - return ::grpc_impl::experimental::CreateCustomInsecureChannelWithInterceptorsFromFd( - target, fd, args, std::move(interceptor_creators)); + return ::grpc_impl::experimental:: + CreateCustomInsecureChannelWithInterceptorsFromFd( + target, fd, args, std::move(interceptor_creators)); } } // namespace experimental diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index 9a55ebc3ec6..6de373577eb 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -28,14 +28,14 @@ namespace grpc_impl { #ifdef GPR_SUPPORT_CHANNELS_FROM_FD -std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, - int fd) { +std::shared_ptr CreateInsecureChannelFromFd( + const grpc::string& target, int fd) { grpc::internal::GrpcLibrary init_lib; init_lib.init(); return grpc::CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr), - std::vector< - std::unique_ptr>()); + std::vector>()); } std::shared_ptr CreateCustomInsecureChannelFromFd( @@ -47,13 +47,14 @@ std::shared_ptr CreateCustomInsecureChannelFromFd( return grpc::CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), - std::vector< - std::unique_ptr>()); + std::vector>()); } namespace experimental { -std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( +std::shared_ptr +CreateCustomInsecureChannelWithInterceptorsFromFd( const grpc::string& target, int fd, const grpc::ChannelArguments& args, std::vector< std::unique_ptr> From 850d02d67df90984f3ad0b0d28d658e8177a0f47 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 14 Mar 2019 15:13:29 -0700 Subject: [PATCH 1602/2143] Move channelz_service_plugin from grpc to grpc_impl namespace --- BUILD | 1 + CMakeLists.txt | 1 + Makefile | 1 + build.yaml | 1 + include/grpcpp/ext/channelz_service_plugin.h | 19 +-------- .../grpcpp/ext/channelz_service_plugin_impl.h | 41 +++++++++++++++++++ 6 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 include/grpcpp/ext/channelz_service_plugin_impl.h diff --git a/BUILD b/BUILD index 12687c799ef..d91d519b56d 100644 --- a/BUILD +++ b/BUILD @@ -2219,6 +2219,7 @@ grpc_cc_library( language = "c++", public_hdrs = [ "include/grpcpp/ext/channelz_service_plugin.h", + "include/grpcpp/ext/channelz_service_plugin_impl.h", ], deps = [ ":grpc++", diff --git a/CMakeLists.txt b/CMakeLists.txt index d39c1941a74..7dbedbb0327 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4965,6 +4965,7 @@ target_link_libraries(grpcpp_channelz foreach(_hdr include/grpcpp/ext/channelz_service_plugin.h + include/grpcpp/ext/channelz_service_plugin_impl.h ) string(REPLACE "include/" "" _path ${_hdr}) get_filename_component(_path ${_path} PATH) diff --git a/Makefile b/Makefile index 85e621f87bb..c33c2b08a93 100644 --- a/Makefile +++ b/Makefile @@ -7218,6 +7218,7 @@ LIBGRPCPP_CHANNELZ_SRC = \ PUBLIC_HEADERS_CXX += \ include/grpcpp/ext/channelz_service_plugin.h \ + include/grpcpp/ext/channelz_service_plugin_impl.h \ LIBGRPCPP_CHANNELZ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPCPP_CHANNELZ_SRC)))) diff --git a/build.yaml b/build.yaml index 34b271f58de..0345ccafd4a 100644 --- a/build.yaml +++ b/build.yaml @@ -1917,6 +1917,7 @@ libs: language: c++ public_headers: - include/grpcpp/ext/channelz_service_plugin.h + - include/grpcpp/ext/channelz_service_plugin_impl.h headers: - src/cpp/server/channelz/channelz_service.h src: diff --git a/include/grpcpp/ext/channelz_service_plugin.h b/include/grpcpp/ext/channelz_service_plugin.h index af3192d4513..6358a2bc1f2 100644 --- a/include/grpcpp/ext/channelz_service_plugin.h +++ b/include/grpcpp/ext/channelz_service_plugin.h @@ -19,23 +19,6 @@ #ifndef GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H #define GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H -#include - -#include -#include -#include - -namespace grpc { -namespace channelz { -namespace experimental { - -/// Add channelz server plugin to \a ServerBuilder. This function should -/// be called at static initialization time. This service is experimental -/// for now. Track progress in https://github.com/grpc/grpc/issues/15988. -void InitChannelzService(); - -} // namespace experimental -} // namespace channelz -} // namespace grpc +#include #endif // GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H diff --git a/include/grpcpp/ext/channelz_service_plugin_impl.h b/include/grpcpp/ext/channelz_service_plugin_impl.h new file mode 100644 index 00000000000..3a5f3c4b99e --- /dev/null +++ b/include/grpcpp/ext/channelz_service_plugin_impl.h @@ -0,0 +1,41 @@ +/* + * + * 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 GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_IMPL_H +#define GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_IMPL_H + +#include + +#include +#include +#include + +namespace grpc_impl { +namespace channelz { +namespace experimental { + +/// Add channelz server plugin to \a ServerBuilder. This function should +/// be called at static initialization time. This service is experimental +/// for now. Track progress in https://github.com/grpc/grpc/issues/15988. +void InitChannelzService(); + +} // namespace experimental +} // namespace channelz +} // namespace grpc_impl + +#endif // GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_IMPL_H From b2b1e57337b89cec11d27aee203fc92489fd4724 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 14:44:20 -0700 Subject: [PATCH 1603/2143] Fix errors from test scripts. --- include/grpcpp/ext/channelz_service_plugin.h | 12 ++++++++++++ src/cpp/server/channelz/channelz_service_plugin.cc | 12 ++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/ext/channelz_service_plugin.h b/include/grpcpp/ext/channelz_service_plugin.h index 6358a2bc1f2..95cb93e3216 100644 --- a/include/grpcpp/ext/channelz_service_plugin.h +++ b/include/grpcpp/ext/channelz_service_plugin.h @@ -21,4 +21,16 @@ #include +namespace grpc { +namespace channelz { +namespace experimental { + +static inline void InitChannelzService() { + ::grpc_impl::channelz::experimental::InitChannelzService(); +} + +} // namespace experimental +} // namespace channelz +} // namespace grpc + #endif // GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H diff --git a/src/cpp/server/channelz/channelz_service_plugin.cc b/src/cpp/server/channelz/channelz_service_plugin.cc index b93e5b551e1..04c6411d5a3 100644 --- a/src/cpp/server/channelz/channelz_service_plugin.cc +++ b/src/cpp/server/channelz/channelz_service_plugin.cc @@ -67,13 +67,21 @@ CreateChannelzServicePlugin() { new ChannelzServicePlugin()); } +} // namespace experimental +} // namespace channelz +} // namespace grpc +namespace grpc_impl { +namespace channelz { +namespace experimental { + void InitChannelzService() { static bool already_here = false; if (already_here) return; already_here = true; - ::grpc::ServerBuilder::InternalAddPluginFactory(&CreateChannelzServicePlugin); + ::grpc::ServerBuilder::InternalAddPluginFactory( + &grpc::channelz::experimental::CreateChannelzServicePlugin); } } // namespace experimental } // namespace channelz -} // namespace grpc +} // namespace grpc_impl From 7b88e58a6cda8ed45ef53ed70d038ae0469106f5 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 18 Mar 2019 10:04:44 -0700 Subject: [PATCH 1604/2143] Fix errors from generate project script --- tools/run_tests/generated/sources_and_headers.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 501e53560ab..a5e68b50fdb 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -6921,6 +6921,7 @@ ], "headers": [ "include/grpcpp/ext/channelz_service_plugin.h", + "include/grpcpp/ext/channelz_service_plugin_impl.h", "src/cpp/server/channelz/channelz_service.h" ], "is_filegroup": false, @@ -6928,6 +6929,7 @@ "name": "grpcpp_channelz", "src": [ "include/grpcpp/ext/channelz_service_plugin.h", + "include/grpcpp/ext/channelz_service_plugin_impl.h", "src/cpp/server/channelz/channelz_service.cc", "src/cpp/server/channelz/channelz_service.h", "src/cpp/server/channelz/channelz_service_plugin.cc" From 872d2787a0628f0c88c5726433c8bbaca0e5813c Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 25 Mar 2019 16:19:08 -0700 Subject: [PATCH 1605/2143] 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 1606/2143] 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 1607/2143] 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 8e393ea13e2be230f021855e46def4d4e90f28a4 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 26 Mar 2019 02:34:51 -0400 Subject: [PATCH 1608/2143] rename BindServiceAttribute --- src/compiler/csharp_generator.cc | 2 +- ...indServiceAttribute.cs => BindServiceMethodAttribute.cs} | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/csharp/Grpc.Core.Api/{BindServiceAttribute.cs => BindServiceMethodAttribute.cs} (92%) diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index 682ce59efbf..778e5c39284 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -383,7 +383,7 @@ void GenerateServerClass(Printer* out, const ServiceDescriptor* service) { "$servicename$\n", "servicename", GetServiceClassName(service)); out->Print( - "[grpc::BindService(typeof($classname$), " + "[grpc::BindServiceMethod(typeof($classname$), " "\"BindService\")]\n", "classname", GetServiceClassName(service)); out->Print("public abstract partial class $name$\n", "name", diff --git a/src/csharp/Grpc.Core.Api/BindServiceAttribute.cs b/src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs similarity index 92% rename from src/csharp/Grpc.Core.Api/BindServiceAttribute.cs rename to src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs index d4ac6a10570..329b23dadff 100644 --- a/src/csharp/Grpc.Core.Api/BindServiceAttribute.cs +++ b/src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs @@ -27,14 +27,14 @@ namespace Grpc.Core /// instance of the service base class, e.g. static void BindService(ServiceBinderBase, GreeterService). /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] - public class BindServiceAttribute : Attribute + public class BindServiceMethodAttribute : Attribute { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The type the service bind method is defined on. /// The name of the service bind method. - public BindServiceAttribute(Type bindType, string bindMethodName) + public BindServiceMethodAttribute(Type bindType, string bindMethodName) { BindType = bindType; BindMethodName = bindMethodName; From 3624963ec9109f6e7e21c8b1813f797f10cf2076 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 26 Mar 2019 02:43:32 -0400 Subject: [PATCH 1609/2143] regenerate c# protos --- src/csharp/Grpc.Examples/MathGrpc.cs | 2 +- src/csharp/Grpc.HealthCheck/HealthGrpc.cs | 2 +- src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs | 2 +- src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs | 2 +- src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs | 2 +- .../Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs | 2 +- src/csharp/Grpc.IntegrationTesting/TestGrpc.cs | 6 +++--- src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs | 2 +- src/csharp/Grpc.Reflection/ReflectionGrpc.cs | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs index 8315b2be82e..fab64354411 100644 --- a/src/csharp/Grpc.Examples/MathGrpc.cs +++ b/src/csharp/Grpc.Examples/MathGrpc.cs @@ -67,7 +67,7 @@ namespace Math { } /// Base class for server-side implementations of Math - [grpc::BindService(typeof(Math), "BindService")] + [grpc::BindServiceMethod(typeof(Math), "BindService")] public abstract partial class MathBase { /// diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs index bc7ae6cedf1..7137b907274 100644 --- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs +++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs @@ -54,7 +54,7 @@ namespace Grpc.Health.V1 { } /// Base class for server-side implementations of Health - [grpc::BindService(typeof(Health), "BindService")] + [grpc::BindServiceMethod(typeof(Health), "BindService")] public abstract partial class HealthBase { /// diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs index 00821bb41bd..5b37b144f2a 100644 --- a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs @@ -74,7 +74,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of BenchmarkService - [grpc::BindService(typeof(BenchmarkService), "BindService")] + [grpc::BindServiceMethod(typeof(BenchmarkService), "BindService")] public abstract partial class BenchmarkServiceBase { /// diff --git a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs index 20f415f72de..50c6e159206 100644 --- a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs @@ -39,7 +39,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of EmptyService - [grpc::BindService(typeof(EmptyService), "BindService")] + [grpc::BindServiceMethod(typeof(EmptyService), "BindService")] public abstract partial class EmptyServiceBase { } diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs index 6e59d1eb6c1..9b11e990d2d 100644 --- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs @@ -58,7 +58,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of MetricsService - [grpc::BindService(typeof(MetricsService), "BindService")] + [grpc::BindServiceMethod(typeof(MetricsService), "BindService")] public abstract partial class MetricsServiceBase { /// diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs index b86dfbf7ec9..1a505ebc764 100644 --- a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs @@ -46,7 +46,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of ReportQpsScenarioService - [grpc::BindService(typeof(ReportQpsScenarioService), "BindService")] + [grpc::BindServiceMethod(typeof(ReportQpsScenarioService), "BindService")] public abstract partial class ReportQpsScenarioServiceBase { /// diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs index c4aa5249ab9..e7b93094c65 100644 --- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs @@ -105,7 +105,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of TestService - [grpc::BindService(typeof(TestService), "BindService")] + [grpc::BindServiceMethod(typeof(TestService), "BindService")] public abstract partial class TestServiceBase { /// @@ -581,7 +581,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of UnimplementedService - [grpc::BindService(typeof(UnimplementedService), "BindService")] + [grpc::BindServiceMethod(typeof(UnimplementedService), "BindService")] public abstract partial class UnimplementedServiceBase { /// @@ -721,7 +721,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of ReconnectService - [grpc::BindService(typeof(ReconnectService), "BindService")] + [grpc::BindServiceMethod(typeof(ReconnectService), "BindService")] public abstract partial class ReconnectServiceBase { public virtual global::System.Threading.Tasks.Task Start(global::Grpc.Testing.ReconnectParams request, grpc::ServerCallContext context) diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs index 5c079a5ec43..14c26f99a6b 100644 --- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs @@ -72,7 +72,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of WorkerService - [grpc::BindService(typeof(WorkerService), "BindService")] + [grpc::BindServiceMethod(typeof(WorkerService), "BindService")] public abstract partial class WorkerServiceBase { /// diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs index 768879bd2a1..f97b3143a69 100644 --- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs +++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs @@ -46,7 +46,7 @@ namespace Grpc.Reflection.V1Alpha { } /// Base class for server-side implementations of ServerReflection - [grpc::BindService(typeof(ServerReflection), "BindService")] + [grpc::BindServiceMethod(typeof(ServerReflection), "BindService")] public abstract partial class ServerReflectionBase { /// From f699bd8604d5e84df5bf2a00948de0b206154201 Mon Sep 17 00:00:00 2001 From: John Luo Date: Tue, 19 Mar 2019 18:13:14 -0700 Subject: [PATCH 1610/2143] 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 1611/2143] 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 996da586675fe6f6553bc3ceed234393caf989f5 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 26 Mar 2019 08:04:32 -0700 Subject: [PATCH 1612/2143] Revert "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, 397 insertions(+), 340 deletions(-) create mode 100644 include/grpcpp/server_builder_impl.h diff --git a/BUILD b/BUILD index 12687c799ef..5bfc88dc186 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 d39c1941a74..9fe76cf11cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3025,6 +3025,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 @@ -3616,6 +3617,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 @@ -4579,6 +4581,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 85e621f87bb..055300cef00 100644 --- a/Makefile +++ b/Makefile @@ -5352,6 +5352,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 \ @@ -5951,6 +5952,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 \ @@ -6863,6 +6865,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 34b271f58de..4251ed9ba01 100644 --- a/build.yaml +++ b/build.yaml @@ -1370,6 +1370,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 5a850bc8438..282a4a1e76c 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 f5c99f22df2..f8947a98cab 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 498e5b7bb31..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,320 +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 - -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_; -}; - +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..a8323c38510 --- /dev/null +++ b/include/grpcpp/server_builder_impl.h @@ -0,0 +1,346 @@ +/* + * + * 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 cd0e516d9a3..c0cb706a5b1 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() @@ -67,29 +67,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_ || 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( - experimental::CallbackGenericService* service) { + grpc::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() { - 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_); @@ -251,9 +251,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) { @@ -282,7 +283,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)); } } @@ -303,13 +304,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 @@ -393,7 +394,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); } @@ -408,4 +409,4 @@ ServerBuilder& ServerBuilder::EnableWorkaround(grpc_workaround_list id) { } } -} // namespace grpc +} // namespace grpc_impl 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 c0078bf2764..937ed0e6749 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 501e53560ab..5e116090819 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10089,6 +10089,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", @@ -10198,6 +10199,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 d1dc707908dbb498af6e3da68d3af50fb9f67eff Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 26 Mar 2019 09:33:15 -0700 Subject: [PATCH 1613/2143] 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 1614/2143] 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 9ff845961ea95c6beb4236fac3770fcc21b768b0 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 26 Mar 2019 19:21:18 +0100 Subject: [PATCH 1615/2143] Breakout of #18445 - part 2 --- src/core/lib/transport/transport.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 9d4b5615e57..8631a1af81f 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -273,40 +273,40 @@ struct grpc_transport_stream_op_batch_payload { /** Transport op: a set of operations to perform on a transport as a whole */ typedef struct grpc_transport_op { /** Called when processing of this op is done. */ - grpc_closure* on_consumed; + grpc_closure* on_consumed = nullptr; /** connectivity monitoring - set connectivity_state to NULL to unsubscribe */ - grpc_closure* on_connectivity_state_change; - grpc_connectivity_state* connectivity_state; + grpc_closure* on_connectivity_state_change = nullptr; + grpc_connectivity_state* connectivity_state = nullptr; /** should the transport be disconnected * Error contract: the transport that gets this op must cause * disconnect_with_error to be unref'ed after processing it */ - grpc_error* disconnect_with_error; + grpc_error* disconnect_with_error = nullptr; /** what should the goaway contain? * Error contract: the transport that gets this op must cause * goaway_error to be unref'ed after processing it */ - grpc_error* goaway_error; + grpc_error* goaway_error = nullptr; /** set the callback for accepting new streams; this is a permanent callback, unlike the other one-shot closures. If true, the callback is set to set_accept_stream_fn, with its user_data argument set to set_accept_stream_user_data */ - bool set_accept_stream; + bool set_accept_stream = false; void (*set_accept_stream_fn)(void* user_data, grpc_transport* transport, - const void* server_data); - void* set_accept_stream_user_data; + const void* server_data) = nullptr; + void* set_accept_stream_user_data = nullptr; /** add this transport to a pollset */ - grpc_pollset* bind_pollset; + grpc_pollset* bind_pollset = nullptr; /** add this transport to a pollset_set */ - grpc_pollset_set* bind_pollset_set; + grpc_pollset_set* bind_pollset_set = nullptr; /** send a ping, if either on_initiate or on_ack is not NULL */ struct { /** Ping may be delayed by the transport, on_initiate callback will be called when the ping is actually being sent. */ - grpc_closure* on_initiate; + grpc_closure* on_initiate = nullptr; /** Called when the ping ack is received */ - grpc_closure* on_ack; + grpc_closure* on_ack = nullptr; } send_ping; // If true, will reset the channel's connection backoff. - bool reset_connect_backoff; + bool reset_connect_backoff = false; /*************************************************************************** * remaining fields are initialized and used at the discretion of the From 206592ce9c104e95cf699e81d20c3cadbf1f4d1a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 26 Mar 2019 10:52:56 -0700 Subject: [PATCH 1616/2143] 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 1617/2143] 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 1618/2143] 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 1619/2143] 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 1620/2143] 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 1621/2143] 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 cd2755b72bd0414f1d91bba64999aa2e7afc38e5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 26 Mar 2019 14:43:21 -0700 Subject: [PATCH 1622/2143] polish tests and fix issues --- src/objective-c/GRPCClient/GRPCCall.m | 12 ++++ src/objective-c/tests/APIv2Tests/APIv2Tests.m | 71 ++++++++++++++++--- 2 files changed, 73 insertions(+), 10 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index e70aa5caba0..e9a0f43cdde 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -122,6 +122,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; BOOL _canceled; /** Flags whether call has been finished. */ BOOL _finished; + /** The number of pending messages receiving requests. */ + NSUInteger _pendingReceiveNextMessage; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -210,6 +212,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (_callOptions.initialMetadata) { [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata]; } + if (_pendingReceiveNextMessage) { + [_call receiveNextMessage]; + _pendingReceiveNextMessage = NO; + } copiedCall = _call; } @@ -397,6 +403,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; GRPCCall *copiedCall = nil; @synchronized(self) { copiedCall = _call; + if (copiedCall == nil) { + _pendingReceiveNextMessage = YES; + return; + } } [copiedCall receiveNextMessage]; } @@ -662,6 +672,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (_callOptions.enableFlowControl && (_pendingCoreRead || !_pendingReceiveNextMessage)) { return; } + _pendingCoreRead = YES; + _pendingReceiveNextMessage = NO; } dispatch_async(_callQueue, ^{ diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index 6509b79b822..17df4ab933e 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -39,11 +39,12 @@ static NSString *const kService = @"TestService"; static GRPCProtoMethod *kInexistentMethod; static GRPCProtoMethod *kEmptyCallMethod; static GRPCProtoMethod *kUnaryCallMethod; +static GRPCProtoMethod *kOutputStreamingCallMethod; static GRPCProtoMethod *kFullDuplexCallMethod; static const int kSimpleDataLength = 100; -static const NSTimeInterval kTestTimeout = 16; +static const NSTimeInterval kTestTimeout = 8; static const NSTimeInterval kInvertedTimeout = 2; // Reveal the _class ivar for testing access @@ -143,6 +144,8 @@ static const NSTimeInterval kInvertedTimeout = 2; [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"EmptyCall"]; kUnaryCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"UnaryCall"]; + kOutputStreamingCallMethod = + [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"StreamingOutputCall"]; kFullDuplexCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"FullDuplexCall"]; } @@ -547,10 +550,8 @@ static const NSTimeInterval kInvertedTimeout = 2; expectBlockedMessage.inverted = YES; expectBlockedClose.inverted = YES; - RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; - RMTResponseParameters *parameters = [RMTResponseParameters message]; - parameters.size = kSimpleDataLength; - [request.responseParametersArray addObject:parameters]; + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseSize = kSimpleDataLength; request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; GRPCRequestOptions *callRequest = @@ -597,15 +598,62 @@ static const NSTimeInterval kInvertedTimeout = 2; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } -- (void)testReadFlowControlReadyBeforeStart { - __weak XCTestExpectation *expectBlockedMessage = - [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; +- (void)testReadFlowControlMultipleMessages { + XCTestExpectation *expectPassedMessage = + [self expectationWithDescription:@"two messages delivered with receiveNextMessage"]; + expectPassedMessage.expectedFulfillmentCount = 2; + XCTestExpectation *expectBlockedMessage = + [self expectationWithDescription:@"Message 3 not delivered"]; expectBlockedMessage.inverted = YES; RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; RMTResponseParameters *parameters = [RMTResponseParameters message]; parameters.size = kSimpleDataLength; [request.responseParametersArray addObject:parameters]; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kOutputStreamingCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.enableFlowControl = YES; + __block NSUInteger messageId = 0; + __block GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(NSData *message) { + if (messageId <= 1) { + [expectPassedMessage fulfill]; + if (messageId < 1) { + [call receiveNextMessage]; + } + } else { + [expectBlockedMessage fulfill]; + } + messageId++; + } + closeCallback:nil] + callOptions:options]; + + [call receiveNextMessage]; + [call start]; + [call writeData:[request data]]; + + [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil]; +} + +- (void)testReadFlowControlReadyBeforeStart { + __weak XCTestExpectation *expectPassedMessage = + [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; + __weak XCTestExpectation *expectPassedClose = + [self expectationWithDescription:@"Close delivered with receiveNextMessage"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseSize = kSimpleDataLength; request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; GRPCRequestOptions *callRequest = @@ -621,10 +669,13 @@ static const NSTimeInterval kInvertedTimeout = 2; responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(NSData *message) { - [expectBlockedMessage fulfill]; + [expectPassedMessage fulfill]; XCTAssertFalse(closed); } - closeCallback:nil] + closeCallback:^(NSDictionary *ttrailers, NSError *error) { + closed = YES; + [expectPassedClose fulfill]; + }] callOptions:options]; [call receiveNextMessage]; From 084ebec9af83b524567abd71fa8886708d516196 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 26 Mar 2019 15:41:19 -0700 Subject: [PATCH 1623/2143] Update jessie-backports URL --- templates/tools/dockerfile/cmake_jessie_backports.include | 2 +- test/distrib/cpp/run_distrib_test_cmake.sh | 3 +-- test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh | 3 +-- tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile | 2 +- tools/dockerfile/grpc_artifact_linux_x64/Dockerfile | 2 +- tools/dockerfile/grpc_artifact_linux_x86/Dockerfile | 2 +- tools/dockerfile/test/cxx_jessie_x64/Dockerfile | 2 +- tools/dockerfile/test/cxx_jessie_x86/Dockerfile | 2 +- tools/dockerfile/test/fuzzer/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 11 deletions(-) diff --git a/templates/tools/dockerfile/cmake_jessie_backports.include b/templates/tools/dockerfile/cmake_jessie_backports.include index 2fc49dc8d60..6acb991cd78 100644 --- a/templates/tools/dockerfile/cmake_jessie_backports.include +++ b/templates/tools/dockerfile/cmake_jessie_backports.include @@ -2,5 +2,5 @@ # Use cmake 3.6 from jessie-backports # should only be used for images based on debian jessie. -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean diff --git a/test/distrib/cpp/run_distrib_test_cmake.sh b/test/distrib/cpp/run_distrib_test_cmake.sh index 6ec3cab6024..06406a40d29 100755 --- a/test/distrib/cpp/run_distrib_test_cmake.sh +++ b/test/distrib/cpp/run_distrib_test_cmake.sh @@ -17,7 +17,7 @@ set -ex cd "$(dirname "$0")/../../.." -echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list apt-get update apt-get install -t jessie-backports -y libssl-dev @@ -63,4 +63,3 @@ mkdir -p cmake/build cd cmake/build cmake ../.. make - diff --git a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh index 163527fbd50..59d7674db6d 100755 --- a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh +++ b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh @@ -17,7 +17,7 @@ set -ex cd "$(dirname "$0")/../../.." -echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list apt-get update apt-get install -t jessie-backports -y libssl-dev @@ -38,4 +38,3 @@ mkdir -p cmake/build cd cmake/build cmake ../.. make - diff --git a/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile b/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile index 894f114951c..dcab64aaeae 100644 --- a/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile +++ b/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile @@ -29,7 +29,7 @@ RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y golang && apt-get clean -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean CMD ["bash"] diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile index f247cc9ca54..5b2b3dbf6de 100644 --- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile @@ -72,7 +72,7 @@ RUN apt-get update && apt-get install -y \ # C# dependencies (needed to build grpc_csharp_ext) # Use cmake 3.6 from jessie-backports -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile index e403f75b594..ee0a7105389 100644 --- a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile @@ -64,7 +64,7 @@ RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-ri --no-rdoc" # C# dependencies (needed to build grpc_csharp_ext) # Use cmake 3.6 from jessie-backports -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile index f9dc8f20d7c..c801edfa386 100644 --- a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev c # Use cmake 3.6 from jessie-backports # should only be used for images based on debian jessie. -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean diff --git a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile index 76015c8c42d..3fdbb27f6e1 100644 --- a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile +++ b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile @@ -79,7 +79,7 @@ RUN mkdir /var/local/jenkins # Use cmake 3.6 from jessie-backports # should only be used for images based on debian jessie. -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean diff --git a/tools/dockerfile/test/fuzzer/Dockerfile b/tools/dockerfile/test/fuzzer/Dockerfile index 7f871f2f62a..ef9305bcc8d 100644 --- a/tools/dockerfile/test/fuzzer/Dockerfile +++ b/tools/dockerfile/test/fuzzer/Dockerfile @@ -76,7 +76,7 @@ RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev c # Use cmake 3.6 from jessie-backports # should only be used for images based on debian jessie. -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean #================= From 0d9ae65c70fd0e0ecabdd800ac73a38ee603c890 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 26 Mar 2019 15:45:29 -0700 Subject: [PATCH 1624/2143] Allow multiple pending reads --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 41 +++++++++---------- src/objective-c/ProtoRPC/ProtoRPC.h | 12 ++++++ src/objective-c/ProtoRPC/ProtoRPC.m | 6 ++- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 41 ++++++++++--------- 5 files changed, 60 insertions(+), 42 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index aab6ecc4445..decafd5c58e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -265,7 +265,7 @@ extern NSString *const kGRPCTrailersKey; */ - (void)finish; -- (void)receiveNextMessage; +- (void)receiveNextMessages:(NSUInteger)numberOfMessages; /** * Get a copy of the original call options. diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index e9a0f43cdde..e2625a63e19 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -70,7 +70,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; callOptions:(GRPCCallOptions *)callOptions writeDone:(void (^)(void))writeDone; -- (void)receiveNextMessage; +- (void)receiveNextMessages:(NSUInteger)numberOfMessages; @end @@ -123,7 +123,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; /** Flags whether call has been finished. */ BOOL _finished; /** The number of pending messages receiving requests. */ - NSUInteger _pendingReceiveNextMessage; + NSUInteger _pendingReceiveNextMessages; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -212,9 +212,9 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (_callOptions.initialMetadata) { [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata]; } - if (_pendingReceiveNextMessage) { - [_call receiveNextMessage]; - _pendingReceiveNextMessage = NO; + if (_pendingReceiveNextMessages > 0) { + [_call receiveNextMessages:_pendingReceiveNextMessages]; + _pendingReceiveNextMessages = 0; } copiedCall = _call; } @@ -399,16 +399,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; } } -- (void)receiveNextMessage { +- (void)receiveNextMessages:(NSUInteger)numberOfMessages { GRPCCall *copiedCall = nil; @synchronized(self) { copiedCall = _call; if (copiedCall == nil) { - _pendingReceiveNextMessage = YES; + _pendingReceiveNextMessages += numberOfMessages; return; } } - [copiedCall receiveNextMessage]; + [copiedCall receiveNextMessages:numberOfMessages]; } @end @@ -481,8 +481,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Indicate a read request to core is pending. BOOL _pendingCoreRead; - // Indicate a read message request from user. - BOOL _pendingReceiveNextMessage; + // Indicate pending read message request from user. + NSUInteger _pendingReceiveNextMessages; } @synthesize state = _state; @@ -591,7 +591,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; _responseQueue = dispatch_get_main_queue(); // do not start a read until initial metadata is received - _pendingReceiveNextMessage = NO; + _pendingReceiveNextMessages = 0; _pendingCoreRead = YES; } return self; @@ -669,11 +669,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (_state != GRXWriterStateStarted) { return; } - if (_callOptions.enableFlowControl && (_pendingCoreRead || !_pendingReceiveNextMessage)) { + if (_callOptions.enableFlowControl && (_pendingCoreRead || _pendingReceiveNextMessages == 0)) { return; } _pendingCoreRead = YES; - _pendingReceiveNextMessage = NO; + _pendingReceiveNextMessages--; } dispatch_async(_callQueue, ^{ @@ -696,7 +696,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // that's on the hands of any server to have. Instead we finish and ask // the server to cancel. @synchronized(strongSelf) { - strongSelf->_pendingReceiveNextMessage = NO; + strongSelf->_pendingReceiveNextMessages--; [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeResourceExhausted @@ -764,13 +764,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; }); } -- (void)receiveNextMessage { +- (void)receiveNextMessages:(NSUInteger)numberOfMessages { + if (numberOfMessages == 0) { + return; + } @synchronized(self) { - // Duplicate invocation of this method. Return - if (_pendingReceiveNextMessage) { - return; - } - _pendingReceiveNextMessage = YES; + _pendingReceiveNextMessages += numberOfMessages; + [self maybeStartNextRead]; } } @@ -793,7 +793,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; } } }; - GRPCOpSendMessage *op = [[GRPCOpSendMessage alloc] initWithMessage:message handler:resumingHandler]; if (!_unaryCall) { diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 19294763fc1..68dec445c71 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -136,8 +136,20 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)finish; +/** + * Tell gRPC to receive the next message. If flow control is enabled, the messages received from the + * server are buffered in gRPC until the user want to receive the next message. If flow control is + * not enabled, messages will be automatically received after the previous one is delivered. + */ - (void)receiveNextMessage; +/** + * Tell gRPC to receive the next N message. If flow control is enabled, the messages received from + * the server are buffered in gRPC until the user want to receive the next message. If flow control + * is not enabled, messages will be automatically received after the previous one is delivered. + */ +- (void)receiveNextMessages:(NSUInteger)numberOfMessages; + @end NS_ASSUME_NONNULL_END diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index e7a56b0f285..80988be318b 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -72,6 +72,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)start { [_call start]; + [_call receiveNextMessage]; [_call writeMessage:_message]; [_call finish]; } @@ -198,11 +199,14 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } - (void)receiveNextMessage { + [self receiveNextMessages:1]; +} +- (void)receiveNextMessages:(NSUInteger)numberOfMessages { GRPCCall2 *copiedCall; @synchronized(self) { copiedCall = _call; } - [copiedCall receiveNextMessage]; + [copiedCall receiveNextMessages:numberOfMessages]; } - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index 17df4ab933e..0966b4e58f9 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -502,7 +502,7 @@ static const NSTimeInterval kInvertedTimeout = 2; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } -- (void)testWriteFlowControl { +- (void)testFlowControlWrite { __weak XCTestExpectation *expectWriteData = [self expectationWithDescription:@"Reported write data"]; @@ -531,7 +531,7 @@ static const NSTimeInterval kInvertedTimeout = 2; callOptions:options]; [call start]; - [call receiveNextMessage]; + [call receiveNextMessages:1]; [call writeData:[request data]]; // Wait for 3 seconds and make sure we do not receive the response @@ -540,7 +540,7 @@ static const NSTimeInterval kInvertedTimeout = 2; [call finish]; } -- (void)testReadFlowControl { +- (void)testFlowControlRead { __weak __block XCTestExpectation *expectBlockedMessage = [self expectationWithDescription:@"Message not delivered without recvNextMessage"]; __weak __block XCTestExpectation *expectPassedMessage = nil; @@ -593,29 +593,31 @@ static const NSTimeInterval kInvertedTimeout = 2; expectPassedClose = [self expectationWithDescription:@"Close delivered after receiveNextMessage"]; unblocked = YES; - [call receiveNextMessage]; + [call receiveNextMessages:1]; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } -- (void)testReadFlowControlMultipleMessages { - XCTestExpectation *expectPassedMessage = +- (void)testFlowControlMultipleMessages { + __weak XCTestExpectation *expectPassedMessage = [self expectationWithDescription:@"two messages delivered with receiveNextMessage"]; expectPassedMessage.expectedFulfillmentCount = 2; - XCTestExpectation *expectBlockedMessage = + __weak XCTestExpectation *expectBlockedMessage = [self expectationWithDescription:@"Message 3 not delivered"]; expectBlockedMessage.inverted = YES; + __weak XCTestExpectation *expectWriteTwice = + [self expectationWithDescription:@"Write 2 messages done"]; + expectWriteTwice.expectedFulfillmentCount = 2; RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; RMTResponseParameters *parameters = [RMTResponseParameters message]; parameters.size = kSimpleDataLength; [request.responseParametersArray addObject:parameters]; - [request.responseParametersArray addObject:parameters]; request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; GRPCRequestOptions *callRequest = [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress - path:kOutputStreamingCallMethod.HTTPPath + path:kFullDuplexCallMethod.HTTPPath safety:GRPCCallSafetyDefault]; GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = GRPCTransportTypeInsecure; @@ -628,25 +630,26 @@ static const NSTimeInterval kInvertedTimeout = 2; messageCallback:^(NSData *message) { if (messageId <= 1) { [expectPassedMessage fulfill]; - if (messageId < 1) { - [call receiveNextMessage]; - } } else { [expectBlockedMessage fulfill]; } messageId++; } - closeCallback:nil] + closeCallback:nil + writeDataCallback:^{ + [expectWriteTwice fulfill]; + }] callOptions:options]; - [call receiveNextMessage]; + [call receiveNextMessages:2]; [call start]; [call writeData:[request data]]; + [call writeData:[request data]]; [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil]; } -- (void)testReadFlowControlReadyBeforeStart { +- (void)testFlowControlReadReadyBeforeStart { __weak XCTestExpectation *expectPassedMessage = [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; __weak XCTestExpectation *expectPassedClose = @@ -678,7 +681,7 @@ static const NSTimeInterval kInvertedTimeout = 2; }] callOptions:options]; - [call receiveNextMessage]; + [call receiveNextMessages:1]; [call start]; [call writeData:[request data]]; [call finish]; @@ -686,7 +689,7 @@ static const NSTimeInterval kInvertedTimeout = 2; [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil]; } -- (void)testReadFlowControlReadyAfterStart { +- (void)testFlowControlReadReadyAfterStart { __weak XCTestExpectation *expectPassedMessage = [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; __weak XCTestExpectation *expectPassedClose = @@ -720,14 +723,14 @@ static const NSTimeInterval kInvertedTimeout = 2; callOptions:options]; [call start]; - [call receiveNextMessage]; + [call receiveNextMessages:1]; [call writeData:[request data]]; [call finish]; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } -- (void)testReadFlowControlNonBlockingFailure { +- (void)testFlowControlReadNonBlockingFailure { __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; GRPCRequestOptions *requestOptions = From 93dc0d6ec3c4a3146d06d307db8b196f9be3f450 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 26 Mar 2019 17:43:20 -0700 Subject: [PATCH 1625/2143] Update fix with new information from post --- templates/tools/dockerfile/cmake_jessie_backports.include | 4 ++-- test/distrib/cpp/run_distrib_test_cmake.sh | 4 ++-- test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh | 4 ++-- tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile | 4 ++-- tools/dockerfile/grpc_artifact_linux_x64/Dockerfile | 4 ++-- tools/dockerfile/grpc_artifact_linux_x86/Dockerfile | 4 ++-- tools/dockerfile/test/cxx_jessie_x64/Dockerfile | 4 ++-- tools/dockerfile/test/cxx_jessie_x86/Dockerfile | 4 ++-- tools/dockerfile/test/fuzzer/Dockerfile | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/templates/tools/dockerfile/cmake_jessie_backports.include b/templates/tools/dockerfile/cmake_jessie_backports.include index 6acb991cd78..1da6ed79190 100644 --- a/templates/tools/dockerfile/cmake_jessie_backports.include +++ b/templates/tools/dockerfile/cmake_jessie_backports.include @@ -2,5 +2,5 @@ # Use cmake 3.6 from jessie-backports # should only be used for images based on debian jessie. -RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean diff --git a/test/distrib/cpp/run_distrib_test_cmake.sh b/test/distrib/cpp/run_distrib_test_cmake.sh index 06406a40d29..f0e1b8c8e39 100755 --- a/test/distrib/cpp/run_distrib_test_cmake.sh +++ b/test/distrib/cpp/run_distrib_test_cmake.sh @@ -17,8 +17,8 @@ set -ex cd "$(dirname "$0")/../../.." -echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -apt-get update +echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +apt-get -o Acquire::Check-Valid-Until=false update apt-get install -t jessie-backports -y libssl-dev # Install c-ares diff --git a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh index 59d7674db6d..ea37bd53b4f 100755 --- a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh +++ b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh @@ -17,8 +17,8 @@ set -ex cd "$(dirname "$0")/../../.." -echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -apt-get update +echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +apt-get -o Acquire::Check-Valid-Until=false update apt-get install -t jessie-backports -y libssl-dev # To increase the confidence that gRPC installation works without depending on diff --git a/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile b/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile index dcab64aaeae..d157a278b1e 100644 --- a/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile +++ b/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile @@ -29,7 +29,7 @@ RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y golang && apt-get clean -RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean CMD ["bash"] diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile index 5b2b3dbf6de..07564dc40a9 100644 --- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile @@ -72,8 +72,8 @@ RUN apt-get update && apt-get install -y \ # C# dependencies (needed to build grpc_csharp_ext) # Use cmake 3.6 from jessie-backports -RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile index ee0a7105389..55091f4fffa 100644 --- a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile @@ -64,8 +64,8 @@ RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-ri --no-rdoc" # C# dependencies (needed to build grpc_csharp_ext) # Use cmake 3.6 from jessie-backports -RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile index c801edfa386..6afad4869fd 100644 --- a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile @@ -76,8 +76,8 @@ RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev c # Use cmake 3.6 from jessie-backports # should only be used for images based on debian jessie. -RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile index 3fdbb27f6e1..c153cd037e6 100644 --- a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile +++ b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile @@ -79,8 +79,8 @@ RUN mkdir /var/local/jenkins # Use cmake 3.6 from jessie-backports # should only be used for images based on debian jessie. -RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean # Install gcc-4.8 and other relevant items diff --git a/tools/dockerfile/test/fuzzer/Dockerfile b/tools/dockerfile/test/fuzzer/Dockerfile index ef9305bcc8d..591ca0ce014 100644 --- a/tools/dockerfile/test/fuzzer/Dockerfile +++ b/tools/dockerfile/test/fuzzer/Dockerfile @@ -76,8 +76,8 @@ RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev c # Use cmake 3.6 from jessie-backports # should only be used for images based on debian jessie. -RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean #================= # Update clang to a version with improved tsan and fuzzing capabilities From 4e9e662729e82bb88570e4151e11fc62d46f6ae7 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Thu, 14 Mar 2019 16:44:04 -0700 Subject: [PATCH 1626/2143] 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 1627/2143] 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 1628/2143] 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 cdf3e001cb9aa26e8ef9af4f58cbdc252e139afa Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 27 Mar 2019 10:26:41 -0700 Subject: [PATCH 1629/2143] wip selective build for windows --- bazel/grpc_build_system.bzl | 20 +++++++++++--------- test/core/end2end/generate_tests.bzl | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index c5eb9ec8bf3..84455cdafc2 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": [], @@ -157,7 +151,6 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data if language.upper() == "C": copts = copts + if_not_windows(["-std=c99"]) args = { - "name": name, "srcs": srcs, "args": args, "data": data, @@ -172,8 +165,17 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data # Only run targets with pollers for non-MSVC # Only run targets without pollers for MSVC native.cc_test( + name = name, + testonly = True, + tags = [ + "manual", + "no_windows", + ], + **args + ) + native.cc_test( + name = name + "_windows", testonly = True, - tags = tags if is_msvc() else ["manual"], **args ) for poller in POLLERS: @@ -189,7 +191,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data poller, "$(location %s)" % name, ] + args["args"], - tags = (tags + ["no_windows"]) if is_msvc() else tags, + tags = (tags + ["no_windows"]), exec_compatible_with = exec_compatible_with, ) else: diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 8020780a909..fa666bac976 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"] From b0e75a42d28c232e8940f4578551cd2eb72a5c2e Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 27 Mar 2019 14:10:46 -0400 Subject: [PATCH 1630/2143] 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 961f25bd2752549f4f4c5fadf605cf3770cd1ee0 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 27 Mar 2019 11:13:02 -0700 Subject: [PATCH 1631/2143] Slightly different check-valid-until fix --- templates/tools/dockerfile/cmake_jessie_backports.include | 3 ++- test/distrib/cpp/run_distrib_test_cmake.sh | 3 ++- test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh | 3 ++- tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile | 3 ++- tools/dockerfile/grpc_artifact_linux_x64/Dockerfile | 3 ++- tools/dockerfile/grpc_artifact_linux_x86/Dockerfile | 3 ++- tools/dockerfile/test/cxx_jessie_x64/Dockerfile | 3 ++- tools/dockerfile/test/cxx_jessie_x86/Dockerfile | 3 ++- tools/dockerfile/test/fuzzer/Dockerfile | 3 ++- 9 files changed, 18 insertions(+), 9 deletions(-) diff --git a/templates/tools/dockerfile/cmake_jessie_backports.include b/templates/tools/dockerfile/cmake_jessie_backports.include index 1da6ed79190..ad08dc95451 100644 --- a/templates/tools/dockerfile/cmake_jessie_backports.include +++ b/templates/tools/dockerfile/cmake_jessie_backports.include @@ -3,4 +3,5 @@ # should only be used for images based on debian jessie. RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean diff --git a/test/distrib/cpp/run_distrib_test_cmake.sh b/test/distrib/cpp/run_distrib_test_cmake.sh index f0e1b8c8e39..d3ecde7cf88 100755 --- a/test/distrib/cpp/run_distrib_test_cmake.sh +++ b/test/distrib/cpp/run_distrib_test_cmake.sh @@ -18,7 +18,8 @@ set -ex cd "$(dirname "$0")/../../.." echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -apt-get -o Acquire::Check-Valid-Until=false update +echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +apt-get update apt-get install -t jessie-backports -y libssl-dev # Install c-ares diff --git a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh index ea37bd53b4f..58d98a9124a 100755 --- a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh +++ b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh @@ -18,7 +18,8 @@ set -ex cd "$(dirname "$0")/../../.." echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -apt-get -o Acquire::Check-Valid-Until=false update +echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +apt-get update apt-get install -t jessie-backports -y libssl-dev # To increase the confidence that gRPC installation works without depending on diff --git a/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile b/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile index d157a278b1e..acce897242a 100644 --- a/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile +++ b/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile @@ -30,6 +30,7 @@ RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y golang && apt-get clean RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean CMD ["bash"] diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile index 07564dc40a9..7d85efe2eb2 100644 --- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile @@ -73,7 +73,8 @@ RUN apt-get update && apt-get install -y \ # Use cmake 3.6 from jessie-backports RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile index 55091f4fffa..e370fafd7fc 100644 --- a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile @@ -65,7 +65,8 @@ RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-ri --no-rdoc" # Use cmake 3.6 from jessie-backports RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile index 6afad4869fd..b4899f1e3fe 100644 --- a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile @@ -77,7 +77,8 @@ RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev c # should only be used for images based on debian jessie. RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile index c153cd037e6..59bed835418 100644 --- a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile +++ b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile @@ -80,7 +80,8 @@ RUN mkdir /var/local/jenkins # should only be used for images based on debian jessie. RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean # Install gcc-4.8 and other relevant items diff --git a/tools/dockerfile/test/fuzzer/Dockerfile b/tools/dockerfile/test/fuzzer/Dockerfile index 591ca0ce014..25e417cecba 100644 --- a/tools/dockerfile/test/fuzzer/Dockerfile +++ b/tools/dockerfile/test/fuzzer/Dockerfile @@ -77,7 +77,8 @@ RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev c # should only be used for images based on debian jessie. RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get -o Acquire::Check-Valid-Until=false update && apt-get install -t jessie-backports -y cmake && apt-get clean +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean #================= # Update clang to a version with improved tsan and fuzzing capabilities From 85bcce2e086d5bbb03eca386665ffd76bd4e957a Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 27 Mar 2019 12:19:00 -0700 Subject: [PATCH 1632/2143] Fix typo in BUILD.bazel --- examples/python/errors/BUILD.bazel | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/python/errors/BUILD.bazel b/examples/python/errors/BUILD.bazel index 1ef36a06471..38bed132844 100644 --- a/examples/python/errors/BUILD.bazel +++ b/examples/python/errors/BUILD.bazel @@ -43,11 +43,9 @@ py_library( py_test( name = "test/_error_handling_example_test", srcs = ["test/_error_handling_example_test.py"], - data = [ + deps = [ ":client", ":server", - "//src/python/grpcio/grpc:grpcio", - "//examples:py_helloworld", "//src/python/grpcio_tests/tests:bazel_namespace_package_hack", ], size = "small", From a88e3f4c2eaace140bcff9cce034266ae6f89566 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 14 Mar 2019 15:32:51 -0700 Subject: [PATCH 1633/2143] Move ServerBuilderOption from grpc to grpc_impl namespace --- BUILD | 1 + CMakeLists.txt | 3 ++ Makefile | 3 ++ build.yaml | 1 + gRPC-C++.podspec | 1 + include/grpcpp/impl/server_builder_option.h | 19 ++------ .../grpcpp/impl/server_builder_option_impl.h | 43 +++++++++++++++++++ 7 files changed, 55 insertions(+), 16 deletions(-) create mode 100644 include/grpcpp/impl/server_builder_option_impl.h diff --git a/BUILD b/BUILD index 349ade626b4..90d60c3a0c0 100644 --- a/BUILD +++ b/BUILD @@ -235,6 +235,7 @@ GRPCXX_PUBLIC_HDRS = [ "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_option_impl.h", "include/grpcpp/impl/server_builder_plugin.h", "include/grpcpp/impl/server_initializer.h", "include/grpcpp/impl/service_type.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index e7857d5d84e..0090b8ad34f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3015,6 +3015,7 @@ foreach(_hdr 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_option_impl.h include/grpcpp/impl/server_builder_plugin.h include/grpcpp/impl/server_initializer.h include/grpcpp/impl/service_type.h @@ -3606,6 +3607,7 @@ foreach(_hdr 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_option_impl.h include/grpcpp/impl/server_builder_plugin.h include/grpcpp/impl/server_initializer.h include/grpcpp/impl/service_type.h @@ -4569,6 +4571,7 @@ foreach(_hdr 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_option_impl.h include/grpcpp/impl/server_builder_plugin.h include/grpcpp/impl/server_initializer.h include/grpcpp/impl/service_type.h diff --git a/Makefile b/Makefile index c0b277f0fb1..0c2a8a95ed6 100644 --- a/Makefile +++ b/Makefile @@ -5342,6 +5342,7 @@ PUBLIC_HEADERS_CXX += \ 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_option_impl.h \ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ @@ -5941,6 +5942,7 @@ PUBLIC_HEADERS_CXX += \ 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_option_impl.h \ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ @@ -6853,6 +6855,7 @@ PUBLIC_HEADERS_CXX += \ 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_option_impl.h \ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ diff --git a/build.yaml b/build.yaml index c1271be9131..c300ff38289 100644 --- a/build.yaml +++ b/build.yaml @@ -1360,6 +1360,7 @@ filegroups: - 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_option_impl.h - include/grpcpp/impl/server_builder_plugin.h - include/grpcpp/impl/server_initializer.h - include/grpcpp/impl/service_type.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 7afd9ef1a84..9f0a4156d24 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -101,6 +101,7 @@ Pod::Spec.new do |s| '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_option_impl.h', 'include/grpcpp/impl/server_builder_plugin.h', 'include/grpcpp/impl/server_initializer.h', 'include/grpcpp/impl/service_type.h', diff --git a/include/grpcpp/impl/server_builder_option.h b/include/grpcpp/impl/server_builder_option.h index c7b7801dab3..4b3d6b54118 100644 --- a/include/grpcpp/impl/server_builder_option.h +++ b/include/grpcpp/impl/server_builder_option.h @@ -1,6 +1,6 @@ /* * - * 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. @@ -19,24 +19,11 @@ #ifndef GRPCPP_IMPL_SERVER_BUILDER_OPTION_H #define GRPCPP_IMPL_SERVER_BUILDER_OPTION_H -#include -#include - -#include -#include +#include namespace grpc { -/// Interface to pass an option to a \a ServerBuilder. -class ServerBuilderOption { - public: - virtual ~ServerBuilderOption() {} - /// Alter the \a ChannelArguments used to create the gRPC server. - virtual void UpdateArguments(ChannelArguments* args) = 0; - /// Alter the ServerBuilderPlugin map that will be added into ServerBuilder. - virtual void UpdatePlugins( - std::vector>* plugins) = 0; -}; +typedef ::grpc_impl::ServerBuilderOption ServerBuilderOption; } // namespace grpc diff --git a/include/grpcpp/impl/server_builder_option_impl.h b/include/grpcpp/impl/server_builder_option_impl.h new file mode 100644 index 00000000000..8271d0f56b2 --- /dev/null +++ b/include/grpcpp/impl/server_builder_option_impl.h @@ -0,0 +1,43 @@ +/* + * + * 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_IMPL_SERVER_BUILDER_OPTION_IMPL_H +#define GRPCPP_IMPL_SERVER_BUILDER_OPTION_IMPL_H + +#include +#include + +#include +#include + +namespace grpc_impl { + +/// Interface to pass an option to a \a ServerBuilder. +class ServerBuilderOption { + public: + virtual ~ServerBuilderOption() {} + /// Alter the \a ChannelArguments used to create the gRPC server. + virtual void UpdateArguments(grpc::ChannelArguments* args) = 0; + /// Alter the ServerBuilderPlugin map that will be added into ServerBuilder. + virtual void UpdatePlugins( + std::vector>* plugins) = 0; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_IMPL_SERVER_BUILDER_OPTION_IMPL_H From ab2bf7abf08a74d3e4118eee92b8b9b77c3fd80a Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 14:47:56 -0700 Subject: [PATCH 1634/2143] Fix presubmit script errors. --- 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..c5bf7d6fcb2 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -991,6 +991,7 @@ 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_option_impl.h \ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 1e17ab8f88b..ebcd10d3e50 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -993,6 +993,7 @@ 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_option_impl.h \ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index cd88082f884..af918aff6f1 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10080,6 +10080,7 @@ "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_option_impl.h", "include/grpcpp/impl/server_builder_plugin.h", "include/grpcpp/impl/server_initializer.h", "include/grpcpp/impl/service_type.h", @@ -10189,6 +10190,7 @@ "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_option_impl.h", "include/grpcpp/impl/server_builder_plugin.h", "include/grpcpp/impl/server_initializer.h", "include/grpcpp/impl/service_type.h", From 7660adfd80718acc65b104accae6e4f4885c9664 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 27 Mar 2019 12:23:32 -0700 Subject: [PATCH 1635/2143] Fix BUILD.gn file --- BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.gn b/BUILD.gn index d15961a4879..183f983e338 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1066,6 +1066,7 @@ config("grpc_config") { "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_option_impl.h", "include/grpcpp/impl/server_builder_plugin.h", "include/grpcpp/impl/server_initializer.h", "include/grpcpp/impl/service_type.h", From 577ddfb1a1fa2d4025c623e89596a0b1d513c24c Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 14 Mar 2019 16:17:21 -0700 Subject: [PATCH 1636/2143] Move ServerInitializer to grpc_impl namespace from grpc --- BUILD | 1 + CMakeLists.txt | 3 + Makefile | 3 + build.yaml | 1 + gRPC-C++.podspec | 1 + .../ext/proto_server_reflection_plugin.h | 9 ++- include/grpcpp/impl/server_builder_plugin.h | 9 ++- include/grpcpp/impl/server_initializer.h | 31 +--------- include/grpcpp/impl/server_initializer_impl.h | 57 +++++++++++++++++++ include/grpcpp/server.h | 11 ++-- ..._reporting_service_server_builder_plugin.h | 6 +- src/cpp/server/server_builder.cc | 2 +- src/cpp/server/server_cc.cc | 2 +- 13 files changed, 93 insertions(+), 43 deletions(-) create mode 100644 include/grpcpp/impl/server_initializer_impl.h diff --git a/BUILD b/BUILD index 349ade626b4..4da4a6017e9 100644 --- a/BUILD +++ b/BUILD @@ -237,6 +237,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/impl/server_builder_option.h", "include/grpcpp/impl/server_builder_plugin.h", "include/grpcpp/impl/server_initializer.h", + "include/grpcpp/impl/server_initializer_impl.h", "include/grpcpp/impl/service_type.h", "include/grpcpp/impl/sync_cxx11.h", "include/grpcpp/impl/sync_no_cxx11.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index e7857d5d84e..168e66b827c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3017,6 +3017,7 @@ foreach(_hdr include/grpcpp/impl/server_builder_option.h include/grpcpp/impl/server_builder_plugin.h include/grpcpp/impl/server_initializer.h + include/grpcpp/impl/server_initializer_impl.h include/grpcpp/impl/service_type.h include/grpcpp/resource_quota.h include/grpcpp/security/auth_context.h @@ -3608,6 +3609,7 @@ foreach(_hdr include/grpcpp/impl/server_builder_option.h include/grpcpp/impl/server_builder_plugin.h include/grpcpp/impl/server_initializer.h + include/grpcpp/impl/server_initializer_impl.h include/grpcpp/impl/service_type.h include/grpcpp/resource_quota.h include/grpcpp/security/auth_context.h @@ -4571,6 +4573,7 @@ foreach(_hdr include/grpcpp/impl/server_builder_option.h include/grpcpp/impl/server_builder_plugin.h include/grpcpp/impl/server_initializer.h + include/grpcpp/impl/server_initializer_impl.h include/grpcpp/impl/service_type.h include/grpcpp/resource_quota.h include/grpcpp/security/auth_context.h diff --git a/Makefile b/Makefile index c0b277f0fb1..69d4e0e2db5 100644 --- a/Makefile +++ b/Makefile @@ -5344,6 +5344,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/server_builder_option.h \ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ + include/grpcpp/impl/server_initializer_impl.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ include/grpcpp/security/auth_context.h \ @@ -5943,6 +5944,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/server_builder_option.h \ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ + include/grpcpp/impl/server_initializer_impl.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ include/grpcpp/security/auth_context.h \ @@ -6855,6 +6857,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/server_builder_option.h \ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ + include/grpcpp/impl/server_initializer_impl.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ include/grpcpp/security/auth_context.h \ diff --git a/build.yaml b/build.yaml index c1271be9131..342a70cafaf 100644 --- a/build.yaml +++ b/build.yaml @@ -1362,6 +1362,7 @@ filegroups: - include/grpcpp/impl/server_builder_option.h - include/grpcpp/impl/server_builder_plugin.h - include/grpcpp/impl/server_initializer.h + - include/grpcpp/impl/server_initializer_impl.h - include/grpcpp/impl/service_type.h - include/grpcpp/resource_quota.h - include/grpcpp/security/auth_context.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 7afd9ef1a84..b33280c46d1 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -103,6 +103,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/server_builder_option.h', 'include/grpcpp/impl/server_builder_plugin.h', 'include/grpcpp/impl/server_initializer.h', + 'include/grpcpp/impl/server_initializer_impl.h', 'include/grpcpp/impl/service_type.h', 'include/grpcpp/resource_quota.h', 'include/grpcpp/security/auth_context.h', diff --git a/include/grpcpp/ext/proto_server_reflection_plugin.h b/include/grpcpp/ext/proto_server_reflection_plugin.h index 1cfdc1b6ccf..584e44190a0 100644 --- a/include/grpcpp/ext/proto_server_reflection_plugin.h +++ b/include/grpcpp/ext/proto_server_reflection_plugin.h @@ -22,8 +22,11 @@ #include #include -namespace grpc { +namespace grpc_impl { + class ServerInitializer; +} +namespace grpc { class ProtoServerReflection; } // namespace grpc @@ -34,8 +37,8 @@ class ProtoServerReflectionPlugin : public ::grpc::ServerBuilderPlugin { public: ProtoServerReflectionPlugin(); ::grpc::string name() override; - void InitServer(::grpc::ServerInitializer* si) override; - void Finish(::grpc::ServerInitializer* si) override; + void InitServer(::grpc_impl::ServerInitializer* si) override; + void Finish(::grpc_impl::ServerInitializer* si) override; void ChangeArguments(const ::grpc::string& name, void* value) override; bool has_async_methods() const override; bool has_sync_methods() const override; diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h index 39450b42d56..adde29da7d1 100644 --- a/include/grpcpp/impl/server_builder_plugin.h +++ b/include/grpcpp/impl/server_builder_plugin.h @@ -23,10 +23,13 @@ #include +namespace grpc_impl { + +class ServerInitializer; +} namespace grpc { class ServerBuilder; -class ServerInitializer; class ChannelArguments; /// This interface is meant for internal usage only. Implementations of this @@ -44,10 +47,10 @@ class ServerBuilderPlugin { /// InitServer will be called in ServerBuilder::BuildAndStart(), after the /// Server instance is created. - virtual void InitServer(ServerInitializer* si) = 0; + virtual void InitServer(grpc_impl::ServerInitializer* si) = 0; /// Finish will be called at the end of ServerBuilder::BuildAndStart(). - virtual void Finish(ServerInitializer* si) = 0; + virtual void Finish(grpc_impl::ServerInitializer* si) = 0; /// ChangeArguments is an interface that can be used in /// ServerBuilderOption::UpdatePlugins diff --git a/include/grpcpp/impl/server_initializer.h b/include/grpcpp/impl/server_initializer.h index f949fabfe6f..d40bb98feb6 100644 --- a/include/grpcpp/impl/server_initializer.h +++ b/include/grpcpp/impl/server_initializer.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,36 +19,11 @@ #ifndef GRPCPP_IMPL_SERVER_INITIALIZER_H #define GRPCPP_IMPL_SERVER_INITIALIZER_H -#include -#include - -#include +#include namespace grpc { -class Server; -class Service; - -class ServerInitializer { - public: - ServerInitializer(Server* server) : server_(server) {} - - bool RegisterService(std::shared_ptr service) { - if (!server_->RegisterService(nullptr, service.get())) { - return false; - } - default_services_.push_back(service); - return true; - } - - const std::vector* GetServiceList() { - return &server_->services_; - } - - private: - Server* server_; - std::vector > default_services_; -}; +typedef ::grpc_impl::ServerInitializer ServerInitializer; } // namespace grpc diff --git a/include/grpcpp/impl/server_initializer_impl.h b/include/grpcpp/impl/server_initializer_impl.h new file mode 100644 index 00000000000..ff610efa2ac --- /dev/null +++ b/include/grpcpp/impl/server_initializer_impl.h @@ -0,0 +1,57 @@ +/* + * + * 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_IMPL_SERVER_INITIALIZER_IMPL_H +#define GRPCPP_IMPL_SERVER_INITIALIZER_IMPL_H + +#include +#include + +#include + +namespace grpc { + +class Server; +class Service; +} // namespace grpc +namespace grpc_impl { + +class ServerInitializer { + public: + ServerInitializer(grpc::Server* server) : server_(server) {} + + bool RegisterService(std::shared_ptr service) { + if (!server_->RegisterService(nullptr, service.get())) { + return false; + } + default_services_.push_back(service); + return true; + } + + const std::vector* GetServiceList() { + return &server_->services_; + } + + private: + grpc::Server* server_; + std::vector > default_services_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_IMPL_SERVER_INITIALIZER_IMPL_H diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index f5c99f22df2..6ff392787af 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -40,12 +40,15 @@ struct grpc_server; +namespace grpc_impl { + +class ServerInitializer; +} namespace grpc { class AsyncGenericService; class HealthCheckServiceInterface; class ServerContext; -class ServerInitializer; /// Represents a gRPC server. /// @@ -199,7 +202,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { friend class AsyncGenericService; friend class ServerBuilder; - friend class ServerInitializer; + friend class grpc_impl::ServerInitializer; class SyncRequest; class CallbackRequestBase; @@ -257,7 +260,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { CompletionQueue* CallbackCQ() override; - ServerInitializer* initializer(); + grpc_impl::ServerInitializer* initializer(); // A vector of interceptor factory objects. // This should be destroyed after health_check_service_ and this requirement @@ -321,7 +324,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { // Pointer to the wrapped grpc_server. grpc_server* server_; - std::unique_ptr server_initializer_; + std::unique_ptr server_initializer_; std::unique_ptr health_check_service_; bool health_check_service_disabled_; diff --git a/src/cpp/server/load_reporter/load_reporting_service_server_builder_plugin.h b/src/cpp/server/load_reporter/load_reporting_service_server_builder_plugin.h index 1f098591d4d..c80802b2638 100644 --- a/src/cpp/server/load_reporter/load_reporting_service_server_builder_plugin.h +++ b/src/cpp/server/load_reporter/load_reporting_service_server_builder_plugin.h @@ -36,13 +36,13 @@ class LoadReportingServiceServerBuilderPlugin : public ServerBuilderPlugin { grpc::string name() override { return "load_reporting_service"; } // Creates a load reporting service. - void UpdateServerBuilder(grpc::ServerBuilder* builder) override; + void UpdateServerBuilder(ServerBuilder* builder) override; // Registers the load reporter service. - void InitServer(grpc::ServerInitializer* si) override; + void InitServer(grpc_impl::ServerInitializer* si) override; // Starts the load reporter service. - void Finish(grpc::ServerInitializer* si) override; + void Finish(grpc_impl::ServerInitializer* si) override; void ChangeArguments(const grpc::string& name, void* value) override {} void UpdateChannelArguments(grpc::ChannelArguments* args) override {} diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index cd0e516d9a3..46a8b11c425 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -309,7 +309,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { sync_server_settings_.cq_timeout_msec, resource_quota_, std::move(interceptor_creators_))); - ServerInitializer* initializer = server->initializer(); + grpc_impl::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 diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 26e84f1aed4..aa9fdac9bea 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -766,7 +766,7 @@ Server::Server( shutdown_(false), shutdown_notified_(false), server_(nullptr), - server_initializer_(new ServerInitializer(this)), + server_initializer_(new grpc_impl::ServerInitializer(this)), health_check_service_disabled_(false) { g_gli_initializer.summon(); gpr_once_init(&g_once_init_callbacks, InitGlobalCallbacks); From 76860add9bb53f24ba308de54983177930791c4b Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 14:50:07 -0700 Subject: [PATCH 1637/2143] Fix error from presubmit test scripts. --- 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..45b86e27f52 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -993,6 +993,7 @@ 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/server_initializer_impl.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ include/grpcpp/security/auth_context.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 1e17ab8f88b..9fea1377b05 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -995,6 +995,7 @@ 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/server_initializer_impl.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ include/grpcpp/security/auth_context.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index cd88082f884..4112d7bc2e2 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10082,6 +10082,7 @@ "include/grpcpp/impl/server_builder_option.h", "include/grpcpp/impl/server_builder_plugin.h", "include/grpcpp/impl/server_initializer.h", + "include/grpcpp/impl/server_initializer_impl.h", "include/grpcpp/impl/service_type.h", "include/grpcpp/resource_quota.h", "include/grpcpp/security/auth_context.h", @@ -10191,6 +10192,7 @@ "include/grpcpp/impl/server_builder_option.h", "include/grpcpp/impl/server_builder_plugin.h", "include/grpcpp/impl/server_initializer.h", + "include/grpcpp/impl/server_initializer_impl.h", "include/grpcpp/impl/service_type.h", "include/grpcpp/resource_quota.h", "include/grpcpp/security/auth_context.h", From 12cd0dbd1d2554b3822645db1002eb6d4c4d18a7 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 27 Mar 2019 12:29:08 -0700 Subject: [PATCH 1638/2143] Fix BUILD.gn file --- BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.gn b/BUILD.gn index d15961a4879..fee71e5b093 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1068,6 +1068,7 @@ config("grpc_config") { "include/grpcpp/impl/server_builder_option.h", "include/grpcpp/impl/server_builder_plugin.h", "include/grpcpp/impl/server_initializer.h", + "include/grpcpp/impl/server_initializer_impl.h", "include/grpcpp/impl/service_type.h", "include/grpcpp/resource_quota.h", "include/grpcpp/security/auth_context.h", From da1ea4d77ef14a7bd5a20079837b67a0e9926ba3 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 27 Mar 2019 12:33:44 -0700 Subject: [PATCH 1639/2143] Fix BUILD.gn files --- BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.gn b/BUILD.gn index d15961a4879..a8dd50111e6 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1004,6 +1004,7 @@ config("grpc_config") { "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", + "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", "include/grpcpp/ext/health_check_service_server_builder_option.h", "include/grpcpp/generic/async_generic_service.h", From da78fdc0510cd4c4acfa85c7b5bd3222e75a502f Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 27 Mar 2019 12:35:41 -0700 Subject: [PATCH 1640/2143] Fix BUILD.gn files --- BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.gn b/BUILD.gn index d15961a4879..1fcb8f357f3 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1005,6 +1005,7 @@ config("grpc_config") { "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", "include/grpcpp/create_channel_posix.h", + "include/grpcpp/create_channel_posix_impl.h", "include/grpcpp/ext/health_check_service_server_builder_option.h", "include/grpcpp/generic/async_generic_service.h", "include/grpcpp/generic/generic_stub.h", From 8d22a7b7752d6d818ff0d8b5501b5aa83a224fed Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 27 Mar 2019 12:39:10 -0700 Subject: [PATCH 1641/2143] Fix BUILD.gn file --- BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.gn b/BUILD.gn index d15961a4879..b3a1fda8723 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1010,6 +1010,7 @@ config("grpc_config") { "include/grpcpp/generic/generic_stub.h", "include/grpcpp/grpcpp.h", "include/grpcpp/health_check_service_interface.h", + "include/grpcpp/health_check_service_interface_impl.h", "include/grpcpp/impl/call.h", "include/grpcpp/impl/channel_argument_option.h", "include/grpcpp/impl/client_unary_call.h", From 47c26836b8ea4dafbd27a2f0f711b8c1a8e14bf8 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 27 Mar 2019 12:51:31 -0700 Subject: [PATCH 1642/2143] Fix BUILD.gn --- BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.gn b/BUILD.gn index d15961a4879..05c2a735407 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1076,6 +1076,7 @@ config("grpc_config") { "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 326e06256bef4e618fa2f1c25657606c8a13d2bc Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 21 Mar 2019 11:00:38 -0400 Subject: [PATCH 1643/2143] C# distribtests should test Grpc.Tools codegen too --- .../DistribTest/DistribTestDotNet.csproj | 5 ++++ .../csharp/DistribTest/testcodegen.proto | 29 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 test/distrib/csharp/DistribTest/testcodegen.proto diff --git a/test/distrib/csharp/DistribTest/DistribTestDotNet.csproj b/test/distrib/csharp/DistribTest/DistribTestDotNet.csproj index f16a0f99591..d19eac91ba4 100644 --- a/test/distrib/csharp/DistribTest/DistribTestDotNet.csproj +++ b/test/distrib/csharp/DistribTest/DistribTestDotNet.csproj @@ -16,8 +16,13 @@ + + + + + /usr/lib/mono/4.5-api diff --git a/test/distrib/csharp/DistribTest/testcodegen.proto b/test/distrib/csharp/DistribTest/testcodegen.proto new file mode 100644 index 00000000000..7845ac92c49 --- /dev/null +++ b/test/distrib/csharp/DistribTest/testcodegen.proto @@ -0,0 +1,29 @@ +// 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. + +syntax = "proto3"; + +package testcodegen; + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +message HelloRequest { + string name = 1; +} + +message HelloReply { + string message = 1; +} From 89281d44989133a2b36bc2c5457d138a41036bfe Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 21 Mar 2019 11:23:44 -0400 Subject: [PATCH 1644/2143] test protobuf used --- test/distrib/csharp/DistribTest/Program.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/distrib/csharp/DistribTest/Program.cs b/test/distrib/csharp/DistribTest/Program.cs index 376add6b7b5..0ea7211fc45 100644 --- a/test/distrib/csharp/DistribTest/Program.cs +++ b/test/distrib/csharp/DistribTest/Program.cs @@ -25,6 +25,9 @@ namespace TestGrpcPackage { public static void Main(string[] args) { + // test codegen works + var reply = new Testcodegen.HelloReply(); + // This code doesn't do much but makes sure the native extension is loaded // which is what we are testing here. Channel c = new Channel("127.0.0.1:1000", ChannelCredentials.Insecure); From 133ff03e97c9d1389b321e25bef587ded6689de8 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 21 Mar 2019 11:24:21 -0400 Subject: [PATCH 1645/2143] classic .csproj Grpc.Tools test --- test/distrib/csharp/DistribTest/DistribTest.csproj | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/distrib/csharp/DistribTest/DistribTest.csproj b/test/distrib/csharp/DistribTest/DistribTest.csproj index d18bb05be68..20d103a41b3 100644 --- a/test/distrib/csharp/DistribTest/DistribTest.csproj +++ b/test/distrib/csharp/DistribTest/DistribTest.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -98,16 +99,22 @@ + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + - 1.20.0-dev + 1.21.0-dev 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 7d403d1338a..8c7718f727f 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.20.0-dev +set VERSION=1.21.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 a318af8f540..af876287038 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.20.0-dev' + v = '1.21.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 4d4431ee365..fcbdfb21539 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.20.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.21.0-dev" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index b3c4788f496..87516de11e8 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.20.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.21.0-dev" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index e8106db7288..a9d0aebffca 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.20.0", + "version": "1.21.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 fac3e85d849..43b3fa629ff 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.20.0dev" +#define PHP_GRPC_VERSION "1.21.0dev" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 069dbf1a1c5..651f8f778f2 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.20.0.dev0""" +__version__ = """1.21.0.dev0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 9e7af710f49..e430cc20a6d 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.20.0.dev0' +VERSION = '1.21.0.dev0' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 9a33dc35b26..d716b953f4b 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.20.0.dev0' +VERSION = '1.21.0.dev0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index eeacbe23bfd..2bb47aaf133 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.20.0.dev0' +VERSION = '1.21.0.dev0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index c76cbbd7a95..e1c4f3df694 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.20.0.dev0' +VERSION = '1.21.0.dev0' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 40d823ed0cd..b484a7ba478 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.20.0.dev0' +VERSION = '1.21.0.dev0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index df40ba743a6..21981ee79d2 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.20.0.dev0' +VERSION = '1.21.0.dev0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index b2db0d0949d..8ce4fdb627d 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.20.0.dev0' +VERSION = '1.21.0.dev0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 0e20b361b7d..cca795b64ec 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.20.0.dev' + VERSION = '1.21.0.dev' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 79201ad1e6e..5604e215b58 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.20.0.dev' + VERSION = '1.21.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 950b2e2d111..22d04c5a1af 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.20.0.dev0' +VERSION = '1.21.0.dev0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 3774d75d16a..c10b71568bc 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.20.0-dev +PROJECT_NUMBER = 1.21.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 7bfee1d1465..8acf3db3a34 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.20.0-dev +PROJECT_NUMBER = 1.21.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 From f0a4fedd6a916d274e85e763d70551aea47cd1f1 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 29 Mar 2019 16:58:37 -0700 Subject: [PATCH 1703/2143] Bump version to v1.20.0-pre1 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index 7d71b9df9eb..d962cd51c41 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "godric" core_version = "7.0.0" -version = "1.20.0-dev" +version = "1.20.0-pre1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 1b0685c509a..e1d425a987e 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: godric - version: 1.20.0-dev + version: 1.20.0-pre1 filegroups: - name: alts_proto headers: From 1d7e99142f3a9200c303aa572381e9f1b53ca54b Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 29 Mar 2019 16:58:59 -0700 Subject: [PATCH 1704/2143] 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 | 4 ++-- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 2 +- src/csharp/build/dependencies.props | 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, 33 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3780b5cfa2..8835079a2a7 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.20.0-dev") +set(PACKAGE_VERSION "1.20.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 18807ad832a..ad9e358f853 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.20.0-dev -CSHARP_VERSION = 1.20.0-dev +CPP_VERSION = 1.20.0-pre1 +CSHARP_VERSION = 1.20.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 dddfdce5f04..20981703b44 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.20.0-dev' - version = '0.0.8-dev' + # version = '1.20.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.20.0-dev' + grpc_version = '1.20.0-pre1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 8e544b0641c..e55559a0ae5 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.20.0-dev' + version = '1.20.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 3de74e49033..6dc05f8a9ae 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.20.0-dev' + version = '1.20.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 6121f67ae29..6626875be3c 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.20.0-dev' + version = '1.20.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 c19419f1857..80fa0aff7dc 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.20.0-dev' + version = '1.20.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 ccdd70bdca3..1d9d8a67cf6 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.20.0dev - 1.20.0dev + 1.20.0RC1 + 1.20.0RC1 beta diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 930ec534fd4..6743b7737ca 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.20.0-dev"; } +grpc::string Version() { return "1.20.0-pre1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index 10efb17a678..b68d6152ac8 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.20.0-dev"; + public const string CurrentVersion = "1.20.0-pre1"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index f3d484643d7..1a66732bbc1 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.20.0-dev + 1.20.0-pre1 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 7d403d1338a..7c472622276 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.20.0-dev +set VERSION=1.20.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 a318af8f540..dd83dce22d9 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.20.0-dev' + v = '1.20.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 4d4431ee365..210ffb14fa3 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.20.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.20.0-pre1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index b3c4788f496..8d37cb5fece 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.20.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.20.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 fac3e85d849..af9d01a05c8 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.20.0dev" +#define PHP_GRPC_VERSION "1.20.0RC1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 069dbf1a1c5..5071e4c6b6b 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.20.0.dev0""" +__version__ = """1.20.0rc1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 9e7af710f49..fdf42b43957 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.20.0.dev0' +VERSION = '1.20.0rc1' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 9a33dc35b26..1ace56a18e7 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.20.0.dev0' +VERSION = '1.20.0rc1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index eeacbe23bfd..a0f6455e115 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.20.0.dev0' +VERSION = '1.20.0rc1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index c76cbbd7a95..59286fb8a61 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.20.0.dev0' +VERSION = '1.20.0rc1' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 40d823ed0cd..634c8fa88af 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.20.0.dev0' +VERSION = '1.20.0rc1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index df40ba743a6..d6665498e47 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.20.0.dev0' +VERSION = '1.20.0rc1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index b2db0d0949d..13d6b4a46de 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.20.0.dev0' +VERSION = '1.20.0rc1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 0e20b361b7d..295e3b3e6ec 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.20.0.dev' + VERSION = '1.20.0.pre1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 79201ad1e6e..450d608d85b 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.20.0.dev' + VERSION = '1.20.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 950b2e2d111..9117a636955 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.20.0.dev0' +VERSION = '1.20.0rc1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 3774d75d16a..16ce053e942 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.20.0-dev +PROJECT_NUMBER = 1.20.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 7bfee1d1465..e60c82cd823 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.20.0-dev +PROJECT_NUMBER = 1.20.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 b2c773d26f6126517526919a31093d919302e688 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 29 Mar 2019 17:06:09 -0700 Subject: [PATCH 1705/2143] Global Registry for Service Config Parsers --- .../filters/client_channel/service_config.cc | 2 ++ .../filters/client_channel/service_config.h | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index bbf671d979e..e2d23010c8a 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -33,6 +33,8 @@ namespace grpc_core { +int ServiceConfig::registered_parsers_count = 0; + RefCountedPtr ServiceConfig::Create(const char* json) { UniquePtr service_config_json(gpr_strdup(json)); UniquePtr json_string(gpr_strdup(json)); diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index d9063479e32..b211d732d3f 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -54,6 +54,15 @@ namespace grpc_core { +/// This is the base class that all service config parsers MUST use to store +/// parsed service config data. +class ServiceConfigParsedObject { + public: + virtual ~ServiceConfigParsedObject() = default; + + GRPC_ABSTRACT_BASE_CLASS; +}; + class ServiceConfig : public RefCounted { public: /// Creates a new service config from parsing \a json_string. @@ -96,6 +105,26 @@ class ServiceConfig : public RefCounted { static RefCountedPtr MethodConfigTableLookup( const SliceHashTable>& table, const grpc_slice& path); + /// Retrieves the parsed object at index \a index. + ServiceConfigParsedObject* GetParsedServiceConfigObject(int index) { + GPR_DEBUG_ASSERT(index < registered_parsers_count); + return parsed_service_config_objects[index].get(); + } + + typedef UniquePtr (*ServiceConfigParser)( + const char* service_config_json); + + /// Globally register a service config parser. On successful registration, it + /// returns the index at which the parser was registered. On failure, -1 is + /// returned. Each new service config update will go through all the + /// registered parser. Each parser is responsible for reading the service + /// config json and returning a parsed object. This parsed object can later be + /// retrieved using the same index that was returned at registration time. + static int RegisterParser(ServiceConfigParser func) { + registered_parsers[registered_parsers_count] = func; + return registered_parsers_count++; + } + private: // So New() can call our private ctor. template @@ -120,9 +149,16 @@ class ServiceConfig : public RefCounted { grpc_json* json, CreateValue create_value, typename SliceHashTable>::Entry* entries, size_t* idx); + static constexpr int kMaxParsers = 32; + static int registered_parsers_count; + static ServiceConfigParser registered_parsers[kMaxParsers]; + UniquePtr service_config_json_; UniquePtr json_string_; // Underlying storage for json_tree. grpc_json* json_tree_; + + InlinedVector, kMaxParsers> + parsed_service_config_objects; }; // From 47132c099e42c4947cc045cb847b46cf1c994afa Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 29 Mar 2019 17:20:38 -0700 Subject: [PATCH 1706/2143] error handling for start_bdp_ping --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index df9e273c71f..07e01733f66 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -2598,6 +2598,9 @@ static void start_bdp_ping_locked(void* tp, grpc_error* error) { gpr_log(GPR_INFO, "%s: Start BDP ping err=%s", t->peer_string, grpc_error_string(error)); } + if (error != GRPC_ERROR_NONE || t->closed_with_error != GRPC_ERROR_NONE) { + return; + } /* Reset the keepalive ping timer */ if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING) { grpc_timer_cancel(&t->keepalive_ping_timer); From da3a2320a2912d0f91fb23938c59f5036ea639b3 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 26 Mar 2019 17:10:41 -0400 Subject: [PATCH 1707/2143] Ref transport and stream before init of chttp2_stream structure. The stream structure is really big and by the time we get to ref the stream and the transport, the fields are out of cache. We need to ref them immediately, before starting to initialize the stream. This commit introduces a 0-byte Reffer so that we can ref the streams on time before the field initializers. --- .../chttp2/transport/chttp2_transport.cc | 19 ++++++++++++------- .../ext/transport/chttp2/transport/internal.h | 6 ++++++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 404539c9e13..cb6596f9d1f 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -645,17 +645,22 @@ void grpc_chttp2_stream_unref(grpc_chttp2_stream* s) { } #endif +grpc_chttp2_stream::Reffer::Reffer(grpc_chttp2_stream* s) { + /* We reserve one 'active stream' that's dropped when the stream is + read-closed. The others are for Chttp2IncomingByteStreams that are + actively reading */ + GRPC_CHTTP2_STREAM_REF(s, "chttp2"); + GRPC_CHTTP2_REF_TRANSPORT(s->t, "stream"); +} + grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t, grpc_stream_refcount* refcount, const void* server_data, gpr_arena* arena) - : t(t), refcount(refcount), metadata_buffer{{arena}, {arena}} { - /* We reserve one 'active stream' that's dropped when the stream is - read-closed. The others are for Chttp2IncomingByteStreams that are - actively reading */ - GRPC_CHTTP2_STREAM_REF(this, "chttp2"); - GRPC_CHTTP2_REF_TRANSPORT(t, "stream"); - + : t(t), + refcount(refcount), + reffer(this), + metadata_buffer{{arena}, {arena}} { if (server_data) { id = static_cast((uintptr_t)server_data); *t->accepting_stream = this; diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 760324c0c95..e4fd5928f2c 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -510,6 +510,12 @@ struct grpc_chttp2_stream { void* context; grpc_chttp2_transport* t; grpc_stream_refcount* refcount; + // Reffer is a 0-len structure, simply reffing `t` and `refcount` in its ctor + // before initializing the rest of the stream, to avoid cache misses. This + // field MUST be right after `t` and `refcount`. + struct Reffer { + explicit Reffer(grpc_chttp2_stream* s); + } reffer; grpc_closure destroy_stream; grpc_closure* destroy_stream_arg; From c239e0416d54c0a19b55a056fa1c92bbd400cac7 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Sun, 31 Mar 2019 20:18:13 -0400 Subject: [PATCH 1708/2143] Initialize time as part of basic initialization. `gpr_time_init` must happen in `do_basic_init`, because for normal initialization we may need the precise clock (e.g., if profilers are enabled). Otherwise, we will have an stack overflow. Fixes #18589 --- src/core/lib/surface/init.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index fdb584da68f..b67d4f12252 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -73,6 +73,7 @@ static void do_basic_init(void) { g_shutting_down = false; grpc_register_built_in_plugins(); grpc_cq_global_init(); + gpr_time_init(); g_initializations = 0; } @@ -132,7 +133,6 @@ void grpc_init(void) { } grpc_core::Fork::GlobalInit(); grpc_fork_handlers_auto_register(); - gpr_time_init(); gpr_arena_init(); grpc_stats_init(); grpc_slice_intern_init(); From f1199912e85e8cb7cc03c3b2c1751797cd474316 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sat, 30 Mar 2019 22:30:18 -0700 Subject: [PATCH 1709/2143] fix typo in log message --- src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs b/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs index d5146e816e2..0777d7933e6 100644 --- a/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs +++ b/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs @@ -63,7 +63,7 @@ namespace Grpc.Core.Internal 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."); + Logger.Error(e, "Caught exception inside callback from native code."); return 0; } } From c835fedd4d42d7799a9a0c89b284db9c9a66a886 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 21 Mar 2019 12:07:08 -0700 Subject: [PATCH 1710/2143] Modify verifyPeerCallback logic to use NativeCallbackDispatcher --- src/csharp/Grpc.Core/ChannelCredentials.cs | 63 ++++++++----- .../Internal/ChannelCredentialsSafeHandle.cs | 12 +-- .../Internal/NativeMethods.Generated.cs | 6 +- .../SslCredentialsTest.cs | 92 ++++++++++--------- src/csharp/ext/grpc_csharp_ext.c | 53 +++++------ .../Grpc.Core/Internal/native_methods.include | 2 +- 6 files changed, 122 insertions(+), 106 deletions(-) diff --git a/src/csharp/Grpc.Core/ChannelCredentials.cs b/src/csharp/Grpc.Core/ChannelCredentials.cs index 103a594bb06..2ecd3875e84 100644 --- a/src/csharp/Grpc.Core/ChannelCredentials.cs +++ b/src/csharp/Grpc.Core/ChannelCredentials.cs @@ -127,8 +127,6 @@ namespace Grpc.Core readonly string rootCertificates; readonly KeyCertificatePair keyCertificatePair; readonly VerifyPeerCallback verifyPeerCallback; - readonly VerifyPeerCallbackInternal verifyPeerCallbackInternal; - readonly GCHandle gcHandle; /// /// Creates client-side SSL credentials loaded from @@ -168,12 +166,7 @@ namespace Grpc.Core { this.rootCertificates = rootCertificates; this.keyCertificatePair = keyCertificatePair; - if (verifyPeerCallback != null) - { - this.verifyPeerCallback = verifyPeerCallback; - this.verifyPeerCallbackInternal = this.VerifyPeerCallbackHandler; - gcHandle = GCHandle.Alloc(verifyPeerCallbackInternal); - } + this.verifyPeerCallback = verifyPeerCallback; } /// @@ -207,29 +200,53 @@ namespace Grpc.Core internal override ChannelCredentialsSafeHandle CreateNativeCredentials() { - return ChannelCredentialsSafeHandle.CreateSslCredentials(rootCertificates, keyCertificatePair, this.verifyPeerCallbackInternal); + IntPtr verifyPeerCallbackTag = IntPtr.Zero; + if (verifyPeerCallback != null) + { + verifyPeerCallbackTag = new VerifyPeerCallbackRegistration(verifyPeerCallback).CallbackRegistration.Tag; + } + return ChannelCredentialsSafeHandle.CreateSslCredentials(rootCertificates, keyCertificatePair, verifyPeerCallbackTag); } - private int VerifyPeerCallbackHandler(IntPtr host, IntPtr pem, IntPtr userData, bool isDestroy) + private class VerifyPeerCallbackRegistration { - if (isDestroy) + readonly VerifyPeerCallback verifyPeerCallback; + readonly NativeCallbackRegistration callbackRegistration; + + public VerifyPeerCallbackRegistration(VerifyPeerCallback verifyPeerCallback) { - this.gcHandle.Free(); - return 0; + this.verifyPeerCallback = verifyPeerCallback; + this.callbackRegistration = NativeCallbackDispatcher.RegisterCallback(HandleUniversalCallback); } - try - { - var context = new VerifyPeerContext(Marshal.PtrToStringAnsi(host), Marshal.PtrToStringAnsi(pem)); + public NativeCallbackRegistration CallbackRegistration => callbackRegistration; - return this.verifyPeerCallback(context) ? 0 : 1; - } - catch (Exception e) + private int HandleUniversalCallback(IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5) { - // eat the exception, we must not throw when inside callback from native code. - Logger.Error(e, "Exception occurred while invoking verify peer callback handler."); - // Return validation failure in case of exception. - return 1; + return VerifyPeerCallbackHandler(arg0, arg1, arg2 != IntPtr.Zero); + } + + private int VerifyPeerCallbackHandler(IntPtr host, IntPtr pem, bool isDestroy) + { + if (isDestroy) + { + this.callbackRegistration.Dispose(); + return 0; + } + + try + { + var context = new VerifyPeerContext(Marshal.PtrToStringAnsi(host), Marshal.PtrToStringAnsi(pem)); + + return this.verifyPeerCallback(context) ? 0 : 1; + } + catch (Exception e) + { + // eat the exception, we must not throw when inside callback from native code. + Logger.Error(e, "Exception occurred while invoking verify peer callback handler."); + // Return validation failure in case of exception. + return 1; + } } } } diff --git a/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs index 5e336673153..d4f50344b23 100644 --- a/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs @@ -20,12 +20,6 @@ using System.Threading.Tasks; namespace Grpc.Core.Internal { - internal delegate int VerifyPeerCallbackInternal( - IntPtr targetHost, - IntPtr targetPem, - IntPtr userData, - bool isDestroy); - /// /// grpc_channel_credentials from grpc/grpc_security.h /// @@ -44,15 +38,15 @@ namespace Grpc.Core.Internal return creds; } - public static ChannelCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, KeyCertificatePair keyCertPair, VerifyPeerCallbackInternal verifyPeerCallback) + public static ChannelCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, KeyCertificatePair keyCertPair, IntPtr verifyPeerCallbackTag) { if (keyCertPair != null) { - return Native.grpcsharp_ssl_credentials_create(pemRootCerts, keyCertPair.CertificateChain, keyCertPair.PrivateKey, verifyPeerCallback); + return Native.grpcsharp_ssl_credentials_create(pemRootCerts, keyCertPair.CertificateChain, keyCertPair.PrivateKey, verifyPeerCallbackTag); } else { - return Native.grpcsharp_ssl_credentials_create(pemRootCerts, null, null, verifyPeerCallback); + return Native.grpcsharp_ssl_credentials_create(pemRootCerts, null, null, verifyPeerCallbackTag); } } diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs index e09b9813f79..a1387aff562 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs @@ -482,7 +482,7 @@ namespace Grpc.Core.Internal public delegate void grpcsharp_channel_args_set_integer_delegate(ChannelArgsSafeHandle args, UIntPtr index, string key, int value); public delegate void grpcsharp_channel_args_destroy_delegate(IntPtr args); public delegate void grpcsharp_override_default_ssl_roots_delegate(string pemRootCerts); - public delegate ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create_delegate(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, VerifyPeerCallbackInternal verifyPeerCallback); + public delegate ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create_delegate(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, IntPtr verifyPeerCallbackTag); public delegate ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create_delegate(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds); public delegate void grpcsharp_channel_credentials_release_delegate(IntPtr credentials); public delegate ChannelSafeHandle grpcsharp_insecure_channel_create_delegate(string target, ChannelArgsSafeHandle channelArgs); @@ -676,7 +676,7 @@ namespace Grpc.Core.Internal public static extern void grpcsharp_override_default_ssl_roots(string pemRootCerts); [DllImport(ImportName)] - public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, VerifyPeerCallbackInternal verifyPeerCallback); + public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, IntPtr verifyPeerCallbackTag); [DllImport(ImportName)] public static extern ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds); @@ -972,7 +972,7 @@ namespace Grpc.Core.Internal public static extern void grpcsharp_override_default_ssl_roots(string pemRootCerts); [DllImport(ImportName)] - public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, VerifyPeerCallbackInternal verifyPeerCallback); + public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, IntPtr verifyPeerCallbackTag); [DllImport(ImportName)] public static extern ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds); diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs index 818ac6d1adc..4c1189320fa 100644 --- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs @@ -44,23 +44,18 @@ namespace Grpc.IntegrationTesting string rootCert; KeyCertificatePair keyCertPair; - string certChain; - List options; - bool isHostEqual; - bool isPemEqual; public void InitClientAndServer(bool clientAddKeyCertPair, - SslClientCertificateRequestType clientCertRequestType) + SslClientCertificateRequestType clientCertRequestType, + VerifyPeerCallback verifyPeerCallback = null) { rootCert = File.ReadAllText(TestCredentials.ClientCertAuthorityPath); - certChain = File.ReadAllText(TestCredentials.ServerCertChainPath); - certChain = certChain.Replace("\r", string.Empty); keyCertPair = new KeyCertificatePair( - certChain, + File.ReadAllText(TestCredentials.ServerCertChainPath), File.ReadAllText(TestCredentials.ServerPrivateKeyPath)); var serverCredentials = new SslServerCredentials(new[] { keyCertPair }, rootCert, clientCertRequestType); - var clientCredentials = clientAddKeyCertPair ? new SslCredentials(rootCert, keyCertPair, context => this.VerifyPeerCallback(context, true)) : new SslCredentials(rootCert); + var clientCredentials = new SslCredentials(rootCert, clientAddKeyCertPair ? keyCertPair : null, verifyPeerCallback); // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) @@ -70,7 +65,7 @@ namespace Grpc.IntegrationTesting }; server.Start(); - options = new List + var options = new List { new ChannelOption(ChannelOptions.SslTargetNameOverride, TestCredentials.DefaultHostOverride) }; @@ -194,6 +189,52 @@ namespace Grpc.IntegrationTesting Assert.Throws(typeof(ArgumentNullException), () => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndRequireAndVerify)); } + [Test] + public async Task VerifyPeerCallback_Accepted() + { + string targetNameFromCallback = null; + string peerPemFromCallback = null; + InitClientAndServer( + clientAddKeyCertPair: false, + clientCertRequestType: SslClientCertificateRequestType.DontRequest, + verifyPeerCallback: (ctx) => + { + targetNameFromCallback = ctx.TargetName; + peerPemFromCallback = ctx.PeerPem; + return true; + }); + await CheckAccepted(expectPeerAuthenticated: false); + Assert.AreEqual(TestCredentials.DefaultHostOverride, targetNameFromCallback); + var expectedServerPem = File.ReadAllText(TestCredentials.ServerCertChainPath).Replace("\r", ""); + Assert.AreEqual(expectedServerPem, peerPemFromCallback); + } + + [Test] + public void VerifyPeerCallback_CallbackThrows_Rejected() + { + InitClientAndServer( + clientAddKeyCertPair: false, + clientCertRequestType: SslClientCertificateRequestType.DontRequest, + verifyPeerCallback: (ctx) => + { + throw new Exception("VerifyPeerCallback has thrown on purpose."); + }); + CheckRejected(); + } + + [Test] + public void VerifyPeerCallback_Rejected() + { + InitClientAndServer( + clientAddKeyCertPair: false, + clientCertRequestType: SslClientCertificateRequestType.DontRequest, + verifyPeerCallback: (ctx) => + { + return false; + }); + CheckRejected(); + } + private async Task CheckAccepted(bool expectPeerAuthenticated) { var call = client.UnaryCallAsync(new SimpleRequest { ResponseSize = 10 }); @@ -216,37 +257,6 @@ namespace Grpc.IntegrationTesting Assert.AreEqual(12345, response.AggregatedPayloadSize); } - [Test] - public void VerifyPeerCallbackTest() - { - InitClientAndServer(true, SslClientCertificateRequestType.RequestAndRequireAndVerify); - - // Force GC collection to verify that the VerifyPeerCallback is not collected. If - // it gets collected, this test will hang. - GC.Collect(); - - client.UnaryCall(new SimpleRequest { ResponseSize = 10 }); - Assert.IsTrue(isHostEqual); - Assert.IsTrue(isPemEqual); - } - - [Test] - public void VerifyPeerCallbackFailTest() - { - InitClientAndServer(true, SslClientCertificateRequestType.RequestAndRequireAndVerify); - var clientCredentials = new SslCredentials(rootCert, keyCertPair, context => this.VerifyPeerCallback(context, false)); - var failingChannel = new Channel(Host, server.Ports.Single().BoundPort, clientCredentials, options); - var failingClient = new TestService.TestServiceClient(failingChannel); - Assert.Throws(() => failingClient.UnaryCall(new SimpleRequest { ResponseSize = 10 })); - } - - private bool VerifyPeerCallback(VerifyPeerContext context, bool returnValue) - { - isHostEqual = TestCredentials.DefaultHostOverride == context.TargetHost; - isPemEqual = certChain == context.TargetPem; - return returnValue; - } - private class SslCredentialsTestServiceImpl : TestService.TestServiceBase { public override Task UnaryCall(SimpleRequest request, ServerCallContext context) diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 5f80d3417a5..4323d40b6d3 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -901,6 +901,21 @@ grpcsharp_server_request_call(grpc_server* server, grpc_completion_queue* cq, &(ctx->request_metadata), cq, cq, ctx); } +/* 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); + +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; +} + /* Security */ static char* default_pem_root_certs = NULL; @@ -927,23 +942,18 @@ grpcsharp_override_default_ssl_roots(const char* pem_root_certs) { grpc_set_ssl_roots_override_callback(override_ssl_roots_handler); } -typedef int(GPR_CALLTYPE* grpcsharp_verify_peer_func)(const char* target_host, - const char* target_pem, - void* userdata, - int32_t isDestroy); - static void grpcsharp_verify_peer_destroy_handler(void* userdata) { - grpcsharp_verify_peer_func callback = - (grpcsharp_verify_peer_func)(intptr_t)userdata; - callback(NULL, NULL, NULL, 1); + native_callback_dispatcher(userdata, NULL, + NULL, (void*)1, NULL, + NULL, NULL); } static int grpcsharp_verify_peer_handler(const char* target_host, const char* target_pem, void* userdata) { - grpcsharp_verify_peer_func callback = - (grpcsharp_verify_peer_func)(intptr_t)userdata; - return callback(target_host, target_pem, NULL, 0); + return native_callback_dispatcher(userdata, (void*)target_host, + (void*)target_pem, (void*)0, NULL, + NULL, NULL); } @@ -951,13 +961,13 @@ GPR_EXPORT grpc_channel_credentials* GPR_CALLTYPE grpcsharp_ssl_credentials_create(const char* pem_root_certs, const char* key_cert_pair_cert_chain, const char* key_cert_pair_private_key, - grpcsharp_verify_peer_func verify_peer_func) { + void* verify_peer_callback_tag) { grpc_ssl_pem_key_cert_pair key_cert_pair; verify_peer_options verify_options; verify_peer_options* p_verify_options = NULL; - if (verify_peer_func != NULL) { + if (verify_peer_callback_tag != NULL) { verify_options.verify_peer_callback_userdata = - (void*)(intptr_t)verify_peer_func; + verify_peer_callback_tag; verify_options.verify_peer_destruct = grpcsharp_verify_peer_destroy_handler; verify_options.verify_peer_callback = grpcsharp_verify_peer_handler; @@ -1043,21 +1053,6 @@ grpcsharp_composite_call_credentials_create(grpc_call_credentials* creds1, return grpc_composite_call_credentials_create(creds1, creds2, NULL); } -/* 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); - -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( diff --git a/templates/src/csharp/Grpc.Core/Internal/native_methods.include b/templates/src/csharp/Grpc.Core/Internal/native_methods.include index 4cb71730529..e8ec4c87b06 100644 --- a/templates/src/csharp/Grpc.Core/Internal/native_methods.include +++ b/templates/src/csharp/Grpc.Core/Internal/native_methods.include @@ -44,7 +44,7 @@ native_method_signatures = [ '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, VerifyPeerCallbackInternal verifyPeerCallback)', + 'ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, IntPtr verifyPeerCallbackTag)', '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)', From 046cd3533b85425631bf3e3be43da8fb77e5d8b3 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sun, 31 Mar 2019 19:34:50 -0700 Subject: [PATCH 1711/2143] add license --- src/csharp/Grpc.Core/VerifyPeerContext.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/csharp/Grpc.Core/VerifyPeerContext.cs b/src/csharp/Grpc.Core/VerifyPeerContext.cs index b48984b093c..52a5fabf7c8 100644 --- a/src/csharp/Grpc.Core/VerifyPeerContext.cs +++ b/src/csharp/Grpc.Core/VerifyPeerContext.cs @@ -1,3 +1,21 @@ +#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 + namespace Grpc.Core { /// From d297ede96a5cb453e32d40ec22015e67e214942a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sun, 31 Mar 2019 19:47:11 -0700 Subject: [PATCH 1712/2143] honor C core's naming of verify_peer_callback arguments --- src/csharp/Grpc.Core/ChannelCredentials.cs | 4 ++-- src/csharp/Grpc.Core/VerifyPeerContext.cs | 18 +++++++++--------- src/csharp/ext/grpc_csharp_ext.c | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/csharp/Grpc.Core/ChannelCredentials.cs b/src/csharp/Grpc.Core/ChannelCredentials.cs index 2ecd3875e84..fbea40d0a4b 100644 --- a/src/csharp/Grpc.Core/ChannelCredentials.cs +++ b/src/csharp/Grpc.Core/ChannelCredentials.cs @@ -226,7 +226,7 @@ namespace Grpc.Core return VerifyPeerCallbackHandler(arg0, arg1, arg2 != IntPtr.Zero); } - private int VerifyPeerCallbackHandler(IntPtr host, IntPtr pem, bool isDestroy) + private int VerifyPeerCallbackHandler(IntPtr targetName, IntPtr peerPem, bool isDestroy) { if (isDestroy) { @@ -236,7 +236,7 @@ namespace Grpc.Core try { - var context = new VerifyPeerContext(Marshal.PtrToStringAnsi(host), Marshal.PtrToStringAnsi(pem)); + var context = new VerifyPeerContext(Marshal.PtrToStringAnsi(targetName), Marshal.PtrToStringAnsi(peerPem)); return this.verifyPeerCallback(context) ? 0 : 1; } diff --git a/src/csharp/Grpc.Core/VerifyPeerContext.cs b/src/csharp/Grpc.Core/VerifyPeerContext.cs index 52a5fabf7c8..b1dc60f8e27 100644 --- a/src/csharp/Grpc.Core/VerifyPeerContext.cs +++ b/src/csharp/Grpc.Core/VerifyPeerContext.cs @@ -27,22 +27,22 @@ namespace Grpc.Core /// /// Initializes a new instance of the class. /// - /// string containing the host name of the peer. - /// string containing PEM encoded certificate of the peer. - internal VerifyPeerContext(string targetHost, string targetPem) + /// The target name of the peer. + /// The PEM encoded certificate of the peer. + internal VerifyPeerContext(string targetName, string peerPem) { - this.TargetHost = targetHost; - this.TargetPem = targetPem; + this.TargetName = targetName; + this.PeerPem = peerPem; } /// - /// String containing the host name of the peer. + /// The target name of the peer. /// - public string TargetHost { get; } + public string TargetName { get; } /// - /// string containing PEM encoded certificate of the peer. + /// The PEM encoded certificate of the peer. /// - public string TargetPem { get; } + public string PeerPem { get; } } } diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 4323d40b6d3..b3bb7c668ca 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -948,11 +948,11 @@ static void grpcsharp_verify_peer_destroy_handler(void* userdata) { NULL, NULL); } -static int grpcsharp_verify_peer_handler(const char* target_host, - const char* target_pem, +static int grpcsharp_verify_peer_handler(const char* target_name, + const char* peer_pem, void* userdata) { - return native_callback_dispatcher(userdata, (void*)target_host, - (void*)target_pem, (void*)0, NULL, + return native_callback_dispatcher(userdata, (void*)target_name, + (void*)peer_pem, (void*)0, NULL, NULL, NULL); } From c02aec32554a44b2d8180cd461ec1617ba0b113e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 1 Apr 2019 00:13:54 -0400 Subject: [PATCH 1713/2143] clang format code --- src/csharp/ext/grpc_csharp_ext.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index b3bb7c668ca..061a5edc4ab 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -943,20 +943,16 @@ grpcsharp_override_default_ssl_roots(const char* pem_root_certs) { } static void grpcsharp_verify_peer_destroy_handler(void* userdata) { - native_callback_dispatcher(userdata, NULL, - NULL, (void*)1, NULL, - NULL, NULL); + native_callback_dispatcher(userdata, NULL, NULL, (void*)1, NULL, NULL, NULL); } static int grpcsharp_verify_peer_handler(const char* target_name, - const char* peer_pem, - void* userdata) { + const char* peer_pem, void* userdata) { return native_callback_dispatcher(userdata, (void*)target_name, - (void*)peer_pem, (void*)0, NULL, - NULL, NULL); + (void*)peer_pem, (void*)0, NULL, NULL, + NULL); } - GPR_EXPORT grpc_channel_credentials* GPR_CALLTYPE grpcsharp_ssl_credentials_create(const char* pem_root_certs, const char* key_cert_pair_cert_chain, @@ -966,10 +962,8 @@ grpcsharp_ssl_credentials_create(const char* pem_root_certs, verify_peer_options verify_options; verify_peer_options* p_verify_options = NULL; if (verify_peer_callback_tag != NULL) { - verify_options.verify_peer_callback_userdata = - verify_peer_callback_tag; - verify_options.verify_peer_destruct = - grpcsharp_verify_peer_destroy_handler; + verify_options.verify_peer_callback_userdata = verify_peer_callback_tag; + verify_options.verify_peer_destruct = grpcsharp_verify_peer_destroy_handler; verify_options.verify_peer_callback = grpcsharp_verify_peer_handler; p_verify_options = &verify_options; } From 57caf7840766999a1c9e44537730a821cbbacb79 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Mon, 1 Apr 2019 08:48:35 -0700 Subject: [PATCH 1714/2143] fix ALPN issues. --- .../ssl/ssl_security_connector.cc | 17 ++------ test/core/security/security_connector_test.cc | 43 ++++++++++++++++++- 2 files changed, 46 insertions(+), 14 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 8a00bbb82ed..ad492f361aa 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 @@ -44,24 +44,15 @@ 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."); + grpc_error* error = grpc_ssl_check_alpn(peer); + if (error != GRPC_ERROR_NONE) { + return error; } - 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); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return error; } diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index 2a31763c73c..496f064439c 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -36,6 +36,10 @@ #include "src/core/tsi/transport_security.h" #include "test/core/util/test_config.h" +#ifndef TSI_OPENSSL_ALPN_SUPPORT +#define TSI_OPENSSL_ALPN_SUPPORT 1 +#endif + static int check_transport_security_type(const grpc_auth_context* ctx) { grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name( ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME); @@ -432,6 +436,43 @@ static void test_default_ssl_roots(void) { gpr_free(roots_env_var_file_path); } +static void test_peer_alpn_check(void) { +#if TSI_OPENSSL_ALPN_SUPPORT + tsi_peer peer; + const char* alpn = "grpc"; + const char* wrong_alpn = "wrong"; + // peer does not have a TSI_SSL_ALPN_SELECTED_PROTOCOL property. + GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property("wrong peer property name", + alpn, strlen(alpn), + &peer.properties[0]) == TSI_OK); + grpc_error* error = grpc_ssl_check_alpn(&peer); + GPR_ASSERT(error != GRPC_ERROR_NONE); + tsi_peer_destruct(&peer); + GRPC_ERROR_UNREF(error); + // peer has a TSI_SSL_ALPN_SELECTED_PROTOCOL property but with an incorrect + // property value. + GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL, + wrong_alpn, strlen(wrong_alpn), + &peer.properties[0]) == TSI_OK); + error = grpc_ssl_check_alpn(&peer); + GPR_ASSERT(error != GRPC_ERROR_NONE); + tsi_peer_destruct(&peer); + GRPC_ERROR_UNREF(error); + // peer has a TSI_SSL_ALPN_SELECTED_PROTOCOL property with a correct property + // value. + GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL, + alpn, strlen(alpn), + &peer.properties[0]) == TSI_OK); + GPR_ASSERT(grpc_ssl_check_alpn(&peer) == GRPC_ERROR_NONE); + tsi_peer_destruct(&peer); +#else + GPR_ASSERT(grpc_ssl_check_alpn(nullptr) == GRPC_ERROR_NONE); +#endif +} + int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); @@ -443,7 +484,7 @@ int main(int argc, char** argv) { test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context(); test_ipv6_address_san(); test_default_ssl_roots(); - + test_peer_alpn_check(); grpc_shutdown(); return 0; } From f931435f2734c818dd0e98dca0a61e29d60cf909 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 1 Apr 2019 09:38:46 -0700 Subject: [PATCH 1715/2143] Update g_stands_for.md for v1.20.x --- doc/g_stands_for.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index 423d8c2fd9a..5c5579d4d28 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -19,4 +19,4 @@ - 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/v1.19.x) -- 1.20 'g' stands for ['godric'](https://github.com/grpc/grpc/tree/master) +- 1.20 'g' stands for ['godric'](https://github.com/grpc/grpc/tree/v1.20.x) From 6ddee61f7567ed000867cdc3238101c087877c99 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 1 Apr 2019 13:31:36 -0700 Subject: [PATCH 1716/2143] Upgrade linux RBE tests to bazel 0.22 --- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index 863b43a1728..1882fe213fa 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -23,7 +23,7 @@ cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321 # Download bazel temp_dir="$(mktemp -d)" -wget -q https://github.com/bazelbuild/bazel/releases/download/0.20.0/bazel-0.20.0-linux-x86_64 -O "${temp_dir}/bazel" +wget -q https://github.com/bazelbuild/bazel/releases/download/0.22.0/bazel-0.22.0-linux-x86_64 -O "${temp_dir}/bazel" chmod 755 "${temp_dir}/bazel" export PATH="${temp_dir}:${PATH}" # This should show ${temp_dir}/bazel From 8e092b45fa2a45c4507d6703987e03ebf1740196 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 1 Apr 2019 13:23:44 -0700 Subject: [PATCH 1717/2143] Move ProtoServerReflectionPlugin from grpc to grpc_impl namespace --- BUILD | 1 + CMakeLists.txt | 1 + Makefile | 1 + build.yaml | 1 + .../ext/proto_server_reflection_plugin.h | 31 +++-------- .../ext/proto_server_reflection_plugin_impl.h | 54 +++++++++++++++++++ src/cpp/ext/proto_server_reflection_plugin.cc | 4 +- .../generated/sources_and_headers.json | 2 + 8 files changed, 69 insertions(+), 26 deletions(-) create mode 100644 include/grpcpp/ext/proto_server_reflection_plugin_impl.h diff --git a/BUILD b/BUILD index 7d71b9df9eb..ae1679d02db 100644 --- a/BUILD +++ b/BUILD @@ -2203,6 +2203,7 @@ grpc_cc_library( public_hdrs = [ "include/grpc++/ext/proto_server_reflection_plugin.h", "include/grpcpp/ext/proto_server_reflection_plugin.h", + "include/grpcpp/ext/proto_server_reflection_plugin_impl.h", ], deps = [ ":grpc++", diff --git a/CMakeLists.txt b/CMakeLists.txt index b80c2c4b1f6..e5965ad23eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3962,6 +3962,7 @@ target_link_libraries(grpc++_reflection foreach(_hdr include/grpc++/ext/proto_server_reflection_plugin.h include/grpcpp/ext/proto_server_reflection_plugin.h + include/grpcpp/ext/proto_server_reflection_plugin_impl.h ) string(REPLACE "include/" "" _path ${_hdr}) get_filename_component(_path ${_path} PATH) diff --git a/Makefile b/Makefile index 873a0e27a19..45cbf21b446 100644 --- a/Makefile +++ b/Makefile @@ -6296,6 +6296,7 @@ LIBGRPC++_REFLECTION_SRC = \ PUBLIC_HEADERS_CXX += \ include/grpc++/ext/proto_server_reflection_plugin.h \ include/grpcpp/ext/proto_server_reflection_plugin.h \ + include/grpcpp/ext/proto_server_reflection_plugin_impl.h \ LIBGRPC++_REFLECTION_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_REFLECTION_SRC)))) diff --git a/build.yaml b/build.yaml index 0a56c6f2802..61f71fe3e9e 100644 --- a/build.yaml +++ b/build.yaml @@ -1741,6 +1741,7 @@ libs: public_headers: - include/grpc++/ext/proto_server_reflection_plugin.h - include/grpcpp/ext/proto_server_reflection_plugin.h + - include/grpcpp/ext/proto_server_reflection_plugin_impl.h headers: - src/cpp/ext/proto_server_reflection.h src: diff --git a/include/grpcpp/ext/proto_server_reflection_plugin.h b/include/grpcpp/ext/proto_server_reflection_plugin.h index 1cfdc1b6ccf..f6f2202ffb3 100644 --- a/include/grpcpp/ext/proto_server_reflection_plugin.h +++ b/include/grpcpp/ext/proto_server_reflection_plugin.h @@ -1,6 +1,6 @@ /* * - * 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. @@ -19,34 +19,17 @@ #ifndef GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H #define GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H -#include -#include - -namespace grpc { -class ServerInitializer; -class ProtoServerReflection; -} // namespace grpc +#include namespace grpc { namespace reflection { -class ProtoServerReflectionPlugin : public ::grpc::ServerBuilderPlugin { - public: - ProtoServerReflectionPlugin(); - ::grpc::string name() override; - void InitServer(::grpc::ServerInitializer* si) override; - void Finish(::grpc::ServerInitializer* si) override; - void ChangeArguments(const ::grpc::string& name, void* value) override; - bool has_async_methods() const override; - bool has_sync_methods() const override; +typedef ::grpc_impl::reflection::ProtoServerReflectionPlugin + ProtoServerReflectionPlugin; - private: - std::shared_ptr reflection_service_; -}; - -/// Add proto reflection plugin to \a ServerBuilder. -/// This function should be called at the static initialization time. -void InitProtoReflectionServerBuilderPlugin(); +static inline void InitProtoReflectionServerBuilderPlugin() { + ::grpc_impl::reflection::InitProtoReflectionServerBuilderPlugin(); +} } // namespace reflection } // namespace grpc diff --git a/include/grpcpp/ext/proto_server_reflection_plugin_impl.h b/include/grpcpp/ext/proto_server_reflection_plugin_impl.h new file mode 100644 index 00000000000..b7e68c0d8c8 --- /dev/null +++ b/include/grpcpp/ext/proto_server_reflection_plugin_impl.h @@ -0,0 +1,54 @@ +/* + * + * 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_EXT_PROTO_SERVER_REFLECTION_PLUGIN_IMPL_H +#define GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_IMPL_H + +#include +#include + +namespace grpc { +class ServerInitializer; +class ProtoServerReflection; +} // namespace grpc + +namespace grpc_impl { +namespace reflection { + +class ProtoServerReflectionPlugin : public ::grpc::ServerBuilderPlugin { + public: + ProtoServerReflectionPlugin(); + ::grpc::string name() override; + void InitServer(::grpc::ServerInitializer* si) override; + void Finish(::grpc::ServerInitializer* si) override; + void ChangeArguments(const ::grpc::string& name, void* value) override; + bool has_async_methods() const override; + bool has_sync_methods() const override; + + private: + std::shared_ptr reflection_service_; +}; + +/// Add proto reflection plugin to \a ServerBuilder. +/// This function should be called at the static initialization time. +void InitProtoReflectionServerBuilderPlugin(); + +} // namespace reflection +} // namespace grpc_impl + +#endif // GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_IMPL_H diff --git a/src/cpp/ext/proto_server_reflection_plugin.cc b/src/cpp/ext/proto_server_reflection_plugin.cc index ee3ac3fee88..0ac4cb80c64 100644 --- a/src/cpp/ext/proto_server_reflection_plugin.cc +++ b/src/cpp/ext/proto_server_reflection_plugin.cc @@ -23,7 +23,7 @@ #include "src/cpp/ext/proto_server_reflection.h" -namespace grpc { +namespace grpc_impl { namespace reflection { ProtoServerReflectionPlugin::ProtoServerReflectionPlugin() @@ -79,4 +79,4 @@ struct StaticProtoReflectionPluginInitializer { } static_proto_reflection_plugin_initializer; } // namespace reflection -} // namespace grpc +} // namespace grpc_impl diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8503ece32e4..1b633328abd 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -6629,6 +6629,7 @@ "headers": [ "include/grpc++/ext/proto_server_reflection_plugin.h", "include/grpcpp/ext/proto_server_reflection_plugin.h", + "include/grpcpp/ext/proto_server_reflection_plugin_impl.h", "src/cpp/ext/proto_server_reflection.h" ], "is_filegroup": false, @@ -6637,6 +6638,7 @@ "src": [ "include/grpc++/ext/proto_server_reflection_plugin.h", "include/grpcpp/ext/proto_server_reflection_plugin.h", + "include/grpcpp/ext/proto_server_reflection_plugin_impl.h", "src/cpp/ext/proto_server_reflection.cc", "src/cpp/ext/proto_server_reflection.h", "src/cpp/ext/proto_server_reflection_plugin.cc" From 39b40cbccbe8145dba88583bbdac0ff88a111198 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 1 Apr 2019 13:37:35 -0700 Subject: [PATCH 1718/2143] Add guard to the tv_nsec field of gpr_now return value --- src/core/lib/gpr/time_posix.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/core/lib/gpr/time_posix.cc b/src/core/lib/gpr/time_posix.cc index 1b3e36486fc..b5a47673676 100644 --- a/src/core/lib/gpr/time_posix.cc +++ b/src/core/lib/gpr/time_posix.cc @@ -108,6 +108,9 @@ static gpr_timespec now_impl(gpr_clock_type clock) { now.clock_type = clock; switch (clock) { case GPR_CLOCK_REALTIME: + // gettimeofday(...) function may return with a value whose tv_usec is + // greater than 1e6 on iOS The case is resolved with the guard at end of + // this function. gettimeofday(&now_tv, nullptr); now.tv_sec = now_tv.tv_sec; now.tv_nsec = now_tv.tv_usec * 1000; @@ -124,6 +127,16 @@ static gpr_timespec now_impl(gpr_clock_type clock) { abort(); } + // Guard the tv_nsec field in valid range for all clock types + while (GPR_UNLIKELY(now.tv_nsec >= 1e9)) { + now.tv_sec++; + now.tv_nsec -= 1e9; + } + while (GPR_UNLIKELY(now.tv_nsec < 0)) { + now.tv_sec--; + now.tv_nsec += 1e9; + } + return now; } #endif From 6da82f08bda80c4c167047bd20ef81655c27551b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 1 Apr 2019 17:14:30 -0400 Subject: [PATCH 1719/2143] add job to give early warning about incompatible bazel changes --- .../grpc_bazel_rbe_incompatible_changes.sh | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.sh diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.sh b/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.sh new file mode 100644 index 00000000000..9c3712a07da --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env 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. + +set -ex + +# TODO(jtattermusch): use the latest version of bazel + +# Use --all_incompatible_changes to give an early warning about future +# bazel incompatibilities. +EXTRA_FLAGS="--config=opt --cache_test_results=no --all_incompatible_changes" +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" From ee4e4bead3d604c37484a657e692d61c9527f70b Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 1 Apr 2019 14:55:29 -0700 Subject: [PATCH 1720/2143] pick_first: don't go into TRANSIENT_FAILURE upon empty update when in IDLE. --- .../lb_policy/pick_first/pick_first.cc | 26 ++++++++++++++----- test/cpp/end2end/client_lb_end2end_test.cc | 26 +++++++++++++++++++ 2 files changed, 45 insertions(+), 7 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 86c6b25ac63..3da0b59f279 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 @@ -188,8 +188,14 @@ void PickFirst::ShutdownLocked() { void PickFirst::ExitIdleLocked() { if (idle_) { idle_ = false; - if (subchannel_list_ != nullptr && - subchannel_list_->num_subchannels() > 0) { + if (subchannel_list_ == nullptr || + subchannel_list_->num_subchannels() == 0) { + grpc_error* error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to"); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + UniquePtr(New(error))); + } else { subchannel_list_->subchannel(0) ->CheckConnectivityStateAndStartWatchingLocked(); } @@ -253,13 +259,19 @@ void PickFirst::UpdateLocked(UpdateArgs 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. + // subchannels. 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))); + // If not idle, put the channel in TRANSIENT_FAILURE. + // (If we are idle, then this will happen in ExitIdleLocked() if we + // haven't gotten a non-empty update by the time the application tries + // to start a new call.) + if (!idle_) { + 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 diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 4244690d76b..77f9db94acc 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -940,6 +940,32 @@ TEST_F(ClientLbEnd2endTest, PickFirstPendingUpdateAndSelectedSubchannelFails) { WaitForServer(stub, 1, DEBUG_LOCATION, true /* ignore_failure */); } +TEST_F(ClientLbEnd2endTest, PickFirstStaysIdleUponEmptyUpdate) { + // Start server, send RPC, and make sure channel is READY. + const int kNumServers = 1; + StartServers(kNumServers); + auto channel = BuildChannel(""); // pick_first is the default. + auto stub = BuildStub(channel); + SetNextResolution(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + // Stop server. Channel should go into state IDLE. + servers_[0]->Shutdown(); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); + // Now send resolver update that includes no addresses. Channel + // should stay in state IDLE. + SetNextResolution({}); + EXPECT_FALSE(channel->WaitForStateChange( + GRPC_CHANNEL_IDLE, grpc_timeout_seconds_to_deadline(3))); + // Now bring the backend back up and send a non-empty resolver update, + // and then try to send an RPC. Channel should go back into state READY. + StartServer(0); + SetNextResolution(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); +} + TEST_F(ClientLbEnd2endTest, RoundRobin) { // Start servers and send one RPC per server. const int kNumServers = 3; From ac7c73605734de136d88b3f5dde8545a468cebe3 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 1 Apr 2019 14:34:27 -0700 Subject: [PATCH 1721/2143] Fix BUILD.gn file https://github.com/grpc/grpc/pull/18345 did not add a file to BUILD.gn causing generate_projects.sh to fail causing this error. Fixing it by running the generate_projects.sh script. --- BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.gn b/BUILD.gn index 4e0bdb6586c..7ceea3c3b63 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1076,6 +1076,7 @@ config("grpc_config") { "include/grpcpp/impl/server_initializer_impl.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 ce3900571250328fa775e7f036d1c58f83a2f112 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 1 Apr 2019 15:30:43 -0700 Subject: [PATCH 1722/2143] Bump up protobuf version --- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/!ProtoCompiler.podspec | 2 +- .../src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index dd83dce22d9..dc290d9d2a8 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.1' + s.dependency '!ProtoCompiler', '3.7.0' # 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 789265470c1..58d74be4d4e 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.1' + v = '3.7.0' s.version = v s.summary = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files' s.description = <<-DESC diff --git a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template index 5a416eb6471..741f9b7e54d 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.1' + s.dependency '!ProtoCompiler', '3.7.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' From 7e6b5db90de63c820e80440502aa1427bcd72ed9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 1 Apr 2019 15:34:41 -0700 Subject: [PATCH 1723/2143] Resolve merge issue --- BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/BUILD b/BUILD index f24e986329f..003914a3c5f 100644 --- a/BUILD +++ b/BUILD @@ -369,7 +369,6 @@ grpc_cc_library( "grpc++_codegen_base", "grpc++_codegen_base_src", "grpc++_codegen_proto", - "grpc_cfstream", ], ) From e69406008fc0c7b7a26c5d0bf79bc7b6efce503b Mon Sep 17 00:00:00 2001 From: Hao Nguyen Date: Mon, 1 Apr 2019 12:30:42 -0700 Subject: [PATCH 1724/2143] Explicitly set case_insensitive_enum_parsing = true when parsing JSON --- src/cpp/server/channelz/channelz_service.cc | 27 ++++++++++----------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc index c44a9ac0de6..0409991fe67 100644 --- a/src/cpp/server/channelz/channelz_service.cc +++ b/src/cpp/server/channelz/channelz_service.cc @@ -24,6 +24,12 @@ #include namespace grpc { +grpc::protobuf::util::Status ParseJson(const char* json_str, + grpc::protobuf::Message* message) { + grpc::protobuf::json::JsonParseOptions options; + options.case_insensitive_enum_parsing = true; + return grpc::protobuf::json::JsonStringToMessage(json_str, message, options); +} Status ChannelzService::GetTopChannels( ServerContext* unused, const channelz::v1::GetTopChannelsRequest* request, @@ -33,8 +39,7 @@ Status ChannelzService::GetTopChannels( return Status(StatusCode::INTERNAL, "grpc_channelz_get_top_channels returned null"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); @@ -50,8 +55,7 @@ Status ChannelzService::GetServers( return Status(StatusCode::INTERNAL, "grpc_channelz_get_servers returned null"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); @@ -67,8 +71,7 @@ Status ChannelzService::GetServer(ServerContext* unused, return Status(StatusCode::INTERNAL, "grpc_channelz_get_server returned null"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); @@ -85,8 +88,7 @@ Status ChannelzService::GetServerSockets( return Status(StatusCode::INTERNAL, "grpc_channelz_get_server_sockets returned null"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); @@ -101,8 +103,7 @@ Status ChannelzService::GetChannel( if (json_str == nullptr) { return Status(StatusCode::NOT_FOUND, "No object found for that ChannelId"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); @@ -118,8 +119,7 @@ Status ChannelzService::GetSubchannel( return Status(StatusCode::NOT_FOUND, "No object found for that SubchannelId"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); @@ -134,8 +134,7 @@ Status ChannelzService::GetSocket(ServerContext* unused, if (json_str == nullptr) { return Status(StatusCode::NOT_FOUND, "No object found for that SocketId"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); From f9a9639088b258f707ed1616b5044787b65ac698 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 1 Apr 2019 15:58:33 -0700 Subject: [PATCH 1725/2143] generate projects --- BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.gn b/BUILD.gn index 4e0bdb6586c..7ceea3c3b63 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1076,6 +1076,7 @@ config("grpc_config") { "include/grpcpp/impl/server_initializer_impl.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 69bbf86d147f988d142914de0da8a0b6eac9afba Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 1 Apr 2019 16:01:49 -0700 Subject: [PATCH 1726/2143] Add a dummy function to grpc cfstream library --- src/core/lib/iomgr/cfstream_handle.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index cf21c4fc511..2fda160f68a 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -192,4 +192,11 @@ void CFStreamHandle::Unref(const char* file, int line, const char* reason) { } } +#else + +/* Creating a dummy function so that the grpc_cfstream library will be + * non-empty. + */ +void CFStreamDummy() {} + #endif From cc44a729db8bec1f991be19f49fa86b681b5f49b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 1 Apr 2019 20:42:02 -0400 Subject: [PATCH 1727/2143] improve doc comment --- src/csharp/Grpc.Core/ChannelCredentials.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core/ChannelCredentials.cs b/src/csharp/Grpc.Core/ChannelCredentials.cs index fbea40d0a4b..dcbe9f3599b 100644 --- a/src/csharp/Grpc.Core/ChannelCredentials.cs +++ b/src/csharp/Grpc.Core/ChannelCredentials.cs @@ -109,8 +109,12 @@ namespace Grpc.Core /// /// Callback invoked with the expected targetHost and the peer's certificate. /// If false is returned by this callback then it is treated as a - /// verification failure. Invocation of the callback is blocking, so any + /// verification failure and the attempted connection will fail. + /// Invocation of the callback is blocking, so any /// implementation should be light-weight. + /// Note that the callback can potentially be invoked multiple times, + /// concurrently from different threads (e.g. when multiple connections + /// are being created for the same credentials). /// /// The associated with the callback /// true if verification succeeded, false otherwise. From c9974ab6c9090bb25e41f80a2f0fb8a12beb9f14 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 1 Apr 2019 20:55:50 -0400 Subject: [PATCH 1728/2143] refactor grpcsharp_ssl_credentials_create --- src/csharp/ext/grpc_csharp_ext.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 061a5edc4ab..91d3957dbf0 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -960,25 +960,29 @@ grpcsharp_ssl_credentials_create(const char* pem_root_certs, void* verify_peer_callback_tag) { grpc_ssl_pem_key_cert_pair key_cert_pair; verify_peer_options verify_options; - verify_peer_options* p_verify_options = NULL; - if (verify_peer_callback_tag != NULL) { - verify_options.verify_peer_callback_userdata = verify_peer_callback_tag; - verify_options.verify_peer_destruct = grpcsharp_verify_peer_destroy_handler; - verify_options.verify_peer_callback = grpcsharp_verify_peer_handler; - p_verify_options = &verify_options; - } + grpc_ssl_pem_key_cert_pair* key_cert_pair_ptr = NULL; + verify_peer_options* verify_options_ptr = NULL; if (key_cert_pair_cert_chain || key_cert_pair_private_key) { + memset(&key_cert_pair, 0, sizeof(key_cert_pair)); key_cert_pair.cert_chain = key_cert_pair_cert_chain; key_cert_pair.private_key = key_cert_pair_private_key; - return grpc_ssl_credentials_create(pem_root_certs, &key_cert_pair, - p_verify_options, NULL); + key_cert_pair_ptr = &key_cert_pair; } else { GPR_ASSERT(!key_cert_pair_cert_chain); GPR_ASSERT(!key_cert_pair_private_key); - return grpc_ssl_credentials_create(pem_root_certs, NULL, p_verify_options, - NULL); } + + if (verify_peer_callback_tag != NULL) { + memset(&verify_options, 0, sizeof(verify_peer_options)); + verify_options.verify_peer_callback_userdata = verify_peer_callback_tag; + verify_options.verify_peer_destruct = grpcsharp_verify_peer_destroy_handler; + verify_options.verify_peer_callback = grpcsharp_verify_peer_handler; + verify_options_ptr = &verify_options; + } + + return grpc_ssl_credentials_create(pem_root_certs, key_cert_pair_ptr, + verify_options_ptr, NULL); } GPR_EXPORT void GPR_CALLTYPE From c4b7423ad019bb1d834c35cc3105305d24f3f2c0 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 1 Apr 2019 17:51:18 -0700 Subject: [PATCH 1729/2143] Fix errors due to rebase --- include/grpcpp/ext/proto_server_reflection_plugin_impl.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/ext/proto_server_reflection_plugin_impl.h b/include/grpcpp/ext/proto_server_reflection_plugin_impl.h index b7e68c0d8c8..a06fe14cdd7 100644 --- a/include/grpcpp/ext/proto_server_reflection_plugin_impl.h +++ b/include/grpcpp/ext/proto_server_reflection_plugin_impl.h @@ -23,19 +23,20 @@ #include namespace grpc { -class ServerInitializer; class ProtoServerReflection; } // namespace grpc namespace grpc_impl { +class ServerInitializer; + namespace reflection { class ProtoServerReflectionPlugin : public ::grpc::ServerBuilderPlugin { public: ProtoServerReflectionPlugin(); ::grpc::string name() override; - void InitServer(::grpc::ServerInitializer* si) override; - void Finish(::grpc::ServerInitializer* si) override; + void InitServer(::grpc_impl::ServerInitializer* si) override; + void Finish(::grpc_impl::ServerInitializer* si) override; void ChangeArguments(const ::grpc::string& name, void* value) override; bool has_async_methods() const override; bool has_sync_methods() const override; From 43b33ee371cb7f1237c363628f4acf6196216a37 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 1 Apr 2019 18:59:01 -0700 Subject: [PATCH 1730/2143] Fix errors from clang scripts --- include/grpcpp/server_builder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 5655761d081..bd8fa4621f7 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -39,7 +39,7 @@ namespace grpc_impl { class ServerCredentials; class ResourceQuota; -} +} // namespace grpc_impl namespace grpc { From 1da6fad8431d41ffab33adc3cec6428e3746a455 Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 2 Apr 2019 10:41:53 -0700 Subject: [PATCH 1731/2143] Move import headers to header from source --- src/compiler/cpp_generator.cc | 42 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index d32f2662dc5..1bb9c509bb5 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -117,6 +117,13 @@ grpc::string GetHeaderPrologue(grpc_generator::File* file, return output; } +// Convert from "a/b/c.proto" to "#include \"a/b/c$message_header_ext$\"\n" +grpc::string ImportInludeFromProtoName(const grpc::string& proto_name) { + return grpc::string("#include \"") + + proto_name.substr(0, proto_name.size() - 6) + + grpc::string("$message_header_ext$\"\n"); +} + grpc::string GetHeaderIncludes(grpc_generator::File* file, const Parameters& params) { grpc::string output; @@ -154,6 +161,20 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, printer->Print(vars, "class ServerContext;\n"); printer->Print(vars, "} // namespace grpc\n\n"); + vars["message_header_ext"] = params.message_header_extension.empty() + ? kCppGeneratorMessageHeaderExt + : params.message_header_extension; + + if (params.include_import_headers) { + const std::vector import_names = file->GetImportNames(); + for (const auto& import_name : import_names) { + const grpc::string include_name = + ImportInludeFromProtoName(import_name); + printer->Print(vars, include_name.c_str()); + } + printer->PrintRaw("\n"); + } + if (!file->package().empty()) { std::vector parts = file->package_parts(); @@ -1584,13 +1605,6 @@ grpc::string GetSourcePrologue(grpc_generator::File* file, return output; } -// Convert from "a/b/c.proto" to "#include \"a/b/c$message_header_ext$\"\n" -grpc::string ImportInludeFromProtoName(const grpc::string& proto_name) { - return grpc::string("#include \"") + - proto_name.substr(0, proto_name.size() - 6) + - grpc::string("$message_header_ext$\"\n"); -} - grpc::string GetSourceIncludes(grpc_generator::File* file, const Parameters& params) { grpc::string output; @@ -1598,20 +1612,6 @@ grpc::string GetSourceIncludes(grpc_generator::File* file, // Scope the output stream so it closes and finalizes output to the string. auto printer = file->CreatePrinter(&output); std::map vars; - vars["message_header_ext"] = params.message_header_extension.empty() - ? kCppGeneratorMessageHeaderExt - : params.message_header_extension; - - if (params.include_import_headers) { - const std::vector import_names = file->GetImportNames(); - for (const auto& import_name : import_names) { - const grpc::string include_name = - ImportInludeFromProtoName(import_name); - printer->Print(vars, include_name.c_str()); - } - printer->PrintRaw("\n"); - } - static const char* headers_strs[] = { "functional", "grpcpp/impl/codegen/async_stream.h", From 1ef874a03f21a2ba138a6763451fb774cd8cef6d Mon Sep 17 00:00:00 2001 From: Doug Fawley Date: Tue, 2 Apr 2019 13:53:21 -0700 Subject: [PATCH 1732/2143] change from 400 to 415 --- doc/PROTOCOL-HTTP2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/PROTOCOL-HTTP2.md b/doc/PROTOCOL-HTTP2.md index 6b4d85db30a..e73e682bbe3 100644 --- a/doc/PROTOCOL-HTTP2.md +++ b/doc/PROTOCOL-HTTP2.md @@ -61,7 +61,7 @@ the form shown above. If **Timeout** is omitted a server should assume an infinite timeout. Client implementations are free to send a default minimum timeout based on their deployment requirements. -If **Content-Type** does not begin with "application/grpc", gRPC servers SHOULD respond with HTTP status of 400 (Bad Request). This will prevent other HTTP/2 clients from interpreting a gRPC error response, which uses status 200 (OK), as successful. +If **Content-Type** does not begin with "application/grpc", gRPC servers SHOULD respond with HTTP status of 415 (Unsupported Media Type). This will prevent other HTTP/2 clients from interpreting a gRPC error response, which uses status 200 (OK), as successful. **Custom-Metadata** is an arbitrary set of key-value pairs defined by the application layer. Header names starting with "grpc-" but not listed here are reserved for future GRPC use and should not be used by applications as **Custom-Metadata**. From 89a9e9d1dd000dff80719c460ed73322a388bbfb Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 2 Apr 2019 14:33:11 -0700 Subject: [PATCH 1733/2143] code review changes --- .../filters/client_channel/client_channel.cc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index c856199d560..f638423a9de 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -107,12 +107,14 @@ class ExternalConnectivityWatcher { int size() const; ExternalConnectivityWatcher* Lookup(grpc_closure* on_complete) const; - void Append(ExternalConnectivityWatcher* watcher); - void Remove(ExternalConnectivityWatcher* watcher); + void Add(ExternalConnectivityWatcher* watcher); + void Remove(const ExternalConnectivityWatcher* watcher); private: - // head_ is guarded by its own mutex, since the size of the list needs - // to be grabbed immediately without polling on a CQ. + // head_ is guarded by a mutex, since the size() method needs to + // iterate over the list, and it's called from the C-core API + // function grpc_channel_num_external_connectivity_watchers(), which + // is synchronous and therefore cannot run in the combiner. mutable gpr_mu mu_; ExternalConnectivityWatcher* head_ = nullptr; }; @@ -260,9 +262,9 @@ ExternalConnectivityWatcher* ExternalConnectivityWatcher::WatcherList::Lookup( return w; } -void ExternalConnectivityWatcher::WatcherList::Append( +void ExternalConnectivityWatcher::WatcherList::Add( ExternalConnectivityWatcher* watcher) { - GPR_ASSERT(!Lookup(watcher->on_complete_)); + GPR_ASSERT(Lookup(watcher->on_complete_) == nullptr); MutexLock lock(&mu_); GPR_ASSERT(watcher->next_ == nullptr); watcher->next_ = head_; @@ -270,7 +272,7 @@ void ExternalConnectivityWatcher::WatcherList::Append( } void ExternalConnectivityWatcher::WatcherList::Remove( - ExternalConnectivityWatcher* watcher) { + const ExternalConnectivityWatcher* watcher) { MutexLock lock(&mu_); if (watcher == head_) { head_ = watcher->next_; @@ -333,7 +335,6 @@ void ExternalConnectivityWatcher::WatchConnectivityStateLocked( self->chand_->external_connectivity_watcher_list->Lookup( self->on_complete_); if (found != nullptr) { - GPR_ASSERT(found->on_complete_ == self->on_complete_); grpc_connectivity_state_notify_on_state_change( &found->chand_->state_tracker, nullptr, &found->my_closure_); } @@ -341,7 +342,7 @@ void ExternalConnectivityWatcher::WatchConnectivityStateLocked( return; } // New watcher. - self->chand_->external_connectivity_watcher_list->Append(self); + self->chand_->external_connectivity_watcher_list->Add(self); // This assumes that the closure is scheduled on the ExecCtx scheduler // and that GRPC_CLOSURE_RUN would run the closure immediately. GRPC_CLOSURE_RUN(self->watcher_timer_init_, GRPC_ERROR_NONE); From adf5f872846ce2d7f03193a72fdf04310ebd25ec Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 2 Apr 2019 15:16:29 -0700 Subject: [PATCH 1734/2143] more code review changes --- src/core/ext/filters/client_channel/client_channel.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index f638423a9de..34a24e2c712 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -127,7 +127,7 @@ class ExternalConnectivityWatcher { ~ExternalConnectivityWatcher(); private: - static void OnExternalWatchCompleteLocked(void* arg, grpc_error* error); + static void OnWatchCompleteLocked(void* arg, grpc_error* error); static void WatchConnectivityStateLocked(void* arg, grpc_error* ignored); channel_data* chand_; @@ -314,8 +314,8 @@ ExternalConnectivityWatcher::~ExternalConnectivityWatcher() { GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack, "ExternalConnectivityWatcher"); } -void ExternalConnectivityWatcher::OnExternalWatchCompleteLocked( - void* arg, grpc_error* error) { +void ExternalConnectivityWatcher::OnWatchCompleteLocked(void* arg, + grpc_error* error) { ExternalConnectivityWatcher* self = static_cast(arg); grpc_closure* on_complete = self->on_complete_; @@ -346,7 +346,7 @@ void ExternalConnectivityWatcher::WatchConnectivityStateLocked( // This assumes that the closure is scheduled on the ExecCtx scheduler // and that GRPC_CLOSURE_RUN would run the closure immediately. GRPC_CLOSURE_RUN(self->watcher_timer_init_, GRPC_ERROR_NONE); - GRPC_CLOSURE_INIT(&self->my_closure_, OnExternalWatchCompleteLocked, self, + GRPC_CLOSURE_INIT(&self->my_closure_, OnWatchCompleteLocked, self, grpc_combiner_scheduler(self->chand_->combiner)); grpc_connectivity_state_notify_on_state_change( &self->chand_->state_tracker, self->state_, &self->my_closure_); From 81c6081a3e392e5a3bff11285181de2d6693b3ae Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 3 Apr 2019 01:35:25 +0200 Subject: [PATCH 1735/2143] Fixing failures. --- src/core/lib/transport/transport.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index 3fc089676ea..09306110c63 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -29,6 +29,7 @@ #include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/slice/slice_internal.h" @@ -243,21 +244,23 @@ void grpc_transport_stream_op_batch_finish_with_failure( GRPC_ERROR_UNREF(error); } -typedef struct { +struct made_transport_op { grpc_closure outer_on_complete; - grpc_closure* inner_on_complete; + grpc_closure* inner_on_complete = nullptr; grpc_transport_op op; -} made_transport_op; + made_transport_op() { + memset(&outer_on_complete, 0, sizeof(outer_on_complete)); + } +}; static void destroy_made_transport_op(void* arg, grpc_error* error) { made_transport_op* op = static_cast(arg); GRPC_CLOSURE_SCHED(op->inner_on_complete, GRPC_ERROR_REF(error)); - gpr_free(op); + grpc_core::Delete(op); } grpc_transport_op* grpc_make_transport_op(grpc_closure* on_complete) { - made_transport_op* op = - static_cast(gpr_malloc(sizeof(*op))); + made_transport_op* op = grpc_core::New(); GRPC_CLOSURE_INIT(&op->outer_on_complete, destroy_made_transport_op, op, grpc_schedule_on_exec_ctx); op->inner_on_complete = on_complete; From 9e841d1aff6b33408dc9ee9480927a1ef69df8ec Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 1 Apr 2019 14:55:29 -0700 Subject: [PATCH 1736/2143] Backport pick_first fix to v1.20.x --- .../lb_policy/pick_first/pick_first.cc | 26 ++++++++++++++----- test/cpp/end2end/client_lb_end2end_test.cc | 26 +++++++++++++++++++ 2 files changed, 45 insertions(+), 7 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 86c6b25ac63..3da0b59f279 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 @@ -188,8 +188,14 @@ void PickFirst::ShutdownLocked() { void PickFirst::ExitIdleLocked() { if (idle_) { idle_ = false; - if (subchannel_list_ != nullptr && - subchannel_list_->num_subchannels() > 0) { + if (subchannel_list_ == nullptr || + subchannel_list_->num_subchannels() == 0) { + grpc_error* error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to"); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + UniquePtr(New(error))); + } else { subchannel_list_->subchannel(0) ->CheckConnectivityStateAndStartWatchingLocked(); } @@ -253,13 +259,19 @@ void PickFirst::UpdateLocked(UpdateArgs 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. + // subchannels. 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))); + // If not idle, put the channel in TRANSIENT_FAILURE. + // (If we are idle, then this will happen in ExitIdleLocked() if we + // haven't gotten a non-empty update by the time the application tries + // to start a new call.) + if (!idle_) { + 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 diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 4244690d76b..77f9db94acc 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -940,6 +940,32 @@ TEST_F(ClientLbEnd2endTest, PickFirstPendingUpdateAndSelectedSubchannelFails) { WaitForServer(stub, 1, DEBUG_LOCATION, true /* ignore_failure */); } +TEST_F(ClientLbEnd2endTest, PickFirstStaysIdleUponEmptyUpdate) { + // Start server, send RPC, and make sure channel is READY. + const int kNumServers = 1; + StartServers(kNumServers); + auto channel = BuildChannel(""); // pick_first is the default. + auto stub = BuildStub(channel); + SetNextResolution(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + // Stop server. Channel should go into state IDLE. + servers_[0]->Shutdown(); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); + // Now send resolver update that includes no addresses. Channel + // should stay in state IDLE. + SetNextResolution({}); + EXPECT_FALSE(channel->WaitForStateChange( + GRPC_CHANNEL_IDLE, grpc_timeout_seconds_to_deadline(3))); + // Now bring the backend back up and send a non-empty resolver update, + // and then try to send an RPC. Channel should go back into state READY. + StartServer(0); + SetNextResolution(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); +} + TEST_F(ClientLbEnd2endTest, RoundRobin) { // Start servers and send one RPC per server. const int kNumServers = 3; From cb6a2968fe1ebbb680bb56fe1c5eb844233205d5 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 3 Apr 2019 11:55:04 -0700 Subject: [PATCH 1737/2143] Make Interceptors work for lame channels --- src/cpp/client/create_channel.cc | 17 ++++++++--------- .../end2end/client_interceptors_end2end_test.cc | 12 ++++++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 457daa674c7..4c725e6b145 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -68,15 +68,14 @@ std::shared_ptr CreateCustomChannelWithInterceptors( std::vector< std::unique_ptr> interceptor_creators) { - return creds ? creds->CreateChannelWithInterceptors( - target, args, std::move(interceptor_creators)) - : CreateChannelInternal( - "", - grpc_lame_client_channel_create( - nullptr, GRPC_STATUS_INVALID_ARGUMENT, - "Invalid credentials."), - std::vector>()); + return creds + ? creds->CreateChannelWithInterceptors( + target, args, std::move(interceptor_creators)) + : CreateChannelInternal("", + grpc_lame_client_channel_create( + nullptr, GRPC_STATUS_INVALID_ARGUMENT, + "Invalid credentials."), + std::move(interceptor_creators)); } } // namespace experimental diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 421b31ad08a..f1aed093dc4 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -611,6 +611,18 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLoggingTest) { EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } +TEST_F(ClientInterceptorsEnd2endTest, + LameChannelClientInterceptorHijackingTest) { + ChannelArguments args; + std::vector> + creators; + creators.push_back(std::unique_ptr( + new HijackingInterceptorFactory())); + auto channel = experimental::CreateCustomChannelWithInterceptors( + server_address_, nullptr, args, std::move(creators)); + MakeCall(channel); +} + TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingTest) { ChannelArguments args; DummyInterceptor::Reset(); From 8a698e2cfdb48c6109b93788b5903d23c63a3b1d Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Tue, 2 Apr 2019 12:27:50 -0700 Subject: [PATCH 1738/2143] release notes generation script --- tools/release/release_notes.py | 369 +++++++++++++++++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 tools/release/release_notes.py diff --git a/tools/release/release_notes.py b/tools/release/release_notes.py new file mode 100644 index 00000000000..46e01843535 --- /dev/null +++ b/tools/release/release_notes.py @@ -0,0 +1,369 @@ +#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. +"""Generate draft and release notes in Markdown from Github PRs. + +You'll need a github API token to avoid being rate-limited. See +https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/ + +This script collects PRs using "git log X..Y" from local repo where X and Y are +tags or release branch names of previous and current releases respectively. +Typically, notes are generated before the release branch is labelled so Y is +almost always the name of the release branch. X is the previous release branch +if this is not a patch release. Otherwise, it is the previous release tag. +For example, for release v1.17.0, X will be origin/v1.16.x and for release v1.17.3, +X will be v1.17.2. In both cases Y will be origin/v1.17.x. + +""" + +from collections import defaultdict +import base64 +import json + +content_header = """Draft Release Notes For {version} +-- +Final release notes will be generated from the PR titles that have *"release notes:yes"* label. If you have any additional notes please add them below. These will be appended to auto generated release notes. Previous releases notes are [here](https://github.com/grpc/grpc/releases). + +**Also, look at the PRs listed below against your name.** Please apply the missing labels and make necessary corrections (like fixing the title) to the PR in Github. Final release notes will be generated just before the release on {date}. + +Add additional notes not in PRs +-- + +Core +- + + +C++ +- + + +C# +- + + +Objective-C +- + + +PHP +- + + +Python +- + + +Ruby +- + + +""" + +rl_header = """This is the {version} release ([{name}](https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md)) of gRPC Core. + +Please see the notes for the previous releases here: https://github.com/grpc/grpc/releases. Please consult https://grpc.io/ for all information regarding this product. + +This release contains refinements, improvements, and bug fixes, with highlights listed below. + + +""" + +HTML_URL = "https://github.com/grpc/grpc/pull/" +API_URL = 'https://api.github.com/repos/grpc/grpc/pulls/' + + +def get_commit_log(prevRelLabel, relBranch): + """Return the output of 'git log --pretty=online --merges prevRelLabel..relBranch' """ + + import subprocess + print("Running git log --pretty=oneline --merges " + prevRelLabel + ".." + + relBranch) + return subprocess.check_output([ + "git", "log", "--pretty=oneline", "--merges", + "%s..%s" % (prevRelLabel, relBranch) + ]) + + +def get_pr_data(pr_num): + """Get the PR data from github. Return 'error' on exception""" + + try: + from urllib2 import Request, urlopen, HTTPError + except ImportError: + import urllib + from urllib.request import Request, urlopen, HTTPError + url = API_URL + pr_num + req = Request(url) + req.add_header('Authorization', 'token %s' % TOKEN) + try: + f = urlopen(req) + response = json.loads(f.read().decode('utf-8')) + #print(response) + except HTTPError as e: + response = json.loads(e.fp.read().decode('utf-8')) + if 'message' in response: + print(response['message']) + response = "error" + return response + + +def get_pr_titles(gitLogs): + import re + error_count = 0 + match = b"Merge pull request #(\d+)" + prlist = re.findall(match, gitLogs, re.MULTILINE) + print("\nPRs matching 'Merge pull request #':") + print(prlist) + print("\n") + langs_pr = defaultdict(list) + for pr_num in prlist: + pr_num = str(pr_num) + print("---------- getting data for PR " + pr_num) + pr = get_pr_data(pr_num) + if pr == "error": + print("\n***ERROR*** Error in getting data for PR " + pr_num + "\n") + error_count += 1 + continue + rl_no_found = False + rl_yes_found = False + lang_found = False + for label in pr['labels']: + if label['name'] == 'release notes: yes': + rl_yes_found = True + elif label['name'] == 'release notes: no': + rl_no_found = True + elif label['name'].startswith('lang/'): + lang_found = True + lang = label['name'].split('/')[1].lower() + #lang = lang[0].upper() + lang[1:] + body = pr["title"] + if not body.endswith("."): + body = body + "." + if not pr["merged_by"]: + print("\n***ERROR***: No merge_by found for PR " + pr_num + "\n") + error_count += 1 + continue + + prline = "- " + body + " ([#" + pr_num + "](" + HTML_URL + pr_num + "))" + detail = "- " + pr["merged_by"]["login"] + "@ " + prline + prline = prline.encode('ascii', 'ignore') + detail = detail.encode('ascii', 'ignore') + print(detail) + #if no RL label + if not rl_no_found and not rl_yes_found: + print("Release notes label missing for " + pr_num) + langs_pr["nolabel"].append(detail) + elif rl_yes_found and not lang_found: + print("Lang label missing for " + pr_num) + langs_pr["nolang"].append(detail) + elif rl_no_found: + print("'Release notes:no' found for " + pr_num) + langs_pr["notinrel"].append(detail) + elif rl_yes_found: + print("'Release notes:yes' found for " + pr_num + " with lang " + + lang) + langs_pr["inrel"].append(detail) + langs_pr[lang].append(prline) + + return langs_pr, error_count + + +def write_draft(langs_pr, file, version, date): + file.write(content_header.format(version=version, date=date)) + file.write("PRs with missing release notes label - please fix in Github\n") + file.write("---\n") + file.write("\n") + if langs_pr["nolabel"]: + langs_pr["nolabel"].sort() + file.write("\n".join(langs_pr["nolabel"])) + else: + file.write("- None") + file.write("\n") + file.write("\n") + file.write("PRs with missing lang label - please fix in Github\n") + file.write("---\n") + file.write("\n") + if langs_pr["nolang"]: + langs_pr["nolang"].sort() + file.write("\n".join(langs_pr["nolang"])) + else: + file.write("- None") + file.write("\n") + file.write("\n") + file.write( + "PRs going into release notes - please check title and fix in Github. Do not edit here.\n" + ) + file.write("---\n") + file.write("\n") + if langs_pr["inrel"]: + langs_pr["inrel"].sort() + file.write("\n".join(langs_pr["inrel"])) + else: + file.write("- None") + file.write("\n") + file.write("\n") + file.write("PRs not going into release notes\n") + file.write("---\n") + file.write("\n") + if langs_pr["notinrel"]: + langs_pr["notinrel"].sort() + file.write("\n".join(langs_pr["notinrel"])) + else: + file.write("- None") + file.write("\n") + file.write("\n") + + +def write_rel_notes(langs_pr, file, version, name): + file.write(rl_header.format(version=version, name=name)) + if langs_pr["core"]: + file.write("Core\n---\n\n") + file.write("\n".join(langs_pr["core"])) + file.write("\n") + file.write("\n") + if langs_pr["c++"]: + file.write("C++\n---\n\n") + file.write("\n".join(langs_pr["c++"])) + file.write("\n") + file.write("\n") + if langs_pr["c#"]: + file.write("C#\n---\n\n") + file.write("\n".join(langs_pr["c#"])) + file.write("\n") + file.write("\n") + if langs_pr["go"]: + file.write("Go\n---\n\n") + file.write("\n".join(langs_pr["go"])) + file.write("\n") + file.write("\n") + if langs_pr["Java"]: + file.write("Java\n---\n\n") + file.write("\n".join(langs_pr["Java"])) + file.write("\n") + file.write("\n") + if langs_pr["node"]: + file.write("Node\n---\n\n") + file.write("\n".join(langs_pr["node"])) + file.write("\n") + file.write("\n") + if langs_pr["objc"]: + file.write("Objective-C\n---\n\n") + file.write("\n".join(langs_pr["objc"])) + file.write("\n") + file.write("\n") + if langs_pr["php"]: + file.write("PHP\n---\n\n") + file.write("\n".join(langs_pr["php"])) + file.write("\n") + file.write("\n") + if langs_pr["python"]: + file.write("Python\n---\n\n") + file.write("\n".join(langs_pr["python"])) + file.write("\n") + file.write("\n") + if langs_pr["ruby"]: + file.write("Ruby\n---\n\n") + file.write("\n".join(langs_pr["ruby"])) + file.write("\n") + file.write("\n") + if langs_pr["other"]: + file.write("Other\n---\n\n") + file.write("\n".join(langs_pr["other"])) + file.write("\n") + file.write("\n") + + +def build_args_parser(): + import argparse + parser = argparse.ArgumentParser() + parser.add_argument( + 'release_version', type=str, help='New release version e.g. 1.14.0') + parser.add_argument( + 'release_name', type=str, help='New release name e.g. gladiolus') + parser.add_argument( + 'release_date', type=str, help='Release date e.g. 7/30/18') + parser.add_argument( + 'previous_release_label', + type=str, + help='Previous release branch/tag e.g. v1.13.x') + parser.add_argument( + 'release_branch', + type=str, + help='Current release branch e.g. origin/v1.14.x') + parser.add_argument( + 'draft_filename', type=str, help='Name of the draft file e.g. draft.md') + parser.add_argument( + 'release_notes_filename', + type=str, + help='Name of the release notes file e.g. relnotes.md') + parser.add_argument( + '--token', + type=str, + default='', + help='GitHub API token to avoid being rate limited') + return parser + + +def main(): + import os + global TOKEN + + parser = build_args_parser() + args = parser.parse_args() + version, name, date = args.release_version, args.release_name, args.release_date + start, end = args.previous_release_label, args.release_branch + + TOKEN = args.token + if TOKEN == '': + try: + TOKEN = os.environ["GITHUB_TOKEN"] + except: + pass + if TOKEN == '': + print( + "Error: Github API token required. Either include param --token= or set environment variable GITHUB_TOKEN to your github token" + ) + return + + langs_pr, error_count = get_pr_titles(get_commit_log(start, end)) + + draft_file, rel_file = args.draft_filename, args.release_notes_filename + filename = os.path.abspath(draft_file) + if os.path.exists(filename): + file = open(filename, 'r+') + else: + file = open(filename, 'w') + + file.seek(0) + write_draft(langs_pr, file, version, date) + file.truncate() + file.close() + print("\nDraft notes written to " + filename) + + filename = os.path.abspath(rel_file) + if os.path.exists(filename): + file = open(filename, 'r+') + else: + file = open(filename, 'w') + + file.seek(0) + write_rel_notes(langs_pr, file, version, name) + file.truncate() + file.close() + print("\nRelease notes written to " + filename) + if error_count > 0: + print("\n\n*** Errors were encountered. See log. *********\n") + + +if __name__ == "__main__": + main() From 4ac28e61f9d0d22104103bfd55ea0b4dc7be5e04 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 3 Apr 2019 12:34:53 -0700 Subject: [PATCH 1739/2143] backport #18606 - Add a dummy function to grpc cfstream library --- src/core/lib/iomgr/cfstream_handle.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index cf21c4fc511..2fda160f68a 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -192,4 +192,11 @@ void CFStreamHandle::Unref(const char* file, int line, const char* reason) { } } +#else + +/* Creating a dummy function so that the grpc_cfstream library will be + * non-empty. + */ +void CFStreamDummy() {} + #endif From ebf4cc1dfa7e9715af795233655777ddfd17e952 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 3 Apr 2019 12:48:27 -0700 Subject: [PATCH 1740/2143] Avoid crash in pick_first when invoking ExitIdleLocked() after shutdown. --- .../filters/client_channel/lb_policy/pick_first/pick_first.cc | 1 + 1 file changed, 1 insertion(+) 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 3da0b59f279..332f66808e0 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 @@ -186,6 +186,7 @@ void PickFirst::ShutdownLocked() { } void PickFirst::ExitIdleLocked() { + if (shutdown_) return; if (idle_) { idle_ = false; if (subchannel_list_ == nullptr || From f97b47c87c08b53f3ed52ce49eb1aabc073fd5d5 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 3 Apr 2019 21:59:42 +0200 Subject: [PATCH 1741/2143] Backports of 18445 and 18517. --- .../health/health_check_client.cc | 4 --- .../google_default_credentials.cc | 1 - src/core/lib/transport/transport.cc | 16 +++++++----- src/core/lib/transport/transport.h | 26 +++++++++---------- 4 files changed, 22 insertions(+), 25 deletions(-) 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..84a7f35ed30 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 @@ -349,7 +349,6 @@ void HealthCheckClient::CallState::StartCall() { return; } // Initialize payload and batch. - memset(&batch_, 0, sizeof(batch_)); payload_.context = context_; batch_.payload = &payload_; // on_complete callback takes ref, handled manually. @@ -401,8 +400,6 @@ void HealthCheckClient::CallState::StartCall() { // Start batch. StartBatch(&batch_); // Initialize recv_trailing_metadata batch. - memset(&recv_trailing_metadata_batch_, 0, - sizeof(recv_trailing_metadata_batch_)); recv_trailing_metadata_batch_.payload = &payload_; // Add recv_trailing_metadata op. grpc_metadata_batch_init(&recv_trailing_metadata_); @@ -507,7 +504,6 @@ void HealthCheckClient::CallState::DoneReadingRecvMessage(grpc_error* error) { // This re-uses the ref we're holding. // Note: Can't just reuse batch_ here, since we don't know that all // callbacks from the original batch have completed yet. - memset(&recv_message_batch_, 0, sizeof(recv_message_batch_)); recv_message_batch_.payload = &payload_; payload_.recv_message.recv_message = &recv_message_; payload_.recv_message.recv_message_ready = GRPC_CLOSURE_INIT( 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 b6a79c1030e..adc76cb1740 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 @@ -172,7 +172,6 @@ static int is_metadata_server_reachable() { detector.pollent = grpc_polling_entity_create_from_pollset(pollset); detector.is_done = 0; detector.success = 0; - memset(&detector.response, 0, sizeof(detector.response)); memset(&request, 0, sizeof(grpc_httpcli_request)); request.host = (char*)GRPC_COMPUTE_ENGINE_DETECTION_HOST; request.http.path = (char*)"/"; diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index 8be0b91b654..09306110c63 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -29,6 +29,7 @@ #include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/slice/slice_internal.h" @@ -243,25 +244,26 @@ void grpc_transport_stream_op_batch_finish_with_failure( GRPC_ERROR_UNREF(error); } -typedef struct { +struct made_transport_op { grpc_closure outer_on_complete; - grpc_closure* inner_on_complete; + grpc_closure* inner_on_complete = nullptr; grpc_transport_op op; -} made_transport_op; + made_transport_op() { + memset(&outer_on_complete, 0, sizeof(outer_on_complete)); + } +}; static void destroy_made_transport_op(void* arg, grpc_error* error) { made_transport_op* op = static_cast(arg); GRPC_CLOSURE_SCHED(op->inner_on_complete, GRPC_ERROR_REF(error)); - gpr_free(op); + grpc_core::Delete(op); } grpc_transport_op* grpc_make_transport_op(grpc_closure* on_complete) { - made_transport_op* op = - static_cast(gpr_malloc(sizeof(*op))); + made_transport_op* op = grpc_core::New(); GRPC_CLOSURE_INIT(&op->outer_on_complete, destroy_made_transport_op, op, grpc_schedule_on_exec_ctx); op->inner_on_complete = on_complete; - memset(&op->op, 0, sizeof(op->op)); op->op.on_consumed = &op->outer_on_complete; return &op->op; } diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 9d4b5615e57..8631a1af81f 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -273,40 +273,40 @@ struct grpc_transport_stream_op_batch_payload { /** Transport op: a set of operations to perform on a transport as a whole */ typedef struct grpc_transport_op { /** Called when processing of this op is done. */ - grpc_closure* on_consumed; + grpc_closure* on_consumed = nullptr; /** connectivity monitoring - set connectivity_state to NULL to unsubscribe */ - grpc_closure* on_connectivity_state_change; - grpc_connectivity_state* connectivity_state; + grpc_closure* on_connectivity_state_change = nullptr; + grpc_connectivity_state* connectivity_state = nullptr; /** should the transport be disconnected * Error contract: the transport that gets this op must cause * disconnect_with_error to be unref'ed after processing it */ - grpc_error* disconnect_with_error; + grpc_error* disconnect_with_error = nullptr; /** what should the goaway contain? * Error contract: the transport that gets this op must cause * goaway_error to be unref'ed after processing it */ - grpc_error* goaway_error; + grpc_error* goaway_error = nullptr; /** set the callback for accepting new streams; this is a permanent callback, unlike the other one-shot closures. If true, the callback is set to set_accept_stream_fn, with its user_data argument set to set_accept_stream_user_data */ - bool set_accept_stream; + bool set_accept_stream = false; void (*set_accept_stream_fn)(void* user_data, grpc_transport* transport, - const void* server_data); - void* set_accept_stream_user_data; + const void* server_data) = nullptr; + void* set_accept_stream_user_data = nullptr; /** add this transport to a pollset */ - grpc_pollset* bind_pollset; + grpc_pollset* bind_pollset = nullptr; /** add this transport to a pollset_set */ - grpc_pollset_set* bind_pollset_set; + grpc_pollset_set* bind_pollset_set = nullptr; /** send a ping, if either on_initiate or on_ack is not NULL */ struct { /** Ping may be delayed by the transport, on_initiate callback will be called when the ping is actually being sent. */ - grpc_closure* on_initiate; + grpc_closure* on_initiate = nullptr; /** Called when the ping ack is received */ - grpc_closure* on_ack; + grpc_closure* on_ack = nullptr; } send_ping; // If true, will reset the channel's connection backoff. - bool reset_connect_backoff; + bool reset_connect_backoff = false; /*************************************************************************** * remaining fields are initialized and used at the discretion of the From eccfecd6a6dc0fe7b2411e00840c95a1c24122e6 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 3 Apr 2019 09:56:11 -0700 Subject: [PATCH 1742/2143] Move functions for individual args out of channel_args.{h,cc}. --- BUILD | 2 + BUILD.gn | 3 + CMakeLists.txt | 6 + Makefile | 6 + build.yaml | 2 + config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 2 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + grpc.gyp | 4 + package.xml | 2 + .../message_compress_filter.cc | 1 + src/core/lib/channel/channel_args.cc | 101 -------------- src/core/lib/channel/channel_args.h | 37 ----- src/core/lib/compression/compression_args.cc | 127 ++++++++++++++++++ src/core/lib/compression/compression_args.h | 55 ++++++++ src/python/grpcio/grpc_core_dependencies.py | 1 + test/core/channel/channel_args_test.cc | 93 ------------- test/core/compression/compression_test.cc | 79 +++++++++++ test/core/end2end/fixtures/h2_compress.cc | 1 + test/core/end2end/tests/compressed_payload.cc | 1 + .../stream_compression_compressed_payload.cc | 1 + .../tests/stream_compression_payload.cc | 1 + .../stream_compression_ping_pong_streaming.cc | 1 + .../tests/workaround_cronet_compression.cc | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 3 + 29 files changed, 309 insertions(+), 231 deletions(-) create mode 100644 src/core/lib/compression/compression_args.cc create mode 100644 src/core/lib/compression/compression_args.h diff --git a/BUILD b/BUILD index 003914a3c5f..f9c57e7df5f 100644 --- a/BUILD +++ b/BUILD @@ -719,6 +719,7 @@ grpc_cc_library( "src/core/lib/channel/handshaker_registry.cc", "src/core/lib/channel/status_util.cc", "src/core/lib/compression/compression.cc", + "src/core/lib/compression/compression_args.cc", "src/core/lib/compression/compression_internal.cc", "src/core/lib/compression/message_compress.cc", "src/core/lib/compression/stream_compression.cc", @@ -874,6 +875,7 @@ grpc_cc_library( "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_args.h", "src/core/lib/compression/compression_internal.h", "src/core/lib/compression/message_compress.h", "src/core/lib/compression/stream_compression.h", diff --git a/BUILD.gn b/BUILD.gn index 7ceea3c3b63..06a1929e714 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -445,6 +445,8 @@ config("grpc_config") { "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_args.cc", + "src/core/lib/compression/compression_args.h", "src/core/lib/compression/compression_internal.cc", "src/core/lib/compression/compression_internal.h", "src/core/lib/compression/message_compress.cc", @@ -1121,6 +1123,7 @@ config("grpc_config") { "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_args.h", "src/core/lib/compression/compression_internal.h", "src/core/lib/compression/message_compress.h", "src/core/lib/compression/stream_compression.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f45bd16eea..34a3b7c1e18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -981,6 +981,7 @@ add_library(grpc src/core/lib/channel/handshaker_registry.cc src/core/lib/channel/status_util.cc src/core/lib/compression/compression.cc + src/core/lib/compression/compression_args.cc src/core/lib/compression/compression_internal.cc src/core/lib/compression/message_compress.cc src/core/lib/compression/stream_compression.cc @@ -1407,6 +1408,7 @@ add_library(grpc_cronet src/core/lib/channel/handshaker_registry.cc src/core/lib/channel/status_util.cc src/core/lib/compression/compression.cc + src/core/lib/compression/compression_args.cc src/core/lib/compression/compression_internal.cc src/core/lib/compression/message_compress.cc src/core/lib/compression/stream_compression.cc @@ -1818,6 +1820,7 @@ add_library(grpc_test_util src/core/lib/channel/handshaker_registry.cc src/core/lib/channel/status_util.cc src/core/lib/compression/compression.cc + src/core/lib/compression/compression_args.cc src/core/lib/compression/compression_internal.cc src/core/lib/compression/message_compress.cc src/core/lib/compression/stream_compression.cc @@ -2142,6 +2145,7 @@ add_library(grpc_test_util_unsecure src/core/lib/channel/handshaker_registry.cc src/core/lib/channel/status_util.cc src/core/lib/compression/compression.cc + src/core/lib/compression/compression_args.cc src/core/lib/compression/compression_internal.cc src/core/lib/compression/message_compress.cc src/core/lib/compression/stream_compression.cc @@ -2442,6 +2446,7 @@ add_library(grpc_unsecure src/core/lib/channel/handshaker_registry.cc src/core/lib/channel/status_util.cc src/core/lib/compression/compression.cc + src/core/lib/compression/compression_args.cc src/core/lib/compression/compression_internal.cc src/core/lib/compression/message_compress.cc src/core/lib/compression/stream_compression.cc @@ -3335,6 +3340,7 @@ add_library(grpc++_cronet src/core/lib/channel/handshaker_registry.cc src/core/lib/channel/status_util.cc src/core/lib/compression/compression.cc + src/core/lib/compression/compression_args.cc src/core/lib/compression/compression_internal.cc src/core/lib/compression/message_compress.cc src/core/lib/compression/stream_compression.cc diff --git a/Makefile b/Makefile index 14fb8d5f7bd..6e33a13c625 100644 --- a/Makefile +++ b/Makefile @@ -3432,6 +3432,7 @@ LIBGRPC_SRC = \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ + src/core/lib/compression/compression_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ @@ -3852,6 +3853,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ + src/core/lib/compression/compression_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ @@ -4256,6 +4258,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ + src/core/lib/compression/compression_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ @@ -4567,6 +4570,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ + src/core/lib/compression/compression_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ @@ -4841,6 +4845,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ + src/core/lib/compression/compression_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ @@ -5710,6 +5715,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ + src/core/lib/compression/compression_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ diff --git a/build.yaml b/build.yaml index 7dbedb7c1cf..20d21df4157 100644 --- a/build.yaml +++ b/build.yaml @@ -245,6 +245,7 @@ filegroups: - src/core/lib/channel/handshaker_registry.cc - src/core/lib/channel/status_util.cc - src/core/lib/compression/compression.cc + - src/core/lib/compression/compression_args.cc - src/core/lib/compression/compression_internal.cc - src/core/lib/compression/message_compress.cc - src/core/lib/compression/stream_compression.cc @@ -418,6 +419,7 @@ filegroups: - 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_args.h - src/core/lib/compression/compression_internal.h - src/core/lib/compression/message_compress.h - src/core/lib/compression/stream_compression.h diff --git a/config.m4 b/config.m4 index 2c64a3eb168..ab2a717cbcd 100644 --- a/config.m4 +++ b/config.m4 @@ -97,6 +97,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ + src/core/lib/compression/compression_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ diff --git a/config.w32 b/config.w32 index 6897c1041ac..02eb773ebb8 100644 --- a/config.w32 +++ b/config.w32 @@ -72,6 +72,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\channel\\handshaker_registry.cc " + "src\\core\\lib\\channel\\status_util.cc " + "src\\core\\lib\\compression\\compression.cc " + + "src\\core\\lib\\compression\\compression_args.cc " + "src\\core\\lib\\compression\\compression_internal.cc " + "src\\core\\lib\\compression\\message_compress.cc " + "src\\core\\lib\\compression\\stream_compression.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index ea1c700fc4d..879bfe562ff 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -405,6 +405,7 @@ Pod::Spec.new do |s| '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_args.h', 'src/core/lib/compression/compression_internal.h', 'src/core/lib/compression/message_compress.h', 'src/core/lib/compression/stream_compression.h', @@ -597,6 +598,7 @@ Pod::Spec.new do |s| '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_args.h', 'src/core/lib/compression/compression_internal.h', 'src/core/lib/compression/message_compress.h', 'src/core/lib/compression/stream_compression.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index bab7ce4378e..b54ec902f92 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -393,6 +393,7 @@ Pod::Spec.new do |s| '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_args.h', 'src/core/lib/compression/compression_internal.h', 'src/core/lib/compression/message_compress.h', 'src/core/lib/compression/stream_compression.h', @@ -547,6 +548,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/handshaker_registry.cc', 'src/core/lib/channel/status_util.cc', 'src/core/lib/compression/compression.cc', + 'src/core/lib/compression/compression_args.cc', 'src/core/lib/compression/compression_internal.cc', 'src/core/lib/compression/message_compress.cc', 'src/core/lib/compression/stream_compression.cc', @@ -1033,6 +1035,7 @@ Pod::Spec.new do |s| '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_args.h', 'src/core/lib/compression/compression_internal.h', 'src/core/lib/compression/message_compress.h', 'src/core/lib/compression/stream_compression.h', diff --git a/grpc.gemspec b/grpc.gemspec index c128d07eaf8..42bb31de8a3 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -327,6 +327,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/channel/handshaker_registry.h ) s.files += %w( src/core/lib/channel/status_util.h ) s.files += %w( src/core/lib/compression/algorithm_metadata.h ) + s.files += %w( src/core/lib/compression/compression_args.h ) s.files += %w( src/core/lib/compression/compression_internal.h ) s.files += %w( src/core/lib/compression/message_compress.h ) s.files += %w( src/core/lib/compression/stream_compression.h ) @@ -481,6 +482,7 @@ Gem::Specification.new do |s| 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 ) + s.files += %w( src/core/lib/compression/compression_args.cc ) s.files += %w( src/core/lib/compression/compression_internal.cc ) s.files += %w( src/core/lib/compression/message_compress.cc ) s.files += %w( src/core/lib/compression/stream_compression.cc ) diff --git a/grpc.gyp b/grpc.gyp index 322259d2ca7..40dc88d7474 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -279,6 +279,7 @@ 'src/core/lib/channel/handshaker_registry.cc', 'src/core/lib/channel/status_util.cc', 'src/core/lib/compression/compression.cc', + 'src/core/lib/compression/compression_args.cc', 'src/core/lib/compression/compression_internal.cc', 'src/core/lib/compression/message_compress.cc', 'src/core/lib/compression/stream_compression.cc', @@ -646,6 +647,7 @@ 'src/core/lib/channel/handshaker_registry.cc', 'src/core/lib/channel/status_util.cc', 'src/core/lib/compression/compression.cc', + 'src/core/lib/compression/compression_args.cc', 'src/core/lib/compression/compression_internal.cc', 'src/core/lib/compression/message_compress.cc', 'src/core/lib/compression/stream_compression.cc', @@ -890,6 +892,7 @@ 'src/core/lib/channel/handshaker_registry.cc', 'src/core/lib/channel/status_util.cc', 'src/core/lib/compression/compression.cc', + 'src/core/lib/compression/compression_args.cc', 'src/core/lib/compression/compression_internal.cc', 'src/core/lib/compression/message_compress.cc', 'src/core/lib/compression/stream_compression.cc', @@ -1110,6 +1113,7 @@ 'src/core/lib/channel/handshaker_registry.cc', 'src/core/lib/channel/status_util.cc', 'src/core/lib/compression/compression.cc', + 'src/core/lib/compression/compression_args.cc', 'src/core/lib/compression/compression_internal.cc', 'src/core/lib/compression/message_compress.cc', 'src/core/lib/compression/stream_compression.cc', diff --git a/package.xml b/package.xml index f3bbb449ac5..1f08eaf4a20 100644 --- a/package.xml +++ b/package.xml @@ -332,6 +332,7 @@ + @@ -486,6 +487,7 @@ + diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.cc b/src/core/ext/filters/http/message_compress/message_compress_filter.cc index 9c8c8d9e188..1527ea440c4 100644 --- a/src/core/ext/filters/http/message_compress/message_compress_filter.cc +++ b/src/core/ext/filters/http/message_compress/message_compress_filter.cc @@ -29,6 +29,7 @@ #include "src/core/ext/filters/http/message_compress/message_compress_filter.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/compression/algorithm_metadata.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/compression/compression_internal.h" #include "src/core/lib/compression/message_compress.h" #include "src/core/lib/gpr/string.h" diff --git a/src/core/lib/channel/channel_args.cc b/src/core/lib/channel/channel_args.cc index 2d9a1bc67cd..a35db186a30 100644 --- a/src/core/lib/channel/channel_args.cc +++ b/src/core/lib/channel/channel_args.cc @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -213,106 +212,6 @@ void grpc_channel_args_destroy(grpc_channel_args* a) { gpr_free(a); } -grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( - const grpc_channel_args* a) { - size_t i; - if (a == nullptr) return GRPC_COMPRESS_NONE; - for (i = 0; i < a->num_args; ++i) { - if (a->args[i].type == GRPC_ARG_INTEGER && - !strcmp(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, a->args[i].key)) { - return static_cast(a->args[i].value.integer); - break; - } - } - return GRPC_COMPRESS_NONE; -} - -grpc_channel_args* grpc_channel_args_set_compression_algorithm( - grpc_channel_args* a, grpc_compression_algorithm algorithm) { - GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT); - grpc_arg tmp; - tmp.type = GRPC_ARG_INTEGER; - tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM; - tmp.value.integer = algorithm; - return grpc_channel_args_copy_and_add(a, &tmp, 1); -} - -/** Returns 1 if the argument for compression algorithm's enabled states bitset - * was found in \a a, returning the arg's value in \a states. Otherwise, returns - * 0. */ -static int find_compression_algorithm_states_bitset(const grpc_channel_args* a, - int** states_arg) { - if (a != nullptr) { - size_t i; - for (i = 0; i < a->num_args; ++i) { - if (a->args[i].type == GRPC_ARG_INTEGER && - !strcmp(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET, - a->args[i].key)) { - *states_arg = &a->args[i].value.integer; - **states_arg |= 0x1; /* forcefully enable support for no compression */ - return 1; - } - } - } - return 0; /* GPR_FALSE */ -} - -grpc_channel_args* grpc_channel_args_compression_algorithm_set_state( - grpc_channel_args** a, grpc_compression_algorithm algorithm, int state) { - int* states_arg = nullptr; - grpc_channel_args* result = *a; - const int states_arg_found = - find_compression_algorithm_states_bitset(*a, &states_arg); - - if (grpc_channel_args_get_compression_algorithm(*a) == algorithm && - state == 0) { - const char* algo_name = nullptr; - GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algo_name) != 0); - gpr_log(GPR_ERROR, - "Tried to disable default compression algorithm '%s'. The " - "operation has been ignored.", - algo_name); - } else if (states_arg_found) { - if (state != 0) { - GPR_BITSET((unsigned*)states_arg, algorithm); - } else if (algorithm != GRPC_COMPRESS_NONE) { - GPR_BITCLEAR((unsigned*)states_arg, algorithm); - } - } else { - /* create a new arg */ - grpc_arg tmp; - tmp.type = GRPC_ARG_INTEGER; - tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET; - /* all enabled by default */ - tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; - if (state != 0) { - GPR_BITSET((unsigned*)&tmp.value.integer, algorithm); - } else if (algorithm != GRPC_COMPRESS_NONE) { - GPR_BITCLEAR((unsigned*)&tmp.value.integer, algorithm); - } - result = grpc_channel_args_copy_and_add(*a, &tmp, 1); - grpc_channel_args_destroy(*a); - *a = result; - } - return result; -} - -uint32_t grpc_channel_args_compression_algorithm_get_states( - const grpc_channel_args* a) { - int* states_arg; - if (find_compression_algorithm_states_bitset(a, &states_arg)) { - return static_cast(*states_arg); - } else { - return (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; /* All algs. enabled */ - } -} - -grpc_channel_args* grpc_channel_args_set_socket_mutator( - grpc_channel_args* a, grpc_socket_mutator* mutator) { - grpc_arg tmp = grpc_socket_mutator_to_arg(mutator); - return grpc_channel_args_copy_and_add(a, &tmp, 1); -} - int grpc_channel_args_compare(const grpc_channel_args* a, const grpc_channel_args* b) { int c = GPR_ICMP(a->num_args, b->num_args); diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h index c47c027b379..2b698a66cfb 100644 --- a/src/core/lib/channel/channel_args.h +++ b/src/core/lib/channel/channel_args.h @@ -21,9 +21,7 @@ #include -#include #include -#include "src/core/lib/iomgr/socket_mutator.h" // Channel args are intentionally immutable, to avoid the need for locking. @@ -60,44 +58,9 @@ 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( - const grpc_channel_args* a); - -/** Returns a channel arg instance with compression enabled. If \a a is - * non-NULL, its args are copied. N.B. GRPC_COMPRESS_NONE disables compression - * for the channel. */ -grpc_channel_args* grpc_channel_args_set_compression_algorithm( - grpc_channel_args* a, grpc_compression_algorithm algorithm); - -/** Sets the support for the given compression algorithm. By default, all - * compression algorithms are enabled. It's an error to disable an algorithm set - * by grpc_channel_args_set_compression_algorithm. - * - * Returns an instance with the updated algorithm states. The \a a pointer is - * modified to point to the returned instance (which may be different from the - * input value of \a a). */ -grpc_channel_args* grpc_channel_args_compression_algorithm_set_state( - grpc_channel_args** a, grpc_compression_algorithm algorithm, int enabled); - -/** Returns the bitset representing the support state (true for enabled, false - * for disabled) for compression algorithms. - * - * The i-th bit of the returned bitset corresponds to the i-th entry in the - * grpc_compression_algorithm enum. */ -uint32_t grpc_channel_args_compression_algorithm_get_states( - const grpc_channel_args* a); - int grpc_channel_args_compare(const grpc_channel_args* a, const grpc_channel_args* b); -/** Returns a channel arg instance with socket mutator added. The socket mutator - * will perform its mutate_fd method on all file descriptors used by the - * channel. - * If \a a is non-MULL, its args are copied. */ -grpc_channel_args* grpc_channel_args_set_socket_mutator( - grpc_channel_args* a, grpc_socket_mutator* mutator); - /** Returns the value of argument \a name from \a args, or NULL if not found. */ const grpc_arg* grpc_channel_args_find(const grpc_channel_args* args, const char* name); diff --git a/src/core/lib/compression/compression_args.cc b/src/core/lib/compression/compression_args.cc new file mode 100644 index 00000000000..6a8232dc033 --- /dev/null +++ b/src/core/lib/compression/compression_args.cc @@ -0,0 +1,127 @@ +/* + * + * 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 +#include + +#include +#include +#include +#include +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" + +grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( + const grpc_channel_args* a) { + size_t i; + if (a == nullptr) return GRPC_COMPRESS_NONE; + for (i = 0; i < a->num_args; ++i) { + if (a->args[i].type == GRPC_ARG_INTEGER && + !strcmp(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, a->args[i].key)) { + return static_cast(a->args[i].value.integer); + break; + } + } + return GRPC_COMPRESS_NONE; +} + +grpc_channel_args* grpc_channel_args_set_compression_algorithm( + grpc_channel_args* a, grpc_compression_algorithm algorithm) { + GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT); + grpc_arg tmp; + tmp.type = GRPC_ARG_INTEGER; + tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM; + tmp.value.integer = algorithm; + return grpc_channel_args_copy_and_add(a, &tmp, 1); +} + +/** Returns 1 if the argument for compression algorithm's enabled states bitset + * was found in \a a, returning the arg's value in \a states. Otherwise, returns + * 0. */ +static int find_compression_algorithm_states_bitset(const grpc_channel_args* a, + int** states_arg) { + if (a != nullptr) { + size_t i; + for (i = 0; i < a->num_args; ++i) { + if (a->args[i].type == GRPC_ARG_INTEGER && + !strcmp(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET, + a->args[i].key)) { + *states_arg = &a->args[i].value.integer; + **states_arg |= 0x1; /* forcefully enable support for no compression */ + return 1; + } + } + } + return 0; /* GPR_FALSE */ +} + +grpc_channel_args* grpc_channel_args_compression_algorithm_set_state( + grpc_channel_args** a, grpc_compression_algorithm algorithm, int state) { + int* states_arg = nullptr; + grpc_channel_args* result = *a; + const int states_arg_found = + find_compression_algorithm_states_bitset(*a, &states_arg); + + if (grpc_channel_args_get_compression_algorithm(*a) == algorithm && + state == 0) { + const char* algo_name = nullptr; + GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algo_name) != 0); + gpr_log(GPR_ERROR, + "Tried to disable default compression algorithm '%s'. The " + "operation has been ignored.", + algo_name); + } else if (states_arg_found) { + if (state != 0) { + GPR_BITSET((unsigned*)states_arg, algorithm); + } else if (algorithm != GRPC_COMPRESS_NONE) { + GPR_BITCLEAR((unsigned*)states_arg, algorithm); + } + } else { + /* create a new arg */ + grpc_arg tmp; + tmp.type = GRPC_ARG_INTEGER; + tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET; + /* all enabled by default */ + tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; + if (state != 0) { + GPR_BITSET((unsigned*)&tmp.value.integer, algorithm); + } else if (algorithm != GRPC_COMPRESS_NONE) { + GPR_BITCLEAR((unsigned*)&tmp.value.integer, algorithm); + } + result = grpc_channel_args_copy_and_add(*a, &tmp, 1); + grpc_channel_args_destroy(*a); + *a = result; + } + return result; +} + +uint32_t grpc_channel_args_compression_algorithm_get_states( + const grpc_channel_args* a) { + int* states_arg; + if (find_compression_algorithm_states_bitset(a, &states_arg)) { + return static_cast(*states_arg); + } else { + return (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; /* All algs. enabled */ + } +} diff --git a/src/core/lib/compression/compression_args.h b/src/core/lib/compression/compression_args.h new file mode 100644 index 00000000000..75084ab0d91 --- /dev/null +++ b/src/core/lib/compression/compression_args.h @@ -0,0 +1,55 @@ +/* + * + * 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 GRPC_CORE_LIB_COMPRESSION_COMPRESSION_ARGS_H +#define GRPC_CORE_LIB_COMPRESSION_COMPRESSION_ARGS_H + +#include + +#include +#include + +/** Returns the compression algorithm set in \a a. */ +grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( + const grpc_channel_args* a); + +/** Returns a channel arg instance with compression enabled. If \a a is + * non-NULL, its args are copied. N.B. GRPC_COMPRESS_NONE disables compression + * for the channel. */ +grpc_channel_args* grpc_channel_args_set_compression_algorithm( + grpc_channel_args* a, grpc_compression_algorithm algorithm); + +/** Sets the support for the given compression algorithm. By default, all + * compression algorithms are enabled. It's an error to disable an algorithm set + * by grpc_channel_args_set_compression_algorithm. + * + * Returns an instance with the updated algorithm states. The \a a pointer is + * modified to point to the returned instance (which may be different from the + * input value of \a a). */ +grpc_channel_args* grpc_channel_args_compression_algorithm_set_state( + grpc_channel_args** a, grpc_compression_algorithm algorithm, int enabled); + +/** Returns the bitset representing the support state (true for enabled, false + * for disabled) for compression algorithms. + * + * The i-th bit of the returned bitset corresponds to the i-th entry in the + * grpc_compression_algorithm enum. */ +uint32_t grpc_channel_args_compression_algorithm_get_states( + const grpc_channel_args* a); + +#endif /* GRPC_CORE_LIB_COMPRESSION_COMPRESSION_ARGS_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 21efd682871..12a47e71d7e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -71,6 +71,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/channel/handshaker_registry.cc', 'src/core/lib/channel/status_util.cc', 'src/core/lib/compression/compression.cc', + 'src/core/lib/compression/compression_args.cc', 'src/core/lib/compression/compression_internal.cc', 'src/core/lib/compression/message_compress.cc', 'src/core/lib/compression/stream_compression.cc', diff --git a/test/core/channel/channel_args_test.cc b/test/core/channel/channel_args_test.cc index 087a7679bf8..9c47d5dd922 100644 --- a/test/core/channel/channel_args_test.cc +++ b/test/core/channel/channel_args_test.cc @@ -58,96 +58,6 @@ static void test_create(void) { grpc_channel_args_destroy(ch_args); } -static void test_set_compression_algorithm(void) { - grpc_core::ExecCtx exec_ctx; - grpc_channel_args* ch_args; - - ch_args = - grpc_channel_args_set_compression_algorithm(nullptr, GRPC_COMPRESS_GZIP); - GPR_ASSERT(ch_args->num_args == 1); - GPR_ASSERT(strcmp(ch_args->args[0].key, - GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM) == 0); - GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_INTEGER); - - grpc_channel_args_destroy(ch_args); -} - -static void test_compression_algorithm_states(void) { - grpc_core::ExecCtx exec_ctx; - grpc_channel_args *ch_args, *ch_args_wo_gzip, *ch_args_wo_gzip_deflate, - *ch_args_wo_gzip_deflate_gzip; - unsigned states_bitset; - size_t i; - - ch_args = grpc_channel_args_copy_and_add(nullptr, nullptr, 0); - /* by default, all enabled */ - states_bitset = static_cast( - grpc_channel_args_compression_algorithm_get_states(ch_args)); - - for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { - GPR_ASSERT(GPR_BITGET(states_bitset, i)); - } - - /* disable gzip and deflate and stream/gzip */ - ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( - &ch_args, GRPC_COMPRESS_GZIP, 0); - GPR_ASSERT(ch_args == ch_args_wo_gzip); - ch_args_wo_gzip_deflate = grpc_channel_args_compression_algorithm_set_state( - &ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0); - GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate); - ch_args_wo_gzip_deflate_gzip = - grpc_channel_args_compression_algorithm_set_state( - &ch_args_wo_gzip_deflate, GRPC_COMPRESS_STREAM_GZIP, 0); - GPR_ASSERT(ch_args_wo_gzip_deflate == ch_args_wo_gzip_deflate_gzip); - - states_bitset = - static_cast(grpc_channel_args_compression_algorithm_get_states( - ch_args_wo_gzip_deflate)); - for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { - if (i == GRPC_COMPRESS_GZIP || i == GRPC_COMPRESS_DEFLATE || - i == GRPC_COMPRESS_STREAM_GZIP) { - GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0); - } else { - GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0); - } - } - - /* re-enabled gzip and stream/gzip only */ - ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( - &ch_args_wo_gzip_deflate_gzip, GRPC_COMPRESS_GZIP, 1); - ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( - &ch_args_wo_gzip, GRPC_COMPRESS_STREAM_GZIP, 1); - GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate_gzip); - - states_bitset = static_cast( - grpc_channel_args_compression_algorithm_get_states(ch_args_wo_gzip)); - for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { - if (i == GRPC_COMPRESS_DEFLATE) { - GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0); - } else { - GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0); - } - } - - grpc_channel_args_destroy(ch_args); -} - -static void test_set_socket_mutator(void) { - grpc_channel_args* ch_args; - grpc_socket_mutator mutator; - grpc_socket_mutator_init(&mutator, nullptr); - - ch_args = grpc_channel_args_set_socket_mutator(nullptr, &mutator); - GPR_ASSERT(ch_args->num_args == 1); - GPR_ASSERT(strcmp(ch_args->args[0].key, GRPC_ARG_SOCKET_MUTATOR) == 0); - GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_POINTER); - - { - grpc_core::ExecCtx exec_ctx; - grpc_channel_args_destroy(ch_args); - } -} - struct fake_class { int foo; }; @@ -234,9 +144,6 @@ int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_create(); - test_set_compression_algorithm(); - test_compression_algorithm_states(); - test_set_socket_mutator(); test_channel_create_with_args(); test_server_create_with_args(); grpc_shutdown(); diff --git a/test/core/compression/compression_test.cc b/test/core/compression/compression_test.cc index 6522988c66e..cf6d18847e6 100644 --- a/test/core/compression/compression_test.cc +++ b/test/core/compression/compression_test.cc @@ -23,7 +23,10 @@ #include #include +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/util/test_config.h" static void test_compression_algorithm_parse(void) { @@ -258,12 +261,88 @@ static void test_compression_enable_disable_algorithm(void) { } } +static void test_channel_args_set_compression_algorithm(void) { + grpc_core::ExecCtx exec_ctx; + grpc_channel_args* ch_args; + + ch_args = + grpc_channel_args_set_compression_algorithm(nullptr, GRPC_COMPRESS_GZIP); + GPR_ASSERT(ch_args->num_args == 1); + GPR_ASSERT(strcmp(ch_args->args[0].key, + GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM) == 0); + GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_INTEGER); + + grpc_channel_args_destroy(ch_args); +} + +static void test_channel_args_compression_algorithm_states(void) { + grpc_core::ExecCtx exec_ctx; + grpc_channel_args *ch_args, *ch_args_wo_gzip, *ch_args_wo_gzip_deflate, + *ch_args_wo_gzip_deflate_gzip; + unsigned states_bitset; + size_t i; + + ch_args = grpc_channel_args_copy_and_add(nullptr, nullptr, 0); + /* by default, all enabled */ + states_bitset = static_cast( + grpc_channel_args_compression_algorithm_get_states(ch_args)); + + for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { + GPR_ASSERT(GPR_BITGET(states_bitset, i)); + } + + /* disable gzip and deflate and stream/gzip */ + ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( + &ch_args, GRPC_COMPRESS_GZIP, 0); + GPR_ASSERT(ch_args == ch_args_wo_gzip); + ch_args_wo_gzip_deflate = grpc_channel_args_compression_algorithm_set_state( + &ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0); + GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate); + ch_args_wo_gzip_deflate_gzip = + grpc_channel_args_compression_algorithm_set_state( + &ch_args_wo_gzip_deflate, GRPC_COMPRESS_STREAM_GZIP, 0); + GPR_ASSERT(ch_args_wo_gzip_deflate == ch_args_wo_gzip_deflate_gzip); + + states_bitset = + static_cast(grpc_channel_args_compression_algorithm_get_states( + ch_args_wo_gzip_deflate)); + for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { + if (i == GRPC_COMPRESS_GZIP || i == GRPC_COMPRESS_DEFLATE || + i == GRPC_COMPRESS_STREAM_GZIP) { + GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0); + } else { + GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0); + } + } + + /* re-enabled gzip and stream/gzip only */ + ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( + &ch_args_wo_gzip_deflate_gzip, GRPC_COMPRESS_GZIP, 1); + ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( + &ch_args_wo_gzip, GRPC_COMPRESS_STREAM_GZIP, 1); + GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate_gzip); + + states_bitset = static_cast( + grpc_channel_args_compression_algorithm_get_states(ch_args_wo_gzip)); + for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { + if (i == GRPC_COMPRESS_DEFLATE) { + GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0); + } else { + GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0); + } + } + + grpc_channel_args_destroy(ch_args); +} + int main(int argc, char** argv) { grpc_init(); test_compression_algorithm_parse(); test_compression_algorithm_name(); test_compression_algorithm_for_level(); test_compression_enable_disable_algorithm(); + test_channel_args_set_compression_algorithm(); + test_channel_args_compression_algorithm_states(); grpc_shutdown(); return 0; diff --git a/test/core/end2end/fixtures/h2_compress.cc b/test/core/end2end/fixtures/h2_compress.cc index 04142daf63f..f97192fecaa 100644 --- a/test/core/end2end/fixtures/h2_compress.cc +++ b/test/core/end2end/fixtures/h2_compress.cc @@ -29,6 +29,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" diff --git a/test/core/end2end/tests/compressed_payload.cc b/test/core/end2end/tests/compressed_payload.cc index 178d68c608d..2b9ab5d642a 100644 --- a/test/core/end2end/tests/compressed_payload.cc +++ b/test/core/end2end/tests/compressed_payload.cc @@ -30,6 +30,7 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/call_test_only.h" #include "src/core/lib/transport/static_metadata.h" diff --git a/test/core/end2end/tests/stream_compression_compressed_payload.cc b/test/core/end2end/tests/stream_compression_compressed_payload.cc index 839f0912a87..39f95b85baa 100644 --- a/test/core/end2end/tests/stream_compression_compressed_payload.cc +++ b/test/core/end2end/tests/stream_compression_compressed_payload.cc @@ -30,6 +30,7 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/call_test_only.h" #include "src/core/lib/transport/static_metadata.h" diff --git a/test/core/end2end/tests/stream_compression_payload.cc b/test/core/end2end/tests/stream_compression_payload.cc index 4c08150723a..5f6b9a7f199 100644 --- a/test/core/end2end/tests/stream_compression_payload.cc +++ b/test/core/end2end/tests/stream_compression_payload.cc @@ -27,6 +27,7 @@ #include #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/surface/call.h" #include "test/core/end2end/cq_verifier.h" diff --git a/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc b/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc index f7af59febe9..6e96f7d2938 100644 --- a/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc +++ b/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc @@ -28,6 +28,7 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/surface/call.h" #include "test/core/end2end/cq_verifier.h" diff --git a/test/core/end2end/tests/workaround_cronet_compression.cc b/test/core/end2end/tests/workaround_cronet_compression.cc index f44ddca3b10..d79b2a9be3b 100644 --- a/test/core/end2end/tests/workaround_cronet_compression.cc +++ b/test/core/end2end/tests/workaround_cronet_compression.cc @@ -30,6 +30,7 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/call_test_only.h" #include "src/core/lib/transport/static_metadata.h" diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 5c6dd838ffc..fe550ab2ef7 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1048,6 +1048,7 @@ 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_args.h \ src/core/lib/compression/compression_internal.h \ src/core/lib/compression/message_compress.h \ src/core/lib/compression/stream_compression.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index e68e758c64e..8827e4b7e38 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1089,6 +1089,8 @@ 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_args.cc \ +src/core/lib/compression/compression_args.h \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/compression_internal.h \ src/core/lib/compression/message_compress.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 5daec0a4e05..f324c523d54 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8162,6 +8162,7 @@ "src/core/lib/channel/handshaker_registry.cc", "src/core/lib/channel/status_util.cc", "src/core/lib/compression/compression.cc", + "src/core/lib/compression/compression_args.cc", "src/core/lib/compression/compression_internal.cc", "src/core/lib/compression/message_compress.cc", "src/core/lib/compression/stream_compression.cc", @@ -8336,6 +8337,7 @@ "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_args.h", "src/core/lib/compression/compression_internal.h", "src/core/lib/compression/message_compress.h", "src/core/lib/compression/stream_compression.h", @@ -8488,6 +8490,7 @@ "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_args.h", "src/core/lib/compression/compression_internal.h", "src/core/lib/compression/message_compress.h", "src/core/lib/compression/stream_compression.h", From 4d696c659ed62dc85c811912d0d68881e98b88cc Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 2 Apr 2019 18:58:53 -0700 Subject: [PATCH 1743/2143] Reviewer comments --- .../client_channel/client_channel_plugin.cc | 2 + .../filters/client_channel/service_config.cc | 2 + .../filters/client_channel/service_config.h | 73 ++++++++++++++++--- 3 files changed, 67 insertions(+), 10 deletions(-) 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 2031ab449f5..3d6fa2edf4b 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -49,6 +49,7 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { } void grpc_client_channel_init(void) { + grpc_core::ServiceConfig::ResetServiceConfigParsers(); grpc_core::LoadBalancingPolicyRegistry::Builder::InitRegistry(); grpc_core::ResolverRegistry::Builder::InitRegistry(); grpc_core::internal::ServerRetryThrottleMap::Init(); @@ -68,4 +69,5 @@ void grpc_client_channel_shutdown(void) { grpc_core::internal::ServerRetryThrottleMap::Shutdown(); grpc_core::ResolverRegistry::Builder::ShutdownRegistry(); grpc_core::LoadBalancingPolicyRegistry::Builder::ShutdownRegistry(); + grpc_core::ServiceConfig::ResetServiceConfigParsers(); } diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index e2d23010c8a..49b45b0e27f 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -34,6 +34,8 @@ namespace grpc_core { int ServiceConfig::registered_parsers_count = 0; +UniquePtr + ServiceConfig::registered_parsers[ServiceConfig::kMaxParsers]; RefCountedPtr ServiceConfig::Create(const char* json) { UniquePtr service_config_json(gpr_strdup(json)); diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index b211d732d3f..a65af4080c2 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -63,6 +63,24 @@ class ServiceConfigParsedObject { GRPC_ABSTRACT_BASE_CLASS; }; +/// This is the base class that all service config parsers should derive from. +class ServiceConfigParser { + public: + virtual ~ServiceConfigParser() = default; + + virtual UniquePtr ParseGlobalParams( + const grpc_json* json) { + return nullptr; + } + + virtual UniquePtr ParsePerMethodParams( + const grpc_json* json) { + return nullptr; + } + + GRPC_ABSTRACT_BASE_CLASS; +}; + class ServiceConfig : public RefCounted { public: /// Creates a new service config from parsing \a json_string. @@ -105,14 +123,40 @@ class ServiceConfig : public RefCounted { static RefCountedPtr MethodConfigTableLookup( const SliceHashTable>& table, const grpc_slice& path); - /// Retrieves the parsed object at index \a index. - ServiceConfigParsedObject* GetParsedServiceConfigObject(int index) { + /// Retrieves the parsed global service config object at index \a index. + ServiceConfigParsedObject* GetParsedGlobalServiceConfigObject(int index) { GPR_DEBUG_ASSERT(index < registered_parsers_count); - return parsed_service_config_objects[index].get(); + return parsed_global_service_config_objects[index].get(); } - typedef UniquePtr (*ServiceConfigParser)( - const char* service_config_json); + static constexpr int kMaxParsers = 32; + + /// Retrieves the vector of method service config objects for a given path \a + /// path. + const grpc_core::InlinedVector, + kMaxParsers>* + GetMethodServiceConfigObjectsVector(const grpc_slice& path) { + // auto parsed_service_config_objects[index].get(); + const auto* value = parsed_method_service_config_objects_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/*"). + if (value == nullptr) { + char* path_str = grpc_slice_to_c_string(path); + const char* sep = strrchr(path_str, '/') + 1; + const size_t len = (size_t)(sep - path_str); + char* buf = (char*)gpr_malloc(len + 2); // '*' and NUL + memcpy(buf, path_str, len); + buf[len] = '*'; + buf[len + 1] = '\0'; + grpc_slice wildcard_path = grpc_slice_from_copied_string(buf); + gpr_free(buf); + value = parsed_method_service_config_objects_table->Get(wildcard_path); + grpc_slice_unref_internal(wildcard_path); + gpr_free(path_str); + if (value == nullptr) return nullptr; + } + return value; + } /// Globally register a service config parser. On successful registration, it /// returns the index at which the parser was registered. On failure, -1 is @@ -120,11 +164,18 @@ class ServiceConfig : public RefCounted { /// registered parser. Each parser is responsible for reading the service /// config json and returning a parsed object. This parsed object can later be /// retrieved using the same index that was returned at registration time. - static int RegisterParser(ServiceConfigParser func) { - registered_parsers[registered_parsers_count] = func; + static int RegisterParser(UniquePtr func) { + registered_parsers[registered_parsers_count] = std::move(func); return registered_parsers_count++; } + static void ResetServiceConfigParsers() { + for (auto i = 0; i < kMaxParsers; i++) { + registered_parsers[i].reset(nullptr); + } + registered_parsers_count = 0; + } + private: // So New() can call our private ctor. template @@ -149,16 +200,18 @@ class ServiceConfig : public RefCounted { grpc_json* json, CreateValue create_value, typename SliceHashTable>::Entry* entries, size_t* idx); - static constexpr int kMaxParsers = 32; static int registered_parsers_count; - static ServiceConfigParser registered_parsers[kMaxParsers]; + static UniquePtr registered_parsers[kMaxParsers]; UniquePtr service_config_json_; UniquePtr json_string_; // Underlying storage for json_tree. grpc_json* json_tree_; InlinedVector, kMaxParsers> - parsed_service_config_objects; + parsed_global_service_config_objects; + RefCountedPtr, kMaxParsers>>> + parsed_method_service_config_objects_table; }; // From c871a0bb32aeadf49efd6f454c7ed01b96da8b4c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 3 Apr 2019 13:34:39 -0700 Subject: [PATCH 1744/2143] Remove commented code --- src/core/ext/filters/client_channel/service_config.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index a65af4080c2..5caf420ff9d 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -136,7 +136,6 @@ class ServiceConfig : public RefCounted { const grpc_core::InlinedVector, kMaxParsers>* GetMethodServiceConfigObjectsVector(const grpc_slice& path) { - // auto parsed_service_config_objects[index].get(); const auto* value = parsed_method_service_config_objects_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/*"). From 39765c1f656312ec4a319847899fbce07e8e234c Mon Sep 17 00:00:00 2001 From: Joe Bolinger Date: Wed, 3 Apr 2019 13:49:27 -0700 Subject: [PATCH 1745/2143] loosen dependency on googleapis-common-protos-types --- grpc.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grpc.gemspec b/grpc.gemspec index c128d07eaf8..b9d2107ee48 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -30,7 +30,7 @@ Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY s.add_dependency 'google-protobuf', '~> 3.7' - s.add_dependency 'googleapis-common-protos-types', '~> 1.0.0' + s.add_dependency 'googleapis-common-protos-types', '~> 1.0' s.add_development_dependency 'bundler', '~> 1.9' s.add_development_dependency 'facter', '~> 2.4' From 0e7ea67351bfbe30c49a60a97fd9944f9303689a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 3 Apr 2019 13:59:08 -0700 Subject: [PATCH 1746/2143] Fix health check client to wait for subchannel call stack destruction before destroying the arena. --- .../client_channel/health/health_check_client.cc | 15 +++++++++++---- .../client_channel/health/health_check_client.h | 5 +++++ 2 files changed, 16 insertions(+), 4 deletions(-) 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..ba8393b0fd6 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,6 @@ 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(); for (size_t i = 0; i < GRPC_CONTEXT_COUNT; i++) { if (context_[i].destroy != nullptr) { context_[i].destroy(context_[i].value); @@ -439,12 +436,22 @@ void HealthCheckClient::CallState::StartBatch( GRPC_ERROR_NONE, "start_subchannel_batch"); } +void HealthCheckClient::CallState::AfterCallStackDestruction( + void *arg, grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast(arg); + self->Unref(DEBUG_LOCATION, "cancel"); +} + void HealthCheckClient::CallState::OnCancelComplete(void* arg, grpc_error* error) { HealthCheckClient::CallState* self = static_cast(arg); GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "health_cancel"); - self->Unref(DEBUG_LOCATION, "cancel"); + GRPC_CLOSURE_INIT(&self->after_call_stack_destruction_, + AfterCallStackDestruction, self, grpc_schedule_on_exec_ctx); + self->call_->SetAfterCallStackDestroy(&self->after_call_stack_destruction_); + self->call_.reset(); } void HealthCheckClient::CallState::StartCancel(void* arg, grpc_error* error) { 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..441d130e864 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 @@ -91,6 +91,8 @@ class HealthCheckClient : public InternallyRefCounted { grpc_error* PullSliceFromRecvMessage(); void DoneReadingRecvMessage(grpc_error* error); + static void AfterCallStackDestruction(void* arg, grpc_error* error); + RefCountedPtr health_check_client_; grpc_polling_entity pollent_; @@ -132,6 +134,9 @@ class HealthCheckClient : public InternallyRefCounted { grpc_metadata_batch recv_trailing_metadata_; grpc_transport_stream_stats collect_stats_; grpc_closure recv_trailing_metadata_ready_; + + // Closure for call stack destruction. + grpc_closure after_call_stack_destruction_; }; void StartCall(); From 80140f53fbdff809de00bde2df3e6180e3ed8cba Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Wed, 3 Apr 2019 13:39:48 -0700 Subject: [PATCH 1747/2143] Fix CFStreamTest.NetworkTransition. It looks like CFStream doesn't detect stream errors when the server is listening on 127.0.0.2 and the interface is shutdown. The test started failing after address was changed from 10.0.0.1 to 127.0.0.2 in #18381. This commit changes the server address back to 10.0.0.1. --- test/cpp/end2end/cfstream_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/end2end/cfstream_test.cc b/test/cpp/end2end/cfstream_test.cc index a6ed7c66d84..63d76e96f8b 100644 --- a/test/cpp/end2end/cfstream_test.cc +++ b/test/cpp/end2end/cfstream_test.cc @@ -62,7 +62,7 @@ class CFStreamTest : public ::testing::Test { CFStreamTest() : server_host_("grpctest"), interface_("lo0"), - ipv4_address_("127.0.0.2"), + ipv4_address_("10.0.0.1"), kRequestMessage_("🖖") {} void DNSUp() { From 13f2c19aee6c99eae455dfba40b137780ce3cafe Mon Sep 17 00:00:00 2001 From: Joe Bolinger Date: Wed, 3 Apr 2019 16:35:23 -0700 Subject: [PATCH 1748/2143] loosen dependecy in gemspec template --- templates/grpc.gemspec.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template index 0e321717c99..d2b54a9c2f5 100644 --- a/templates/grpc.gemspec.template +++ b/templates/grpc.gemspec.template @@ -32,7 +32,7 @@ s.platform = Gem::Platform::RUBY s.add_dependency 'google-protobuf', '~> 3.7' - s.add_dependency 'googleapis-common-protos-types', '~> 1.0.0' + s.add_dependency 'googleapis-common-protos-types', '~> 1.0' s.add_development_dependency 'bundler', '~> 1.9' s.add_development_dependency 'facter', '~> 2.4' From 1ad85dfc9e8f5f4f15ee11aad8ddf480985e6416 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 3 Apr 2019 17:01:04 -0700 Subject: [PATCH 1749/2143] Bump version to v1.20.0-pre2 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index d962cd51c41..7db6db3c2d5 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "godric" core_version = "7.0.0" -version = "1.20.0-pre1" +version = "1.20.0-pre2" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index e1d425a987e..40741f2f0fe 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: godric - version: 1.20.0-pre1 + version: 1.20.0-pre2 filegroups: - name: alts_proto headers: From aaef785de8c1bfea7ff68e26d009006c91e3db64 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 3 Apr 2019 17:02:02 -0700 Subject: [PATCH 1750/2143] 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 | 4 ++-- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 2 +- src/csharp/build/dependencies.props | 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, 33 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8835079a2a7..644e309ae7b 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.20.0-pre1") +set(PACKAGE_VERSION "1.20.0-pre2") 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 ad9e358f853..ab15fc01601 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.20.0-pre1 -CSHARP_VERSION = 1.20.0-pre1 +CPP_VERSION = 1.20.0-pre2 +CSHARP_VERSION = 1.20.0-pre2 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 20981703b44..0a0624707d5 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.20.0-pre1' - version = '0.0.8-pre1' + # version = '1.20.0-pre2' + version = '0.0.8-pre2' 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.20.0-pre1' + grpc_version = '1.20.0-pre2' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index e55559a0ae5..e76977cb2ec 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.20.0-pre1' + version = '1.20.0-pre2' 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 6dc05f8a9ae..73f20a1a17c 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.20.0-pre1' + version = '1.20.0-pre2' 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 6626875be3c..ab2d7c53707 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.20.0-pre1' + version = '1.20.0-pre2' 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 80fa0aff7dc..6a0ef18f9ad 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.20.0-pre1' + version = '1.20.0-pre2' 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 1d9d8a67cf6..c0f1e13fa09 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.20.0RC1 - 1.20.0RC1 + 1.20.0RC2 + 1.20.0RC2 beta diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 6743b7737ca..fd77ae95b92 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.20.0-pre1"; } +grpc::string Version() { return "1.20.0-pre2"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index b68d6152ac8..23c7f49fe30 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.20.0-pre1"; + public const string CurrentVersion = "1.20.0-pre2"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index 1a66732bbc1..3e6c122bb80 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.20.0-pre1 + 1.20.0-pre2 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 7c472622276..5b2a75310f4 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.20.0-pre1 +set VERSION=1.20.0-pre2 @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 dd83dce22d9..984ca403591 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.20.0-pre1' + v = '1.20.0-pre2' 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 210ffb14fa3..d3ec6c5aaf7 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.20.0-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.20.0-pre2" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 8d37cb5fece..1f390ada086 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.20.0-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.20.0-pre2" #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 af9d01a05c8..9e9da239a35 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.20.0RC1" +#define PHP_GRPC_VERSION "1.20.0RC2" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 5071e4c6b6b..e7f07d54ab1 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.20.0rc1""" +__version__ = """1.20.0rc2""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index fdf42b43957..5c2d54c00d5 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.20.0rc1' +VERSION = '1.20.0rc2' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 1ace56a18e7..d3f28419c9e 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.20.0rc1' +VERSION = '1.20.0rc2' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index a0f6455e115..2f200c4fba2 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.20.0rc1' +VERSION = '1.20.0rc2' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 59286fb8a61..400b3e24d24 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.20.0rc1' +VERSION = '1.20.0rc2' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 634c8fa88af..a7945b11735 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.20.0rc1' +VERSION = '1.20.0rc2' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index d6665498e47..15411c8d61b 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.20.0rc1' +VERSION = '1.20.0rc2' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 13d6b4a46de..e5a8b3aa750 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.20.0rc1' +VERSION = '1.20.0rc2' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 295e3b3e6ec..05fbcc35e01 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.20.0.pre1' + VERSION = '1.20.0.pre2' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 450d608d85b..8f8d6f0b0f3 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.20.0.pre1' + VERSION = '1.20.0.pre2' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 9117a636955..19f672f5032 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.20.0rc1' +VERSION = '1.20.0rc2' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 16ce053e942..7c3716b764f 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.20.0-pre1 +PROJECT_NUMBER = 1.20.0-pre2 # 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 e60c82cd823..b2a509b47e9 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.20.0-pre1 +PROJECT_NUMBER = 1.20.0-pre2 # 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 9bfd2354ecdd43c8688a26d60d3615a695eea784 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 3 Apr 2019 16:54:31 -0700 Subject: [PATCH 1751/2143] Add global and method parsing logic --- .../filters/client_channel/service_config.cc | 150 +++++++++++++++++- .../filters/client_channel/service_config.h | 53 +++++-- 2 files changed, 183 insertions(+), 20 deletions(-) diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index 49b45b0e27f..e01eb11fe98 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -35,7 +35,7 @@ namespace grpc_core { int ServiceConfig::registered_parsers_count = 0; UniquePtr - ServiceConfig::registered_parsers[ServiceConfig::kMaxParsers]; + ServiceConfig::registered_parsers[ServiceConfigParser::kMaxParsers]; RefCountedPtr ServiceConfig::Create(const char* json) { UniquePtr service_config_json(gpr_strdup(json)); @@ -45,15 +45,155 @@ RefCountedPtr ServiceConfig::Create(const char* json) { gpr_log(GPR_INFO, "failed to parse JSON for service config"); return nullptr; } - return MakeRefCounted(std::move(service_config_json), - std::move(json_string), json_tree); + bool success; + auto return_value = MakeRefCounted( + std::move(service_config_json), std::move(json_string), json_tree, + &success); + + // return return_value; + return success ? return_value : nullptr; } ServiceConfig::ServiceConfig(UniquePtr service_config_json, - UniquePtr json_string, grpc_json* json_tree) + UniquePtr json_string, grpc_json* json_tree, + bool* success) : service_config_json_(std::move(service_config_json)), json_string_(std::move(json_string)), - json_tree_(json_tree) {} + json_tree_(json_tree) { + GPR_DEBUG_ASSERT(success != nullptr); + if (json_tree->type != GRPC_JSON_OBJECT || json_tree->key != nullptr) { + gpr_log(GPR_ERROR, "error"); + *success = false; + return; + } + ParseGlobalParams(json_tree, success); + if (!*success) { + gpr_log(GPR_ERROR, "global error"); + return; + } + ParsePerMethodParams(json_tree, success); + if (!*success) { + gpr_log(GPR_ERROR, "local error"); + return; + } +} + +void ServiceConfig::ParseGlobalParams(const grpc_json* json_tree, + bool* success) { + GPR_DEBUG_ASSERT(success != nullptr); + GPR_DEBUG_ASSERT(json_tree_->type == GRPC_JSON_OBJECT); + GPR_DEBUG_ASSERT(json_tree_->key == nullptr); + for (auto i = 0; i < registered_parsers_count; i++) { + auto parsed_obj = + registered_parsers[i]->ParseGlobalParams(json_tree, success); + if (!*success) { + return; + } + parsed_global_service_config_objects.push_back(parsed_obj); + } + *success = true; +} + +bool ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( + const grpc_json* json, + SliceHashTable>::Entry* entries, + size_t* idx) { + auto objs_vector = MakeRefCounted(); + for (auto i = 0; i < registered_parsers_count; i++) { + bool success; + auto parsed_obj = + registered_parsers[i]->ParsePerMethodParams(json, &success); + if (!success) { + return false; + } + objs_vector->vector.push_back(parsed_obj); + } + // Construct list of paths. + InlinedVector, 10> paths; + for (grpc_json* child = json->child; child != nullptr; child = child->next) { + if (child->key == nullptr) continue; + if (strcmp(child->key, "name") == 0) { + if (child->type != GRPC_JSON_ARRAY) return false; + for (grpc_json* name = child->child; name != nullptr; name = name->next) { + UniquePtr path = ParseJsonMethodName(name); + if (path == nullptr) return false; + paths.push_back(std::move(path)); + } + } + } + if (paths.size() == 0) return false; // No names specified. + // Add entry for each path. + for (size_t i = 0; i < paths.size(); ++i) { + entries[*idx].key = grpc_slice_from_copied_string(paths[i].get()); + entries[*idx].value = objs_vector; // Takes a new ref. + ++*idx; + } + return true; +} + +void ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree, + bool* success) { + GPR_DEBUG_ASSERT(success != nullptr); + GPR_DEBUG_ASSERT(json_tree_->type == GRPC_JSON_OBJECT); + GPR_DEBUG_ASSERT(json_tree_->key == nullptr); + SliceHashTable>::Entry* entries = + nullptr; + size_t num_entries = 0; + for (grpc_json* field = json_tree->child; field != nullptr; + field = field->next) { + if (field->key == nullptr) { + *success = false; + return; + } + if (strcmp(field->key, "methodConfig") == 0) { + if (entries != nullptr) { + GPR_ASSERT(false); + } + if (field->type != GRPC_JSON_ARRAY) { + *success = false; + return; + } + for (grpc_json* method = field->child; method != nullptr; + method = method->next) { + int count = CountNamesInMethodConfig(method); + if (count <= 0) { + *success = false; + return; + } + num_entries += static_cast(count); + } + entries = static_cast< + SliceHashTable>::Entry*>( + gpr_zalloc( + num_entries * + sizeof(SliceHashTable< + RefCountedPtr>::Entry))); + size_t idx = 0; + for (grpc_json* method = field->child; method != nullptr; + method = method->next) { + if (!ParseJsonMethodConfigToServiceConfigObjectsTable(method, entries, + &idx)) { + for (size_t i = 0; i < idx; ++i) { + grpc_slice_unref_internal(entries[i].key); + entries[i].value.reset(); + } + gpr_free(entries); + *success = false; + return; + } + } + GPR_DEBUG_ASSERT(idx == num_entries); + break; + } + } + if (entries != nullptr) { + parsed_method_service_config_objects_table = + SliceHashTable>::Create( + num_entries, entries, nullptr); + gpr_free(entries); + } + *success = true; +} ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); } diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 5caf420ff9d..acf618b3432 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -56,7 +56,7 @@ namespace grpc_core { /// This is the base class that all service config parsers MUST use to store /// parsed service config data. -class ServiceConfigParsedObject { +class ServiceConfigParsedObject : public RefCounted { public: virtual ~ServiceConfigParsedObject() = default; @@ -68,19 +68,35 @@ class ServiceConfigParser { public: virtual ~ServiceConfigParser() = default; - virtual UniquePtr ParseGlobalParams( - const grpc_json* json) { + virtual RefCountedPtr ParseGlobalParams( + const grpc_json* json, bool* success) { + if (success != nullptr) { + *success = true; + } return nullptr; } - virtual UniquePtr ParsePerMethodParams( - const grpc_json* json) { + virtual RefCountedPtr ParsePerMethodParams( + const grpc_json* json, bool* success) { + if (success != nullptr) { + *success = true; + } return nullptr; } + static constexpr int kMaxParsers = 32; + GRPC_ABSTRACT_BASE_CLASS; }; +class ServiceConfigObjectsVector + : public RefCounted { + public: + grpc_core::InlinedVector, + ServiceConfigParser::kMaxParsers> + vector; +}; + class ServiceConfig : public RefCounted { public: /// Creates a new service config from parsing \a json_string. @@ -129,12 +145,9 @@ class ServiceConfig : public RefCounted { return parsed_global_service_config_objects[index].get(); } - static constexpr int kMaxParsers = 32; - /// Retrieves the vector of method service config objects for a given path \a /// path. - const grpc_core::InlinedVector, - kMaxParsers>* + const RefCountedPtr* GetMethodServiceConfigObjectsVector(const grpc_slice& path) { const auto* value = parsed_method_service_config_objects_table->Get(path); // If we didn't find a match for the path, try looking for a wildcard @@ -169,7 +182,7 @@ class ServiceConfig : public RefCounted { } static void ResetServiceConfigParsers() { - for (auto i = 0; i < kMaxParsers; i++) { + for (auto i = 0; i < ServiceConfigParser::kMaxParsers; i++) { registered_parsers[i].reset(nullptr); } registered_parsers_count = 0; @@ -182,7 +195,11 @@ class ServiceConfig : public RefCounted { // Takes ownership of \a json_tree. ServiceConfig(UniquePtr service_config_json, - UniquePtr json_string, grpc_json* json_tree); + UniquePtr json_string, grpc_json* json_tree, + bool* success); + + void ParseGlobalParams(const grpc_json* json_tree, bool* success); + void ParsePerMethodParams(const grpc_json* json_tree, bool* success); // Returns the number of names specified in the method config \a json. static int CountNamesInMethodConfig(grpc_json* json); @@ -199,17 +216,23 @@ class ServiceConfig : public RefCounted { grpc_json* json, CreateValue create_value, typename SliceHashTable>::Entry* entries, size_t* idx); + static bool ParseJsonMethodConfigToServiceConfigObjectsTable( + const grpc_json* json, + SliceHashTable>::Entry* entries, + size_t* idx); + static int registered_parsers_count; - static UniquePtr registered_parsers[kMaxParsers]; + static UniquePtr + registered_parsers[ServiceConfigParser::kMaxParsers]; UniquePtr service_config_json_; UniquePtr json_string_; // Underlying storage for json_tree. grpc_json* json_tree_; - InlinedVector, kMaxParsers> + InlinedVector, + ServiceConfigParser::kMaxParsers> parsed_global_service_config_objects; - RefCountedPtr, kMaxParsers>>> + RefCountedPtr>> parsed_method_service_config_objects_table; }; From 615c95ed5c5516bd59f16e1c22568298148467a7 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 3 Apr 2019 18:13:52 -0700 Subject: [PATCH 1752/2143] Mitigate #18256 --- WORKSPACE | 54 ++++++++++++++++---------------------- bazel/grpc_python_deps.bzl | 15 +++++++++++ 2 files changed, 37 insertions(+), 32 deletions(-) create mode 100644 bazel/grpc_python_deps.bzl diff --git a/WORKSPACE b/WORKSPACE index 81371bf4187..18f389edd24 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -17,6 +17,26 @@ register_toolchains( "//third_party/toolchains:cc-toolchain-clang-x86_64-default", ) +# TODO(https://github.com/grpc/grpc/issues/18331): Move off of this dependency. +git_repository( + name = "org_pubref_rules_protobuf", + remote = "https://github.com/ghostwriternr/rules_protobuf", + tag = "v0.8.2.1-alpha", +) + +git_repository( + name = "io_bazel_rules_python", + commit = "8b5d0683a7d878b28fffe464779c8a53659fc645", + remote = "https://github.com/bazelbuild/rules_python.git", +) + +load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories", "pip_import") + +pip_import( + name = "grpc_python_dependencies", + requirements = "//:requirements.bazel.txt", +) + http_archive( name = "cython", build_file = "//third_party:cython.BUILD", @@ -27,36 +47,6 @@ http_archive( ], ) -load("//third_party/py:python_configure.bzl", "python_configure") +load("//bazel:grpc_python_deps.bzl", "grpc_python_deps") -python_configure(name = "local_config_python") - -git_repository( - name = "io_bazel_rules_python", - commit = "8b5d0683a7d878b28fffe464779c8a53659fc645", - remote = "https://github.com/bazelbuild/rules_python.git", -) - -load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories", "pip_import") - -pip_repositories() - -pip_import( - name = "grpc_python_dependencies", - requirements = "//:requirements.bazel.txt", -) - -load("@grpc_python_dependencies//:requirements.bzl", "pip_install") - -pip_install() - -# NOTE(https://github.com/pubref/rules_protobuf/pull/196): Switch to upstream repo after this gets merged. -git_repository( - name = "org_pubref_rules_protobuf", - remote = "https://github.com/ghostwriternr/rules_protobuf", - tag = "v0.8.2.1-alpha", -) - -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories") - -py_proto_repositories() +grpc_python_deps() diff --git a/bazel/grpc_python_deps.bzl b/bazel/grpc_python_deps.bzl new file mode 100644 index 00000000000..2f1fb02aff4 --- /dev/null +++ b/bazel/grpc_python_deps.bzl @@ -0,0 +1,15 @@ +load("//third_party/py:python_configure.bzl", "python_configure") +load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories") +load("@grpc_python_dependencies//:requirements.bzl", "pip_install") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories") + +def grpc_python_deps(): + # TODO(https://github.com/grpc/grpc/issues/18256): Remove conditional. + if hasattr(native, "http_archive"): + python_configure(name = "local_config_python") + pip_repositories() + pip_install() + py_proto_repositories() + else: + print("Building python gRPC with bazel 23.0+ is disabled pending resolution of https://github.com/grpc/grpc/issues/18256.") + From f3f6237e6dbaec990c939bc9ce391492e6d71715 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 3 Apr 2019 18:16:24 -0700 Subject: [PATCH 1753/2143] Wrap long line --- bazel/grpc_python_deps.bzl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bazel/grpc_python_deps.bzl b/bazel/grpc_python_deps.bzl index 2f1fb02aff4..ec3df19e03a 100644 --- a/bazel/grpc_python_deps.bzl +++ b/bazel/grpc_python_deps.bzl @@ -11,5 +11,6 @@ def grpc_python_deps(): pip_install() py_proto_repositories() else: - print("Building python gRPC with bazel 23.0+ is disabled pending resolution of https://github.com/grpc/grpc/issues/18256.") + print("Building Python gRPC with bazel 23.0+ is disabled pending " + + "resolution of https://github.com/grpc/grpc/issues/18256.") From 0c8ef41a5ec2b0a8fbb41d0ec88ae3afb58c23dc Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 3 Apr 2019 18:53:14 -0700 Subject: [PATCH 1754/2143] Remove smart pointers from global registry --- .../ext/filters/client_channel/service_config.cc | 6 +++--- .../ext/filters/client_channel/service_config.h | 13 ++++--------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index e01eb11fe98..46f34ac14a1 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -34,7 +34,7 @@ namespace grpc_core { int ServiceConfig::registered_parsers_count = 0; -UniquePtr +ServiceConfigParser ServiceConfig::registered_parsers[ServiceConfigParser::kMaxParsers]; RefCountedPtr ServiceConfig::Create(const char* json) { @@ -85,7 +85,7 @@ void ServiceConfig::ParseGlobalParams(const grpc_json* json_tree, GPR_DEBUG_ASSERT(json_tree_->key == nullptr); for (auto i = 0; i < registered_parsers_count; i++) { auto parsed_obj = - registered_parsers[i]->ParseGlobalParams(json_tree, success); + registered_parsers[i].ParseGlobalParams(json_tree, success); if (!*success) { return; } @@ -102,7 +102,7 @@ bool ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( for (auto i = 0; i < registered_parsers_count; i++) { bool success; auto parsed_obj = - registered_parsers[i]->ParsePerMethodParams(json, &success); + registered_parsers[i].ParsePerMethodParams(json, &success); if (!success) { return false; } diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index acf618b3432..0a2fea9735f 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -176,17 +176,12 @@ class ServiceConfig : public RefCounted { /// registered parser. Each parser is responsible for reading the service /// config json and returning a parsed object. This parsed object can later be /// retrieved using the same index that was returned at registration time. - static int RegisterParser(UniquePtr func) { - registered_parsers[registered_parsers_count] = std::move(func); + static int RegisterParser(const ServiceConfigParser& parser) { + registered_parsers[registered_parsers_count] = parser; return registered_parsers_count++; } - static void ResetServiceConfigParsers() { - for (auto i = 0; i < ServiceConfigParser::kMaxParsers; i++) { - registered_parsers[i].reset(nullptr); - } - registered_parsers_count = 0; - } + static void ResetServiceConfigParsers() { registered_parsers_count = 0; } private: // So New() can call our private ctor. @@ -222,7 +217,7 @@ class ServiceConfig : public RefCounted { size_t* idx); static int registered_parsers_count; - static UniquePtr + static ServiceConfigParser registered_parsers[ServiceConfigParser::kMaxParsers]; UniquePtr service_config_json_; From 0f0e774722f8d00682b6c2d6a05d4aebd22fd972 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 3 Apr 2019 19:02:43 -0700 Subject: [PATCH 1755/2143] Clean up --- .../filters/client_channel/service_config.cc | 20 +++++++--------- .../filters/client_channel/service_config.h | 24 ++++++++++--------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index 46f34ac14a1..f47b170d75e 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -33,9 +33,9 @@ namespace grpc_core { -int ServiceConfig::registered_parsers_count = 0; +int ServiceConfig::registered_parsers_count_ = 0; ServiceConfigParser - ServiceConfig::registered_parsers[ServiceConfigParser::kMaxParsers]; + ServiceConfig::registered_parsers_[ServiceConfigParser::kMaxParsers]; RefCountedPtr ServiceConfig::Create(const char* json) { UniquePtr service_config_json(gpr_strdup(json)); @@ -50,7 +50,6 @@ RefCountedPtr ServiceConfig::Create(const char* json) { std::move(service_config_json), std::move(json_string), json_tree, &success); - // return return_value; return success ? return_value : nullptr; } @@ -62,18 +61,15 @@ ServiceConfig::ServiceConfig(UniquePtr service_config_json, json_tree_(json_tree) { GPR_DEBUG_ASSERT(success != nullptr); if (json_tree->type != GRPC_JSON_OBJECT || json_tree->key != nullptr) { - gpr_log(GPR_ERROR, "error"); *success = false; return; } ParseGlobalParams(json_tree, success); if (!*success) { - gpr_log(GPR_ERROR, "global error"); return; } ParsePerMethodParams(json_tree, success); if (!*success) { - gpr_log(GPR_ERROR, "local error"); return; } } @@ -83,13 +79,13 @@ void ServiceConfig::ParseGlobalParams(const grpc_json* json_tree, GPR_DEBUG_ASSERT(success != nullptr); GPR_DEBUG_ASSERT(json_tree_->type == GRPC_JSON_OBJECT); GPR_DEBUG_ASSERT(json_tree_->key == nullptr); - for (auto i = 0; i < registered_parsers_count; i++) { + for (auto i = 0; i < registered_parsers_count_; i++) { auto parsed_obj = - registered_parsers[i].ParseGlobalParams(json_tree, success); + registered_parsers_[i].ParseGlobalParams(json_tree, success); if (!*success) { return; } - parsed_global_service_config_objects.push_back(parsed_obj); + parsed_global_service_config_objects_.push_back(parsed_obj); } *success = true; } @@ -99,10 +95,10 @@ bool ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( SliceHashTable>::Entry* entries, size_t* idx) { auto objs_vector = MakeRefCounted(); - for (auto i = 0; i < registered_parsers_count; i++) { + for (auto i = 0; i < registered_parsers_count_; i++) { bool success; auto parsed_obj = - registered_parsers[i].ParsePerMethodParams(json, &success); + registered_parsers_[i].ParsePerMethodParams(json, &success); if (!success) { return false; } @@ -187,7 +183,7 @@ void ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree, } } if (entries != nullptr) { - parsed_method_service_config_objects_table = + parsed_method_service_config_objects_table_ = SliceHashTable>::Create( num_entries, entries, nullptr); gpr_free(entries); diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 0a2fea9735f..9752bf7ba27 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -141,15 +141,15 @@ class ServiceConfig : public RefCounted { /// Retrieves the parsed global service config object at index \a index. ServiceConfigParsedObject* GetParsedGlobalServiceConfigObject(int index) { - GPR_DEBUG_ASSERT(index < registered_parsers_count); - return parsed_global_service_config_objects[index].get(); + GPR_DEBUG_ASSERT(index < registered_parsers_count_); + return parsed_global_service_config_objects_[index].get(); } /// Retrieves the vector of method service config objects for a given path \a /// path. const RefCountedPtr* GetMethodServiceConfigObjectsVector(const grpc_slice& path) { - const auto* value = parsed_method_service_config_objects_table->Get(path); + const auto* value = parsed_method_service_config_objects_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/*"). if (value == nullptr) { @@ -162,7 +162,7 @@ class ServiceConfig : public RefCounted { buf[len + 1] = '\0'; grpc_slice wildcard_path = grpc_slice_from_copied_string(buf); gpr_free(buf); - value = parsed_method_service_config_objects_table->Get(wildcard_path); + value = parsed_method_service_config_objects_table_->Get(wildcard_path); grpc_slice_unref_internal(wildcard_path); gpr_free(path_str); if (value == nullptr) return nullptr; @@ -177,11 +177,12 @@ class ServiceConfig : public RefCounted { /// config json and returning a parsed object. This parsed object can later be /// retrieved using the same index that was returned at registration time. static int RegisterParser(const ServiceConfigParser& parser) { - registered_parsers[registered_parsers_count] = parser; - return registered_parsers_count++; + registered_parsers_[registered_parsers_count_] = parser; + return registered_parsers_count_++; } - static void ResetServiceConfigParsers() { registered_parsers_count = 0; } + /// Should be called on initialization and shutdown. + static void ResetServiceConfigParsers() { registered_parsers_count_ = 0; } private: // So New() can call our private ctor. @@ -193,6 +194,7 @@ class ServiceConfig : public RefCounted { UniquePtr json_string, grpc_json* json_tree, bool* success); + // Helper functions to parse the service config void ParseGlobalParams(const grpc_json* json_tree, bool* success); void ParsePerMethodParams(const grpc_json* json_tree, bool* success); @@ -216,9 +218,9 @@ class ServiceConfig : public RefCounted { SliceHashTable>::Entry* entries, size_t* idx); - static int registered_parsers_count; + static int registered_parsers_count_; static ServiceConfigParser - registered_parsers[ServiceConfigParser::kMaxParsers]; + registered_parsers_[ServiceConfigParser::kMaxParsers]; UniquePtr service_config_json_; UniquePtr json_string_; // Underlying storage for json_tree. @@ -226,9 +228,9 @@ class ServiceConfig : public RefCounted { InlinedVector, ServiceConfigParser::kMaxParsers> - parsed_global_service_config_objects; + parsed_global_service_config_objects_; RefCountedPtr>> - parsed_method_service_config_objects_table; + parsed_method_service_config_objects_table_; }; // From cba5c089ebf4b52cf0f75535e2e8698d2fcacc8c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 4 Apr 2019 10:18:53 +0200 Subject: [PATCH 1756/2143] Upgrade linux RBE tests to bazel 0.23.2 --- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index 1882fe213fa..dd34eac7b38 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -23,7 +23,7 @@ cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321 # Download bazel temp_dir="$(mktemp -d)" -wget -q https://github.com/bazelbuild/bazel/releases/download/0.22.0/bazel-0.22.0-linux-x86_64 -O "${temp_dir}/bazel" +wget -q https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-linux-x86_64 -O "${temp_dir}/bazel" chmod 755 "${temp_dir}/bazel" export PATH="${temp_dir}:${PATH}" # This should show ${temp_dir}/bazel From 4a19b2f45f0c3cc66963e241f4a5507671b67b59 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 4 Apr 2019 07:25:41 -0700 Subject: [PATCH 1757/2143] Add atomic to ensure we don't cancel twice. Also convert existing seen_response_ to new atomic API. --- .../client_channel/health/health_check_client.cc | 11 ++++++----- .../client_channel/health/health_check_client.h | 7 +++++-- 2 files changed, 11 insertions(+), 7 deletions(-) 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 ba8393b0fd6..993582a01e7 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 @@ -287,7 +287,6 @@ HealthCheckClient::CallState::CallState( ->GetInitialCallSizeEstimate(0))), payload_(context_) { grpc_call_combiner_init(&call_combiner_); - gpr_atm_rel_store(&seen_response_, static_cast(0)); } HealthCheckClient::CallState::~CallState() { @@ -437,7 +436,7 @@ void HealthCheckClient::CallState::StartBatch( } void HealthCheckClient::CallState::AfterCallStackDestruction( - void *arg, grpc_error* error) { + void* arg, grpc_error* error) { HealthCheckClient::CallState* self = static_cast(arg); self->Unref(DEBUG_LOCATION, "cancel"); @@ -465,7 +464,9 @@ void HealthCheckClient::CallState::StartCancel(void* arg, grpc_error* error) { } void HealthCheckClient::CallState::Cancel() { - if (call_ != nullptr) { + bool expected = false; + if (cancelled_.CompareExchangeStrong(&expected, true, MemoryOrder::ACQ_REL, + MemoryOrder::ACQUIRE)) { Ref(DEBUG_LOCATION, "cancel").release(); GRPC_CALL_COMBINER_START( &call_combiner_, @@ -508,7 +509,7 @@ void HealthCheckClient::CallState::DoneReadingRecvMessage(grpc_error* error) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("backend unhealthy"); } health_check_client_->SetHealthStatus(state, error); - gpr_atm_rel_store(&seen_response_, static_cast(1)); + seen_response_.Store(true, MemoryOrder::RELEASE); grpc_slice_buffer_destroy_internal(&recv_message_buffer_); // Start another recv_message batch. // This re-uses the ref we're holding. @@ -642,7 +643,7 @@ void HealthCheckClient::CallState::CallEnded(bool retry) { health_check_client_->call_state_.reset(); if (retry) { GPR_ASSERT(!health_check_client_->shutting_down_); - if (static_cast(gpr_atm_acq_load(&seen_response_))) { + if (seen_response_.Load(MemoryOrder::ACQUIRE)) { // If the call fails after we've gotten a successful response, reset // the backoff and restart the call immediately. health_check_client_->retry_backoff_.Reset(); 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 441d130e864..1fa4487c403 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 @@ -22,13 +22,13 @@ #include #include -#include #include #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/gpr/arena.h" +#include "src/core/lib/gprpp/atomic.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/call_combiner.h" @@ -128,13 +128,16 @@ class HealthCheckClient : public InternallyRefCounted { OrphanablePtr recv_message_; grpc_closure recv_message_ready_; grpc_slice_buffer recv_message_buffer_; - gpr_atm seen_response_; + Atomic seen_response_{false}; // recv_trailing_metadata grpc_metadata_batch recv_trailing_metadata_; grpc_transport_stream_stats collect_stats_; grpc_closure recv_trailing_metadata_ready_; + // True if the cancel_stream batch has been started. + Atomic cancelled_{false}; + // Closure for call stack destruction. grpc_closure after_call_stack_destruction_; }; From 9222d4f3c23a7067f563bc3c223bd086bb9dee4c Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 4 Apr 2019 10:03:26 -0700 Subject: [PATCH 1758/2143] Fix clang issues --- include/grpcpp/server_builder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 182fdebeec9..0976b09bb8c 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -39,7 +39,7 @@ namespace grpc_impl { class Server; class ResourceQuota; -} // namespace grpc_impl +} // namespace grpc_impl namespace grpc { class AsyncGenericService; From 6287a60b5be0a3f86cbb2acf3c094e74443b2511 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 4 Apr 2019 10:11:52 -0700 Subject: [PATCH 1759/2143] Fix script errors --- BUILD.gn | 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.gn b/BUILD.gn index 5b0677023dd..0e9eb7fc95c 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1083,6 +1083,7 @@ config("grpc_config") { "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", "include/grpcpp/security/server_credentials.h", + "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", "include/grpcpp/server_builder.h", "include/grpcpp/server_context.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 50d69f90388..f4da2e83761 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3031,6 +3031,7 @@ foreach(_hdr include/grpcpp/security/auth_metadata_processor_impl.h include/grpcpp/security/credentials.h include/grpcpp/security/server_credentials.h + include/grpcpp/security/server_credentials_impl.h include/grpcpp/server.h include/grpcpp/server_builder.h include/grpcpp/server_context.h @@ -3630,6 +3631,7 @@ foreach(_hdr include/grpcpp/security/auth_metadata_processor_impl.h include/grpcpp/security/credentials.h include/grpcpp/security/server_credentials.h + include/grpcpp/security/server_credentials_impl.h include/grpcpp/server.h include/grpcpp/server_builder.h include/grpcpp/server_context.h @@ -4602,6 +4604,7 @@ foreach(_hdr include/grpcpp/security/auth_metadata_processor_impl.h include/grpcpp/security/credentials.h include/grpcpp/security/server_credentials.h + include/grpcpp/security/server_credentials_impl.h include/grpcpp/server.h include/grpcpp/server_builder.h include/grpcpp/server_context.h diff --git a/Makefile b/Makefile index 3ecbf182393..c2e57c2556e 100644 --- a/Makefile +++ b/Makefile @@ -5362,6 +5362,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ include/grpcpp/security/server_credentials.h \ + include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ @@ -5969,6 +5970,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ include/grpcpp/security/server_credentials.h \ + include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ @@ -6890,6 +6892,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ include/grpcpp/security/server_credentials.h \ + include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ diff --git a/build.yaml b/build.yaml index d5ce77c2844..0ddb8154669 100644 --- a/build.yaml +++ b/build.yaml @@ -1377,6 +1377,7 @@ filegroups: - include/grpcpp/security/auth_metadata_processor_impl.h - include/grpcpp/security/credentials.h - include/grpcpp/security/server_credentials.h + - include/grpcpp/security/server_credentials_impl.h - include/grpcpp/server.h - include/grpcpp/server_builder.h - include/grpcpp/server_context.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 602c66b93d9..b52124d0e0f 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -116,6 +116,7 @@ Pod::Spec.new do |s| 'include/grpcpp/security/auth_metadata_processor_impl.h', 'include/grpcpp/security/credentials.h', 'include/grpcpp/security/server_credentials.h', + 'include/grpcpp/security/server_credentials_impl.h', 'include/grpcpp/server.h', 'include/grpcpp/server_builder.h', 'include/grpcpp/server_context.h', diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 7dbb63813c2..f15219dd15e 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -1006,6 +1006,7 @@ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ include/grpcpp/security/server_credentials.h \ +include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c7d29b228ab..c0a9d4c9bcf 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1008,6 +1008,7 @@ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ include/grpcpp/security/server_credentials.h \ +include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 7a5d92abdaa..3fd9cc88375 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10124,6 +10124,7 @@ "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", "include/grpcpp/security/server_credentials.h", + "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", "include/grpcpp/server_builder.h", "include/grpcpp/server_context.h", @@ -10241,6 +10242,7 @@ "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", "include/grpcpp/security/server_credentials.h", + "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", "include/grpcpp/server_builder.h", "include/grpcpp/server_context.h", From a93ff7d61752f08f2bea11fc8f31d51f0a8a812b Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 4 Apr 2019 10:14:26 -0700 Subject: [PATCH 1760/2143] Fix script errors --- include/grpcpp/impl/server_builder_plugin.h | 2 +- include/grpcpp/server_builder_impl.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h index ec5fd09fe45..dd600a839d7 100644 --- a/include/grpcpp/impl/server_builder_plugin.h +++ b/include/grpcpp/impl/server_builder_plugin.h @@ -27,7 +27,7 @@ namespace grpc_impl { class ServerBuilder; class ServerInitializer; -} +} // namespace grpc_impl namespace grpc { class ChannelArguments; diff --git a/include/grpcpp/server_builder_impl.h b/include/grpcpp/server_builder_impl.h index 9f7872b54da..2653a7ee881 100644 --- a/include/grpcpp/server_builder_impl.h +++ b/include/grpcpp/server_builder_impl.h @@ -38,7 +38,7 @@ struct grpc_resource_quota; namespace grpc_impl { class ResourceQuota; -} // namespace grpc_impl +} // namespace grpc_impl namespace grpc { class AsyncGenericService; @@ -194,7 +194,8 @@ 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 grpc_impl::ResourceQuota& resource_quota); ServerBuilder& SetOption(std::unique_ptr option); From c28f16e481993b27e996a7959a6c48385788976f Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 4 Apr 2019 12:26:26 -0700 Subject: [PATCH 1761/2143] Reviewer comments --- .../client_channel/client_channel_plugin.cc | 4 +- .../resolver/dns/c_ares/dns_resolver_ares.cc | 3 +- .../client_channel/resolver_result_parsing.cc | 2 +- .../filters/client_channel/service_config.cc | 165 +++++++++++------- .../filters/client_channel/service_config.h | 104 +++++------ .../ext/filters/client_channel/subchannel.cc | 2 +- .../message_size/message_size_filter.cc | 2 +- 7 files changed, 153 insertions(+), 129 deletions(-) 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 3d6fa2edf4b..8e76c4cbb15 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -49,7 +49,7 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { } void grpc_client_channel_init(void) { - grpc_core::ServiceConfig::ResetServiceConfigParsers(); + grpc_core::ServiceConfig::Init(); grpc_core::LoadBalancingPolicyRegistry::Builder::InitRegistry(); grpc_core::ResolverRegistry::Builder::InitRegistry(); grpc_core::internal::ServerRetryThrottleMap::Init(); @@ -69,5 +69,5 @@ void grpc_client_channel_shutdown(void) { grpc_core::internal::ServerRetryThrottleMap::Shutdown(); grpc_core::ResolverRegistry::Builder::ShutdownRegistry(); grpc_core::LoadBalancingPolicyRegistry::Builder::ShutdownRegistry(); - grpc_core::ServiceConfig::ResetServiceConfigParsers(); + grpc_core::ServiceConfig::Shutdown(); } 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 7de1c221a13..7ce706724ee 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 @@ -308,7 +308,8 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { if (service_config_string != nullptr) { GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s", r, service_config_string); - result.service_config = ServiceConfig::Create(service_config_string); + result.service_config = + ServiceConfig::Create(service_config_string, nullptr); } gpr_free(service_config_string); } 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 daac4f0ff6a..f523ffe1610 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -52,7 +52,7 @@ ProcessedResolverResult::ProcessedResolverResult( 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); + service_config_ = ServiceConfig::Create(service_config_json, nullptr); } } else { // Add the service config JSON to channel args so that it's diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index f47b170d75e..fbeb578a08b 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -33,11 +33,11 @@ namespace grpc_core { -int ServiceConfig::registered_parsers_count_ = 0; -ServiceConfigParser - ServiceConfig::registered_parsers_[ServiceConfigParser::kMaxParsers]; +ServiceConfig::ServiceConfigParserList* ServiceConfig::registered_parsers_ = + nullptr; -RefCountedPtr ServiceConfig::Create(const char* json) { +RefCountedPtr ServiceConfig::Create(const char* json, + grpc_error** error) { UniquePtr service_config_json(gpr_strdup(json)); UniquePtr json_string(gpr_strdup(json)); grpc_json* json_tree = grpc_json_parse_string(json_string.get()); @@ -45,137 +45,153 @@ RefCountedPtr ServiceConfig::Create(const char* json) { gpr_log(GPR_INFO, "failed to parse JSON for service config"); return nullptr; } - bool success; + + grpc_error* create_error; auto return_value = MakeRefCounted( std::move(service_config_json), std::move(json_string), json_tree, - &success); - - return success ? return_value : nullptr; + &create_error); + if (create_error != GRPC_ERROR_NONE) { + if (error != nullptr) { + *error = create_error; + } else { + GRPC_ERROR_UNREF(create_error); + } + return nullptr; + } + if (error != nullptr) { + *error = GRPC_ERROR_NONE; + } + return return_value; } ServiceConfig::ServiceConfig(UniquePtr service_config_json, UniquePtr json_string, grpc_json* json_tree, - bool* success) + grpc_error** error) : service_config_json_(std::move(service_config_json)), json_string_(std::move(json_string)), json_tree_(json_tree) { - GPR_DEBUG_ASSERT(success != nullptr); if (json_tree->type != GRPC_JSON_OBJECT || json_tree->key != nullptr) { - *success = false; + if (error != nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Malformed service Config JSON object"); + } return; } - ParseGlobalParams(json_tree, success); - if (!*success) { - return; + grpc_error* parser_error = ParseGlobalParams(json_tree); + if (parser_error != GRPC_ERROR_NONE) { + parser_error = ParsePerMethodParams(json_tree); } - ParsePerMethodParams(json_tree, success); - if (!*success) { - return; + if (error != nullptr) { + *error = parser_error; + } else { + GRPC_ERROR_UNREF(parser_error); } } -void ServiceConfig::ParseGlobalParams(const grpc_json* json_tree, - bool* success) { - GPR_DEBUG_ASSERT(success != nullptr); +grpc_error* ServiceConfig::ParseGlobalParams(const grpc_json* json_tree) { GPR_DEBUG_ASSERT(json_tree_->type == GRPC_JSON_OBJECT); GPR_DEBUG_ASSERT(json_tree_->key == nullptr); - for (auto i = 0; i < registered_parsers_count_; i++) { + for (size_t i = 0; i < registered_parsers_->size(); i++) { + grpc_error* error; auto parsed_obj = - registered_parsers_[i].ParseGlobalParams(json_tree, success); - if (!*success) { - return; + (*registered_parsers_)[i].ParseGlobalParams(json_tree, &error); + if (error != GRPC_ERROR_NONE) { + return error; } - parsed_global_service_config_objects_.push_back(parsed_obj); + parsed_global_service_config_objects_.push_back(std::move(parsed_obj)); } - *success = true; + return GRPC_ERROR_NONE; } -bool ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( +grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( const grpc_json* json, - SliceHashTable>::Entry* entries, + SliceHashTable::Entry* entries, size_t* idx) { - auto objs_vector = MakeRefCounted(); - for (auto i = 0; i < registered_parsers_count_; i++) { - bool success; + auto objs_vector = MakeUnique(); + for (size_t i = 0; i < registered_parsers_->size(); i++) { + grpc_error* error; auto parsed_obj = - registered_parsers_[i].ParsePerMethodParams(json, &success); - if (!success) { - return false; + (*registered_parsers_)[i].ParsePerMethodParams(json, &error); + if (error != GRPC_ERROR_NONE) { + return error; } - objs_vector->vector.push_back(parsed_obj); + objs_vector->push_back(std::move(parsed_obj)); } + const auto* vector_ptr = objs_vector.get(); + service_config_objects_vectors_storage_.push_back(std::move(objs_vector)); // Construct list of paths. InlinedVector, 10> paths; for (grpc_json* child = json->child; child != nullptr; child = child->next) { if (child->key == nullptr) continue; if (strcmp(child->key, "name") == 0) { - if (child->type != GRPC_JSON_ARRAY) return false; + if (child->type != GRPC_JSON_ARRAY) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "name should be of type Array"); + } for (grpc_json* name = child->child; name != nullptr; name = name->next) { UniquePtr path = ParseJsonMethodName(name); - if (path == nullptr) return false; + if (path == nullptr) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to parse name"); + } paths.push_back(std::move(path)); } } } - if (paths.size() == 0) return false; // No names specified. + if (paths.size() == 0) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "No names specified in methodConfig"); + } // Add entry for each path. for (size_t i = 0; i < paths.size(); ++i) { entries[*idx].key = grpc_slice_from_copied_string(paths[i].get()); - entries[*idx].value = objs_vector; // Takes a new ref. + entries[*idx].value = vector_ptr; // Takes a new ref. ++*idx; } - return true; + return GRPC_ERROR_NONE; } -void ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree, - bool* success) { - GPR_DEBUG_ASSERT(success != nullptr); +grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { GPR_DEBUG_ASSERT(json_tree_->type == GRPC_JSON_OBJECT); GPR_DEBUG_ASSERT(json_tree_->key == nullptr); - SliceHashTable>::Entry* entries = - nullptr; + SliceHashTable::Entry* entries = nullptr; size_t num_entries = 0; for (grpc_json* field = json_tree->child; field != nullptr; field = field->next) { if (field->key == nullptr) { - *success = false; - return; + return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal key value - NULL"); } if (strcmp(field->key, "methodConfig") == 0) { if (entries != nullptr) { GPR_ASSERT(false); } if (field->type != GRPC_JSON_ARRAY) { - *success = false; - return; + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "methodConfig is not of type Array"); } for (grpc_json* method = field->child; method != nullptr; method = method->next) { int count = CountNamesInMethodConfig(method); if (count <= 0) { - *success = false; - return; + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "No names found in methodConfig"); } num_entries += static_cast(count); } entries = static_cast< - SliceHashTable>::Entry*>( - gpr_zalloc( - num_entries * - sizeof(SliceHashTable< - RefCountedPtr>::Entry))); + SliceHashTable::Entry*>(gpr_zalloc( + num_entries * + sizeof(SliceHashTable::Entry))); size_t idx = 0; for (grpc_json* method = field->child; method != nullptr; method = method->next) { - if (!ParseJsonMethodConfigToServiceConfigObjectsTable(method, entries, - &idx)) { + grpc_error* error = ParseJsonMethodConfigToServiceConfigObjectsTable( + method, entries, &idx); + if (error != GRPC_ERROR_NONE) { for (size_t i = 0; i < idx; ++i) { grpc_slice_unref_internal(entries[i].key); - entries[i].value.reset(); } gpr_free(entries); - *success = false; - return; + return error; } } GPR_DEBUG_ASSERT(idx == num_entries); @@ -184,11 +200,11 @@ void ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree, } if (entries != nullptr) { parsed_method_service_config_objects_table_ = - SliceHashTable>::Create( + SliceHashTable::Create( num_entries, entries, nullptr); gpr_free(entries); } - *success = true; + return GRPC_ERROR_NONE; } ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); } @@ -248,4 +264,27 @@ UniquePtr ServiceConfig::ParseJsonMethodName(grpc_json* json) { return UniquePtr(path); } +const ServiceConfig::ServiceConfigObjectsVector* const* +ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) { + const auto* value = parsed_method_service_config_objects_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/*"). + if (value == nullptr) { + char* path_str = grpc_slice_to_c_string(path); + const char* sep = strrchr(path_str, '/') + 1; + const size_t len = (size_t)(sep - path_str); + char* buf = (char*)gpr_malloc(len + 2); // '*' and NUL + memcpy(buf, path_str, len); + buf[len] = '*'; + buf[len + 1] = '\0'; + grpc_slice wildcard_path = grpc_slice_from_copied_string(buf); + gpr_free(buf); + value = parsed_method_service_config_objects_table_->Get(wildcard_path); + grpc_slice_unref_internal(wildcard_path); + gpr_free(path_str); + if (value == nullptr) return nullptr; + } + return value; +} + } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 9752bf7ba27..90f1a2d790c 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -25,6 +25,7 @@ #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/iomgr/error.h" #include "src/core/lib/json/json.h" #include "src/core/lib/slice/slice_hash_table.h" @@ -56,11 +57,9 @@ namespace grpc_core { /// This is the base class that all service config parsers MUST use to store /// parsed service config data. -class ServiceConfigParsedObject : public RefCounted { +class ServiceConfigParsedObject { public: virtual ~ServiceConfigParsedObject() = default; - - GRPC_ABSTRACT_BASE_CLASS; }; /// This is the base class that all service config parsers should derive from. @@ -68,40 +67,31 @@ class ServiceConfigParser { public: virtual ~ServiceConfigParser() = default; - virtual RefCountedPtr ParseGlobalParams( - const grpc_json* json, bool* success) { - if (success != nullptr) { - *success = true; + virtual UniquePtr ParseGlobalParams( + const grpc_json* json, grpc_error** error) { + if (error != nullptr) { + *error = GRPC_ERROR_NONE; } return nullptr; } - virtual RefCountedPtr ParsePerMethodParams( - const grpc_json* json, bool* success) { - if (success != nullptr) { - *success = true; + virtual UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) { + if (error != nullptr) { + *error = GRPC_ERROR_NONE; } return nullptr; } static constexpr int kMaxParsers = 32; - - GRPC_ABSTRACT_BASE_CLASS; -}; - -class ServiceConfigObjectsVector - : public RefCounted { - public: - grpc_core::InlinedVector, - ServiceConfigParser::kMaxParsers> - vector; }; class ServiceConfig : public RefCounted { public: /// Creates a new service config from parsing \a json_string. /// Returns null on parse error. - static RefCountedPtr Create(const char* json); + static RefCountedPtr Create(const char* json, + grpc_error** error); ~ServiceConfig(); @@ -141,34 +131,19 @@ class ServiceConfig : public RefCounted { /// Retrieves the parsed global service config object at index \a index. ServiceConfigParsedObject* GetParsedGlobalServiceConfigObject(int index) { - GPR_DEBUG_ASSERT(index < registered_parsers_count_); + GPR_DEBUG_ASSERT( + index < static_cast(parsed_global_service_config_objects_.size())); return parsed_global_service_config_objects_[index].get(); } + static constexpr int kMaxParsers = 32; + typedef InlinedVector, kMaxParsers> + ServiceConfigObjectsVector; + /// Retrieves the vector of method service config objects for a given path \a /// path. - const RefCountedPtr* - GetMethodServiceConfigObjectsVector(const grpc_slice& path) { - const auto* value = parsed_method_service_config_objects_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/*"). - if (value == nullptr) { - char* path_str = grpc_slice_to_c_string(path); - const char* sep = strrchr(path_str, '/') + 1; - const size_t len = (size_t)(sep - path_str); - char* buf = (char*)gpr_malloc(len + 2); // '*' and NUL - memcpy(buf, path_str, len); - buf[len] = '*'; - buf[len + 1] = '\0'; - grpc_slice wildcard_path = grpc_slice_from_copied_string(buf); - gpr_free(buf); - value = parsed_method_service_config_objects_table_->Get(wildcard_path); - grpc_slice_unref_internal(wildcard_path); - gpr_free(path_str); - if (value == nullptr) return nullptr; - } - return value; - } + const ServiceConfigObjectsVector* const* GetMethodServiceConfigObjectsVector( + const grpc_slice& path); /// Globally register a service config parser. On successful registration, it /// returns the index at which the parser was registered. On failure, -1 is @@ -177,12 +152,22 @@ class ServiceConfig : public RefCounted { /// config json and returning a parsed object. This parsed object can later be /// retrieved using the same index that was returned at registration time. static int RegisterParser(const ServiceConfigParser& parser) { - registered_parsers_[registered_parsers_count_] = parser; - return registered_parsers_count_++; + registered_parsers_->push_back(parser); + return registered_parsers_->size() - 1; } - /// Should be called on initialization and shutdown. - static void ResetServiceConfigParsers() { registered_parsers_count_ = 0; } + typedef InlinedVector + ServiceConfigParserList; + + static void Init() { + GPR_ASSERT(registered_parsers_ == nullptr); + registered_parsers_ = New(); + } + + static void Shutdown() { + Delete(registered_parsers_); + registered_parsers_ = nullptr; + } private: // So New() can call our private ctor. @@ -192,11 +177,11 @@ class ServiceConfig : public RefCounted { // Takes ownership of \a json_tree. ServiceConfig(UniquePtr service_config_json, UniquePtr json_string, grpc_json* json_tree, - bool* success); + grpc_error** error); // Helper functions to parse the service config - void ParseGlobalParams(const grpc_json* json_tree, bool* success); - void ParsePerMethodParams(const grpc_json* json_tree, bool* success); + grpc_error* ParseGlobalParams(const grpc_json* json_tree); + grpc_error* ParsePerMethodParams(const grpc_json* json_tree); // Returns the number of names specified in the method config \a json. static int CountNamesInMethodConfig(grpc_json* json); @@ -213,24 +198,23 @@ class ServiceConfig : public RefCounted { grpc_json* json, CreateValue create_value, typename SliceHashTable>::Entry* entries, size_t* idx); - static bool ParseJsonMethodConfigToServiceConfigObjectsTable( + grpc_error* ParseJsonMethodConfigToServiceConfigObjectsTable( const grpc_json* json, - SliceHashTable>::Entry* entries, + SliceHashTable::Entry* entries, size_t* idx); - static int registered_parsers_count_; - static ServiceConfigParser - registered_parsers_[ServiceConfigParser::kMaxParsers]; + static ServiceConfigParserList* registered_parsers_; UniquePtr service_config_json_; UniquePtr json_string_; // Underlying storage for json_tree. grpc_json* json_tree_; - InlinedVector, - ServiceConfigParser::kMaxParsers> + InlinedVector, kMaxParsers> parsed_global_service_config_objects_; - RefCountedPtr>> + RefCountedPtr> parsed_method_service_config_objects_table_; + InlinedVector, kMaxParsers> + service_config_objects_vectors_storage_; }; // diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 8bb0c4c3498..d66779e6192 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -591,7 +591,7 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, grpc_channel_args_find(args_, GRPC_ARG_SERVICE_CONFIG)); if (service_config_json != nullptr) { RefCountedPtr service_config = - ServiceConfig::Create(service_config_json); + ServiceConfig::Create(service_config_json, nullptr); if (service_config != nullptr) { HealthCheckParams params; service_config->ParseGlobalParams(HealthCheckParams::Parse, ¶ms); 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 8a422ddca54..8c2a32cc618 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -320,7 +320,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, const char* service_config_str = grpc_channel_arg_get_string(channel_arg); if (service_config_str != nullptr) { grpc_core::RefCountedPtr service_config = - grpc_core::ServiceConfig::Create(service_config_str); + grpc_core::ServiceConfig::Create(service_config_str, nullptr); if (service_config != nullptr) { chand->method_limit_table = service_config->CreateMethodConfigTable( grpc_core::MessageSizeLimits::CreateFromJson); From 190609d332e4b413a4e1ffd93b66ca99ebe6927b Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Thu, 4 Apr 2019 13:01:47 -0700 Subject: [PATCH 1762/2143] add v1.19.0 to interop matrix for cxx, python, csharp --- tools/interop_matrix/client_matrix.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 654dfd6faef..013b9d0f1ee 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -99,6 +99,7 @@ LANG_RELEASE_MATRIX = { ('v1.16.0', ReleaseInfo()), ('v1.17.1', ReleaseInfo()), ('v1.18.0', ReleaseInfo()), + ('v1.19.0', ReleaseInfo()), ]), 'go': OrderedDict([ @@ -164,6 +165,7 @@ LANG_RELEASE_MATRIX = { ('v1.16.0', ReleaseInfo(testcases_file='python__v1.11.1')), ('v1.17.1', ReleaseInfo(testcases_file='python__v1.11.1')), ('v1.18.0', ReleaseInfo()), + ('v1.19.0', ReleaseInfo()), ]), 'node': OrderedDict([ @@ -210,6 +212,9 @@ LANG_RELEASE_MATRIX = { ReleaseInfo(patch=[ 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', ])), + # TODO: https://github.com/grpc/grpc/issues/18262. + # If you are not encountering the error in above issue + # go ahead and upload the docker image for new releases. ]), 'php': OrderedDict([ @@ -231,6 +236,8 @@ LANG_RELEASE_MATRIX = { ('v1.16.0', ReleaseInfo()), ('v1.17.1', ReleaseInfo()), ('v1.18.0', ReleaseInfo()), + # TODO:https://github.com/grpc/grpc/issues/18264 + # Error in above issues needs to be resolved. ]), 'csharp': OrderedDict([ @@ -258,5 +265,6 @@ LANG_RELEASE_MATRIX = { ('v1.16.0', ReleaseInfo(testcases_file='csharp__v1.3.9')), ('v1.17.1', ReleaseInfo(testcases_file='csharp__v1.3.9')), ('v1.18.0', ReleaseInfo()), + ('v1.19.0', ReleaseInfo()), ]), } From fbe3b3575fcb8f16327e16b36b2dfcc2d5e82018 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 4 Apr 2019 16:05:43 -0700 Subject: [PATCH 1763/2143] Cleanup and continue parsing service config even if parser errors are received --- .../filters/client_channel/service_config.cc | 87 ++++++++----------- .../filters/client_channel/service_config.h | 36 ++++---- 2 files changed, 56 insertions(+), 67 deletions(-) diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index fbeb578a08b..b03bbb127ef 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -33,19 +33,19 @@ namespace grpc_core { -ServiceConfig::ServiceConfigParserList* ServiceConfig::registered_parsers_ = - nullptr; - +ServiceConfig::ServiceConfigParserList* ServiceConfig::registered_parsers_; RefCountedPtr ServiceConfig::Create(const char* json, grpc_error** error) { 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"); + if (error != nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "failed to parse JSON for service config"); + } return nullptr; } - grpc_error* create_error; auto return_value = MakeRefCounted( std::move(service_config_json), std::move(json_string), json_tree, @@ -70,37 +70,28 @@ ServiceConfig::ServiceConfig(UniquePtr service_config_json, : service_config_json_(std::move(service_config_json)), json_string_(std::move(json_string)), json_tree_(json_tree) { + GPR_DEBUG_ASSERT(error != nullptr); if (json_tree->type != GRPC_JSON_OBJECT || json_tree->key != nullptr) { - if (error != nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Malformed service Config JSON object"); - } + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Malformed service Config JSON object"); return; } - grpc_error* parser_error = ParseGlobalParams(json_tree); - if (parser_error != GRPC_ERROR_NONE) { - parser_error = ParsePerMethodParams(json_tree); - } - if (error != nullptr) { - *error = parser_error; - } else { - GRPC_ERROR_UNREF(parser_error); - } + *error = ParseGlobalParams(json_tree); + *error = grpc_error_add_child(*error, ParsePerMethodParams(json_tree)); } grpc_error* ServiceConfig::ParseGlobalParams(const grpc_json* json_tree) { GPR_DEBUG_ASSERT(json_tree_->type == GRPC_JSON_OBJECT); GPR_DEBUG_ASSERT(json_tree_->key == nullptr); + grpc_error* error = GRPC_ERROR_NONE; for (size_t i = 0; i < registered_parsers_->size(); i++) { - grpc_error* error; + grpc_error* parser_error = GRPC_ERROR_NONE; auto parsed_obj = - (*registered_parsers_)[i].ParseGlobalParams(json_tree, &error); - if (error != GRPC_ERROR_NONE) { - return error; - } + (*registered_parsers_)[i].ParseGlobalParams(json_tree, &parser_error); + error = grpc_error_add_child(error, parser_error); parsed_global_service_config_objects_.push_back(std::move(parsed_obj)); } - return GRPC_ERROR_NONE; + return error; } grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( @@ -108,13 +99,12 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( SliceHashTable::Entry* entries, size_t* idx) { auto objs_vector = MakeUnique(); + grpc_error* error = GRPC_ERROR_NONE; for (size_t i = 0; i < registered_parsers_->size(); i++) { - grpc_error* error; + grpc_error* parser_error = GRPC_ERROR_NONE; auto parsed_obj = (*registered_parsers_)[i].ParsePerMethodParams(json, &error); - if (error != GRPC_ERROR_NONE) { - return error; - } + error = grpc_error_add_child(error, parser_error); objs_vector->push_back(std::move(parsed_obj)); } const auto* vector_ptr = objs_vector.get(); @@ -125,8 +115,8 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( if (child->key == nullptr) continue; if (strcmp(child->key, "name") == 0) { if (child->type != GRPC_JSON_ARRAY) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "name should be of type Array"); + return grpc_error_add_child(error, GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "name should be of type Array")); } for (grpc_json* name = child->child; name != nullptr; name = name->next) { UniquePtr path = ParseJsonMethodName(name); @@ -138,8 +128,9 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( } } if (paths.size() == 0) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No names specified in methodConfig"); + return grpc_error_add_child(error, + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "No names specified in methodConfig")); } // Add entry for each path. for (size_t i = 0; i < paths.size(); ++i) { @@ -147,7 +138,7 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( entries[*idx].value = vector_ptr; // Takes a new ref. ++*idx; } - return GRPC_ERROR_NONE; + return error; } grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { @@ -155,25 +146,30 @@ grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { GPR_DEBUG_ASSERT(json_tree_->key == nullptr); SliceHashTable::Entry* entries = nullptr; size_t num_entries = 0; + grpc_error* error = GRPC_ERROR_NONE; for (grpc_json* field = json_tree->child; field != nullptr; field = field->next) { if (field->key == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal key value - NULL"); + error = grpc_error_add_child(error, GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Illegal key value - NULL")); + continue; } if (strcmp(field->key, "methodConfig") == 0) { if (entries != nullptr) { GPR_ASSERT(false); } if (field->type != GRPC_JSON_ARRAY) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "methodConfig is not of type Array"); + return grpc_error_add_child(error, + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "methodConfig is not of type Array")); } for (grpc_json* method = field->child; method != nullptr; method = method->next) { int count = CountNamesInMethodConfig(method); if (count <= 0) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No names found in methodConfig"); + error = grpc_error_add_child(error, + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "No names found in methodConfig")); } num_entries += static_cast(count); } @@ -184,17 +180,10 @@ grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { size_t idx = 0; for (grpc_json* method = field->child; method != nullptr; method = method->next) { - grpc_error* error = ParseJsonMethodConfigToServiceConfigObjectsTable( - method, entries, &idx); - if (error != GRPC_ERROR_NONE) { - for (size_t i = 0; i < idx; ++i) { - grpc_slice_unref_internal(entries[i].key); - } - gpr_free(entries); - return error; - } + error = grpc_error_add_child( + error, ParseJsonMethodConfigToServiceConfigObjectsTable( + method, entries, &idx)); } - GPR_DEBUG_ASSERT(idx == num_entries); break; } } @@ -204,7 +193,7 @@ grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { num_entries, entries, nullptr); gpr_free(entries); } - return GRPC_ERROR_NONE; + return error; } ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); } diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 90f1a2d790c..e371af2746e 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -60,6 +60,8 @@ namespace grpc_core { class ServiceConfigParsedObject { public: virtual ~ServiceConfigParsedObject() = default; + + GRPC_ABSTRACT_BASE_CLASS; }; /// This is the base class that all service config parsers should derive from. @@ -69,25 +71,28 @@ class ServiceConfigParser { virtual UniquePtr ParseGlobalParams( const grpc_json* json, grpc_error** error) { - if (error != nullptr) { - *error = GRPC_ERROR_NONE; - } + GPR_DEBUG_ASSERT(error != nullptr); + *error = GRPC_ERROR_NONE; return nullptr; } virtual UniquePtr ParsePerMethodParams( const grpc_json* json, grpc_error** error) { - if (error != nullptr) { - *error = GRPC_ERROR_NONE; - } + GPR_DEBUG_ASSERT(error != nullptr); + *error = GRPC_ERROR_NONE; return nullptr; } - static constexpr int kMaxParsers = 32; + GRPC_ABSTRACT_BASE_CLASS; }; class ServiceConfig : public RefCounted { public: + static constexpr int kNumPreallocatedParsers = 4; + typedef InlinedVector, + kNumPreallocatedParsers> + ServiceConfigObjectsVector; + /// Creates a new service config from parsing \a json_string. /// Returns null on parse error. static RefCountedPtr Create(const char* json, @@ -136,10 +141,6 @@ class ServiceConfig : public RefCounted { return parsed_global_service_config_objects_[index].get(); } - static constexpr int kMaxParsers = 32; - typedef InlinedVector, kMaxParsers> - ServiceConfigObjectsVector; - /// Retrieves the vector of method service config objects for a given path \a /// path. const ServiceConfigObjectsVector* const* GetMethodServiceConfigObjectsVector( @@ -151,14 +152,11 @@ class ServiceConfig : public RefCounted { /// registered parser. Each parser is responsible for reading the service /// config json and returning a parsed object. This parsed object can later be /// retrieved using the same index that was returned at registration time. - static int RegisterParser(const ServiceConfigParser& parser) { - registered_parsers_->push_back(parser); + static int RegisterParser(ServiceConfigParser parser) { + registered_parsers_->push_back(std::move(parser)); return registered_parsers_->size() - 1; } - typedef InlinedVector - ServiceConfigParserList; - static void Init() { GPR_ASSERT(registered_parsers_ == nullptr); registered_parsers_ = New(); @@ -170,6 +168,8 @@ class ServiceConfig : public RefCounted { } private: + typedef InlinedVector + ServiceConfigParserList; // So New() can call our private ctor. template friend T* New(Args&&... args); @@ -209,11 +209,11 @@ class ServiceConfig : public RefCounted { UniquePtr json_string_; // Underlying storage for json_tree. grpc_json* json_tree_; - InlinedVector, kMaxParsers> + InlinedVector, kNumPreallocatedParsers> parsed_global_service_config_objects_; RefCountedPtr> parsed_method_service_config_objects_table_; - InlinedVector, kMaxParsers> + InlinedVector, 32> service_config_objects_vectors_storage_; }; From 4ae20ad9726b6a38b3db3e485c2cd99520077785 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 26 Mar 2019 10:45:02 -0700 Subject: [PATCH 1764/2143] Fix count in xds/grpclb test --- test/cpp/end2end/grpclb_end2end_test.cc | 152 ++++++++++++------------ test/cpp/end2end/xds_end2end_test.cc | 4 + 2 files changed, 77 insertions(+), 79 deletions(-) diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 3afcd0c578f..a08d6aa2ee1 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -207,67 +207,74 @@ class BalancerServiceImpl : public BalancerService { client_load_reporting_interval_seconds) {} Status BalanceLoad(ServerContext* context, Stream* stream) override { - // Balancer shouldn't receive the call credentials metadata. - EXPECT_EQ(context->client_metadata().find(g_kCallCredsMdKey), - context->client_metadata().end()); gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this); - 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()); - - // TODO(juanlishen): Initial response should always be the first response. - if (client_load_reporting_interval_seconds_ > 0) { - 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) { - SendResponse(stream, response_and_delay.first, response_and_delay.second); + if (serverlist_done_) goto done; } { - std::unique_lock lock(mu_); - serverlist_cond_.wait(lock, [this] { return serverlist_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 (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(); + if (!stream->Read(&request)) { + goto done; + } + IncreaseRequestCount(); + gpr_log(GPR_INFO, "LB[%p]: received initial message '%s'", this, + request.DebugString().c_str()); + + // TODO(juanlishen): Initial response should always be the first response. + if (client_load_reporting_interval_seconds_ > 0) { + 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) { + SendResponse(stream, response_and_delay.first, + response_and_delay.second); + } + { + std::unique_lock lock(mu_); + serverlist_cond_.wait(lock, [this] { return serverlist_done_; }); + } + + 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(); } - load_report_ready_ = true; - load_report_cond_.notify_one(); } } done: @@ -1365,7 +1372,7 @@ class UpdatesTest : public GrpclbEnd2endTest { UpdatesTest() : GrpclbEnd2endTest(4, 3, 0) {} }; -TEST_F(UpdatesTest, UpdateBalancers) { +TEST_F(UpdatesTest, UpdateBalancersButKeepUsingOriginalBalancer) { SetNextResolutionAllBalancers(); const std::vector first_backend{GetBackendPorts()[0]}; const std::vector second_backend{GetBackendPorts()[1]}; @@ -1385,9 +1392,6 @@ TEST_F(UpdatesTest, UpdateBalancers) { // All 10 requests should have gone to the first backend. EXPECT_EQ(10U, backends_[0]->service_.request_count()); - balancers_[0]->service_.NotifyDoneWithServerlists(); - balancers_[1]->service_.NotifyDoneWithServerlists(); - balancers_[2]->service_.NotifyDoneWithServerlists(); // Balancer 0 got a single request. EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. @@ -1403,25 +1407,21 @@ TEST_F(UpdatesTest, UpdateBalancers) { 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, backends_[1]->service_.request_count()); - WaitForBackend(1); + 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 grpclb continued using it to the + // first balancer, which doesn't assign the second backend. + EXPECT_EQ(0U, backends_[1]->service_.request_count()); - 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, backends_[1]->service_.request_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_[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()); } @@ -1532,9 +1532,6 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { EXPECT_EQ(20U, backends_[0]->service_.request_count()); EXPECT_EQ(0U, backends_[1]->service_.request_count()); - balancers_[0]->service_.NotifyDoneWithServerlists(); - balancers_[1]->service_.NotifyDoneWithServerlists(); - balancers_[2]->service_.NotifyDoneWithServerlists(); // Balancer 0 got a single request. EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. @@ -1564,9 +1561,6 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { // All 10 requests should have gone to the second backend. EXPECT_EQ(10U, backends_[1]->service_.request_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 diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index 8657ba78d90..6d3ede141f4 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -207,6 +207,10 @@ class BalancerServiceImpl : public BalancerService { 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 (serverlist_done_) goto done; + } { // Balancer shouldn't receive the call credentials metadata. EXPECT_EQ(context->client_metadata().find(g_kCallCredsMdKey), From 9b42ab79e087879dfebaab618bd63d019d322834 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 4 Apr 2019 16:40:16 -0700 Subject: [PATCH 1765/2143] Make build fixes for bazel build :all --- include/grpcpp/impl/server_builder_plugin.h | 2 +- include/grpcpp/security/credentials.h | 1 - include/grpcpp/support/channel_arguments_impl.h | 2 +- src/cpp/client/create_channel.cc | 4 ---- 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h index 9ab40bd7615..ccc8b832760 100644 --- a/include/grpcpp/impl/server_builder_plugin.h +++ b/include/grpcpp/impl/server_builder_plugin.h @@ -26,10 +26,10 @@ namespace grpc_impl { class ChannelArguments; -class ServerBuilder; class ServerInitializer; } // namespace grpc_impl namespace grpc { +class ServerBuilder; /// This interface is meant for internal usage only. Implementations of this /// interface should add themselves to a \a ServerBuilder instance through the diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 43f68f3a9fa..8662b068a59 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -35,7 +35,6 @@ struct grpc_call; namespace grpc { class CallCredentials; -class ChannelArguments; class ChannelCredentials; } // namespace grpc namespace grpc_impl { diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h index 1e1340e716d..8276c1d9099 100644 --- a/include/grpcpp/support/channel_arguments_impl.h +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -24,6 +24,7 @@ #include #include +#include #include namespace grpc { @@ -31,7 +32,6 @@ namespace testing { class ChannelArgumentsTest; } // namespace testing -class ResourceQuota; class SecureChannelCredentials; } // namespace grpc diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 9426a4e7f6e..15bc193af72 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -25,10 +25,6 @@ #include "src/cpp/client/create_channel_internal.h" -namespace grpc { - -class ChannelArguments; -} namespace grpc_impl { std::shared_ptr CreateChannel( const grpc::string& target, From d74e4079c535bc6b9348394cb820bfb03b8531f7 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 4 Apr 2019 15:38:51 -0700 Subject: [PATCH 1766/2143] upgrade bazel to 0.23.2 for docker legacy bazel builds excluded Python tests from Bazel legacy C/C++ Kokoro CI jobs disabled building examples due to existance of python --- templates/tools/dockerfile/bazel.include | 6 +++--- tools/dockerfile/test/bazel/Dockerfile | 6 +++--- tools/dockerfile/test/sanity/Dockerfile | 6 +++--- tools/internal_ci/linux/grpc_bazel_build_in_docker.sh | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/templates/tools/dockerfile/bazel.include b/templates/tools/dockerfile/bazel.include index 62d68607453..8888e938f43 100644 --- a/templates/tools/dockerfile/bazel.include +++ b/templates/tools/dockerfile/bazel.include @@ -2,6 +2,6 @@ # 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 +RUN wget https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-installer-linux-x86_64.sh && ${'\\'} + bash ./bazel-0.23.2-installer-linux-x86_64.sh && ${'\\'} + rm bazel-0.23.2-installer-linux-x86_64.sh diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile index 7dee0051176..2536fe299cb 100644 --- a/tools/dockerfile/test/bazel/Dockerfile +++ b/tools/dockerfile/test/bazel/Dockerfile @@ -52,9 +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 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 wget https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-installer-linux-x86_64.sh && \ + bash ./bazel-0.23.2-installer-linux-x86_64.sh && \ + rm bazel-0.23.2-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 7a6fbfee7f4..765bd7267a4 100644 --- a/tools/dockerfile/test/sanity/Dockerfile +++ b/tools/dockerfile/test/sanity/Dockerfile @@ -98,9 +98,9 @@ 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 +RUN wget https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-installer-linux-x86_64.sh && \ + bash ./bazel-0.23.2-installer-linux-x86_64.sh && \ + rm bazel-0.23.2-installer-linux-x86_64.sh # Define the default command. diff --git a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh index 24598f43f02..343ca17793d 100755 --- a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh +++ b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh @@ -24,4 +24,4 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc && git submodule update --init --reference /var/local/jenkins/grpc/${name} \ ${name}') cd /var/local/git/grpc -bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/... +bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... From 1f84f8950c04dc0890bd1c4f709d0a99e8af5b53 Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Thu, 4 Apr 2019 17:45:00 -0700 Subject: [PATCH 1767/2143] Remove vestigial sed for /etc/apt/sources.list in Dockerfiles Jessie has a line that looks like this, now-a-days, so the regex is no longer matching: deb http://security.debian.org/debian-security jessie/updates main But because that line was changed, downloads are also working correctly out-of-the-box. The sed was originally added in #18530. --- templates/tools/dockerfile/debian_jessie_header.include | 1 - tools/dockerfile/grpc_clang_format/Dockerfile | 1 - tools/dockerfile/grpc_clang_tidy/Dockerfile | 1 - tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile | 1 - tools/dockerfile/interoptest/grpc_interop_java/Dockerfile | 1 - .../dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile | 1 - tools/dockerfile/interoptest/grpc_interop_node/Dockerfile | 1 - tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile | 1 - tools/dockerfile/interoptest/grpc_interop_php/Dockerfile | 1 - tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile | 1 - tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile | 1 - tools/dockerfile/test/cxx_jessie_x64/Dockerfile | 1 - tools/dockerfile/test/fuzzer/Dockerfile | 1 - tools/dockerfile/test/node_jessie_x64/Dockerfile | 1 - tools/dockerfile/test/php7_jessie_x64/Dockerfile | 1 - tools/dockerfile/test/php_jessie_x64/Dockerfile | 1 - tools/dockerfile/test/python_jessie_x64/Dockerfile | 1 - tools/dockerfile/test/ruby_jessie_x64/Dockerfile | 1 - 18 files changed, 18 deletions(-) diff --git a/templates/tools/dockerfile/debian_jessie_header.include b/templates/tools/dockerfile/debian_jessie_header.include index 11bd5f9b129..f71f98626f3 100644 --- a/templates/tools/dockerfile/debian_jessie_header.include +++ b/templates/tools/dockerfile/debian_jessie_header.include @@ -1,2 +1 @@ FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list diff --git a/tools/dockerfile/grpc_clang_format/Dockerfile b/tools/dockerfile/grpc_clang_format/Dockerfile index 8e5edf75d52..876992fd99d 100644 --- a/tools/dockerfile/grpc_clang_format/Dockerfile +++ b/tools/dockerfile/grpc_clang_format/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list RUN apt-get update && apt-get -y install wget xz-utils diff --git a/tools/dockerfile/grpc_clang_tidy/Dockerfile b/tools/dockerfile/grpc_clang_tidy/Dockerfile index 2e0e683c202..a5abca0c6e3 100644 --- a/tools/dockerfile/grpc_clang_tidy/Dockerfile +++ b/tools/dockerfile/grpc_clang_tidy/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list RUN apt-get update && apt-get -y install wget xz-utils diff --git a/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile index 1fe64a462aa..e9f2a853344 100644 --- a/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. diff --git a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile index d16830688ca..a2be2f3465b 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install JDK 8 and Git diff --git a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile index d16830688ca..a2be2f3465b 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install JDK 8 and Git diff --git a/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile index 96adf6edd86..283a99d0c5f 100644 --- a/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. diff --git a/tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile index 88e3cfacd97..fd089f1bc4d 100644 --- a/tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. diff --git a/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile index c9c141e5d54..04f0ac2a659 100644 --- a/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. diff --git a/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile index 84241391dfc..01de0eb39e9 100644 --- a/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list #================= diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile index cce5e86cd37..8e605a8c341 100644 --- a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. diff --git a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile index c46f9618b17..b79faa09c05 100644 --- a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. diff --git a/tools/dockerfile/test/fuzzer/Dockerfile b/tools/dockerfile/test/fuzzer/Dockerfile index 14e447891da..f9dd948a1b3 100644 --- a/tools/dockerfile/test/fuzzer/Dockerfile +++ b/tools/dockerfile/test/fuzzer/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. diff --git a/tools/dockerfile/test/node_jessie_x64/Dockerfile b/tools/dockerfile/test/node_jessie_x64/Dockerfile index 0ef32109ded..7c0b86acc0c 100644 --- a/tools/dockerfile/test/node_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/node_jessie_x64/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. diff --git a/tools/dockerfile/test/php7_jessie_x64/Dockerfile b/tools/dockerfile/test/php7_jessie_x64/Dockerfile index a32b764cfb9..5cca63d4f02 100644 --- a/tools/dockerfile/test/php7_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php7_jessie_x64/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list #================= diff --git a/tools/dockerfile/test/php_jessie_x64/Dockerfile b/tools/dockerfile/test/php_jessie_x64/Dockerfile index ebbbcf524cd..ee54263f96a 100644 --- a/tools/dockerfile/test/php_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php_jessie_x64/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. diff --git a/tools/dockerfile/test/python_jessie_x64/Dockerfile b/tools/dockerfile/test/python_jessie_x64/Dockerfile index 5ac3af8b26d..367785f42fd 100644 --- a/tools/dockerfile/test/python_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/python_jessie_x64/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. diff --git a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile index ae460756f88..767040907b2 100644 --- a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile @@ -13,7 +13,6 @@ # limitations under the License. FROM debian:jessie -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. From 977e4b1450d9910ccc51f2f8de51e2e00349c969 Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Thu, 4 Apr 2019 18:23:00 -0700 Subject: [PATCH 1768/2143] grpc_interop_java: Remove unnecessary cruft from container This reduces the container size from 1.4 GB to 640 MB. 129 MB is jessie, 489 MB jdk, and 22 MB grpc-java. When we swap from jessie to stretch, we could swap to openjdk:8-jdk-slim-stretch which would make the entire image 265 MB. Python was never needed; it was added by mistake in 0589e533. Pre-downloading gradle artifacts isn't helpful these days, because we build on a clean machine. Git isn't needed as cp is sufficient. libapr1 has not been required by tcnative for a long time, and we even use tcnative-boringssl-static since at least 1.0, which also doesn't need it. The final cleanup is to remove source and downloaded artifacts when done compiling. --- .../Dockerfile.include | 9 +---- .../java_deps.include | 13 +++---- .../dockerfile/java_build_interop.sh.include | 16 ++++++--- .../interoptest/grpc_interop_java/Dockerfile | 35 +++---------------- .../grpc_interop_java/build_interop.sh | 16 ++++++--- .../grpc_interop_java_oracle8/Dockerfile | 35 +++---------------- .../build_interop.sh | 16 ++++++--- 7 files changed, 51 insertions(+), 89 deletions(-) diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.include b/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.include index e80b51778c6..7307e29f0a0 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.include +++ b/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.include @@ -15,13 +15,6 @@ <%include file="../../debian_jessie_header.include"/> <%include file="java_deps.include"/> -<%include file="../../python_deps.include"/> - -# Trigger download of as many Gradle artifacts as possible. -RUN git clone --recursive --depth 1 https://github.com/grpc/grpc-java.git && ${'\\'} - cd grpc-java && ${'\\'} - ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true && ${'\\'} - rm -r "$(pwd)" # Define the default command. -CMD ["bash"] \ No newline at end of file +CMD ["bash"] diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/java_deps.include b/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/java_deps.include index 40d70e06d1a..c05b5642393 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/java_deps.include +++ b/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/java_deps.include @@ -1,16 +1,11 @@ -# Install JDK 8 and Git +# Install JDK 8 # RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && ${'\\'} echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list && ${'\\'} echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list && ${'\\'} - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 - -RUN apt-get update && apt-get -y install ${'\\'} - git ${'\\'} - libapr1 ${'\\'} - oracle-java8-installer ${'\\'} - && ${'\\'} - apt-get clean && rm -r /var/cache/oracle-jdk8-installer/ + apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 && ${'\\'} + apt-get update && apt-get -y install oracle-java8-installer && ${'\\'} + apt-get clean && rm -r /var/cache/oracle-jdk8-installer/ ENV JAVA_HOME /usr/lib/jvm/java-8-oracle ENV PATH $PATH:$JAVA_HOME/bin diff --git a/templates/tools/dockerfile/java_build_interop.sh.include b/templates/tools/dockerfile/java_build_interop.sh.include index 16d5fb65cf1..e30b53e3f2a 100755 --- a/templates/tools/dockerfile/java_build_interop.sh.include +++ b/templates/tools/dockerfile/java_build_interop.sh.include @@ -16,16 +16,24 @@ # Builds Java interop server and client in a base image. set -e -mkdir -p /var/local/git -git clone --recursive --depth 1 /var/local/jenkins/grpc-java /var/local/git/grpc-java +cp -r /var/local/jenkins/grpc-java /tmp/grpc-java # copy service account keys if available cp -r /var/local/jenkins/service_account $HOME || true -cd /var/local/git/grpc-java - +pushd /tmp/grpc-java ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true +mkdir -p /var/local/git/grpc-java/ +cp -r --parents -t /var/local/git/grpc-java/ ${'\\'} + interop-testing/build/install/ ${'\\'} + run-test-client.sh ${'\\'} + run-test-server.sh + +popd +rm -r /tmp/grpc-java +rm -r "$HOME/.gradle" + # enable extra java logging mkdir -p /var/local/grpc_java_logging echo "handlers = java.util.logging.ConsoleHandler diff --git a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile index d16830688ca..217175159df 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile @@ -16,45 +16,20 @@ FROM debian:jessie RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list -# Install JDK 8 and Git +# Install JDK 8 # RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && \ echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list && \ echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list && \ - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 - -RUN apt-get update && apt-get -y install \ - git \ - libapr1 \ - oracle-java8-installer \ - && \ - apt-get clean && rm -r /var/cache/oracle-jdk8-installer/ + apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 && \ + apt-get update && apt-get -y install oracle-java8-installer && \ + apt-get clean && rm -r /var/cache/oracle-jdk8-installer/ ENV JAVA_HOME /usr/lib/jvm/java-8-oracle ENV PATH $PATH:$JAVA_HOME/bin -#==================== -# 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 - - -# Trigger download of as many Gradle artifacts as possible. -RUN git clone --recursive --depth 1 https://github.com/grpc/grpc-java.git && \ - cd grpc-java && \ - ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true && \ - rm -r "$(pwd)" # Define the default command. CMD ["bash"] + diff --git a/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh index 0e36c193c91..8e1154679d7 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh @@ -16,16 +16,24 @@ # Builds Java interop server and client in a base image. set -e -mkdir -p /var/local/git -git clone --recursive --depth 1 /var/local/jenkins/grpc-java /var/local/git/grpc-java +cp -r /var/local/jenkins/grpc-java /tmp/grpc-java # copy service account keys if available cp -r /var/local/jenkins/service_account $HOME || true -cd /var/local/git/grpc-java - +pushd /tmp/grpc-java ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true +mkdir -p /var/local/git/grpc-java/ +cp -r --parents -t /var/local/git/grpc-java/ \ + interop-testing/build/install/ \ + run-test-client.sh \ + run-test-server.sh + +popd +rm -r /tmp/grpc-java +rm -r "$HOME/.gradle" + # enable extra java logging mkdir -p /var/local/grpc_java_logging echo "handlers = java.util.logging.ConsoleHandler diff --git a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile index d16830688ca..217175159df 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile @@ -16,45 +16,20 @@ FROM debian:jessie RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list -# Install JDK 8 and Git +# Install JDK 8 # RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && \ echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list && \ echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list && \ - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 - -RUN apt-get update && apt-get -y install \ - git \ - libapr1 \ - oracle-java8-installer \ - && \ - apt-get clean && rm -r /var/cache/oracle-jdk8-installer/ + apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 && \ + apt-get update && apt-get -y install oracle-java8-installer && \ + apt-get clean && rm -r /var/cache/oracle-jdk8-installer/ ENV JAVA_HOME /usr/lib/jvm/java-8-oracle ENV PATH $PATH:$JAVA_HOME/bin -#==================== -# 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 - - -# Trigger download of as many Gradle artifacts as possible. -RUN git clone --recursive --depth 1 https://github.com/grpc/grpc-java.git && \ - cd grpc-java && \ - ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true && \ - rm -r "$(pwd)" # Define the default command. CMD ["bash"] + diff --git a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh index 4c5ba4b7a3a..77d322882f7 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh @@ -16,16 +16,24 @@ # Builds Java interop server and client in a base image. set -e -mkdir -p /var/local/git -git clone --recursive --depth 1 /var/local/jenkins/grpc-java /var/local/git/grpc-java +cp -r /var/local/jenkins/grpc-java /tmp/grpc-java # copy service account keys if available cp -r /var/local/jenkins/service_account $HOME || true -cd /var/local/git/grpc-java - +pushd /tmp/grpc-java ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true +mkdir -p /var/local/git/grpc-java/ +cp -r --parents -t /var/local/git/grpc-java/ \ + interop-testing/build/install/ \ + run-test-client.sh \ + run-test-server.sh + +popd +rm -r /tmp/grpc-java +rm -r "$HOME/.gradle" + # enable extra java logging mkdir -p /var/local/grpc_java_logging echo "handlers = java.util.logging.ConsoleHandler From 390078b7a8a82b15de1c52a22e3e2d98b5843f24 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 4 Apr 2019 18:55:10 -0700 Subject: [PATCH 1769/2143] Add tests for new service config mechanism --- CMakeLists.txt | 40 ++++ Makefile | 48 ++++ build.yaml | 13 ++ .../filters/client_channel/service_config.cc | 4 +- .../filters/client_channel/service_config.h | 6 +- test/core/client_channel/BUILD | 14 ++ .../client_channel/service_config_test.cc | 221 ++++++++++++++++++ .../generated/sources_and_headers.json | 18 ++ tools/run_tests/generated/tests.json | 24 ++ 9 files changed, 382 insertions(+), 6 deletions(-) create mode 100644 test/core/client_channel/service_config_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index e7857d5d84e..7554de69936 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -698,6 +698,7 @@ add_dependencies(buildtests_cxx server_crash_test_client) add_dependencies(buildtests_cxx server_early_return_test) add_dependencies(buildtests_cxx server_interceptors_end2end_test) add_dependencies(buildtests_cxx server_request_call_test) +add_dependencies(buildtests_cxx service_config_test) add_dependencies(buildtests_cxx shutdown_test) add_dependencies(buildtests_cxx slice_hash_table_test) add_dependencies(buildtests_cxx slice_weak_hash_table_test) @@ -15679,6 +15680,45 @@ target_link_libraries(server_request_call_test ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(service_config_test + test/core/client_channel/service_config_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(service_config_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(service_config_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 c0b277f0fb1..a1c8118b8ab 100644 --- a/Makefile +++ b/Makefile @@ -1261,6 +1261,7 @@ server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client server_early_return_test: $(BINDIR)/$(CONFIG)/server_early_return_test server_interceptors_end2end_test: $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test server_request_call_test: $(BINDIR)/$(CONFIG)/server_request_call_test +service_config_test: $(BINDIR)/$(CONFIG)/service_config_test shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test slice_hash_table_test: $(BINDIR)/$(CONFIG)/slice_hash_table_test slice_weak_hash_table_test: $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test @@ -1725,6 +1726,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/server_early_return_test \ $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test \ $(BINDIR)/$(CONFIG)/server_request_call_test \ + $(BINDIR)/$(CONFIG)/service_config_test \ $(BINDIR)/$(CONFIG)/shutdown_test \ $(BINDIR)/$(CONFIG)/slice_hash_table_test \ $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test \ @@ -1866,6 +1868,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/server_early_return_test \ $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test \ $(BINDIR)/$(CONFIG)/server_request_call_test \ + $(BINDIR)/$(CONFIG)/service_config_test \ $(BINDIR)/$(CONFIG)/shutdown_test \ $(BINDIR)/$(CONFIG)/slice_hash_table_test \ $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test \ @@ -2377,6 +2380,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test || ( echo test server_interceptors_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing server_request_call_test" $(Q) $(BINDIR)/$(CONFIG)/server_request_call_test || ( echo test server_request_call_test failed ; exit 1 ) + $(E) "[RUN] Testing service_config_test" + $(Q) $(BINDIR)/$(CONFIG)/service_config_test || ( echo test service_config_test failed ; exit 1 ) $(E) "[RUN] Testing shutdown_test" $(Q) $(BINDIR)/$(CONFIG)/shutdown_test || ( echo test shutdown_test failed ; exit 1 ) $(E) "[RUN] Testing slice_hash_table_test" @@ -18601,6 +18606,49 @@ endif $(OBJDIR)/$(CONFIG)/test/cpp/server/server_request_call_test.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc +SERVICE_CONFIG_TEST_SRC = \ + test/core/client_channel/service_config_test.cc \ + +SERVICE_CONFIG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVICE_CONFIG_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/service_config_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)/service_config_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/service_config_test: $(PROTOBUF_DEP) $(SERVICE_CONFIG_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) $(SERVICE_CONFIG_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)/service_config_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/client_channel/service_config_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_service_config_test: $(SERVICE_CONFIG_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(SERVICE_CONFIG_TEST_OBJS:.o=.dep) +endif +endif + + SHUTDOWN_TEST_SRC = \ test/cpp/end2end/shutdown_test.cc \ diff --git a/build.yaml b/build.yaml index c1271be9131..4272cdbcdf4 100644 --- a/build.yaml +++ b/build.yaml @@ -5441,6 +5441,19 @@ targets: - grpc++_unsecure - grpc_unsecure - gpr +- name: service_config_test + gtest: true + build: test + language: c++ + src: + - test/core/client_channel/service_config_test.cc + deps: + - grpc_test_util + - grpc++ + - grpc + - gpr + uses: + - grpc++_test - name: shutdown_test gtest: true build: test diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index b03bbb127ef..30b5981da84 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -87,7 +87,7 @@ grpc_error* ServiceConfig::ParseGlobalParams(const grpc_json* json_tree) { for (size_t i = 0; i < registered_parsers_->size(); i++) { grpc_error* parser_error = GRPC_ERROR_NONE; auto parsed_obj = - (*registered_parsers_)[i].ParseGlobalParams(json_tree, &parser_error); + (*registered_parsers_)[i]->ParseGlobalParams(json_tree, &parser_error); error = grpc_error_add_child(error, parser_error); parsed_global_service_config_objects_.push_back(std::move(parsed_obj)); } @@ -103,7 +103,7 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( for (size_t i = 0; i < registered_parsers_->size(); i++) { grpc_error* parser_error = GRPC_ERROR_NONE; auto parsed_obj = - (*registered_parsers_)[i].ParsePerMethodParams(json, &error); + (*registered_parsers_)[i]->ParsePerMethodParams(json, &error); error = grpc_error_add_child(error, parser_error); objs_vector->push_back(std::move(parsed_obj)); } diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index e371af2746e..3eb3bd54644 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -72,14 +72,12 @@ class ServiceConfigParser { virtual UniquePtr ParseGlobalParams( const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr); - *error = GRPC_ERROR_NONE; return nullptr; } virtual UniquePtr ParsePerMethodParams( const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr); - *error = GRPC_ERROR_NONE; return nullptr; } @@ -152,7 +150,7 @@ class ServiceConfig : public RefCounted { /// registered parser. Each parser is responsible for reading the service /// config json and returning a parsed object. This parsed object can later be /// retrieved using the same index that was returned at registration time. - static int RegisterParser(ServiceConfigParser parser) { + static int RegisterParser(UniquePtr parser) { registered_parsers_->push_back(std::move(parser)); return registered_parsers_->size() - 1; } @@ -168,7 +166,7 @@ class ServiceConfig : public RefCounted { } private: - typedef InlinedVector + typedef InlinedVector, kNumPreallocatedParsers> ServiceConfigParserList; // So New() can call our private ctor. template diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD index 57e5191af4c..f88a51adbf6 100644 --- a/test/core/client_channel/BUILD +++ b/test/core/client_channel/BUILD @@ -78,3 +78,17 @@ grpc_cc_test( "//test/core/util:grpc_test_util", ], ) + +grpc_cc_test( + name = "service_config_test", + srcs = ["service_config_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc new file mode 100644 index 00000000000..d8cb3532cb5 --- /dev/null +++ b/test/core/client_channel/service_config_test.cc @@ -0,0 +1,221 @@ +/* + * + * 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 "src/core/ext/filters/client_channel/service_config.h" +#include "src/core/lib/gpr/string.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +namespace grpc_core { +namespace testing { + +class TestParsedObject1 : public ServiceConfigParsedObject { + public: + TestParsedObject1(int value) : value_(value) {} + + int value() const { return value_; } + + private: + int value_; +}; + +class TestParser1 : public ServiceConfigParser { + public: + UniquePtr ParseGlobalParams( + const grpc_json* json, grpc_error** error) override { + GPR_DEBUG_ASSERT(error != nullptr); + for (grpc_json* field = json->child; field != nullptr; + field = field->next) { + if (strcmp(field->key, "global_param") == 0) { + if (field->type != GRPC_JSON_NUMBER) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "global_param value type should be a number"); + return nullptr; + } + int value = gpr_parse_nonnegative_int(field->value); + if (value == -1) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "global_param value type should be non-negative"); + return nullptr; + } + return UniquePtr( + New(value)); + } + } + return nullptr; + } +}; + +class TestParser2 : public ServiceConfigParser { + public: + UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) override { + GPR_DEBUG_ASSERT(error != nullptr); + for (grpc_json* field = json->child; field != nullptr; + field = field->next) { + if (field->key == nullptr || strcmp(field->key, "name") == 0) { + continue; + } + if (strcmp(field->key, "method_param") == 0) { + if (field->type != GRPC_JSON_NUMBER) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "method_param value type should be a number"); + return nullptr; + } + int value = gpr_parse_nonnegative_int(field->value); + if (value == -1) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "method_param value type should be non-negative"); + return nullptr; + } + return UniquePtr( + New(value)); + } + } + return nullptr; + } +}; + +class ServiceConfigTest : public ::testing::Test { + protected: + void SetUp() override { + ServiceConfig::Shutdown(); + ServiceConfig::Init(); + EXPECT_TRUE(ServiceConfig::RegisterParser( + UniquePtr(New())) == 0); + EXPECT_TRUE(ServiceConfig::RegisterParser( + UniquePtr(New())) == 1); + } +}; + +TEST_F(ServiceConfigTest, ErrorCheck1) { + const char* test_json = ""; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + EXPECT_TRUE(error != GRPC_ERROR_NONE); +} + +TEST_F(ServiceConfigTest, BasicTest1) { + const char* test_json = "{}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + EXPECT_TRUE(error == GRPC_ERROR_NONE); +} + +TEST_F(ServiceConfigTest, ErrorNoNames) { + const char* test_json = "{\"methodConfig\": [{\"blah\":1}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + EXPECT_TRUE(error != GRPC_ERROR_NONE); +} + +TEST_F(ServiceConfigTest, ErrorNoNamesWithMultipleMethodConfigs) { + const char* test_json = + "{\"methodConfig\": [{}, {\"name\":[{\"service\":\"TestServ\"}]}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + EXPECT_TRUE(error != GRPC_ERROR_NONE); +} + +TEST_F(ServiceConfigTest, ValidMethodConfig) { + const char* test_json = + "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}]}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + EXPECT_TRUE(error == GRPC_ERROR_NONE); +} + +TEST_F(ServiceConfigTest, Parser1BasicTest1) { + const char* test_json = "{\"global_param\":5}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_TRUE((static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0))) + ->value() == 5); +} + +TEST_F(ServiceConfigTest, Parser1BasicTest2) { + const char* test_json = "{\"global_param\":1000}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_TRUE((static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0))) + ->value() == 1000); +} + +TEST_F(ServiceConfigTest, Parser1ErrorInvalidType) { + const char* test_json = "{\"global_param\":\"5\"}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + EXPECT_TRUE(error != GRPC_ERROR_NONE); +} + +TEST_F(ServiceConfigTest, Parser1ErrorInvalidValue) { + const char* test_json = "{\"global_param\":-5}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + EXPECT_TRUE(error != GRPC_ERROR_NONE); +} + +TEST_F(ServiceConfigTest, Parser2BasicTest) { + const char* test_json = + "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}], " + "\"method_param\":5}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + EXPECT_TRUE(error == GRPC_ERROR_NONE); +} + +TEST_F(ServiceConfigTest, Parser2ErrorInvalidType) { + const char* test_json = + "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}], " + "\"method_param\":\"5\"}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + EXPECT_TRUE(error != GRPC_ERROR_NONE); +} + +TEST_F(ServiceConfigTest, Parser2ErrorInvalidValue) { + const char* test_json = + "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}], " + "\"method_param\":-5}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + EXPECT_TRUE(error != GRPC_ERROR_NONE); +} + +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + grpc_init(); + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + grpc_shutdown(); + return ret; +} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index cd88082f884..09b7ff2a70a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -4723,6 +4723,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "service_config_test", + "src": [ + "test/core/client_channel/service_config_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 cf0e574b09d..a25897735a7 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -5349,6 +5349,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": "service_config_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From e3290aa0fee675a61d8698e40475a649486dc5b6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 2 Apr 2019 18:18:50 -0700 Subject: [PATCH 1770/2143] split up CallCredentials.cs into multiple files --- src/csharp/Grpc.Core/CallCredentials.cs | 69 ------------------ .../Internal/CompositeCallCredentials.cs | 72 +++++++++++++++++++ .../Grpc.Core/Internal/MetadataCredentials.cs | 51 +++++++++++++ 3 files changed, 123 insertions(+), 69 deletions(-) create mode 100644 src/csharp/Grpc.Core/Internal/CompositeCallCredentials.cs create mode 100644 src/csharp/Grpc.Core/Internal/MetadataCredentials.cs diff --git a/src/csharp/Grpc.Core/CallCredentials.cs b/src/csharp/Grpc.Core/CallCredentials.cs index c1bd95b9e22..bac75038070 100644 --- a/src/csharp/Grpc.Core/CallCredentials.cs +++ b/src/csharp/Grpc.Core/CallCredentials.cs @@ -57,73 +57,4 @@ namespace Grpc.Core /// The native credentials. internal abstract CallCredentialsSafeHandle ToNativeCredentials(); } - - /// - /// Client-side credentials that delegate metadata based auth to an interceptor. - /// The interceptor is automatically invoked for each remote call that uses MetadataCredentials. - /// - internal sealed class MetadataCredentials : CallCredentials - { - readonly AsyncAuthInterceptor interceptor; - - /// - /// Initializes a new instance of MetadataCredentials class. - /// - /// authentication interceptor - public MetadataCredentials(AsyncAuthInterceptor interceptor) - { - this.interceptor = GrpcPreconditions.CheckNotNull(interceptor); - } - - internal override CallCredentialsSafeHandle ToNativeCredentials() - { - NativeMetadataCredentialsPlugin plugin = new NativeMetadataCredentialsPlugin(interceptor); - return plugin.Credentials; - } - } - - /// - /// Credentials that allow composing multiple credentials objects into one object. - /// - internal sealed class CompositeCallCredentials : CallCredentials - { - readonly List credentials; - - /// - /// Initializes a new instance of CompositeCallCredentials class. - /// The resulting credentials object will be composite of all the credentials specified as parameters. - /// - /// credentials to compose - public CompositeCallCredentials(params CallCredentials[] credentials) - { - GrpcPreconditions.CheckArgument(credentials.Length >= 2, "Composite credentials object can only be created from 2 or more credentials."); - this.credentials = new List(credentials); - } - - internal override CallCredentialsSafeHandle ToNativeCredentials() - { - return ToNativeRecursive(0); - } - - // Recursive descent makes managing lifetime of intermediate CredentialSafeHandle instances easier. - // In practice, we won't usually see composites from more than two credentials anyway. - private CallCredentialsSafeHandle ToNativeRecursive(int startIndex) - { - if (startIndex == credentials.Count - 1) - { - return credentials[startIndex].ToNativeCredentials(); - } - - using (var cred1 = credentials[startIndex].ToNativeCredentials()) - using (var cred2 = ToNativeRecursive(startIndex + 1)) - { - var nativeComposite = CallCredentialsSafeHandle.CreateComposite(cred1, cred2); - if (nativeComposite.IsInvalid) - { - throw new ArgumentException("Error creating native composite credentials. Likely, this is because you are trying to compose incompatible credentials."); - } - return nativeComposite; - } - } - } } diff --git a/src/csharp/Grpc.Core/Internal/CompositeCallCredentials.cs b/src/csharp/Grpc.Core/Internal/CompositeCallCredentials.cs new file mode 100644 index 00000000000..43ce8519e5b --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/CompositeCallCredentials.cs @@ -0,0 +1,72 @@ +#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.Threading.Tasks; + +using Grpc.Core.Internal; +using Grpc.Core.Utils; + +namespace Grpc.Core.Internal +{ + /// + /// Credentials that allow composing multiple credentials objects into one object. + /// + internal sealed class CompositeCallCredentials : CallCredentials + { + readonly List credentials; + + /// + /// Initializes a new instance of CompositeCallCredentials class. + /// The resulting credentials object will be composite of all the credentials specified as parameters. + /// + /// credentials to compose + public CompositeCallCredentials(params CallCredentials[] credentials) + { + GrpcPreconditions.CheckArgument(credentials.Length >= 2, "Composite credentials object can only be created from 2 or more credentials."); + this.credentials = new List(credentials); + } + + internal override CallCredentialsSafeHandle ToNativeCredentials() + { + return ToNativeRecursive(0); + } + + // Recursive descent makes managing lifetime of intermediate CredentialSafeHandle instances easier. + // In practice, we won't usually see composites from more than two credentials anyway. + private CallCredentialsSafeHandle ToNativeRecursive(int startIndex) + { + if (startIndex == credentials.Count - 1) + { + return credentials[startIndex].ToNativeCredentials(); + } + + using (var cred1 = credentials[startIndex].ToNativeCredentials()) + using (var cred2 = ToNativeRecursive(startIndex + 1)) + { + var nativeComposite = CallCredentialsSafeHandle.CreateComposite(cred1, cred2); + if (nativeComposite.IsInvalid) + { + throw new ArgumentException("Error creating native composite credentials. Likely, this is because you are trying to compose incompatible credentials."); + } + return nativeComposite; + } + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/MetadataCredentials.cs b/src/csharp/Grpc.Core/Internal/MetadataCredentials.cs new file mode 100644 index 00000000000..8dd00f072e5 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/MetadataCredentials.cs @@ -0,0 +1,51 @@ +#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.Threading.Tasks; + +using Grpc.Core.Internal; +using Grpc.Core.Utils; + +namespace Grpc.Core.Internal +{ + /// + /// Client-side credentials that delegate metadata based auth to an interceptor. + /// The interceptor is automatically invoked for each remote call that uses MetadataCredentials. + /// + internal sealed class MetadataCredentials : CallCredentials + { + readonly AsyncAuthInterceptor interceptor; + + /// + /// Initializes a new instance of MetadataCredentials class. + /// + /// authentication interceptor + public MetadataCredentials(AsyncAuthInterceptor interceptor) + { + this.interceptor = GrpcPreconditions.CheckNotNull(interceptor); + } + + internal override CallCredentialsSafeHandle ToNativeCredentials() + { + NativeMetadataCredentialsPlugin plugin = new NativeMetadataCredentialsPlugin(interceptor); + return plugin.Credentials; + } + } +} From a1a878b593366780c3caf272d9c4eb6911906f7c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 5 Apr 2019 04:47:06 +0200 Subject: [PATCH 1771/2143] make CallCredentials implementation agnostic --- src/csharp/Grpc.Core.Tests/FakeCredentials.cs | 4 +- src/csharp/Grpc.Core/CallCredentials.cs | 44 +++++++++++++--- .../CallCredentialsConfiguratorBase.cs | 38 ++++++++++++++ ... => DefaultCallCredentialsConfigurator.cs} | 49 +++++++++++------- .../Grpc.Core/Internal/MetadataCredentials.cs | 51 ------------------- 5 files changed, 108 insertions(+), 78 deletions(-) create mode 100644 src/csharp/Grpc.Core/CallCredentialsConfiguratorBase.cs rename src/csharp/Grpc.Core/Internal/{CompositeCallCredentials.cs => DefaultCallCredentialsConfigurator.cs} (51%) delete mode 100644 src/csharp/Grpc.Core/Internal/MetadataCredentials.cs diff --git a/src/csharp/Grpc.Core.Tests/FakeCredentials.cs b/src/csharp/Grpc.Core.Tests/FakeCredentials.cs index f23c9e97574..59587b9a510 100644 --- a/src/csharp/Grpc.Core.Tests/FakeCredentials.cs +++ b/src/csharp/Grpc.Core.Tests/FakeCredentials.cs @@ -42,9 +42,9 @@ namespace Grpc.Core.Tests internal class FakeCallCredentials : CallCredentials { - internal override CallCredentialsSafeHandle ToNativeCredentials() + public override void InternalPopulateConfiguration(CallCredentialsConfiguratorBase configurator, object state) { - return null; + // not invoking the configurator on purpose } } } diff --git a/src/csharp/Grpc.Core/CallCredentials.cs b/src/csharp/Grpc.Core/CallCredentials.cs index bac75038070..ebe5f260df4 100644 --- a/src/csharp/Grpc.Core/CallCredentials.cs +++ b/src/csharp/Grpc.Core/CallCredentials.cs @@ -16,9 +16,8 @@ #endregion -using System; using System.Collections.Generic; -using System.Threading.Tasks; +using System.Collections.ObjectModel; using Grpc.Core.Internal; using Grpc.Core.Utils; @@ -38,7 +37,7 @@ namespace Grpc.Core /// The new CompositeCallCredentials public static CallCredentials Compose(params CallCredentials[] credentials) { - return new CompositeCallCredentials(credentials); + return new CompositeCallCredentialsConfiguration(credentials); } /// @@ -48,13 +47,44 @@ namespace Grpc.Core /// authentication interceptor public static CallCredentials FromInterceptor(AsyncAuthInterceptor interceptor) { - return new MetadataCredentials(interceptor); + return new AsyncAuthInterceptorCredentialsConfiguration(interceptor); } /// - /// Creates native object for the credentials. + /// Populates this call credential instances. + /// You never need to invoke this, part of internal implementation. /// - /// The native credentials. - internal abstract CallCredentialsSafeHandle ToNativeCredentials(); + public abstract void InternalPopulateConfiguration(CallCredentialsConfiguratorBase configurator, object state); + + private class CompositeCallCredentialsConfiguration : CallCredentials + { + readonly IReadOnlyList credentials; + + public CompositeCallCredentialsConfiguration(CallCredentials[] credentials) + { + GrpcPreconditions.CheckArgument(credentials.Length >= 2, "Composite credentials object can only be created from 2 or more credentials."); + this.credentials = new List(credentials).AsReadOnly(); + } + + public override void InternalPopulateConfiguration(CallCredentialsConfiguratorBase configurator, object state) + { + configurator.SetCompositeCredentials(state, credentials); + } + } + + internal class AsyncAuthInterceptorCredentialsConfiguration : CallCredentials + { + readonly AsyncAuthInterceptor interceptor; + + public AsyncAuthInterceptorCredentialsConfiguration(AsyncAuthInterceptor interceptor) + { + this.interceptor = GrpcPreconditions.CheckNotNull(interceptor); + } + + public override void InternalPopulateConfiguration(CallCredentialsConfiguratorBase configurator, object state) + { + configurator.SetAsyncAuthInterceptorCredentials(state, interceptor); + } + } } } diff --git a/src/csharp/Grpc.Core/CallCredentialsConfiguratorBase.cs b/src/csharp/Grpc.Core/CallCredentialsConfiguratorBase.cs new file mode 100644 index 00000000000..40a33bbf599 --- /dev/null +++ b/src/csharp/Grpc.Core/CallCredentialsConfiguratorBase.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.Collections.Generic; + +namespace Grpc.Core +{ + /// + /// Base class for objects that can consume configuration from CallCredentials objects. + /// + public abstract class CallCredentialsConfiguratorBase + { + /// + /// Consumes configuration for composite call credentials. + /// + public abstract void SetCompositeCredentials(object state, IReadOnlyList credentials); + + /// + /// Consumes configuration for call credentials created from AsyncAuthInterceptor + /// + public abstract void SetAsyncAuthInterceptorCredentials(object state, AsyncAuthInterceptor interceptor); + } +} diff --git a/src/csharp/Grpc.Core/Internal/CompositeCallCredentials.cs b/src/csharp/Grpc.Core/Internal/DefaultCallCredentialsConfigurator.cs similarity index 51% rename from src/csharp/Grpc.Core/Internal/CompositeCallCredentials.cs rename to src/csharp/Grpc.Core/Internal/DefaultCallCredentialsConfigurator.cs index 43ce8519e5b..a2c53a173c5 100644 --- a/src/csharp/Grpc.Core/Internal/CompositeCallCredentials.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultCallCredentialsConfigurator.cs @@ -18,39 +18,38 @@ using System; using System.Collections.Generic; -using System.Threading.Tasks; - -using Grpc.Core.Internal; using Grpc.Core.Utils; namespace Grpc.Core.Internal { /// - /// Credentials that allow composing multiple credentials objects into one object. + /// Creates native call credential objects from instances of CallCredentials. /// - internal sealed class CompositeCallCredentials : CallCredentials + internal class DefaultCallCredentialsConfigurator : CallCredentialsConfiguratorBase { - readonly List credentials; + CallCredentialsSafeHandle nativeCredentials; - /// - /// Initializes a new instance of CompositeCallCredentials class. - /// The resulting credentials object will be composite of all the credentials specified as parameters. - /// - /// credentials to compose - public CompositeCallCredentials(params CallCredentials[] credentials) + public CallCredentialsSafeHandle NativeCredentials => nativeCredentials; + + public override void SetAsyncAuthInterceptorCredentials(object state, AsyncAuthInterceptor interceptor) { - GrpcPreconditions.CheckArgument(credentials.Length >= 2, "Composite credentials object can only be created from 2 or more credentials."); - this.credentials = new List(credentials); + GrpcPreconditions.CheckState(nativeCredentials == null); + + var plugin = new NativeMetadataCredentialsPlugin(interceptor); + nativeCredentials = plugin.Credentials; } - internal override CallCredentialsSafeHandle ToNativeCredentials() + public override void SetCompositeCredentials(object state, IReadOnlyList credentials) { - return ToNativeRecursive(0); + GrpcPreconditions.CheckState(nativeCredentials == null); + + GrpcPreconditions.CheckArgument(credentials.Count >= 2); + nativeCredentials = CompositeToNativeRecursive(credentials, 0); } // Recursive descent makes managing lifetime of intermediate CredentialSafeHandle instances easier. // In practice, we won't usually see composites from more than two credentials anyway. - private CallCredentialsSafeHandle ToNativeRecursive(int startIndex) + private CallCredentialsSafeHandle CompositeToNativeRecursive(IReadOnlyList credentials, int startIndex) { if (startIndex == credentials.Count - 1) { @@ -58,7 +57,7 @@ namespace Grpc.Core.Internal } using (var cred1 = credentials[startIndex].ToNativeCredentials()) - using (var cred2 = ToNativeRecursive(startIndex + 1)) + using (var cred2 = CompositeToNativeRecursive(credentials, startIndex + 1)) { var nativeComposite = CallCredentialsSafeHandle.CreateComposite(cred1, cred2); if (nativeComposite.IsInvalid) @@ -69,4 +68,18 @@ namespace Grpc.Core.Internal } } } + + internal static class CallCredentialsExtensions + { + /// + /// Creates native object for the credentials. + /// + /// The native credentials. + public static CallCredentialsSafeHandle ToNativeCredentials(this CallCredentials credentials) + { + var configurator = new DefaultCallCredentialsConfigurator(); + credentials.InternalPopulateConfiguration(configurator, credentials); + return configurator.NativeCredentials; + } + } } diff --git a/src/csharp/Grpc.Core/Internal/MetadataCredentials.cs b/src/csharp/Grpc.Core/Internal/MetadataCredentials.cs deleted file mode 100644 index 8dd00f072e5..00000000000 --- a/src/csharp/Grpc.Core/Internal/MetadataCredentials.cs +++ /dev/null @@ -1,51 +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.Collections.Generic; -using System.Threading.Tasks; - -using Grpc.Core.Internal; -using Grpc.Core.Utils; - -namespace Grpc.Core.Internal -{ - /// - /// Client-side credentials that delegate metadata based auth to an interceptor. - /// The interceptor is automatically invoked for each remote call that uses MetadataCredentials. - /// - internal sealed class MetadataCredentials : CallCredentials - { - readonly AsyncAuthInterceptor interceptor; - - /// - /// Initializes a new instance of MetadataCredentials class. - /// - /// authentication interceptor - public MetadataCredentials(AsyncAuthInterceptor interceptor) - { - this.interceptor = GrpcPreconditions.CheckNotNull(interceptor); - } - - internal override CallCredentialsSafeHandle ToNativeCredentials() - { - NativeMetadataCredentialsPlugin plugin = new NativeMetadataCredentialsPlugin(interceptor); - return plugin.Credentials; - } - } -} From 0de1cd2d66faa6a2380b46dab5c834663a4f9996 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 5 Apr 2019 05:26:01 +0200 Subject: [PATCH 1772/2143] Update license header --- src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs b/src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs index 329b23dadff..2ee0abe1d0a 100644 --- a/src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs +++ b/src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs @@ -1,5 +1,5 @@ #region Copyright notice and license -// Copyright 2015 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 ca209ae00e77226a2f70dc3b9221928b18af146d Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Fri, 5 Apr 2019 09:33:40 -0700 Subject: [PATCH 1773/2143] Fix typo in server credentials impl header file --- include/grpcpp/security/server_credentials_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/security/server_credentials_impl.h b/include/grpcpp/security/server_credentials_impl.h index e0fddbf1bc8..afe8d22650b 100644 --- a/include/grpcpp/security/server_credentials_impl.h +++ b/include/grpcpp/security/server_credentials_impl.h @@ -51,7 +51,7 @@ class ServerCredentials { /// Tries to bind \a server to the given \a addr (eg, localhost:1234, /// 192.168.1.1:31416, [::1]:27182, etc.) /// - /// \return bound port number on sucess, 0 on failure. + /// \return bound port number on success, 0 on failure. // TODO(dgq): the "port" part seems to be a misnomer. virtual int AddPortToServer(const grpc::string& addr, grpc_server* server) = 0; From 7eb3f28b7fa54de50e4d63960d615d4f430cf12a Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 5 Apr 2019 10:10:55 -0700 Subject: [PATCH 1774/2143] added todo statments --- .../internal_ci/linux/grpc_bazel_build_in_docker.sh | 1 + .../linux/grpc_python_bazel_test_in_docker.sh | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh index 343ca17793d..3dd0167b7c0 100755 --- a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh +++ b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh @@ -24,4 +24,5 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc && git submodule update --init --reference /var/local/jenkins/grpc/${name} \ ${name}') cd /var/local/git/grpc +#TODO(yfen): add back examples/... to build targets once python rules issues are resolved bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... 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 d844cff7f9a..3ca4673ca08 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 @@ -23,9 +23,10 @@ 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 -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/... +#TODO(yfen): temporarily disabled all python bazel tests due to incompatibility with bazel 0.23.2 +#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 e8c0b2433ac82f21dde122380dfb523859bacbe4 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 5 Apr 2019 10:20:13 -0700 Subject: [PATCH 1775/2143] Make script fixes --- BUILD.gn | 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.gn b/BUILD.gn index 8fed27e202e..3fd5154834f 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1088,6 +1088,7 @@ config("grpc_config") { "include/grpcpp/server.h", "include/grpcpp/server_builder.h", "include/grpcpp/server_context.h", + "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index a84523e5c92..a53847588f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3036,6 +3036,7 @@ foreach(_hdr include/grpcpp/server.h include/grpcpp/server_builder.h include/grpcpp/server_context.h + include/grpcpp/server_impl.h include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h @@ -3637,6 +3638,7 @@ foreach(_hdr include/grpcpp/server.h include/grpcpp/server_builder.h include/grpcpp/server_context.h + include/grpcpp/server_impl.h include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h @@ -4612,6 +4614,7 @@ foreach(_hdr include/grpcpp/server.h include/grpcpp/server_builder.h include/grpcpp/server_context.h + include/grpcpp/server_impl.h include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h diff --git a/Makefile b/Makefile index d1158bf31ba..b04ab44b33d 100644 --- a/Makefile +++ b/Makefile @@ -5367,6 +5367,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ + include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ @@ -5976,6 +5977,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ + include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ @@ -6900,6 +6902,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ + include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ diff --git a/build.yaml b/build.yaml index 888b613dc0e..42ae58793e1 100644 --- a/build.yaml +++ b/build.yaml @@ -1382,6 +1382,7 @@ filegroups: - include/grpcpp/server.h - include/grpcpp/server_builder.h - include/grpcpp/server_context.h + - include/grpcpp/server_impl.h - include/grpcpp/server_posix.h - include/grpcpp/server_posix_impl.h - include/grpcpp/support/async_stream.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 051397f1e67..2d2ee28850d 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -121,6 +121,7 @@ Pod::Spec.new do |s| 'include/grpcpp/server.h', 'include/grpcpp/server_builder.h', 'include/grpcpp/server_context.h', + 'include/grpcpp/server_impl.h', 'include/grpcpp/server_posix.h', 'include/grpcpp/server_posix_impl.h', 'include/grpcpp/support/async_stream.h', diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index a56d2df8530..114d5e6dfa1 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -1011,6 +1011,7 @@ include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ +include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 6bf498307bb..4f6bd406bdf 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1013,6 +1013,7 @@ include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_context.h \ +include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.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 71e2b0d2207..898f96ad4b9 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10131,6 +10131,7 @@ "include/grpcpp/server.h", "include/grpcpp/server_builder.h", "include/grpcpp/server_context.h", + "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", @@ -10250,6 +10251,7 @@ "include/grpcpp/server.h", "include/grpcpp/server_builder.h", "include/grpcpp/server_context.h", + "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", From 1fb7a841333658eee482801f0428fc297e979042 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Mon, 1 Apr 2019 08:48:35 -0700 Subject: [PATCH 1776/2143] fix ALPN issues. --- .../ssl/ssl_security_connector.cc | 17 ++------ test/core/security/security_connector_test.cc | 43 ++++++++++++++++++- 2 files changed, 46 insertions(+), 14 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 8a00bbb82ed..ad492f361aa 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 @@ -44,24 +44,15 @@ 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."); + grpc_error* error = grpc_ssl_check_alpn(peer); + if (error != GRPC_ERROR_NONE) { + return error; } - 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); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return error; } diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index 2a31763c73c..496f064439c 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -36,6 +36,10 @@ #include "src/core/tsi/transport_security.h" #include "test/core/util/test_config.h" +#ifndef TSI_OPENSSL_ALPN_SUPPORT +#define TSI_OPENSSL_ALPN_SUPPORT 1 +#endif + static int check_transport_security_type(const grpc_auth_context* ctx) { grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name( ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME); @@ -432,6 +436,43 @@ static void test_default_ssl_roots(void) { gpr_free(roots_env_var_file_path); } +static void test_peer_alpn_check(void) { +#if TSI_OPENSSL_ALPN_SUPPORT + tsi_peer peer; + const char* alpn = "grpc"; + const char* wrong_alpn = "wrong"; + // peer does not have a TSI_SSL_ALPN_SELECTED_PROTOCOL property. + GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property("wrong peer property name", + alpn, strlen(alpn), + &peer.properties[0]) == TSI_OK); + grpc_error* error = grpc_ssl_check_alpn(&peer); + GPR_ASSERT(error != GRPC_ERROR_NONE); + tsi_peer_destruct(&peer); + GRPC_ERROR_UNREF(error); + // peer has a TSI_SSL_ALPN_SELECTED_PROTOCOL property but with an incorrect + // property value. + GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL, + wrong_alpn, strlen(wrong_alpn), + &peer.properties[0]) == TSI_OK); + error = grpc_ssl_check_alpn(&peer); + GPR_ASSERT(error != GRPC_ERROR_NONE); + tsi_peer_destruct(&peer); + GRPC_ERROR_UNREF(error); + // peer has a TSI_SSL_ALPN_SELECTED_PROTOCOL property with a correct property + // value. + GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL, + alpn, strlen(alpn), + &peer.properties[0]) == TSI_OK); + GPR_ASSERT(grpc_ssl_check_alpn(&peer) == GRPC_ERROR_NONE); + tsi_peer_destruct(&peer); +#else + GPR_ASSERT(grpc_ssl_check_alpn(nullptr) == GRPC_ERROR_NONE); +#endif +} + int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); @@ -443,7 +484,7 @@ int main(int argc, char** argv) { test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context(); test_ipv6_address_san(); test_default_ssl_roots(); - + test_peer_alpn_check(); grpc_shutdown(); return 0; } From df89d8e157b05f524bd25a191cba59a134d8c2c3 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 5 Apr 2019 11:32:44 -0700 Subject: [PATCH 1777/2143] bazel RBE Windows build --- BUILD | 1 + WORKSPACE | 2 + test/core/end2end/generate_tests.bzl | 5 + test/core/handshake/BUILD | 4 + test/core/network_benchmarks/BUILD | 1 + test/core/util/BUILD | 1 + third_party/toolchains/BUILD | 30 + third_party/toolchains/bazel_0.23.2/BUILD | 188 ++ .../bazel_0.23.2/cc_toolchain_config.bzl | 1704 +++++++++++++++++ .../bazel_0.23.2/dummy_toolchain.bzl | 23 + .../linux/grpc_bazel_build_in_docker.sh | 2 +- tools/remote_build/windows.bazelrc | 48 + 12 files changed, 2008 insertions(+), 1 deletion(-) create mode 100644 third_party/toolchains/bazel_0.23.2/BUILD create mode 100644 third_party/toolchains/bazel_0.23.2/cc_toolchain_config.bzl create mode 100644 third_party/toolchains/bazel_0.23.2/dummy_toolchain.bzl diff --git a/BUILD b/BUILD index 562a71c2f29..ff500c72a39 100644 --- a/BUILD +++ b/BUILD @@ -2347,6 +2347,7 @@ grpc_cc_library( ":google_api_upb", ":proto_gen_validate_upb", ], + tags = ["no_windows"], ) grpc_cc_library( diff --git a/WORKSPACE b/WORKSPACE index 18f389edd24..d90d7b6751d 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -11,10 +11,12 @@ grpc_test_only_deps() register_execution_platforms( "//third_party/toolchains:rbe_ubuntu1604", "//third_party/toolchains:rbe_ubuntu1604_large", + "//third_party/toolchains:rbe_windows", ) register_toolchains( "//third_party/toolchains:cc-toolchain-clang-x86_64-default", + "//third_party/toolchains/bazel_0.23.2:cc-toolchain-x64_windows", ) # TODO(https://github.com/grpc/grpc/issues/18331): Move off of this dependency. diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index b3c58bf29b4..10b9314a84a 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -385,6 +385,7 @@ def grpc_end2end_tests(): ":proxy", ":local_util", ], + tags = ["no_windows"], ) for f, fopt in END2END_FIXTURES.items(): @@ -398,6 +399,7 @@ def grpc_end2end_tests(): "//:grpc", "//:gpr", ], + tags = ["no_windows"], ) for t, topt in END2END_TESTS.items(): #print(_compatible(fopt, topt), f, t, fopt, topt) @@ -413,6 +415,7 @@ def grpc_end2end_tests(): t, poller, ], + tags = ["no_windows"], ) def grpc_end2end_nosec_tests(): @@ -435,6 +438,7 @@ def grpc_end2end_nosec_tests(): ":proxy", ":local_util", ], + tags = ["no_windows"], ) for f, fopt in END2END_NOSEC_FIXTURES.items(): @@ -450,6 +454,7 @@ def grpc_end2end_nosec_tests(): "//:grpc_unsecure", "//:gpr", ], + tags = ["no_windows"], ) for t, topt in END2END_TESTS.items(): #print(_compatible(fopt, topt), f, t, fopt, topt) diff --git a/test/core/handshake/BUILD b/test/core/handshake/BUILD index b9d2f31515a..0824efb980f 100644 --- a/test/core/handshake/BUILD +++ b/test/core/handshake/BUILD @@ -32,6 +32,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_library( @@ -43,6 +44,7 @@ grpc_cc_library( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -60,6 +62,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -77,6 +80,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( diff --git a/test/core/network_benchmarks/BUILD b/test/core/network_benchmarks/BUILD index fbc611d5fe3..1194e4ad7bb 100644 --- a/test/core/network_benchmarks/BUILD +++ b/test/core/network_benchmarks/BUILD @@ -33,4 +33,5 @@ grpc_cc_binary( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) diff --git a/test/core/util/BUILD b/test/core/util/BUILD index b10d3e4287b..98e69c6ef34 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -133,6 +133,7 @@ grpc_cc_library( ":grpc_test_util", "//:grpc", ], + tags = ["no_windows"], ) grpc_cc_test( diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 943690a2efd..5ee528d5d46 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -28,6 +28,36 @@ alias( actual = ":rbe_ubuntu1604_r346485_large", ) +alias( + name = "rbe_windows", + actual = ":rbe_windows_1803", +) + +# RBE Windows +platform( + name = "rbe_windows_1803", + constraint_values = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:windows", + "@bazel_tools//tools/cpp:msvc", + ], + remote_execution_properties = """ + properties: { + name: "container-image" + value:"docker://gcr.io/grpc-testing/rbe_windows_toolchain@sha256:689b177e4a157c431c7077d19d043de27922c37de835031f29c9093b8d5c6370" + } + properties: { + name: "gceMachineType" # Small machines for majority of tests. + value: "n1-highmem-2" + } + properties:{ + name: "OSFamily" + value: "Windows" + } + + """, +) + # RBE Ubuntu16_04 r346485 platform( name = "rbe_ubuntu1604_r346485", diff --git a/third_party/toolchains/bazel_0.23.2/BUILD b/third_party/toolchains/bazel_0.23.2/BUILD new file mode 100644 index 00000000000..5ce4e00c866 --- /dev/null +++ b/third_party/toolchains/bazel_0.23.2/BUILD @@ -0,0 +1,188 @@ +# Copyright 2018 The Bazel Authors. All rights reserved. +# +# 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 becomes the BUILD file for @local_config_cc// under Windows. +licenses(["notice"]) # Apache v2 + +package(default_visibility = ["//visibility:public"]) + +load(":cc_toolchain_config.bzl", "cc_toolchain_config") + +cc_library( + name = "malloc", +) + +filegroup( + name = "empty", + srcs = [], +) + +# Hardcoded toolchain, legacy behaviour. +cc_toolchain_suite( + name = "toolchain", + toolchains = { + "armeabi-v7a|compiler": ":cc-compiler-armeabi-v7a", + "x64_windows|msvc-cl": ":cc-compiler-x64_windows", + "x64_windows|msys-gcc": ":cc-compiler-x64_windows_msys", + "x64_windows|mingw-gcc": ":cc-compiler-x64_windows_mingw", + "x64_windows_msys": ":cc-compiler-x64_windows_msys", + "x64_windows": ":cc-compiler-x64_windows", + "armeabi-v7a": ":cc-compiler-armeabi-v7a", + }, +) + +cc_toolchain( + name = "cc-compiler-x64_windows_msys", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 1, + toolchain_config = ":msys_x64", + toolchain_identifier = "msys_x64", +) + +cc_toolchain_config( + name = "msys_x64", + compiler = "msys-gcc", + cpu = "x64_windows", +) + +toolchain( + name = "cc-toolchain-x64_windows_msys", + exec_compatible_with = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:windows", + "@bazel_tools//tools/cpp:msys", + ], + target_compatible_with = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:windows", + ], + toolchain = ":cc-compiler-x64_windows_msys", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +cc_toolchain( + name = "cc-compiler-x64_windows_mingw", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 0, + toolchain_config = ":msys_x64_mingw", + toolchain_identifier = "msys_x64_mingw", +) + +cc_toolchain_config( + name = "msys_x64_mingw", + compiler = "mingw-gcc", + cpu = "x64_windows", +) + +toolchain( + name = "cc-toolchain-x64_windows_mingw", + exec_compatible_with = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:windows", + "@bazel_tools//tools/cpp:mingw", + ], + target_compatible_with = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:windows", + ], + toolchain = ":cc-compiler-x64_windows_mingw", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +cc_toolchain( + name = "cc-compiler-x64_windows", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 1, + toolchain_config = ":msvc_x64", + toolchain_identifier = "msvc_x64", +) + +cc_toolchain_config( + name = "msvc_x64", + compiler = "msvc-cl", + cpu = "x64_windows", +) + +toolchain( + name = "cc-toolchain-x64_windows", + exec_compatible_with = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:windows", + ], + target_compatible_with = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:windows", + ], + toolchain = ":cc-compiler-x64_windows", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +cc_toolchain( + name = "cc-compiler-armeabi-v7a", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 1, + toolchain_config = ":stub_armeabi-v7a", + toolchain_identifier = "stub_armeabi-v7a", +) + +cc_toolchain_config( + name = "stub_armeabi-v7a", + compiler = "compiler", + cpu = "armeabi-v7a", +) + +toolchain( + name = "cc-toolchain-armeabi-v7a", + exec_compatible_with = [ + ], + target_compatible_with = [ + "@bazel_tools//platforms:arm", + "@bazel_tools//platforms:android", + ], + toolchain = ":cc-compiler-armeabi-v7a", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +filegroup( + name = "link_dynamic_library", + srcs = ["link_dynamic_library.sh"], +) diff --git a/third_party/toolchains/bazel_0.23.2/cc_toolchain_config.bzl b/third_party/toolchains/bazel_0.23.2/cc_toolchain_config.bzl new file mode 100644 index 00000000000..790ddcb0947 --- /dev/null +++ b/third_party/toolchains/bazel_0.23.2/cc_toolchain_config.bzl @@ -0,0 +1,1704 @@ +# Copyright 2019 The Bazel Authors. All rights reserved. +# +# 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. + +"""A Starlark cc_toolchain configuration rule""" + +load( + "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", + "action_config", + "artifact_name_pattern", + "env_entry", + "env_set", + "feature", + "feature_set", + "flag_group", + "flag_set", + "make_variable", + "tool", + "tool_path", + "variable_with_value", + "with_feature_set", +) +load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES") + +all_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.clif_match, + ACTION_NAMES.lto_backend, +] + +all_cpp_compile_actions = [ + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.clif_match, +] + +preprocessor_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.clif_match, +] + +codegen_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, +] + +all_link_actions = [ + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, +] + +def _windows_msvc_impl(ctx): + toolchain_identifier = "msvc_x64" + host_system_name = "local" + target_system_name = "local" + target_cpu = "x64_windows" + target_libc = "msvcrt" + compiler = "msvc-cl" + abi_version = "local" + abi_libc_version = "local" + cc_target_os = None + builtin_sysroot = None + + cxx_builtin_include_directories = [ + # This is a workaround for https://github.com/bazelbuild/bazel/issues/5087. + "C:\\botcode\\w", + "c:/tools/msys64/usr/", + "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\INCLUDE", + "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.10240.0\\ucrt", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\shared", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\um", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\winrt", + ] + + cpp_link_nodeps_dynamic_library_action = action_config( + action_name = ACTION_NAMES.cpp_link_nodeps_dynamic_library, + implies = [ + "nologo", + "shared_flag", + "linkstamps", + "output_execpath_flags", + "input_param_flags", + "user_link_flags", + "default_link_flags", + "linker_subsystem_flag", + "linker_param_file", + "msvc_env", + "no_stripping", + "has_configured_linker_path", + "def_file", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/link.exe")], + ) + + cpp_link_static_library_action = action_config( + action_name = ACTION_NAMES.cpp_link_static_library, + implies = [ + "nologo", + "archiver_flags", + "input_param_flags", + "linker_param_file", + "msvc_env", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/lib.exe")], + ) + + assemble_action = action_config( + action_name = ACTION_NAMES.assemble, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "nologo", + "msvc_env", + "sysroot", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/ml64.exe")], + ) + + preprocess_assemble_action = action_config( + action_name = ACTION_NAMES.preprocess_assemble, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "nologo", + "msvc_env", + "sysroot", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/ml64.exe")], + ) + + c_compile_action = action_config( + action_name = ACTION_NAMES.c_compile, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "default_compile_flags", + "nologo", + "msvc_env", + "parse_showincludes", + "user_compile_flags", + "sysroot", + "unfiltered_compile_flags", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe")], + ) + + cpp_compile_action = action_config( + action_name = ACTION_NAMES.cpp_compile, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "default_compile_flags", + "nologo", + "msvc_env", + "parse_showincludes", + "user_compile_flags", + "sysroot", + "unfiltered_compile_flags", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe")], + ) + + cpp_link_executable_action = action_config( + action_name = ACTION_NAMES.cpp_link_executable, + implies = [ + "nologo", + "linkstamps", + "output_execpath_flags", + "input_param_flags", + "user_link_flags", + "default_link_flags", + "linker_subsystem_flag", + "linker_param_file", + "msvc_env", + "no_stripping", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/link.exe")], + ) + + cpp_link_dynamic_library_action = action_config( + action_name = ACTION_NAMES.cpp_link_dynamic_library, + implies = [ + "nologo", + "shared_flag", + "linkstamps", + "output_execpath_flags", + "input_param_flags", + "user_link_flags", + "default_link_flags", + "linker_subsystem_flag", + "linker_param_file", + "msvc_env", + "no_stripping", + "has_configured_linker_path", + "def_file", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/link.exe")], + ) + + action_configs = [ + assemble_action, + preprocess_assemble_action, + c_compile_action, + cpp_compile_action, + cpp_link_executable_action, + cpp_link_dynamic_library_action, + cpp_link_nodeps_dynamic_library_action, + cpp_link_static_library_action, + ] + + msvc_link_env_feature = feature( + name = "msvc_link_env", + env_sets = [ + env_set( + actions = all_link_actions + + [ACTION_NAMES.cpp_link_static_library], + env_entries = [env_entry(key = "LIB", value = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\LIB\\amd64;C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.10240.0\\ucrt\\x64;C:\\Program Files (x86)\\Windows Kits\\8.1\\lib\\winv6.3\\um\\x64;")], + ), + ], + ) + + shared_flag_feature = feature( + name = "shared_flag", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [flag_group(flags = ["/DLL"])], + ), + ], + ) + + determinism_feature = feature( + name = "determinism", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [ + flag_group( + flags = [ + "/wd4117", + "-D__DATE__=\"redacted\"", + "-D__TIMESTAMP__=\"redacted\"", + "-D__TIME__=\"redacted\"", + ], + ), + ], + ), + ], + ) + + sysroot_feature = feature( + name = "sysroot", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = ["--sysroot=%{sysroot}"], + iterate_over = "sysroot", + expand_if_available = "sysroot", + ), + ], + ), + ], + ) + + unfiltered_compile_flags_feature = feature( + name = "unfiltered_compile_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flags = ["%{unfiltered_compile_flags}"], + iterate_over = "unfiltered_compile_flags", + expand_if_available = "unfiltered_compile_flags", + ), + ], + ), + ], + ) + + copy_dynamic_libraries_to_binary_feature = feature(name = "copy_dynamic_libraries_to_binary") + + input_param_flags_feature = feature( + name = "input_param_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = ["/IMPLIB:%{interface_library_output_path}"], + expand_if_available = "interface_library_output_path", + ), + ], + ), + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["%{libopts}"], + iterate_over = "libopts", + expand_if_available = "libopts", + ), + ], + ), + flag_set( + actions = all_link_actions + + [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group( + iterate_over = "libraries_to_link", + flag_groups = [ + flag_group( + iterate_over = "libraries_to_link.object_files", + flag_groups = [flag_group(flags = ["%{libraries_to_link.object_files}"])], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file_group", + ), + ), + flag_group( + flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file", + ), + ), + flag_group( + flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "interface_library", + ), + ), + flag_group( + flag_groups = [ + flag_group( + flags = ["%{libraries_to_link.name}"], + expand_if_false = "libraries_to_link.is_whole_archive", + ), + flag_group( + flags = ["/WHOLEARCHIVE:%{libraries_to_link.name}"], + expand_if_true = "libraries_to_link.is_whole_archive", + ), + ], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "static_library", + ), + ), + ], + expand_if_available = "libraries_to_link", + ), + ], + ), + ], + ) + + fastbuild_feature = feature( + name = "fastbuild", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Od", "/Z7"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["/DEBUG:FASTLINK", "/INCREMENTAL:NO"], + ), + ], + ), + ], + implies = ["generate_pdb_file"], + ) + + user_compile_flags_feature = feature( + name = "user_compile_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flags = ["%{user_compile_flags}"], + iterate_over = "user_compile_flags", + expand_if_available = "user_compile_flags", + ), + ], + ), + ], + ) + + archiver_flags_feature = feature( + name = "archiver_flags", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group( + flags = ["/OUT:%{output_execpath}"], + expand_if_available = "output_execpath", + ), + ], + ), + ], + ) + + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/MACHINE:X64"])], + ), + ], + ) + + static_link_msvcrt_feature = feature(name = "static_link_msvcrt") + + dynamic_link_msvcrt_debug_feature = feature( + name = "dynamic_link_msvcrt_debug", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MDd"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrtd.lib"])], + ), + ], + requires = [feature_set(features = ["dbg"])], + ) + + dbg_feature = feature( + name = "dbg", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Od", "/Z7"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["/DEBUG:FULL", "/INCREMENTAL:NO"], + ), + ], + ), + ], + implies = ["generate_pdb_file"], + ) + + opt_feature = feature( + name = "opt", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/O2"])], + ), + ], + implies = ["frame_pointer"], + ) + + supports_interface_shared_libraries_feature = feature( + name = "supports_interface_shared_libraries", + enabled = True, + ) + + user_link_flags_feature = feature( + name = "user_link_flags", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["%{user_link_flags}"], + iterate_over = "user_link_flags", + expand_if_available = "user_link_flags", + ), + ], + ), + ], + ) + + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = [ + flag_group( + flags = [ + "/DCOMPILER_MSVC", + "/DNOMINMAX", + "/D_WIN32_WINNT=0x0601", + "/D_CRT_SECURE_NO_DEPRECATE", + "/D_CRT_SECURE_NO_WARNINGS", + "/bigobj", + "/Zm500", + "/EHsc", + "/wd4351", + "/wd4291", + "/wd4250", + "/wd4996", + ], + ), + ], + ), + ], + ) + + msvc_compile_env_feature = feature( + name = "msvc_compile_env", + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ], + env_entries = [env_entry(key = "INCLUDE", value = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\INCLUDE;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.10240.0\\ucrt;C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\shared;C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\um;C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\winrt;")], + ), + ], + ) + + preprocessor_defines_feature = feature( + name = "preprocessor_defines", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ], + flag_groups = [ + flag_group( + flags = ["/D%{preprocessor_defines}"], + iterate_over = "preprocessor_defines", + ), + ], + ), + ], + ) + + generate_pdb_file_feature = feature( + name = "generate_pdb_file", + requires = [ + feature_set(features = ["dbg"]), + feature_set(features = ["fastbuild"]), + ], + ) + + output_execpath_flags_feature = feature( + name = "output_execpath_flags", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["/OUT:%{output_execpath}"], + expand_if_available = "output_execpath", + ), + ], + ), + ], + ) + + dynamic_link_msvcrt_no_debug_feature = feature( + name = "dynamic_link_msvcrt_no_debug", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MD"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrt.lib"])], + ), + ], + requires = [ + feature_set(features = ["fastbuild"]), + feature_set(features = ["opt"]), + ], + ) + + disable_assertions_feature = feature( + name = "disable_assertions", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/DNDEBUG"])], + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + + has_configured_linker_path_feature = feature(name = "has_configured_linker_path") + + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + + no_stripping_feature = feature(name = "no_stripping") + + linker_param_file_feature = feature( + name = "linker_param_file", + flag_sets = [ + flag_set( + actions = all_link_actions + + [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group( + flags = ["@%{linker_param_file}"], + expand_if_available = "linker_param_file", + ), + ], + ), + ], + ) + + ignore_noisy_warnings_feature = feature( + name = "ignore_noisy_warnings", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.cpp_link_static_library], + flag_groups = [flag_group(flags = ["/ignore:4221"])], + ), + ], + ) + + no_legacy_features_feature = feature(name = "no_legacy_features") + + parse_showincludes_feature = feature( + name = "parse_showincludes", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_header_parsing, + ], + flag_groups = [flag_group(flags = ["/showIncludes"])], + ), + ], + ) + + static_link_msvcrt_no_debug_feature = feature( + name = "static_link_msvcrt_no_debug", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MT"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmt.lib"])], + ), + ], + requires = [ + feature_set(features = ["fastbuild"]), + feature_set(features = ["opt"]), + ], + ) + + treat_warnings_as_errors_feature = feature( + name = "treat_warnings_as_errors", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/WX"])], + ), + ], + ) + + windows_export_all_symbols_feature = feature(name = "windows_export_all_symbols") + + no_windows_export_all_symbols_feature = feature(name = "no_windows_export_all_symbols") + + include_paths_feature = feature( + name = "include_paths", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ], + flag_groups = [ + flag_group( + flags = ["/I%{quote_include_paths}"], + iterate_over = "quote_include_paths", + ), + flag_group( + flags = ["/I%{include_paths}"], + iterate_over = "include_paths", + ), + flag_group( + flags = ["/I%{system_include_paths}"], + iterate_over = "system_include_paths", + ), + ], + ), + ], + ) + + linkstamps_feature = feature( + name = "linkstamps", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["%{linkstamp_paths}"], + iterate_over = "linkstamp_paths", + expand_if_available = "linkstamp_paths", + ), + ], + ), + ], + ) + + targets_windows_feature = feature( + name = "targets_windows", + enabled = True, + implies = ["copy_dynamic_libraries_to_binary"], + ) + + linker_subsystem_flag_feature = feature( + name = "linker_subsystem_flag", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/SUBSYSTEM:CONSOLE"])], + ), + ], + ) + + static_link_msvcrt_debug_feature = feature( + name = "static_link_msvcrt_debug", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MTd"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmtd.lib"])], + ), + ], + requires = [feature_set(features = ["dbg"])], + ) + + frame_pointer_feature = feature( + name = "frame_pointer", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Oy-"])], + ), + ], + ) + + compiler_output_flags_feature = feature( + name = "compiler_output_flags", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.assemble], + flag_groups = [ + flag_group( + flag_groups = [ + flag_group( + flags = ["/Fo%{output_file}", "/Zi"], + expand_if_available = "output_file", + expand_if_not_available = "output_assembly_file", + ), + ], + expand_if_not_available = "output_preprocess_file", + ), + ], + ), + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flag_groups = [ + flag_group( + flags = ["/Fo%{output_file}"], + expand_if_not_available = "output_preprocess_file", + ), + ], + expand_if_available = "output_file", + expand_if_not_available = "output_assembly_file", + ), + flag_group( + flag_groups = [ + flag_group( + flags = ["/Fa%{output_file}"], + expand_if_available = "output_assembly_file", + ), + ], + expand_if_available = "output_file", + ), + flag_group( + flag_groups = [ + flag_group( + flags = ["/P", "/Fi%{output_file}"], + expand_if_available = "output_preprocess_file", + ), + ], + expand_if_available = "output_file", + ), + ], + ), + ], + ) + + nologo_feature = feature( + name = "nologo", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + flag_groups = [flag_group(flags = ["/nologo"])], + ), + ], + ) + + smaller_binary_feature = feature( + name = "smaller_binary", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Gy", "/Gw"])], + with_features = [with_feature_set(features = ["opt"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/OPT:ICF", "/OPT:REF"])], + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + + compiler_input_flags_feature = feature( + name = "compiler_input_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flags = ["/c", "%{source_file}"], + expand_if_available = "source_file", + ), + ], + ), + ], + ) + + def_file_feature = feature( + name = "def_file", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["/DEF:%{def_file_path}", "/ignore:4070"], + expand_if_available = "def_file_path", + ), + ], + ), + ], + ) + + msvc_env_feature = feature( + name = "msvc_env", + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + env_entries = [ + env_entry(key = "PATH", value = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\amd64;C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319;C:\\Windows\\Microsoft.NET\\Framework64\\;C:\\Program Files (x86)\\Windows Kits\\8.1\\bin\\x64;C:\\Program Files (x86)\\Windows Kits\\8.1\\bin\\x86;;C:\\Windows\\system32"), + env_entry(key = "TMP", value = "C:\\Users\\ContainerAdministrator\\AppData\\Local\\Temp"), + env_entry(key = "TEMP", value = "C:\\Users\\ContainerAdministrator\\AppData\\Local\\Temp"), + ], + ), + ], + implies = ["msvc_compile_env", "msvc_link_env"], + ) + + features = [ + no_legacy_features_feature, + nologo_feature, + has_configured_linker_path_feature, + no_stripping_feature, + targets_windows_feature, + copy_dynamic_libraries_to_binary_feature, + default_compile_flags_feature, + msvc_env_feature, + msvc_compile_env_feature, + msvc_link_env_feature, + include_paths_feature, + preprocessor_defines_feature, + parse_showincludes_feature, + generate_pdb_file_feature, + shared_flag_feature, + linkstamps_feature, + output_execpath_flags_feature, + archiver_flags_feature, + input_param_flags_feature, + linker_subsystem_flag_feature, + user_link_flags_feature, + default_link_flags_feature, + linker_param_file_feature, + static_link_msvcrt_feature, + static_link_msvcrt_no_debug_feature, + dynamic_link_msvcrt_no_debug_feature, + static_link_msvcrt_debug_feature, + dynamic_link_msvcrt_debug_feature, + dbg_feature, + fastbuild_feature, + opt_feature, + frame_pointer_feature, + disable_assertions_feature, + determinism_feature, + treat_warnings_as_errors_feature, + smaller_binary_feature, + ignore_noisy_warnings_feature, + user_compile_flags_feature, + sysroot_feature, + unfiltered_compile_flags_feature, + compiler_output_flags_feature, + compiler_input_flags_feature, + def_file_feature, + windows_export_all_symbols_feature, + no_windows_export_all_symbols_feature, + supports_dynamic_linker_feature, + supports_interface_shared_libraries_feature, + ] + + artifact_name_patterns = [ + artifact_name_pattern( + category_name = "object_file", + prefix = "", + extension = ".obj", + ), + artifact_name_pattern( + category_name = "static_library", + prefix = "", + extension = ".lib", + ), + artifact_name_pattern( + category_name = "alwayslink_static_library", + prefix = "", + extension = ".lo.lib", + ), + artifact_name_pattern( + category_name = "executable", + prefix = "", + extension = ".exe", + ), + artifact_name_pattern( + category_name = "dynamic_library", + prefix = "", + extension = ".dll", + ), + artifact_name_pattern( + category_name = "interface_library", + prefix = "", + extension = ".if.lib", + ), + ] + + make_variables = [] + + tool_paths = [ + tool_path(name = "ar", path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/lib.exe"), + tool_path(name = "ml", path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/ml64.exe"), + tool_path(name = "cpp", path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe"), + tool_path(name = "gcc", path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe"), + tool_path(name = "gcov", path = "wrapper/bin/msvc_nop.bat"), + tool_path(name = "ld", path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/link.exe"), + tool_path(name = "nm", path = "wrapper/bin/msvc_nop.bat"), + tool_path( + name = "objcopy", + path = "wrapper/bin/msvc_nop.bat", + ), + tool_path( + name = "objdump", + path = "wrapper/bin/msvc_nop.bat", + ), + tool_path( + name = "strip", + path = "wrapper/bin/msvc_nop.bat", + ), + ] + + return cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + artifact_name_patterns = artifact_name_patterns, + cxx_builtin_include_directories = cxx_builtin_include_directories, + toolchain_identifier = toolchain_identifier, + host_system_name = host_system_name, + target_system_name = target_system_name, + target_cpu = target_cpu, + target_libc = target_libc, + compiler = compiler, + abi_version = abi_version, + abi_libc_version = abi_libc_version, + tool_paths = tool_paths, + make_variables = make_variables, + builtin_sysroot = builtin_sysroot, + cc_target_os = None, + ) + +def _windows_msys_mingw_impl(ctx): + toolchain_identifier = "msys_x64_mingw" + host_system_name = "local" + target_system_name = "local" + target_cpu = "x64_windows" + target_libc = "mingw" + compiler = "mingw-gcc" + abi_version = "local" + abi_libc_version = "local" + cc_target_os = None + builtin_sysroot = None + action_configs = [] + + targets_windows_feature = feature( + name = "targets_windows", + implies = ["copy_dynamic_libraries_to_binary"], + enabled = True, + ) + + copy_dynamic_libraries_to_binary_feature = feature(name = "copy_dynamic_libraries_to_binary") + + gcc_env_feature = feature( + name = "gcc_env", + enabled = True, + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + env_entries = [ + env_entry(key = "PATH", value = "c:/tools/msys64/mingw64/bin"), + ], + ), + ], + ) + + msys_mingw_flags = [ + "-std=gnu++0x", + ] + msys_mingw_link_flags = [ + "-lstdc++", + ] + + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + ), + flag_set( + actions = [ + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = ([flag_group(flags = msys_mingw_flags)] if msys_mingw_flags else []), + ), + ], + ) + + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = ([flag_group(flags = msys_mingw_link_flags)] if msys_mingw_link_flags else []), + ), + ], + ) + + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + + features = [ + targets_windows_feature, + copy_dynamic_libraries_to_binary_feature, + gcc_env_feature, + default_compile_flags_feature, + default_link_flags_feature, + supports_dynamic_linker_feature, + ] + + cxx_builtin_include_directories = [ + # This is a workaround for https://github.com/bazelbuild/bazel/issues/5087. + "C:\\botcode\\w", + "c:/tools/msys64/mingw64/", + "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\INCLUDE", + "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.10240.0\\ucrt", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\shared", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\um", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\winrt", + ] + + artifact_name_patterns = [ + artifact_name_pattern( + category_name = "executable", + prefix = "", + extension = ".exe", + ), + ] + + make_variables = [] + tool_paths = [ + tool_path(name = "ar", path = "c:/tools/msys64/mingw64/bin/ar"), + tool_path(name = "compat-ld", path = "c:/tools/msys64/mingw64/bin/ld"), + tool_path(name = "cpp", path = "c:/tools/msys64/mingw64/bin/cpp"), + tool_path(name = "dwp", path = "c:/tools/msys64/mingw64/bin/dwp"), + tool_path(name = "gcc", path = "c:/tools/msys64/mingw64/bin/gcc"), + tool_path(name = "gcov", path = "c:/tools/msys64/mingw64/bin/gcov"), + tool_path(name = "ld", path = "c:/tools/msys64/mingw64/bin/ld"), + tool_path(name = "nm", path = "c:/tools/msys64/mingw64/bin/nm"), + tool_path(name = "objcopy", path = "c:/tools/msys64/mingw64/bin/objcopy"), + tool_path(name = "objdump", path = "c:/tools/msys64/mingw64/bin/objdump"), + tool_path(name = "strip", path = "c:/tools/msys64/mingw64/bin/strip"), + ] + + return cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + artifact_name_patterns = artifact_name_patterns, + cxx_builtin_include_directories = cxx_builtin_include_directories, + toolchain_identifier = toolchain_identifier, + host_system_name = host_system_name, + target_system_name = target_system_name, + target_cpu = target_cpu, + target_libc = target_libc, + compiler = compiler, + abi_version = abi_version, + abi_libc_version = abi_libc_version, + tool_paths = tool_paths, + make_variables = make_variables, + builtin_sysroot = builtin_sysroot, + cc_target_os = cc_target_os, + ) + +def _armeabi_impl(ctx): + toolchain_identifier = "stub_armeabi-v7a" + host_system_name = "armeabi-v7a" + target_system_name = "armeabi-v7a" + target_cpu = "armeabi-v7a" + target_libc = "armeabi-v7a" + compiler = "compiler" + abi_version = "armeabi-v7a" + abi_libc_version = "armeabi-v7a" + cc_target_os = None + builtin_sysroot = None + action_configs = [] + + supports_pic_feature = feature(name = "supports_pic", enabled = True) + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + features = [supports_dynamic_linker_feature, supports_pic_feature] + + cxx_builtin_include_directories = [ + # This is a workaround for https://github.com/bazelbuild/bazel/issues/5087. + "C:\\botcode\\w", + ] + artifact_name_patterns = [] + make_variables = [] + + tool_paths = [ + tool_path(name = "ar", path = "/bin/false"), + tool_path(name = "compat-ld", path = "/bin/false"), + tool_path(name = "cpp", path = "/bin/false"), + tool_path(name = "dwp", path = "/bin/false"), + tool_path(name = "gcc", path = "/bin/false"), + tool_path(name = "gcov", path = "/bin/false"), + tool_path(name = "ld", path = "/bin/false"), + tool_path(name = "nm", path = "/bin/false"), + tool_path(name = "objcopy", path = "/bin/false"), + tool_path(name = "objdump", path = "/bin/false"), + tool_path(name = "strip", path = "/bin/false"), + ] + + return cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + artifact_name_patterns = artifact_name_patterns, + cxx_builtin_include_directories = cxx_builtin_include_directories, + toolchain_identifier = toolchain_identifier, + host_system_name = host_system_name, + target_system_name = target_system_name, + target_cpu = target_cpu, + target_libc = target_libc, + compiler = compiler, + abi_version = abi_version, + abi_libc_version = abi_libc_version, + tool_paths = tool_paths, + make_variables = make_variables, + builtin_sysroot = builtin_sysroot, + cc_target_os = cc_target_os, + ) + +def _impl(ctx): + if ctx.attr.cpu == "armeabi-v7a": + return _armeabi_impl(ctx) + elif ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "msvc-cl": + return _windows_msvc_impl(ctx) + elif ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "mingw-gcc": + return _windows_msys_mingw_impl(ctx) + + tool_paths = [ + tool_path(name = "ar", path = "c:/tools/msys64/usr/bin/ar"), + tool_path(name = "compat-ld", path = "c:/tools/msys64/usr/bin/ld"), + tool_path(name = "cpp", path = "c:/tools/msys64/usr/bin/cpp"), + tool_path(name = "dwp", path = "c:/tools/msys64/usr/bin/dwp"), + tool_path(name = "gcc", path = "c:/tools/msys64/usr/bin/gcc"), + tool_path(name = "gcov", path = "c:/tools/msys64/usr/bin/gcov"), + tool_path(name = "ld", path = "c:/tools/msys64/usr/bin/ld"), + tool_path(name = "nm", path = "c:/tools/msys64/usr/bin/nm"), + tool_path(name = "objcopy", path = "c:/tools/msys64/usr/bin/objcopy"), + tool_path(name = "objdump", path = "c:/tools/msys64/usr/bin/objdump"), + tool_path(name = "strip", path = "c:/tools/msys64/usr/bin/strip"), + ] + + cxx_builtin_include_directories = [ + # This is a workaround for https://github.com/bazelbuild/bazel/issues/5087. + "C:\\botcode\\w", + "c:/tools/msys64/usr/", + "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\INCLUDE", + "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.10240.0\\ucrt", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\shared", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\um", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\winrt", + ] + + action_configs = [] + + compile_flags = [ + ] + + dbg_compile_flags = [ + ] + + opt_compile_flags = [ + ] + + cxx_flags = [ + "-std=gnu++0x", + ] + + link_flags = [ + "-lstdc++", + ] + + opt_link_flags = [ + ] + + unfiltered_compile_flags = [ + ] + + targets_windows_feature = feature( + name = "targets_windows", + implies = ["copy_dynamic_libraries_to_binary"], + enabled = True, + ) + + copy_dynamic_libraries_to_binary_feature = feature(name = "copy_dynamic_libraries_to_binary") + + gcc_env_feature = feature( + name = "gcc_env", + enabled = True, + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + env_entries = [ + env_entry(key = "PATH", value = "c:/tools/msys64/usr/bin"), + ], + ), + ], + ) + + windows_features = [ + targets_windows_feature, + copy_dynamic_libraries_to_binary_feature, + gcc_env_feature, + ] + + supports_pic_feature = feature( + name = "supports_pic", + enabled = True, + ) + supports_start_end_lib_feature = feature( + name = "supports_start_end_lib", + enabled = True, + ) + + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = ([flag_group(flags = compile_flags)] if compile_flags else []), + ), + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = ([flag_group(flags = dbg_compile_flags)] if dbg_compile_flags else []), + with_features = [with_feature_set(features = ["dbg"])], + ), + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = ([flag_group(flags = opt_compile_flags)] if opt_compile_flags else []), + with_features = [with_feature_set(features = ["opt"])], + ), + flag_set( + actions = [ + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = ([flag_group(flags = cxx_flags)] if cxx_flags else []), + ), + ], + ) + + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = ([flag_group(flags = link_flags)] if link_flags else []), + ), + flag_set( + actions = all_link_actions, + flag_groups = ([flag_group(flags = opt_link_flags)] if opt_link_flags else []), + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + + dbg_feature = feature(name = "dbg") + + opt_feature = feature(name = "opt") + + sysroot_feature = feature( + name = "sysroot", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = ["--sysroot=%{sysroot}"], + expand_if_available = "sysroot", + ), + ], + ), + ], + ) + + fdo_optimize_feature = feature( + name = "fdo_optimize", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [ + flag_group( + flags = [ + "-fprofile-use=%{fdo_profile_path}", + "-fprofile-correction", + ], + expand_if_available = "fdo_profile_path", + ), + ], + ), + ], + provides = ["profile"], + ) + + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + + user_compile_flags_feature = feature( + name = "user_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = [ + flag_group( + flags = ["%{user_compile_flags}"], + iterate_over = "user_compile_flags", + expand_if_available = "user_compile_flags", + ), + ], + ), + ], + ) + + unfiltered_compile_flags_feature = feature( + name = "unfiltered_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = ([flag_group(flags = unfiltered_compile_flags)] if unfiltered_compile_flags else []), + ), + ], + ) + + features = windows_features + [ + supports_pic_feature, + default_compile_flags_feature, + default_link_flags_feature, + fdo_optimize_feature, + supports_dynamic_linker_feature, + dbg_feature, + opt_feature, + user_compile_flags_feature, + sysroot_feature, + unfiltered_compile_flags_feature, + ] + + artifact_name_patterns = [ + artifact_name_pattern(category_name = "executable", prefix = "", extension = ".exe"), + ] + + make_variables = [] + + return cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + artifact_name_patterns = artifact_name_patterns, + cxx_builtin_include_directories = cxx_builtin_include_directories, + toolchain_identifier = "msys_x64", + host_system_name = "local", + target_system_name = "local", + target_cpu = "x64_windows", + target_libc = "msys", + compiler = "msys-gcc", + abi_version = "local", + abi_libc_version = "local", + tool_paths = tool_paths, + make_variables = make_variables, + builtin_sysroot = "", + cc_target_os = None, + ) + +cc_toolchain_config = rule( + implementation = _impl, + attrs = { + "cpu": attr.string(mandatory = True), + "compiler": attr.string(), + }, + provides = [CcToolchainConfigInfo], +) diff --git a/third_party/toolchains/bazel_0.23.2/dummy_toolchain.bzl b/third_party/toolchains/bazel_0.23.2/dummy_toolchain.bzl new file mode 100644 index 00000000000..45c0285d232 --- /dev/null +++ b/third_party/toolchains/bazel_0.23.2/dummy_toolchain.bzl @@ -0,0 +1,23 @@ +# pylint: disable=g-bad-file-header +# Copyright 2017 The Bazel Authors. All rights reserved. +# +# 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. + +"""Skylark rule that stubs a toolchain.""" + +def _dummy_toolchain_impl(ctx): + ctx = ctx # unused argument + toolchain = platform_common.ToolchainInfo() + return [toolchain] + +dummy_toolchain = rule(_dummy_toolchain_impl, attrs = {}) diff --git a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh index 3dd0167b7c0..93f6bd65fe6 100755 --- a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh +++ b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh @@ -25,4 +25,4 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc ${name}') cd /var/local/git/grpc #TODO(yfen): add back examples/... to build targets once python rules issues are resolved -bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... +bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... \ No newline at end of file diff --git a/tools/remote_build/windows.bazelrc b/tools/remote_build/windows.bazelrc index 70575372d02..a4cb66a7d34 100644 --- a/tools/remote_build/windows.bazelrc +++ b/tools/remote_build/windows.bazelrc @@ -1,3 +1,51 @@ # TODO(yfen): Merge with rbe_common.bazelrc and enable Windows RBE + +startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 + +build --remote_cache=remotebuildexecution.googleapis.com +build --remote_executor=remotebuildexecution.googleapis.com +build --tls_enabled=true + +build --host_crosstool_top=//third_party/toolchains/bazel_0.23.2:toolchain +build --crosstool_top=//third_party/toolchains/bazel_0.23.2:toolchain +build --extra_toolchains=//third_party/toolchains/bazel_0.23.2:cc-toolchain-x64_windows +# Use custom execution platforms defined in third_party/toolchains +build --extra_execution_platforms=//third_party/toolchains:rbe_windows +build --host_platform=//third_party/toolchains:rbe_windows +build --platforms=//third_party/toolchains:rbe_windows + +build --shell_executable=C:\\tools\\msys64\\usr\\bin\\bash.exe +build --python_path=C:\\Python27\\python.exe + +build --spawn_strategy=remote +build --strategy=Javac=remote +build --strategy=Closure=remote +build --genrule_strategy=remote +build --remote_timeout=3600 + +build --remote_instance_name=projects/grpc-testing/instances/grpc-windows-rbe-test + +build --verbose_failures=true + +build --experimental_strict_action_env=true +build --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 + +# don't use port server +build --define GRPC_PORT_ISOLATED_RUNTIME=1 build --test_tag_filters=-no_windows build --build_tag_filters=-no_windows + +# without verbose gRPC logs the test outputs are not very useful +test --test_env=GRPC_VERBOSITY=debug + +# Set flags for uploading to BES in order to view results in the Bazel Build +# Results UI. +build --bes_backend="buildeventservice.googleapis.com" +build --bes_timeout=60s +build --bes_results_url="https://source.cloud.google.com/results/invocations/" +build --project_id=grpc-testing + +build --jobs=30 + +# print output for tests that fail (default is "summary") +build --test_output=errors From 327350ab3996f12d8daa425f89b3aba94c682854 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 5 Apr 2019 12:16:37 -0700 Subject: [PATCH 1778/2143] ServiceConfig::Create expects non-Null error and better errors --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 5 +- .../client_channel/resolver_result_parsing.cc | 5 +- .../filters/client_channel/service_config.cc | 115 +++++++++++------- .../filters/client_channel/service_config.h | 15 ++- .../ext/filters/client_channel/subchannel.cc | 5 +- .../message_size/message_size_filter.cc | 5 +- .../client_channel/service_config_test.cc | 51 ++++++-- test/cpp/end2end/grpclb_end2end_test.cc | 4 +- test/cpp/end2end/xds_end2end_test.cc | 4 + 9 files changed, 150 insertions(+), 59 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 7ce706724ee..7b5eb311393 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 @@ -308,8 +308,11 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { if (service_config_string != nullptr) { GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s", r, service_config_string); + grpc_error* service_config_error = GRPC_ERROR_NONE; result.service_config = - ServiceConfig::Create(service_config_string, nullptr); + ServiceConfig::Create(service_config_string, &service_config_error); + // Error is currently unused. + GRPC_ERROR_UNREF(service_config_error); } gpr_free(service_config_string); } 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 f523ffe1610..7148e16e70b 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -52,7 +52,10 @@ ProcessedResolverResult::ProcessedResolverResult( 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, nullptr); + grpc_error* error = GRPC_ERROR_NONE; + service_config_ = ServiceConfig::Create(service_config_json, &error); + // Error is currently unused. + GRPC_ERROR_UNREF(error); } } else { // Add the service config JSON to channel args so that it's diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index 30b5981da84..360b4cd81bf 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -38,30 +38,16 @@ RefCountedPtr ServiceConfig::Create(const char* json, grpc_error** error) { UniquePtr service_config_json(gpr_strdup(json)); UniquePtr json_string(gpr_strdup(json)); + GPR_DEBUG_ASSERT(error != nullptr); grpc_json* json_tree = grpc_json_parse_string(json_string.get()); if (json_tree == nullptr) { - if (error != nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "failed to parse JSON for service config"); - } + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "failed to parse JSON for service config"); return nullptr; } - grpc_error* create_error; auto return_value = MakeRefCounted( - std::move(service_config_json), std::move(json_string), json_tree, - &create_error); - if (create_error != GRPC_ERROR_NONE) { - if (error != nullptr) { - *error = create_error; - } else { - GRPC_ERROR_UNREF(create_error); - } - return nullptr; - } - if (error != nullptr) { - *error = GRPC_ERROR_NONE; - } - return return_value; + std::move(service_config_json), std::move(json_string), json_tree, error); + return *error == GRPC_ERROR_NONE ? return_value : nullptr; } ServiceConfig::ServiceConfig(UniquePtr service_config_json, @@ -115,22 +101,26 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( if (child->key == nullptr) continue; if (strcmp(child->key, "name") == 0) { if (child->type != GRPC_JSON_ARRAY) { - return grpc_error_add_child(error, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "name should be of type Array")); + error = grpc_error_add_child(error, + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error:not of type Array")); + goto wrap_error; } for (grpc_json* name = child->child; name != nullptr; name = name->next) { - UniquePtr path = ParseJsonMethodName(name); + grpc_error* parse_error = GRPC_ERROR_NONE; + UniquePtr path = ParseJsonMethodName(name, &parse_error); if (path == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to parse name"); + error = grpc_error_add_child(error, parse_error); + } else { + GPR_DEBUG_ASSERT(parse_error == GRPC_ERROR_NONE); } paths.push_back(std::move(path)); } } } if (paths.size() == 0) { - return grpc_error_add_child(error, - GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No names specified in methodConfig")); + error = grpc_error_add_child( + error, GRPC_ERROR_CREATE_FROM_STATIC_STRING("No names specified")); } // Add entry for each path. for (size_t i = 0; i < paths.size(); ++i) { @@ -138,6 +128,11 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( entries[*idx].value = vector_ptr; // Takes a new ref. ++*idx; } +wrap_error: + if (error != GRPC_ERROR_NONE) { + error = grpc_error_add_child( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("field:methodConfig"), error); + } return error; } @@ -150,8 +145,9 @@ grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { for (grpc_json* field = json_tree->child; field != nullptr; field = field->next) { if (field->key == nullptr) { - error = grpc_error_add_child(error, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Illegal key value - NULL")); + error = + grpc_error_add_child(error, GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "error:Illegal key value - NULL")); continue; } if (strcmp(field->key, "methodConfig") == 0) { @@ -159,17 +155,17 @@ grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { GPR_ASSERT(false); } if (field->type != GRPC_JSON_ARRAY) { - return grpc_error_add_child(error, - GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "methodConfig is not of type Array")); + return grpc_error_add_child( + error, GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:methodConfig error:not of type Array")); } for (grpc_json* method = field->child; method != nullptr; method = method->next) { int count = CountNamesInMethodConfig(method); if (count <= 0) { - error = grpc_error_add_child(error, - GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No names found in methodConfig")); + error = grpc_error_add_child( + error, GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:methodConfig error:No names found")); } num_entries += static_cast(count); } @@ -184,6 +180,7 @@ grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { error, ParseJsonMethodConfigToServiceConfigObjectsTable( method, entries, &idx)); } + GPR_DEBUG_ASSERT(num_entries == idx); break; } } @@ -229,24 +226,56 @@ int ServiceConfig::CountNamesInMethodConfig(grpc_json* json) { return num_names; } -UniquePtr ServiceConfig::ParseJsonMethodName(grpc_json* json) { - if (json->type != GRPC_JSON_OBJECT) return nullptr; +UniquePtr ServiceConfig::ParseJsonMethodName(grpc_json* json, + grpc_error** error) { + if (json->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Field name should be of type object"); + return nullptr; + } const char* service_name = nullptr; const char* method_name = nullptr; for (grpc_json* child = json->child; child != nullptr; child = child->next) { - if (child->key == nullptr) return nullptr; - if (child->type != GRPC_JSON_STRING) return nullptr; + if (child->key == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Child entry with no key"); + return nullptr; + } + if (child->type != GRPC_JSON_STRING) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Child entry should of type string"); + return nullptr; + } if (strcmp(child->key, "service") == 0) { - if (service_name != nullptr) return nullptr; // Duplicate. - if (child->value == nullptr) return nullptr; + if (service_name != nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:service error:Multiple entries"); + return nullptr; // Duplicate. + } + if (child->value == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:service error:empty value"); + return nullptr; + } service_name = child->value; } else if (strcmp(child->key, "method") == 0) { - if (method_name != nullptr) return nullptr; // Duplicate. - if (child->value == nullptr) return nullptr; + if (method_name != nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:method error:multiple entries"); + return nullptr; // Duplicate. + } + if (child->value == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:method error:empty value"); + return nullptr; + } method_name = child->value; } } - if (service_name == nullptr) return nullptr; // Required field. + if (service_name == nullptr) { + *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("field:service error:not found"); + return nullptr; // Required field. + } char* path; gpr_asprintf(&path, "/%s/%s", service_name, method_name == nullptr ? "*" : method_name); diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 3eb3bd54644..9738cc82d30 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -185,8 +185,9 @@ class ServiceConfig : public RefCounted { static int CountNamesInMethodConfig(grpc_json* json); // Returns a path string for the JSON name object specified by \a json. - // Returns null on error. - static UniquePtr ParseJsonMethodName(grpc_json* json); + // Returns null on error, and stores error in \a error. + static UniquePtr ParseJsonMethodName(grpc_json* json, + grpc_error** error); // Parses the method config from \a json. Adds an entry to \a entries for // each name found, incrementing \a idx for each entry added. @@ -209,8 +210,13 @@ class ServiceConfig : public RefCounted { InlinedVector, kNumPreallocatedParsers> parsed_global_service_config_objects_; + // A map from the method name to the service config objects vector. Note that + // we are using a raw pointer and not a unique pointer so that we can use the + // same vector for multiple names. RefCountedPtr> parsed_method_service_config_objects_table_; + // Storage for all the vectors that are being used in + // parsed_method_service_config_objects_table_. InlinedVector, 32> service_config_objects_vectors_storage_; }; @@ -247,7 +253,10 @@ bool ServiceConfig::ParseJsonMethodConfig( if (strcmp(child->key, "name") == 0) { if (child->type != GRPC_JSON_ARRAY) return false; for (grpc_json* name = child->child; name != nullptr; name = name->next) { - UniquePtr path = ParseJsonMethodName(name); + grpc_error* error = GRPC_ERROR_NONE; + UniquePtr path = ParseJsonMethodName(name, &error); + // We are not reporting the error here. + GRPC_ERROR_UNREF(error); if (path == nullptr) return false; paths.push_back(std::move(path)); } diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index d66779e6192..20a6023f71c 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -590,8 +590,11 @@ 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) { + grpc_error* service_config_error = GRPC_ERROR_NONE; RefCountedPtr service_config = - ServiceConfig::Create(service_config_json, nullptr); + ServiceConfig::Create(service_config_json, &service_config_error); + // service_config_error is currently unused. + GRPC_ERROR_UNREF(service_config_error); if (service_config != nullptr) { HealthCheckParams params; service_config->ParseGlobalParams(HealthCheckParams::Parse, ¶ms); 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 8c2a32cc618..4d120c0eb76 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -319,8 +319,11 @@ 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_error* service_config_error = GRPC_ERROR_NONE; grpc_core::RefCountedPtr service_config = - grpc_core::ServiceConfig::Create(service_config_str, nullptr); + grpc_core::ServiceConfig::Create(service_config_str, + &service_config_error); + GRPC_ERROR_UNREF(service_config_error); if (service_config != nullptr) { chand->method_limit_table = service_config->CreateMethodConfigTable( grpc_core::MessageSizeLimits::CreateFromJson); diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index d8cb3532cb5..50e99ccfc10 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -46,14 +46,14 @@ class TestParser1 : public ServiceConfigParser { field = field->next) { if (strcmp(field->key, "global_param") == 0) { if (field->type != GRPC_JSON_NUMBER) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "global_param value type should be a number"); + *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidTypeErrorMessage()); return nullptr; } int value = gpr_parse_nonnegative_int(field->value); if (value == -1) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "global_param value type should be non-negative"); + *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidValueErrorMessage()); return nullptr; } return UniquePtr( @@ -62,6 +62,14 @@ class TestParser1 : public ServiceConfigParser { } return nullptr; } + + static const char* InvalidTypeErrorMessage() { + return "global_param value type should be a number"; + } + + static const char* InvalidValueErrorMessage() { + return "global_param value type should be non-negative"; + } }; class TestParser2 : public ServiceConfigParser { @@ -76,14 +84,14 @@ class TestParser2 : public ServiceConfigParser { } if (strcmp(field->key, "method_param") == 0) { if (field->type != GRPC_JSON_NUMBER) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "method_param value type should be a number"); + *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidTypeErrorMessage()); return nullptr; } int value = gpr_parse_nonnegative_int(field->value); if (value == -1) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "method_param value type should be non-negative"); + *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidValueErrorMessage()); return nullptr; } return UniquePtr( @@ -92,6 +100,14 @@ class TestParser2 : public ServiceConfigParser { } return nullptr; } + + static const char* InvalidTypeErrorMessage() { + return "method_param value type should be a number"; + } + + static const char* InvalidValueErrorMessage() { + return "method_param value type should be non-negative"; + } }; class ServiceConfigTest : public ::testing::Test { @@ -110,7 +126,10 @@ TEST_F(ServiceConfigTest, ErrorCheck1) { const char* test_json = ""; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); EXPECT_TRUE(error != GRPC_ERROR_NONE); + EXPECT_TRUE(strstr(grpc_error_string(error), + "failed to parse JSON for service config") != nullptr); } TEST_F(ServiceConfigTest, BasicTest1) { @@ -126,6 +145,7 @@ TEST_F(ServiceConfigTest, ErrorNoNames) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); EXPECT_TRUE(error != GRPC_ERROR_NONE); + EXPECT_TRUE(strstr(grpc_error_string(error), "No names found") != nullptr); } TEST_F(ServiceConfigTest, ErrorNoNamesWithMultipleMethodConfigs) { @@ -135,6 +155,7 @@ TEST_F(ServiceConfigTest, ErrorNoNamesWithMultipleMethodConfigs) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); EXPECT_TRUE(error != GRPC_ERROR_NONE); + EXPECT_TRUE(strstr(grpc_error_string(error), "No names found") != nullptr); } TEST_F(ServiceConfigTest, ValidMethodConfig) { @@ -171,6 +192,8 @@ TEST_F(ServiceConfigTest, Parser1ErrorInvalidType) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); EXPECT_TRUE(error != GRPC_ERROR_NONE); + EXPECT_TRUE(strstr(grpc_error_string(error), + TestParser1::InvalidTypeErrorMessage()) != nullptr); } TEST_F(ServiceConfigTest, Parser1ErrorInvalidValue) { @@ -179,6 +202,8 @@ TEST_F(ServiceConfigTest, Parser1ErrorInvalidValue) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); EXPECT_TRUE(error != GRPC_ERROR_NONE); + EXPECT_TRUE(strstr(grpc_error_string(error), + TestParser1::InvalidValueErrorMessage()) != nullptr); } TEST_F(ServiceConfigTest, Parser2BasicTest) { @@ -188,6 +213,12 @@ TEST_F(ServiceConfigTest, Parser2BasicTest) { grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); EXPECT_TRUE(error == GRPC_ERROR_NONE); + const auto* const* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + ASSERT_TRUE(vector_ptr != nullptr); + const auto* vector = *vector_ptr; + auto parsed_object = ((*vector)[1]).get(); + EXPECT_TRUE(static_cast(parsed_object)->value() == 5); } TEST_F(ServiceConfigTest, Parser2ErrorInvalidType) { @@ -197,6 +228,8 @@ TEST_F(ServiceConfigTest, Parser2ErrorInvalidType) { grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); EXPECT_TRUE(error != GRPC_ERROR_NONE); + EXPECT_TRUE(strstr(grpc_error_string(error), + TestParser2::InvalidTypeErrorMessage()) != nullptr); } TEST_F(ServiceConfigTest, Parser2ErrorInvalidValue) { @@ -206,6 +239,8 @@ TEST_F(ServiceConfigTest, Parser2ErrorInvalidValue) { grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); EXPECT_TRUE(error != GRPC_ERROR_NONE); + EXPECT_TRUE(strstr(grpc_error_string(error), + TestParser2::InvalidValueErrorMessage()) != nullptr); } } // namespace testing diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 7c6432379a6..096482543ca 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -542,8 +542,10 @@ class GrpclbEnd2endTest : public ::testing::Test { grpc_core::Resolver::Result result; result.addresses = CreateLbAddressesFromAddressDataList(address_data); if (service_config_json != nullptr) { + grpc_error* error = GRPC_ERROR_NONE; result.service_config = - grpc_core::ServiceConfig::Create(service_config_json); + grpc_core::ServiceConfig::Create(service_config_json, &error); + GRPC_ERROR_UNREF(error); } response_generator_->SetResponse(std::move(result)); } diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index 61e759c61b5..fc343939041 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -524,8 +524,10 @@ class XdsEnd2endTest : public ::testing::Test { grpc_core::Resolver::Result result; result.addresses = CreateLbAddressesFromPortList(ports); if (service_config_json != nullptr) { + grpc_error* error = GRPC_ERROR_NONE; result.service_config = grpc_core::ServiceConfig::Create(service_config_json); + GRPC_ERROR_UNREF(error); } grpc_arg arg = grpc_core::FakeResolverResponseGenerator::MakeChannelArg( lb_channel_response_generator == nullptr @@ -555,8 +557,10 @@ class XdsEnd2endTest : public ::testing::Test { grpc_core::Resolver::Result result; result.addresses = CreateLbAddressesFromPortList(ports); if (service_config_json != nullptr) { + grpc_error* error = GRPC_ERROR_NONE; result.service_config = grpc_core::ServiceConfig::Create(service_config_json); + GRPC_ERROR_UNREF(error); } if (lb_channel_response_generator == nullptr) { lb_channel_response_generator = lb_channel_response_generator_.get(); From 8eeb429db026e13514bd6dd6f98297c14cd97d4c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 5 Apr 2019 13:44:41 -0700 Subject: [PATCH 1779/2143] Missing argument --- test/cpp/end2end/xds_end2end_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index fc343939041..e4c5d444c12 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -526,7 +526,7 @@ class XdsEnd2endTest : public ::testing::Test { if (service_config_json != nullptr) { grpc_error* error = GRPC_ERROR_NONE; result.service_config = - grpc_core::ServiceConfig::Create(service_config_json); + grpc_core::ServiceConfig::Create(service_config_json, &error); GRPC_ERROR_UNREF(error); } grpc_arg arg = grpc_core::FakeResolverResponseGenerator::MakeChannelArg( @@ -559,7 +559,7 @@ class XdsEnd2endTest : public ::testing::Test { if (service_config_json != nullptr) { grpc_error* error = GRPC_ERROR_NONE; result.service_config = - grpc_core::ServiceConfig::Create(service_config_json); + grpc_core::ServiceConfig::Create(service_config_json, &error); GRPC_ERROR_UNREF(error); } if (lb_channel_response_generator == nullptr) { From b873516e6a025f9f139bca1309b53097596ce533 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Fri, 5 Apr 2019 15:10:08 -0700 Subject: [PATCH 1780/2143] PHP: fix windows build --- src/php/bin/run_tests.sh | 7 ++++--- src/php/ext/grpc/php_grpc.c | 8 ++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh index 49fd84514c1..a78dd259e2f 100755 --- a/src/php/bin/run_tests.sh +++ b/src/php/bin/run_tests.sh @@ -22,16 +22,17 @@ 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 \ +$(which 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 \ +$(which 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 \ + $(which valgrind) --error-exitcode=10 --leak-check=yes \ + $(which php) $extension_dir -d max_execution_time=300 \ ../tests/MemoryLeakTest/MemoryLeakTest.php fi diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 3064563d03f..f6c2f85ed47 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -205,11 +205,15 @@ void register_fork_handlers() { void apply_ini_settings() { if (GRPC_G(enable_fork_support)) { - setenv("GRPC_ENABLE_FORK_SUPPORT", "1", 1 /* overwrite? */); + putenv("GRPC_ENABLE_FORK_SUPPORT=1"); } if (GRPC_G(poll_strategy)) { - setenv("GRPC_POLL_STRATEGY", GRPC_G(poll_strategy), 1 /* overwrite? */); + char *poll_str = malloc(sizeof("GRPC_POLL_STRATEGY=") + + strlen(GRPC_G(poll_strategy))); + strcpy(poll_str, "GRPC_POLL_STRATEGY="); + strcat(poll_str, GRPC_G(poll_strategy)); + putenv(poll_str); } } From 896a59c6feb36cf38fec24d304c667ad2d44b470 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Fri, 5 Apr 2019 15:26:10 -0700 Subject: [PATCH 1781/2143] Change third_party/protoc-gen-validate repo path --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 06f1394df65..f4690a2687f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -50,7 +50,7 @@ url = https://github.com/googleapis/googleapis.git [submodule "third_party/protoc-gen-validate"] path = third_party/protoc-gen-validate - url = https://github.com/lyft/protoc-gen-validate.git + url = https://github.com/envoyproxy/protoc-gen-validate.git [submodule "third_party/upb"] path = third_party/upb url = https://github.com/google/upb.git From a20247ef01bf64cdeb25018607d515ca332e3a83 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 5 Apr 2019 16:54:38 -0700 Subject: [PATCH 1782/2143] Bump version to v1.20.0-pre3 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index 7db6db3c2d5..6ad0da80e22 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "godric" core_version = "7.0.0" -version = "1.20.0-pre2" +version = "1.20.0-pre3" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 40741f2f0fe..3868e5793ab 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: godric - version: 1.20.0-pre2 + version: 1.20.0-pre3 filegroups: - name: alts_proto headers: From 8beaac29115565f8070fe8a14787a8c9be855a7e Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 5 Apr 2019 16:57:57 -0700 Subject: [PATCH 1783/2143] 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 | 4 ++-- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 2 +- src/csharp/build/dependencies.props | 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, 33 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 644e309ae7b..2c57715bd9c 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.20.0-pre2") +set(PACKAGE_VERSION "1.20.0-pre3") 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 ab15fc01601..8664ceeb96a 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.20.0-pre2 -CSHARP_VERSION = 1.20.0-pre2 +CPP_VERSION = 1.20.0-pre3 +CSHARP_VERSION = 1.20.0-pre3 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 0a0624707d5..2a68ca4e04b 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.20.0-pre2' - version = '0.0.8-pre2' + # version = '1.20.0-pre3' + version = '0.0.8-pre3' 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.20.0-pre2' + grpc_version = '1.20.0-pre3' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index e76977cb2ec..bd153c71c72 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.20.0-pre2' + version = '1.20.0-pre3' 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 73f20a1a17c..56954ffae93 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.20.0-pre2' + version = '1.20.0-pre3' 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 ab2d7c53707..ca1a2ec5d23 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.20.0-pre2' + version = '1.20.0-pre3' 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 6a0ef18f9ad..201053844b6 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.20.0-pre2' + version = '1.20.0-pre3' 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 c0f1e13fa09..a16c9995c9b 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.20.0RC2 - 1.20.0RC2 + 1.20.0RC3 + 1.20.0RC3 beta diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index fd77ae95b92..a9f9aaa93a8 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.20.0-pre2"; } +grpc::string Version() { return "1.20.0-pre3"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index 23c7f49fe30..a49b2cdc251 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.20.0-pre2"; + public const string CurrentVersion = "1.20.0-pre3"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index 3e6c122bb80..2eb9b6b3ab8 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.20.0-pre2 + 1.20.0-pre3 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 5b2a75310f4..a614f1362f1 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.20.0-pre2 +set VERSION=1.20.0-pre3 @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 4bec215b9ad..956898ed247 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.20.0-pre2' + v = '1.20.0-pre3' 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 d3ec6c5aaf7..4cba1f3c2ae 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.20.0-pre2" +#define GRPC_OBJC_VERSION_STRING @"1.20.0-pre3" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 1f390ada086..d54641e19ce 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.20.0-pre2" +#define GRPC_OBJC_VERSION_STRING @"1.20.0-pre3" #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 9e9da239a35..13e217be68e 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.20.0RC2" +#define PHP_GRPC_VERSION "1.20.0RC3" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index e7f07d54ab1..d4017ab4b99 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.20.0rc2""" +__version__ = """1.20.0rc3""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 5c2d54c00d5..7dce9c7882b 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.20.0rc2' +VERSION = '1.20.0rc3' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index d3f28419c9e..9600168ce9d 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.20.0rc2' +VERSION = '1.20.0rc3' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 2f200c4fba2..f25a63617a9 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.20.0rc2' +VERSION = '1.20.0rc3' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 400b3e24d24..e699dc58d41 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.20.0rc2' +VERSION = '1.20.0rc3' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index a7945b11735..333e6dfbf53 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.20.0rc2' +VERSION = '1.20.0rc3' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 15411c8d61b..65c06d8c47b 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.20.0rc2' +VERSION = '1.20.0rc3' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index e5a8b3aa750..1dcc0cf14c5 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.20.0rc2' +VERSION = '1.20.0rc3' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 05fbcc35e01..118e780f1ed 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.20.0.pre2' + VERSION = '1.20.0.pre3' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 8f8d6f0b0f3..4afaa7e3c97 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.20.0.pre2' + VERSION = '1.20.0.pre3' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 19f672f5032..d0aefff6d6b 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.20.0rc2' +VERSION = '1.20.0rc3' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 7c3716b764f..511b487990f 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.20.0-pre2 +PROJECT_NUMBER = 1.20.0-pre3 # 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 b2a509b47e9..9d728aa004e 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.20.0-pre2 +PROJECT_NUMBER = 1.20.0-pre3 # 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 9580c45c65e0fb2032a5ac1375a210fd05b01639 Mon Sep 17 00:00:00 2001 From: John Luo Date: Fri, 5 Apr 2019 17:31:27 -0700 Subject: [PATCH 1784/2143] Add VS integration for design time build --- .../build/_protobuf/Google.Protobuf.Tools.targets | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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 1a862337c58..de2f66e5be1 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets @@ -38,6 +38,21 @@ + + + + + + + + + + + + MSBuild:Compile + + + - - - - MSBuild:Compile - From cee3292cdf8464bb98e5113f74d6a4073c36489e Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Mon, 8 Apr 2019 09:11:04 -0700 Subject: [PATCH 1789/2143] Update callback API documentation --- include/grpcpp/impl/codegen/server_callback.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 87edea84f41..9afddfba09f 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -253,7 +253,9 @@ class ServerBidiReactor : public internal::ServerReactor { void Finish(Status s) { stream_->Finish(std::move(s)); } /// Notify the application that a streaming RPC has started and that it is now - /// ok to call any operation initation method. + /// ok to call any operation initiation method. An RPC is considered started + /// after the server has received all initial metadata from the client, which + /// is a result of the client calling StartCall(). /// /// \param[in] context The context object now associated with this RPC virtual void OnStarted(ServerContext* context) {} From b86e70592e25e04d27f52e697cd29c0bf4a02972 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Mon, 8 Apr 2019 10:13:17 -0700 Subject: [PATCH 1790/2143] Format --- include/grpcpp/impl/codegen/server_callback.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 9afddfba09f..4c6b189214e 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -254,7 +254,7 @@ class ServerBidiReactor : public internal::ServerReactor { /// Notify the application that a streaming RPC has started and that it is now /// ok to call any operation initiation method. An RPC is considered started - /// after the server has received all initial metadata from the client, which + /// after the server has received all initial metadata from the client, which /// is a result of the client calling StartCall(). /// /// \param[in] context The context object now associated with this RPC From d116f58e8e0aa376ce1e8fc1147aa1a1780c09d0 Mon Sep 17 00:00:00 2001 From: John Luo Date: Mon, 8 Apr 2019 11:19:57 -0700 Subject: [PATCH 1791/2143] Remove fix for bug in project system --- .../build/_protobuf/Google.Protobuf.Tools.targets | 10 ---------- 1 file changed, 10 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 d1597872dab..80c7109e016 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets @@ -39,16 +39,6 @@ - - - - - - - - - - - 1.20.0-pre3 + 1.20.0 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index a614f1362f1..d0230757628 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.20.0-pre3 +set VERSION=1.20.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 956898ed247..f1529fbd3fb 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.20.0-pre3' + v = '1.20.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 4cba1f3c2ae..d7c7e65bd46 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.20.0-pre3" +#define GRPC_OBJC_VERSION_STRING @"1.20.0" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index d54641e19ce..6c547e15bee 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.20.0-pre3" +#define GRPC_OBJC_VERSION_STRING @"1.20.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 13e217be68e..0333c8d17a6 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.20.0RC3" +#define PHP_GRPC_VERSION "1.20.0" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index d4017ab4b99..d2b7655ed4a 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.20.0rc3""" +__version__ = """1.20.0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 7dce9c7882b..b28450deab7 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.20.0rc3' +VERSION = '1.20.0' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 9600168ce9d..85c468277c3 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.20.0rc3' +VERSION = '1.20.0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index f25a63617a9..eecc1fe5eb0 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.20.0rc3' +VERSION = '1.20.0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index e699dc58d41..892b4010e90 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.20.0rc3' +VERSION = '1.20.0' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 333e6dfbf53..6c042c2aace 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.20.0rc3' +VERSION = '1.20.0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 65c06d8c47b..8af49a7c801 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.20.0rc3' +VERSION = '1.20.0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 1dcc0cf14c5..df1ab623e79 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.20.0rc3' +VERSION = '1.20.0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 118e780f1ed..9ea2b99566c 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.20.0.pre3' + VERSION = '1.20.0' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 4afaa7e3c97..b13415996e9 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.20.0.pre3' + VERSION = '1.20.0' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index d0aefff6d6b..d864b7bede5 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.20.0rc3' +VERSION = '1.20.0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 511b487990f..26840372f34 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.20.0-pre3 +PROJECT_NUMBER = 1.20.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 9d728aa004e..5d359830eab 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.20.0-pre3 +PROJECT_NUMBER = 1.20.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 a19d8dcfb50caa81cddc25bc1a6afdd7a2f497b7 Mon Sep 17 00:00:00 2001 From: Jean de Klerk Date: Mon, 15 Apr 2019 12:43:40 -0600 Subject: [PATCH 1862/2143] docs: add note about retrying UNAVAILABLE release note: no --- doc/statuscodes.md | 2 +- include/grpc/impl/codegen/status.h | 3 ++- include/grpcpp/impl/codegen/status_code_enum.h | 3 ++- src/csharp/Grpc.Core.Api/StatusCode.cs | 3 ++- src/objective-c/GRPCClient/GRPCCall.h | 3 ++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/statuscodes.md b/doc/statuscodes.md index 3d4d87e931a..61e0d820b48 100644 --- a/doc/statuscodes.md +++ b/doc/statuscodes.md @@ -20,7 +20,7 @@ statuses are defined as such: | 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 | +| UNAVAILABLE | 14 | The service is currently unavailable. This is most likely a transient condition, which can be corrected by retrying with a backoff. Note that it is not always safe to retry non-idempotent operations. | 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 diff --git a/include/grpc/impl/codegen/status.h b/include/grpc/impl/codegen/status.h index 9bc3dc95609..dec3b8f340e 100644 --- a/include/grpc/impl/codegen/status.h +++ b/include/grpc/impl/codegen/status.h @@ -128,7 +128,8 @@ typedef enum { /** The service is currently unavailable. This is a most likely a transient condition and may be corrected by retrying with - a backoff. + a backoff. Note that it is not always safe to retry non-idempotent + operations. WARNING: Although data MIGHT not have been transmitted when this status occurs, there is NOT A GUARANTEE that the server has not seen diff --git a/include/grpcpp/impl/codegen/status_code_enum.h b/include/grpcpp/impl/codegen/status_code_enum.h index 09943f10de8..bdd7ead6add 100644 --- a/include/grpcpp/impl/codegen/status_code_enum.h +++ b/include/grpcpp/impl/codegen/status_code_enum.h @@ -119,7 +119,8 @@ enum StatusCode { INTERNAL = 13, /// The service is currently unavailable. This is a most likely a transient - /// condition and may be corrected by retrying with a backoff. + /// condition and may be corrected by retrying with a backoff. Note that it is + /// not always safe to retry non-idempotent operations. /// /// \warning Although data MIGHT not have been transmitted when this /// status occurs, there is NOT A GUARANTEE that the server has not seen diff --git a/src/csharp/Grpc.Core.Api/StatusCode.cs b/src/csharp/Grpc.Core.Api/StatusCode.cs index 57fe538e815..8493f375adb 100644 --- a/src/csharp/Grpc.Core.Api/StatusCode.cs +++ b/src/csharp/Grpc.Core.Api/StatusCode.cs @@ -114,7 +114,8 @@ namespace Grpc.Core /// /// The service is currently unavailable. This is a most likely a /// transient condition and may be corrected by retrying with - /// a backoff. + /// a backoff. Note that it is not always safe to retry + /// non-idempotent operations. /// Unavailable = 14, diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 6669067fbff..7f9dd971bc6 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -135,7 +135,8 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { /** * The server is currently unavailable. This is most likely a transient condition and may be - * corrected by retrying with a backoff. + * corrected by retrying with a backoff. Note that it is not always safe to retry + * non-idempotent operations. */ GRPCErrorCodeUnavailable = 14, From a922bd7a03a35af0aaceb8f79e71f234e3fb418c Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Mon, 15 Apr 2019 12:47:50 -0700 Subject: [PATCH 1863/2143] Revert "Merge pull request #18547 from lidizheng/fix-gevent" This reverts commit 09d1011663708986d4a0e67898caa99d7f52575f, reversing changes made to e076a30f16c6d75246df2431a6b8b4070b9e87b8. --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 8 +-- src/core/lib/iomgr/iomgr_custom.cc | 3 - src/core/lib/iomgr/iomgr_custom.h | 2 - src/python/grpcio_tests/commands.py | 8 +-- src/python/grpcio_tests/tests/tests.json | 1 - .../grpcio_tests/tests/unit/BUILD.bazel | 1 - .../tests/unit/_dns_resolver_test.py | 63 ------------------- 7 files changed, 3 insertions(+), 83 deletions(-) delete mode 100644 src/python/grpcio_tests/tests/unit/_dns_resolver_test.py 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 6994f63bee4..7b5eb311393 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 @@ -43,7 +43,6 @@ #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/gethostname.h" -#include "src/core/lib/iomgr/iomgr_custom.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/json/json.h" @@ -431,11 +430,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) { - // TODO(lidiz): Remove the "g_custom_iomgr_enabled" flag once c-ares support - // custom IO managers (e.g. gevent). - return !g_custom_iomgr_enabled && - (resolver_env == nullptr || strlen(resolver_env) == 0 || - 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/src/core/lib/iomgr/iomgr_custom.cc b/src/core/lib/iomgr/iomgr_custom.cc index f5ac8a0670a..56363c35fd6 100644 --- a/src/core/lib/iomgr/iomgr_custom.cc +++ b/src/core/lib/iomgr/iomgr_custom.cc @@ -49,8 +49,6 @@ static bool iomgr_platform_add_closure_to_background_poller( return false; } -bool g_custom_iomgr_enabled = false; - static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, @@ -63,7 +61,6 @@ void grpc_custom_iomgr_init(grpc_socket_vtable* socket, grpc_custom_resolver_vtable* resolver, grpc_custom_timer_vtable* timer, grpc_custom_poller_vtable* poller) { - g_custom_iomgr_enabled = true; grpc_custom_endpoint_init(socket); grpc_custom_timer_init(timer); grpc_custom_pollset_init(poller); diff --git a/src/core/lib/iomgr/iomgr_custom.h b/src/core/lib/iomgr/iomgr_custom.h index e6a88843e5c..57cc2f9b923 100644 --- a/src/core/lib/iomgr/iomgr_custom.h +++ b/src/core/lib/iomgr/iomgr_custom.h @@ -39,8 +39,6 @@ extern gpr_thd_id g_init_thread; #define GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD() #endif /* GRPC_CUSTOM_IOMGR_THREAD_CHECK */ -extern bool g_custom_iomgr_enabled; - void grpc_custom_iomgr_init(grpc_socket_vtable* socket, grpc_custom_resolver_vtable* resolver, grpc_custom_timer_vtable* timer, diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index dc0795d4a12..e9b6333c891 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -154,9 +154,6 @@ class TestGevent(setuptools.Command): # TODO(https://github.com/grpc/grpc/issues/15411) enable this test 'unit._cython._channel_test.ChannelTest.test_negative_deadline_connectivity' ) - BANNED_WINDOWS_TESTS = ( - # TODO(https://github.com/grpc/grpc/pull/15411) enable this test - 'unit._dns_resolver_test.DNSResolverTest.test_connect_loopback',) description = 'run tests with gevent. Assumes grpc/gevent are installed' user_options = [] @@ -182,10 +179,7 @@ class TestGevent(setuptools.Command): loader = tests.Loader() loader.loadTestsFromNames(['tests']) runner = tests.Runner() - if sys.platform == 'win32': - runner.skip_tests(self.BANNED_TESTS + self.BANNED_WINDOWS_TESTS) - else: - runner.skip_tests(self.BANNED_TESTS) + runner.skip_tests(self.BANNED_TESTS) result = gevent.spawn(runner.run, loader.suite) result.join() if not result.value.wasSuccessful(): diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index cc08d56248a..7729ca01d53 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -46,7 +46,6 @@ "unit._cython.cygrpc_test.InsecureServerInsecureClient", "unit._cython.cygrpc_test.SecureServerSecureClient", "unit._cython.cygrpc_test.TypeSmokeTest", - "unit._dns_resolver_test.DNSResolverTest", "unit._empty_message_test.EmptyMessageTest", "unit._error_message_encoding_test.ErrorMessageEncodingTest", "unit._exit_test.ExitTest", diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel index a161794f8be..04f91e63a18 100644 --- a/src/python/grpcio_tests/tests/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel @@ -14,7 +14,6 @@ GRPCIO_TESTS_UNIT = [ "_channel_ready_future_test.py", "_compression_test.py", "_credentials_test.py", - "_dns_resolver_test.py", "_empty_message_test.py", "_exit_test.py", "_interceptor_test.py", diff --git a/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py b/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py deleted file mode 100644 index d119707b19d..00000000000 --- a/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py +++ /dev/null @@ -1,63 +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. -"""Tests for an actual dns resolution.""" - -import unittest -import logging -import six - -import grpc -from tests.unit import test_common -from tests.unit.framework.common import test_constants - -_METHOD = '/ANY/METHOD' -_REQUEST = b'\x00\x00\x00' -_RESPONSE = _REQUEST - - -class GenericHandler(grpc.GenericRpcHandler): - - def service(self, unused_handler_details): - return grpc.unary_unary_rpc_method_handler( - lambda request, unused_context: request, - ) - - -class DNSResolverTest(unittest.TestCase): - - def setUp(self): - self._server = test_common.test_server() - self._server.add_generic_rpc_handlers((GenericHandler(),)) - self._port = self._server.add_insecure_port('[::]:0') - self._server.start() - - def tearDown(self): - self._server.stop(None) - - def test_connect_loopback(self): - # NOTE(https://github.com/grpc/grpc/issues/18422) - # In short, Gevent + C-Ares = Segfault. The C-Ares driver is not - # supported by custom io manager like "gevent" or "libuv". - with grpc.insecure_channel( - 'loopback4.unittest.grpc.io:%d' % self._port) as channel: - self.assertEqual( - channel.unary_unary(_METHOD)( - _REQUEST, - timeout=test_constants.SHORT_TIMEOUT, - ), _RESPONSE) - - -if __name__ == '__main__': - logging.basicConfig() - unittest.main(verbosity=2) From 432c97e1ba0ae44bb1aceeecffaefec3e846c9c0 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 15 Apr 2019 13:14:19 -0700 Subject: [PATCH 1864/2143] Remove error from connectivity state tracking. --- .../filters/client_channel/client_channel.cc | 34 ++++------ .../client_channel/client_channel_channelz.cc | 3 +- .../ext/filters/client_channel/lb_policy.h | 1 - .../client_channel/lb_policy/grpclb/grpclb.cc | 24 ++----- .../lb_policy/pick_first/pick_first.cc | 67 +++++++++---------- .../lb_policy/round_robin/round_robin.cc | 48 ++++++------- .../lb_policy/subchannel_list.h | 12 ++-- .../client_channel/lb_policy/xds/xds.cc | 22 ++---- .../client_channel/resolving_lb_policy.cc | 24 ++----- .../ext/filters/client_channel/subchannel.cc | 40 ++++------- .../ext/filters/client_channel/subchannel.h | 5 +- .../chttp2/transport/chttp2_transport.cc | 18 ++--- .../ext/transport/inproc/inproc_transport.cc | 6 +- src/core/lib/transport/connectivity_state.cc | 42 ++---------- src/core/lib/transport/connectivity_state.h | 8 --- .../core/transport/connectivity_state_test.cc | 4 -- test/core/util/test_lb_policies.cc | 7 +- 17 files changed, 125 insertions(+), 240 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 86938a51d9b..35e284d7d97 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -227,13 +227,11 @@ namespace { class ConnectivityStateAndPickerSetter { public: ConnectivityStateAndPickerSetter( - channel_data* chand, grpc_connectivity_state state, - grpc_error* state_error, const char* reason, + channel_data* chand, grpc_connectivity_state state, 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); + grpc_connectivity_state_set(&chand->state_tracker, state, reason); if (chand->channelz_node != nullptr) { chand->channelz_node->AddTraceEvent( channelz::ChannelTrace::Severity::Info, @@ -456,7 +454,7 @@ class ClientChannelControlHelper } void UpdateState( - grpc_connectivity_state state, grpc_error* state_error, + grpc_connectivity_state state, UniquePtr picker) override { grpc_error* disconnect_error = chand_->disconnect_error.Load(grpc_core::MemoryOrder::ACQUIRE); @@ -464,17 +462,14 @@ class ClientChannelControlHelper 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", - chand_, grpc_connectivity_state_name(state), - grpc_error_string(state_error), picker.get(), extra); + gpr_log(GPR_INFO, "chand=%p: update: state=%s picker=%p%s", chand_, + grpc_connectivity_state_name(state), picker.get(), extra); } // Do update only if not shutting down. if (disconnect_error == GRPC_ERROR_NONE) { // Will delete itself. - New(chand_, state, state_error, - "helper", std::move(picker)); - } else { - GRPC_ERROR_UNREF(state_error); + New(chand_, state, "helper", + std::move(picker)); } } @@ -524,16 +519,12 @@ static bool process_resolver_result_locked( } 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; + if (grpc_connectivity_state_check(&chand->state_tracker) != + GRPC_CHANNEL_READY) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING("channel not connected"); } LoadBalancingPolicy::PickArgs pick; + grpc_error* error = GRPC_ERROR_NONE; chand->picker->Pick(&pick, &error); if (pick.connected_subchannel != nullptr) { pick.connected_subchannel->Ping(op->send_ping.on_initiate, @@ -587,8 +578,7 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { chand->resolving_lb_policy.reset(); // Will delete itself. grpc_core::New( - chand, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(op->disconnect_with_error), - "shutdown from API", + chand, GRPC_CHANNEL_SHUTDOWN, "shutdown from API", grpc_core::UniquePtr( grpc_core::New( GRPC_ERROR_REF(op->disconnect_with_error)))); 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..1ae3faa9e73 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -127,8 +127,7 @@ void SubchannelNode::PopulateConnectivityState(grpc_json* json) { if (subchannel_ == nullptr) { state = GRPC_CHANNEL_SHUTDOWN; } else { - state = subchannel_->CheckConnectivity(nullptr, - true /* inhibit_health_checking */); + state = subchannel_->CheckConnectivity(true /* inhibit_health_checking */); } json = grpc_json_create_child(nullptr, json, "state", nullptr, GRPC_JSON_OBJECT, false); diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 1c17f95423e..e369f591727 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -185,7 +185,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// 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) GRPC_ABSTRACT; /// Requests that the resolver re-resolve. 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 aebd2fd3faa..867a5c667fc 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 @@ -282,7 +282,7 @@ class GrpcLb : public LoadBalancingPolicy { Subchannel* CreateSubchannel(const grpc_channel_args& args) override; grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override; - void UpdateState(grpc_connectivity_state state, grpc_error* state_error, + void UpdateState(grpc_connectivity_state state, UniquePtr picker) override; void RequestReresolution() override; @@ -622,12 +622,8 @@ grpc_channel* GrpcLb::Helper::CreateChannel(const char* target, } void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, - grpc_error* state_error, UniquePtr picker) { - if (parent_->shutting_down_) { - GRPC_ERROR_UNREF(state_error); - return; - } + if (parent_->shutting_down_) 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()) { @@ -637,10 +633,7 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, parent_.get(), this, parent_->pending_child_policy_.get(), grpc_connectivity_state_name(state)); } - if (state != GRPC_CHANNEL_READY) { - GRPC_ERROR_UNREF(state_error); - return; - } + if (state != GRPC_CHANNEL_READY) return; grpc_pollset_set_del_pollset_set( parent_->child_policy_->interested_parties(), parent_->interested_parties()); @@ -648,7 +641,6 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, 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; } // Record whether child policy reports READY. @@ -683,8 +675,7 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, parent_.get(), this, grpc_connectivity_state_name(state), picker.get()); } - parent_->channel_control_helper()->UpdateState(state, state_error, - std::move(picker)); + parent_->channel_control_helper()->UpdateState(state, std::move(picker)); return; } // Cases 2 and 3a: wrap picker from the child in our own picker. @@ -699,10 +690,9 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, 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)))); + state, UniquePtr( + New(parent_.get(), parent_->serverlist_, + std::move(picker), std::move(client_stats)))); } void GrpcLb::Helper::RequestReresolution() { 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 332f66808e0..35ca68f717b 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 @@ -73,7 +73,7 @@ class PickFirst : public LoadBalancingPolicy { : SubchannelData(subchannel_list, address, subchannel, combiner) {} void ProcessConnectivityChangeLocked( - grpc_connectivity_state connectivity_state, grpc_error* error) override; + grpc_connectivity_state connectivity_state) override; // Processes the connectivity change to READY for an unselected subchannel. void ProcessUnselectedReadyLocked(); @@ -191,10 +191,11 @@ void PickFirst::ExitIdleLocked() { idle_ = false; if (subchannel_list_ == nullptr || subchannel_list_->num_subchannels() == 0) { - grpc_error* error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to"); + grpc_error* error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + GRPC_CHANNEL_TRANSIENT_FAILURE, UniquePtr(New(error))); } else { subchannel_list_->subchannel(0) @@ -268,9 +269,11 @@ void PickFirst::UpdateLocked(UpdateArgs args) { // haven't gotten a non-empty update by the time the application tries // to start a new call.) if (!idle_) { - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"); + grpc_error* error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + GRPC_CHANNEL_TRANSIENT_FAILURE, UniquePtr(New(error))); } return; @@ -284,9 +287,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) { // 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; - grpc_connectivity_state state = sd->CheckConnectivityStateLocked(&error); - GRPC_ERROR_UNREF(error); + grpc_connectivity_state state = sd->CheckConnectivityStateLocked(); if (state == GRPC_CHANNEL_READY) { subchannel_list_ = std::move(subchannel_list); sd->StartConnectivityWatchLocked(); @@ -340,7 +341,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) { } void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( - grpc_connectivity_state connectivity_state, grpc_error* error) { + grpc_connectivity_state connectivity_state) { PickFirst* p = static_cast(subchannel_list()->policy()); AutoChildRefsUpdater guard(p); // The notification must be for a subchannel in either the current or @@ -371,17 +372,16 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); // 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); + grpc_error* error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "selected subchannel failed; switching to pending update"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error), - UniquePtr( - New(new_error))); + GRPC_CHANNEL_TRANSIENT_FAILURE, + UniquePtr(New(error))); } else { p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + GRPC_CHANNEL_CONNECTING, UniquePtr(New(p->Ref()))); } } else { @@ -395,7 +395,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( p->selected_ = nullptr; StopConnectivityWatchLocked(); p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, + GRPC_CHANNEL_IDLE, UniquePtr(New(p->Ref()))); } else { // This is unlikely but can happen when a subchannel has been asked @@ -403,19 +403,17 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // 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()))); + GRPC_CHANNEL_READY, UniquePtr(New( + connected_subchannel()->Ref()))); } else { // CONNECTING p->channel_control_helper()->UpdateState( - connectivity_state, GRPC_ERROR_REF(error), + connectivity_state, UniquePtr(New(p->Ref()))); } // Renew notification. RenewConnectivityWatchLocked(); } } - GRPC_ERROR_UNREF(error); return; } // If we get here, there are two possible cases: @@ -452,13 +450,13 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( 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); + grpc_error* error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "failed to connect to all addresses"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error), - UniquePtr( - New(new_error))); + GRPC_CHANNEL_TRANSIENT_FAILURE, + UniquePtr(New(error))); } } sd->CheckConnectivityStateAndStartWatchingLocked(); @@ -469,7 +467,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // 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, + GRPC_CHANNEL_CONNECTING, UniquePtr(New(p->Ref()))); } // Renew notification. @@ -479,7 +477,6 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( case GRPC_CHANNEL_SHUTDOWN: GPR_UNREACHABLE_CODE(break); } - GRPC_ERROR_UNREF(error); } void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { @@ -509,7 +506,7 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { // Cases 1 and 2. p->selected_ = this; p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_READY, GRPC_ERROR_NONE, + GRPC_CHANNEL_READY, UniquePtr(New(connected_subchannel()->Ref()))); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); @@ -520,9 +517,7 @@ void PickFirst::PickFirstSubchannelData:: CheckConnectivityStateAndStartWatchingLocked() { PickFirst* p = static_cast(subchannel_list()->policy()); // Check current state. - grpc_error* error = GRPC_ERROR_NONE; - grpc_connectivity_state current_state = CheckConnectivityStateLocked(&error); - GRPC_ERROR_UNREF(error); + grpc_connectivity_state current_state = CheckConnectivityStateLocked(); // Start watch. StartConnectivityWatchLocked(); // If current state is READY, select the subchannel now, since we started 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 d3faaaddc98..74ad1893c6a 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 @@ -92,11 +92,11 @@ class RoundRobin : public LoadBalancingPolicy { } void UpdateConnectivityStateLocked( - grpc_connectivity_state connectivity_state, grpc_error* error); + grpc_connectivity_state connectivity_state); private: void ProcessConnectivityChangeLocked( - grpc_connectivity_state connectivity_state, grpc_error* error) override; + grpc_connectivity_state connectivity_state) override; grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE; }; @@ -119,7 +119,6 @@ class RoundRobin : public LoadBalancingPolicy { } ~RoundRobinSubchannelList() { - GRPC_ERROR_UNREF(last_transient_failure_error_); RoundRobin* p = static_cast(policy()); p->Unref(DEBUG_LOCATION, "subchannel_list"); } @@ -129,11 +128,8 @@ class RoundRobin : public LoadBalancingPolicy { // Updates the counters of subchannels in each state when a // subchannel transitions from old_state to new_state. - // transient_failure_error is the error that is reported when - // new_state is TRANSIENT_FAILURE. void UpdateStateCountersLocked(grpc_connectivity_state old_state, - grpc_connectivity_state new_state, - grpc_error* transient_failure_error); + grpc_connectivity_state new_state); // If this subchannel list is the RR policy's current subchannel // list, updates the RR policy's connectivity state based on the @@ -148,7 +144,6 @@ class RoundRobin : public LoadBalancingPolicy { 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 { @@ -317,11 +312,10 @@ void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() { // subchannel already used by some other channel may have a non-IDLE // state. for (size_t i = 0; i < num_subchannels(); ++i) { - grpc_error* error = GRPC_ERROR_NONE; grpc_connectivity_state state = - subchannel(i)->CheckConnectivityStateLocked(&error); + subchannel(i)->CheckConnectivityStateLocked(); if (state != GRPC_CHANNEL_IDLE) { - subchannel(i)->UpdateConnectivityStateLocked(state, error); + subchannel(i)->UpdateConnectivityStateLocked(state); } } // Start connectivity watch for each subchannel. @@ -335,8 +329,7 @@ void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() { } void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked( - grpc_connectivity_state old_state, grpc_connectivity_state new_state, - grpc_error* transient_failure_error) { + grpc_connectivity_state old_state, grpc_connectivity_state new_state) { GPR_ASSERT(old_state != GRPC_CHANNEL_SHUTDOWN); GPR_ASSERT(new_state != GRPC_CHANNEL_SHUTDOWN); if (old_state == GRPC_CHANNEL_READY) { @@ -356,8 +349,6 @@ void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked( } else if (new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { ++num_transient_failure_; } - GRPC_ERROR_UNREF(last_transient_failure_error_); - last_transient_failure_error_ = transient_failure_error; } // Sets the RR policy's connectivity state and generates a new picker based @@ -384,20 +375,21 @@ 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_CHANNEL_READY, UniquePtr(New(p, this))); } else if (num_connecting_ > 0) { /* 2) CONNECTING */ p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + GRPC_CHANNEL_CONNECTING, UniquePtr(New(p->Ref()))); } else if (num_transient_failure_ == num_subchannels()) { /* 3) TRANSIENT_FAILURE */ + grpc_error* error = + grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "connections to all backends failing"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); 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_)))); + UniquePtr(New(error))); } } @@ -432,7 +424,7 @@ void RoundRobin::RoundRobinSubchannelList:: } void RoundRobin::RoundRobinSubchannelData::UpdateConnectivityStateLocked( - grpc_connectivity_state connectivity_state, grpc_error* error) { + grpc_connectivity_state connectivity_state) { RoundRobin* p = static_cast(subchannel_list()->policy()); if (grpc_lb_round_robin_trace.enabled()) { gpr_log( @@ -445,12 +437,12 @@ void RoundRobin::RoundRobinSubchannelData::UpdateConnectivityStateLocked( grpc_connectivity_state_name(connectivity_state)); } subchannel_list()->UpdateStateCountersLocked(last_connectivity_state_, - connectivity_state, error); + connectivity_state); last_connectivity_state_ = connectivity_state; } void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( - grpc_connectivity_state connectivity_state, grpc_error* error) { + grpc_connectivity_state connectivity_state) { RoundRobin* p = static_cast(subchannel_list()->policy()); GPR_ASSERT(subchannel() != nullptr); // If the new state is TRANSIENT_FAILURE, re-resolve. @@ -470,7 +462,7 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( // Renew connectivity watch. RenewConnectivityWatchLocked(); // Update state counters. - UpdateConnectivityStateLocked(connectivity_state, error); + UpdateConnectivityStateLocked(connectivity_state); // Update overall state and renew notification. subchannel_list()->UpdateRoundRobinStateFromSubchannelStateCountsLocked(); } @@ -494,9 +486,11 @@ void RoundRobin::UpdateLocked(UpdateArgs 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. - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"); + grpc_error* error = + grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + GRPC_CHANNEL_TRANSIENT_FAILURE, UniquePtr(New(error))); subchannel_list_ = std::move(latest_pending_subchannel_list_); } else if (subchannel_list_ == nullptr) { 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 4fde90c2584..004ee04459b 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 @@ -51,7 +51,7 @@ class MySubchannelData : public SubchannelData { public: void ProcessConnectivityChangeLocked( - grpc_connectivity_state connectivity_state, grpc_error* error) override { + grpc_connectivity_state connectivity_state) override { // ...code to handle connectivity changes... } }; @@ -101,10 +101,10 @@ class SubchannelData { // pending (i.e., between calling StartConnectivityWatchLocked() or // RenewConnectivityWatchLocked() and the resulting invocation of // ProcessConnectivityChangeLocked()). - grpc_connectivity_state CheckConnectivityStateLocked(grpc_error** error) { + grpc_connectivity_state CheckConnectivityStateLocked() { GPR_ASSERT(!connectivity_notification_pending_); pending_connectivity_state_unsafe_ = subchannel()->CheckConnectivity( - error, subchannel_list_->inhibit_health_checking()); + subchannel_list_->inhibit_health_checking()); UpdateConnectedSubchannelLocked(); return pending_connectivity_state_unsafe_; } @@ -153,8 +153,7 @@ class SubchannelData { // Implementations must invoke either RenewConnectivityWatchLocked() or // StopConnectivityWatchLocked() before returning. virtual void ProcessConnectivityChangeLocked( - grpc_connectivity_state connectivity_state, - grpc_error* error) GRPC_ABSTRACT; + grpc_connectivity_state connectivity_state) GRPC_ABSTRACT; // Unrefs the subchannel. void UnrefSubchannelLocked(const char* reason); @@ -462,8 +461,7 @@ void SubchannelData:: return; } // Call the subclass's ProcessConnectivityChangeLocked() method. - sd->ProcessConnectivityChangeLocked(sd->pending_connectivity_state_unsafe_, - GRPC_ERROR_REF(error)); + sd->ProcessConnectivityChangeLocked(sd->pending_connectivity_state_unsafe_); } template 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 fe49e9aca03..225bae7aa1c 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 @@ -301,7 +301,7 @@ class XdsLb : public LoadBalancingPolicy { Subchannel* CreateSubchannel(const grpc_channel_args& args) override; grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override; - void UpdateState(grpc_connectivity_state state, grpc_error* state_error, + void UpdateState(grpc_connectivity_state state, UniquePtr picker) override; void RequestReresolution() override; void set_child(LoadBalancingPolicy* child) { child_ = child; } @@ -1565,6 +1565,7 @@ void XdsLb::LocalityMap::LocalityEntry::Orphan() { // // LocalityEntry::Helper implementation // + bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByPendingChild() const { GPR_ASSERT(child_ != nullptr); return child_ == entry_->pending_child_policy_.get(); @@ -1594,12 +1595,8 @@ grpc_channel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateChannel( } void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState( - grpc_connectivity_state state, grpc_error* state_error, - UniquePtr picker) { - if (entry_->parent_->shutting_down_) { - GRPC_ERROR_UNREF(state_error); - return; - } + grpc_connectivity_state state, UniquePtr picker) { + if (entry_->parent_->shutting_down_) 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()) { @@ -1609,10 +1606,7 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState( entry_->parent_.get(), this, entry_->pending_child_policy_.get(), grpc_connectivity_state_name(state)); } - if (state != GRPC_CHANNEL_READY) { - GRPC_ERROR_UNREF(state_error); - return; - } + if (state != GRPC_CHANNEL_READY) return; grpc_pollset_set_del_pollset_set( entry_->child_policy_->interested_parties(), entry_->parent_->interested_parties()); @@ -1620,7 +1614,6 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState( entry_->child_policy_ = std::move(entry_->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 @@ -1632,9 +1625,8 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState( ? nullptr : entry_->parent_->lb_chand_->lb_calld()->client_stats(); entry_->parent_->channel_control_helper()->UpdateState( - state, state_error, - UniquePtr( - New(std::move(picker), std::move(client_stats)))); + state, UniquePtr( + New(std::move(picker), std::move(client_stats)))); } void XdsLb::LocalityMap::LocalityEntry::Helper::RequestReresolution() { 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 d15af908b3f..8f53c33b7fd 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -119,13 +119,9 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper return parent_->channel_control_helper()->CreateChannel(target, args); } - void UpdateState(grpc_connectivity_state state, grpc_error* state_error, + void UpdateState(grpc_connectivity_state state, UniquePtr picker) override { - if (parent_->resolver_ == nullptr) { - // shutting down. - GRPC_ERROR_UNREF(state_error); - return; - } + if (parent_->resolver_ == nullptr) return; // Shutting down. // 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()) { @@ -136,10 +132,7 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper parent_.get(), this, child_, grpc_connectivity_state_name(state)); } - if (state != GRPC_CHANNEL_READY) { - GRPC_ERROR_UNREF(state_error); - return; - } + if (state != GRPC_CHANNEL_READY) return; grpc_pollset_set_del_pollset_set( parent_->lb_policy_->interested_parties(), parent_->interested_parties()); @@ -147,11 +140,9 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper 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)); + parent_->channel_control_helper()->UpdateState(state, std::move(picker)); } void RequestReresolution() override { @@ -234,8 +225,7 @@ grpc_error* ResolvingLoadBalancingPolicy::Init(const grpc_channel_args& args) { } // Return our picker to the channel. channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, - UniquePtr(New(Ref()))); + GRPC_CHANNEL_IDLE, UniquePtr(New(Ref()))); return GRPC_ERROR_NONE; } @@ -313,7 +303,7 @@ void ResolvingLoadBalancingPolicy::StartResolvingLocked() { GPR_ASSERT(!started_resolving_); started_resolving_ = true; channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + GRPC_CHANNEL_CONNECTING, UniquePtr(New(Ref()))); resolver_->StartLocked(); } @@ -334,7 +324,7 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { grpc_error* state_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Resolver transient failure", &error, 1); channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(state_error), + GRPC_CHANNEL_TRANSIENT_FAILURE, UniquePtr(New(state_error))); } GRPC_ERROR_UNREF(error); diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 8bb0c4c3498..088c9022990 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -332,10 +332,9 @@ class Subchannel::ConnectedSubchannelStateWatcher health_state = GRPC_CHANNEL_CONNECTING; } // Report initial state. - c->SetConnectivityStateLocked(GRPC_CHANNEL_READY, GRPC_ERROR_NONE, - "subchannel_connected"); + c->SetConnectivityStateLocked(GRPC_CHANNEL_READY, "subchannel_connected"); grpc_connectivity_state_set(&c->state_and_health_tracker_, health_state, - GRPC_ERROR_NONE, "subchannel_connected"); + "subchannel_connected"); } ~ConnectedSubchannelStateWatcher() { @@ -367,11 +366,10 @@ class Subchannel::ConnectedSubchannelStateWatcher 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_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(error), "reflect_child"); + "reflect_child"); c->backoff_begun_ = false; c->backoff_.Reset(); c->MaybeStartConnectingLocked(); @@ -388,11 +386,11 @@ class Subchannel::ConnectedSubchannelStateWatcher // 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"); + "reflect_child"); if (self->pending_connectivity_state_ != GRPC_CHANNEL_READY) { grpc_connectivity_state_set(&c->state_and_health_tracker_, self->pending_connectivity_state_, - GRPC_ERROR_REF(error), "reflect_child"); + "reflect_child"); } c->connected_subchannel_->NotifyOnStateChange( nullptr, &self->pending_connectivity_state_, @@ -415,8 +413,7 @@ class Subchannel::ConnectedSubchannelStateWatcher 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_, - GRPC_ERROR_REF(error), "health_changed"); + self->health_state_, "health_changed"); } self->health_check_client_->NotifyOnHealthChange( &self->health_state_, &self->on_health_changed_); @@ -740,11 +737,10 @@ channelz::SubchannelNode* Subchannel::channelz_node() { } grpc_connectivity_state Subchannel::CheckConnectivity( - grpc_error** error, bool inhibit_health_checking) { - MutexLock lock(&mu_); + bool inhibit_health_checking) { grpc_connectivity_state_tracker* tracker = inhibit_health_checking ? &state_tracker_ : &state_and_health_tracker_; - grpc_connectivity_state state = grpc_connectivity_state_get(tracker, error); + grpc_connectivity_state state = grpc_connectivity_state_check(tracker); return state; } @@ -852,7 +848,6 @@ const char* SubchannelConnectivityStateChangeString( } // namespace void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state, - grpc_error* error, const char* reason) { if (channelz_node_ != nullptr) { channelz_node_->AddTraceEvent( @@ -860,7 +855,7 @@ void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state, grpc_slice_from_static_string( SubchannelConnectivityStateChangeString(state))); } - grpc_connectivity_state_set(&state_tracker_, state, error, reason); + grpc_connectivity_state_set(&state_tracker_, state, reason); } void Subchannel::MaybeStartConnectingLocked() { @@ -935,11 +930,9 @@ void Subchannel::ContinueConnectingLocked() { 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"); + SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING, "connecting"); grpc_connectivity_state_set(&state_and_health_tracker_, - GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, - "connecting"); + GRPC_CHANNEL_CONNECTING, "connecting"); grpc_connector_connect(connector_, &args, &connecting_result_, &on_connecting_finished_); } @@ -956,16 +949,11 @@ 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 = - grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Connect Failed", &error, 1), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + gpr_log(GPR_INFO, "Connect failed: %s", grpc_error_string(error)); c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(error), "connect_failed"); + "connect_failed"); grpc_connectivity_state_set(&c->state_and_health_tracker_, - GRPC_CHANNEL_TRANSIENT_FAILURE, error, + GRPC_CHANNEL_TRANSIENT_FAILURE, "connect_failed"); c->MaybeStartConnectingLocked(); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 968fc74e22a..54bd13b6065 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -207,8 +207,7 @@ class Subchannel { channelz::SubchannelNode* channelz_node(); // Polls the current connectivity state of the subchannel. - grpc_connectivity_state CheckConnectivity(grpc_error** error, - bool inhibit_health_checking); + grpc_connectivity_state CheckConnectivity(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. @@ -241,7 +240,7 @@ class Subchannel { // Sets the subchannel's connectivity state to \a state. void SetConnectivityStateLocked(grpc_connectivity_state state, - grpc_error* error, const char* reason); + const char* reason); // Methods for connection. void MaybeStartConnectingLocked(); diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index fe92835f690..07659bb09bb 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -119,7 +119,7 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t); static void connectivity_state_set(grpc_chttp2_transport* t, grpc_connectivity_state state, - grpc_error* error, const char* reason); + const char* reason); static void benign_reclaimer_locked(void* t, grpc_error* error); static void destructive_reclaimer_locked(void* t, grpc_error* error); @@ -592,8 +592,7 @@ static void close_transport_locked(grpc_chttp2_transport* t, } GPR_ASSERT(error != GRPC_ERROR_NONE); t->closed_with_error = GRPC_ERROR_REF(error); - connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), - "close_transport"); + connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, "close_transport"); if (t->ping_state.is_delayed_ping_timer_set) { grpc_timer_cancel(&t->ping_state.delayed_ping_timer); } @@ -1171,8 +1170,7 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, /* lie: use transient failure from the transport to indicate goaway has been * received */ - connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(t->goaway_error), "got_goaway"); + connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE, "got_goaway"); } static void maybe_start_some_streams(grpc_chttp2_transport* t) { @@ -1194,10 +1192,8 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t) { t->next_stream_id += 2; if (t->next_stream_id >= MAX_CLIENT_STREAM_ID) { - connectivity_state_set( - t, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Stream IDs exhausted"), - "no_more_stream_ids"); + connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE, + "no_more_stream_ids"); } grpc_chttp2_stream_map_add(&t->stream_map, s->id, s); @@ -2804,9 +2800,9 @@ static void keepalive_watchdog_fired_locked(void* arg, grpc_error* error) { static void connectivity_state_set(grpc_chttp2_transport* t, grpc_connectivity_state state, - grpc_error* error, const char* reason) { + const char* reason) { GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "set connectivity_state=%d", state)); - grpc_connectivity_state_set(&t->channel_callback.state_tracker, state, error, + grpc_connectivity_state_set(&t->channel_callback.state_tracker, state, reason); } diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index d46c24a1de0..7ded133bebf 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -1088,10 +1088,8 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs, void close_transport_locked(inproc_transport* t) { INPROC_LOG(GPR_INFO, "close_transport %p %d", t, t->is_closed); - grpc_connectivity_state_set( - &t->connectivity, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Closing transport."), - "close transport"); + grpc_connectivity_state_set(&t->connectivity, GRPC_CHANNEL_SHUTDOWN, + "close transport"); if (!t->is_closed) { t->is_closed = true; /* Also end all streams on this transport */ diff --git a/src/core/lib/transport/connectivity_state.cc b/src/core/lib/transport/connectivity_state.cc index db6b6c04440..5b73085c7f3 100644 --- a/src/core/lib/transport/connectivity_state.cc +++ b/src/core/lib/transport/connectivity_state.cc @@ -48,7 +48,6 @@ void grpc_connectivity_state_init(grpc_connectivity_state_tracker* tracker, grpc_connectivity_state init_state, const char* name) { gpr_atm_no_barrier_store(&tracker->current_state_atm, init_state); - tracker->current_error = GRPC_ERROR_NONE; tracker->watchers = nullptr; tracker->name = gpr_strdup(name); } @@ -69,7 +68,6 @@ void grpc_connectivity_state_destroy(grpc_connectivity_state_tracker* tracker) { GRPC_CLOSURE_SCHED(w->notify, error); gpr_free(w); } - GRPC_ERROR_UNREF(tracker->current_error); gpr_free(tracker->name); } @@ -84,20 +82,6 @@ grpc_connectivity_state grpc_connectivity_state_check( return cur; } -grpc_connectivity_state grpc_connectivity_state_get( - grpc_connectivity_state_tracker* tracker, grpc_error** error) { - grpc_connectivity_state cur = static_cast( - gpr_atm_no_barrier_load(&tracker->current_state_atm)); - if (grpc_connectivity_state_trace.enabled()) { - gpr_log(GPR_INFO, "CONWATCH: %p %s: get %s", tracker, tracker->name, - grpc_connectivity_state_name(cur)); - } - if (error != nullptr) { - *error = GRPC_ERROR_REF(tracker->current_error); - } - return cur; -} - bool grpc_connectivity_state_has_watchers( grpc_connectivity_state_tracker* connectivity_state) { return connectivity_state->watchers != nullptr; @@ -140,7 +124,7 @@ bool grpc_connectivity_state_notify_on_state_change( } else { if (cur != *current) { *current = cur; - GRPC_CLOSURE_SCHED(notify, GRPC_ERROR_REF(tracker->current_error)); + GRPC_CLOSURE_SCHED(notify, GRPC_ERROR_NONE); } else { grpc_connectivity_state_watcher* w = static_cast(gpr_malloc(sizeof(*w))); @@ -155,29 +139,15 @@ bool grpc_connectivity_state_notify_on_state_change( void grpc_connectivity_state_set(grpc_connectivity_state_tracker* tracker, grpc_connectivity_state state, - grpc_error* error, const char* reason) { + const char* reason) { grpc_connectivity_state cur = static_cast( gpr_atm_no_barrier_load(&tracker->current_state_atm)); grpc_connectivity_state_watcher* w; if (grpc_connectivity_state_trace.enabled()) { - const char* error_string = grpc_error_string(error); - gpr_log(GPR_INFO, "SET: %p %s: %s --> %s [%s] error=%p %s", tracker, - tracker->name, grpc_connectivity_state_name(cur), - grpc_connectivity_state_name(state), reason, error, error_string); + gpr_log(GPR_INFO, "SET: %p %s: %s --> %s [%s]", tracker, tracker->name, + grpc_connectivity_state_name(cur), + grpc_connectivity_state_name(state), reason); } - switch (state) { - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_IDLE: - case GRPC_CHANNEL_READY: - GPR_ASSERT(error == GRPC_ERROR_NONE); - break; - case GRPC_CHANNEL_SHUTDOWN: - case GRPC_CHANNEL_TRANSIENT_FAILURE: - GPR_ASSERT(error != GRPC_ERROR_NONE); - break; - } - GRPC_ERROR_UNREF(tracker->current_error); - tracker->current_error = error; if (cur == state) { return; } @@ -189,7 +159,7 @@ void grpc_connectivity_state_set(grpc_connectivity_state_tracker* tracker, if (grpc_connectivity_state_trace.enabled()) { gpr_log(GPR_INFO, "NOTIFY: %p %s: %p", tracker, tracker->name, w->notify); } - GRPC_CLOSURE_SCHED(w->notify, GRPC_ERROR_REF(tracker->current_error)); + GRPC_CLOSURE_SCHED(w->notify, GRPC_ERROR_NONE); gpr_free(w); } } diff --git a/src/core/lib/transport/connectivity_state.h b/src/core/lib/transport/connectivity_state.h index ecb083cfc2f..0ff1432cb9d 100644 --- a/src/core/lib/transport/connectivity_state.h +++ b/src/core/lib/transport/connectivity_state.h @@ -37,8 +37,6 @@ typedef struct grpc_connectivity_state_watcher { typedef struct { /** current grpc_connectivity_state */ gpr_atm current_state_atm; - /** error associated with state */ - grpc_error* current_error; /** all our watchers */ grpc_connectivity_state_watcher* watchers; /** a name to help debugging */ @@ -59,7 +57,6 @@ void grpc_connectivity_state_destroy(grpc_connectivity_state_tracker* tracker); * external lock */ void grpc_connectivity_state_set(grpc_connectivity_state_tracker* tracker, grpc_connectivity_state state, - grpc_error* associated_error, const char* reason); /** Return true if this connectivity state has watchers. @@ -71,11 +68,6 @@ bool grpc_connectivity_state_has_watchers( grpc_connectivity_state grpc_connectivity_state_check( grpc_connectivity_state_tracker* tracker); -/** Return the last seen connectivity state, and the associated error. - Access must be serialized with an external lock. */ -grpc_connectivity_state grpc_connectivity_state_get( - grpc_connectivity_state_tracker* tracker, grpc_error** error); - /** Return 1 if the channel should start connecting, 0 otherwise. If current==NULL cancel notify if it is already queued (success==0 in that case). diff --git a/test/core/transport/connectivity_state_test.cc b/test/core/transport/connectivity_state_test.cc index 7c7e3084bf5..26c09a76039 100644 --- a/test/core/transport/connectivity_state_test.cc +++ b/test/core/transport/connectivity_state_test.cc @@ -60,13 +60,9 @@ static void test_connectivity_state_name(void) { static void test_check(void) { grpc_connectivity_state_tracker tracker; grpc_core::ExecCtx exec_ctx; - grpc_error* error; gpr_log(GPR_DEBUG, "test_check"); grpc_connectivity_state_init(&tracker, GRPC_CHANNEL_IDLE, "xxx"); - GPR_ASSERT(grpc_connectivity_state_get(&tracker, &error) == - GRPC_CHANNEL_IDLE); GPR_ASSERT(grpc_connectivity_state_check(&tracker) == GRPC_CHANNEL_IDLE); - GPR_ASSERT(error == GRPC_ERROR_NONE); grpc_connectivity_state_destroy(&tracker); } diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 05e25eb08bc..b871f04bc9e 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -150,12 +150,11 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy return parent_->channel_control_helper()->CreateChannel(target, args); } - void UpdateState(grpc_connectivity_state state, grpc_error* state_error, + void UpdateState(grpc_connectivity_state state, UniquePtr picker) override { parent_->channel_control_helper()->UpdateState( - state, state_error, - UniquePtr( - New(std::move(picker), cb_, user_data_))); + state, UniquePtr( + New(std::move(picker), cb_, user_data_))); } void RequestReresolution() override { From 38220243b04e0366ffe47cfaf0d1fa44d2e22937 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 15 Apr 2019 14:18:09 -0700 Subject: [PATCH 1865/2143] Convert client_channel channel_data to C++. --- .../filters/client_channel/client_channel.cc | 1068 +++++++++-------- .../client_channel/client_channel_channelz.cc | 2 +- 2 files changed, 580 insertions(+), 490 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index b51a1587166..0304a265a09 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -73,7 +73,9 @@ using grpc_core::internal::ServerRetryThrottleData; using grpc_core::LoadBalancingPolicy; -/* Client channel implementation */ +// +// Client channel filter +// // By default, we buffer 256 KiB per RPC for retries. // TODO(roth): Do we have any data to suggest a better value? @@ -88,231 +90,313 @@ grpc_core::TraceFlag grpc_client_channel_call_trace(false, grpc_core::TraceFlag grpc_client_channel_routing_trace( false, "client_channel_routing"); -/************************************************************************* - * CHANNEL-WIDE FUNCTIONS - */ - -// Forward declaration. -typedef struct client_channel_channel_data channel_data; +// Forward declarations. +static void start_pick_locked(void* arg, grpc_error* error); +static void maybe_apply_service_config_to_call_locked(grpc_call_element* elem); namespace grpc_core { namespace { -class ExternalConnectivityWatcher { +// +// ChannelData definition +// + +class ChannelData { public: - class WatcherList { - public: - WatcherList() { gpr_mu_init(&mu_); } - ~WatcherList() { gpr_mu_destroy(&mu_); } - - int size() const; - ExternalConnectivityWatcher* Lookup(grpc_closure* on_complete) const; - void Add(ExternalConnectivityWatcher* watcher); - void Remove(const ExternalConnectivityWatcher* watcher); - - private: - // head_ is guarded by a mutex, since the size() method needs to - // iterate over the list, and it's called from the C-core API - // function grpc_channel_num_external_connectivity_watchers(), which - // is synchronous and therefore cannot run in the combiner. - mutable gpr_mu mu_; - ExternalConnectivityWatcher* head_ = nullptr; + struct QueuedPick { + LoadBalancingPolicy::PickArgs pick; + grpc_call_element* elem; + QueuedPick* next = nullptr; }; - ExternalConnectivityWatcher(channel_data* chand, grpc_polling_entity pollent, - grpc_connectivity_state* state, - grpc_closure* on_complete, - grpc_closure* watcher_timer_init); + static grpc_error* Init(grpc_channel_element* elem, + grpc_channel_element_args* args); + static void Destroy(grpc_channel_element* elem); + static void StartTransportOp(grpc_channel_element* elem, + grpc_transport_op* op); + static void GetChannelInfo(grpc_channel_element* elem, + const grpc_channel_info* info); - ~ExternalConnectivityWatcher(); + void set_channelz_node(channelz::ClientChannelNode* node) { + channelz_node_ = node; + resolving_lb_policy_->set_channelz_node(node->Ref()); + } + void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) { + if (resolving_lb_policy_ != nullptr) { + resolving_lb_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } + } + + bool deadline_checking_enabled() const { return deadline_checking_enabled_; } + bool enable_retries() const { return enable_retries_; } + size_t per_rpc_retry_buffer_size() const { + return per_rpc_retry_buffer_size_; + } + + // Note: Does NOT return a new ref. + grpc_error* disconnect_error() const { + return disconnect_error_.Load(MemoryOrder::ACQUIRE); + } + + grpc_combiner* data_plane_combiner() const { return data_plane_combiner_; } + + LoadBalancingPolicy::SubchannelPicker* picker() const { + return picker_.get(); + } + void AddQueuedPick(QueuedPick* pick, grpc_polling_entity* pollent); + void RemoveQueuedPick(QueuedPick* pick, grpc_polling_entity* pollent); + + bool received_service_config_data() const { + return received_service_config_data_; + } + RefCountedPtr retry_throttle_data() const { + return retry_throttle_data_; + } + RefCountedPtr GetMethodParams( + const grpc_slice& path) { + if (method_params_table_ == nullptr) return nullptr; + return ServiceConfig::MethodConfigTableLookup(*method_params_table_, path); + } + + grpc_connectivity_state CheckConnectivityState(bool try_to_connect); + void AddExternalConnectivityWatcher(grpc_polling_entity pollent, + grpc_connectivity_state* state, + grpc_closure* on_complete, + grpc_closure* watcher_timer_init) { + // Will delete itself. + New(this, pollent, state, on_complete, + watcher_timer_init); + } + int NumExternalConnectivityWatchers() const { + return external_connectivity_watcher_list_.size(); + } private: - static void OnWatchCompleteLocked(void* arg, grpc_error* error); - static void WatchConnectivityStateLocked(void* arg, grpc_error* ignored); + class ConnectivityStateAndPickerSetter; + class ServiceConfigSetter; + class ClientChannelControlHelper; - channel_data* chand_; - grpc_polling_entity pollent_; - grpc_connectivity_state* state_; - grpc_closure* on_complete_; - grpc_closure* watcher_timer_init_; - grpc_closure my_closure_; - ExternalConnectivityWatcher* next_ = nullptr; -}; + class ExternalConnectivityWatcher { + public: + class WatcherList { + public: + WatcherList() { gpr_mu_init(&mu_); } + ~WatcherList() { gpr_mu_destroy(&mu_); } -} // namespace -} // namespace grpc_core + int size() const; + ExternalConnectivityWatcher* Lookup(grpc_closure* on_complete) const; + void Add(ExternalConnectivityWatcher* watcher); + void Remove(const ExternalConnectivityWatcher* watcher); -struct QueuedPick { - LoadBalancingPolicy::PickArgs pick; - grpc_call_element* elem; - QueuedPick* next = nullptr; -}; + private: + // head_ is guarded by a mutex, since the size() method needs to + // iterate over the list, and it's called from the C-core API + // function grpc_channel_num_external_connectivity_watchers(), which + // is synchronous and therefore cannot run in the combiner. + mutable gpr_mu mu_; + ExternalConnectivityWatcher* head_ = nullptr; + }; + + ExternalConnectivityWatcher(ChannelData* chand, grpc_polling_entity pollent, + grpc_connectivity_state* state, + grpc_closure* on_complete, + grpc_closure* watcher_timer_init); + + ~ExternalConnectivityWatcher(); + + private: + static void OnWatchCompleteLocked(void* arg, grpc_error* error); + static void WatchConnectivityStateLocked(void* arg, grpc_error* ignored); + + ChannelData* chand_; + grpc_polling_entity pollent_; + grpc_connectivity_state* state_; + grpc_closure* on_complete_; + grpc_closure* watcher_timer_init_; + grpc_closure my_closure_; + ExternalConnectivityWatcher* next_ = nullptr; + }; + + ChannelData(grpc_channel_element_args* args, grpc_error** error); + ~ChannelData(); + + static bool ProcessResolverResultLocked( + void* arg, Resolver::Result* args, const char** lb_policy_name, + RefCountedPtr* lb_policy_config); + + grpc_error* DoPingLocked(grpc_transport_op* op); + + static void StartTransportOpLocked(void* arg, grpc_error* ignored); + + static void TryToConnectLocked(void* arg, grpc_error* error_ignored); -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; - grpc_channel_stack* owning_stack; - grpc_core::ClientChannelFactory* client_channel_factory; - - grpc_core::channelz::ClientChannelNode* channelz_node; + const bool deadline_checking_enabled_; + const bool enable_retries_; + const size_t per_rpc_retry_buffer_size_; + grpc_channel_stack* owning_stack_; + ClientChannelFactory* client_channel_factory_; + // Initialized shortly after construction. + channelz::ClientChannelNode* channelz_node_ = nullptr; // - // Fields used in the data plane. Protected by data_plane_combiner. + // Fields used in the data plane. Guarded by data_plane_combiner. // - grpc_combiner* data_plane_combiner; - grpc_core::UniquePtr picker; - QueuedPick* queued_picks; // Linked list of queued picks. + grpc_combiner* data_plane_combiner_; + UniquePtr picker_; + QueuedPick* queued_picks_ = nullptr; // Linked list of queued picks. // Data from service config. - bool received_service_config_data; - grpc_core::RefCountedPtr retry_throttle_data; - grpc_core::RefCountedPtr method_params_table; + bool received_service_config_data_ = false; + RefCountedPtr retry_throttle_data_; + RefCountedPtr method_params_table_; // - // Fields used in the control plane. Protected by combiner. + // Fields used in the control plane. Guarded 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; + grpc_combiner* combiner_; + grpc_pollset_set* interested_parties_; + RefCountedPtr subchannel_pool_; + OrphanablePtr resolving_lb_policy_; + grpc_connectivity_state_tracker state_tracker_; + ExternalConnectivityWatcher::WatcherList external_connectivity_watcher_list_; // // Fields accessed from both data plane and control plane combiners. // - grpc_core::Atomic disconnect_error; + Atomic disconnect_error_; - // 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_core::ManualConstructor< - grpc_core::ExternalConnectivityWatcher::WatcherList> - external_connectivity_watcher_list; + // + // Fields guarded by a mutex, since they need to be accessed + // synchronously via get_channel_info(). + // + gpr_mu info_mu_; + UniquePtr info_lb_policy_name_; + UniquePtr info_service_config_json_; }; -// 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"); -} - -namespace grpc_core { -namespace { +// +// ChannelData::ConnectivityStateAndPickerSetter +// // 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 { +class ChannelData::ConnectivityStateAndPickerSetter { public: ConnectivityStateAndPickerSetter( - channel_data* chand, grpc_connectivity_state state, const char* reason, + ChannelData* chand, grpc_connectivity_state state, 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, reason); - if (chand->channelz_node != nullptr) { - chand->channelz_node->AddTraceEvent( + grpc_connectivity_state_set(&chand->state_tracker_, state, 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))); + GetChannelConnectivityStateChangeString(state))); } // Bounce into the data plane combiner to reset the picker. - GRPC_CHANNEL_STACK_REF(chand->owning_stack, + GRPC_CHANNEL_STACK_REF(chand->owning_stack_, "ConnectivityStateAndPickerSetter"); GRPC_CLOSURE_INIT(&closure_, SetPicker, this, - grpc_combiner_scheduler(chand->data_plane_combiner)); + grpc_combiner_scheduler(chand->data_plane_combiner_)); GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); } private: + static 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"); + } + static void SetPicker(void* arg, grpc_error* ignored) { auto* self = static_cast(arg); // Update picker. - self->chand_->picker = std::move(self->picker_); + self->chand_->picker_ = std::move(self->picker_); // Re-process queued picks. - for (QueuedPick* pick = self->chand_->queued_picks; pick != nullptr; + 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, + GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack_, "ConnectivityStateAndPickerSetter"); Delete(self); } - channel_data* chand_; + ChannelData* chand_; UniquePtr picker_; grpc_closure closure_; }; +// +// ChannelData::ServiceConfigSetter +// + // A fire-and-forget class that sets the channel's service config data // in the data plane combiner. Deletes itself when done. -class ServiceConfigSetter { +class ChannelData::ServiceConfigSetter { public: ServiceConfigSetter( - channel_data* chand, + ChannelData* 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_CHANNEL_STACK_REF(chand->owning_stack_, "ServiceConfigSetter"); GRPC_CLOSURE_INIT(&closure_, SetServiceConfigData, this, - grpc_combiner_scheduler(chand->data_plane_combiner)); + 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_; + ChannelData* 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_); + 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; + 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"); + GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack_, + "ServiceConfigSetter"); Delete(self); } - channel_data* chand_; + ChannelData* chand_; RefCountedPtr retry_throttle_data_; RefCountedPtr method_params_table_; grpc_closure closure_; }; // -// ExternalConnectivityWatcher::WatcherList +// ChannelData::ExternalConnectivityWatcher::WatcherList // -int ExternalConnectivityWatcher::WatcherList::size() const { +int ChannelData::ExternalConnectivityWatcher::WatcherList::size() const { MutexLock lock(&mu_); int count = 0; for (ExternalConnectivityWatcher* w = head_; w != nullptr; w = w->next_) { @@ -321,7 +405,8 @@ int ExternalConnectivityWatcher::WatcherList::size() const { return count; } -ExternalConnectivityWatcher* ExternalConnectivityWatcher::WatcherList::Lookup( +ChannelData::ExternalConnectivityWatcher* +ChannelData::ExternalConnectivityWatcher::WatcherList::Lookup( grpc_closure* on_complete) const { MutexLock lock(&mu_); ExternalConnectivityWatcher* w = head_; @@ -331,7 +416,7 @@ ExternalConnectivityWatcher* ExternalConnectivityWatcher::WatcherList::Lookup( return w; } -void ExternalConnectivityWatcher::WatcherList::Add( +void ChannelData::ExternalConnectivityWatcher::WatcherList::Add( ExternalConnectivityWatcher* watcher) { GPR_ASSERT(Lookup(watcher->on_complete_) == nullptr); MutexLock lock(&mu_); @@ -340,7 +425,7 @@ void ExternalConnectivityWatcher::WatcherList::Add( head_ = watcher; } -void ExternalConnectivityWatcher::WatcherList::Remove( +void ChannelData::ExternalConnectivityWatcher::WatcherList::Remove( const ExternalConnectivityWatcher* watcher) { MutexLock lock(&mu_); if (watcher == head_) { @@ -357,11 +442,11 @@ void ExternalConnectivityWatcher::WatcherList::Remove( } // -// ExternalConnectivityWatcher +// ChannelData::ExternalConnectivityWatcher // -ExternalConnectivityWatcher::ExternalConnectivityWatcher( - channel_data* chand, grpc_polling_entity pollent, +ChannelData::ExternalConnectivityWatcher::ExternalConnectivityWatcher( + ChannelData* chand, grpc_polling_entity pollent, grpc_connectivity_state* state, grpc_closure* on_complete, grpc_closure* watcher_timer_init) : chand_(chand), @@ -369,31 +454,33 @@ ExternalConnectivityWatcher::ExternalConnectivityWatcher( state_(state), on_complete_(on_complete), watcher_timer_init_(watcher_timer_init) { - grpc_polling_entity_add_to_pollset_set(&pollent_, chand_->interested_parties); - GRPC_CHANNEL_STACK_REF(chand_->owning_stack, "ExternalConnectivityWatcher"); + grpc_polling_entity_add_to_pollset_set(&pollent_, + chand_->interested_parties_); + GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "ExternalConnectivityWatcher"); GRPC_CLOSURE_SCHED( GRPC_CLOSURE_INIT(&my_closure_, WatchConnectivityStateLocked, this, - grpc_combiner_scheduler(chand_->combiner)), + grpc_combiner_scheduler(chand_->combiner_)), GRPC_ERROR_NONE); } -ExternalConnectivityWatcher::~ExternalConnectivityWatcher() { +ChannelData::ExternalConnectivityWatcher::~ExternalConnectivityWatcher() { grpc_polling_entity_del_from_pollset_set(&pollent_, - chand_->interested_parties); - GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack, "ExternalConnectivityWatcher"); + chand_->interested_parties_); + GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, + "ExternalConnectivityWatcher"); } -void ExternalConnectivityWatcher::OnWatchCompleteLocked(void* arg, - grpc_error* error) { +void ChannelData::ExternalConnectivityWatcher::OnWatchCompleteLocked( + void* arg, grpc_error* error) { ExternalConnectivityWatcher* self = static_cast(arg); grpc_closure* on_complete = self->on_complete_; - self->chand_->external_connectivity_watcher_list->Remove(self); + self->chand_->external_connectivity_watcher_list_.Remove(self); Delete(self); GRPC_CLOSURE_SCHED(on_complete, GRPC_ERROR_REF(error)); } -void ExternalConnectivityWatcher::WatchConnectivityStateLocked( +void ChannelData::ExternalConnectivityWatcher::WatchConnectivityStateLocked( void* arg, grpc_error* ignored) { ExternalConnectivityWatcher* self = static_cast(arg); @@ -401,63 +488,63 @@ void ExternalConnectivityWatcher::WatchConnectivityStateLocked( // Handle cancellation. GPR_ASSERT(self->watcher_timer_init_ == nullptr); ExternalConnectivityWatcher* found = - self->chand_->external_connectivity_watcher_list->Lookup( + self->chand_->external_connectivity_watcher_list_.Lookup( self->on_complete_); if (found != nullptr) { grpc_connectivity_state_notify_on_state_change( - &found->chand_->state_tracker, nullptr, &found->my_closure_); + &found->chand_->state_tracker_, nullptr, &found->my_closure_); } Delete(self); return; } // New watcher. - self->chand_->external_connectivity_watcher_list->Add(self); + self->chand_->external_connectivity_watcher_list_.Add(self); // This assumes that the closure is scheduled on the ExecCtx scheduler // and that GRPC_CLOSURE_RUN would run the closure immediately. GRPC_CLOSURE_RUN(self->watcher_timer_init_, GRPC_ERROR_NONE); GRPC_CLOSURE_INIT(&self->my_closure_, OnWatchCompleteLocked, self, - grpc_combiner_scheduler(self->chand_->combiner)); + grpc_combiner_scheduler(self->chand_->combiner_)); grpc_connectivity_state_notify_on_state_change( - &self->chand_->state_tracker, self->state_, &self->my_closure_); + &self->chand_->state_tracker_, self->state_, &self->my_closure_); } // -// ClientChannelControlHelper +// ChannelData::ClientChannelControlHelper // -class ClientChannelControlHelper +class ChannelData::ClientChannelControlHelper : public LoadBalancingPolicy::ChannelControlHelper { public: - explicit ClientChannelControlHelper(channel_data* chand) : chand_(chand) { - GRPC_CHANNEL_STACK_REF(chand_->owning_stack, "ClientChannelControlHelper"); + explicit ClientChannelControlHelper(ChannelData* chand) : chand_(chand) { + GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "ClientChannelControlHelper"); } ~ClientChannelControlHelper() override { - GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack, + 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()); + chand_->subchannel_pool_.get()); grpc_channel_args* new_args = grpc_channel_args_copy_and_add(&args, &arg, 1); Subchannel* subchannel = - chand_->client_channel_factory->CreateSubchannel(new_args); + chand_->client_channel_factory_->CreateSubchannel(new_args); grpc_channel_args_destroy(new_args); return subchannel; } grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override { - return chand_->client_channel_factory->CreateChannel(target, &args); + return chand_->client_channel_factory_->CreateChannel(target, &args); } void UpdateState( grpc_connectivity_state state, UniquePtr picker) override { grpc_error* disconnect_error = - chand_->disconnect_error.Load(grpc_core::MemoryOrder::ACQUIRE); + chand_->disconnect_error_.Load(MemoryOrder::ACQUIRE); if (grpc_client_channel_routing_trace.enabled()) { const char* extra = disconnect_error == GRPC_ERROR_NONE ? "" @@ -477,55 +564,181 @@ class ClientChannelControlHelper void RequestReresolution() override {} private: - channel_data* chand_; + ChannelData* chand_; }; -} // namespace -} // namespace grpc_core +// +// ChannelData implementation +// -// Synchronous callback from chand->resolving_lb_policy to process a resolver -// result update. -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); - ProcessedResolverResult resolver_result(result, chand->enable_retries); - grpc_core::UniquePtr service_config_json = - resolver_result.service_config_json(); +grpc_error* ChannelData::Init(grpc_channel_element* elem, + grpc_channel_element_args* args) { + GPR_ASSERT(args->is_last); + GPR_ASSERT(elem->filter == &grpc_client_channel_filter); + grpc_error* error = GRPC_ERROR_NONE; + new (elem->channel_data) ChannelData(args, &error); + return error; +} + +void ChannelData::Destroy(grpc_channel_element* elem) { + ChannelData* chand = static_cast(elem->channel_data); + chand->~ChannelData(); +} + +bool GetEnableRetries(const grpc_channel_args* args) { + return grpc_channel_arg_get_bool( + grpc_channel_args_find(args, GRPC_ARG_ENABLE_RETRIES), true); +} + +size_t GetMaxPerRpcRetryBufferSize(const grpc_channel_args* args) { + return static_cast(grpc_channel_arg_get_integer( + grpc_channel_args_find(args, GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE), + {DEFAULT_PER_RPC_RETRY_BUFFER_SIZE, 0, INT_MAX})); +} + +RefCountedPtr GetSubchannelPool( + const grpc_channel_args* args) { + const bool use_local_subchannel_pool = grpc_channel_arg_get_bool( + grpc_channel_args_find(args, GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL), false); + if (use_local_subchannel_pool) { + return MakeRefCounted(); + } + return GlobalSubchannelPool::instance(); +} + +ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) + : deadline_checking_enabled_( + grpc_deadline_checking_enabled(args->channel_args)), + enable_retries_(GetEnableRetries(args->channel_args)), + per_rpc_retry_buffer_size_( + GetMaxPerRpcRetryBufferSize(args->channel_args)), + owning_stack_(args->channel_stack), + client_channel_factory_( + ClientChannelFactory::GetFromChannelArgs(args->channel_args)), + data_plane_combiner_(grpc_combiner_create()), + combiner_(grpc_combiner_create()), + interested_parties_(grpc_pollset_set_create()), + subchannel_pool_(GetSubchannelPool(args->channel_args)), + disconnect_error_(GRPC_ERROR_NONE) { + // Initialize data members. + grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, + "client_channel"); + gpr_mu_init(&info_mu_); + // Start backup polling. + grpc_client_channel_start_backup_polling(interested_parties_); + // Check client channel factory. + if (client_channel_factory_ == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Missing client channel factory in args for client channel filter"); + return; + } + // Get server name to resolve, using proxy mapper if needed. + const char* server_uri = grpc_channel_arg_get_string( + grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI)); + if (server_uri == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "server URI channel arg missing or wrong type in client channel " + "filter"); + return; + } + char* proxy_name = nullptr; + grpc_channel_args* new_args = nullptr; + grpc_proxy_mappers_map_name(server_uri, args->channel_args, &proxy_name, + &new_args); + UniquePtr target_uri(proxy_name != nullptr ? proxy_name + : gpr_strdup(server_uri)); + // Instantiate resolving LB policy. + LoadBalancingPolicy::Args lb_args; + lb_args.combiner = combiner_; + lb_args.channel_control_helper = + UniquePtr( + New(this)); + lb_args.args = new_args != nullptr ? new_args : args->channel_args; + resolving_lb_policy_.reset(New( + std::move(lb_args), &grpc_client_channel_routing_trace, + std::move(target_uri), ProcessResolverResultLocked, this, 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. + resolving_lb_policy_.reset(); + ExecCtx::Get()->Flush(); + } else { + grpc_pollset_set_add_pollset_set(resolving_lb_policy_->interested_parties(), + interested_parties_); + if (grpc_client_channel_routing_trace.enabled()) { + gpr_log(GPR_INFO, "chand=%p: created resolving_lb_policy=%p", this, + resolving_lb_policy_.get()); + } + } +} + +ChannelData::~ChannelData() { + if (resolving_lb_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set(resolving_lb_policy_->interested_parties(), + interested_parties_); + resolving_lb_policy_.reset(); + } + // Stop backup polling. + grpc_client_channel_stop_backup_polling(interested_parties_); + grpc_pollset_set_destroy(interested_parties_); + GRPC_COMBINER_UNREF(data_plane_combiner_, "client_channel"); + GRPC_COMBINER_UNREF(combiner_, "client_channel"); + GRPC_ERROR_UNREF(disconnect_error_.Load(MemoryOrder::RELAXED)); + grpc_connectivity_state_destroy(&state_tracker_); + gpr_mu_destroy(&info_mu_); +} + +// Synchronous callback from ResolvingLoadBalancingPolicy to process a +// resolver result update. +bool ChannelData::ProcessResolverResultLocked( + void* arg, Resolver::Result* result, const char** lb_policy_name, + RefCountedPtr* lb_policy_config) { + ChannelData* chand = static_cast(arg); + ProcessedResolverResult resolver_result(result, chand->enable_retries_); + UniquePtr service_config_json = resolver_result.service_config_json(); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", chand, service_config_json.get()); } // 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(); - const bool service_config_changed = - ((service_config_json == nullptr) != - (chand->info_service_config_json == nullptr)) || - (service_config_json != nullptr && - strcmp(service_config_json.get(), - chand->info_service_config_json.get()) != 0); - chand->info_service_config_json = std::move(service_config_json); - gpr_mu_unlock(&chand->info_mu); + New(chand, resolver_result.retry_throttle_data(), + resolver_result.method_params_table()); + // Swap out the data used by GetChannelInfo(). + bool service_config_changed; + { + MutexLock lock(&chand->info_mu_); + chand->info_lb_policy_name_ = resolver_result.lb_policy_name(); + service_config_changed = + ((service_config_json == nullptr) != + (chand->info_service_config_json_ == nullptr)) || + (service_config_json != nullptr && + strcmp(service_config_json.get(), + chand->info_service_config_json_.get()) != 0); + chand->info_service_config_json_ = std::move(service_config_json); + } // Return results. - *lb_policy_name = chand->info_lb_policy_name.get(); + *lb_policy_name = chand->info_lb_policy_name_.get(); *lb_policy_config = resolver_result.lb_policy_config(); return service_config_changed; } -static grpc_error* do_ping_locked(channel_data* chand, grpc_transport_op* op) { - if (grpc_connectivity_state_check(&chand->state_tracker) != - GRPC_CHANNEL_READY) { +grpc_error* ChannelData::DoPingLocked(grpc_transport_op* op) { + if (grpc_connectivity_state_check(&state_tracker_) != GRPC_CHANNEL_READY) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING("channel not connected"); } LoadBalancingPolicy::PickArgs pick; grpc_error* error = GRPC_ERROR_NONE; - chand->picker->Pick(&pick, &error); + picker_->Pick(&pick, &error); if (pick.connected_subchannel != nullptr) { pick.connected_subchannel->Ping(op->send_ping.on_initiate, op->send_ping.on_ack); @@ -538,22 +751,22 @@ static grpc_error* do_ping_locked(channel_data* chand, grpc_transport_op* op) { return error; } -static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { +void ChannelData::StartTransportOpLocked(void* arg, grpc_error* ignored) { grpc_transport_op* op = static_cast(arg); grpc_channel_element* elem = static_cast(op->handler_private.extra_arg); - channel_data* chand = static_cast(elem->channel_data); - + ChannelData* chand = static_cast(elem->channel_data); + // Connectivity watch. if (op->on_connectivity_state_change != nullptr) { grpc_connectivity_state_notify_on_state_change( - &chand->state_tracker, op->connectivity_state, + &chand->state_tracker_, op->connectivity_state, op->on_connectivity_state_change); op->on_connectivity_state_change = nullptr; op->connectivity_state = nullptr; } - + // Ping. if (op->send_ping.on_initiate != nullptr || op->send_ping.on_ack != nullptr) { - grpc_error* error = do_ping_locked(chand, op); + grpc_error* error = chand->DoPingLocked(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); @@ -562,194 +775,117 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { op->send_ping.on_initiate = nullptr; op->send_ping.on_ack = nullptr; } - + // Reset backoff. if (op->reset_connect_backoff) { - chand->resolving_lb_policy->ResetBackoffLocked(); + if (chand->resolving_lb_policy_ != nullptr) { + chand->resolving_lb_policy_->ResetBackoffLocked(); + } } - + // Disconnect. if (op->disconnect_with_error != GRPC_ERROR_NONE) { 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)); + GPR_ASSERT(chand->disconnect_error_.CompareExchangeStrong( + &error, op->disconnect_with_error, MemoryOrder::ACQ_REL, + MemoryOrder::ACQUIRE)); grpc_pollset_set_del_pollset_set( - chand->resolving_lb_policy->interested_parties(), - chand->interested_parties); - chand->resolving_lb_policy.reset(); + chand->resolving_lb_policy_->interested_parties(), + chand->interested_parties_); + chand->resolving_lb_policy_.reset(); // Will delete itself. - grpc_core::New( + New( chand, GRPC_CHANNEL_SHUTDOWN, "shutdown from API", - grpc_core::UniquePtr( - grpc_core::New( + UniquePtr( + New( GRPC_ERROR_REF(op->disconnect_with_error)))); } - - GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "start_transport_op"); + GRPC_CHANNEL_STACK_UNREF(chand->owning_stack_, "start_transport_op"); GRPC_CLOSURE_SCHED(op->on_consumed, GRPC_ERROR_NONE); } -static void cc_start_transport_op(grpc_channel_element* elem, - grpc_transport_op* op) { - channel_data* chand = static_cast(elem->channel_data); - +void ChannelData::StartTransportOp(grpc_channel_element* elem, + grpc_transport_op* op) { + ChannelData* chand = static_cast(elem->channel_data); GPR_ASSERT(op->set_accept_stream == false); + // Handle bind_pollset. if (op->bind_pollset != nullptr) { - grpc_pollset_set_add_pollset(chand->interested_parties, op->bind_pollset); + grpc_pollset_set_add_pollset(chand->interested_parties_, op->bind_pollset); } - + // Pop into control plane combiner for remaining ops. op->handler_private.extra_arg = elem; - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "start_transport_op"); + GRPC_CHANNEL_STACK_REF(chand->owning_stack_, "start_transport_op"); GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_INIT(&op->handler_private.closure, start_transport_op_locked, - op, grpc_combiner_scheduler(chand->combiner)), + GRPC_CLOSURE_INIT(&op->handler_private.closure, + ChannelData::StartTransportOpLocked, op, + grpc_combiner_scheduler(chand->combiner_)), GRPC_ERROR_NONE); } -static void cc_get_channel_info(grpc_channel_element* elem, - const grpc_channel_info* info) { - channel_data* chand = static_cast(elem->channel_data); - gpr_mu_lock(&chand->info_mu); +void ChannelData::GetChannelInfo(grpc_channel_element* elem, + const grpc_channel_info* info) { + ChannelData* chand = static_cast(elem->channel_data); + MutexLock lock(&chand->info_mu_); if (info->lb_policy_name != nullptr) { - *info->lb_policy_name = gpr_strdup(chand->info_lb_policy_name.get()); + *info->lb_policy_name = gpr_strdup(chand->info_lb_policy_name_.get()); } if (info->service_config_json != nullptr) { *info->service_config_json = - gpr_strdup(chand->info_service_config_json.get()); + gpr_strdup(chand->info_service_config_json_.get()); } - gpr_mu_unlock(&chand->info_mu); } -/* Constructor for channel_data */ -static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, - grpc_channel_element_args* args) { - channel_data* chand = static_cast(elem->channel_data); - 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.Store(GRPC_ERROR_NONE, - grpc_core::MemoryOrder::RELAXED); - gpr_mu_init(&chand->info_mu); - chand->external_connectivity_watcher_list.Init(); - chand->owning_stack = args->channel_stack; - chand->deadline_checking_enabled = - grpc_deadline_checking_enabled(args->channel_args); - chand->interested_parties = grpc_pollset_set_create(); - grpc_client_channel_start_backup_polling(chand->interested_parties); - // Record max per-RPC retry buffer size. - const grpc_arg* arg = grpc_channel_args_find( - args->channel_args, GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE); - chand->per_rpc_retry_buffer_size = (size_t)grpc_channel_arg_get_integer( - arg, {DEFAULT_PER_RPC_RETRY_BUFFER_SIZE, 0, INT_MAX}); - // Record enable_retries. - 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. - 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"); - } - // 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) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Missing server uri in args for client channel filter"); - } - if (arg->type != GRPC_ARG_STRING) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "server uri arg must be a string"); - } - char* proxy_name = nullptr; - 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; - grpc_error* error = GRPC_ERROR_NONE; - chand->resolving_lb_policy.reset( - grpc_core::New( - 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 - // 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_routing_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: created resolving_lb_policy=%p", chand, - chand->resolving_lb_policy.get()); +void ChannelData::AddQueuedPick(QueuedPick* pick, + grpc_polling_entity* pollent) { + // Add call to queued picks list. + pick->next = queued_picks_; + queued_picks_ = 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(pollent, interested_parties_); +} + +void ChannelData::RemoveQueuedPick(QueuedPick* to_remove, + grpc_polling_entity* pollent) { + // Remove call's pollent from channel's interested_parties. + grpc_polling_entity_del_from_pollset_set(pollent, interested_parties_); + // Remove from queued picks list. + for (QueuedPick** pick = &queued_picks_; *pick != nullptr; + pick = &(*pick)->next) { + if (*pick == to_remove) { + *pick = to_remove->next; + return; } } - 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(); +void ChannelData::TryToConnectLocked(void* arg, grpc_error* error_ignored) { + auto* chand = static_cast(arg); + if (chand->resolving_lb_policy_ != nullptr) { + chand->resolving_lb_policy_->ExitIdleLocked(); } - // 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(); - chand->info_lb_policy_name.reset(); - chand->info_service_config_json.reset(); - chand->retry_throttle_data.reset(); - 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.Load(grpc_core::MemoryOrder::RELAXED)); - grpc_connectivity_state_destroy(&chand->state_tracker); - gpr_mu_destroy(&chand->info_mu); - chand->external_connectivity_watcher_list.Destroy(); + GRPC_CHANNEL_STACK_UNREF(chand->owning_stack_, "TryToConnect"); } +grpc_connectivity_state ChannelData::CheckConnectivityState( + bool try_to_connect) { + grpc_connectivity_state out = grpc_connectivity_state_check(&state_tracker_); + if (out == GRPC_CHANNEL_IDLE && try_to_connect) { + GRPC_CHANNEL_STACK_REF(owning_stack_, "TryToConnect"); + GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(TryToConnectLocked, this, + grpc_combiner_scheduler(combiner_)), + GRPC_ERROR_NONE); + } + return out; +} + +} // namespace +} // namespace grpc_core + /************************************************************************* * PER-CALL FUNCTIONS */ +using grpc_core::ChannelData; + // Max number of batches that can be pending on a call at any given // time. This includes one batch for each of the following ops: // recv_initial_metadata @@ -914,10 +1050,10 @@ struct pending_batch { for initial metadata before trying to create a call object, and handling cancellation gracefully. */ struct call_data { - call_data(grpc_call_element* elem, const channel_data& chand, + call_data(grpc_call_element* elem, const ChannelData& chand, const grpc_call_element_args& args) : deadline_state(elem, args.call_stack, args.call_combiner, - GPR_LIKELY(chand.deadline_checking_enabled) + GPR_LIKELY(chand.deadline_checking_enabled()) ? args.deadline : GRPC_MILLIS_INF_FUTURE), path(grpc_slice_ref_internal(args.path)), @@ -930,7 +1066,7 @@ struct call_data { pending_send_initial_metadata(false), pending_send_message(false), pending_send_trailing_metadata(false), - enable_retries(chand.enable_retries), + enable_retries(chand.enable_retries()), retry_committed(false), last_attempt_got_server_pushback(false) {} @@ -966,7 +1102,7 @@ struct call_data { // Set when we get a cancel_stream op. grpc_error* cancel_error = GRPC_ERROR_NONE; - QueuedPick pick; + ChannelData::QueuedPick pick; bool pick_queued = false; bool service_config_applied = false; grpc_core::QueuedPickCanceller* pick_canceller = nullptr; @@ -1086,7 +1222,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, +static void free_cached_send_initial_metadata(ChannelData* chand, call_data* calld) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, @@ -1097,7 +1233,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, +static void free_cached_send_message(ChannelData* chand, call_data* calld, size_t idx) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, @@ -1108,7 +1244,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, +static void free_cached_send_trailing_metadata(ChannelData* chand, call_data* calld) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, @@ -1122,7 +1258,7 @@ static void free_cached_send_trailing_metadata(channel_data* chand, // committing the call. static void free_cached_send_op_data_after_commit( grpc_call_element* elem, subchannel_call_retry_state* retry_state) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (retry_state->completed_send_initial_metadata) { free_cached_send_initial_metadata(chand, calld); @@ -1140,7 +1276,7 @@ static void free_cached_send_op_data_after_commit( static void free_cached_send_op_data_for_completed_batch( grpc_call_element* elem, subchannel_batch_data* batch_data, subchannel_call_retry_state* retry_state) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (batch_data->batch.send_initial_metadata) { free_cached_send_initial_metadata(chand, calld); @@ -1193,7 +1329,7 @@ static size_t get_batch_index(grpc_transport_stream_op_batch* batch) { // This is called via the call combiner, so access to calld is synchronized. static void pending_batches_add(grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* 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_call_trace.enabled()) { @@ -1224,7 +1360,7 @@ static void pending_batches_add(grpc_call_element* elem, calld->pending_send_trailing_metadata = true; } if (GPR_UNLIKELY(calld->bytes_buffered_for_retry > - chand->per_rpc_retry_buffer_size)) { + chand->per_rpc_retry_buffer_size())) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: exceeded retry buffer size, committing", @@ -1346,7 +1482,7 @@ static void resume_pending_batch_in_call_combiner(void* arg, // 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); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (calld->enable_retries) { start_retriable_subchannel_batches(elem, GRPC_ERROR_NONE); @@ -1387,7 +1523,7 @@ static void pending_batches_resume(grpc_call_element* elem) { static void maybe_clear_pending_batch(grpc_call_element* elem, pending_batch* pending) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); grpc_transport_stream_op_batch* batch = pending->batch; // We clear the pending batch if all of its callbacks have been @@ -1415,7 +1551,7 @@ template static pending_batch* pending_batch_find(grpc_call_element* elem, const char* log_message, Predicate predicate) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { pending_batch* pending = &calld->pending_batches[i]; @@ -1439,7 +1575,7 @@ static pending_batch* pending_batch_find(grpc_call_element* elem, // Commits the call so that no further retry attempts will be performed. static void retry_commit(grpc_call_element* elem, subchannel_call_retry_state* retry_state) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (calld->retry_committed) return; calld->retry_committed = true; @@ -1455,7 +1591,7 @@ static void retry_commit(grpc_call_element* elem, static void do_retry(grpc_call_element* elem, subchannel_call_retry_state* retry_state, grpc_millis server_pushback_ms) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); GPR_ASSERT(calld->method_params != nullptr); const ClientChannelMethodParams::RetryPolicy* retry_policy = @@ -1489,7 +1625,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->data_plane_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; @@ -1500,7 +1636,7 @@ static bool maybe_retry(grpc_call_element* elem, subchannel_batch_data* batch_data, grpc_status_code status, grpc_mdelem* server_pushback_md) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); // Get retry policy. if (calld->method_params == nullptr) return false; @@ -1714,7 +1850,7 @@ static void invoke_recv_initial_metadata_callback(void* arg, static void recv_initial_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); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, @@ -1804,7 +1940,7 @@ static void invoke_recv_message_callback(void* arg, grpc_error* error) { static void recv_message_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); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: got recv_message_ready, error=%s", @@ -1975,7 +2111,7 @@ static bool pending_batch_is_unstarted( static void add_closures_to_fail_unstarted_pending_batches( grpc_call_element* elem, subchannel_call_retry_state* retry_state, grpc_error* error, grpc_core::CallCombinerClosureList* closures) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { pending_batch* pending = &calld->pending_batches[i]; @@ -2027,7 +2163,7 @@ static void run_closures_for_completed_call(subchannel_batch_data* batch_data, 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); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, @@ -2111,7 +2247,7 @@ static void add_closures_for_replay_or_pending_send_ops( grpc_call_element* elem, subchannel_batch_data* batch_data, subchannel_call_retry_state* retry_state, grpc_core::CallCombinerClosureList* closures) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); bool have_pending_send_message_ops = retry_state->started_send_message_count < calld->send_messages.size(); @@ -2149,7 +2285,7 @@ static void add_closures_for_replay_or_pending_send_ops( static void on_complete(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); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (grpc_client_channel_call_trace.enabled()) { char* batch_str = grpc_transport_stream_op_batch_string(&batch_data->batch); @@ -2225,7 +2361,7 @@ static void start_batch_in_call_combiner(void* arg, grpc_error* ignored) { static void add_closure_for_subchannel_batch( grpc_call_element* elem, grpc_transport_stream_op_batch* batch, grpc_core::CallCombinerClosureList* closures) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); batch->handler_private.extra_arg = calld->subchannel_call.get(); GRPC_CLOSURE_INIT(&batch->handler_private.closure, @@ -2297,7 +2433,7 @@ static void add_retriable_send_initial_metadata_op( static void add_retriable_send_message_op( grpc_call_element* elem, subchannel_call_retry_state* retry_state, subchannel_batch_data* batch_data) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, @@ -2391,7 +2527,7 @@ static void add_retriable_recv_trailing_metadata_op( // op fails in a way that we know the call is over but when the application // has not yet started its own recv_trailing_metadata op. static void start_internal_recv_trailing_metadata(grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, @@ -2419,7 +2555,7 @@ static void start_internal_recv_trailing_metadata(grpc_call_element* elem) { // to replay those ops. Otherwise, returns nullptr. static subchannel_batch_data* maybe_create_subchannel_batch_for_replay( grpc_call_element* elem, subchannel_call_retry_state* retry_state) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); subchannel_batch_data* replay_batch_data = nullptr; // send_initial_metadata. @@ -2610,7 +2746,7 @@ static void add_subchannel_batches_for_pending_batches( // subchannel call. 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); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: constructing retriable batches", @@ -2652,7 +2788,7 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { // static void create_subchannel_call(grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* 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; @@ -2690,7 +2826,7 @@ static void create_subchannel_call(grpc_call_element* elem) { // Invoked when a pick is completed, on both success or failure. static void pick_done(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (error != GRPC_ERROR_NONE) { if (grpc_client_channel_routing_trace.enabled()) { @@ -2713,17 +2849,17 @@ 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); + 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->data_plane_combiner)); + grpc_combiner_scheduler(chand->data_plane_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* chand = static_cast(self->elem_->channel_data); auto* calld = static_cast(self->elem_->call_data); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, @@ -2752,44 +2888,29 @@ class QueuedPickCanceller { // 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* 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_routing_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; - } + if (grpc_client_channel_routing_trace.enabled()) { + gpr_log(GPR_INFO, "chand=%p calld=%p: removing from queued picks list", + chand, calld); } + chand->RemoveQueuedPick(&calld->pick, calld->pollent); + calld->pick_queued = false; + // Lame the call combiner canceller. + calld->pick_canceller = nullptr; } // 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* chand = static_cast(elem->channel_data); auto* calld = static_cast(elem->call_data); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: adding to queued picks list", chand, calld); } 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); + chand->AddQueuedPick(&calld->pick, calld->pollent); // Register call combiner cancellation callback. calld->pick_canceller = grpc_core::New(elem); } @@ -2797,48 +2918,41 @@ static void add_call_to_queued_picks_locked(grpc_call_element* elem) { // Applies service config to the call. Must be invoked once we know // that the resolver has returned results to the channel. static void apply_service_config_to_call_locked(grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call", chand, calld); } - if (chand->retry_throttle_data != nullptr) { - calld->retry_throttle_data = chand->retry_throttle_data->Ref(); - } - if (chand->method_params_table != nullptr) { - calld->method_params = grpc_core::ServiceConfig::MethodConfigTableLookup( - *chand->method_params_table, calld->path); - if (calld->method_params != nullptr) { - // If the deadline from the service config is shorter than the one - // from the client API, reset the deadline timer. - if (chand->deadline_checking_enabled && - calld->method_params->timeout() != 0) { - const grpc_millis per_method_deadline = - grpc_timespec_to_millis_round_up(calld->call_start_time) + - calld->method_params->timeout(); - if (per_method_deadline < calld->deadline) { - calld->deadline = per_method_deadline; - grpc_deadline_state_reset(elem, calld->deadline); - } + calld->retry_throttle_data = chand->retry_throttle_data(); + calld->method_params = chand->GetMethodParams(calld->path); + if (calld->method_params != nullptr) { + // If the deadline from the service config is shorter than the one + // from the client API, reset the deadline timer. + if (chand->deadline_checking_enabled() && + calld->method_params->timeout() != 0) { + const grpc_millis per_method_deadline = + grpc_timespec_to_millis_round_up(calld->call_start_time) + + calld->method_params->timeout(); + if (per_method_deadline < calld->deadline) { + calld->deadline = per_method_deadline; + grpc_deadline_state_reset(elem, calld->deadline); } - // If the service config set wait_for_ready and the application - // did not explicitly set it, use the value from the service config. - uint32_t* send_initial_metadata_flags = - &calld->pending_batches[0] - .batch->payload->send_initial_metadata - .send_initial_metadata_flags; - if (GPR_UNLIKELY( - calld->method_params->wait_for_ready() != - ClientChannelMethodParams::WAIT_FOR_READY_UNSET && - !(*send_initial_metadata_flags & - GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET))) { - if (calld->method_params->wait_for_ready() == - ClientChannelMethodParams::WAIT_FOR_READY_TRUE) { - *send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY; - } else { - *send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY; - } + } + // If the service config set wait_for_ready and the application + // did not explicitly set it, use the value from the service config. + uint32_t* send_initial_metadata_flags = + &calld->pending_batches[0] + .batch->payload->send_initial_metadata.send_initial_metadata_flags; + if (GPR_UNLIKELY(calld->method_params->wait_for_ready() != + ClientChannelMethodParams::WAIT_FOR_READY_UNSET && + !(*send_initial_metadata_flags & + GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET))) { + if (calld->method_params->wait_for_ready() == + ClientChannelMethodParams::WAIT_FOR_READY_TRUE) { + *send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY; + } else { + *send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY; } } } @@ -2852,11 +2966,11 @@ 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); + ChannelData* chand = static_cast(elem->channel_data); 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->received_service_config_data && + if (GPR_LIKELY(chand->received_service_config_data() && !calld->service_config_applied)) { calld->service_config_applied = true; apply_service_config_to_call_locked(elem); @@ -2878,7 +2992,7 @@ static const char* pick_result_name(LoadBalancingPolicy::PickResult result) { 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); + ChannelData* chand = static_cast(elem->channel_data); GPR_ASSERT(calld->pick.pick.connected_subchannel == nullptr); GPR_ASSERT(calld->subchannel_call == nullptr); // If this is a retry, use the send_initial_metadata payload that @@ -2909,7 +3023,7 @@ static void start_pick_locked(void* arg, grpc_error* error) { grpc_schedule_on_exec_ctx); // Attempt pick. error = GRPC_ERROR_NONE; - auto pick_result = chand->picker->Pick(&calld->pick.pick, &error); + auto pick_result = chand->picker()->Pick(&calld->pick.pick, &error); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: LB pick returned %s (connected_subchannel=%p, " @@ -2921,8 +3035,7 @@ static void start_pick_locked(void* arg, grpc_error* error) { switch (pick_result) { case LoadBalancingPolicy::PICK_TRANSIENT_FAILURE: { // If we're shutting down, fail all RPCs. - grpc_error* disconnect_error = - chand->disconnect_error.Load(grpc_core::MemoryOrder::ACQUIRE); + grpc_error* disconnect_error = chand->disconnect_error(); if (disconnect_error != GRPC_ERROR_NONE) { GRPC_ERROR_UNREF(error); GRPC_CLOSURE_SCHED(&calld->pick_closure, @@ -2976,8 +3089,8 @@ static void cc_start_transport_stream_op_batch( grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { GPR_TIMER_SCOPE("cc_start_transport_stream_op_batch", 0); call_data* calld = static_cast(elem->call_data); - channel_data* chand = static_cast(elem->channel_data); - if (GPR_LIKELY(chand->deadline_checking_enabled)) { + ChannelData* chand = static_cast(elem->channel_data); + if (GPR_LIKELY(chand->deadline_checking_enabled())) { grpc_deadline_state_client_start_transport_stream_op_batch(elem, batch); } // If we've previously been cancelled, immediately fail any new batches. @@ -3046,9 +3159,9 @@ static void cc_start_transport_stream_op_batch( chand, calld); } GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_INIT(&batch->handler_private.closure, start_pick_locked, - elem, - grpc_combiner_scheduler(chand->data_plane_combiner)), + GRPC_CLOSURE_INIT( + &batch->handler_private.closure, start_pick_locked, elem, + grpc_combiner_scheduler(chand->data_plane_combiner())), GRPC_ERROR_NONE); } else { // For all other batches, release the call combiner. @@ -3065,7 +3178,7 @@ static void cc_start_transport_stream_op_batch( /* Constructor for call_data */ static grpc_error* cc_init_call_elem(grpc_call_element* elem, const grpc_call_element_args* args) { - channel_data* chand = static_cast(elem->channel_data); + ChannelData* chand = static_cast(elem->channel_data); new (elem->call_data) call_data(elem, *chand, *args); return GRPC_ERROR_NONE; } @@ -3095,74 +3208,51 @@ static void cc_set_pollset_or_pollset_set(grpc_call_element* elem, const grpc_channel_filter grpc_client_channel_filter = { cc_start_transport_stream_op_batch, - cc_start_transport_op, + ChannelData::StartTransportOp, sizeof(call_data), cc_init_call_elem, cc_set_pollset_or_pollset_set, cc_destroy_call_elem, - sizeof(channel_data), - cc_init_channel_elem, - cc_destroy_channel_elem, - cc_get_channel_info, + sizeof(ChannelData), + ChannelData::Init, + ChannelData::Destroy, + ChannelData::GetChannelInfo, "client-channel", }; -// -// functions exported to the rest of core -// - 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()); + auto* chand = static_cast(elem->channel_data); + chand->set_channelz_node(node); } void grpc_client_channel_populate_child_refs( grpc_channel_element* elem, 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); - } -} - -static void try_to_connect_locked(void* arg, grpc_error* error_ignored) { - channel_data* chand = static_cast(arg); - chand->resolving_lb_policy->ExitIdleLocked(); - GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "try_to_connect"); + auto* chand = static_cast(elem->channel_data); + chand->FillChildRefsForChannelz(child_subchannels, child_channels); } 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); - if (out == GRPC_CHANNEL_IDLE && try_to_connect) { - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "try_to_connect"); - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(try_to_connect_locked, chand, - grpc_combiner_scheduler(chand->combiner)), - GRPC_ERROR_NONE); - } - return out; + auto* chand = static_cast(elem->channel_data); + return chand->CheckConnectivityState(try_to_connect); } int grpc_client_channel_num_external_connectivity_watchers( grpc_channel_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - return chand->external_connectivity_watcher_list->size(); + auto* chand = static_cast(elem->channel_data); + return chand->NumExternalConnectivityWatchers(); } void grpc_client_channel_watch_connectivity_state( grpc_channel_element* elem, grpc_polling_entity pollent, grpc_connectivity_state* state, grpc_closure* closure, grpc_closure* watcher_timer_init) { - channel_data* chand = static_cast(elem->channel_data); - grpc_core::New( - chand, pollent, state, closure, watcher_timer_init); + auto* chand = static_cast(elem->channel_data); + return chand->AddExternalConnectivityWatcher(pollent, state, closure, + watcher_timer_init); } grpc_core::RefCountedPtr 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 1ae3faa9e73..a7a47e9eb10 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -49,8 +49,8 @@ ClientChannelNode::ClientChannelNode(grpc_channel* channel, : ChannelNode(channel, channel_tracer_max_nodes, is_top_level_channel) { client_channel_ = grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel)); - grpc_client_channel_set_channelz_node(client_channel_, this); GPR_ASSERT(client_channel_->filter == &grpc_client_channel_filter); + grpc_client_channel_set_channelz_node(client_channel_, this); } void ClientChannelNode::PopulateConnectivityState(grpc_json* json) { From 75e7e189274cde98c2efdf4d83ffa11f8bb97b8a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 15 Apr 2019 14:36:41 -0700 Subject: [PATCH 1866/2143] Fix concurrent writer dispatch queue --- src/objective-c/GRPCClient/GRPCCall.m | 1 + 1 file changed, 1 insertion(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index cd3db898985..245a5e9ba02 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -191,6 +191,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; callSafety:_requestOptions.safety requestsWriter:_pipe callOptions:_callOptions]; + [_call setResponseDispatchQueue:_dispatchQueue]; if (_callOptions.initialMetadata) { [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata]; } From b416019f72a1b56ba11e60021d69bea9b4d42484 Mon Sep 17 00:00:00 2001 From: SataQiu Date: Tue, 16 Apr 2019 11:45:42 +0800 Subject: [PATCH 1867/2143] fix spelling errors of include/* --- include/grpc/grpc_security.h | 2 +- include/grpc/slice.h | 2 +- include/grpcpp/impl/codegen/completion_queue.h | 10 +++++----- include/grpcpp/impl/codegen/server_interface.h | 2 +- include/grpcpp/impl/codegen/sync_stream.h | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index f1185d2b2a6..53189097b9b 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -264,7 +264,7 @@ GRPCAPI grpc_call_credentials* grpc_google_refresh_token_credentials_create( const char* json_refresh_token, void* reserved); /** Creates an Oauth2 Access Token credentials with an access token that was - aquired by an out of band mechanism. */ + acquired by an out of band mechanism. */ GRPCAPI grpc_call_credentials* grpc_access_token_credentials_create( const char* access_token, void* reserved); diff --git a/include/grpc/slice.h b/include/grpc/slice.h index ce482922afa..192a8cfeef4 100644 --- a/include/grpc/slice.h +++ b/include/grpc/slice.h @@ -147,7 +147,7 @@ GPRAPI int grpc_slice_buf_start_eq(grpc_slice a, const void* b, size_t blen); GPRAPI int grpc_slice_rchr(grpc_slice s, char c); GPRAPI int grpc_slice_chr(grpc_slice s, char c); -/** return the index of the first occurance of \a needle in \a haystack, or -1 +/** return the index of the first occurrence of \a needle in \a haystack, or -1 if it's not found */ GPRAPI int grpc_slice_slice(grpc_slice haystack, grpc_slice needle); diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 73556ce9899..49c281b807d 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -183,8 +183,8 @@ class CompletionQueue : private GrpcLibraryCodegen { /// within the \a deadline). A \a tag points to an arbitrary location usually /// employed to uniquely identify an event. /// - /// \param tag [out] Upon sucess, updated to point to the event's tag. - /// \param ok [out] Upon sucess, true if a successful event, false otherwise + /// \param tag [out] Upon success, updated to point to the event's tag. + /// \param ok [out] Upon success, true if a successful event, false otherwise /// See documentation for CompletionQueue::Next for explanation of ok /// \param deadline [in] How long to block in wait for an event. /// @@ -203,8 +203,8 @@ class CompletionQueue : private GrpcLibraryCodegen { /// employed to uniquely identify an event. /// /// \param f [in] Function to execute before calling AsyncNext on this queue. - /// \param tag [out] Upon sucess, updated to point to the event's tag. - /// \param ok [out] Upon sucess, true if read a regular event, false + /// \param tag [out] Upon success, updated to point to the event's tag. + /// \param ok [out] Upon success, true if read a regular event, false /// otherwise. /// \param deadline [in] How long to block in wait for an event. /// @@ -362,7 +362,7 @@ class CompletionQueue : private GrpcLibraryCodegen { /// queue should not really shutdown until all avalanching operations have /// been finalized. Note that we maintain the requirement that an avalanche /// registration must take place before CQ shutdown (which must be maintained - /// elsehwere) + /// elsewhere) void InitialAvalanching() { gpr_atm_rel_store(&avalanches_in_flight_, static_cast(1)); } diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index a0b0a580979..328f4389628 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -149,7 +149,7 @@ class ServerInterface : public internal::CallHook { /// 192.168.1.1:31416, [::1]:27182, etc.). /// \params creds The credentials associated with the server. /// - /// \return bound port number on sucess, 0 on failure. + /// \return bound port number on success, 0 on failure. /// /// \warning It's an error to call this method on an already started server. virtual int AddListeningPort(const grpc::string& addr, diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index d9edad42153..0d3fdfcb8dc 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -180,7 +180,7 @@ class ClientReader final : public ClientReaderInterface { /// // Side effect: /// Once complete, the initial metadata read from - /// the server will be accessable through the \a ClientContext used to + /// the server will be accessible through the \a ClientContext used to /// construct this object. void WaitForInitialMetadata() override { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -298,7 +298,7 @@ class ClientWriter : public ClientWriterInterface { /// // Side effect: /// Once complete, the initial metadata read from the server will be - /// accessable through the \a ClientContext used to construct this object. + /// accessible through the \a ClientContext used to construct this object. void WaitForInitialMetadata() { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -449,7 +449,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { /// with or after the \a Finish method. /// /// Once complete, the initial metadata read from the server will be - /// accessable through the \a ClientContext used to construct this object. + /// accessible through the \a ClientContext used to construct this object. void WaitForInitialMetadata() override { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); From e9ecccaf03838c63ae2c3ec2cb52886f7e16c08e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 16 Apr 2019 08:46:29 -0700 Subject: [PATCH 1868/2143] Add test case for async dispatch --- src/objective-c/tests/InteropTests.m | 46 ++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index b6bc3f4bc7f..d5429bf302d 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -229,6 +229,52 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +// Test that responses can be dispatched even if we do not run main run-loop +- (void)testAsyncDispatchWithV2API { + XCTAssertNotNil([[self class] host]); + + GPBEmpty *request = [GPBEmpty message]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + + __block BOOL messageReceived = NO; + __block BOOL done = NO; + NSCondition *cond = [[NSCondition alloc] init]; + GRPCUnaryProtoCall *call = [_service + emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + if (message) { + id expectedResponse = [GPBEmpty message]; + XCTAssertEqualObjects(message, expectedResponse); + [cond lock]; + messageReceived = YES; + [cond unlock]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + [cond lock]; + done = YES; + [cond signal]; + [cond unlock]; + }] + callOptions:options]; + + NSDate *deadline = [NSDate dateWithTimeIntervalSinceNow:TEST_TIMEOUT]; + [call start]; + + [cond lock]; + while (!done && [deadline timeIntervalSinceNow] > 0) { + [cond waitUntilDate:deadline]; + } + XCTAssertTrue(messageReceived); + XCTAssertTrue(done); + [cond unlock]; +} + - (void)testLargeUnaryRPC { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; From ef4508ca0d9ce71dc6140b0b599758ddef5e350d Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Tue, 16 Apr 2019 11:09:30 -0700 Subject: [PATCH 1869/2143] fix memory leaks in ssl credential reload. --- CMakeLists.txt | 36 + Makefile | 34 + .../ssl/ssl_security_connector.cc | 5 +- .../end2end/fixtures/h2_ssl_cred_reload.cc | 208 ++ test/core/end2end/gen_build_yaml.py | 1 + test/core/end2end/generate_tests.bzl | 2 + .../generated/sources_and_headers.json | 17 + tools/run_tests/generated/tests.json | 1775 +++++++++++++++++ 8 files changed, 2076 insertions(+), 2 deletions(-) create mode 100644 test/core/end2end/fixtures/h2_ssl_cred_reload.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e1bee493f8..f2a4f698255 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -484,6 +484,7 @@ 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_cred_reload_test) add_dependencies(buildtests_c h2_ssl_proxy_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c h2_uds_test) @@ -17679,6 +17680,41 @@ target_link_libraries(h2_ssl_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(h2_ssl_cred_reload_test + test/core/end2end/fixtures/h2_ssl_cred_reload.cc +) + + +target_include_directories(h2_ssl_cred_reload_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_ssl_cred_reload_test + ${_gRPC_ALLTARGETS_LIBRARIES} + end2end_tests + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_ssl_cred_reload_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_ssl_cred_reload_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(h2_ssl_proxy_test test/core/end2end/fixtures/h2_ssl_proxy.cc ) diff --git a/Makefile b/Makefile index 5c3e0614c7a..6f19cc8d76b 100644 --- a/Makefile +++ b/Makefile @@ -1316,6 +1316,7 @@ 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_cred_reload_test: $(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test h2_ssl_proxy_test: $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test h2_uds_test: $(BINDIR)/$(CONFIG)/h2_uds_test inproc_test: $(BINDIR)/$(CONFIG)/inproc_test @@ -1579,6 +1580,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test \ $(BINDIR)/$(CONFIG)/h2_spiffe_test \ $(BINDIR)/$(CONFIG)/h2_ssl_test \ + $(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test \ $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test \ $(BINDIR)/$(CONFIG)/h2_uds_test \ $(BINDIR)/$(CONFIG)/inproc_test \ @@ -20667,6 +20669,38 @@ endif endif +H2_SSL_CRED_RELOAD_TEST_SRC = \ + test/core/end2end/fixtures/h2_ssl_cred_reload.cc \ + +H2_SSL_CRED_RELOAD_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SSL_CRED_RELOAD_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test: $(H2_SSL_CRED_RELOAD_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_SSL_CRED_RELOAD_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_ssl_cred_reload_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_cred_reload.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_h2_ssl_cred_reload_test: $(H2_SSL_CRED_RELOAD_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(H2_SSL_CRED_RELOAD_TEST_OBJS:.o=.dep) +endif +endif + + H2_SSL_PROXY_TEST_SRC = \ test/core/end2end/fixtures/h2_ssl_proxy.cc \ 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 ad492f361aa..e76f4f15a7c 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 @@ -314,7 +314,6 @@ 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 = @@ -374,7 +373,9 @@ class grpc_ssl_server_security_connector 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); + grpc_tsi_ssl_pem_key_cert_pairs_destroy( + const_cast(options.pem_key_cert_pairs), + options.num_key_cert_pairs); gpr_free((void*)alpn_protocol_strings); if (result != TSI_OK) { diff --git a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc new file mode 100644 index 00000000000..04d876ce3cd --- /dev/null +++ b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc @@ -0,0 +1,208 @@ +/* + * + * 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 "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/security/credentials/credentials.h" +#include "test/core/end2end/data/ssl_test_data.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +typedef struct fullstack_secure_fixture_data { + char* localaddr; + bool server_credential_reloaded; +} fullstack_secure_fixture_data; + +static grpc_ssl_certificate_config_reload_status +ssl_server_certificate_config_callback( + void* user_data, grpc_ssl_server_certificate_config** config) { + if (config == nullptr) { + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL; + } + fullstack_secure_fixture_data* ffd = + static_cast(user_data); + if (!ffd->server_credential_reloaded) { + grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key, + test_server1_cert}; + *config = grpc_ssl_server_certificate_config_create(test_root_cert, + &pem_key_cert_pair, 1); + ffd->server_credential_reloaded = true; + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW; + } else { + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED; + } +} + +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 = + static_cast( + gpr_malloc(sizeof(fullstack_secure_fixture_data))); + 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); + } + ffd->server_credential_reloaded = false; + 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); + gpr_free(ffd->localaddr); + gpr_free(ffd); +} + +static void chttp2_init_client_simple_ssl_secure_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* client_args) { + grpc_channel_credentials* ssl_creds = + grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr); + 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_simple_ssl_secure_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* server_args) { + grpc_ssl_server_credentials_options* options = + grpc_ssl_server_credentials_create_options_using_config_fetcher( + GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, + ssl_server_certificate_config_callback, f->fixture_data); + grpc_server_credentials* ssl_creds = + grpc_ssl_server_credentials_create_with_options(options); + 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); +} + +/* All test configurations */ + +static grpc_end2end_test_config configs[] = { + {"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_simple_ssl_secure_fullstack, + chttp2_init_server_simple_ssl_secure_fullstack, + chttp2_tear_down_secure_fullstack}, +}; + +int main(int argc, char** argv) { + size_t i; + FILE* roots_file; + size_t roots_size = strlen(test_root_cert); + char* roots_filename; + + grpc::testing::TestEnvironment env(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 (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + + 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 231d2262a9d..7bb802aa6d5 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_ssl_cred_reload': default_secure_fixture_options, 'h2_spiffe': default_secure_fixture_options, 'h2_local_uds': local_fixture_options, 'h2_local_ipv4': local_fixture_options, diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 10b9314a84a..85faca16364 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_ssl_cred_reload": _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"]), @@ -150,6 +151,7 @@ END2END_NOSEC_FIXTURES = { client_channel = False, ), "h2_ssl": _fixture_options(secure = False), + "h2_ssl_cred_reload": _fixture_options(secure = False), "h2_ssl_proxy": _fixture_options(includes_proxy = True, secure = False), "h2_uds": _fixture_options( dns_resolver = False, diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index de84eb74b29..b41d10b61f3 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -5672,6 +5672,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "end2end_tests", + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "src": [ + "test/core/end2end/fixtures/h2_ssl_cred_reload.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "end2end_tests", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index cfeff6fa838..80392e00518 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -36867,6 +36867,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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_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_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "authority_not_supported" From 7095f5acbef42667bd59baf3a3ae9748bee44286 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 16 Apr 2019 11:27:31 -0700 Subject: [PATCH 1870/2143] Use requirements.bazel.txt to generate Python documents --- tools/distrib/python/docgen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/distrib/python/docgen.py b/tools/distrib/python/docgen.py index de47c00618d..67d0054656c 100755 --- a/tools/distrib/python/docgen.py +++ b/tools/distrib/python/docgen.py @@ -44,7 +44,7 @@ PROJECT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, '..', '..', '..')) CONFIG = args.config SETUP_PATH = os.path.join(PROJECT_ROOT, 'setup.py') -REQUIREMENTS_PATH = os.path.join(PROJECT_ROOT, 'requirements.txt') +REQUIREMENTS_PATH = os.path.join(PROJECT_ROOT, 'requirements.bazel.txt') DOC_PATH = os.path.join(PROJECT_ROOT, 'doc/build') INCLUDE_PATH = os.path.join(PROJECT_ROOT, 'include') LIBRARY_PATH = os.path.join(PROJECT_ROOT, 'libs/{}'.format(CONFIG)) From 541cb0047057a4d4d915d556c77e9fc610599f8c Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 25 Mar 2019 11:11:47 -0700 Subject: [PATCH 1871/2143] Add wait-for-ready example * With unit test * With Bazel integration * With REAME.md explaination --- examples/python/wait_for_ready/BUILD.bazel | 32 +++++ examples/python/wait_for_ready/README.md | 32 +++++ .../test/_wait_for_ready_example_test.py | 31 +++++ .../wait_for_ready/wait_for_ready_example.py | 112 ++++++++++++++++++ 4 files changed, 207 insertions(+) create mode 100644 examples/python/wait_for_ready/BUILD.bazel create mode 100644 examples/python/wait_for_ready/README.md create mode 100644 examples/python/wait_for_ready/test/_wait_for_ready_example_test.py create mode 100644 examples/python/wait_for_ready/wait_for_ready_example.py diff --git a/examples/python/wait_for_ready/BUILD.bazel b/examples/python/wait_for_ready/BUILD.bazel new file mode 100644 index 00000000000..70daf83d334 --- /dev/null +++ b/examples/python/wait_for_ready/BUILD.bazel @@ -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. + +load("@grpc_python_dependencies//:requirements.bzl", "requirement") + +py_library( + name = "wait_for_ready_example", + testonly = 1, + srcs = ["wait_for_ready_example.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//examples:py_helloworld", + ], +) + +py_test( + name = "test/_wait_for_ready_example_test", + srcs = ["test/_wait_for_ready_example_test.py"], + deps = [":wait_for_ready_example",], + size = "small", +) diff --git a/examples/python/wait_for_ready/README.md b/examples/python/wait_for_ready/README.md new file mode 100644 index 00000000000..5c9d19688e1 --- /dev/null +++ b/examples/python/wait_for_ready/README.md @@ -0,0 +1,32 @@ +# gRPC Python Example for Wait-for-ready + +The default behavior of an RPC will fail instantly if the server is not ready yet. This example demonstrates how to change that behavior. + + +### Definition of '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 transmitted promptly. By default, gRPC implementations SHOULD fail such RPCs immediately. This is known as "fail fast," but the usage of the term is historical. RPCs SHOULD NOT fail as a result of the channel being in other states (CONNECTING, READY, or IDLE). +> +> gRPC implementations MAY provide a per-RPC option to not fail RPCs as a result of the channel being in TRANSIENT_FAILURE state. Instead, the implementation queues the RPCs until the channel is READY. This is known as "wait for ready." The RPCs SHOULD still fail before READY if there are unrelated reasons, such as the channel is SHUTDOWN or the RPC's deadline is reached. +> +> From https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md + + +### Use cases for 'wait-for-ready' + +When developers spin up gRPC clients and servers at the same time, it is very like to fail first couple RPC calls due to unavailability of the server. If developers failed to prepare for this situation, the result can be catastrophic. But with 'wait-for-ready' semantics, developers can initialize the client and server in any order, especially useful in testing. + +Also, developers may ensure the server is up before starting client. But in some cases like transient network failure may result in a temporary unavailability of the server. With 'wait-for-ready' semantics, those RPC calls will automatically wait until the server is ready to accept incoming requests. + + +### DEMO Snippets + +```Python +# Per RPC level +stub = ...Stub(...) + +stub.important_transaction_1(..., wait_for_ready=True) +stub.unimportant_transaction_2(...) +stub.important_transaction_3(..., wait_for_ready=True) +stub.unimportant_transaction_4(...) +# The unimportant transactions can be status report, or health check, etc. +``` diff --git a/examples/python/wait_for_ready/test/_wait_for_ready_example_test.py b/examples/python/wait_for_ready/test/_wait_for_ready_example_test.py new file mode 100644 index 00000000000..03e83a12c56 --- /dev/null +++ b/examples/python/wait_for_ready/test/_wait_for_ready_example_test.py @@ -0,0 +1,31 @@ +# 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. +"""Tests of the wait-for-ready example.""" + +import unittest +import logging + +from examples.python.wait_for_ready import wait_for_ready_example + + +class WaitForReadyExampleTest(unittest.TestCase): + + def test_wait_for_ready_example(self): + wait_for_ready_example.main() + # No unhandled exception raised, no deadlock, test passed! + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py new file mode 100644 index 00000000000..91d5a7c50cd --- /dev/null +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -0,0 +1,112 @@ +# 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. +"""The Python example of utilizing wait-for-ready flag.""" + +from __future__ import print_function +import logging +from concurrent import futures +import socket +import threading + +import grpc + +from examples.protos import helloworld_pb2 +from examples.protos import helloworld_pb2_grpc + +_LOGGER = logging.getLogger(__name__) +_LOGGER.setLevel(logging.INFO) + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +def get_free_loopback_tcp_port(): + tcp = socket.socket(socket.AF_INET6) + tcp.bind(('', 0)) + address_tuple = tcp.getsockname() + return tcp, "[::1]:%s" % (address_tuple[1]) + + +class Greeter(helloworld_pb2_grpc.GreeterServicer): + + def SayHello(self, request, unused_context): + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def create_server(server_address): + server = grpc.server(futures.ThreadPoolExecutor()) + helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) + bound_port = server.add_insecure_port(server_address) + assert bound_port == int(server_address.split(':')[-1]) + return server + + +def process(stub, wait_for_ready=None): + try: + response = stub.SayHello( + helloworld_pb2.HelloRequest(name='you'), + wait_for_ready=wait_for_ready) + message = response.message + except grpc.RpcError as rpc_error: + assert rpc_error.code() == grpc.StatusCode.UNAVAILABLE + assert not wait_for_ready + message = rpc_error + else: + assert wait_for_ready + _LOGGER.info("Wait-for-ready %s, client received: %s", "enabled" + if wait_for_ready else "disabled", message) + + +def main(): + # Pick a random free port + tcp, server_address = get_free_loopback_tcp_port() + + # Register connectivity event to notify main thread + transient_failure_event = threading.Event() + + def wait_for_transient_failure(channel_connectivity): + if channel_connectivity == grpc.ChannelConnectivity.TRANSIENT_FAILURE: + transient_failure_event.set() + + # Create gRPC channel + channel = grpc.insecure_channel(server_address) + channel.subscribe(wait_for_transient_failure) + stub = helloworld_pb2_grpc.GreeterStub(channel) + + # Fire an RPC without wait_for_ready + thread_disabled_wait_for_ready = threading.Thread( + target=process, args=(stub, False)) + thread_disabled_wait_for_ready.start() + # Fire an RPC with wait_for_ready + thread_enabled_wait_for_ready = threading.Thread( + target=process, args=(stub, True)) + thread_enabled_wait_for_ready.start() + + # Wait for the channel entering TRANSIENT FAILURE state. + tcp.close() + transient_failure_event.wait() + server = create_server(server_address) + server.start() + + # Expected to fail with StatusCode.UNAVAILABLE. + thread_disabled_wait_for_ready.join() + # Expected to success. + thread_enabled_wait_for_ready.join() + + server.stop(None) + channel.close() + + +if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + main() From f062722c6187fa5ec4c28a564465dc13c164c0df Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 16 Apr 2019 13:44:46 -0700 Subject: [PATCH 1872/2143] Adopt reviewer's advice * Use context manager to manage tcp socket * Rename tcp socket * Fix grammer error --- examples/python/wait_for_ready/README.md | 2 +- .../wait_for_ready/wait_for_ready_example.py | 48 ++++++++++--------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/examples/python/wait_for_ready/README.md b/examples/python/wait_for_ready/README.md index 5c9d19688e1..6e873d2222d 100644 --- a/examples/python/wait_for_ready/README.md +++ b/examples/python/wait_for_ready/README.md @@ -1,6 +1,6 @@ # gRPC Python Example for Wait-for-ready -The default behavior of an RPC will fail instantly if the server is not ready yet. This example demonstrates how to change that behavior. +The default behavior of an RPC is to fail instantly if the server is not ready yet. This example demonstrates how to change that behavior. ### Definition of 'wait-for-ready' semantics diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py index 91d5a7c50cd..7c16b9bd4a1 100644 --- a/examples/python/wait_for_ready/wait_for_ready_example.py +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -16,6 +16,7 @@ from __future__ import print_function import logging from concurrent import futures +from contextlib import contextmanager import socket import threading @@ -30,11 +31,13 @@ _LOGGER.setLevel(logging.INFO) _ONE_DAY_IN_SECONDS = 60 * 60 * 24 +@contextmanager def get_free_loopback_tcp_port(): - tcp = socket.socket(socket.AF_INET6) - tcp.bind(('', 0)) - address_tuple = tcp.getsockname() - return tcp, "[::1]:%s" % (address_tuple[1]) + tcp_socket = socket.socket(socket.AF_INET6) + tcp_socket.bind(('', 0)) + address_tuple = tcp_socket.getsockname() + yield "[::1]:%s" % (address_tuple[1]) + tcp_socket.close() class Greeter(helloworld_pb2_grpc.GreeterServicer): @@ -69,31 +72,30 @@ def process(stub, wait_for_ready=None): def main(): # Pick a random free port - tcp, server_address = get_free_loopback_tcp_port() + with get_free_loopback_tcp_port() as server_address: - # Register connectivity event to notify main thread - transient_failure_event = threading.Event() + # Register connectivity event to notify main thread + transient_failure_event = threading.Event() - def wait_for_transient_failure(channel_connectivity): - if channel_connectivity == grpc.ChannelConnectivity.TRANSIENT_FAILURE: - transient_failure_event.set() + def wait_for_transient_failure(channel_connectivity): + if channel_connectivity == grpc.ChannelConnectivity.TRANSIENT_FAILURE: + transient_failure_event.set() - # Create gRPC channel - channel = grpc.insecure_channel(server_address) - channel.subscribe(wait_for_transient_failure) - stub = helloworld_pb2_grpc.GreeterStub(channel) + # Create gRPC channel + channel = grpc.insecure_channel(server_address) + channel.subscribe(wait_for_transient_failure) + stub = helloworld_pb2_grpc.GreeterStub(channel) - # Fire an RPC without wait_for_ready - thread_disabled_wait_for_ready = threading.Thread( - target=process, args=(stub, False)) - thread_disabled_wait_for_ready.start() - # Fire an RPC with wait_for_ready - thread_enabled_wait_for_ready = threading.Thread( - target=process, args=(stub, True)) - thread_enabled_wait_for_ready.start() + # Fire an RPC without wait_for_ready + thread_disabled_wait_for_ready = threading.Thread( + target=process, args=(stub, False)) + thread_disabled_wait_for_ready.start() + # Fire an RPC with wait_for_ready + thread_enabled_wait_for_ready = threading.Thread( + target=process, args=(stub, True)) + thread_enabled_wait_for_ready.start() # Wait for the channel entering TRANSIENT FAILURE state. - tcp.close() transient_failure_event.wait() server = create_server(server_address) server.start() From 123fd943f130779e2e200b1c3227e54bce0ef4b1 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 16 Apr 2019 14:13:04 -0700 Subject: [PATCH 1873/2143] Revert "Revert "Merge pull request #18547 from lidizheng/fix-gevent"" This reverts commit a922bd7a03a35af0aaceb8f79e71f234e3fb418c. --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 8 ++- src/core/lib/iomgr/iomgr_custom.cc | 3 + src/core/lib/iomgr/iomgr_custom.h | 2 + src/python/grpcio_tests/commands.py | 8 ++- src/python/grpcio_tests/tests/tests.json | 1 + .../grpcio_tests/tests/unit/BUILD.bazel | 1 + .../tests/unit/_dns_resolver_test.py | 63 +++++++++++++++++++ 7 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 src/python/grpcio_tests/tests/unit/_dns_resolver_test.py 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 7b5eb311393..6994f63bee4 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 @@ -43,6 +43,7 @@ #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/gethostname.h" +#include "src/core/lib/iomgr/iomgr_custom.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/json/json.h" @@ -430,8 +431,11 @@ 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; + // TODO(lidiz): Remove the "g_custom_iomgr_enabled" flag once c-ares support + // custom IO managers (e.g. gevent). + return !g_custom_iomgr_enabled && + (resolver_env == nullptr || strlen(resolver_env) == 0 || + gpr_stricmp(resolver_env, "ares") == 0); } void grpc_resolver_dns_ares_init() { diff --git a/src/core/lib/iomgr/iomgr_custom.cc b/src/core/lib/iomgr/iomgr_custom.cc index 56363c35fd6..f5ac8a0670a 100644 --- a/src/core/lib/iomgr/iomgr_custom.cc +++ b/src/core/lib/iomgr/iomgr_custom.cc @@ -49,6 +49,8 @@ static bool iomgr_platform_add_closure_to_background_poller( return false; } +bool g_custom_iomgr_enabled = false; + static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, @@ -61,6 +63,7 @@ void grpc_custom_iomgr_init(grpc_socket_vtable* socket, grpc_custom_resolver_vtable* resolver, grpc_custom_timer_vtable* timer, grpc_custom_poller_vtable* poller) { + g_custom_iomgr_enabled = true; grpc_custom_endpoint_init(socket); grpc_custom_timer_init(timer); grpc_custom_pollset_init(poller); diff --git a/src/core/lib/iomgr/iomgr_custom.h b/src/core/lib/iomgr/iomgr_custom.h index 57cc2f9b923..e6a88843e5c 100644 --- a/src/core/lib/iomgr/iomgr_custom.h +++ b/src/core/lib/iomgr/iomgr_custom.h @@ -39,6 +39,8 @@ extern gpr_thd_id g_init_thread; #define GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD() #endif /* GRPC_CUSTOM_IOMGR_THREAD_CHECK */ +extern bool g_custom_iomgr_enabled; + void grpc_custom_iomgr_init(grpc_socket_vtable* socket, grpc_custom_resolver_vtable* resolver, grpc_custom_timer_vtable* timer, diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index e9b6333c891..dc0795d4a12 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -154,6 +154,9 @@ class TestGevent(setuptools.Command): # TODO(https://github.com/grpc/grpc/issues/15411) enable this test 'unit._cython._channel_test.ChannelTest.test_negative_deadline_connectivity' ) + BANNED_WINDOWS_TESTS = ( + # TODO(https://github.com/grpc/grpc/pull/15411) enable this test + 'unit._dns_resolver_test.DNSResolverTest.test_connect_loopback',) description = 'run tests with gevent. Assumes grpc/gevent are installed' user_options = [] @@ -179,7 +182,10 @@ class TestGevent(setuptools.Command): loader = tests.Loader() loader.loadTestsFromNames(['tests']) runner = tests.Runner() - runner.skip_tests(self.BANNED_TESTS) + if sys.platform == 'win32': + runner.skip_tests(self.BANNED_TESTS + self.BANNED_WINDOWS_TESTS) + else: + runner.skip_tests(self.BANNED_TESTS) result = gevent.spawn(runner.run, loader.suite) result.join() if not result.value.wasSuccessful(): diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index 7729ca01d53..cc08d56248a 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -46,6 +46,7 @@ "unit._cython.cygrpc_test.InsecureServerInsecureClient", "unit._cython.cygrpc_test.SecureServerSecureClient", "unit._cython.cygrpc_test.TypeSmokeTest", + "unit._dns_resolver_test.DNSResolverTest", "unit._empty_message_test.EmptyMessageTest", "unit._error_message_encoding_test.ErrorMessageEncodingTest", "unit._exit_test.ExitTest", diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel index 04f91e63a18..a161794f8be 100644 --- a/src/python/grpcio_tests/tests/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel @@ -14,6 +14,7 @@ GRPCIO_TESTS_UNIT = [ "_channel_ready_future_test.py", "_compression_test.py", "_credentials_test.py", + "_dns_resolver_test.py", "_empty_message_test.py", "_exit_test.py", "_interceptor_test.py", diff --git a/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py b/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py new file mode 100644 index 00000000000..d119707b19d --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py @@ -0,0 +1,63 @@ +# 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. +"""Tests for an actual dns resolution.""" + +import unittest +import logging +import six + +import grpc +from tests.unit import test_common +from tests.unit.framework.common import test_constants + +_METHOD = '/ANY/METHOD' +_REQUEST = b'\x00\x00\x00' +_RESPONSE = _REQUEST + + +class GenericHandler(grpc.GenericRpcHandler): + + def service(self, unused_handler_details): + return grpc.unary_unary_rpc_method_handler( + lambda request, unused_context: request, + ) + + +class DNSResolverTest(unittest.TestCase): + + def setUp(self): + self._server = test_common.test_server() + self._server.add_generic_rpc_handlers((GenericHandler(),)) + self._port = self._server.add_insecure_port('[::]:0') + self._server.start() + + def tearDown(self): + self._server.stop(None) + + def test_connect_loopback(self): + # NOTE(https://github.com/grpc/grpc/issues/18422) + # In short, Gevent + C-Ares = Segfault. The C-Ares driver is not + # supported by custom io manager like "gevent" or "libuv". + with grpc.insecure_channel( + 'loopback4.unittest.grpc.io:%d' % self._port) as channel: + self.assertEqual( + channel.unary_unary(_METHOD)( + _REQUEST, + timeout=test_constants.SHORT_TIMEOUT, + ), _RESPONSE) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) From 09d18aa6592b14950042e22ab4354bc1de6d074c Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 16 Apr 2019 15:30:48 -0700 Subject: [PATCH 1874/2143] Propagate KeyboardInterrupt above completion queue --- src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi | 2 +- src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi index 9f06ce086ee..0307f74cbef 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi @@ -13,7 +13,7 @@ # limitations under the License. -cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline) +cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline) except * cdef _interpret_event(grpc_event c_event) 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 212d27dc2b7..325e72afa0a 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi @@ -20,7 +20,7 @@ import time cdef int _INTERRUPT_CHECK_PERIOD_MS = 200 -cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline): +cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline) except *: cdef gpr_timespec c_increment cdef gpr_timespec c_timeout cdef gpr_timespec c_deadline From 6929cdd65454f0e77d5ad931209a4207ae15331c Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 16 Apr 2019 14:16:55 -0700 Subject: [PATCH 1875/2143] initial --- BUILD | 2 + BUILD.gn | 2 + CMakeLists.txt | 49 +++ Makefile | 56 +++ build.yaml | 15 + gRPC-C++.podspec | 2 + .../grpcpp/impl/codegen/message_allocator.h | 53 +++ .../grpcpp/impl/codegen/method_handler_impl.h | 12 +- .../grpcpp/impl/codegen/rpc_service_method.h | 8 +- include/grpcpp/impl/codegen/server_callback.h | 105 +++-- include/grpcpp/support/message_allocator.h | 24 ++ src/compiler/cpp_generator.cc | 20 +- src/cpp/server/server_cc.cc | 12 +- src/proto/grpc/testing/echo_messages.proto | 2 + test/cpp/end2end/BUILD | 20 + .../end2end/message_allocator_end2end_test.cc | 395 ++++++++++++++++++ tools/doxygen/Doxyfile.c++ | 2 + tools/doxygen/Doxyfile.c++.internal | 2 + .../generated/sources_and_headers.json | 22 + tools/run_tests/generated/tests.json | 24 ++ 20 files changed, 789 insertions(+), 38 deletions(-) create mode 100644 include/grpcpp/impl/codegen/message_allocator.h create mode 100644 include/grpcpp/support/message_allocator.h create mode 100644 test/cpp/end2end/message_allocator_end2end_test.cc diff --git a/BUILD b/BUILD index fd75012d214..ad040d1f924 100644 --- a/BUILD +++ b/BUILD @@ -268,6 +268,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", "include/grpcpp/support/interceptor.h", + "include/grpcpp/support/message_allocator.h", "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", @@ -2127,6 +2128,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/intercepted_channel.h", "include/grpcpp/impl/codegen/interceptor.h", "include/grpcpp/impl/codegen/interceptor_common.h", + "include/grpcpp/impl/codegen/message_allocator.h", "include/grpcpp/impl/codegen/metadata_map.h", "include/grpcpp/impl/codegen/method_handler_impl.h", "include/grpcpp/impl/codegen/rpc_method.h", diff --git a/BUILD.gn b/BUILD.gn index 21f567d9af4..6f1864a6d8c 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1047,6 +1047,7 @@ config("grpc_config") { "include/grpcpp/impl/codegen/intercepted_channel.h", "include/grpcpp/impl/codegen/interceptor.h", "include/grpcpp/impl/codegen/interceptor_common.h", + "include/grpcpp/impl/codegen/message_allocator.h", "include/grpcpp/impl/codegen/metadata_map.h", "include/grpcpp/impl/codegen/method_handler_impl.h", "include/grpcpp/impl/codegen/proto_buffer_reader.h", @@ -1101,6 +1102,7 @@ config("grpc_config") { "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", "include/grpcpp/support/interceptor.h", + "include/grpcpp/support/message_allocator.h", "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e1bee493f8..cfb5af701cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -660,6 +660,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx json_run_localhost) endif() add_dependencies(buildtests_cxx memory_test) +add_dependencies(buildtests_cxx message_allocator_end2end_test) add_dependencies(buildtests_cxx metrics_client) add_dependencies(buildtests_cxx mock_test) add_dependencies(buildtests_cxx nonblocking_test) @@ -3053,6 +3054,7 @@ foreach(_hdr include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h include/grpcpp/support/interceptor.h + include/grpcpp/support/message_allocator.h include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h @@ -3168,6 +3170,7 @@ foreach(_hdr include/grpcpp/impl/codegen/intercepted_channel.h include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/interceptor_common.h + include/grpcpp/impl/codegen/message_allocator.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -3656,6 +3659,7 @@ foreach(_hdr include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h include/grpcpp/support/interceptor.h + include/grpcpp/support/message_allocator.h include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h @@ -3771,6 +3775,7 @@ foreach(_hdr include/grpcpp/impl/codegen/intercepted_channel.h include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/interceptor_common.h + include/grpcpp/impl/codegen/message_allocator.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -4203,6 +4208,7 @@ foreach(_hdr include/grpcpp/impl/codegen/intercepted_channel.h include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/interceptor_common.h + include/grpcpp/impl/codegen/message_allocator.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -4399,6 +4405,7 @@ foreach(_hdr include/grpcpp/impl/codegen/intercepted_channel.h include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/interceptor_common.h + include/grpcpp/impl/codegen/message_allocator.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -4632,6 +4639,7 @@ foreach(_hdr include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h include/grpcpp/support/interceptor.h + include/grpcpp/support/message_allocator.h include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h @@ -4747,6 +4755,7 @@ foreach(_hdr include/grpcpp/impl/codegen/intercepted_channel.h include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/interceptor_common.h + include/grpcpp/impl/codegen/message_allocator.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -14495,6 +14504,46 @@ target_link_libraries(memory_test ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(message_allocator_end2end_test + test/cpp/end2end/message_allocator_end2end_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(message_allocator_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(message_allocator_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) diff --git a/Makefile b/Makefile index 5c3e0614c7a..235ec8297d8 100644 --- a/Makefile +++ b/Makefile @@ -1233,6 +1233,7 @@ interop_server: $(BINDIR)/$(CONFIG)/interop_server interop_test: $(BINDIR)/$(CONFIG)/interop_test json_run_localhost: $(BINDIR)/$(CONFIG)/json_run_localhost memory_test: $(BINDIR)/$(CONFIG)/memory_test +message_allocator_end2end_test: $(BINDIR)/$(CONFIG)/message_allocator_end2end_test metrics_client: $(BINDIR)/$(CONFIG)/metrics_client mock_test: $(BINDIR)/$(CONFIG)/mock_test nonblocking_test: $(BINDIR)/$(CONFIG)/nonblocking_test @@ -1699,6 +1700,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/interop_test \ $(BINDIR)/$(CONFIG)/json_run_localhost \ $(BINDIR)/$(CONFIG)/memory_test \ + $(BINDIR)/$(CONFIG)/message_allocator_end2end_test \ $(BINDIR)/$(CONFIG)/metrics_client \ $(BINDIR)/$(CONFIG)/mock_test \ $(BINDIR)/$(CONFIG)/nonblocking_test \ @@ -1842,6 +1844,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/interop_test \ $(BINDIR)/$(CONFIG)/json_run_localhost \ $(BINDIR)/$(CONFIG)/memory_test \ + $(BINDIR)/$(CONFIG)/message_allocator_end2end_test \ $(BINDIR)/$(CONFIG)/metrics_client \ $(BINDIR)/$(CONFIG)/mock_test \ $(BINDIR)/$(CONFIG)/nonblocking_test \ @@ -2341,6 +2344,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/interop_test || ( echo test interop_test failed ; exit 1 ) $(E) "[RUN] Testing memory_test" $(Q) $(BINDIR)/$(CONFIG)/memory_test || ( echo test memory_test failed ; exit 1 ) + $(E) "[RUN] Testing message_allocator_end2end_test" + $(Q) $(BINDIR)/$(CONFIG)/message_allocator_end2end_test || ( echo test message_allocator_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing mock_test" $(Q) $(BINDIR)/$(CONFIG)/mock_test || ( echo test mock_test failed ; exit 1 ) $(E) "[RUN] Testing nonblocking_test" @@ -5388,6 +5393,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ include/grpcpp/support/interceptor.h \ + include/grpcpp/support/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ @@ -5503,6 +5509,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/intercepted_channel.h \ include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/interceptor_common.h \ + include/grpcpp/impl/codegen/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -5999,6 +6006,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ include/grpcpp/support/interceptor.h \ + include/grpcpp/support/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ @@ -6114,6 +6122,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/intercepted_channel.h \ include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/interceptor_common.h \ + include/grpcpp/impl/codegen/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6518,6 +6527,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/intercepted_channel.h \ include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/interceptor_common.h \ + include/grpcpp/impl/codegen/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6685,6 +6695,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/intercepted_channel.h \ include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/interceptor_common.h \ + include/grpcpp/impl/codegen/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6924,6 +6935,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ include/grpcpp/support/interceptor.h \ + include/grpcpp/support/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ @@ -7039,6 +7051,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/intercepted_channel.h \ include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/interceptor_common.h \ + include/grpcpp/impl/codegen/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -17400,6 +17413,49 @@ endif endif +MESSAGE_ALLOCATOR_END2END_TEST_SRC = \ + test/cpp/end2end/message_allocator_end2end_test.cc \ + +MESSAGE_ALLOCATOR_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MESSAGE_ALLOCATOR_END2END_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/message_allocator_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)/message_allocator_end2end_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/message_allocator_end2end_test: $(PROTOBUF_DEP) $(MESSAGE_ALLOCATOR_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) $(MESSAGE_ALLOCATOR_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)/message_allocator_end2end_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/message_allocator_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_message_allocator_end2end_test: $(MESSAGE_ALLOCATOR_END2END_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(MESSAGE_ALLOCATOR_END2END_TEST_OBJS:.o=.dep) +endif +endif + + METRICS_CLIENT_SRC = \ $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc \ test/cpp/interop/metrics_client.cc \ diff --git a/build.yaml b/build.yaml index 6683db05fd4..efc89c7594c 100644 --- a/build.yaml +++ b/build.yaml @@ -1258,6 +1258,7 @@ filegroups: - include/grpcpp/impl/codegen/intercepted_channel.h - include/grpcpp/impl/codegen/interceptor.h - include/grpcpp/impl/codegen/interceptor_common.h + - include/grpcpp/impl/codegen/message_allocator.h - include/grpcpp/impl/codegen/metadata_map.h - include/grpcpp/impl/codegen/method_handler_impl.h - include/grpcpp/impl/codegen/rpc_method.h @@ -1395,6 +1396,7 @@ filegroups: - include/grpcpp/support/client_interceptor.h - include/grpcpp/support/config.h - include/grpcpp/support/interceptor.h + - include/grpcpp/support/message_allocator.h - include/grpcpp/support/proto_buffer_reader.h - include/grpcpp/support/proto_buffer_writer.h - include/grpcpp/support/server_callback.h @@ -5063,6 +5065,19 @@ targets: uses: - grpc++_test uses_polling: false +- name: message_allocator_end2end_test + gtest: true + cpu_cost: 0.5 + build: test + language: c++ + src: + - test/cpp/end2end/message_allocator_end2end_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr - name: metrics_client build: test run: false diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 4d858ab6c77..1c4c7e48d91 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -132,6 +132,7 @@ Pod::Spec.new do |s| 'include/grpcpp/support/client_interceptor.h', 'include/grpcpp/support/config.h', 'include/grpcpp/support/interceptor.h', + 'include/grpcpp/support/message_allocator.h', 'include/grpcpp/support/proto_buffer_reader.h', 'include/grpcpp/support/proto_buffer_writer.h', 'include/grpcpp/support/server_callback.h', @@ -166,6 +167,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/intercepted_channel.h', 'include/grpcpp/impl/codegen/interceptor.h', 'include/grpcpp/impl/codegen/interceptor_common.h', + 'include/grpcpp/impl/codegen/message_allocator.h', 'include/grpcpp/impl/codegen/metadata_map.h', 'include/grpcpp/impl/codegen/method_handler_impl.h', 'include/grpcpp/impl/codegen/rpc_method.h', diff --git a/include/grpcpp/impl/codegen/message_allocator.h b/include/grpcpp/impl/codegen/message_allocator.h new file mode 100644 index 00000000000..8f37d36eb8b --- /dev/null +++ b/include/grpcpp/impl/codegen/message_allocator.h @@ -0,0 +1,53 @@ +/* + * + * 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_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H_ +#define GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H_ + +namespace grpc { + +// This is per rpc struct for the allocator. We can potentially put the grpc +// call arena in here in the future. +template +struct RpcAllocatorInfo { + RequestT* request = nullptr; + ResponseT* response = nullptr; + // per rpc allocator internal state. MessageAllocator can set it when + // AllocateMessages is called and use it later. + void* allocator_state = nullptr; +}; + +// Implementations need to be thread-safe +template +class MessageAllocator { + public: + virtual ~MessageAllocator() = default; + // Allocate both request and response + virtual void AllocateMessages( + RpcAllocatorInfo* info) = 0; + // Optional: deallocate request early, called by + // ServerCallbackRpcController::ReleaseRequest + virtual void DeallocateRequest(RpcAllocatorInfo* info) {} + // Deallocate response and request (if applicable) + virtual void DeallocateMessages( + RpcAllocatorInfo* info) = 0; +}; + +} // namespace grpc + +#endif // GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H_ diff --git a/include/grpcpp/impl/codegen/method_handler_impl.h b/include/grpcpp/impl/codegen/method_handler_impl.h index 094286294c2..dee1cb56ad1 100644 --- a/include/grpcpp/impl/codegen/method_handler_impl.h +++ b/include/grpcpp/impl/codegen/method_handler_impl.h @@ -86,8 +86,8 @@ class RpcMethodHandler : public MethodHandler { param.call->cq()->Pluck(&ops); } - void* Deserialize(grpc_call* call, grpc_byte_buffer* req, - Status* status) final { + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, + void** handler_data) final { ByteBuffer buf; buf.set_buffer(req); auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc( @@ -191,8 +191,8 @@ class ServerStreamingHandler : public MethodHandler { param.call->cq()->Pluck(&ops); } - void* Deserialize(grpc_call* call, grpc_byte_buffer* req, - Status* status) final { + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, + void** handler_data) final { ByteBuffer buf; buf.set_buffer(req); auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc( @@ -327,8 +327,8 @@ class ErrorMethodHandler : public MethodHandler { param.call->cq()->Pluck(&ops); } - void* Deserialize(grpc_call* call, grpc_byte_buffer* req, - Status* status) final { + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, + void** handler_data) final { // We have to destroy any request payload if (req != nullptr) { g_core_codegen_interface->grpc_byte_buffer_destroy(req); diff --git a/include/grpcpp/impl/codegen/rpc_service_method.h b/include/grpcpp/impl/codegen/rpc_service_method.h index 56df61cdfae..21fb2ac2130 100644 --- a/include/grpcpp/impl/codegen/rpc_service_method.h +++ b/include/grpcpp/impl/codegen/rpc_service_method.h @@ -46,21 +46,25 @@ 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 handler_data: internal data for the handler. /// \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, - Status req_status, std::function requester) + Status req_status, void* handler_data, + std::function requester) : call(c), server_context(context), request(req), status(req_status), + internal_data(handler_data), call_requester(std::move(requester)) {} ~HandlerParameter() {} Call* call; ServerContext* server_context; void* request; Status status; + void* internal_data; std::function call_requester; }; virtual void RunHandler(const HandlerParameter& param) = 0; @@ -71,7 +75,7 @@ class MethodHandler { pointer after calling RunHandler. Ownership of the deserialized request is retained by the handler. Returns nullptr if deserialization failed. */ virtual void* Deserialize(grpc_call* call, grpc_byte_buffer* req, - Status* status) { + Status* status, void** handler_data) { GPR_CODEGEN_ASSERT(req == nullptr); return nullptr; } diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index ce27b156283..030e4aea92a 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -135,6 +136,9 @@ class ServerCallbackRpcController { /// to be called before the callback completes. virtual void SetCancelCallback(std::function callback) = 0; virtual void ClearCancelCallback() = 0; + + virtual void FreeRequest() = 0; + virtual void* GetAllocatorState() = 0; }; // NOTE: The actual streaming object classes are provided @@ -445,19 +449,22 @@ class CallbackUnaryHandler : public MethodHandler { CallbackUnaryHandler( std::function - func) - : func_(func) {} + func, + MessageAllocator* allocator) + : func_(func), allocator_(allocator) {} + void RunHandler(const HandlerParameter& param) final { // Arena allocate a controller structure (that includes request/response) g_core_codegen_interface->grpc_call_ref(param.call->call()); + auto* allocator_info = + static_cast*>( + param.internal_data); auto* controller = new (g_core_codegen_interface->grpc_call_arena_alloc( param.call->call(), sizeof(ServerCallbackRpcControllerImpl))) - ServerCallbackRpcControllerImpl( - param.server_context, param.call, - static_cast(param.request), - std::move(param.call_requester)); + ServerCallbackRpcControllerImpl(param.server_context, param.call, + allocator_info, allocator_, + std::move(param.call_requester)); Status status = param.status; - if (status.ok()) { // Call the actual function handler and expect the user to call finish CatchingCallback(func_, param.server_context, controller->request(), @@ -468,18 +475,41 @@ class CallbackUnaryHandler : public MethodHandler { } } - void* Deserialize(grpc_call* call, grpc_byte_buffer* req, - Status* status) final { + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, + void** handler_data) final { ByteBuffer buf; buf.set_buffer(req); - auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc( - call, sizeof(RequestType))) RequestType(); + RequestType* request = nullptr; + RpcAllocatorInfo* allocator_info = + new (g_core_codegen_interface->grpc_call_arena_alloc( + call, sizeof(*allocator_info))) + RpcAllocatorInfo(); + if (allocator_ != nullptr) { + allocator_->AllocateMessages(allocator_info); + } else { + allocator_info->request = + new (g_core_codegen_interface->grpc_call_arena_alloc( + call, sizeof(RequestType))) RequestType(); + allocator_info->response = + new (g_core_codegen_interface->grpc_call_arena_alloc( + call, sizeof(ResponseType))) ResponseType(); + } + *handler_data = allocator_info; + request = allocator_info->request; *status = SerializationTraits::Deserialize(&buf, request); buf.Release(); if (status->ok()) { return request; } - request->~RequestType(); + // Clean up on deserialization failure. + if (allocator_ != nullptr) { + allocator_->DeallocateMessages(allocator_info); + } else { + allocator_info->request->~RequestType(); + allocator_info->response->~ResponseType(); + allocator_info->request = nullptr; + allocator_info->response = nullptr; + } return nullptr; } @@ -487,6 +517,7 @@ class CallbackUnaryHandler : public MethodHandler { std::function func_; + MessageAllocator* allocator_; // The implementation class of ServerCallbackRpcController is a private member // of CallbackUnaryHandler since it is never exposed anywhere, and this allows @@ -507,8 +538,9 @@ class CallbackUnaryHandler : public MethodHandler { } // The response is dropped if the status is not OK. if (s.ok()) { - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_ops_.SendMessagePtr(&resp_)); + finish_ops_.ServerSendStatus( + &ctx_->trailing_metadata_, + finish_ops_.SendMessagePtr(allocator_info_->response)); } else { finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); } @@ -546,29 +578,52 @@ class CallbackUnaryHandler : public MethodHandler { void ClearCancelCallback() override { ctx_->ClearCancelCallback(); } + void FreeRequest() override { + if (allocator_ != nullptr) { + allocator_->DeallocateRequest(allocator_info_); + } + } + + void* GetAllocatorState() override { + return allocator_info_->allocator_state; + } + private: friend class CallbackUnaryHandler; - ServerCallbackRpcControllerImpl(ServerContext* ctx, Call* call, - const RequestType* req, - std::function call_requester) + ServerCallbackRpcControllerImpl( + ServerContext* ctx, Call* call, + RpcAllocatorInfo* allocator_info, + MessageAllocator* allocator, + std::function call_requester) : ctx_(ctx), call_(*call), - req_(req), + allocator_info_(allocator_info), + allocator_(allocator), call_requester_(std::move(call_requester)) { ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, nullptr); } - ~ServerCallbackRpcControllerImpl() { req_->~RequestType(); } + ~ServerCallbackRpcControllerImpl() {} - const RequestType* request() { return req_; } - ResponseType* response() { return &resp_; } + const RequestType* request() { return allocator_info_->request; } + ResponseType* response() { return allocator_info_->response; } void MaybeDone() { if (--callbacks_outstanding_ == 0) { grpc_call* call = call_.call(); auto call_requester = std::move(call_requester_); this->~ServerCallbackRpcControllerImpl(); // explicitly call destructor + if (allocator_ != nullptr) { + allocator_->DeallocateMessages(allocator_info_); + } else { + if (allocator_info_->request != nullptr) { + allocator_info_->request->~RequestType(); + } + if (allocator_info_->response != nullptr) { + allocator_info_->response->~ResponseType(); + } + } g_core_codegen_interface->grpc_call_unref(call); call_requester(); } @@ -583,8 +638,8 @@ class CallbackUnaryHandler : public MethodHandler { ServerContext* ctx_; Call call_; - const RequestType* req_; - ResponseType resp_; + RpcAllocatorInfo* allocator_info_; + MessageAllocator* allocator_; std::function call_requester_; std::atomic_int callbacks_outstanding_{ 2}; // reserve for Finish and CompletionOp @@ -771,8 +826,8 @@ class CallbackServerStreamingHandler : public MethodHandler { writer->MaybeDone(); } - void* Deserialize(grpc_call* call, grpc_byte_buffer* req, - Status* status) final { + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, + void** handler_data) final { ByteBuffer buf; buf.set_buffer(req); auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc( diff --git a/include/grpcpp/support/message_allocator.h b/include/grpcpp/support/message_allocator.h new file mode 100644 index 00000000000..eb1dbb14764 --- /dev/null +++ b/include/grpcpp/support/message_allocator.h @@ -0,0 +1,24 @@ +/* + * + * 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_SUPPORT_MESSAGE_ALLOCATOR_H_ +#define GRPCPP_SUPPORT_MESSAGE_ALLOCATOR_H_ + +#include + +#endif // GRPCPP_SUPPORT_MESSAGE_ALLOCATOR_H_ diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 1bb9c509bb5..86f4e3c5df9 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -155,6 +155,8 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, params.grpc_search_path); printer->Print(vars, "\n"); printer->Print(vars, "namespace grpc {\n"); + printer->Print(vars, "template \n"); + printer->Print(vars, "class MessageAllocator;\n"); printer->Print(vars, "class CompletionQueue;\n"); printer->Print(vars, "class Channel;\n"); printer->Print(vars, "class ServerCompletionQueue;\n"); @@ -993,7 +995,23 @@ void PrintHeaderServerMethodCallback( "controller) {\n" " return this->$" "Method$(context, request, response, controller);\n" - " }));\n"); + " }, nullptr));\n}\n"); + printer->Print( + *vars, + "void SetMessageAllocatorFor_$Method$(\n" + " ::grpc::MessageAllocator<$RealRequest$, $RealResponse$>* " + "allocator) {\n" + " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" + " new ::grpc::internal::CallbackUnaryHandler< " + "$RealRequest$, $RealResponse$>(\n" + " [this](::grpc::ServerContext* context,\n" + " const $RealRequest$* request,\n" + " $RealResponse$* response,\n" + " ::grpc::experimental::ServerCallbackRpcController* " + "controller) {\n" + " return this->$" + "Method$(context, request, response, controller);\n" + " }, allocator));\n"); } else if (ClientOnlyStreaming(method)) { printer->Print( *vars, diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index aa9fdac9bea..836435c86a9 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -281,7 +281,7 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { auto* handler = resources_ ? method_->handler() : server_->resource_exhausted_handler_.get(); request_ = handler->Deserialize(call_.call(), request_payload_, - &request_status_); + &request_status_, nullptr); request_payload_ = nullptr; interceptor_methods_.AddInterceptionHookPoint( @@ -305,7 +305,7 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { auto* handler = resources_ ? method_->handler() : server_->resource_exhausted_handler_.get(); handler->RunHandler(internal::MethodHandler::HandlerParameter( - &call_, &ctx_, request_, request_status_, nullptr)); + &call_, &ctx_, request_, request_status_, nullptr, nullptr)); request_ = nullptr; global_callbacks_->PostSynchronousRequest(&ctx_); @@ -512,7 +512,8 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { if (req_->has_request_payload_) { // Set interception point for RECV MESSAGE req_->request_ = req_->method_->handler()->Deserialize( - req_->call_, req_->request_payload_, &req_->request_status_); + req_->call_, req_->request_payload_, &req_->request_status_, + &req_->handler_data_); req_->request_payload_ = nullptr; req_->interceptor_methods_.AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); @@ -532,7 +533,8 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { ? req_->method_->handler() : req_->server_->generic_handler_.get(); handler->RunHandler(internal::MethodHandler::HandlerParameter( - call_, &req_->ctx_, req_->request_, req_->request_status_, [this] { + call_, &req_->ctx_, req_->request_, req_->request_status_, + req_->handler_data_, [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 @@ -577,6 +579,7 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { ctx_.Setup(gpr_inf_future(GPR_CLOCK_REALTIME)); request_payload_ = nullptr; request_ = nullptr; + handler_data_ = nullptr; request_status_ = Status(); } @@ -587,6 +590,7 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { const bool has_request_payload_; grpc_byte_buffer* request_payload_; void* request_; + void* handler_data_ = nullptr; Status request_status_; grpc_call_details* call_details_ = nullptr; grpc_call* call_; diff --git a/src/proto/grpc/testing/echo_messages.proto b/src/proto/grpc/testing/echo_messages.proto index 2f935304ab2..066a0850d6a 100644 --- a/src/proto/grpc/testing/echo_messages.proto +++ b/src/proto/grpc/testing/echo_messages.proto @@ -17,6 +17,8 @@ syntax = "proto3"; package grpc.testing; +option cc_enable_arenas = true; + // Message to be echoed back serialized in trailer. message DebugInfo { repeated string stack_entries = 1; diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 707a628148e..e89667a9714 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -675,3 +675,23 @@ grpc_cc_test( "//test/cpp/util:test_util", ], ) + +grpc_cc_test( + name = "message_allocator_end2end_test", + srcs = ["message_allocator_end2end_test.cc"], + external_deps = [ + "gtest", + ], + deps = [ + ":test_service_impl", + "//:grpc", + "//:gpr", + "//:grpc++", + "//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/message_allocator_end2end_test.cc b/test/cpp/end2end/message_allocator_end2end_test.cc new file mode 100644 index 00000000000..995318ce8d9 --- /dev/null +++ b/test/cpp/end2end/message_allocator_end2end_test.cc @@ -0,0 +1,395 @@ +/* + * + * 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 "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/util/test_credentials_provider.h" + +// 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 { + +class CallbackTestServiceImpl + : public EchoTestService::ExperimentalCallbackService { + public: + explicit CallbackTestServiceImpl() {} + + void SetFreeRequest() { free_request_ = true; } + + void SetAllocatorMutator( + std::function + mutator) { + allocator_mutator_ = mutator; + } + + void Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response, + experimental::ServerCallbackRpcController* controller) override { + response->set_message(request->message()); + if (free_request_) { + controller->FreeRequest(); + } else if (allocator_mutator_) { + allocator_mutator_(controller->GetAllocatorState(), request, response); + } + controller->Finish(Status::OK); + } + + private: + bool free_request_ = false; + std::function + allocator_mutator_; +}; + +enum class Protocol { INPROC, TCP }; + +class TestScenario { + public: + TestScenario(Protocol protocol, const grpc::string& creds_type) + : protocol(protocol), credentials_type(creds_type) {} + void Log() const; + Protocol protocol; + const grpc::string credentials_type; +}; + +static std::ostream& operator<<(std::ostream& out, + const TestScenario& scenario) { + return out << "TestScenario{protocol=" + << (scenario.protocol == Protocol::INPROC ? "INPROC" : "TCP") + << "," << scenario.credentials_type << "}"; +} + +void TestScenario::Log() const { + std::ostringstream out; + out << *this; + gpr_log(GPR_INFO, "%s", out.str().c_str()); +} + +class MessageAllocatorEnd2endTestBase + : public ::testing::TestWithParam { + protected: + MessageAllocatorEnd2endTestBase() { + GetParam().Log(); + if (GetParam().protocol == Protocol::TCP) { + if (!grpc_iomgr_run_in_background()) { + do_not_test_ = true; + return; + } + } + } + + ~MessageAllocatorEnd2endTestBase() = default; + + void CreateServer(MessageAllocator* allocator) { + ServerBuilder builder; + + auto server_creds = GetCredentialsProvider()->GetServerCredentials( + GetParam().credentials_type); + if (GetParam().protocol == Protocol::TCP) { + picked_port_ = grpc_pick_unused_port_or_die(); + server_address_ << "localhost:" << picked_port_; + builder.AddListeningPort(server_address_.str(), server_creds); + } + callback_service_.SetMessageAllocatorFor_Echo(allocator); + builder.RegisterService(&callback_service_); + + 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_ = + CreateCustomChannel(server_address_.str(), channel_creds, args); + break; + case Protocol::INPROC: + channel_ = server_->InProcessChannel(args); + break; + default: + assert(false); + } + stub_ = EchoTestService::NewStub(channel_); + } + + void TearDown() override { + if (is_server_started_) { + server_->Shutdown(); + } + if (picked_port_ > 0) { + grpc_recycle_unused_port(picked_port_); + } + } + + void SendRpcs(int num_rpcs) { + grpc::string test_string(""); + for (int i = 0; i < num_rpcs; i++) { + EchoRequest request; + EchoResponse response; + ClientContext cli_ctx; + + test_string += "Hello world. "; + request.set_message(test_string); + grpc::string val; + cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); + + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub_->experimental_async()->Echo( + &cli_ctx, &request, &response, + [&request, &response, &done, &mu, &cv, val](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); + } + } + } + + bool do_not_test_{false}; + bool is_server_started_{false}; + int picked_port_{0}; + std::shared_ptr channel_; + std::unique_ptr stub_; + CallbackTestServiceImpl callback_service_; + std::unique_ptr server_; + std::ostringstream server_address_; +}; + +class NullAllocatorTest : public MessageAllocatorEnd2endTestBase {}; + +TEST_P(NullAllocatorTest, SimpleRpc) { + MAYBE_SKIP_TEST; + CreateServer(nullptr); + ResetStub(); + SendRpcs(1); +} + +class SimpleAllocatorTest : public MessageAllocatorEnd2endTestBase { + public: + class SimpleAllocator : public MessageAllocator { + public: + void AllocateMessages(RpcAllocatorInfo* info) { + allocation_count++; + info->request = new EchoRequest; + info->response = new EchoResponse; + info->allocator_state = info; + } + void DeallocateRequest(RpcAllocatorInfo* info) { + request_deallocation_count++; + delete info->request; + info->request = nullptr; + } + void DeallocateMessages(RpcAllocatorInfo* info) { + messages_deallocation_count++; + delete info->request; + delete info->response; + } + + int allocation_count = 0; + int request_deallocation_count = 0; + int messages_deallocation_count = 0; + }; +}; + +TEST_P(SimpleAllocatorTest, SimpleRpc) { + MAYBE_SKIP_TEST; + const int kRpcCount = 10; + std::unique_ptr allocator(new SimpleAllocator); + CreateServer(allocator.get()); + ResetStub(); + SendRpcs(kRpcCount); + EXPECT_EQ(kRpcCount, allocator->allocation_count); + EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); + EXPECT_EQ(0, allocator->request_deallocation_count); +} + +TEST_P(SimpleAllocatorTest, RpcWithEarlyFreeRequest) { + MAYBE_SKIP_TEST; + const int kRpcCount = 10; + std::unique_ptr allocator(new SimpleAllocator); + callback_service_.SetFreeRequest(); + CreateServer(allocator.get()); + ResetStub(); + SendRpcs(kRpcCount); + EXPECT_EQ(kRpcCount, allocator->allocation_count); + EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); + EXPECT_EQ(kRpcCount, allocator->request_deallocation_count); +} + +TEST_P(SimpleAllocatorTest, RpcWithReleaseRequest) { + MAYBE_SKIP_TEST; + const int kRpcCount = 10; + std::unique_ptr allocator(new SimpleAllocator); + std::vector released_requests; + auto mutator = [&released_requests](void* allocator_state, + const EchoRequest* req, + EchoResponse* resp) { + auto* info = static_cast*>( + allocator_state); + EXPECT_EQ(req, info->request); + EXPECT_EQ(resp, info->response); + EXPECT_EQ(allocator_state, info->allocator_state); + released_requests.push_back(info->request); + info->request = nullptr; + }; + callback_service_.SetAllocatorMutator(mutator); + CreateServer(allocator.get()); + ResetStub(); + SendRpcs(kRpcCount); + EXPECT_EQ(kRpcCount, allocator->allocation_count); + EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); + EXPECT_EQ(0, allocator->request_deallocation_count); + EXPECT_EQ(static_cast(kRpcCount), released_requests.size()); + for (auto* req : released_requests) { + delete req; + } +} + +class ArenaAllocatorTest : public MessageAllocatorEnd2endTestBase { + public: + class ArenaAllocator : public MessageAllocator { + public: + void AllocateMessages(RpcAllocatorInfo* info) { + allocation_count++; + auto* arena = new google::protobuf::Arena; + info->allocator_state = arena; + info->request = + google::protobuf::Arena::CreateMessage(arena); + info->response = + google::protobuf::Arena::CreateMessage(arena); + } + void DeallocateRequest(RpcAllocatorInfo* info) { + GPR_ASSERT(0); + } + void DeallocateMessages(RpcAllocatorInfo* info) { + deallocation_count++; + auto* arena = + static_cast(info->allocator_state); + delete arena; + } + + int allocation_count = 0; + int deallocation_count = 0; + }; +}; + +TEST_P(ArenaAllocatorTest, SimpleRpc) { + MAYBE_SKIP_TEST; + const int kRpcCount = 10; + std::unique_ptr allocator(new ArenaAllocator); + CreateServer(allocator.get()); + ResetStub(); + SendRpcs(kRpcCount); + EXPECT_EQ(kRpcCount, allocator->allocation_count); + EXPECT_EQ(kRpcCount, allocator->deallocation_count); +} + +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()); + + 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; + } + scenarios.emplace_back(p, cred); + } + } + return scenarios; +} + +INSTANTIATE_TEST_CASE_P(NullAllocatorTest, NullAllocatorTest, + ::testing::ValuesIn(CreateTestScenarios(true))); +INSTANTIATE_TEST_CASE_P(SimpleAllocatorTest, SimpleAllocatorTest, + ::testing::ValuesIn(CreateTestScenarios(true))); +INSTANTIATE_TEST_CASE_P(ArenaAllocatorTest, ArenaAllocatorTest, + ::testing::ValuesIn(CreateTestScenarios(true))); + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + // The grpc_init is to cover the MAYBE_SKIP_TEST. + grpc_init(); + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + grpc_shutdown(); + return ret; +} diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 7274f9588b3..1b8faf655ae 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -968,6 +968,7 @@ 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/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ @@ -1022,6 +1023,7 @@ 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/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 80760da0c58..47f583bf7f7 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -970,6 +970,7 @@ 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/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ @@ -1024,6 +1025,7 @@ 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/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index de84eb74b29..61c828ec61a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -4149,6 +4149,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "message_allocator_end2end_test", + "src": [ + "test/cpp/end2end/message_allocator_end2end_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -9919,6 +9937,7 @@ "include/grpcpp/impl/codegen/intercepted_channel.h", "include/grpcpp/impl/codegen/interceptor.h", "include/grpcpp/impl/codegen/interceptor_common.h", + "include/grpcpp/impl/codegen/message_allocator.h", "include/grpcpp/impl/codegen/metadata_map.h", "include/grpcpp/impl/codegen/method_handler_impl.h", "include/grpcpp/impl/codegen/rpc_method.h", @@ -9995,6 +10014,7 @@ "include/grpcpp/impl/codegen/intercepted_channel.h", "include/grpcpp/impl/codegen/interceptor.h", "include/grpcpp/impl/codegen/interceptor_common.h", + "include/grpcpp/impl/codegen/message_allocator.h", "include/grpcpp/impl/codegen/metadata_map.h", "include/grpcpp/impl/codegen/method_handler_impl.h", "include/grpcpp/impl/codegen/rpc_method.h", @@ -10163,6 +10183,7 @@ "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", "include/grpcpp/support/interceptor.h", + "include/grpcpp/support/message_allocator.h", "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", @@ -10283,6 +10304,7 @@ "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", "include/grpcpp/support/interceptor.h", + "include/grpcpp/support/message_allocator.h", "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index cfeff6fa838..881695f3bdd 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -4857,6 +4857,30 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 0.5, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "message_allocator_end2end_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From 051d4215794a98e8dd78ddfa75bc43d6fcd3761b Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 16 Apr 2019 16:54:35 -0700 Subject: [PATCH 1876/2143] Resolve sanity --- .../grpcpp/impl/codegen/message_allocator.h | 6 ++-- include/grpcpp/impl/codegen/server_callback.h | 4 +-- include/grpcpp/support/message_allocator.h | 6 ++-- test/cpp/codegen/compiler_test_golden | 28 +++++++++++++++++-- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/include/grpcpp/impl/codegen/message_allocator.h b/include/grpcpp/impl/codegen/message_allocator.h index 8f37d36eb8b..28702a4500f 100644 --- a/include/grpcpp/impl/codegen/message_allocator.h +++ b/include/grpcpp/impl/codegen/message_allocator.h @@ -16,8 +16,8 @@ * */ -#ifndef GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H_ -#define GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H_ +#ifndef GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H +#define GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H namespace grpc { @@ -50,4 +50,4 @@ class MessageAllocator { } // namespace grpc -#endif // GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H_ +#endif // GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 030e4aea92a..359472bc392 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -604,8 +604,6 @@ class CallbackUnaryHandler : public MethodHandler { ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, nullptr); } - ~ServerCallbackRpcControllerImpl() {} - const RequestType* request() { return allocator_info_->request; } ResponseType* response() { return allocator_info_->response; } @@ -613,7 +611,6 @@ class CallbackUnaryHandler : public MethodHandler { if (--callbacks_outstanding_ == 0) { grpc_call* call = call_.call(); auto call_requester = std::move(call_requester_); - this->~ServerCallbackRpcControllerImpl(); // explicitly call destructor if (allocator_ != nullptr) { allocator_->DeallocateMessages(allocator_info_); } else { @@ -624,6 +621,7 @@ class CallbackUnaryHandler : public MethodHandler { allocator_info_->response->~ResponseType(); } } + this->~ServerCallbackRpcControllerImpl(); // explicitly call destructor g_core_codegen_interface->grpc_call_unref(call); call_requester(); } diff --git a/include/grpcpp/support/message_allocator.h b/include/grpcpp/support/message_allocator.h index eb1dbb14764..20ce072b901 100644 --- a/include/grpcpp/support/message_allocator.h +++ b/include/grpcpp/support/message_allocator.h @@ -16,9 +16,9 @@ * */ -#ifndef GRPCPP_SUPPORT_MESSAGE_ALLOCATOR_H_ -#define GRPCPP_SUPPORT_MESSAGE_ALLOCATOR_H_ +#ifndef GRPCPP_SUPPORT_MESSAGE_ALLOCATOR_H +#define GRPCPP_SUPPORT_MESSAGE_ALLOCATOR_H #include -#endif // GRPCPP_SUPPORT_MESSAGE_ALLOCATOR_H_ +#endif // GRPCPP_SUPPORT_MESSAGE_ALLOCATOR_H diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 7f9fd29026e..175ab821858 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -41,6 +41,8 @@ #include namespace grpc { +template +class MessageAllocator; class CompletionQueue; class Channel; class ServerCompletionQueue; @@ -330,7 +332,18 @@ class ServiceA final { ::grpc::testing::Response* response, ::grpc::experimental::ServerCallbackRpcController* controller) { return this->MethodA1(context, request, response, controller); - })); + }, nullptr)); + } + void SetMessageAllocatorFor_MethodA1( + ::grpc::MessageAllocator<::grpc::testing::Request, ::grpc::testing::Response>* allocator) { + ::grpc::Service::experimental().MarkMethodCallback(0, + new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + [this](::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response, + ::grpc::experimental::ServerCallbackRpcController* controller) { + return this->MethodA1(context, request, response, controller); + }, allocator)); } ~ExperimentalWithCallbackMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); @@ -798,7 +811,18 @@ class ServiceB final { ::grpc::testing::Response* response, ::grpc::experimental::ServerCallbackRpcController* controller) { return this->MethodB1(context, request, response, controller); - })); + }, nullptr)); + } + void SetMessageAllocatorFor_MethodB1( + ::grpc::MessageAllocator<::grpc::testing::Request, ::grpc::testing::Response>* allocator) { + ::grpc::Service::experimental().MarkMethodCallback(0, + new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + [this](::grpc::ServerContext* context, + const ::grpc::testing::Request* request, + ::grpc::testing::Response* response, + ::grpc::experimental::ServerCallbackRpcController* controller) { + return this->MethodB1(context, request, response, controller); + }, allocator)); } ~ExperimentalWithCallbackMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); From 2b9448a71c39e5ebcd79bedc71d1da8efcdbfceb Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 16 Apr 2019 14:51:16 -0400 Subject: [PATCH 1877/2143] Revert "Revert "Introduce C++ wrappers for gpr_mu and gpr_cv."" This reverts commit d09c9f8e20363918d6b1aa92ee977e6f62551b48. --- BUILD | 14 +- BUILD.gn | 5 +- CMakeLists.txt | 5 + Makefile | 5 + build.yaml | 8 +- gRPC-C++.podspec | 7 +- gRPC-Core.podspec | 4 +- grpc.gemspec | 2 +- include/grpcpp/channel.h | 3 +- include/grpcpp/impl/codegen/client_context.h | 3 +- include/grpcpp/impl/codegen/sync.h | 138 ++++++++++++++++++ include/grpcpp/server.h | 8 +- include/grpcpp/server_impl.h | 8 +- package.xml | 2 +- .../filters/client_channel/client_channel.cc | 2 +- .../health/health_check_client.cc | 4 +- .../health/health_check_client.h | 3 +- .../client_channel/http_connect_handshaker.cc | 2 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 1 - .../lb_policy/grpclb/grpclb_client_stats.cc | 2 +- .../lb_policy/grpclb/grpclb_client_stats.h | 6 +- .../lb_policy/pick_first/pick_first.cc | 6 +- .../lb_policy/round_robin/round_robin.cc | 6 +- .../client_channel/lb_policy/xds/xds.cc | 19 +-- .../client_channel/resolving_lb_policy.cc | 2 +- .../ext/filters/client_channel/subchannel.cc | 58 ++++---- .../ext/filters/client_channel/subchannel.h | 3 +- src/core/lib/channel/channelz_registry.cc | 2 +- src/core/lib/channel/handshaker.h | 2 +- src/core/lib/gprpp/mutex_lock.h | 42 ------ src/core/lib/gprpp/sync.h | 126 ++++++++++++++++ src/core/lib/iomgr/ev_epollex_linux.cc | 2 +- src/core/lib/surface/init.cc | 2 +- .../ssl/session_cache/ssl_session_cache.cc | 2 +- src/cpp/client/channel_cc.cc | 2 +- src/cpp/client/client_context.cc | 5 +- src/cpp/server/dynamic_thread_pool.cc | 23 +-- src/cpp/server/dynamic_thread_pool.h | 7 +- .../health/default_health_check_service.cc | 28 ++-- .../health/default_health_check_service.h | 7 +- src/cpp/server/load_reporter/load_reporter.cc | 18 +-- src/cpp/server/load_reporter/load_reporter.h | 5 +- .../load_reporter_async_service_impl.cc | 24 +-- .../load_reporter_async_service_impl.h | 3 +- src/cpp/server/server_cc.cc | 24 +-- src/cpp/server/server_context.cc | 17 +-- src/cpp/thread_manager/thread_manager.cc | 34 ++--- src/cpp/thread_manager/thread_manager.h | 7 +- test/cpp/client/client_channel_stress_test.cc | 17 ++- test/cpp/end2end/client_lb_end2end_test.cc | 37 ++--- test/cpp/end2end/grpclb_end2end_test.cc | 67 ++++----- test/cpp/end2end/thread_stress_test.cc | 21 +-- test/cpp/end2end/xds_end2end_test.cc | 66 ++++----- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 3 +- tools/doxygen/Doxyfile.core.internal | 2 +- .../generated/sources_and_headers.json | 20 ++- 57 files changed, 606 insertions(+), 336 deletions(-) create mode 100644 include/grpcpp/impl/codegen/sync.h delete mode 100644 src/core/lib/gprpp/mutex_lock.h create mode 100644 src/core/lib/gprpp/sync.h diff --git a/BUILD b/BUILD index fd75012d214..56d332e0807 100644 --- a/BUILD +++ b/BUILD @@ -525,6 +525,17 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "grpc++_internal_hdrs_only", + hdrs = [ + "include/grpcpp/impl/codegen/sync.h", + ], + language = "c++", + deps = [ + "gpr_codegen", + ], +) + grpc_cc_library( name = "gpr_base", srcs = [ @@ -590,8 +601,8 @@ grpc_cc_library( "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", - "src/core/lib/gprpp/mutex_lock.h", "src/core/lib/gprpp/pair.h", + "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/profiling/timers.h", ], @@ -2147,6 +2158,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/time.h", ], deps = [ + "grpc++_internal_hdrs_only", "grpc_codegen", ], ) diff --git a/BUILD.gn b/BUILD.gn index 21f567d9af4..10b514f8f2e 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -186,8 +186,8 @@ config("grpc_config") { "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", - "src/core/lib/gprpp/mutex_lock.h", "src/core/lib/gprpp/pair.h", + "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/gprpp/thd_posix.cc", "src/core/lib/gprpp/thd_windows.cc", @@ -1066,6 +1066,7 @@ config("grpc_config") { "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.h", "include/grpcpp/impl/codegen/sync_stream.h", "include/grpcpp/impl/codegen/time.h", "include/grpcpp/impl/grpc_library.h", @@ -1161,12 +1162,12 @@ config("grpc_config") { "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.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/pair.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", + "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index f2a4f698255..ee8712f1d38 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3187,6 +3187,7 @@ foreach(_hdr include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h include/grpcpp/impl/codegen/time.h + include/grpcpp/impl/codegen/sync.h include/grpc++/impl/codegen/proto_utils.h include/grpcpp/impl/codegen/proto_buffer_reader.h include/grpcpp/impl/codegen/proto_buffer_writer.h @@ -3790,6 +3791,7 @@ foreach(_hdr include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h include/grpcpp/impl/codegen/time.h + include/grpcpp/impl/codegen/sync.h include/grpc/census.h ) string(REPLACE "include/" "" _path ${_hdr}) @@ -4244,6 +4246,7 @@ foreach(_hdr include/grpc/impl/codegen/sync_generic.h include/grpc/impl/codegen/sync_posix.h include/grpc/impl/codegen/sync_windows.h + include/grpcpp/impl/codegen/sync.h include/grpc++/impl/codegen/proto_utils.h include/grpcpp/impl/codegen/proto_buffer_reader.h include/grpcpp/impl/codegen/proto_buffer_writer.h @@ -4440,6 +4443,7 @@ foreach(_hdr include/grpc/impl/codegen/sync_generic.h include/grpc/impl/codegen/sync_posix.h include/grpc/impl/codegen/sync_windows.h + include/grpcpp/impl/codegen/sync.h include/grpc++/impl/codegen/proto_utils.h include/grpcpp/impl/codegen/proto_buffer_reader.h include/grpcpp/impl/codegen/proto_buffer_writer.h @@ -4766,6 +4770,7 @@ foreach(_hdr include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h include/grpcpp/impl/codegen/time.h + include/grpcpp/impl/codegen/sync.h ) string(REPLACE "include/" "" _path ${_hdr}) get_filename_component(_path ${_path} PATH) diff --git a/Makefile b/Makefile index 6f19cc8d76b..c7fbca51225 100644 --- a/Makefile +++ b/Makefile @@ -5523,6 +5523,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ include/grpcpp/impl/codegen/time.h \ + include/grpcpp/impl/codegen/sync.h \ include/grpc++/impl/codegen/proto_utils.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ include/grpcpp/impl/codegen/proto_buffer_writer.h \ @@ -6134,6 +6135,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ include/grpcpp/impl/codegen/time.h \ + include/grpcpp/impl/codegen/sync.h \ include/grpc/census.h \ LIBGRPC++_CRONET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_CRONET_SRC)))) @@ -6560,6 +6562,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc/impl/codegen/sync_generic.h \ include/grpc/impl/codegen/sync_posix.h \ include/grpc/impl/codegen/sync_windows.h \ + include/grpcpp/impl/codegen/sync.h \ include/grpc++/impl/codegen/proto_utils.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ include/grpcpp/impl/codegen/proto_buffer_writer.h \ @@ -6727,6 +6730,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc/impl/codegen/sync_generic.h \ include/grpc/impl/codegen/sync_posix.h \ include/grpc/impl/codegen/sync_windows.h \ + include/grpcpp/impl/codegen/sync.h \ include/grpc++/impl/codegen/proto_utils.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ include/grpcpp/impl/codegen/proto_buffer_writer.h \ @@ -7059,6 +7063,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ include/grpcpp/impl/codegen/time.h \ + include/grpcpp/impl/codegen/sync.h \ LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC)))) diff --git a/build.yaml b/build.yaml index 6683db05fd4..4593be986bf 100644 --- a/build.yaml +++ b/build.yaml @@ -196,8 +196,8 @@ filegroups: - src/core/lib/gprpp/manual_constructor.h - src/core/lib/gprpp/map.h - src/core/lib/gprpp/memory.h - - src/core/lib/gprpp/mutex_lock.h - src/core/lib/gprpp/pair.h + - src/core/lib/gprpp/sync.h - src/core/lib/gprpp/thd.h - src/core/lib/profiling/timers.h uses: @@ -1278,6 +1278,7 @@ filegroups: - include/grpcpp/impl/codegen/time.h uses: - grpc_codegen + - grpc++_internal_hdrs_only - name: grpc++_codegen_base_src language: c++ src: @@ -1452,6 +1453,7 @@ filegroups: - grpc_base_headers - grpc_transport_inproc_headers - grpc++_codegen_base + - grpc++_internal_hdrs_only - nanopb_headers - health_proto - name: grpc++_config_proto @@ -1459,6 +1461,10 @@ filegroups: public_headers: - include/grpc++/impl/codegen/config_protobuf.h - include/grpcpp/impl/codegen/config_protobuf.h +- name: grpc++_internal_hdrs_only + language: c++ + public_headers: + - include/grpcpp/impl/codegen/sync.h - name: grpc++_reflection_proto language: c++ src: diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 4d858ab6c77..74f758e6487 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -183,7 +183,8 @@ Pod::Spec.new do |s| '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/codegen/time.h', + 'include/grpcpp/impl/codegen/sync.h' end s.subspec 'Implementation' do |ss| @@ -266,8 +267,8 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', - 'src/core/lib/gprpp/mutex_lock.h', 'src/core/lib/gprpp/pair.h', + 'src/core/lib/gprpp/sync.h', 'src/core/lib/gprpp/thd.h', 'src/core/lib/profiling/timers.h', 'src/core/ext/transport/chttp2/transport/bin_decoder.h', @@ -584,8 +585,8 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', - 'src/core/lib/gprpp/mutex_lock.h', 'src/core/lib/gprpp/pair.h', + 'src/core/lib/gprpp/sync.h', 'src/core/lib/gprpp/thd.h', 'src/core/lib/profiling/timers.h', 'src/core/lib/avl/avl.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index b54ec902f92..5cf45c63cef 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -210,8 +210,8 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', - 'src/core/lib/gprpp/mutex_lock.h', 'src/core/lib/gprpp/pair.h', + 'src/core/lib/gprpp/sync.h', 'src/core/lib/gprpp/thd.h', 'src/core/lib/profiling/timers.h', 'src/core/lib/gpr/alloc.cc', @@ -891,8 +891,8 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', - 'src/core/lib/gprpp/mutex_lock.h', 'src/core/lib/gprpp/pair.h', + 'src/core/lib/gprpp/sync.h', 'src/core/lib/gprpp/thd.h', 'src/core/lib/profiling/timers.h', 'src/core/ext/transport/chttp2/transport/bin_decoder.h', diff --git a/grpc.gemspec b/grpc.gemspec index c7ceac4a9ee..15c26f11569 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -104,8 +104,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/manual_constructor.h ) s.files += %w( src/core/lib/gprpp/map.h ) s.files += %w( src/core/lib/gprpp/memory.h ) - s.files += %w( src/core/lib/gprpp/mutex_lock.h ) s.files += %w( src/core/lib/gprpp/pair.h ) + s.files += %w( src/core/lib/gprpp/sync.h ) s.files += %w( src/core/lib/gprpp/thd.h ) s.files += %w( src/core/lib/profiling/timers.h ) s.files += %w( src/core/lib/gpr/alloc.cc ) diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h index ee833960698..c4d5ab1177b 100644 --- a/include/grpcpp/channel.h +++ b/include/grpcpp/channel.h @@ -28,6 +28,7 @@ #include #include #include +#include struct grpc_channel; @@ -97,7 +98,7 @@ class Channel final : public ChannelInterface, grpc_channel* const c_channel_; // owned // mu_ protects callback_cq_ (the per-channel callbackable completion queue) - std::mutex mu_; + grpc::internal::Mutex mu_; // callback_cq_ references the callbackable completion queue associated // with this channel (if any). It is set on the first call to CallbackCQ(). diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 5946488566e..85bbf36f06d 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -51,6 +51,7 @@ #include #include #include +#include #include struct census_context; @@ -457,7 +458,7 @@ class ClientContext { bool idempotent_; bool cacheable_; std::shared_ptr channel_; - std::mutex mu_; + grpc::internal::Mutex mu_; grpc_call* call_; bool call_canceled_; gpr_timespec deadline_; diff --git a/include/grpcpp/impl/codegen/sync.h b/include/grpcpp/impl/codegen/sync.h new file mode 100644 index 00000000000..2ed71eeb9f2 --- /dev/null +++ b/include/grpcpp/impl/codegen/sync.h @@ -0,0 +1,138 @@ +/* + * + * 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_IMPL_CODEGEN_SYNC_H +#define GRPCPP_IMPL_CODEGEN_SYNC_H + +#include +#include +#include + +#include + +// The core library is not accessible in C++ codegen headers, and vice versa. +// Thus, we need to have duplicate headers with similar functionality. +// Make sure any change to this file is also reflected in +// src/core/lib/gprpp/sync.h too. +// +// Whenever possible, prefer "src/core/lib/gprpp/sync.h" over this file, +// since in core we do not rely on g_core_codegen_interface and hence do not +// pay the costs of virtual function calls. + +namespace grpc { +namespace internal { + +class Mutex { + public: + Mutex() { g_core_codegen_interface->gpr_mu_init(&mu_); } + ~Mutex() { g_core_codegen_interface->gpr_mu_destroy(&mu_); } + + Mutex(const Mutex&) = delete; + Mutex& operator=(const Mutex&) = delete; + + gpr_mu* get() { return &mu_; } + const gpr_mu* get() const { return &mu_; } + + private: + gpr_mu mu_; +}; + +// MutexLock is a std:: +class MutexLock { + public: + explicit MutexLock(Mutex* mu) : mu_(mu->get()) { + g_core_codegen_interface->gpr_mu_lock(mu_); + } + explicit MutexLock(gpr_mu* mu) : mu_(mu) { + g_core_codegen_interface->gpr_mu_lock(mu_); + } + ~MutexLock() { g_core_codegen_interface->gpr_mu_unlock(mu_); } + + MutexLock(const MutexLock&) = delete; + MutexLock& operator=(const MutexLock&) = delete; + + private: + gpr_mu* const mu_; +}; + +class ReleasableMutexLock { + public: + explicit ReleasableMutexLock(Mutex* mu) : mu_(mu->get()) { + g_core_codegen_interface->gpr_mu_lock(mu_); + } + explicit ReleasableMutexLock(gpr_mu* mu) : mu_(mu) { + g_core_codegen_interface->gpr_mu_lock(mu_); + } + ~ReleasableMutexLock() { + if (!released_) g_core_codegen_interface->gpr_mu_unlock(mu_); + } + + ReleasableMutexLock(const ReleasableMutexLock&) = delete; + ReleasableMutexLock& operator=(const ReleasableMutexLock&) = delete; + + void Lock() { + GPR_DEBUG_ASSERT(released_); + g_core_codegen_interface->gpr_mu_lock(mu_); + released_ = false; + } + + void Unlock() { + GPR_DEBUG_ASSERT(!released_); + released_ = true; + g_core_codegen_interface->gpr_mu_unlock(mu_); + } + + private: + gpr_mu* const mu_; + bool released_ = false; +}; + +class CondVar { + public: + CondVar() { g_core_codegen_interface->gpr_cv_init(&cv_); } + ~CondVar() { g_core_codegen_interface->gpr_cv_destroy(&cv_); } + + CondVar(const CondVar&) = delete; + CondVar& operator=(const CondVar&) = delete; + + void Signal() { g_core_codegen_interface->gpr_cv_signal(&cv_); } + void Broadcast() { g_core_codegen_interface->gpr_cv_broadcast(&cv_); } + + int Wait(Mutex* mu) { + return Wait(mu, + g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME)); + } + int Wait(Mutex* mu, const gpr_timespec& deadline) { + return g_core_codegen_interface->gpr_cv_wait(&cv_, mu->get(), deadline); + } + + template + void WaitUntil(Mutex* mu, Predicate pred) { + while (!pred()) { + Wait(mu, g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME)); + } + } + + private: + gpr_cv cv_; +}; + +} // namespace internal +} // namespace grpc + +#endif // GRPCPP_IMPL_CODEGEN_SYNC_H diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 2ae9d712012..8aff0663fe2 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -297,12 +297,12 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { experimental_registration_type experimental_registration_{this}; // Server status - std::mutex mu_; + grpc::internal::Mutex mu_; bool started_; bool shutdown_; bool shutdown_notified_; // Was notify called on the shutdown_cv_ - std::condition_variable shutdown_cv_; + grpc::internal::CondVar 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 must be @@ -311,8 +311,8 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { // 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_; + grpc::internal::Mutex callback_reqs_mu_; + grpc::internal::CondVar callback_reqs_done_cv_; std::atomic_int callback_reqs_outstanding_{0}; std::shared_ptr global_callbacks_; diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h index 771a3a10be9..14b16a06f4e 100644 --- a/include/grpcpp/server_impl.h +++ b/include/grpcpp/server_impl.h @@ -304,12 +304,12 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { experimental_registration_type experimental_registration_{this}; // Server status - std::mutex mu_; + grpc::internal::Mutex mu_; bool started_; bool shutdown_; bool shutdown_notified_; // Was notify called on the shutdown_cv_ - std::condition_variable shutdown_cv_; + grpc::internal::CondVar 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 must be @@ -318,8 +318,8 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { // 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_; + grpc::internal::Mutex callback_reqs_mu_; + grpc::internal::CondVar callback_reqs_done_cv_; std::atomic_int callback_reqs_outstanding_{0}; std::shared_ptr global_callbacks_; diff --git a/package.xml b/package.xml index 1f08eaf4a20..c3f4e17dd12 100644 --- a/package.xml +++ b/package.xml @@ -109,8 +109,8 @@ - + diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 0304a265a09..2ce7c99f16f 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -51,7 +51,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/gprpp/sync.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/polling_entity.h" 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 a22d6450cbd..a99f1e54062 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 @@ -27,7 +27,7 @@ #include "pb_encode.h" #include "src/core/ext/filters/client_channel/health/health.pb.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/error_utils.h" #include "src/core/lib/transport/status_metadata.h" @@ -69,7 +69,6 @@ HealthCheckClient::HealthCheckClient( } GRPC_CLOSURE_INIT(&retry_timer_callback_, OnRetryTimer, this, grpc_schedule_on_exec_ctx); - gpr_mu_init(&mu_); StartCall(); } @@ -78,7 +77,6 @@ HealthCheckClient::~HealthCheckClient() { gpr_log(GPR_INFO, "destroying HealthCheckClient %p", this); } GRPC_ERROR_UNREF(error_); - gpr_mu_destroy(&mu_); } void HealthCheckClient::NotifyOnHealthChange(grpc_connectivity_state* state, 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 1fa4487c403..6e0123e4925 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 @@ -31,6 +31,7 @@ #include "src/core/lib/gprpp/atomic.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/call_combiner.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/polling_entity.h" @@ -157,7 +158,7 @@ class HealthCheckClient : public InternallyRefCounted { grpc_pollset_set* interested_parties_; // Do not own. RefCountedPtr channelz_node_; - gpr_mu mu_; + Mutex mu_; grpc_connectivity_state state_ = GRPC_CHANNEL_CONNECTING; grpc_error* error_ = GRPC_ERROR_NONE; grpc_connectivity_state* notify_state_ = nullptr; 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 2b1eb92bbd4..90a79843458 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc @@ -33,7 +33,7 @@ #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/gprpp/sync.h" #include "src/core/lib/http/format_request.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/slice/slice_internal.h" 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 867a5c667fc..4423e479d62 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 @@ -88,7 +88,6 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/combiner.h" 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 84b9c41a734..35123633feb 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 @@ -25,7 +25,7 @@ #include #include -#include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/gprpp/sync.h" namespace grpc_core { 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 fdebdf55c17..bcc6598c105 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 @@ -26,6 +26,7 @@ #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/sync.h" namespace grpc_core { @@ -41,9 +42,6 @@ class GrpcLbClientStats : public RefCounted { typedef InlinedVector DroppedCallCounts; - GrpcLbClientStats() { gpr_mu_init(&drop_count_mu_); } - ~GrpcLbClientStats() { gpr_mu_destroy(&drop_count_mu_); } - void AddCallStarted(); void AddCallFinished(bool finished_with_client_failed_to_send, bool finished_known_received); @@ -66,7 +64,7 @@ class GrpcLbClientStats : public RefCounted { gpr_atm num_calls_finished_ = 0; gpr_atm num_calls_finished_with_client_failed_to_send_ = 0; gpr_atm num_calls_finished_known_received_ = 0; - gpr_mu drop_count_mu_; // Guards drop_token_counts_. + Mutex drop_count_mu_; // Guards drop_token_counts_. UniquePtr drop_token_counts_; }; 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 35ca68f717b..637806b4804 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 @@ -27,7 +27,7 @@ #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/transport/connectivity_state.h" @@ -154,13 +154,12 @@ class PickFirst : public LoadBalancingPolicy { /// Lock and data used to capture snapshots of this channels child /// channels and subchannels. This data is consumed by channelz. - gpr_mu child_refs_mu_; + Mutex child_refs_mu_; channelz::ChildRefsList child_subchannels_; channelz::ChildRefsList child_channels_; }; PickFirst::PickFirst(Args args) : LoadBalancingPolicy(std::move(args)) { - gpr_mu_init(&child_refs_mu_); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p created.", this); } @@ -170,7 +169,6 @@ PickFirst::~PickFirst() { if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Destroying Pick First %p", this); } - gpr_mu_destroy(&child_refs_mu_); GPR_ASSERT(subchannel_list_ == nullptr); GPR_ASSERT(latest_pending_subchannel_list_ == 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 74ad1893c6a..b913333fb45 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 @@ -36,8 +36,8 @@ #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/transport/connectivity_state.h" @@ -188,7 +188,7 @@ class RoundRobin : public LoadBalancingPolicy { bool shutdown_ = false; /// 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_; + Mutex child_refs_mu_; channelz::ChildRefsList child_subchannels_; channelz::ChildRefsList child_channels_; }; @@ -240,7 +240,6 @@ RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs* pick, // 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); } @@ -250,7 +249,6 @@ RoundRobin::~RoundRobin() { if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] Destroying Round Robin policy", this); } - gpr_mu_destroy(&child_refs_mu_); GPR_ASSERT(subchannel_list_ == nullptr); GPR_ASSERT(latest_pending_subchannel_list_ == 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 225bae7aa1c..dd782ac53c3 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 @@ -89,9 +89,9 @@ #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/map.h" #include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -278,10 +278,8 @@ class XdsLb : public LoadBalancingPolicy { class LocalityEntry : public InternallyRefCounted { public: explicit LocalityEntry(RefCountedPtr parent) - : parent_(std::move(parent)) { - gpr_mu_init(&child_policy_mu_); - } - ~LocalityEntry() { gpr_mu_destroy(&child_policy_mu_); } + : parent_(std::move(parent)) {} + ~LocalityEntry() = default; void UpdateLocked(xds_grpclb_serverlist* serverlist, LoadBalancingPolicy::Config* child_policy_config, @@ -323,13 +321,10 @@ class XdsLb : public LoadBalancingPolicy { OrphanablePtr pending_child_policy_; // Lock held when modifying the value of child_policy_ or // pending_child_policy_. - gpr_mu child_policy_mu_; + Mutex child_policy_mu_; RefCountedPtr parent_; }; - LocalityMap() { gpr_mu_init(&child_refs_mu_); } - ~LocalityMap() { gpr_mu_destroy(&child_refs_mu_); } - void UpdateLocked(const LocalityList& locality_list, LoadBalancingPolicy::Config* child_policy_config, const grpc_channel_args* args, XdsLb* parent); @@ -343,7 +338,7 @@ class XdsLb : public LoadBalancingPolicy { Map, OrphanablePtr, StringLess> map_; // Lock held while filling child refs for all localities // inside the map - gpr_mu child_refs_mu_; + Mutex child_refs_mu_; }; struct LocalityServerlistEntry { @@ -397,7 +392,7 @@ class XdsLb : public LoadBalancingPolicy { // Mutex to protect the channel to the LB server. This is used when // processing a channelz request. // TODO(juanlishen): Replace this with atomic. - gpr_mu lb_chand_mu_; + Mutex lb_chand_mu_; // Timeout in milliseconds for the LB call. 0 means no deadline. int lb_call_timeout_ms_ = 0; @@ -1090,7 +1085,6 @@ XdsLb::XdsLb(Args args) : LoadBalancingPolicy(std::move(args)), locality_map_(), locality_serverlist_() { - 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); @@ -1114,7 +1108,6 @@ XdsLb::XdsLb(Args args) } XdsLb::~XdsLb() { - gpr_mu_destroy(&lb_chand_mu_); gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); locality_serverlist_.clear(); 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 8f53c33b7fd..4ccd8be29c0 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -48,7 +48,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/gprpp/sync.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/polling_entity.h" diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 9fbec8c3859..e29cd0a6dc3 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -42,8 +42,8 @@ #include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/manual_constructor.h" -#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" @@ -454,13 +454,14 @@ struct Subchannel::ExternalStateWatcher { 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; + { + MutexLock 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; } - 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)); @@ -582,7 +583,6 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, "subchannel"); grpc_connectivity_state_init(&state_and_health_tracker_, GRPC_CHANNEL_IDLE, "subchannel"); - 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(args_, GRPC_ARG_SERVICE_CONFIG)); @@ -629,7 +629,6 @@ Subchannel::~Subchannel() { grpc_connector_unref(connector_); grpc_pollset_set_destroy(pollset_set_); Delete(key_); - gpr_mu_destroy(&mu_); } Subchannel* Subchannel::Create(grpc_connector* connector, @@ -903,7 +902,9 @@ void Subchannel::MaybeStartConnectingLocked() { void Subchannel::OnRetryAlarm(void* arg, grpc_error* error) { Subchannel* c = static_cast(arg); - gpr_mu_lock(&c->mu_); + // TODO(soheilhy): Once subchannel refcounting is simplified, we can get use + // MutexLock instead of ReleasableMutexLock, here. + ReleasableMutexLock lock(&c->mu_); c->have_retry_alarm_ = false; if (c->disconnected_) { error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected", @@ -917,9 +918,9 @@ void Subchannel::OnRetryAlarm(void* arg, grpc_error* error) { if (error == GRPC_ERROR_NONE) { gpr_log(GPR_INFO, "Failed to connect to channel, retrying"); c->ContinueConnectingLocked(); - gpr_mu_unlock(&c->mu_); + lock.Unlock(); } else { - gpr_mu_unlock(&c->mu_); + lock.Unlock(); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } GRPC_ERROR_UNREF(error); @@ -944,24 +945,25 @@ 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 { - gpr_log(GPR_INFO, "Connect failed: %s", grpc_error_string(error)); - c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, + { + MutexLock 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 { + gpr_log(GPR_INFO, "Connect failed: %s", grpc_error_string(error)); + c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, + "connect_failed"); + grpc_connectivity_state_set(&c->state_and_health_tracker_, + GRPC_CHANNEL_TRANSIENT_FAILURE, "connect_failed"); - grpc_connectivity_state_set(&c->state_and_health_tracker_, - GRPC_CHANNEL_TRANSIENT_FAILURE, - "connect_failed"); - c->MaybeStartConnectingLocked(); - GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); + c->MaybeStartConnectingLocked(); + GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); + } } - gpr_mu_unlock(&c->mu_); GRPC_SUBCHANNEL_WEAK_UNREF(c, "on_connecting_finished"); grpc_channel_args_destroy(delete_channel_args); } diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 54bd13b6065..9c2e57d3e05 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -29,6 +29,7 @@ #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/gprpp/sync.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/transport/connectivity_state.h" @@ -263,7 +264,7 @@ class Subchannel { // pollset_set tracking who's interested in a connection being setup. grpc_pollset_set* pollset_set_; // Protects the other members. - gpr_mu mu_; + Mutex mu_; // Refcount // - lower INTERNAL_REF_BITS bits are for internal references: // these do not keep the subchannel open. diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index 9f0169aeaab..b6a660b18fd 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -23,7 +23,7 @@ #include "src/core/lib/channel/channelz_registry.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/gprpp/sync.h" #include #include diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index 912d524c8db..b68799b6e0e 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -27,8 +27,8 @@ #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/gprpp/sync.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" diff --git a/src/core/lib/gprpp/mutex_lock.h b/src/core/lib/gprpp/mutex_lock.h deleted file mode 100644 index 54751d5fe46..00000000000 --- a/src/core/lib/gprpp/mutex_lock.h +++ /dev/null @@ -1,42 +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_LIB_GPRPP_MUTEX_LOCK_H -#define GRPC_CORE_LIB_GPRPP_MUTEX_LOCK_H - -#include - -#include - -namespace grpc_core { - -class MutexLock { - public: - explicit MutexLock(gpr_mu* mu) : mu_(mu) { gpr_mu_lock(mu); } - ~MutexLock() { gpr_mu_unlock(mu_); } - - MutexLock(const MutexLock&) = delete; - MutexLock& operator=(const MutexLock&) = delete; - - private: - gpr_mu* const mu_; -}; - -} // namespace grpc_core - -#endif /* GRPC_CORE_LIB_GPRPP_MUTEX_LOCK_H */ diff --git a/src/core/lib/gprpp/sync.h b/src/core/lib/gprpp/sync.h new file mode 100644 index 00000000000..895ca60fec0 --- /dev/null +++ b/src/core/lib/gprpp/sync.h @@ -0,0 +1,126 @@ +/* + * + * 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_SYNC_H +#define GRPC_CORE_LIB_GPRPP_SYNC_H + +#include + +#include +#include +#include +#include + +// The core library is not accessible in C++ codegen headers, and vice versa. +// Thus, we need to have duplicate headers with similar functionality. +// Make sure any change to this file is also reflected in +// include/grpcpp/impl/codegen/sync.h. +// +// Whenever possible, prefer using this file over +// since this file doesn't rely on g_core_codegen_interface and hence does not +// pay the costs of virtual function calls. + +namespace grpc_core { + +class Mutex { + public: + Mutex() { gpr_mu_init(&mu_); } + ~Mutex() { gpr_mu_destroy(&mu_); } + + Mutex(const Mutex&) = delete; + Mutex& operator=(const Mutex&) = delete; + + gpr_mu* get() { return &mu_; } + const gpr_mu* get() const { return &mu_; } + + private: + gpr_mu mu_; +}; + +// MutexLock is a std:: +class MutexLock { + public: + explicit MutexLock(Mutex* mu) : mu_(mu->get()) { gpr_mu_lock(mu_); } + explicit MutexLock(gpr_mu* mu) : mu_(mu) { gpr_mu_lock(mu_); } + ~MutexLock() { gpr_mu_unlock(mu_); } + + MutexLock(const MutexLock&) = delete; + MutexLock& operator=(const MutexLock&) = delete; + + private: + gpr_mu* const mu_; +}; + +class ReleasableMutexLock { + public: + explicit ReleasableMutexLock(Mutex* mu) : mu_(mu->get()) { gpr_mu_lock(mu_); } + explicit ReleasableMutexLock(gpr_mu* mu) : mu_(mu) { gpr_mu_lock(mu_); } + ~ReleasableMutexLock() { + if (!released_) gpr_mu_unlock(mu_); + } + + ReleasableMutexLock(const ReleasableMutexLock&) = delete; + ReleasableMutexLock& operator=(const ReleasableMutexLock&) = delete; + + void Lock() { + GPR_DEBUG_ASSERT(released_); + gpr_mu_lock(mu_); + released_ = false; + } + + void Unlock() { + GPR_DEBUG_ASSERT(!released_); + released_ = true; + gpr_mu_unlock(mu_); + } + + private: + gpr_mu* const mu_; + bool released_ = false; +}; + +class CondVar { + public: + CondVar() { gpr_cv_init(&cv_); } + ~CondVar() { gpr_cv_destroy(&cv_); } + + CondVar(const CondVar&) = delete; + CondVar& operator=(const CondVar&) = delete; + + void Signal() { gpr_cv_signal(&cv_); } + void Broadcast() { gpr_cv_broadcast(&cv_); } + + int Wait(Mutex* mu) { return Wait(mu, gpr_inf_future(GPR_CLOCK_REALTIME)); } + int Wait(Mutex* mu, const gpr_timespec& deadline) { + return gpr_cv_wait(&cv_, mu->get(), deadline); + } + + template + void WaitUntil(Mutex* mu, Predicate pred) { + while (!pred()) { + Wait(mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + } + } + + private: + gpr_cv cv_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_GPRPP_SYNC_H */ diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index 01be46c9f68..c387f8359a0 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -47,7 +47,7 @@ #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/gprpp/sync.h" #include "src/core/lib/iomgr/block_annotate.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/is_epollexclusive_available.h" diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index b67d4f12252..57d975564b1 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -33,7 +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/gprpp/sync.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/call_combiner.h" #include "src/core/lib/iomgr/combiner.h" diff --git a/src/core/tsi/ssl/session_cache/ssl_session_cache.cc b/src/core/tsi/ssl/session_cache/ssl_session_cache.cc index f9184bcc34f..ba0745a2359 100644 --- a/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +++ b/src/core/tsi/ssl/session_cache/ssl_session_cache.cc @@ -18,7 +18,7 @@ #include -#include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/tsi/ssl/session_cache/ssl_session.h" #include "src/core/tsi/ssl/session_cache/ssl_session_cache.h" diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index db59d4d8416..2d5e74163a9 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -232,7 +232,7 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { 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_); + grpc::internal::MutexLock l(&mu_); if (callback_cq_ == nullptr) { auto* shutdown_callback = new ShutdownCallback; callback_cq_ = new CompletionQueue(grpc_completion_queue_attributes{ diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc index efb59c71a8c..b4fce79b99a 100644 --- a/src/cpp/client/client_context.cc +++ b/src/cpp/client/client_context.cc @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -84,7 +85,7 @@ void ClientContext::AddMetadata(const grpc::string& meta_key, void ClientContext::set_call(grpc_call* call, const std::shared_ptr& channel) { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); GPR_ASSERT(call_ == nullptr); call_ = call; channel_ = channel; @@ -114,7 +115,7 @@ void ClientContext::set_compression_algorithm( } void ClientContext::TryCancel() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); if (call_) { SendCancelToInterceptors(); grpc_call_cancel(call_, nullptr); diff --git a/src/cpp/server/dynamic_thread_pool.cc b/src/cpp/server/dynamic_thread_pool.cc index ef99d6459f7..c8bdbdea7e6 100644 --- a/src/cpp/server/dynamic_thread_pool.cc +++ b/src/cpp/server/dynamic_thread_pool.cc @@ -21,6 +21,7 @@ #include #include +#include #include "src/core/lib/gprpp/thd.h" @@ -40,27 +41,27 @@ DynamicThreadPool::DynamicThread::~DynamicThread() { thd_.Join(); } void DynamicThreadPool::DynamicThread::ThreadFunc() { pool_->ThreadFunc(); // Now that we have killed ourselves, we should reduce the thread count - std::unique_lock lock(pool_->mu_); + grpc_core::MutexLock lock(&pool_->mu_); pool_->nthreads_--; // Move ourselves to dead list pool_->dead_threads_.push_back(this); if ((pool_->shutdown_) && (pool_->nthreads_ == 0)) { - pool_->shutdown_cv_.notify_one(); + pool_->shutdown_cv_.Signal(); } } void DynamicThreadPool::ThreadFunc() { for (;;) { // Wait until work is available or we are shutting down. - std::unique_lock lock(mu_); + grpc_core::ReleasableMutexLock lock(&mu_); if (!shutdown_ && callbacks_.empty()) { // If there are too many threads waiting, then quit this thread if (threads_waiting_ >= reserve_threads_) { break; } threads_waiting_++; - cv_.wait(lock); + cv_.Wait(&mu_); threads_waiting_--; } // Drain callbacks before considering shutdown to ensure all work @@ -68,7 +69,7 @@ void DynamicThreadPool::ThreadFunc() { if (!callbacks_.empty()) { auto cb = callbacks_.front(); callbacks_.pop(); - lock.unlock(); + lock.Unlock(); cb(); } else if (shutdown_) { break; @@ -82,7 +83,7 @@ DynamicThreadPool::DynamicThreadPool(int reserve_threads) nthreads_(0), threads_waiting_(0) { for (int i = 0; i < reserve_threads_; i++) { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); nthreads_++; new DynamicThread(this); } @@ -95,17 +96,17 @@ void DynamicThreadPool::ReapThreads(std::list* tlist) { } DynamicThreadPool::~DynamicThreadPool() { - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); shutdown_ = true; - cv_.notify_all(); + cv_.Broadcast(); while (nthreads_ != 0) { - shutdown_cv_.wait(lock); + shutdown_cv_.Wait(&mu_); } ReapThreads(&dead_threads_); } void DynamicThreadPool::Add(const std::function& callback) { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); // Add works to the callbacks list callbacks_.push(callback); // Increase pool size or notify as needed @@ -114,7 +115,7 @@ void DynamicThreadPool::Add(const std::function& callback) { nthreads_++; new DynamicThread(this); } else { - cv_.notify_one(); + cv_.Signal(); } // Also use this chance to harvest dead threads if (!dead_threads_.empty()) { diff --git a/src/cpp/server/dynamic_thread_pool.h b/src/cpp/server/dynamic_thread_pool.h index 5df8cf2b043..4ae0257d40b 100644 --- a/src/cpp/server/dynamic_thread_pool.h +++ b/src/cpp/server/dynamic_thread_pool.h @@ -27,6 +27,7 @@ #include +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/gprpp/thd.h" #include "src/cpp/server/thread_pool_interface.h" @@ -50,9 +51,9 @@ class DynamicThreadPool final : public ThreadPoolInterface { grpc_core::Thread thd_; void ThreadFunc(); }; - std::mutex mu_; - std::condition_variable cv_; - std::condition_variable shutdown_cv_; + grpc_core::Mutex mu_; + grpc_core::CondVar cv_; + grpc_core::CondVar shutdown_cv_; bool shutdown_; std::queue> callbacks_; int reserve_threads_; diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index 44aebd2f9d9..01bc51aa213 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -41,7 +41,7 @@ DefaultHealthCheckService::DefaultHealthCheckService() { void DefaultHealthCheckService::SetServingStatus( const grpc::string& service_name, bool serving) { - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); if (shutdown_) { // Set to NOT_SERVING in case service_name is not in the map. serving = false; @@ -51,7 +51,7 @@ void DefaultHealthCheckService::SetServingStatus( void DefaultHealthCheckService::SetServingStatus(bool serving) { const ServingStatus status = serving ? SERVING : NOT_SERVING; - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); if (shutdown_) { return; } @@ -62,7 +62,7 @@ void DefaultHealthCheckService::SetServingStatus(bool serving) { } void DefaultHealthCheckService::Shutdown() { - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); if (shutdown_) { return; } @@ -76,7 +76,7 @@ void DefaultHealthCheckService::Shutdown() { DefaultHealthCheckService::ServingStatus DefaultHealthCheckService::GetServingStatus( const grpc::string& service_name) const { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); auto it = services_map_.find(service_name); if (it == services_map_.end()) { return NOT_FOUND; @@ -88,7 +88,7 @@ DefaultHealthCheckService::GetServingStatus( void DefaultHealthCheckService::RegisterCallHandler( const grpc::string& service_name, std::shared_ptr handler) { - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); ServiceData& service_data = services_map_[service_name]; service_data.AddCallHandler(handler /* copies ref */); HealthCheckServiceImpl::CallHandler* h = handler.get(); @@ -98,7 +98,7 @@ void DefaultHealthCheckService::RegisterCallHandler( void DefaultHealthCheckService::UnregisterCallHandler( const grpc::string& service_name, const std::shared_ptr& handler) { - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); auto it = services_map_.find(service_name); if (it == services_map_.end()) return; ServiceData& service_data = it->second; @@ -166,7 +166,7 @@ DefaultHealthCheckService::HealthCheckServiceImpl::~HealthCheckServiceImpl() { // We will reach here after the server starts shutting down. shutdown_ = true; { - std::unique_lock lock(cq_shutdown_mu_); + grpc_core::MutexLock lock(&cq_shutdown_mu_); cq_->Shutdown(); } thread_->Join(); @@ -266,7 +266,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: std::make_shared(cq, database, service); CheckCallHandler* handler = static_cast(self.get()); { - std::unique_lock lock(service->cq_shutdown_mu_); + grpc_core::MutexLock lock(&service->cq_shutdown_mu_); if (service->shutdown_) return; // Request a Check() call. handler->next_ = @@ -311,7 +311,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: } // Send response. { - std::unique_lock lock(service_->cq_shutdown_mu_); + grpc_core::MutexLock lock(&service_->cq_shutdown_mu_); if (!service_->shutdown_) { next_ = CallableTag(std::bind(&CheckCallHandler::OnFinishDone, this, @@ -347,7 +347,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: std::make_shared(cq, database, service); WatchCallHandler* handler = static_cast(self.get()); { - std::unique_lock lock(service->cq_shutdown_mu_); + grpc_core::MutexLock lock(&service->cq_shutdown_mu_); if (service->shutdown_) return; // Request AsyncNotifyWhenDone(). handler->on_done_notified_ = @@ -402,7 +402,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: SendHealth(std::shared_ptr self, ServingStatus status) { - std::unique_lock lock(send_mu_); + grpc_core::MutexLock lock(&send_mu_); // If there's already a send in flight, cache the new status, and // we'll start a new send for it when the one in flight completes. if (send_in_flight_) { @@ -420,7 +420,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: ByteBuffer response; bool success = service_->EncodeResponse(status, &response); // Grab shutdown lock and send response. - std::unique_lock cq_lock(service_->cq_shutdown_mu_); + grpc_core::MutexLock cq_lock(&service_->cq_shutdown_mu_); if (service_->shutdown_) { SendFinishLocked(std::move(self), Status::CANCELLED); return; @@ -442,7 +442,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: SendFinish(std::move(self), Status::CANCELLED); return; } - std::unique_lock lock(send_mu_); + grpc_core::MutexLock lock(&send_mu_); send_in_flight_ = false; // If we got a new status since we started the last send, start a // new send for it. @@ -456,7 +456,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: SendFinish(std::shared_ptr self, const Status& status) { if (finish_called_) return; - std::unique_lock cq_lock(service_->cq_shutdown_mu_); + grpc_core::MutexLock cq_lock(&service_->cq_shutdown_mu_); if (service_->shutdown_) return; SendFinishLocked(std::move(self), status); } diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h index 9551cd2e2cf..4b926efdfe8 100644 --- a/src/cpp/server/health/default_health_check_service.h +++ b/src/cpp/server/health/default_health_check_service.h @@ -31,6 +31,7 @@ #include #include +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/gprpp/thd.h" namespace grpc { @@ -197,7 +198,7 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface { GenericServerAsyncWriter stream_; ServerContext ctx_; - std::mutex send_mu_; + grpc_core::Mutex send_mu_; bool send_in_flight_ = false; // Guarded by mu_. ServingStatus pending_status_ = NOT_FOUND; // Guarded by mu_. @@ -226,7 +227,7 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface { // To synchronize the operations related to shutdown state of cq_, so that // we don't enqueue new tags into cq_ after it is already shut down. - std::mutex cq_shutdown_mu_; + grpc_core::Mutex cq_shutdown_mu_; std::atomic_bool shutdown_{false}; std::unique_ptr<::grpc_core::Thread> thread_; }; @@ -273,7 +274,7 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface { const grpc::string& service_name, const std::shared_ptr& handler); - mutable std::mutex mu_; + mutable grpc_core::Mutex mu_; bool shutdown_ = false; // Guarded by mu_. std::map services_map_; // Guarded by mu_. std::unique_ptr impl_; diff --git a/src/cpp/server/load_reporter/load_reporter.cc b/src/cpp/server/load_reporter/load_reporter.cc index 464063a13ff..422ea62efd5 100644 --- a/src/cpp/server/load_reporter/load_reporter.cc +++ b/src/cpp/server/load_reporter/load_reporter.cc @@ -239,7 +239,7 @@ grpc::string LoadReporter::GenerateLbId() { ::grpc::lb::v1::LoadBalancingFeedback LoadReporter::GenerateLoadBalancingFeedback() { - std::unique_lock lock(feedback_mu_); + grpc_core::ReleasableMutexLock lock(&feedback_mu_); auto now = std::chrono::system_clock::now(); // Discard records outside the window until there is only one record // outside the window, which is used as the base for difference. @@ -277,7 +277,7 @@ LoadReporter::GenerateLoadBalancingFeedback() { double cpu_limit = newest->cpu_limit - oldest->cpu_limit; std::chrono::duration duration_seconds = newest->end_time - oldest->end_time; - lock.unlock(); + lock.Unlock(); ::grpc::lb::v1::LoadBalancingFeedback feedback; feedback.set_server_utilization(static_cast(cpu_usage / cpu_limit)); feedback.set_calls_per_second( @@ -290,7 +290,7 @@ LoadReporter::GenerateLoadBalancingFeedback() { ::google::protobuf::RepeatedPtrField<::grpc::lb::v1::Load> LoadReporter::GenerateLoads(const grpc::string& hostname, const grpc::string& lb_id) { - std::lock_guard lock(store_mu_); + grpc_core::MutexLock lock(&store_mu_); auto assigned_stores = load_data_store_.GetAssignedStores(hostname, lb_id); GPR_ASSERT(assigned_stores != nullptr); GPR_ASSERT(!assigned_stores->empty()); @@ -371,7 +371,7 @@ void LoadReporter::AppendNewFeedbackRecord(uint64_t rpcs, uint64_t errors) { // This will make the load balancing feedback generation a no-op. cpu_stats = {0, 0}; } - std::unique_lock lock(feedback_mu_); + grpc_core::MutexLock lock(&feedback_mu_); feedback_records_.emplace_back(std::chrono::system_clock::now(), rpcs, errors, cpu_stats.first, cpu_stats.second); } @@ -379,7 +379,7 @@ void LoadReporter::AppendNewFeedbackRecord(uint64_t rpcs, uint64_t errors) { void LoadReporter::ReportStreamCreated(const grpc::string& hostname, const grpc::string& lb_id, const grpc::string& load_key) { - std::lock_guard lock(store_mu_); + grpc_core::MutexLock lock(&store_mu_); load_data_store_.ReportStreamCreated(hostname, lb_id, load_key); gpr_log(GPR_INFO, "[LR %p] Report stream created (host: %s, LB ID: %s, load key: %s).", @@ -388,7 +388,7 @@ void LoadReporter::ReportStreamCreated(const grpc::string& hostname, void LoadReporter::ReportStreamClosed(const grpc::string& hostname, const grpc::string& lb_id) { - std::lock_guard lock(store_mu_); + grpc_core::MutexLock lock(&store_mu_); load_data_store_.ReportStreamClosed(hostname, lb_id); gpr_log(GPR_INFO, "[LR %p] Report stream closed (host: %s, LB ID: %s).", this, hostname.c_str(), lb_id.c_str()); @@ -407,7 +407,7 @@ void LoadReporter::ProcessViewDataCallStart( LoadRecordKey key(client_ip_and_token, user_id); LoadRecordValue value = LoadRecordValue(start_count); { - std::unique_lock lock(store_mu_); + grpc_core::MutexLock lock(&store_mu_); load_data_store_.MergeRow(host, key, value); } } @@ -459,7 +459,7 @@ void LoadReporter::ProcessViewDataCallEnd( LoadRecordValue value = LoadRecordValue( 0, ok_count, error_count, bytes_sent, bytes_received, latency_ms); { - std::unique_lock lock(store_mu_); + grpc_core::MutexLock lock(&store_mu_); load_data_store_.MergeRow(host, key, value); } } @@ -486,7 +486,7 @@ void LoadReporter::ProcessViewDataOtherCallMetrics( LoadRecordValue value = LoadRecordValue( metric_name, static_cast(num_calls), total_metric_value); { - std::unique_lock lock(store_mu_); + grpc_core::MutexLock lock(&store_mu_); load_data_store_.MergeRow(host, key, value); } } diff --git a/src/cpp/server/load_reporter/load_reporter.h b/src/cpp/server/load_reporter/load_reporter.h index b2254d56016..766e02a407a 100644 --- a/src/cpp/server/load_reporter/load_reporter.h +++ b/src/cpp/server/load_reporter/load_reporter.h @@ -29,6 +29,7 @@ #include #include +#include "src/core/lib/gprpp/sync.h" #include "src/cpp/server/load_reporter/load_data_store.h" #include "src/proto/grpc/lb/v1/load_reporter.grpc.pb.h" @@ -212,11 +213,11 @@ class LoadReporter { std::atomic next_lb_id_{0}; const std::chrono::seconds feedback_sample_window_seconds_; - std::mutex feedback_mu_; + grpc_core::Mutex feedback_mu_; std::deque feedback_records_; // TODO(juanlishen): Lock in finer grain. Locking the whole store may be // too expensive. - std::mutex store_mu_; + grpc_core::Mutex store_mu_; LoadDataStore load_data_store_; std::unique_ptr census_view_provider_; std::unique_ptr cpu_stats_provider_; 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 859ad9946c8..9eaab5d6366 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 @@ -48,7 +48,7 @@ LoadReporterAsyncServiceImpl::~LoadReporterAsyncServiceImpl() { // We will reach here after the server starts shutting down. shutdown_ = true; { - std::unique_lock lock(cq_shutdown_mu_); + grpc_core::MutexLock lock(&cq_shutdown_mu_); cq_->Shutdown(); } if (next_fetch_and_sample_alarm_ != nullptr) @@ -62,7 +62,7 @@ void LoadReporterAsyncServiceImpl::ScheduleNextFetchAndSample() { gpr_time_from_millis(kFetchAndSampleIntervalSeconds * 1000, GPR_TIMESPAN)); { - std::unique_lock lock(cq_shutdown_mu_); + grpc_core::MutexLock lock(&cq_shutdown_mu_); if (shutdown_) return; // TODO(juanlishen): Improve the Alarm implementation to reuse a single // instance for multiple events. @@ -119,7 +119,7 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::CreateAndStart( std::make_shared(cq, service, load_reporter); ReportLoadHandler* p = handler.get(); { - std::unique_lock lock(service->cq_shutdown_mu_); + grpc_core::MutexLock lock(&service->cq_shutdown_mu_); if (service->shutdown_) return; p->on_done_notified_ = CallableTag(std::bind(&ReportLoadHandler::OnDoneNotified, p, @@ -164,9 +164,9 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::OnRequestDelivered( // instance will deallocate itself when it's done. CreateAndStart(cq_, service_, load_reporter_); { - std::unique_lock lock(service_->cq_shutdown_mu_); + grpc_core::ReleasableMutexLock lock(&service_->cq_shutdown_mu_); if (service_->shutdown_) { - lock.release()->unlock(); + lock.Unlock(); Shutdown(std::move(self), "OnRequestDelivered"); return; } @@ -222,9 +222,9 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::OnReadDone( SendReport(self, true /* ok */); // Expect this read to fail. { - std::unique_lock lock(service_->cq_shutdown_mu_); + grpc_core::ReleasableMutexLock lock(&service_->cq_shutdown_mu_); if (service_->shutdown_) { - lock.release()->unlock(); + lock.Unlock(); Shutdown(std::move(self), "OnReadDone"); return; } @@ -254,9 +254,9 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::ScheduleNextReport( gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_millis(load_report_interval_ms_, GPR_TIMESPAN)); { - std::unique_lock lock(service_->cq_shutdown_mu_); + grpc_core::ReleasableMutexLock lock(&service_->cq_shutdown_mu_); if (service_->shutdown_) { - lock.release()->unlock(); + lock.Unlock(); Shutdown(std::move(self), "ScheduleNextReport"); return; } @@ -294,9 +294,9 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::SendReport( call_status_ = INITIAL_RESPONSE_SENT; } { - std::unique_lock lock(service_->cq_shutdown_mu_); + grpc_core::ReleasableMutexLock lock(&service_->cq_shutdown_mu_); if (service_->shutdown_) { - lock.release()->unlock(); + lock.Unlock(); Shutdown(std::move(self), "SendReport"); return; } @@ -342,7 +342,7 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::Shutdown( // OnRequestDelivered() may be called after OnDoneNotified(), so we need to // try to Finish() every time we are in Shutdown(). if (call_status_ >= DELIVERED && call_status_ < FINISH_CALLED) { - std::unique_lock lock(service_->cq_shutdown_mu_); + grpc_core::MutexLock lock(&service_->cq_shutdown_mu_); if (!service_->shutdown_) { on_finish_done_ = CallableTag(std::bind(&ReportLoadHandler::OnFinishDone, this, diff --git a/src/cpp/server/load_reporter/load_reporter_async_service_impl.h b/src/cpp/server/load_reporter/load_reporter_async_service_impl.h index 6fc577ff493..3087cbfc04d 100644 --- a/src/cpp/server/load_reporter/load_reporter_async_service_impl.h +++ b/src/cpp/server/load_reporter/load_reporter_async_service_impl.h @@ -25,6 +25,7 @@ #include #include +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/gprpp/thd.h" #include "src/cpp/server/load_reporter/load_reporter.h" @@ -181,7 +182,7 @@ class LoadReporterAsyncServiceImpl std::unique_ptr cq_; // To synchronize the operations related to shutdown state of cq_, so that we // don't enqueue new tags into cq_ after it is already shut down. - std::mutex cq_shutdown_mu_; + grpc_core::Mutex cq_shutdown_mu_; std::atomic_bool shutdown_{false}; std::unique_ptr<::grpc_core::Thread> thread_; std::unique_ptr load_reporter_; diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index aa9fdac9bea..64a6de97d7e 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -388,9 +388,9 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { // 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_); + grpc::internal::MutexLock l(&server_->callback_reqs_mu_); if (--server_->callback_reqs_outstanding_ == 0) { - server_->callback_reqs_done_cv_.notify_one(); + server_->callback_reqs_done_cv_.Signal(); } } @@ -814,12 +814,12 @@ Server::Server( Server::~Server() { { - std::unique_lock lock(mu_); + grpc::internal::ReleasableMutexLock lock(&mu_); if (callback_cq_ != nullptr) { callback_cq_->Shutdown(); } if (started_ && !shutdown_) { - lock.unlock(); + lock.Unlock(); Shutdown(); } else if (!started_) { // Shutdown the completion queues @@ -1051,7 +1051,7 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { } void Server::ShutdownInternal(gpr_timespec deadline) { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); if (shutdown_) { return; } @@ -1102,9 +1102,9 @@ void Server::ShutdownInternal(gpr_timespec deadline) { // 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; }); + grpc::internal::MutexLock cblock(&callback_reqs_mu_); + callback_reqs_done_cv_.WaitUntil( + &callback_reqs_mu_, [this] { return callback_reqs_outstanding_ == 0; }); } // Drain the shutdown queue (if the previous call to AsyncNext() timed out @@ -1114,13 +1114,13 @@ void Server::ShutdownInternal(gpr_timespec deadline) { } shutdown_notified_ = true; - shutdown_cv_.notify_all(); + shutdown_cv_.Broadcast(); } void Server::Wait() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); while (started_ && !shutdown_notified_) { - shutdown_cv_.wait(lock); + shutdown_cv_.Wait(&mu_); } } @@ -1322,7 +1322,7 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { CompletionQueue* Server::CallbackCQ() { // TODO(vjpai): Consider using a single global CQ for the default CQ // if there is no explicit per-server CQ registered - std::lock_guard l(mu_); + grpc::internal::MutexLock l(&mu_); if (callback_cq_ == nullptr) { auto* shutdown_callback = new ShutdownCallback; callback_cq_ = new CompletionQueue(grpc_completion_queue_attributes{ diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index 2bbf0e727a1..eced89d1a79 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -33,6 +33,7 @@ #include #include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/surface/call.h" namespace grpc { @@ -96,7 +97,7 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { } void SetCancelCallback(std::function callback) { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); if (finalized_ && (cancelled_ != 0)) { callback(); @@ -107,7 +108,7 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { } void ClearCancelCallback() { - std::lock_guard g(mu_); + grpc_core::MutexLock g(&mu_); cancel_callback_ = nullptr; } @@ -144,7 +145,7 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { private: bool CheckCancelledNoPluck() { - std::lock_guard g(mu_); + grpc_core::MutexLock lock(&mu_); return finalized_ ? (cancelled_ != 0) : false; } @@ -154,7 +155,7 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { void* tag_; void* core_cq_tag_; grpc_core::RefCount refs_; - std::mutex mu_; + grpc_core::Mutex mu_; bool finalized_; int cancelled_; // This is an int (not bool) because it is passed to core std::function cancel_callback_; @@ -186,7 +187,7 @@ void ServerContext::CompletionOp::FillOps(internal::Call* call) { bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { bool ret = false; - std::unique_lock lock(mu_); + grpc_core::ReleasableMutexLock lock(&mu_); if (done_intercepting_) { /* We are done intercepting. */ if (has_tag_) { @@ -218,14 +219,12 @@ bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { cancel_callback_(); } - // Release the lock since we are going to be calling a callback and - // interceptors now - lock.unlock(); + // Release the lock since we may call a callback and interceptors now. + lock.Unlock(); if (call_cancel && reactor_ != nullptr) { reactor_->MaybeCallOnCancel(); } - /* Add interception point and run through interceptors */ interceptor_methods_.AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_CLOSE); diff --git a/src/cpp/thread_manager/thread_manager.cc b/src/cpp/thread_manager/thread_manager.cc index 3e8606a76fd..2b65352f797 100644 --- a/src/cpp/thread_manager/thread_manager.cc +++ b/src/cpp/thread_manager/thread_manager.cc @@ -62,7 +62,7 @@ ThreadManager::ThreadManager(const char* name, ThreadManager::~ThreadManager() { { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); GPR_ASSERT(num_threads_ == 0); } @@ -72,38 +72,38 @@ ThreadManager::~ThreadManager() { } void ThreadManager::Wait() { - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); while (num_threads_ != 0) { - shutdown_cv_.wait(lock); + shutdown_cv_.Wait(&mu_); } } void ThreadManager::Shutdown() { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); shutdown_ = true; } bool ThreadManager::IsShutdown() { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); return shutdown_; } int ThreadManager::GetMaxActiveThreadsSoFar() { - std::lock_guard list_lock(list_mu_); + grpc_core::MutexLock list_lock(&list_mu_); return max_active_threads_sofar_; } void ThreadManager::MarkAsCompleted(WorkerThread* thd) { { - std::lock_guard list_lock(list_mu_); + grpc_core::MutexLock list_lock(&list_mu_); completed_threads_.push_back(thd); } { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); num_threads_--; if (num_threads_ == 0) { - shutdown_cv_.notify_one(); + shutdown_cv_.Signal(); } } @@ -116,7 +116,7 @@ void ThreadManager::CleanupCompletedThreads() { { // swap out the completed threads list: allows other threads to clean up // more quickly - std::unique_lock lock(list_mu_); + grpc_core::MutexLock lock(&list_mu_); completed_threads.swap(completed_threads_); } for (auto thd : completed_threads) delete thd; @@ -132,7 +132,7 @@ void ThreadManager::Initialize() { } { - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); num_pollers_ = min_pollers_; num_threads_ = min_pollers_; max_active_threads_sofar_ = min_pollers_; @@ -149,7 +149,7 @@ void ThreadManager::MainWorkLoop() { bool ok; WorkStatus work_status = PollForWork(&tag, &ok); - std::unique_lock lock(mu_); + grpc_core::ReleasableMutexLock lock(&mu_); // Reduce the number of pollers by 1 and check what happened with the poll num_pollers_--; bool done = false; @@ -176,30 +176,30 @@ void ThreadManager::MainWorkLoop() { max_active_threads_sofar_ = num_threads_; } // Drop lock before spawning thread to avoid contention - lock.unlock(); + lock.Unlock(); new WorkerThread(this); } else if (num_pollers_ > 0) { // There is still at least some thread polling, so we can go on // even though we are below the number of pollers that we would // like to have (min_pollers_) - lock.unlock(); + lock.Unlock(); } else { // There are no pollers to spare and we couldn't allocate // a new thread, so resources are exhausted! - lock.unlock(); + lock.Unlock(); resource_exhausted = true; } } else { // There are a sufficient number of pollers available so we can do // the work and continue polling with our existing poller threads - lock.unlock(); + lock.Unlock(); } // Lock is always released at this point - do the application work // or return resource exhausted if there is new work but we couldn't // get a thread in which to do it. DoWork(tag, ok, !resource_exhausted); // Take the lock again to check post conditions - lock.lock(); + lock.Lock(); // If we're shutdown, we should finish at this point. if (shutdown_) done = true; break; diff --git a/src/cpp/thread_manager/thread_manager.h b/src/cpp/thread_manager/thread_manager.h index 6f0bd17c5fe..2fbf309d421 100644 --- a/src/cpp/thread_manager/thread_manager.h +++ b/src/cpp/thread_manager/thread_manager.h @@ -26,6 +26,7 @@ #include +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/resource_quota.h" @@ -140,10 +141,10 @@ class ThreadManager { // Protects shutdown_, num_pollers_, num_threads_ and // max_active_threads_sofar_ - std::mutex mu_; + grpc_core::Mutex mu_; bool shutdown_; - std::condition_variable shutdown_cv_; + grpc_core::CondVar shutdown_cv_; // The resource user object to use when requesting quota to create threads // @@ -169,7 +170,7 @@ class ThreadManager { // ever set so far int max_active_threads_sofar_; - std::mutex list_mu_; + grpc_core::Mutex list_mu_; std::list completed_threads_; }; diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index 91419cb257b..d326b2ed37e 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -168,24 +169,24 @@ class ClientChannelStressTest { explicit ServerThread(const grpc::string& type, const grpc::string& server_host, T* service) : type_(type), service_(service) { - std::mutex mu; + grpc::internal::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); + grpc::internal::MutexLock 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; + grpc::internal::CondVar cond; thread_.reset(new std::thread( std::bind(&ServerThread::Start, this, server_host, &mu, &cond))); - cond.wait(lock); + cond.Wait(&mu); 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) { + void Start(const grpc::string& server_host, grpc::internal::Mutex* mu, + grpc::internal::CondVar* 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); + grpc::internal::MutexLock lock(mu); std::ostringstream server_address; server_address << server_host << ":" << port_; ServerBuilder builder; @@ -193,7 +194,7 @@ class ClientChannelStressTest { InsecureServerCredentials()); builder.RegisterService(service_); server_ = builder.BuildAndStart(); - cond->notify_one(); + cond->Signal(); } void Shutdown() { diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 77f9db94acc..6623a2ff55f 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -98,7 +99,7 @@ class MyTestServiceImpl : public TestServiceImpl { Status Echo(ServerContext* context, const EchoRequest* request, EchoResponse* response) override { { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); ++request_count_; } AddClient(context->peer()); @@ -106,29 +107,29 @@ class MyTestServiceImpl : public TestServiceImpl { } int request_count() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); return request_count_; } void ResetCounters() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); request_count_ = 0; } std::set clients() { - std::unique_lock lock(clients_mu_); + grpc::internal::MutexLock lock(&clients_mu_); return clients_; } private: void AddClient(const grpc::string& client) { - std::unique_lock lock(clients_mu_); + grpc::internal::MutexLock lock(&clients_mu_); clients_.insert(client); } - std::mutex mu_; + grpc::internal::Mutex mu_; int request_count_; - std::mutex clients_mu_; + grpc::internal::Mutex clients_mu_; std::set clients_; }; @@ -293,18 +294,18 @@ class ClientLbEnd2endTest : public ::testing::Test { void Start(const grpc::string& server_host) { gpr_log(GPR_INFO, "starting server on port %d", port_); started_ = true; - std::mutex mu; - std::unique_lock lock(mu); - std::condition_variable cond; + grpc::internal::Mutex mu; + grpc::internal::MutexLock lock(&mu); + grpc::internal::CondVar cond; thread_.reset(new std::thread( std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); - cond.wait(lock, [this] { return server_ready_; }); + cond.WaitUntil(&mu, [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) { + void Serve(const grpc::string& server_host, grpc::internal::Mutex* mu, + grpc::internal::CondVar* cond) { std::ostringstream server_address; server_address << server_host << ":" << port_; ServerBuilder builder; @@ -313,9 +314,9 @@ class ClientLbEnd2endTest : public ::testing::Test { builder.AddListeningPort(server_address.str(), std::move(creds)); builder.RegisterService(&service_); server_ = builder.BuildAndStart(); - std::lock_guard lock(*mu); + grpc::internal::MutexLock lock(mu); server_ready_ = true; - cond->notify_one(); + cond->Signal(); } void Shutdown() { @@ -1374,7 +1375,7 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { void TearDown() override { ClientLbEnd2endTest::TearDown(); } int trailers_intercepted() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); return trailers_intercepted_; } @@ -1382,11 +1383,11 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { static void ReportTrailerIntercepted(void* arg) { ClientLbInterceptTrailingMetadataTest* self = static_cast(arg); - std::unique_lock lock(self->mu_); + grpc::internal::MutexLock lock(&self->mu_); self->trailers_intercepted_++; } - std::mutex mu_; + grpc::internal::Mutex mu_; int trailers_intercepted_ = 0; }; diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 0dc3746c2d7..f8d887dd24d 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -85,32 +86,32 @@ template class CountedService : public ServiceType { public: size_t request_count() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); return request_count_; } size_t response_count() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); return response_count_; } void IncreaseResponseCount() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); ++response_count_; } void IncreaseRequestCount() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); ++request_count_; } void ResetCounters() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); request_count_ = 0; response_count_ = 0; } protected: - std::mutex mu_; + grpc::internal::Mutex mu_; private: size_t request_count_ = 0; @@ -148,18 +149,18 @@ class BackendServiceImpl : public BackendService { void Shutdown() {} std::set clients() { - std::unique_lock lock(clients_mu_); + grpc::internal::MutexLock lock(&clients_mu_); return clients_; } private: void AddClient(const grpc::string& client) { - std::unique_lock lock(clients_mu_); + grpc::internal::MutexLock lock(&clients_mu_); clients_.insert(client); } - std::mutex mu_; - std::mutex clients_mu_; + grpc::internal::Mutex mu_; + grpc::internal::Mutex clients_mu_; std::set clients_; }; @@ -210,7 +211,7 @@ class BalancerServiceImpl : public BalancerService { Status BalanceLoad(ServerContext* context, Stream* stream) override { gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this); { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); if (serverlist_done_) goto done; } { @@ -237,7 +238,7 @@ class BalancerServiceImpl : public BalancerService { } { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); responses_and_delays = responses_and_delays_; } for (const auto& response_and_delay : responses_and_delays) { @@ -245,8 +246,8 @@ class BalancerServiceImpl : public BalancerService { response_and_delay.second); } { - std::unique_lock lock(mu_); - serverlist_cond_.wait(lock, [this] { return serverlist_done_; }); + grpc::internal::MutexLock lock(&mu_); + serverlist_cond_.WaitUntil(&mu_, [this] { return serverlist_done_; }); } if (client_load_reporting_interval_seconds_ > 0) { @@ -257,7 +258,7 @@ class BalancerServiceImpl : public BalancerService { 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_); + grpc::internal::MutexLock lock(&mu_); client_stats_.num_calls_started += request.client_stats().num_calls_started(); client_stats_.num_calls_finished += @@ -274,7 +275,7 @@ class BalancerServiceImpl : public BalancerService { drop_token_count.num_calls(); } load_report_ready_ = true; - load_report_cond_.notify_one(); + load_report_cond_.Signal(); } } } @@ -284,12 +285,12 @@ class BalancerServiceImpl : public BalancerService { } void add_response(const LoadBalanceResponse& response, int send_after_ms) { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); responses_and_delays_.push_back(std::make_pair(response, send_after_ms)); } void Start() { - std::lock_guard lock(mu_); + grpc::internal::MutexLock lock(&mu_); serverlist_done_ = false; load_report_ready_ = false; responses_and_delays_.clear(); @@ -326,17 +327,17 @@ class BalancerServiceImpl : public BalancerService { } const ClientStats& WaitForLoadReport() { - std::unique_lock lock(mu_); - load_report_cond_.wait(lock, [this] { return load_report_ready_; }); + grpc::internal::MutexLock lock(&mu_); + load_report_cond_.WaitUntil(&mu_, [this] { return load_report_ready_; }); load_report_ready_ = false; return client_stats_; } void NotifyDoneWithServerlists() { - std::lock_guard lock(mu_); + grpc::internal::MutexLock lock(&mu_); if (!serverlist_done_) { serverlist_done_ = true; - serverlist_cond_.notify_all(); + serverlist_cond_.Broadcast(); } } @@ -355,10 +356,10 @@ class BalancerServiceImpl : public BalancerService { const int client_load_reporting_interval_seconds_; std::vector responses_and_delays_; - std::mutex mu_; - std::condition_variable load_report_cond_; + grpc::internal::Mutex mu_; + grpc::internal::CondVar load_report_cond_; bool load_report_ready_ = false; - std::condition_variable serverlist_cond_; + grpc::internal::CondVar serverlist_cond_; bool serverlist_done_ = false; ClientStats client_stats_; }; @@ -624,22 +625,22 @@ class GrpclbEnd2endTest : public ::testing::Test { GPR_ASSERT(!running_); running_ = true; service_.Start(); - std::mutex mu; + grpc::internal::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. - std::unique_lock lock(mu); - std::condition_variable cond; + grpc::internal::MutexLock lock(&mu); + grpc::internal::CondVar cond; thread_.reset(new std::thread( std::bind(&ServerThread::Serve, this, server_host, &mu, &cond))); - cond.wait(lock); + cond.Wait(&mu); gpr_log(GPR_INFO, "%s server startup complete", type_.c_str()); } - void Serve(const grpc::string& server_host, std::mutex* mu, - std::condition_variable* cond) { + void Serve(const grpc::string& server_host, grpc::internal::Mutex* mu, + grpc::internal::CondVar* 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); + grpc::internal::MutexLock lock(mu); std::ostringstream server_address; server_address << server_host << ":" << port_; ServerBuilder builder; @@ -648,7 +649,7 @@ class GrpclbEnd2endTest : public ::testing::Test { builder.AddListeningPort(server_address.str(), creds); builder.RegisterService(&service_); server_ = builder.BuildAndStart(); - cond->notify_one(); + cond->Signal(); } void Shutdown() { diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index e30ce0dbcbf..5b8af61ee33 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -188,7 +189,7 @@ class CommonStressTestAsyncServer : public BaseClass { } void TearDown() override { { - std::unique_lock l(mu_); + grpc::internal::MutexLock l(&mu_); this->TearDownStart(); shutting_down_ = true; cq_->Shutdown(); @@ -229,7 +230,7 @@ class CommonStressTestAsyncServer : public BaseClass { } } void RefreshContext(int i) { - std::unique_lock l(mu_); + grpc::internal::MutexLock l(&mu_); if (!shutting_down_) { contexts_[i].state = Context::READY; contexts_[i].srv_ctx.reset(new ServerContext); @@ -253,7 +254,7 @@ class CommonStressTestAsyncServer : public BaseClass { ::grpc::testing::EchoTestService::AsyncService service_; std::unique_ptr cq_; bool shutting_down_; - std::mutex mu_; + grpc::internal::Mutex mu_; std::vector server_threads_; }; @@ -341,9 +342,9 @@ class AsyncClientEnd2endTest : public ::testing::Test { } void Wait() { - std::unique_lock l(mu_); + grpc::internal::MutexLock l(&mu_); while (rpcs_outstanding_ != 0) { - cv_.wait(l); + cv_.Wait(&mu_); } cq_.Shutdown(); @@ -366,7 +367,7 @@ class AsyncClientEnd2endTest : public ::testing::Test { call->response_reader->Finish(&call->response, &call->status, (void*)call); - std::unique_lock l(mu_); + grpc::internal::MutexLock l(&mu_); rpcs_outstanding_++; } } @@ -384,20 +385,20 @@ class AsyncClientEnd2endTest : public ::testing::Test { bool notify; { - std::unique_lock l(mu_); + grpc::internal::MutexLock l(&mu_); rpcs_outstanding_--; notify = (rpcs_outstanding_ == 0); } if (notify) { - cv_.notify_all(); + cv_.Signal(); } } } Common common_; CompletionQueue cq_; - std::mutex mu_; - std::condition_variable cv_; + grpc::internal::Mutex mu_; + grpc::internal::CondVar cv_; int rpcs_outstanding_; }; diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index c767a4485ce..ee248239909 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -84,32 +84,32 @@ template class CountedService : public ServiceType { public: size_t request_count() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); return request_count_; } size_t response_count() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); return response_count_; } void IncreaseResponseCount() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); ++response_count_; } void IncreaseRequestCount() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); ++request_count_; } void ResetCounters() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); request_count_ = 0; response_count_ = 0; } protected: - std::mutex mu_; + grpc::internal::Mutex mu_; private: size_t request_count_ = 0; @@ -145,18 +145,18 @@ class BackendServiceImpl : public BackendService { void Shutdown() {} std::set clients() { - std::unique_lock lock(clients_mu_); + grpc::internal::MutexLock lock(&clients_mu_); return clients_; } private: void AddClient(const grpc::string& client) { - std::unique_lock lock(clients_mu_); + grpc::internal::MutexLock lock(&clients_mu_); clients_.insert(client); } - std::mutex mu_; - std::mutex clients_mu_; + grpc::internal::Mutex mu_; + grpc::internal::Mutex clients_mu_; std::set clients_; }; @@ -208,7 +208,7 @@ class BalancerServiceImpl : public BalancerService { // TODO(juanlishen): Clean up the scoping. gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this); { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); if (serverlist_done_) goto done; } { @@ -234,7 +234,7 @@ class BalancerServiceImpl : public BalancerService { } { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); responses_and_delays = responses_and_delays_; } for (const auto& response_and_delay : responses_and_delays) { @@ -242,8 +242,8 @@ class BalancerServiceImpl : public BalancerService { response_and_delay.second); } { - std::unique_lock lock(mu_); - serverlist_cond_.wait(lock, [this] { return serverlist_done_; }); + grpc::internal::MutexLock lock(&mu_); + serverlist_cond_.WaitUntil(&mu_, [this] { return serverlist_done_; }); } if (client_load_reporting_interval_seconds_ > 0) { @@ -254,7 +254,7 @@ class BalancerServiceImpl : public BalancerService { 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_); + grpc::internal::MutexLock lock(&mu_); client_stats_.num_calls_started += request.client_stats().num_calls_started(); client_stats_.num_calls_finished += @@ -271,7 +271,7 @@ class BalancerServiceImpl : public BalancerService { drop_token_count.num_calls(); } load_report_ready_ = true; - load_report_cond_.notify_one(); + load_report_cond_.Signal(); } } } @@ -281,12 +281,12 @@ class BalancerServiceImpl : public BalancerService { } void add_response(const LoadBalanceResponse& response, int send_after_ms) { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); responses_and_delays_.push_back(std::make_pair(response, send_after_ms)); } void Shutdown() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); NotifyDoneWithServerlistsLocked(); responses_and_delays_.clear(); client_stats_.Reset(); @@ -318,21 +318,21 @@ class BalancerServiceImpl : public BalancerService { } const ClientStats& WaitForLoadReport() { - std::unique_lock lock(mu_); - load_report_cond_.wait(lock, [this] { return load_report_ready_; }); + grpc::internal::MutexLock lock(&mu_); + load_report_cond_.WaitUntil(&mu_, [this] { return load_report_ready_; }); load_report_ready_ = false; return client_stats_; } void NotifyDoneWithServerlists() { - std::lock_guard lock(mu_); + grpc::internal::MutexLock lock(&mu_); NotifyDoneWithServerlistsLocked(); } void NotifyDoneWithServerlistsLocked() { if (!serverlist_done_) { serverlist_done_ = true; - serverlist_cond_.notify_all(); + serverlist_cond_.Broadcast(); } } @@ -351,10 +351,10 @@ class BalancerServiceImpl : public BalancerService { const int client_load_reporting_interval_seconds_; std::vector responses_and_delays_; - std::mutex mu_; - std::condition_variable load_report_cond_; + grpc::internal::Mutex mu_; + grpc::internal::CondVar load_report_cond_; bool load_report_ready_ = false; - std::condition_variable serverlist_cond_; + grpc::internal::CondVar serverlist_cond_; bool serverlist_done_ = false; ClientStats client_stats_; }; @@ -637,22 +637,22 @@ class XdsEnd2endTest : public ::testing::Test { gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); GPR_ASSERT(!running_); running_ = true; - std::mutex mu; + grpc::internal::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. - std::unique_lock lock(mu); - std::condition_variable cond; + grpc::internal::MutexLock lock(&mu); + grpc::internal::CondVar cond; thread_.reset(new std::thread( std::bind(&ServerThread::Serve, this, server_host, &mu, &cond))); - cond.wait(lock); + cond.Wait(&mu); gpr_log(GPR_INFO, "%s server startup complete", type_.c_str()); } - void Serve(const grpc::string& server_host, std::mutex* mu, - std::condition_variable* cond) { + void Serve(const grpc::string& server_host, grpc::internal::Mutex* mu, + grpc::internal::CondVar* 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); + grpc::internal::MutexLock lock(mu); std::ostringstream server_address; server_address << server_host << ":" << port_; ServerBuilder builder; @@ -661,7 +661,7 @@ class XdsEnd2endTest : public ::testing::Test { builder.AddListeningPort(server_address.str(), creds); builder.RegisterService(&service_); server_ = builder.BuildAndStart(); - cond->notify_one(); + cond->Signal(); } void Shutdown() { diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 7274f9588b3..a0a6e952409 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -987,6 +987,7 @@ 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.h \ include/grpcpp/impl/codegen/sync_stream.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/grpc_library.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 80760da0c58..c48c15bd1f5 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -989,6 +989,7 @@ 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.h \ include/grpcpp/impl/codegen/sync_stream.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/grpc_library.h \ @@ -1086,12 +1087,12 @@ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.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/pair.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ +src/core/lib/gprpp/sync.h \ src/core/lib/gprpp/thd.h \ src/core/lib/http/format_request.h \ src/core/lib/http/httpcli.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 8827e4b7e38..dad6c98269d 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1168,12 +1168,12 @@ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.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/pair.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ +src/core/lib/gprpp/sync.h \ src/core/lib/gprpp/thd.h \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index b41d10b61f3..bd6d68bc5c3 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8050,8 +8050,8 @@ "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", - "src/core/lib/gprpp/mutex_lock.h", "src/core/lib/gprpp/pair.h", + "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/profiling/timers.h" ], @@ -8098,8 +8098,8 @@ "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", - "src/core/lib/gprpp/mutex_lock.h", "src/core/lib/gprpp/pair.h", + "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/profiling/timers.h" ], @@ -9880,6 +9880,7 @@ }, { "deps": [ + "grpc++_internal_hdrs_only", "grpc_codegen" ], "headers": [ @@ -10076,6 +10077,7 @@ "gpr", "gpr_base_headers", "grpc++_codegen_base", + "grpc++_internal_hdrs_only", "grpc_base_headers", "grpc_transport_inproc_headers", "health_proto", @@ -10370,6 +10372,20 @@ "third_party": false, "type": "filegroup" }, + { + "deps": [], + "headers": [ + "include/grpcpp/impl/codegen/sync.h" + ], + "is_filegroup": true, + "language": "c++", + "name": "grpc++_internal_hdrs_only", + "src": [ + "include/grpcpp/impl/codegen/sync.h" + ], + "third_party": false, + "type": "filegroup" + }, { "deps": [], "headers": [ From 1c186784cd011d758cac79249dade3460e81cb96 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 16 Apr 2019 14:54:04 -0400 Subject: [PATCH 1878/2143] Make sure grpc::internal::Mutex has enough space for gpr_mu, std::mutex, and pthread_mutex_t. --- include/grpc/impl/codegen/port_platform.h | 10 ++++++++++ include/grpcpp/impl/codegen/sync.h | 17 +++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 0349e31bb3b..d7294d59d41 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -115,6 +115,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 @@ -144,6 +145,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #define GPR_SUPPORT_CHANNELS_FROM_FD 1 #elif defined(__linux__) @@ -170,6 +172,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 @@ -235,6 +238,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifndef GRPC_CFSTREAM #define GPR_SUPPORT_CHANNELS_FROM_FD 1 @@ -260,6 +264,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #define GPR_SUPPORT_CHANNELS_FROM_FD 1 #ifdef _LP64 @@ -283,6 +288,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #define GPR_SUPPORT_CHANNELS_FROM_FD 1 #ifdef _LP64 @@ -303,6 +309,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 @@ -325,6 +332,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 @@ -353,6 +361,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 @@ -378,6 +387,7 @@ #define GPR_POSIX_SYNC 1 #define GPR_POSIX_STRING 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #else #error "Could not auto-detect platform" diff --git a/include/grpcpp/impl/codegen/sync.h b/include/grpcpp/impl/codegen/sync.h index 2ed71eeb9f2..146f182e57b 100644 --- a/include/grpcpp/impl/codegen/sync.h +++ b/include/grpcpp/impl/codegen/sync.h @@ -19,8 +19,15 @@ #ifndef GRPCPP_IMPL_CODEGEN_SYNC_H #define GRPCPP_IMPL_CODEGEN_SYNC_H -#include #include + +#ifdef GPR_HAS_PTHREAD_H +#include +#endif + +#include + +#include #include #include @@ -49,7 +56,13 @@ class Mutex { const gpr_mu* get() const { return &mu_; } private: - gpr_mu mu_; + union { + gpr_mu mu_; + std::mutex do_not_use_sth_; +#ifdef GPR_HAS_PTHREAD_H + pthread_mutex_t do_not_use_pth_; +#endif + }; }; // MutexLock is a std:: From 0d9b4212f887dda4f8bfd0ec71917a7063c01bb0 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 17 Apr 2019 11:41:22 -0700 Subject: [PATCH 1879/2143] Cleanup Clang Tidy errors --- src/core/ext/filters/client_channel/client_channel.cc | 4 ++-- src/core/lib/compression/compression_args.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 0304a265a09..689978a4b32 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -146,7 +146,7 @@ class ChannelData { return picker_.get(); } void AddQueuedPick(QueuedPick* pick, grpc_polling_entity* pollent); - void RemoveQueuedPick(QueuedPick* pick, grpc_polling_entity* pollent); + void RemoveQueuedPick(QueuedPick* to_remove, grpc_polling_entity* pollent); bool received_service_config_data() const { return received_service_config_data_; @@ -223,7 +223,7 @@ class ChannelData { ~ChannelData(); static bool ProcessResolverResultLocked( - void* arg, Resolver::Result* args, const char** lb_policy_name, + void* arg, Resolver::Result* result, const char** lb_policy_name, RefCountedPtr* lb_policy_config); grpc_error* DoPingLocked(grpc_transport_op* op); diff --git a/src/core/lib/compression/compression_args.h b/src/core/lib/compression/compression_args.h index 75084ab0d91..407d6e2b8ca 100644 --- a/src/core/lib/compression/compression_args.h +++ b/src/core/lib/compression/compression_args.h @@ -42,7 +42,7 @@ grpc_channel_args* grpc_channel_args_set_compression_algorithm( * modified to point to the returned instance (which may be different from the * input value of \a a). */ grpc_channel_args* grpc_channel_args_compression_algorithm_set_state( - grpc_channel_args** a, grpc_compression_algorithm algorithm, int enabled); + grpc_channel_args** a, grpc_compression_algorithm algorithm, int state); /** Returns the bitset representing the support state (true for enabled, false * for disabled) for compression algorithms. From 212e4b865734f31603e94cafa2fbf8b9774573a5 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 17 Apr 2019 15:26:07 -0400 Subject: [PATCH 1880/2143] Retire the GRPC_ARENA_INIT_STRATEGY env variable. This is in the hot path and it is not needed anymore. Remove it for good. --- doc/environment_variables.md | 10 -------- src/core/lib/gpr/arena.cc | 50 ++++-------------------------------- src/core/lib/gpr/arena.h | 2 -- src/core/lib/surface/init.cc | 1 - 4 files changed, 5 insertions(+), 58 deletions(-) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index e8d0dbd25f8..43dcd7616e7 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -145,13 +145,3 @@ some configuration as environment variables that can be set. * grpc_cfstream set to 1 to turn on CFStream experiment. With this experiment gRPC uses CFStream API to make TCP connections. The option is only available on iOS platform and when macro GRPC_CFSTREAM is defined. - -* GRPC_ARENA_INIT_STRATEGY - Selects the initialization strategy for blocks allocated in the arena. Valid - values are: - - 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. - - NOTE: This environment variable is experimental and will be removed. Thus, it - should not be relied upon. diff --git a/src/core/lib/gpr/arena.cc b/src/core/lib/gpr/arena.cc index 836a7ca793d..ede5cc48050 100644 --- a/src/core/lib/gpr/arena.cc +++ b/src/core/lib/gpr/arena.cc @@ -29,49 +29,10 @@ #include #include "src/core/lib/gpr/alloc.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/memory.h" -namespace { -enum init_strategy { - NO_INIT, // Do not initialize the arena blocks. - ZERO_INIT, // Initialize arena blocks with 0. - NON_ZERO_INIT, // Initialize arena blocks with a non-zero value. -}; - -gpr_once g_init_strategy_once = GPR_ONCE_INIT; -init_strategy g_init_strategy = NO_INIT; -} // namespace - -static void set_strategy_from_env() { - char* str = gpr_getenv("GRPC_ARENA_INIT_STRATEGY"); - if (str == nullptr) { - g_init_strategy = NO_INIT; - } else if (strcmp(str, "zero_init") == 0) { - g_init_strategy = ZERO_INIT; - } else if (strcmp(str, "non_zero_init") == 0) { - g_init_strategy = NON_ZERO_INIT; - } else { - g_init_strategy = NO_INIT; - } - gpr_free(str); -} - -static void* gpr_arena_alloc_maybe_init(size_t size) { - void* mem = gpr_malloc_aligned(size, GPR_MAX_ALIGNMENT); - gpr_once_init(&g_init_strategy_once, set_strategy_from_env); - if (GPR_UNLIKELY(g_init_strategy != NO_INIT)) { - if (g_init_strategy == ZERO_INIT) { - memset(mem, 0, size); - } else { // NON_ZERO_INIT. - memset(mem, 0xFE, size); - } - } - return mem; -} - -void gpr_arena_init() { - gpr_once_init(&g_init_strategy_once, set_strategy_from_env); +static void* gpr_arena_malloc(size_t size) { + return gpr_malloc_aligned(size, GPR_MAX_ALIGNMENT); } // Uncomment this to use a simple arena that simply allocates the @@ -109,8 +70,7 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) { gpr_mu_lock(&arena->mu); arena->ptrs = (void**)gpr_realloc(arena->ptrs, sizeof(void*) * (arena->num_ptrs + 1)); - void* retval = arena->ptrs[arena->num_ptrs++] = - gpr_arena_alloc_maybe_init(size); + void* retval = arena->ptrs[arena->num_ptrs++] = gpr_arena_malloc(size); gpr_mu_unlock(&arena->mu); return retval; } @@ -154,7 +114,7 @@ struct gpr_arena { gpr_arena* gpr_arena_create(size_t initial_size) { initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size); - return new (gpr_arena_alloc_maybe_init( + return new (gpr_arena_malloc( GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size)) gpr_arena(initial_size); } @@ -179,7 +139,7 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) { // sizing historesis (that is, most calls should have a large enough initial // zone and will not need to grow the arena). gpr_mu_lock(&arena->arena_growth_mutex); - zone* z = new (gpr_arena_alloc_maybe_init( + zone* z = new (gpr_arena_malloc( GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + size)) zone(); arena->last_zone->next = z; arena->last_zone = z; diff --git a/src/core/lib/gpr/arena.h b/src/core/lib/gpr/arena.h index 069892b2282..6d2a073dd58 100644 --- a/src/core/lib/gpr/arena.h +++ b/src/core/lib/gpr/arena.h @@ -37,7 +37,5 @@ gpr_arena* gpr_arena_create(size_t initial_size); void* gpr_arena_alloc(gpr_arena* arena, size_t size); // Destroy an arena, returning the total number of bytes allocated size_t gpr_arena_destroy(gpr_arena* arena); -// Initializes the Arena component. -void gpr_arena_init(); #endif /* GRPC_CORE_LIB_GPR_ARENA_H */ diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index b67d4f12252..a19e1c94505 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -133,7 +133,6 @@ void grpc_init(void) { } grpc_core::Fork::GlobalInit(); grpc_fork_handlers_auto_register(); - gpr_arena_init(); grpc_stats_init(); grpc_slice_intern_init(); grpc_mdctx_global_init(); From 0468a803b44ece5fe03986e90d15568e6c965637 Mon Sep 17 00:00:00 2001 From: Keith Moyer Date: Wed, 10 Apr 2019 14:01:45 -0700 Subject: [PATCH 1881/2143] Add missing sha256 for http_archive deps --- bazel/grpc_deps.bzl | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 864a0824980..a4e6509782d 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -110,6 +110,8 @@ def grpc_deps(): http_archive( name = "boringssl", # on the chromium-stable-with-bazel branch + # NOTE: This URL generates a tarball containing dynamic date + # information, so the sha256 is not consistent. url = "https://boringssl.googlesource.com/boringssl/+archive/afc30d43eef92979b05776ec0963c9cede5fb80f.tar.gz", ) @@ -117,6 +119,7 @@ def grpc_deps(): http_archive( name = "com_github_madler_zlib", build_file = "@com_github_grpc_grpc//third_party:zlib.BUILD", + sha256 = "6d4d6640ca3121620995ee255945161821218752b551a1a180f4215f7d124d45", strip_prefix = "zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f", url = "https://github.com/madler/zlib/archive/cacf7f1d4e3d44d871b605da3b647f07d718623f.tar.gz", ) @@ -124,6 +127,7 @@ def grpc_deps(): if "com_google_protobuf" not in native.existing_rules(): http_archive( name = "com_google_protobuf", + sha256 = "cf9e2fb1d2cd30ec9d51ff1749045208bd641f290f64b85046485934b0e03783", strip_prefix = "protobuf-582743bf40c5d3639a70f98f183914a2c0cd0680", url = "https://github.com/google/protobuf/archive/582743bf40c5d3639a70f98f183914a2c0cd0680.tar.gz", ) @@ -132,6 +136,7 @@ def grpc_deps(): http_archive( name = "com_github_nanopb_nanopb", build_file = "@com_github_grpc_grpc//third_party:nanopb.BUILD", + sha256 = "8bbbb1e78d4ddb0a1919276924ab10d11b631df48b657d960e0c795a25515735", strip_prefix = "nanopb-f8ac463766281625ad710900479130c7fcb4d63b", url = "https://github.com/nanopb/nanopb/archive/f8ac463766281625ad710900479130c7fcb4d63b.tar.gz", ) @@ -140,6 +145,7 @@ def grpc_deps(): http_archive( name = "com_github_google_googletest", build_file = "@com_github_grpc_grpc//third_party:gtest.BUILD", + sha256 = "175a22300b3450e27e5f2e6f95cc9abca74617cbc21a1e0ed19bdfbd22ea0305", strip_prefix = "googletest-ec44c6c1675c25b9827aacd08c02433cccde7780", url = "https://github.com/google/googletest/archive/ec44c6c1675c25b9827aacd08c02433cccde7780.tar.gz", ) @@ -147,6 +153,7 @@ def grpc_deps(): if "com_github_gflags_gflags" not in native.existing_rules(): http_archive( name = "com_github_gflags_gflags", + sha256 = "63ae70ea3e05780f7547d03503a53de3a7d2d83ad1caaa443a31cb20aea28654", strip_prefix = "gflags-28f50e0fed19872e0fd50dd23ce2ee8cd759338e", url = "https://github.com/gflags/gflags/archive/28f50e0fed19872e0fd50dd23ce2ee8cd759338e.tar.gz", ) @@ -154,6 +161,7 @@ def grpc_deps(): if "com_github_google_benchmark" not in native.existing_rules(): http_archive( name = "com_github_google_benchmark", + sha256 = "c7682e9007ddfd94072647abab3e89ffd9084089460ae47d67060974467b58bf", strip_prefix = "benchmark-e776aa0275e293707b6a0901e0e8d8a8a3679508", url = "https://github.com/google/benchmark/archive/e776aa0275e293707b6a0901e0e8d8a8a3679508.tar.gz", ) @@ -162,6 +170,7 @@ def grpc_deps(): http_archive( name = "com_github_cares_cares", build_file = "@com_github_grpc_grpc//third_party:cares/cares.BUILD", + sha256 = "e8c2751ddc70fed9dc6f999acd92e232d5846f009ee1674f8aee81f19b2b915a", strip_prefix = "c-ares-e982924acee7f7313b4baa4ee5ec000c5e373c30", url = "https://github.com/c-ares/c-ares/archive/e982924acee7f7313b4baa4ee5ec000c5e373c30.tar.gz", ) @@ -169,6 +178,7 @@ def grpc_deps(): if "com_google_absl" not in native.existing_rules(): http_archive( name = "com_google_absl", + sha256 = "5fe2a3a8f8378e81d4d3db6541f48030e04233ccd2d6c7e9d981ed577b314ae8", strip_prefix = "abseil-cpp-308ce31528a7edfa39f5f6d36142278a0ae1bf45", url = "https://github.com/abseil/abseil-cpp/archive/308ce31528a7edfa39f5f6d36142278a0ae1bf45.tar.gz", ) @@ -176,12 +186,12 @@ def grpc_deps(): if "bazel_toolchains" not in native.existing_rules(): http_archive( name = "bazel_toolchains", + sha256 = "67335b3563d9b67dc2550b8f27cc689b64fadac491e69ce78763d9ba894cc5cc", strip_prefix = "bazel-toolchains-cddc376d428ada2927ad359211c3e356bd9c9fbb", urls = [ "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/cddc376d428ada2927ad359211c3e356bd9c9fbb.tar.gz", "https://github.com/bazelbuild/bazel-toolchains/archive/cddc376d428ada2927ad359211c3e356bd9c9fbb.tar.gz", ], - sha256 = "67335b3563d9b67dc2550b8f27cc689b64fadac491e69ce78763d9ba894cc5cc", ) if "bazel_skylib" not in native.existing_rules(): @@ -195,6 +205,7 @@ def grpc_deps(): if "io_opencensus_cpp" not in native.existing_rules(): http_archive( name = "io_opencensus_cpp", + sha256 = "3436ca23dc1b3345186defd0f46d64244079ba3d3234a0c5d6ef5e8d5d06c8b5", strip_prefix = "opencensus-cpp-9b1e354e89bf3d92aedc00af45b418ce870f3d77", url = "https://github.com/census-instrumentation/opencensus-cpp/archive/9b1e354e89bf3d92aedc00af45b418ce870f3d77.tar.gz", ) @@ -202,6 +213,7 @@ def grpc_deps(): if "upb" not in native.existing_rules(): http_archive( name = "upb", + sha256 = "0e749a8973968397f849a3b42e28ee9c85dc418c2477954c2a6a4495f323241d", strip_prefix = "upb-ed9faae0993704b033c594b072d65e1bf19207fa", url = "https://github.com/google/upb/archive/ed9faae0993704b033c594b072d65e1bf19207fa.tar.gz", ) @@ -223,6 +235,7 @@ def grpc_test_only_deps(): if "com_github_twisted_twisted" not in native.existing_rules(): http_archive( name = "com_github_twisted_twisted", + sha256 = "ca17699d0d62eafc5c28daf2c7d0a18e62ae77b4137300b6c7d7868b39b06139", strip_prefix = "twisted-twisted-17.5.0", url = "https://github.com/twisted/twisted/archive/twisted-17.5.0.zip", build_file = "@com_github_grpc_grpc//third_party:twisted.BUILD", @@ -231,6 +244,7 @@ def grpc_test_only_deps(): if "com_github_yaml_pyyaml" not in native.existing_rules(): http_archive( name = "com_github_yaml_pyyaml", + sha256 = "6b4314b1b2051ddb9d4fcd1634e1fa9c1bb4012954273c9ff3ef689f6ec6c93e", strip_prefix = "pyyaml-3.12", url = "https://github.com/yaml/pyyaml/archive/3.12.zip", build_file = "@com_github_grpc_grpc//third_party:yaml.BUILD", @@ -239,6 +253,7 @@ def grpc_test_only_deps(): if "com_github_twisted_incremental" not in native.existing_rules(): http_archive( name = "com_github_twisted_incremental", + sha256 = "f0ca93359ee70243ff7fbf2d904a6291810bd88cb80ed4aca6fa77f318a41a36", strip_prefix = "incremental-incremental-17.5.0", url = "https://github.com/twisted/incremental/archive/incremental-17.5.0.zip", build_file = "@com_github_grpc_grpc//third_party:incremental.BUILD", @@ -247,6 +262,7 @@ def grpc_test_only_deps(): if "com_github_zopefoundation_zope_interface" not in native.existing_rules(): http_archive( name = "com_github_zopefoundation_zope_interface", + sha256 = "e9579fc6149294339897be3aa9ecd8a29217c0b013fe6f44fcdae00e3204198a", strip_prefix = "zope.interface-4.4.3", url = "https://github.com/zopefoundation/zope.interface/archive/4.4.3.zip", build_file = "@com_github_grpc_grpc//third_party:zope_interface.BUILD", @@ -255,6 +271,7 @@ def grpc_test_only_deps(): if "com_github_twisted_constantly" not in native.existing_rules(): http_archive( name = "com_github_twisted_constantly", + sha256 = "2702cd322161a579d2c0dbf94af4e57712eedc7bd7bbbdc554a230544f7d346c", strip_prefix = "constantly-15.1.0", url = "https://github.com/twisted/constantly/archive/15.1.0.zip", build_file = "@com_github_grpc_grpc//third_party:constantly.BUILD", From 4b4ecdf3b9e931a1e26d38c1f6d1f716e4d7137e Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Wed, 17 Apr 2019 13:35:56 -0700 Subject: [PATCH 1882/2143] Fixed sanitize.sh It has been broken since check_copyright dropped the --fix option. This script is modified not to use the missing option. --- tools/distrib/sanitize.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/distrib/sanitize.sh b/tools/distrib/sanitize.sh index fed1e64b7ca..13488b1e235 100755 --- a/tools/distrib/sanitize.sh +++ b/tools/distrib/sanitize.sh @@ -29,11 +29,11 @@ if [ "x$1" == 'x--pre-commit' ]; then fi fi CHANGED_FILES=$(eval $DIFF_COMMAND) ./tools/distrib/clang_format_code.sh - ./tools/distrib/check_copyright.py --fix --precommit + ./tools/distrib/check_copyright.py --precommit ./tools/distrib/check_trailing_newlines.sh else ./tools/buildgen/generate_projects.sh ./tools/distrib/clang_format_code.sh - ./tools/distrib/check_copyright.py --fix + ./tools/distrib/check_copyright.py ./tools/distrib/check_trailing_newlines.sh fi From 7afc6dbae31860670aa751e865fb85de7316df5f Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Thu, 18 Apr 2019 03:00:33 -0600 Subject: [PATCH 1883/2143] Update BadStatus#to_rpc_status Change the implementation to no longer raise when the rpc_status protobuf value cannot be properly decoded. Update the documentation. --- src/ruby/lib/grpc/errors.rb | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb index 236bd9e26f7..2075e91560c 100644 --- a/src/ruby/lib/grpc/errors.rb +++ b/src/ruby/lib/grpc/errors.rb @@ -51,17 +51,20 @@ module GRPC Struct::Status.new(code, details, metadata) end - # Converts the exception to a deserialized Google::Rpc::Status proto. - # Returns nil if the `grpc-status-details-bin` trailer could not be + # Converts the exception to a deserialized {Google::Rpc::Status} object. + # Returns `nil` if the `grpc-status-details-bin` trailer could not be # converted to a {Google::Rpc::Status} due to the server not providing # the necessary trailers. # - # Raises an error if the server did provide the necessary trailers - # but they fail to deserialize into a {Google::Rpc::Status} protobuf. - # - # @return [Google::Rpc::Status] with the same code and details + # @return [Google::Rpc::Status, nil] def to_rpc_status - GoogleRpcStatusUtils.extract_google_rpc_status to_status + status = to_status + + return if status.nil? + + GoogleRpcStatusUtils.extract_google_rpc_status(status) + rescue + nil end def self.new_status_exception(code, details = 'unknown cause', From 71db662452a3d1881cf003389c09f7c8cd9aead7 Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Thu, 18 Apr 2019 03:01:28 -0600 Subject: [PATCH 1884/2143] Add tests for error methods --- src/ruby/spec/errors_spec.rb | 132 +++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 src/ruby/spec/errors_spec.rb diff --git a/src/ruby/spec/errors_spec.rb b/src/ruby/spec/errors_spec.rb new file mode 100644 index 00000000000..7469ee982a2 --- /dev/null +++ b/src/ruby/spec/errors_spec.rb @@ -0,0 +1,132 @@ +# 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. + +require 'spec_helper' +require 'google/protobuf/well_known_types' +require_relative '../pb/src/proto/grpc/testing/messages_pb' + +describe GRPC::BadStatus do + describe :attributes do + it 'has attributes' do + code = 1 + details = 'details' + metadata = { 'key' => 'val' } + + exception = GRPC::BadStatus.new(code, details, metadata) + + expect(exception.code).to eq code + expect(exception.details).to eq details + expect(exception.metadata).to eq metadata + end + end + + describe :new_status_exception do + let(:codes_and_classes) do + [ + [GRPC::Core::StatusCodes::OK, GRPC::Ok], + [GRPC::Core::StatusCodes::CANCELLED, GRPC::Cancelled], + [GRPC::Core::StatusCodes::UNKNOWN, GRPC::Unknown], + [GRPC::Core::StatusCodes::INVALID_ARGUMENT, GRPC::InvalidArgument], + [GRPC::Core::StatusCodes::DEADLINE_EXCEEDED, GRPC::DeadlineExceeded], + [GRPC::Core::StatusCodes::NOT_FOUND, GRPC::NotFound], + [GRPC::Core::StatusCodes::ALREADY_EXISTS, GRPC::AlreadyExists], + [GRPC::Core::StatusCodes::PERMISSION_DENIED, GRPC::PermissionDenied], + [GRPC::Core::StatusCodes::UNAUTHENTICATED, GRPC::Unauthenticated], + [GRPC::Core::StatusCodes::RESOURCE_EXHAUSTED, GRPC::ResourceExhausted], + [GRPC::Core::StatusCodes::FAILED_PRECONDITION, GRPC::FailedPrecondition], + [GRPC::Core::StatusCodes::ABORTED, GRPC::Aborted], + [GRPC::Core::StatusCodes::OUT_OF_RANGE, GRPC::OutOfRange], + [GRPC::Core::StatusCodes::UNIMPLEMENTED, GRPC::Unimplemented], + [GRPC::Core::StatusCodes::INTERNAL, GRPC::Internal], + [GRPC::Core::StatusCodes::UNAVAILABLE, GRPC::Unavailable], + [GRPC::Core::StatusCodes::DATA_LOSS, GRPC::DataLoss], + [99, GRPC::BadStatus] # Unknown codes default to BadStatus + ] + end + + it 'maps codes to the correct error class' do + codes_and_classes.each do |code, grpc_error_class| + exception = GRPC::BadStatus.new_status_exception(code) + + expect(exception).to be_a grpc_error_class + end + end + end + + describe :to_status do + it 'gets status' do + code = 1 + details = 'details' + metadata = { 'key' => 'val' } + + exception = GRPC::BadStatus.new(code, details, metadata) + status = Struct::Status.new(code, details, metadata) + + expect(exception.to_status).to eq status + end + end + + describe :to_rpc_status do + let(:simple_request_any) do + Google::Protobuf::Any.new.tap do |any| + any.pack( + Grpc::Testing::SimpleRequest.new( + payload: Grpc::Testing::Payload.new(body: 'request') + ) + ) + end + end + let(:simple_response_any) do + Google::Protobuf::Any.new.tap do |any| + any.pack( + Grpc::Testing::SimpleResponse.new( + payload: Grpc::Testing::Payload.new(body: 'response') + ) + ) + end + end + let(:payload_any) do + Google::Protobuf::Any.new.tap do |any| + any.pack(Grpc::Testing::Payload.new(body: 'payload')) + end + end + + it 'decodes proto values' do + rpc_status = Google::Rpc::Status.new( + code: 1, + message: 'matching message', + details: [simple_request_any, simple_response_any, payload_any] + ) + rpc_status_proto = Google::Rpc::Status.encode(rpc_status) + + code = 1 + details = 'details' + metadata = { 'grpc-status-details-bin' => rpc_status_proto } + + exception = GRPC::BadStatus.new(code, details, metadata) + + expect(exception.to_rpc_status).to eq rpc_status + end + + it 'does not raise when decoding a bad proto' do + code = 1 + details = 'details' + metadata = { 'grpc-status-details-bin' => 'notavalidprotostream' } + + exception = GRPC::BadStatus.new(code, details, metadata) + + expect(exception.to_rpc_status).to be nil + end + end +end From 0fa7cf9194dc0e74cbdc30e33da106cc778ff0e4 Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Thu, 18 Apr 2019 03:02:31 -0600 Subject: [PATCH 1885/2143] Update Add BadStatus#to_status documentation --- src/ruby/lib/grpc/errors.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb index 2075e91560c..148f0dadb6f 100644 --- a/src/ruby/lib/grpc/errors.rb +++ b/src/ruby/lib/grpc/errors.rb @@ -43,10 +43,10 @@ module GRPC @metadata = metadata end - # Converts the exception to a GRPC::Status for use in the networking + # Converts the exception to a {Struct::Status} for use in the networking # wrapper layer. # - # @return [Status] with the same code and details + # @return [Struct::Status] with the same code and details def to_status Struct::Status.new(code, details, metadata) end From f6dfcf89664eb2f4167e71ae5b0607fb10e6bda7 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 18 Apr 2019 16:51:07 -0700 Subject: [PATCH 1886/2143] Add configurable list of module prefixes to be stripped in Python gRPC protoc plugin. --- src/compiler/protobuf_plugin.h | 21 ++++++++------- src/compiler/python_generator.cc | 36 ++++++++++++++++--------- src/compiler/python_generator.h | 2 ++ src/compiler/python_generator_helpers.h | 34 ++++++++++++++++------- src/compiler/schema_interface.h | 6 +++-- 5 files changed, 66 insertions(+), 33 deletions(-) diff --git a/src/compiler/protobuf_plugin.h b/src/compiler/protobuf_plugin.h index a20e263e542..06cda5f85e6 100644 --- a/src/compiler/protobuf_plugin.h +++ b/src/compiler/protobuf_plugin.h @@ -55,22 +55,23 @@ class ProtoBufMethod : public grpc_generator::Method { return method_->output_type()->file()->name(); } - bool get_module_and_message_path_input(grpc::string* str, - grpc::string generator_file_name, - bool generate_in_pb2_grpc, - grpc::string import_prefix) const { + // TODO(https://github.com/grpc/grpc/issues/18800): Clean this up. + bool get_module_and_message_path_input( + grpc::string* str, grpc::string generator_file_name, + bool generate_in_pb2_grpc, grpc::string import_prefix, + const std::vector& prefixes_to_filter) const final { return grpc_python_generator::GetModuleAndMessagePath( method_->input_type(), str, generator_file_name, generate_in_pb2_grpc, - import_prefix); + import_prefix, prefixes_to_filter); } - bool get_module_and_message_path_output(grpc::string* str, - grpc::string generator_file_name, - bool generate_in_pb2_grpc, - grpc::string import_prefix) const { + bool get_module_and_message_path_output( + grpc::string* str, grpc::string generator_file_name, + bool generate_in_pb2_grpc, grpc::string import_prefix, + const std::vector& prefixes_to_filter) const final { return grpc_python_generator::GetModuleAndMessagePath( method_->output_type(), str, generator_file_name, generate_in_pb2_grpc, - import_prefix); + import_prefix, prefixes_to_filter); } bool NoStreaming() const { diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc index 8a0b8894549..705aef1c884 100644 --- a/src/compiler/python_generator.cc +++ b/src/compiler/python_generator.cc @@ -214,13 +214,15 @@ bool PrivateGenerator::PrintBetaServerFactory( grpc::string input_message_module_and_class; if (!method->get_module_and_message_path_input( &input_message_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } grpc::string output_message_module_and_class; if (!method->get_module_and_message_path_output( &output_message_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } method_implementation_constructors.insert( @@ -320,13 +322,15 @@ bool PrivateGenerator::PrintBetaStubFactory( grpc::string input_message_module_and_class; if (!method->get_module_and_message_path_input( &input_message_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } grpc::string output_message_module_and_class; if (!method->get_module_and_message_path_output( &output_message_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } method_cardinalities.insert( @@ -425,13 +429,15 @@ bool PrivateGenerator::PrintStub( grpc::string request_module_and_class; if (!method->get_module_and_message_path_input( &request_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } grpc::string response_module_and_class; if (!method->get_module_and_message_path_output( &response_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } StringMap method_dict; @@ -516,13 +522,15 @@ bool PrivateGenerator::PrintAddServicerToServer( grpc::string request_module_and_class; if (!method->get_module_and_message_path_input( &request_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } grpc::string response_module_and_class; if (!method->get_module_and_message_path_output( &response_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } StringMap method_dict; @@ -589,17 +597,21 @@ bool PrivateGenerator::PrintPreamble(grpc_generator::Printer* out) { grpc::string input_type_file_name = method->get_input_type_name(); grpc::string input_module_name = - ModuleName(input_type_file_name, config.import_prefix); + ModuleName(input_type_file_name, config.import_prefix, + config.prefixes_to_filter); grpc::string input_module_alias = - ModuleAlias(input_type_file_name, config.import_prefix); + ModuleAlias(input_type_file_name, config.import_prefix, + config.prefixes_to_filter); imports_set.insert( std::make_tuple(input_module_name, input_module_alias)); grpc::string output_type_file_name = method->get_output_type_name(); grpc::string output_module_name = - ModuleName(output_type_file_name, config.import_prefix); + ModuleName(output_type_file_name, config.import_prefix, + config.prefixes_to_filter); grpc::string output_module_alias = - ModuleAlias(output_type_file_name, config.import_prefix); + ModuleAlias(output_type_file_name, config.import_prefix, + config.prefixes_to_filter); imports_set.insert( std::make_tuple(output_module_name, output_module_alias)); } diff --git a/src/compiler/python_generator.h b/src/compiler/python_generator.h index 9139307e63c..6077ac4ec68 100644 --- a/src/compiler/python_generator.h +++ b/src/compiler/python_generator.h @@ -20,6 +20,7 @@ #define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H #include +#include #include "src/compiler/config.h" #include "src/compiler/schema_interface.h" @@ -35,6 +36,7 @@ struct GeneratorConfiguration { grpc::string beta_package_root; // TODO(https://github.com/google/protobuf/issues/888): Drop this. grpc::string import_prefix; + std::vector prefixes_to_filter; }; class PythonGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { diff --git a/src/compiler/python_generator_helpers.h b/src/compiler/python_generator_helpers.h index b1b58befdf4..171dd730a24 100644 --- a/src/compiler/python_generator_helpers.h +++ b/src/compiler/python_generator_helpers.h @@ -49,23 +49,39 @@ namespace { typedef vector DescriptorVector; typedef vector StringVector; +static grpc::string StripModulePrefixes( + const grpc::string& raw_module_name, + const std::vector& prefixes_to_filter) { + for (const auto& prefix : prefixes_to_filter) { + if (raw_module_name.rfind(prefix, 0) == 0) { + return raw_module_name.substr(prefix.size(), + raw_module_name.size() - prefix.size()); + } + } + return raw_module_name; +} + // TODO(https://github.com/google/protobuf/issues/888): // Export `ModuleName` from protobuf's // `src/google/protobuf/compiler/python/python_generator.cc` file. grpc::string ModuleName(const grpc::string& filename, - const grpc::string& import_prefix) { + const grpc::string& import_prefix, + const std::vector& prefixes_to_filter) { grpc::string basename = StripProto(filename); basename = StringReplace(basename, "-", "_"); basename = StringReplace(basename, "/", "."); - return import_prefix + basename + "_pb2"; + return StripModulePrefixes(import_prefix + basename + "_pb2", + prefixes_to_filter); } // TODO(https://github.com/google/protobuf/issues/888): // Export `ModuleAlias` from protobuf's // `src/google/protobuf/compiler/python/python_generator.cc` file. grpc::string ModuleAlias(const grpc::string& filename, - const grpc::string& import_prefix) { - grpc::string module_name = ModuleName(filename, import_prefix); + const grpc::string& import_prefix, + const std::vector& prefixes_to_filter) { + grpc::string module_name = + ModuleName(filename, import_prefix, prefixes_to_filter); // We can't have dots in the module name, so we replace each with _dot_. // But that could lead to a collision between a.b and a_dot_b, so we also // duplicate each underscore. @@ -74,10 +90,10 @@ grpc::string ModuleAlias(const grpc::string& filename, return module_name; } -bool GetModuleAndMessagePath(const Descriptor* type, grpc::string* out, - grpc::string generator_file_name, - bool generate_in_pb2_grpc, - grpc::string& import_prefix) { +bool GetModuleAndMessagePath( + const Descriptor* type, grpc::string* out, grpc::string generator_file_name, + bool generate_in_pb2_grpc, grpc::string& import_prefix, + const std::vector& prefixes_to_filter) { const Descriptor* path_elem_type = type; DescriptorVector message_path; do { @@ -93,7 +109,7 @@ bool GetModuleAndMessagePath(const Descriptor* type, grpc::string* out, grpc::string module; if (generator_file_name != file_name || generate_in_pb2_grpc) { - module = ModuleAlias(file_name, import_prefix) + "."; + module = ModuleAlias(file_name, import_prefix, prefixes_to_filter) + "."; } else { module = ""; } diff --git a/src/compiler/schema_interface.h b/src/compiler/schema_interface.h index cac131b1190..e7b427d89b1 100644 --- a/src/compiler/schema_interface.h +++ b/src/compiler/schema_interface.h @@ -57,10 +57,12 @@ struct Method : public CommentHolder { virtual bool get_module_and_message_path_input( grpc::string* str, grpc::string generator_file_name, - bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0; + bool generate_in_pb2_grpc, grpc::string import_prefix, + const std::vector& prefixes_to_filter) const = 0; virtual bool get_module_and_message_path_output( grpc::string* str, grpc::string generator_file_name, - bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0; + bool generate_in_pb2_grpc, grpc::string import_prefix, + const std::vector& prefixes_to_filter) const = 0; virtual grpc::string get_input_type_name() const = 0; virtual grpc::string get_output_type_name() const = 0; From 41871bf7de69cf601378178d28e117ffab5470a3 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 18 Apr 2019 17:01:45 -0700 Subject: [PATCH 1887/2143] Add cares glue for libuv event loop --- BUILD | 2 + BUILD.gn | 2 + CMakeLists.txt | 4 + Makefile | 4 + build.yaml | 2 + config.m4 | 2 + config.w32 | 2 + gRPC-Core.podspec | 2 + grpc.gemspec | 2 + grpc.gyp | 4 + package.xml | 2 + .../resolver/dns/c_ares/dns_resolver_ares.cc | 6 +- .../dns/c_ares/grpc_ares_ev_driver.cc | 6 +- .../dns/c_ares/grpc_ares_ev_driver_libuv.cc | 134 ++++++++++++++++++ .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 4 +- .../dns/c_ares/grpc_ares_wrapper_fallback.cc | 4 +- .../dns/c_ares/grpc_ares_wrapper_libuv.cc | 103 ++++++++++++++ src/python/grpcio/grpc_core_dependencies.py | 2 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 2 + 20 files changed, 282 insertions(+), 9 deletions(-) create mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc create mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc diff --git a/BUILD b/BUILD index 0bcfc293be3..58f0855961e 100644 --- a/BUILD +++ b/BUILD @@ -1552,10 +1552,12 @@ grpc_cc_library( srcs = [ "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_libuv.cc", "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_fallback.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.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", ], diff --git a/BUILD.gn b/BUILD.gn index 1417f1db5ea..a188ed86ac3 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -309,11 +309,13 @@ config("grpc_config") { "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_libuv.cc", "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_libuv.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", diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b99a57633a..dd32088e97f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1281,10 +1281,12 @@ add_library(grpc src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc 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_libuv.cc 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_fallback.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.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 @@ -2650,10 +2652,12 @@ add_library(grpc_unsecure src/core/ext/transport/inproc/inproc_transport.cc 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_libuv.cc 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_fallback.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.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 diff --git a/Makefile b/Makefile index 2e6e6070c43..b1dcc82c601 100644 --- a/Makefile +++ b/Makefile @@ -3736,10 +3736,12 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \ 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_libuv.cc \ 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_fallback.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.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 \ @@ -5053,10 +5055,12 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/transport/inproc/inproc_transport.cc \ 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_libuv.cc \ 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_fallback.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.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 \ diff --git a/build.yaml b/build.yaml index 5e8c803e56f..48c45eb799d 100644 --- a/build.yaml +++ b/build.yaml @@ -781,10 +781,12 @@ filegroups: src: - 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_libuv.cc - 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_fallback.cc + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.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 plugin: grpc_resolver_dns_ares diff --git a/config.m4 b/config.m4 index 2c64a3eb168..e255602a48d 100644 --- a/config.m4 +++ b/config.m4 @@ -396,10 +396,12 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \ 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_libuv.cc \ 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_fallback.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.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 \ diff --git a/config.w32 b/config.w32 index 6897c1041ac..e83b3e3dd7f 100644 --- a/config.w32 +++ b/config.w32 @@ -371,10 +371,12 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin\\round_robin.cc " + "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_libuv.cc " + "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_fallback.cc " + + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv.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 " + diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index bab7ce4378e..4a2ea853f29 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -843,10 +843,12 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc', '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_libuv.cc', '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_fallback.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.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', diff --git a/grpc.gemspec b/grpc.gemspec index b9d2107ee48..b7e0d54eaab 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -780,10 +780,12 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc ) diff --git a/grpc.gyp b/grpc.gyp index 322259d2ca7..19427da3ca6 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -578,10 +578,12 @@ 'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc', '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_libuv.cc', '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_fallback.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.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', @@ -1317,10 +1319,12 @@ 'src/core/ext/transport/inproc/inproc_transport.cc', '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_libuv.cc', '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_fallback.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.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', diff --git a/package.xml b/package.xml index f3bbb449ac5..26cc17756e8 100644 --- a/package.xml +++ b/package.xml @@ -785,10 +785,12 @@ + + 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 7b5eb311393..3f1a700c3d6 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 @@ -18,7 +18,7 @@ #include -#if GRPC_ARES == 1 && !defined(GRPC_UV) +#if GRPC_ARES == 1 #include #include @@ -464,10 +464,10 @@ void grpc_resolver_dns_ares_shutdown() { gpr_free(resolver_env); } -#else /* GRPC_ARES == 1 && !defined(GRPC_UV) */ +#else /* GRPC_ARES == 1 */ void grpc_resolver_dns_ares_init(void) {} void grpc_resolver_dns_ares_shutdown(void) {} -#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */ +#endif /* GRPC_ARES == 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc index d99c2e30047..9fff92da52f 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -18,7 +18,7 @@ #include #include "src/core/lib/iomgr/port.h" -#if GRPC_ARES == 1 && !defined(GRPC_UV) +#if GRPC_ARES == 1 #include #include @@ -218,6 +218,7 @@ static void on_timeout_locked(void* arg, grpc_error* error) { static void on_readable_locked(void* arg, grpc_error* error) { fd_node* fdn = static_cast(arg); + GPR_ASSERT(fdn->readable_registered); grpc_ares_ev_driver* ev_driver = fdn->ev_driver; const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked(); fdn->readable_registered = false; @@ -242,6 +243,7 @@ static void on_readable_locked(void* arg, grpc_error* error) { static void on_writable_locked(void* arg, grpc_error* error) { fd_node* fdn = static_cast(arg); + GPR_ASSERT(fdn->writable_registered); grpc_ares_ev_driver* ev_driver = fdn->ev_driver; const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked(); fdn->writable_registered = false; @@ -365,4 +367,4 @@ void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) { } } -#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */ +#endif /* GRPC_ARES == 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc new file mode 100644 index 00000000000..5831056dde8 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -0,0 +1,134 @@ +/* + * + * 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 "src/core/lib/iomgr/port.h" +#if GRPC_ARES == 1 && defined(GRPC_UV) + +#include +#include + +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" + +#include +#include +#include +#include +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/lib/gpr/string.h" + +namespace grpc_core { + +void ares_uv_poll_cb(uv_poll_t* handle, int status, int events); + +void ares_uv_poll_close_cb(uv_handle_t *handle) { + delete handle; +} + +class GrpcPolledFdLibuv : public GrpcPolledFd { + public: + GrpcPolledFdLibuv(ares_socket_t as): as_(as) { + gpr_asprintf(&name_, "c-ares socket: %" PRIdPTR, (intptr_t)as); + handle_ = new uv_poll_t; + uv_poll_init_socket(uv_default_loop(), handle_, as); + handle_->data = this; + } + + ~GrpcPolledFdLibuv() { + gpr_free(name_); + } + + void RegisterForOnReadableLocked(grpc_closure* read_closure) override { + GPR_ASSERT(read_closure_ == nullptr); + GPR_ASSERT((poll_events_ & UV_READABLE) == 0); + read_closure_ = read_closure; + poll_events_ |= UV_READABLE; + uv_poll_start(handle_, poll_events_, ares_uv_poll_cb); + } + + void RegisterForOnWriteableLocked(grpc_closure* write_closure) override { + GPR_ASSERT(write_closure_ == nullptr); + GPR_ASSERT((poll_events_ & UV_WRITABLE) == 0); + write_closure_ = write_closure; + poll_events_ |= UV_WRITABLE; + uv_poll_start(handle_, poll_events_, ares_uv_poll_cb); + } + + bool IsFdStillReadableLocked() override { + /* uv_poll_t is based on poll, which is level triggered. So, if cares + * leaves some data unread, the event will trigger again. */ + return false; + } + + void ShutdownLocked(grpc_error* error) override { + uv_poll_stop(handle_); + uv_close(reinterpret_cast(handle_), ares_uv_poll_close_cb); + } + + ares_socket_t GetWrappedAresSocketLocked() override { return as_; } + + const char* GetName() override { return name_; } + + char* name_; + ares_socket_t as_; + uv_poll_t* handle_; + grpc_closure* read_closure_ = nullptr; + grpc_closure* write_closure_ = nullptr; + int poll_events_ = 0; +}; + +void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { + grpc_core::ExecCtx exec_ctx; + GrpcPolledFdLibuv* polled_fd = reinterpret_cast(handle->data); + grpc_error *error = GRPC_ERROR_NONE; + if (status < 0) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("cares polling error"); + error = grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, + grpc_slice_from_static_string(uv_strerror(status))); + } + if ((events & UV_READABLE) && polled_fd->read_closure_) { + GRPC_CLOSURE_SCHED(polled_fd->read_closure_, error); + polled_fd->read_closure_ = nullptr; + polled_fd->poll_events_ &= ~UV_READABLE; + } + if ((events & UV_WRITABLE) && polled_fd->write_closure_) { + GRPC_CLOSURE_SCHED(polled_fd->write_closure_, error); + polled_fd->write_closure_ = nullptr; + polled_fd->poll_events_ &= ~UV_WRITABLE; + } + uv_poll_start(handle, polled_fd->poll_events_, ares_uv_poll_cb); +} + +class GrpcPolledFdFactoryLibuv : public GrpcPolledFdFactory { + public: + GrpcPolledFd* NewGrpcPolledFdLocked(ares_socket_t as, + grpc_pollset_set* driver_pollset_set, + grpc_combiner* combiner) override { + return New(as); + } + + void ConfigureAresChannelLocked(ares_channel channel) override {} +}; + +UniquePtr NewGrpcPolledFdFactory(grpc_combiner* combiner) { + return UniquePtr(New()); +} + +} // namespace grpc_core + +#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ \ No newline at end of file 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 37b0b365eed..97ef61d2f33 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 @@ -18,7 +18,7 @@ #include -#if GRPC_ARES == 1 && !defined(GRPC_UV) +#if GRPC_ARES == 1 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -687,4 +687,4 @@ void (*grpc_resolve_address_ares)( grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_resolved_addresses** addrs) = grpc_resolve_address_ares_impl; -#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */ +#endif /* GRPC_ARES == 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc index 1f4701c9994..d2de88eaa1e 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc @@ -18,7 +18,7 @@ #include -#if GRPC_ARES != 1 || defined(GRPC_UV) +#if GRPC_ARES != 1 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" @@ -62,4 +62,4 @@ void (*grpc_resolve_address_ares)( grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_resolved_addresses** addrs) = grpc_resolve_address_ares_impl; -#endif /* GRPC_ARES != 1 || defined(GRPC_UV) */ +#endif /* GRPC_ARES != 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc new file mode 100644 index 00000000000..eb8d7e5e900 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -0,0 +1,103 @@ +/* + * + * 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" +#if GRPC_ARES == 1 && defined(GRPC_UV) + +#include + +#include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" + +bool grpc_ares_query_ipv6() { + /* The libuv grpc code currently does not have the code to probe for this, + * so we assume for nowthat IPv6 is always available in contexts where this + * code will be used. */ + return true; +} + +/* The following two functions were copied entirely from the Windows file. This + * code can run on Windows so it can have the same problem. */ +static bool inner_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port) { + gpr_split_host_port(name, host, port); + if (*host == nullptr) { + gpr_log(GPR_ERROR, + "Failed to parse %s into host:port during Windows localhost " + "resolution check.", + name); + return false; + } + if (*port == nullptr) { + if (default_port == nullptr) { + gpr_log(GPR_ERROR, + "No port or default port for %s during Windows localhost " + "resolution check.", + name); + return false; + } + *port = gpr_strdup(default_port); + } + if (gpr_stricmp(*host, "localhost") == 0) { + GPR_ASSERT(*addrs == nullptr); + *addrs = grpc_core::MakeUnique(); + uint16_t numeric_port = grpc_strhtons(*port); + // Append the ipv6 loopback address. + struct sockaddr_in6 ipv6_loopback_addr; + memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); + ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; + ipv6_loopback_addr.sin6_family = AF_INET6; + ipv6_loopback_addr.sin6_port = numeric_port; + (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), + nullptr /* args */); + // Append the ipv4 loopback address. + struct sockaddr_in ipv4_loopback_addr; + memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); + ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; + ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; + ipv4_loopback_addr.sin_family = AF_INET; + ipv4_loopback_addr.sin_port = numeric_port; + (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), + nullptr /* args */); + // Let the address sorter figure out which one should be tried first. + grpc_cares_wrapper_address_sorting_sort(addrs->get()); + return true; + } + return false; +} + +bool grpc_ares_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { + char* host = nullptr; + char* port = nullptr; + bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, + addrs, &host, &port); + gpr_free(host); + gpr_free(port); + return out; +} + +#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ \ No newline at end of file diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 21efd682871..9c375f5eb87 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -370,10 +370,12 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc', '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_libuv.cc', '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_fallback.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.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', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index e68e758c64e..a3869cd239c 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -942,11 +942,13 @@ src/core/ext/filters/client_channel/resolver/README.md \ 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_libuv.cc \ 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_libuv.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/README.md \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 29fd6f32e59..52c69ad10b5 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9084,11 +9084,13 @@ "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_libuv.cc", "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_libuv.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" ], From a84d188021c9f76905e6c211ff7b9e2af2d16345 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 18 Apr 2019 17:45:36 -0700 Subject: [PATCH 1888/2143] Don't use 'new' or 'delete' --- .../resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc index 5831056dde8..fd09d899187 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -37,14 +37,14 @@ namespace grpc_core { void ares_uv_poll_cb(uv_poll_t* handle, int status, int events); void ares_uv_poll_close_cb(uv_handle_t *handle) { - delete handle; + Delete(handle); } class GrpcPolledFdLibuv : public GrpcPolledFd { public: GrpcPolledFdLibuv(ares_socket_t as): as_(as) { gpr_asprintf(&name_, "c-ares socket: %" PRIdPTR, (intptr_t)as); - handle_ = new uv_poll_t; + handle_ = New(); uv_poll_init_socket(uv_default_loop(), handle_, as); handle_->data = this; } From b47f2048b8f321de3f4c4f1cd7e36e33407994ad Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Thu, 18 Apr 2019 22:26:39 -0600 Subject: [PATCH 1889/2143] Log ParseError raised in BadStatus#to_rpc_status --- src/ruby/lib/grpc/errors.rb | 4 +++- src/ruby/spec/errors_spec.rb | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb index 148f0dadb6f..83beb6a906a 100644 --- a/src/ruby/lib/grpc/errors.rb +++ b/src/ruby/lib/grpc/errors.rb @@ -63,7 +63,9 @@ module GRPC return if status.nil? GoogleRpcStatusUtils.extract_google_rpc_status(status) - rescue + rescue Google::Protobuf::ParseError => parse_error + GRPC.logger.warn('parse error: to_rpc_status failed') + GRPC.logger.warn(parse_error) nil end diff --git a/src/ruby/spec/errors_spec.rb b/src/ruby/spec/errors_spec.rb index 7469ee982a2..30e897700b3 100644 --- a/src/ruby/spec/errors_spec.rb +++ b/src/ruby/spec/errors_spec.rb @@ -127,6 +127,14 @@ describe GRPC::BadStatus do exception = GRPC::BadStatus.new(code, details, metadata) expect(exception.to_rpc_status).to be nil + + # Check that the parse error was logged correctly + log_contents = @log_output.read + expected_line_1 = 'WARN GRPC : parse error: to_rpc_status failed' + expected_line_2 = 'WARN GRPC : ' \ + 'Error occurred during parsing: Invalid wire type' + expect(log_contents).to include expected_line_1 + expect(log_contents).to include expected_line_2 end end end From 813865acafe90a369a6986f87428af3344c1a1b9 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 11 Apr 2019 17:46:12 -0700 Subject: [PATCH 1890/2143] Adding service config parser --- .../filters/client_channel/client_channel.cc | 102 ++-- .../client_channel/client_channel_plugin.cc | 6 + .../ext/filters/client_channel/lb_policy.cc | 32 +- .../ext/filters/client_channel/lb_policy.h | 26 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 93 +++- .../lb_policy/pick_first/pick_first.cc | 20 + .../lb_policy/round_robin/round_robin.cc | 20 + .../client_channel/lb_policy/xds/xds.cc | 176 ++++-- .../client_channel/lb_policy_factory.h | 14 +- .../client_channel/lb_policy_registry.cc | 24 + .../client_channel/lb_policy_registry.h | 3 + .../client_channel/resolver_result_parsing.cc | 506 ++++++++++++------ .../client_channel/resolver_result_parsing.h | 149 ++++-- .../client_channel/resolving_lb_policy.cc | 13 +- .../client_channel/resolving_lb_policy.h | 15 +- .../filters/client_channel/service_config.cc | 29 +- .../filters/client_channel/service_config.h | 7 +- src/core/lib/channel/context.h | 2 + src/core/lib/gprpp/optional.h | 5 +- src/core/lib/iomgr/error.h | 1 + .../client_channel/service_config_test.cc | 61 ++- 21 files changed, 906 insertions(+), 398 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 049c8d0a13f..262795b025c 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -66,8 +66,7 @@ #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_metadata.h" -using grpc_core::internal::ClientChannelMethodParams; -using grpc_core::internal::ClientChannelMethodParamsTable; +using grpc_core::internal::ClientChannelMethodParsedObject; using grpc_core::internal::ProcessedResolverResult; using grpc_core::internal::ServerRetryThrottleData; @@ -169,7 +168,6 @@ struct client_channel_channel_data { // Data from service config. bool received_service_config_data; grpc_core::RefCountedPtr retry_throttle_data; - grpc_core::RefCountedPtr method_params_table; grpc_core::RefCountedPtr service_config; // @@ -277,11 +275,9 @@ class ServiceConfigSetter { ServiceConfigSetter( channel_data* chand, RefCountedPtr retry_throttle_data, - RefCountedPtr method_params_table, RefCountedPtr service_config) : chand_(chand), retry_throttle_data_(std::move(retry_throttle_data)), - method_params_table_(std::move(method_params_table)), service_config_(std::move(service_config)) { GRPC_CHANNEL_STACK_REF(chand->owning_stack, "ServiceConfigSetter"); GRPC_CLOSURE_INIT(&closure_, SetServiceConfigData, this, @@ -296,7 +292,6 @@ class ServiceConfigSetter { // 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_); chand->service_config = std::move(self->service_config_); // Apply service config to queued picks. for (QueuedPick* pick = chand->queued_picks; pick != nullptr; @@ -310,7 +305,6 @@ class ServiceConfigSetter { channel_data* chand_; RefCountedPtr retry_throttle_data_; - RefCountedPtr method_params_table_; RefCountedPtr service_config_; grpc_closure closure_; }; @@ -497,20 +491,19 @@ class ClientChannelControlHelper // result update. static bool process_resolver_result_locked( void* arg, grpc_core::Resolver::Result* result, const char** lb_policy_name, - grpc_core::RefCountedPtr* lb_policy_config) { + const grpc_core::ParsedLoadBalancingConfig** lb_policy_config) { channel_data* chand = static_cast(arg); ProcessedResolverResult resolver_result(result, chand->enable_retries); - grpc_core::UniquePtr service_config_json = - resolver_result.service_config_json(); + const char* service_config_json = resolver_result.service_config_json(); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", - chand, service_config_json.get()); + chand, service_config_json); } // 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(), resolver_result.service_config()); + resolver_result.service_config()); // 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(); @@ -518,9 +511,8 @@ static bool process_resolver_result_locked( ((service_config_json == nullptr) != (chand->info_service_config_json == nullptr)) || (service_config_json != nullptr && - strcmp(service_config_json.get(), - chand->info_service_config_json.get()) != 0); - chand->info_service_config_json = std::move(service_config_json); + strcmp(service_config_json, chand->info_service_config_json.get()) != 0); + chand->info_service_config_json.reset(gpr_strdup(service_config_json)); gpr_mu_unlock(&chand->info_mu); // Return results. *lb_policy_name = chand->info_lb_policy_name.get(); @@ -749,7 +741,7 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { chand->info_lb_policy_name.reset(); chand->info_service_config_json.reset(); chand->retry_throttle_data.reset(); - chand->method_params_table.reset(); + chand->service_config.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"); @@ -974,8 +966,8 @@ struct call_data { grpc_call_context_element* call_context; grpc_core::RefCountedPtr retry_throttle_data; - grpc_core::RefCountedPtr method_params; grpc_core::RefCountedPtr service_config; + ClientChannelMethodParsedObject* method_params = nullptr; grpc_core::RefCountedPtr subchannel_call; @@ -1474,8 +1466,7 @@ static void do_retry(grpc_call_element* elem, channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); GPR_ASSERT(calld->method_params != nullptr); - const ClientChannelMethodParams::RetryPolicy* retry_policy = - calld->method_params->retry_policy(); + const auto* retry_policy = calld->method_params->retry_policy(); GPR_ASSERT(retry_policy != nullptr); // Reset subchannel call and connected subchannel. calld->subchannel_call.reset(); @@ -1520,8 +1511,7 @@ static bool maybe_retry(grpc_call_element* elem, call_data* calld = static_cast(elem->call_data); // Get retry policy. if (calld->method_params == nullptr) return false; - const ClientChannelMethodParams::RetryPolicy* retry_policy = - calld->method_params->retry_policy(); + const auto* retry_policy = calld->method_params->retry_policy(); if (retry_policy == nullptr) return false; // If we've already dispatched a retry from this call, return true. // This catches the case where the batch has multiple callbacks @@ -2819,46 +2809,50 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) { gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call", chand, calld); } - if(chand->service_config != nullptr) { + if (chand->service_config != nullptr) { calld->service_config = chand->service_config; calld->call_context[GRPC_SERVICE_CONFIG].value = &calld->service_config; + const auto* method_params_vector_ptr = + chand->service_config->GetMethodServiceConfigObjectsVector(calld->path); + if (method_params_vector_ptr != nullptr) { + calld->method_params = static_cast( + ((*method_params_vector_ptr) + [grpc_core::internal::ClientChannelServiceConfigParser:: + client_channel_service_config_parser_index()]) + .get()); + calld->call_context[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value = + const_cast( + method_params_vector_ptr); + } } if (chand->retry_throttle_data != nullptr) { calld->retry_throttle_data = chand->retry_throttle_data->Ref(); } - if (chand->method_params_table != nullptr) { - calld->method_params = grpc_core::ServiceConfig::MethodConfigTableLookup( - *chand->method_params_table, calld->path); - if (calld->method_params != nullptr) { - // If the deadline from the service config is shorter than the one - // from the client API, reset the deadline timer. - if (chand->deadline_checking_enabled && - calld->method_params->timeout() != 0) { - const grpc_millis per_method_deadline = - grpc_timespec_to_millis_round_up(calld->call_start_time) + - calld->method_params->timeout(); - if (per_method_deadline < calld->deadline) { - calld->deadline = per_method_deadline; - grpc_deadline_state_reset(elem, calld->deadline); - } + if (calld->method_params != nullptr) { + // If the deadline from the service config is shorter than the one + // from the client API, reset the deadline timer. + if (chand->deadline_checking_enabled && + calld->method_params->timeout() != 0) { + const grpc_millis per_method_deadline = + grpc_timespec_to_millis_round_up(calld->call_start_time) + + calld->method_params->timeout(); + if (per_method_deadline < calld->deadline) { + calld->deadline = per_method_deadline; + grpc_deadline_state_reset(elem, calld->deadline); } - // If the service config set wait_for_ready and the application - // did not explicitly set it, use the value from the service config. - uint32_t* send_initial_metadata_flags = - &calld->pending_batches[0] - .batch->payload->send_initial_metadata - .send_initial_metadata_flags; - if (GPR_UNLIKELY( - calld->method_params->wait_for_ready() != - ClientChannelMethodParams::WAIT_FOR_READY_UNSET && - !(*send_initial_metadata_flags & - GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET))) { - if (calld->method_params->wait_for_ready() == - ClientChannelMethodParams::WAIT_FOR_READY_TRUE) { - *send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY; - } else { - *send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY; - } + } + // If the service config set wait_for_ready and the application + // did not explicitly set it, use the value from the service config. + uint32_t* send_initial_metadata_flags = + &calld->pending_batches[0] + .batch->payload->send_initial_metadata.send_initial_metadata_flags; + if (calld->method_params->wait_for_ready().has_value() && + !(*send_initial_metadata_flags & + GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET)) { + if (calld->method_params->wait_for_ready().value()) { + *send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY; + } else { + *send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY; } } } 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 8e76c4cbb15..12f02fc49fb 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -32,6 +32,7 @@ #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/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" #include "src/core/lib/surface/channel_init.h" @@ -48,8 +49,13 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { builder, static_cast(arg), nullptr, nullptr); } +void grpc_service_config_register_parsers() { + grpc_core::internal::ClientChannelServiceConfigParser::Register(); +} + void grpc_client_channel_init(void) { grpc_core::ServiceConfig::Init(); + grpc_service_config_register_parsers(); grpc_core::LoadBalancingPolicyRegistry::Builder::InitRegistry(); grpc_core::ResolverRegistry::Builder::InitRegistry(); grpc_core::internal::ServerRetryThrottleMap::Init(); diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 6b657465891..1cd5e6c9e98 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -63,28 +63,50 @@ void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg, } grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( - const grpc_json* lb_config_array) { + const grpc_json* lb_config_array, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:type should be 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; + if (lb_config->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:child entry should be of type " + "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) + if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:child entry should be of type " + "object"); return nullptr; - if (policy != nullptr) return nullptr; // Violate "oneof" type. + } + if (policy != nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:oneOf violation"); + return nullptr; + } // Violate "oneof" type. policy = field; } - if (policy == nullptr) return nullptr; + if (policy == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:no policy found in child entry"); + return nullptr; + } // If we support this policy, then select it. if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key)) { return policy; } } + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:No known policy"); return nullptr; } diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 1c17f95423e..30e6dca1cd9 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -36,6 +36,8 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount; namespace grpc_core { +class ParsedLoadBalancingConfig; + /// Interface for load balancing policies. /// /// The following concepts are used here: @@ -194,30 +196,11 @@ class LoadBalancingPolicy : public InternallyRefCounted { GRPC_ABSTRACT_BASE_CLASS }; - /// 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, - RefCountedPtr service_config) - : json_(lb_config), service_config_(std::move(service_config)) {} - - const char* name() const { return json_->key; } - const grpc_json* config() const { return json_->child; } - RefCountedPtr service_config() const { - return service_config_; - } - - private: - const grpc_json* json_; - RefCountedPtr service_config_; - }; - /// Data passed to the UpdateLocked() method when new addresses and /// config are available. struct UpdateArgs { ServerAddressList addresses; - RefCountedPtr config; + const ParsedLoadBalancingConfig* config = nullptr; const grpc_channel_args* args = nullptr; // TODO(roth): Remove everything below once channel args is @@ -290,7 +273,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// 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); + static grpc_json* ParseLoadBalancingConfig(const grpc_json* lb_config_array, + grpc_error** error); // A picker that returns PICK_QUEUE for all picks. // Also calls the parent LB policy's ExitIdleLocked() method when the 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 ead15308f49..f8922bf7bcc 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 @@ -118,6 +118,23 @@ namespace { constexpr char kGrpclb[] = "grpclb"; +class ParsedGrpcLbConfig : public ParsedLoadBalancingConfig { + public: + ParsedGrpcLbConfig(UniquePtr child_policy, + const grpc_json* json) + : child_policy_(std::move(child_policy)), json_(json) {} + const char* name() const override { return kGrpclb; } + + const ParsedLoadBalancingConfig* child_policy() const { + return child_policy_.get(); + } + const grpc_json* config() const { return json_; } + + private: + UniquePtr child_policy_; + const grpc_json* json_ = nullptr; +}; + class GrpcLb : public LoadBalancingPolicy { public: explicit GrpcLb(Args args); @@ -302,7 +319,7 @@ class GrpcLb : public LoadBalancingPolicy { // Helper functions used in UpdateLocked(). void ProcessAddressesAndChannelArgsLocked(const ServerAddressList& addresses, const grpc_channel_args& args); - void ParseLbConfig(Config* grpclb_config); + void ParseLbConfig(const ParsedGrpcLbConfig* grpclb_config); static void OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error); void CancelBalancerChannelConnectivityWatchLocked(); @@ -380,7 +397,7 @@ class GrpcLb : public LoadBalancingPolicy { // until it reports READY, at which point it will be moved to child_policy_. OrphanablePtr pending_child_policy_; // The child policy config. - RefCountedPtr child_policy_config_; + const ParsedLoadBalancingConfig* child_policy_config_ = nullptr; // Child policy in state READY. bool child_policy_ready_ = false; }; @@ -1383,7 +1400,7 @@ void GrpcLb::FillChildRefsForChannelz( void GrpcLb::UpdateLocked(UpdateArgs args) { const bool is_initial_update = lb_channel_ == nullptr; - ParseLbConfig(args.config.get()); + ParseLbConfig(static_cast(args.config)); ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); // Update the existing child policy. if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); @@ -1472,24 +1489,11 @@ void GrpcLb::ProcessAddressesAndChannelArgsLocked( response_generator_->SetResponse(std::move(result)); } -void GrpcLb::ParseLbConfig(Config* grpclb_config) { - const grpc_json* child_policy = nullptr; +void GrpcLb::ParseLbConfig(const ParsedGrpcLbConfig* grpclb_config) { if (grpclb_config != nullptr) { - 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; - if (strcmp(field->key, "childPolicy") == 0) { - if (child_policy != nullptr) return; // Duplicate. - child_policy = ParseLoadBalancingConfig(field); - } - } - } - if (child_policy != nullptr) { - child_policy_config_ = - MakeRefCounted(child_policy, grpclb_config->service_config()); + child_policy_config_ = grpclb_config->child_policy(); } else { - child_policy_config_.reset(); + child_policy_config_ = nullptr; } } @@ -1802,6 +1806,24 @@ void GrpcLb::CreateOrUpdateChildPolicyLocked() { policy_to_update->UpdateLocked(std::move(update_args)); } +// Consumes all the errors in the vector and forms a referencing error from +// them. If the vector is empty, return GRPC_ERROR_NONE. +template +grpc_error* CreateErrorFromVector(const char* desc, + InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; +} + // // factory // @@ -1814,6 +1836,39 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { } const char* name() const override { return kGrpclb; } + + UniquePtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const override { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + GPR_DEBUG_ASSERT(json != nullptr); + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + InlinedVector error_list; + UniquePtr child_policy = nullptr; + + for (const grpc_json* field = json->child; field != nullptr; + field = field->next) { + if (field->key == nullptr) continue; + if (strcmp(field->key, "childPolicy") == 0) { + if (child_policy != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:childPolicy error:Duplicate entry")); + } + grpc_error* parse_error = GRPC_ERROR_NONE; + child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, &parse_error); + if (parse_error != GRPC_ERROR_NONE) { + error_list.push_back(parse_error); + } + } + } + if (error_list.empty()) { + return UniquePtr( + New(std::move(child_policy), json)); + } else { + *error = CreateErrorFromVector("GrpcLb Parser", &error_list); + return nullptr; + } + } }; } // namespace 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 892472e1c9b..4b7b00237cb 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 @@ -531,6 +531,18 @@ void PickFirst::PickFirstSubchannelData:: } } +class ParsedPickFirstConfig : public ParsedLoadBalancingConfig { + public: + ParsedPickFirstConfig(const grpc_json* json) : json_(json) {} + + const char* name() const override { return kPickFirst; } + + const grpc_json* config() const { return json_; } + + private: + const grpc_json* json_; +}; + // // factory // @@ -543,6 +555,14 @@ class PickFirstFactory : public LoadBalancingPolicyFactory { } const char* name() const override { return kPickFirst; } + + UniquePtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const override { + GPR_DEBUG_ASSERT(json != nullptr); + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + return UniquePtr( + New(json)); + } }; } // namespace 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 29cfe972f78..721844d689e 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 @@ -509,6 +509,18 @@ void RoundRobin::UpdateLocked(UpdateArgs args) { } } +class ParsedRoundRobinConfig : public ParsedLoadBalancingConfig { + public: + ParsedRoundRobinConfig(const grpc_json* json) : json_(json) {} + + const char* name() const override { return kRoundRobin; } + + const grpc_json* config() const { return json_; } + + private: + const grpc_json* json_; +}; + // // factory // @@ -521,6 +533,14 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory { } const char* name() const override { return kRoundRobin; } + + UniquePtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const override { + GPR_DEBUG_ASSERT(json != nullptr); + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + return UniquePtr( + New(json)); + } }; } // namespace 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 443deb01274..73b5de8f15a 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 @@ -119,6 +119,38 @@ namespace { constexpr char kXds[] = "xds_experimental"; constexpr char kDefaultLocalityName[] = "xds_default_locality"; +class ParsedXdsConfig : public ParsedLoadBalancingConfig { + public: + ParsedXdsConfig(const char* balancer_name, + UniquePtr child_policy, + UniquePtr fallback_policy, + const grpc_json* json) + : balancer_name_(balancer_name), + child_policy_(std::move(child_policy)), + fallback_policy_(std::move(fallback_policy)), + json_(json) {} + + const char* name() const override { return kXds; } + + const char* balancer_name() const { return balancer_name_; }; + + const ParsedLoadBalancingConfig* child_policy() const { + return child_policy_.get(); + } + + const ParsedLoadBalancingConfig* fallback_policy() const { + return fallback_policy_.get(); + } + + const grpc_json* config() const { return json_; } + + private: + const char* balancer_name_ = nullptr; + UniquePtr child_policy_; + UniquePtr fallback_policy_; + const grpc_json* json_ = nullptr; +}; + class XdsLb : public LoadBalancingPolicy { public: explicit XdsLb(Args args); @@ -282,7 +314,7 @@ class XdsLb : public LoadBalancingPolicy { ~LocalityEntry() = default; void UpdateLocked(xds_grpclb_serverlist* serverlist, - LoadBalancingPolicy::Config* child_policy_config, + const ParsedLoadBalancingConfig* child_policy_config, const grpc_channel_args* args); void ShutdownLocked(); void ResetBackoffLocked(); @@ -326,7 +358,7 @@ class XdsLb : public LoadBalancingPolicy { }; void UpdateLocked(const LocalityList& locality_list, - LoadBalancingPolicy::Config* child_policy_config, + const ParsedLoadBalancingConfig* child_policy_config, const grpc_channel_args* args, XdsLb* parent); void ShutdownLocked(); void ResetBackoffLocked(); @@ -364,7 +396,7 @@ class XdsLb : public LoadBalancingPolicy { // If parsing succeeds, updates \a balancer_name, and updates \a // child_policy_config_ and \a fallback_policy_config_ if they are also // found. Does nothing upon failure. - void ParseLbConfig(Config* xds_config); + void ParseLbConfig(const ParsedXdsConfig* xds_config); BalancerChannelState* LatestLbChannel() const { return pending_lb_chand_ != nullptr ? pending_lb_chand_.get() @@ -399,7 +431,7 @@ class XdsLb : public LoadBalancingPolicy { // Timeout in milliseconds for before using fallback backend addresses. // 0 means not using fallback. - RefCountedPtr fallback_policy_config_; + const ParsedLoadBalancingConfig* fallback_policy_config_ = nullptr; int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. UniquePtr fallback_backend_addresses_; @@ -409,7 +441,7 @@ class XdsLb : public LoadBalancingPolicy { grpc_closure lb_on_fallback_; // The policy to use for the backends. - RefCountedPtr child_policy_config_; + const ParsedLoadBalancingConfig* child_policy_config_ = nullptr; // Map of policies to use in the backend LocalityMap locality_map_; LocalityList locality_serverlist_; @@ -942,7 +974,7 @@ void XdsLb::BalancerChannelState::BalancerCallState:: xdslb_policy->locality_serverlist_[0]->serverlist = serverlist; xdslb_policy->locality_map_.UpdateLocked( xdslb_policy->locality_serverlist_, - xdslb_policy->child_policy_config_.get(), xdslb_policy->args_, + xdslb_policy->child_policy_config_, xdslb_policy->args_, xdslb_policy); } } else { @@ -1204,41 +1236,17 @@ void XdsLb::ProcessAddressesAndChannelArgsLocked( grpc_channel_args_destroy(lb_channel_args); } -void XdsLb::ParseLbConfig(Config* xds_config) { - const grpc_json* xds_config_json = xds_config->config(); - const char* balancer_name = nullptr; - grpc_json* child_policy = nullptr; - grpc_json* fallback_policy = 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) { - 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. - balancer_name_ = UniquePtr(gpr_strdup(balancer_name)); - if (child_policy != nullptr) { - child_policy_config_ = - MakeRefCounted(child_policy, xds_config->service_config()); - } - if (fallback_policy != nullptr) { - fallback_policy_config_ = - MakeRefCounted(fallback_policy, xds_config->service_config()); - } +void XdsLb::ParseLbConfig(const ParsedXdsConfig* xds_config) { + if (xds_config == nullptr || xds_config->balancer_name() == nullptr) return; + // TODO(yashykt) : does this need to be a gpr_strdup + balancer_name_ = UniquePtr(gpr_strdup(xds_config->balancer_name())); + child_policy_config_ = xds_config->child_policy(); + fallback_policy_config_ = xds_config->fallback_policy(); } void XdsLb::UpdateLocked(UpdateArgs args) { const bool is_initial_update = lb_chand_ == nullptr; - ParseLbConfig(args.config.get()); + ParseLbConfig(static_cast(args.config)); // TODO(juanlishen): Pass fallback policy config update after fallback policy // is added. if (balancer_name_ == nullptr) { @@ -1251,8 +1259,8 @@ void XdsLb::UpdateLocked(UpdateArgs args) { // have been created from a serverlist. // TODO(vpowar): Handle the fallback_address changes when we add support for // fallback in xDS. - locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_.get(), - args_, this); + locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_, args_, + this); // If this is the initial update, start the fallback timer. if (is_initial_update) { if (lb_fallback_timeout_ms_ > 0 && locality_serverlist_.empty() && @@ -1308,7 +1316,7 @@ void XdsLb::LocalityMap::PruneLocalities(const LocalityList& locality_list) { void XdsLb::LocalityMap::UpdateLocked( const LocalityList& locality_serverlist, - LoadBalancingPolicy::Config* child_policy_config, + const ParsedLoadBalancingConfig* child_policy_config, const grpc_channel_args* args, XdsLb* parent) { if (parent->shutting_down_) return; for (size_t i = 0; i < locality_serverlist.size(); i++) { @@ -1401,7 +1409,7 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked( void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( xds_grpclb_serverlist* serverlist, - LoadBalancingPolicy::Config* child_policy_config, + const ParsedLoadBalancingConfig* child_policy_config, const grpc_channel_args* args_in) { if (parent_->shutting_down_) return; // This should never be invoked if we do not have serverlist_, as fallback @@ -1412,8 +1420,7 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( // Construct update args. UpdateArgs update_args; update_args.addresses = ProcessServerlist(serverlist); - update_args.config = - child_policy_config == nullptr ? nullptr : child_policy_config->Ref(); + update_args.config = child_policy_config; update_args.args = CreateChildPolicyArgsLocked(args_in); // If the child policy name changes, we need to create a new child @@ -1654,6 +1661,24 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::RequestReresolution() { } } +// Consumes all the errors in the vector and forms a referencing error from +// them. If the vector is empty, return GRPC_ERROR_NONE. +template +grpc_error* CreateErrorFromVector(const char* desc, + InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; +} + // // factory // @@ -1666,6 +1691,71 @@ class XdsFactory : public LoadBalancingPolicyFactory { } const char* name() const override { return kXds; } + + UniquePtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const override { + GPR_DEBUG_ASSERT(json != nullptr); + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + + InlinedVector error_list; + const char* balancer_name = nullptr; + UniquePtr child_policy = nullptr; + UniquePtr fallback_policy = nullptr; + for (const grpc_json* field = json->child; field != nullptr; + field = field->next) { + if (field->key == nullptr) continue; + if (strcmp(field->key, "balancerName") == 0) { + if (balancer_name != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:balancerName error:Duplicate entry")); + continue; + } + if (field->type != GRPC_JSON_STRING) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:balancerName error:type should be string")); + continue; + } + balancer_name = field->value; + } else if (strcmp(field->key, "childPolicy") == 0) { + if (child_policy != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:childPolicy error:Duplicate entry")); + continue; + } + grpc_error* parse_error = GRPC_ERROR_NONE; + child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, &parse_error); + if (child_policy == nullptr) { + GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); + error_list.push_back(parse_error); + } + } else if (strcmp(field->key, "fallbackPolicy") == 0) { + if (fallback_policy != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:fallbackPolicy error:Duplicate entry")); + } + grpc_error* parse_error = GRPC_ERROR_NONE; + fallback_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, &parse_error); + if (fallback_policy == nullptr) { + GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); + error_list.push_back(parse_error); + } + } + } + if (balancer_name == nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:balancerName error:not found")); + } + if (error_list.empty()) { + return UniquePtr( + New(balancer_name, std::move(child_policy), + std::move(fallback_policy), json)); + } else { + *error = CreateErrorFromVector("Xds Parser", &error_list); + return nullptr; + } + } }; } // namespace 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 1da4b7c6956..cb7b547f589 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -27,6 +27,15 @@ namespace grpc_core { +class ParsedLoadBalancingConfig { + public: + virtual ~ParsedLoadBalancingConfig() = default; + + virtual const char* name() const GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS; +}; + class LoadBalancingPolicyFactory { public: /// Returns a new LB policy instance. @@ -37,9 +46,12 @@ class LoadBalancingPolicyFactory { /// Caller does NOT take ownership of result. virtual const char* name() const GRPC_ABSTRACT; + virtual UniquePtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const GRPC_ABSTRACT; + virtual ~LoadBalancingPolicyFactory() {} - GRPC_ABSTRACT_BASE_CLASS + GRPC_ABSTRACT_BASE_CLASS; }; } // namespace grpc_core 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 99980d5500d..e22a0a793de 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -99,4 +99,28 @@ bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) { return g_state->GetLoadBalancingPolicyFactory(name) != nullptr; } +UniquePtr +LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + GPR_ASSERT(g_state != nullptr); + const grpc_json* policy = + LoadBalancingPolicy::ParseLoadBalancingConfig(json, error); + if (policy == nullptr) { + return nullptr; + } else { + GPR_DEBUG_ASSERT(*error == GRPC_ERROR_NONE); + // Find factory. + LoadBalancingPolicyFactory* factory = + g_state->GetLoadBalancingPolicyFactory(policy->key); + if (factory == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig entry:Factory not found to create policy"); + return nullptr; + } + // Parse load balancing config via factory. + return factory->ParseLoadBalancingConfig(policy, error); + } +} + } // namespace grpc_core 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 7472ba9f8a8..af85e511fbb 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -51,6 +51,9 @@ class LoadBalancingPolicyRegistry { /// Returns true if the LB policy factory specified by \a name exists in this /// registry. static bool LoadBalancingPolicyExists(const char* name); + + static UniquePtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error); }; } // namespace grpc_core 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 7148e16e70b..69aeaf9eb85 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -35,6 +35,7 @@ #include "src/core/lib/channel/status_util.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/optional.h" #include "src/core/lib/uri/uri_parser.h" // As per the retry design, we do not allow more than 5 retry attempts. @@ -43,6 +44,9 @@ namespace grpc_core { namespace internal { +size_t ClientChannelServiceConfigParser:: + client_channel_service_config_parser_index_; + ProcessedResolverResult::ProcessedResolverResult( Resolver::Result* resolver_result, bool parse_retry) : service_config_(resolver_result->service_config) { @@ -81,11 +85,38 @@ ProcessedResolverResult::ProcessedResolverResult( if (lb_policy_name_ == nullptr) ProcessLbPolicyName(*resolver_result); } +namespace { +// Consumes all the errors in the vector and forms a referencing error from +// them. If the vector is empty, return GRPC_ERROR_NONE. +template +grpc_error* CreateErrorFromVector(const char* desc, + InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; +} +} // namespace + void ProcessedResolverResult::ProcessServiceConfig( const Resolver::Result& resolver_result, bool parse_retry) { if (service_config_ == nullptr) return; - service_config_json_ = - UniquePtr(gpr_strdup(service_config_->service_config_json())); + service_config_json_ = service_config_->service_config_json(); + auto* parsed_object = static_cast( + service_config_->GetParsedGlobalServiceConfigObject( + ClientChannelServiceConfigParser:: + client_channel_service_config_parser_index())); + + if (!parsed_object) { + return; + } if (parse_retry) { const grpc_arg* channel_arg = grpc_channel_args_find(resolver_result.args, GRPC_ARG_SERVER_URI); @@ -94,29 +125,32 @@ void ProcessedResolverResult::ProcessServiceConfig( 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); + if (parsed_object->retry_throttling().has_value()) { + retry_throttle_data_ = + grpc_core::internal::ServerRetryThrottleMap::GetDataForServer( + server_name_, + parsed_object->retry_throttling().value().max_milli_tokens, + parsed_object->retry_throttling().value().milli_token_ratio); + } grpc_uri_destroy(uri); - } else { - service_config_->ParseGlobalParams(ParseServiceConfig, this); } - method_params_table_ = service_config_->CreateMethodConfigTable( - ClientChannelMethodParams::CreateFromJson); + if (parsed_object->parsed_lb_config()) { + lb_policy_name_.reset( + gpr_strdup(parsed_object->parsed_lb_config()->name())); + lb_policy_config_ = parsed_object->parsed_lb_config(); + } else { + lb_policy_name_.reset( + gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); + } } void ProcessedResolverResult::ProcessLbPolicyName( 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. - if (service_config_ != nullptr) { - lb_policy_name_.reset( - gpr_strdup(service_config_->GetLoadBalancingPolicyName())); - // Convert to lower-case. - if (lb_policy_name_ != nullptr) { - char* lb_policy_name = lb_policy_name_.get(); - for (size_t i = 0; i < strlen(lb_policy_name); ++i) { - lb_policy_name[i] = tolower(lb_policy_name[i]); - } + // Prefer the LB policy name found in the service config. + if (lb_policy_name_ != nullptr) { + char* lb_policy_name = lb_policy_name_.get(); + for (size_t i = 0; i < strlen(lb_policy_name); ++i) { + lb_policy_name[i] = tolower(lb_policy_name[i]); } } // Otherwise, find the LB policy name set by the client API. @@ -152,97 +186,8 @@ void ProcessedResolverResult::ProcessLbPolicyName( } } -void ProcessedResolverResult::ParseServiceConfig( - const grpc_json* field, ProcessedResolverResult* parsing_state) { - parsing_state->ParseLbConfigFromServiceConfig(field); - if (parsing_state->server_name_ != nullptr) { - parsing_state->ParseRetryThrottleParamsFromServiceConfig(field); - } -} - -void ProcessedResolverResult::ParseLbConfigFromServiceConfig( - const grpc_json* field) { - if (lb_policy_config_ != nullptr) return; // Already found. - if (field->key == nullptr || strcmp(field->key, "loadBalancingConfig") != 0) { - return; // Not the LB config global parameter. - } - const grpc_json* policy = - LoadBalancingPolicy::ParseLoadBalancingConfig(field); - if (policy != nullptr) { - lb_policy_name_.reset(gpr_strdup(policy->key)); - lb_policy_config_ = - MakeRefCounted(policy, service_config_); - } -} - -void ProcessedResolverResult::ParseRetryThrottleParamsFromServiceConfig( - const grpc_json* field) { - if (strcmp(field->key, "retryThrottling") == 0) { - if (retry_throttle_data_ != nullptr) return; // Duplicate. - if (field->type != GRPC_JSON_OBJECT) return; - int max_milli_tokens = 0; - int milli_token_ratio = 0; - for (grpc_json* sub_field = field->child; sub_field != nullptr; - sub_field = sub_field->next) { - if (sub_field->key == nullptr) return; - if (strcmp(sub_field->key, "maxTokens") == 0) { - if (max_milli_tokens != 0) return; // Duplicate. - if (sub_field->type != GRPC_JSON_NUMBER) return; - max_milli_tokens = gpr_parse_nonnegative_int(sub_field->value); - if (max_milli_tokens == -1) return; - max_milli_tokens *= 1000; - } else if (strcmp(sub_field->key, "tokenRatio") == 0) { - if (milli_token_ratio != 0) return; // Duplicate. - if (sub_field->type != GRPC_JSON_NUMBER) return; - // We support up to 3 decimal digits. - size_t whole_len = strlen(sub_field->value); - uint32_t multiplier = 1; - uint32_t decimal_value = 0; - const char* decimal_point = strchr(sub_field->value, '.'); - if (decimal_point != nullptr) { - whole_len = static_cast(decimal_point - sub_field->value); - multiplier = 1000; - size_t decimal_len = strlen(decimal_point + 1); - if (decimal_len > 3) decimal_len = 3; - if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len, - &decimal_value)) { - return; - } - uint32_t decimal_multiplier = 1; - for (size_t i = 0; i < (3 - decimal_len); ++i) { - decimal_multiplier *= 10; - } - decimal_value *= decimal_multiplier; - } - uint32_t whole_value; - if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len, - &whole_value)) { - return; - } - milli_token_ratio = - static_cast((whole_value * multiplier) + decimal_value); - if (milli_token_ratio <= 0) return; - } - } - retry_throttle_data_ = - grpc_core::internal::ServerRetryThrottleMap::GetDataForServer( - server_name_, max_milli_tokens, milli_token_ratio); - } -} - namespace { -bool ParseWaitForReady( - grpc_json* field, ClientChannelMethodParams::WaitForReady* wait_for_ready) { - if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) { - return false; - } - *wait_for_ready = field->type == GRPC_JSON_TRUE - ? ClientChannelMethodParams::WAIT_FOR_READY_TRUE - : ClientChannelMethodParams::WAIT_FOR_READY_FALSE; - return true; -} - // Parses a JSON field of the form generated for a google.proto.Duration // proto message, as per: // https://developers.google.com/protocol-buffers/docs/proto3#json @@ -275,18 +220,37 @@ bool ParseDuration(grpc_json* field, grpc_millis* duration) { return true; } -UniquePtr ParseRetryPolicy( - grpc_json* field) { - auto retry_policy = MakeUnique(); - if (field->type != GRPC_JSON_OBJECT) return nullptr; +UniquePtr ParseRetryPolicy( + grpc_json* field, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + auto retry_policy = + MakeUnique(); + if (field->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryPolicy error:should be of type object"); + return nullptr; + } + InlinedVector error_list; for (grpc_json* sub_field = field->child; sub_field != nullptr; sub_field = sub_field->next) { - if (sub_field->key == nullptr) return nullptr; + if (sub_field->key == nullptr) continue; if (strcmp(sub_field->key, "maxAttempts") == 0) { - if (retry_policy->max_attempts != 0) return nullptr; // Duplicate. - if (sub_field->type != GRPC_JSON_NUMBER) return nullptr; + if (retry_policy->max_attempts != 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxAttempts error:Duplicate entry")); + continue; + } // Duplicate. + if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxAttempts error:should be of type number")); + continue; + } retry_policy->max_attempts = gpr_parse_nonnegative_int(sub_field->value); - if (retry_policy->max_attempts <= 1) return nullptr; + if (retry_policy->max_attempts <= 1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxAttempts error:should be atleast 2")); + continue; + } if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) { gpr_log(GPR_ERROR, "service config: clamped retryPolicy.maxAttempts at %d", @@ -294,78 +258,314 @@ UniquePtr ParseRetryPolicy( retry_policy->max_attempts = MAX_MAX_RETRY_ATTEMPTS; } } else if (strcmp(sub_field->key, "initialBackoff") == 0) { - if (retry_policy->initial_backoff > 0) return nullptr; // Duplicate. + if (retry_policy->initial_backoff > 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:initialBackoff error:Duplicate entry")); + continue; + } if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) { - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:initialBackoff error:Failed to parse")); + continue; + } + if (retry_policy->initial_backoff == 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:initialBackoff error:must be greater than 0")); } - if (retry_policy->initial_backoff == 0) return nullptr; } else if (strcmp(sub_field->key, "maxBackoff") == 0) { - if (retry_policy->max_backoff > 0) return nullptr; // Duplicate. - if (!ParseDuration(sub_field, &retry_policy->max_backoff)) { - return nullptr; + if (retry_policy->max_backoff > 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxBackoff error:Duplicate entry")); + continue; + } + if (!ParseDuration(sub_field, &retry_policy->max_backoff)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxBackoff error:failed to parse")); + continue; + } + if (retry_policy->max_backoff == 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxBackoff error:should be greater than 0")); } - if (retry_policy->max_backoff == 0) return nullptr; } else if (strcmp(sub_field->key, "backoffMultiplier") == 0) { - if (retry_policy->backoff_multiplier != 0) return nullptr; // Duplicate. - if (sub_field->type != GRPC_JSON_NUMBER) return nullptr; + if (retry_policy->backoff_multiplier != 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:backoffMultiplier error:Duplicate entry")); + continue; + } + if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:backoffMultiplier error:should be of type number")); + continue; + } if (sscanf(sub_field->value, "%f", &retry_policy->backoff_multiplier) != 1) { - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:backoffMultiplier error:failed to parse")); + continue; + } + if (retry_policy->backoff_multiplier <= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:backoffMultiplier error:should be greater than 0")); } - if (retry_policy->backoff_multiplier <= 0) return nullptr; } else if (strcmp(sub_field->key, "retryableStatusCodes") == 0) { if (!retry_policy->retryable_status_codes.Empty()) { - return nullptr; // Duplicate. + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:Duplicate entry")); + continue; + } + if (sub_field->type != GRPC_JSON_ARRAY) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:should be of type array")); + continue; } - if (sub_field->type != GRPC_JSON_ARRAY) return nullptr; for (grpc_json* element = sub_field->child; element != nullptr; element = element->next) { - if (element->type != GRPC_JSON_STRING) return nullptr; + if (element->type != GRPC_JSON_STRING) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:status codes should be of type " + "string")); + continue; + } grpc_status_code status; if (!grpc_status_code_from_string(element->value, &status)) { - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:failed to parse status code")); + continue; } retry_policy->retryable_status_codes.Add(status); } - if (retry_policy->retryable_status_codes.Empty()) return nullptr; + if (retry_policy->retryable_status_codes.Empty()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:should be non-empty")); + }; } } // Make sure required fields are set. - if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 || - retry_policy->max_backoff == 0 || retry_policy->backoff_multiplier == 0 || - retry_policy->retryable_status_codes.Empty()) { - return nullptr; + if (error_list.empty()) { + if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 || + retry_policy->max_backoff == 0 || + retry_policy->backoff_multiplier == 0 || + retry_policy->retryable_status_codes.Empty()) { + return nullptr; + } } - return retry_policy; + *error = CreateErrorFromVector("retryPolicy", &error_list); + return *error == GRPC_ERROR_NONE ? std::move(retry_policy) : nullptr; } } // namespace -RefCountedPtr -ClientChannelMethodParams::CreateFromJson(const grpc_json* json) { - RefCountedPtr method_params = - MakeRefCounted(); +UniquePtr +ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + InlinedVector error_list; + UniquePtr parsed_lb_config; + const char* lb_policy_name = nullptr; + grpc_core::Optional + retry_throttling; + for (grpc_json* field = json->child; field != nullptr; field = field->next) { + if (field->key == nullptr) { + continue; // Not the LB config global parameter + } + // Parsed Load balancing config + if (strcmp(field->key, "loadBalancingConfig") == 0) { + if (parsed_lb_config != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:Duplicate entry")); + } else { + grpc_error* parse_error = GRPC_ERROR_NONE; + parsed_lb_config = + LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(field, + &parse_error); + if (parsed_lb_config == nullptr) { + error_list.push_back(parse_error); + } + } + } + // Parse deprecated loadBalancingPolicy + if (strcmp(field->key, "loadBalancingPolicy") == 0) { + if (lb_policy_name != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:Duplicate entry")); + } else if (field->type != GRPC_JSON_STRING) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:type should be string")); + } else if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( + field->value)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:Unrecognized lb policy")); + } else { + lb_policy_name = field->value; + } + } + // Parse retry throttling + if (strcmp(field->key, "retryThrottling") == 0) { + if (field->type != GRPC_JSON_OBJECT) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling error:Type should be object")); + } else if (retry_throttling.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling error:Duplicate entry")); + } else { + grpc_core::Optional max_milli_tokens(false, 0); + grpc_core::Optional milli_token_ratio(false, 0); + for (grpc_json* sub_field = field->child; sub_field != nullptr; + sub_field = sub_field->next) { + if (sub_field->key == nullptr) continue; + if (strcmp(sub_field->key, "maxTokens") == 0) { + if (max_milli_tokens.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Duplicate " + "entry")); + } else if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Type should be " + "number")); + } else { + max_milli_tokens.set(gpr_parse_nonnegative_int(sub_field->value) * + 1000); + if (max_milli_tokens.value() <= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:should be " + "greater than zero")); + } + } + } else if (strcmp(sub_field->key, "tokenRatio") == 0) { + if (milli_token_ratio.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Duplicate " + "entry")); + } else if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:type should be " + "number")); + } else { + // We support up to 3 decimal digits. + size_t whole_len = strlen(sub_field->value); + uint32_t multiplier = 1; + uint32_t decimal_value = 0; + const char* decimal_point = strchr(sub_field->value, '.'); + if (decimal_point != nullptr) { + whole_len = + static_cast(decimal_point - sub_field->value); + multiplier = 1000; + size_t decimal_len = strlen(decimal_point + 1); + if (decimal_len > 3) decimal_len = 3; + if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len, + &decimal_value)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Failed " + "parsing")); + continue; + } + uint32_t decimal_multiplier = 1; + for (size_t i = 0; i < (3 - decimal_len); ++i) { + decimal_multiplier *= 10; + } + decimal_value *= decimal_multiplier; + } + uint32_t whole_value; + if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len, + &whole_value)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Failed " + "parsing")); + continue; + } + milli_token_ratio.set( + static_cast((whole_value * multiplier) + decimal_value)); + if (milli_token_ratio.value() <= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:value should " + "be greater than 0")); + } + } + } + } + if (!max_milli_tokens.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Not found")); + } + if (!milli_token_ratio.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Not found")); + } + if (error_list.size() == 0) { + ClientChannelGlobalParsedObject::RetryThrottling data; + data.max_milli_tokens = max_milli_tokens.value(); + data.milli_token_ratio = milli_token_ratio.value(); + retry_throttling.set(data); + } + } + } + } + *error = CreateErrorFromVector("Client channel global parser", &error_list); + if (*error == GRPC_ERROR_NONE) { + return UniquePtr( + New(std::move(parsed_lb_config), + lb_policy_name, retry_throttling)); + } + return nullptr; +} + +UniquePtr +ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + InlinedVector error_list; + Optional wait_for_ready; + grpc_millis timeout = 0; + UniquePtr retry_policy; for (grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) continue; if (strcmp(field->key, "waitForReady") == 0) { - if (method_params->wait_for_ready_ != WAIT_FOR_READY_UNSET) { - return nullptr; // Duplicate. + if (wait_for_ready.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:waitForReady error:Duplicate entry")); + continue; } - if (!ParseWaitForReady(field, &method_params->wait_for_ready_)) { - return nullptr; + if (field->type == GRPC_JSON_TRUE) { + wait_for_ready.set(true); + } else if (field->type == GRPC_JSON_FALSE) { + wait_for_ready.set(false); + } else { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:waitForReady error:Type should be a true/false")); } } else if (strcmp(field->key, "timeout") == 0) { - if (method_params->timeout_ > 0) return nullptr; // Duplicate. - if (!ParseDuration(field, &method_params->timeout_)) return nullptr; - } else if (strcmp(field->key, "retryPolicy") == 0) { - if (method_params->retry_policy_ != nullptr) { - return nullptr; // Duplicate. + if (timeout > 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:timeout error:Duplicate entry")); + continue; + } + if (!ParseDuration(field, &timeout)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:timeout error:Failed parsing")); + }; + } else if (strcmp(field->key, "retryPolicy") == 0) { + if (retry_policy != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryPolicy error:Duplicate entry")); + continue; + } + grpc_error* error = GRPC_ERROR_NONE; + retry_policy = ParseRetryPolicy(field, &error); + if (retry_policy == nullptr) { + error_list.push_back(error); } - method_params->retry_policy_ = ParseRetryPolicy(field); - if (method_params->retry_policy_ == nullptr) return nullptr; } } - return method_params; + *error = CreateErrorFromVector("Client channel parser", &error_list); + if (*error == GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "hura"); + return UniquePtr( + New(timeout, wait_for_ready, + std::move(retry_policy))); + } + gpr_log(GPR_ERROR, "hura"); + return nullptr; } } // namespace internal 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 ad40c4991fe..41b5ccdcb65 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -22,10 +22,12 @@ #include #include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_factory.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/optional.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 @@ -35,11 +37,89 @@ namespace grpc_core { namespace internal { -class ClientChannelMethodParams; +class ClientChannelGlobalParsedObject : public ServiceConfigParsedObject { + public: + struct RetryThrottling { + int max_milli_tokens = 0; + int milli_token_ratio = 0; + }; -// A table mapping from a method name to its method parameters. -typedef SliceHashTable> - ClientChannelMethodParamsTable; + ClientChannelGlobalParsedObject( + UniquePtr parsed_lb_config, + const char* parsed_deprecated_lb_policy, + const grpc_core::Optional& retry_throttling) + : parsed_lb_config_(std::move(parsed_lb_config)), + parsed_deprecated_lb_policy_(parsed_deprecated_lb_policy), + retry_throttling_(retry_throttling) {} + + grpc_core::Optional retry_throttling() const { + return retry_throttling_; + } + + const ParsedLoadBalancingConfig* parsed_lb_config() const { + return parsed_lb_config_.get(); + } + + const char* parsed_deprecated_lb_policy() const { + return parsed_deprecated_lb_policy_; + } + + private: + UniquePtr parsed_lb_config_; + const char* parsed_deprecated_lb_policy_ = nullptr; + grpc_core::Optional retry_throttling_; +}; + +class ClientChannelMethodParsedObject : public ServiceConfigParsedObject { + public: + struct RetryPolicy { + int max_attempts = 0; + grpc_millis initial_backoff = 0; + grpc_millis max_backoff = 0; + float backoff_multiplier = 0; + StatusCodeSet retryable_status_codes; + }; + + ClientChannelMethodParsedObject(grpc_millis timeout, + const Optional& wait_for_ready, + UniquePtr retry_policy) + : timeout_(timeout), + wait_for_ready_(wait_for_ready), + retry_policy_(std::move(retry_policy)) {} + + grpc_millis timeout() const { return timeout_; } + + Optional wait_for_ready() const { return wait_for_ready_; } + + const RetryPolicy* retry_policy() const { return retry_policy_.get(); } + + private: + grpc_millis timeout_ = 0; + Optional wait_for_ready_; + UniquePtr retry_policy_; +}; + +class ClientChannelServiceConfigParser : public ServiceConfigParser { + public: + UniquePtr ParseGlobalParams( + const grpc_json* json, grpc_error** error) override; + + UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) override; + + static size_t client_channel_service_config_parser_index() { + return client_channel_service_config_parser_index_; + } + + static void Register() { + client_channel_service_config_parser_index_ = + ServiceConfig::RegisterParser(UniquePtr( + New())); + } + + private: + static size_t client_channel_service_config_parser_index_; +}; // A container of processed fields from the resolver result. Simplifies the // usage of resolver result. @@ -51,18 +131,14 @@ class ProcessedResolverResult { ProcessedResolverResult(Resolver::Result* resolver_result, bool parse_retry); // Getters. Any managed object's ownership is transferred. - UniquePtr service_config_json() { - return std::move(service_config_json_); - } + const char* service_config_json() { return service_config_json_; } RefCountedPtr retry_throttle_data() { return std::move(retry_throttle_data_); } - RefCountedPtr method_params_table() { - return std::move(method_params_table_); - } + UniquePtr lb_policy_name() { return std::move(lb_policy_name_); } - RefCountedPtr lb_policy_config() { - return std::move(lb_policy_config_); + const ParsedLoadBalancingConfig* lb_policy_config() { + return lb_policy_config_; } RefCountedPtr service_config() { return service_config_; } @@ -85,59 +161,14 @@ class ProcessedResolverResult { void ParseRetryThrottleParamsFromServiceConfig(const grpc_json* field); // Service config. - UniquePtr service_config_json_; + const char* service_config_json_ = nullptr; RefCountedPtr service_config_; // LB policy. UniquePtr lb_policy_name_; - RefCountedPtr lb_policy_config_; + const ParsedLoadBalancingConfig* lb_policy_config_ = nullptr; // Retry throttle data. char* server_name_ = nullptr; RefCountedPtr retry_throttle_data_; - // Method params table. - RefCountedPtr method_params_table_; -}; - -// The parameters of a method. -class ClientChannelMethodParams : public RefCounted { - public: - enum WaitForReady { - WAIT_FOR_READY_UNSET = 0, - WAIT_FOR_READY_FALSE, - WAIT_FOR_READY_TRUE - }; - - struct RetryPolicy { - int max_attempts = 0; - grpc_millis initial_backoff = 0; - grpc_millis max_backoff = 0; - float backoff_multiplier = 0; - StatusCodeSet retryable_status_codes; - }; - - /// Creates a method_parameters object from \a json. - /// Intended for use with ServiceConfig::CreateMethodConfigTable(). - static RefCountedPtr CreateFromJson( - const grpc_json* json); - - grpc_millis timeout() const { return timeout_; } - WaitForReady wait_for_ready() const { return wait_for_ready_; } - const RetryPolicy* retry_policy() const { return retry_policy_.get(); } - - private: - // So New() can call our private ctor. - template - friend T* grpc_core::New(Args&&... args); - - // So Delete() can call our private dtor. - template - friend void grpc_core::Delete(T*); - - ClientChannelMethodParams() {} - virtual ~ClientChannelMethodParams() {} - - grpc_millis timeout_ = 0; - WaitForReady wait_for_ready_ = WAIT_FOR_READY_UNSET; - UniquePtr retry_policy_; }; } // namespace internal 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 a2367e09d9b..2d0f72f8520 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -192,8 +192,8 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( Args args, TraceFlag* tracer, UniquePtr target_uri, - UniquePtr child_policy_name, RefCountedPtr child_lb_config, - grpc_error** error) + UniquePtr child_policy_name, + const ParsedLoadBalancingConfig* child_lb_config, grpc_error** error) : LoadBalancingPolicy(std::move(args)), tracer_(tracer), target_uri_(std::move(target_uri)), @@ -341,8 +341,9 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { } void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( - const char* lb_policy_name, RefCountedPtr lb_policy_config, - Resolver::Result result, TraceStringVector* trace_strings) { + const char* lb_policy_name, + const ParsedLoadBalancingConfig* lb_policy_config, 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 @@ -538,7 +539,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( const bool resolution_contains_addresses = result.addresses.size() > 0; // Process the resolver result. const char* lb_policy_name = nullptr; - RefCountedPtr lb_policy_config; + const ParsedLoadBalancingConfig* lb_policy_config = nullptr; bool service_config_changed = false; if (process_resolver_result_ != nullptr) { service_config_changed = @@ -550,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), + CreateOrUpdateLbPolicyLocked(lb_policy_name, lb_policy_config, std::move(result), &trace_strings); // Add channel trace event. if (channelz_node() != nullptr) { 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 c9349769dd2..d36ae627066 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -23,6 +23,7 @@ #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/lb_policy_factory.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" @@ -56,7 +57,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { ResolvingLoadBalancingPolicy(Args args, TraceFlag* tracer, UniquePtr target_uri, UniquePtr child_policy_name, - RefCountedPtr child_lb_config, + const ParsedLoadBalancingConfig* child_lb_config, grpc_error** error); // Private ctor, to be used by client_channel only! @@ -66,7 +67,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // Returns true if the service config has changed since the last result. typedef bool (*ProcessResolverResultCallback)( void* user_data, Resolver::Result* result, const char** lb_policy_name, - RefCountedPtr* lb_policy_config); + const ParsedLoadBalancingConfig** lb_policy_config); // If error is set when this returns, then construction failed, and // the caller may not use the new object. ResolvingLoadBalancingPolicy( @@ -102,10 +103,10 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { void StartResolvingLocked(); void OnResolverError(grpc_error* error); - void CreateOrUpdateLbPolicyLocked(const char* lb_policy_name, - RefCountedPtr lb_policy_config, - Resolver::Result result, - TraceStringVector* trace_strings); + void CreateOrUpdateLbPolicyLocked( + const char* lb_policy_name, + const ParsedLoadBalancingConfig* lb_policy_config, + Resolver::Result result, TraceStringVector* trace_strings); OrphanablePtr CreateLbPolicyLocked( const char* lb_policy_name, const grpc_channel_args& args, TraceStringVector* trace_strings); @@ -121,7 +122,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { ProcessResolverResultCallback process_resolver_result_ = nullptr; void* process_resolver_result_user_data_ = nullptr; UniquePtr child_policy_name_; - RefCountedPtr child_lb_config_; + const ParsedLoadBalancingConfig* child_lb_config_ = nullptr; // Resolver and associated state. OrphanablePtr resolver_; diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index d9e64ccf5a8..06a413a89af 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -134,8 +134,11 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( } objs_vector->push_back(std::move(parsed_obj)); } - const auto* vector_ptr = objs_vector.get(); service_config_objects_vectors_storage_.push_back(std::move(objs_vector)); + const auto* vector_ptr = + service_config_objects_vectors_storage_ + [service_config_objects_vectors_storage_.size() - 1] + .get(); // Construct list of paths. InlinedVector, 10> paths; for (grpc_json* child = json->child; child != nullptr; child = child->next) { @@ -231,23 +234,6 @@ grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); } -const char* ServiceConfig::GetLoadBalancingPolicyName() const { - if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) { - return nullptr; - } - const char* lb_policy_name = nullptr; - for (grpc_json* field = json_tree_->child; field != nullptr; - field = field->next) { - if (field->key == nullptr) return nullptr; - if (strcmp(field->key, "loadBalancingPolicy") == 0) { - if (lb_policy_name != nullptr) return nullptr; // Duplicate. - if (field->type != GRPC_JSON_STRING) return nullptr; - lb_policy_name = field->value; - } - } - return lb_policy_name; -} - int ServiceConfig::CountNamesInMethodConfig(grpc_json* json) { int num_names = 0; for (grpc_json* field = json->child; field != nullptr; field = field->next) { @@ -319,8 +305,11 @@ UniquePtr ServiceConfig::ParseJsonMethodName(grpc_json* json, return UniquePtr(path); } -const ServiceConfig::ServiceConfigObjectsVector* const* +const ServiceConfig::ServiceConfigObjectsVector* ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) { + if (parsed_method_service_config_objects_table_.get() == nullptr) { + return nullptr; + } const auto* value = parsed_method_service_config_objects_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/*"). @@ -339,7 +328,7 @@ ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) { gpr_free(path_str); if (value == nullptr) return nullptr; } - return value; + return *value; } size_t ServiceConfig::RegisterParser(UniquePtr parser) { diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 0f2d2b387ae..5ec6c6de346 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -107,11 +107,6 @@ class ServiceConfig : public RefCounted { template void ParseGlobalParams(ProcessJson process_json, T* arg) const; - /// Gets the LB policy name from \a service_config. - /// Returns NULL if no LB policy name was specified. - /// Caller does NOT take ownership. - const char* GetLoadBalancingPolicyName() const; - /// Creates a method config table based on the data in \a json. /// The table's keys are request paths. The table's value type is /// returned by \a create_value(), based on data parsed from the JSON tree. @@ -141,7 +136,7 @@ class ServiceConfig : public RefCounted { /// Retrieves the vector of method service config objects for a given path \a /// path. - const ServiceConfigObjectsVector* const* GetMethodServiceConfigObjectsVector( + const ServiceConfigObjectsVector* GetMethodServiceConfigObjectsVector( const grpc_slice& path); /// Globally register a service config parser. On successful registration, it diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h index 722c22c4623..3c91f9365f8 100644 --- a/src/core/lib/channel/context.h +++ b/src/core/lib/channel/context.h @@ -37,6 +37,8 @@ typedef enum { GRPC_SERVICE_CONFIG, + GRPC_SERVICE_CONFIG_METHOD_PARAMS, + GRPC_CONTEXT_COUNT } grpc_context_index; diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index a8e3ce1505e..5c519fe7ec0 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -26,6 +26,9 @@ namespace grpc_core { template class Optional { public: + Optional() = default; + + Optional(bool set, T value) : set_(set), value_(value) {} void set(const T& val) { value_ = val; set_ = true; @@ -38,8 +41,8 @@ class Optional { T value() const { return value_; } private: - T value_; bool set_ = false; + T value_; }; } /* namespace grpc_core */ diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index fcc6f0761b3..99a148ddc26 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -30,6 +30,7 @@ #include #include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/inlined_vector.h" /// Opaque representation of an error. /// See https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md for a diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index 10cb4cd4404..229944435b0 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -21,6 +21,7 @@ #include #include +#include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/gpr/string.h" #include "test/core/util/port.h" @@ -201,6 +202,9 @@ TEST_F(ServiceConfigTest, Parser1BasicTest1) { EXPECT_TRUE((static_cast( svc_cfg->GetParsedGlobalServiceConfigObject(0))) ->value() == 5); + EXPECT_TRUE(svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")) == + nullptr); } TEST_F(ServiceConfigTest, Parser1BasicTest2) { @@ -252,11 +256,10 @@ TEST_F(ServiceConfigTest, Parser2BasicTest) { grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); ASSERT_TRUE(error == GRPC_ERROR_NONE); - const auto* const* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( grpc_slice_from_static_string("/TestServ/TestMethod")); EXPECT_TRUE(vector_ptr != nullptr); - const auto* vector = *vector_ptr; - auto parsed_object = ((*vector)[1]).get(); + auto parsed_object = ((*vector_ptr)[1]).get(); EXPECT_TRUE(static_cast(parsed_object)->value() == 5); } @@ -352,6 +355,58 @@ TEST_F(ErroredParsersScopingTest, MethodParams) { GRPC_ERROR_UNREF(error); } +class ClientChannelParserTest : public ::testing::Test { + protected: + void SetUp() override { + ServiceConfig::Shutdown(); + ServiceConfig::Init(); + EXPECT_TRUE( + ServiceConfig::RegisterParser(UniquePtr( + New())) == + 0); + } +}; + +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig1) { + const char* test_json = "{\"loadBalancingConfig\": [{\"pick_first\":{}}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto* lb_config = parsed_object->parsed_lb_config(); + EXPECT_TRUE(strcmp(lb_config->name(), "pick_first") == 0); +} + +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig2) { + const char* test_json = + "{\"loadBalancingConfig\": [{\"round_robin\":{}}, {}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto* lb_config = parsed_object->parsed_lb_config(); + EXPECT_TRUE(strcmp(lb_config->name(), "round_robin") == 0); +} + +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig3) { + const char* test_json = + "{\"loadBalancingConfig\": " + "[{\"grpclb\":{\"childPolicy\":[{\"pick_first\":{}}]}}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto* lb_config = parsed_object->parsed_lb_config(); + EXPECT_TRUE(strcmp(lb_config->name(), "grpclb") == 0); +} + } // namespace testing } // namespace grpc_core From 2c4c8438cc11e4ffbac2ed10078a0513d5036b37 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 18 Apr 2019 11:27:54 -0700 Subject: [PATCH 1891/2143] Message size filter parser and health check parser --- BUILD | 2 + BUILD.gn | 2 + CMakeLists.txt | 6 + Makefile | 6 + build.yaml | 2 + config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + grpc.gyp | 4 + package.xml | 2 + .../client_channel/client_channel_plugin.cc | 2 + .../health/health_check_parser.cc | 75 +++++++ .../health/health_check_parser.h | 49 +++++ .../filters/client_channel/service_config.h | 5 +- .../message_size/message_size_filter.cc | 193 +++++++++++++----- .../message_size/message_size_filter.h | 13 ++ src/python/grpcio/grpc_core_dependencies.py | 1 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 3 + 21 files changed, 319 insertions(+), 56 deletions(-) create mode 100644 src/core/ext/filters/client_channel/health/health_check_parser.cc create mode 100644 src/core/ext/filters/client_channel/health/health_check_parser.h diff --git a/BUILD b/BUILD index ec9f58dbed1..104351bd1ad 100644 --- a/BUILD +++ b/BUILD @@ -1081,6 +1081,7 @@ grpc_cc_library( "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/health/health_check_parser.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", @@ -1107,6 +1108,7 @@ grpc_cc_library( "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/health/health_check_parser.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", diff --git a/BUILD.gn b/BUILD.gn index 78e434477b8..feb0225a037 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -260,6 +260,8 @@ config("grpc_config") { "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/health/health_check_parser.cc", + "src/core/ext/filters/client_channel/health/health_check_parser.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", diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d5e448d688..f268f4156fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1232,6 +1232,7 @@ add_library(grpc 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/health/health_check_parser.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 @@ -1586,6 +1587,7 @@ add_library(grpc_cronet 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/health/health_check_parser.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 @@ -1965,6 +1967,7 @@ add_library(grpc_test_util 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/health/health_check_parser.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 @@ -2289,6 +2292,7 @@ add_library(grpc_test_util_unsecure 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/health/health_check_parser.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 @@ -2624,6 +2628,7 @@ add_library(grpc_unsecure 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/health/health_check_parser.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 @@ -3496,6 +3501,7 @@ add_library(grpc++_cronet 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/health/health_check_parser.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 diff --git a/Makefile b/Makefile index c3c7412590d..ed5d1329679 100644 --- a/Makefile +++ b/Makefile @@ -3687,6 +3687,7 @@ LIBGRPC_SRC = \ 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/health/health_check_parser.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 \ @@ -4035,6 +4036,7 @@ LIBGRPC_CRONET_SRC = \ 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/health/health_check_parser.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 \ @@ -4407,6 +4409,7 @@ LIBGRPC_TEST_UTIL_SRC = \ 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/health/health_check_parser.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 \ @@ -4718,6 +4721,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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/health/health_check_parser.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 \ @@ -5027,6 +5031,7 @@ LIBGRPC_UNSECURE_SRC = \ 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/health/health_check_parser.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 \ @@ -5875,6 +5880,7 @@ LIBGRPC++_CRONET_SRC = \ 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/health/health_check_parser.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 \ diff --git a/build.yaml b/build.yaml index 8752447f125..c8b4619bae7 100644 --- a/build.yaml +++ b/build.yaml @@ -574,6 +574,7 @@ filegroups: - 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/health/health_check_parser.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 @@ -603,6 +604,7 @@ filegroups: - 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/health/health_check_parser.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 diff --git a/config.m4 b/config.m4 index 2c64a3eb168..03576f2f90c 100644 --- a/config.m4 +++ b/config.m4 @@ -347,6 +347,7 @@ if test "$PHP_GRPC" != "no"; then 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/health/health_check_parser.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 \ diff --git a/config.w32 b/config.w32 index 6897c1041ac..b727e989717 100644 --- a/config.w32 +++ b/config.w32 @@ -322,6 +322,7 @@ if (PHP_GRPC != "no") { "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\\health\\health_check_parser.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 " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 7c90454f1a9..1ce79bed4ca 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -368,6 +368,7 @@ Pod::Spec.new do |s| '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/health/health_check_parser.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', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index c58152cf7f8..e5849c21066 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -347,6 +347,7 @@ Pod::Spec.new do |s| '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/health/health_check_parser.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', @@ -794,6 +795,7 @@ Pod::Spec.new do |s| '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/health/health_check_parser.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', @@ -987,6 +989,7 @@ Pod::Spec.new do |s| '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/health/health_check_parser.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', diff --git a/grpc.gemspec b/grpc.gemspec index c41db6f6293..2230b2d1d4d 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -281,6 +281,7 @@ Gem::Specification.new do |s| 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/health/health_check_parser.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 ) @@ -731,6 +732,7 @@ Gem::Specification.new do |s| 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/health/health_check_parser.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 ) diff --git a/grpc.gyp b/grpc.gyp index 322259d2ca7..66cfa592832 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -529,6 +529,7 @@ '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/health/health_check_parser.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', @@ -792,6 +793,7 @@ '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/health/health_check_parser.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', @@ -1036,6 +1038,7 @@ '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/health/health_check_parser.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', @@ -1291,6 +1294,7 @@ '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/health/health_check_parser.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', diff --git a/package.xml b/package.xml index 5be3d24365d..27d6da303b3 100644 --- a/package.xml +++ b/package.xml @@ -286,6 +286,7 @@ + @@ -736,6 +737,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 12f02fc49fb..b699f995b37 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -34,6 +34,7 @@ #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/retry_throttle.h" +#include "src/core/ext/filters/message_size/message_size_filter.h" #include "src/core/lib/surface/channel_init.h" static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { @@ -51,6 +52,7 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { void grpc_service_config_register_parsers() { grpc_core::internal::ClientChannelServiceConfigParser::Register(); + grpc_core::MessageSizeParser::Register(); } void grpc_client_channel_init(void) { diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.cc b/src/core/ext/filters/client_channel/health/health_check_parser.cc new file mode 100644 index 00000000000..b9ccc3cb3b6 --- /dev/null +++ b/src/core/ext/filters/client_channel/health/health_check_parser.cc @@ -0,0 +1,75 @@ +/* + * + * 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 "src/core/ext/filters/client_channel/health/health_check_parser.h" + +namespace grpc_core { +namespace { +size_t health_check_parser_index; +} + +UniquePtr HealthCheckParser::ParseGlobalParams( + const grpc_json* json, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + const char* service_name = nullptr; + for (grpc_json* field = json->child; field != nullptr; field = field->next) { + if (field->key == nullptr) { + continue; + } + if (strcmp(field->key, "healthCheckConfig") == 0) { + if (field->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:healthCheckConfig error:should be of type object"); + return nullptr; + } + for (grpc_json* sub_field = field->child; sub_field != nullptr; + sub_field = sub_field->next) { + if (sub_field->key == nullptr) { + continue; + } + if (strcmp(sub_field->key, "serviceName") == 0) { + if (service_name != nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:healthCheckConfig field:serviceName error:Duplicate " + "entry"); + return nullptr; + } + if (sub_field->type != GRPC_JSON_STRING) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:healthCheckConfig error:should be of type string"); + return nullptr; + } + service_name = sub_field->value; + } + } + } + } + return UniquePtr( + New(service_name)); +} + +void HealthCheckParser::Register() { + health_check_parser_index = ServiceConfig::RegisterParser( + UniquePtr(New())); +} + +size_t HealthCheckParser::ParserIndex() { return health_check_parser_index; } + +} // namespace grpc_core \ No newline at end of file diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.h b/src/core/ext/filters/client_channel/health/health_check_parser.h new file mode 100644 index 00000000000..8ab1ba9425d --- /dev/null +++ b/src/core/ext/filters/client_channel/health/health_check_parser.h @@ -0,0 +1,49 @@ +/* + * + * 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_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H + +#include + +#include "src/core/ext/filters/client_channel/service_config.h" + +namespace grpc_core { + +class HealthCheckParsedObject : public ServiceConfigParsedObject { + public: + HealthCheckParsedObject(const char* service_name) + : service_name_(service_name) {} + + const char* service_name() const { return service_name_; } + + private: + const char* service_name_; +}; + +class HealthCheckParser : public ServiceConfigParser { + public: + UniquePtr ParseGlobalParams( + const grpc_json* json, grpc_error** error) override; + + static void Register(); + + static size_t ParserIndex(); +}; +} // namespace grpc_core +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H */ diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 5ec6c6de346..28e482bf2b7 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -128,9 +128,8 @@ class ServiceConfig : public RefCounted { const SliceHashTable>& table, const grpc_slice& path); /// Retrieves the parsed global service config object at index \a index. - ServiceConfigParsedObject* GetParsedGlobalServiceConfigObject(int index) { - GPR_DEBUG_ASSERT( - index < static_cast(parsed_global_service_config_objects_.size())); + ServiceConfigParsedObject* GetParsedGlobalServiceConfigObject(size_t index) { + GPR_DEBUG_ASSERT(index < parsed_global_service_config_objects_.size()); return parsed_global_service_config_objects_[index].get(); } 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 4d120c0eb76..26c78241b70 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -32,6 +32,7 @@ #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/call.h" #include "src/core/lib/surface/channel_init.h" typedef struct { @@ -39,8 +40,99 @@ typedef struct { int max_recv_size; } message_size_limits; -namespace grpc_core { namespace { +size_t message_size_parser_index; + +// Consumes all the errors in the vector and forms a referencing error from +// them. If the vector is empty, return GRPC_ERROR_NONE. +template +grpc_error* CreateErrorFromVector( + const char* desc, grpc_core::InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; +} +} // namespace + +namespace grpc_core { + +class MessageSizeParsedObject : public ServiceConfigParsedObject { + public: + MessageSizeParsedObject(int max_send_size, int max_recv_size) { + limits_.max_send_size = max_send_size; + limits_.max_recv_size = max_recv_size; + } + + const message_size_limits& limits() const { return limits_; } + + private: + message_size_limits limits_; +}; + +UniquePtr MessageSizeParser::ParsePerMethodParams( + const grpc_json* json, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + int max_request_message_bytes = -1; + int max_response_message_bytes = -1; + InlinedVector error_list; + for (grpc_json* field = json->child; field != nullptr; field = field->next) { + if (field->key == nullptr) continue; + if (strcmp(field->key, "maxRequestMessageBytes") == 0) { + if (max_request_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:Duplicate entry")); + continue; + } + if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be of type number")); + continue; + } + max_request_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_request_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be non-negative")); + } + } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { + if (max_response_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:Duplicate entry")); + continue; + } + if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be of type number")); + } + max_response_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_response_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be non-negative")); + } + } + } + if (!error_list.empty()) { + *error = CreateErrorFromVector("Message size parser", &error_list); + return nullptr; + } + return UniquePtr(New( + max_request_message_bytes, max_response_message_bytes)); +} + +void MessageSizeParser::Register() { + gpr_log(GPR_ERROR, "registered"); + message_size_parser_index = ServiceConfig::RegisterParser( + UniquePtr(New())); +} + +size_t MessageSizeParser::ParserIndex() { return message_size_parser_index; } class MessageSizeLimits : public RefCounted { public: @@ -60,34 +152,6 @@ class MessageSizeLimits : public RefCounted { message_size_limits limits_; }; - -RefCountedPtr MessageSizeLimits::CreateFromJson( - const grpc_json* json) { - int max_request_message_bytes = -1; - int max_response_message_bytes = -1; - for (grpc_json* field = json->child; field != nullptr; field = field->next) { - if (field->key == nullptr) continue; - if (strcmp(field->key, "maxRequestMessageBytes") == 0) { - if (max_request_message_bytes >= 0) return nullptr; // Duplicate. - if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { - return nullptr; - } - max_request_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_request_message_bytes == -1) return nullptr; - } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { - if (max_response_message_bytes >= 0) return nullptr; // Duplicate. - if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { - return nullptr; - } - max_response_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_response_message_bytes == -1) return nullptr; - } - } - return MakeRefCounted(max_request_message_bytes, - max_response_message_bytes); -} - -} // namespace } // namespace grpc_core static void recv_message_ready(void* user_data, grpc_error* error); @@ -97,6 +161,7 @@ namespace { struct channel_data { message_size_limits limits; + grpc_core::RefCountedPtr svc_cfg; // Maps path names to refcounted_message_size_limits structs. grpc_core::RefCountedPtr>> @@ -116,21 +181,32 @@ struct call_data { // Note: Per-method config is only available on the client, so we // apply the max request size to the send limit and the max response // size to the receive limit. - if (chand.method_limit_table != nullptr) { - grpc_core::RefCountedPtr limits = - grpc_core::ServiceConfig::MethodConfigTableLookup( - *chand.method_limit_table, args.path); - if (limits != nullptr) { - if (limits->limits().max_send_size >= 0 && - (limits->limits().max_send_size < this->limits.max_send_size || - this->limits.max_send_size < 0)) { - this->limits.max_send_size = limits->limits().max_send_size; - } - if (limits->limits().max_recv_size >= 0 && - (limits->limits().max_recv_size < this->limits.max_recv_size || - this->limits.max_recv_size < 0)) { - this->limits.max_recv_size = limits->limits().max_recv_size; - } + const grpc_core::MessageSizeParsedObject* limits = nullptr; + const grpc_core::ServiceConfig::ServiceConfigObjectsVector* objs_vector = + static_cast< + const grpc_core::ServiceConfig::ServiceConfigObjectsVector*>( + args.context[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value); + if (objs_vector != nullptr) { + limits = static_cast( + (*objs_vector)[message_size_parser_index].get()); + } else if (chand.svc_cfg != nullptr) { + objs_vector = + chand.svc_cfg->GetMethodServiceConfigObjectsVector(args.path); + if (objs_vector != nullptr) { + limits = static_cast( + (*objs_vector)[message_size_parser_index].get()); + } + } + if (limits != nullptr) { + if (limits->limits().max_send_size >= 0 && + (limits->limits().max_send_size < this->limits.max_send_size || + this->limits.max_send_size < 0)) { + this->limits.max_send_size = limits->limits().max_send_size; + } + if (limits->limits().max_recv_size >= 0 && + (limits->limits().max_recv_size < this->limits.max_recv_size || + this->limits.max_recv_size < 0)) { + this->limits.max_recv_size = limits->limits().max_recv_size; } } } @@ -313,6 +389,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, grpc_channel_element_args* args) { GPR_ASSERT(!args->is_last); channel_data* chand = static_cast(elem->channel_data); + new (chand) channel_data(); chand->limits = get_message_size_limits(args->channel_args); // Get method config table from channel args. const grpc_arg* channel_arg = @@ -320,14 +397,14 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, const char* service_config_str = grpc_channel_arg_get_string(channel_arg); if (service_config_str != nullptr) { grpc_error* service_config_error = GRPC_ERROR_NONE; - grpc_core::RefCountedPtr service_config = - grpc_core::ServiceConfig::Create(service_config_str, - &service_config_error); - GRPC_ERROR_UNREF(service_config_error); - if (service_config != nullptr) { - chand->method_limit_table = service_config->CreateMethodConfigTable( - grpc_core::MessageSizeLimits::CreateFromJson); + auto svc_cfg = grpc_core::ServiceConfig::Create(service_config_str, + &service_config_error); + if (service_config_error == GRPC_ERROR_NONE) { + chand->svc_cfg = std::move(svc_cfg); + } else { + gpr_log(GPR_ERROR, "%s", grpc_error_string(service_config_error)); } + GRPC_ERROR_UNREF(service_config_error); } return GRPC_ERROR_NONE; } @@ -351,6 +428,15 @@ const grpc_channel_filter grpc_message_size_filter = { grpc_channel_next_get_info, "message_size"}; +// Used for GRPC_CLIENT_SUBCHANNEL +static bool add_message_size_filter(grpc_channel_stack_builder* builder, + void* arg) { + return grpc_channel_stack_builder_prepend_filter( + builder, &grpc_message_size_filter, nullptr, nullptr); +} + +// Used for GRPC_CLIENT_DIRECT_CHANNEL and GRPC_SERVER_CHANNEL. Adds the filter +// only if message size limits or service config is specified. static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder, void* arg) { const grpc_channel_args* channel_args = @@ -362,7 +448,8 @@ static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder, } const grpc_arg* a = grpc_channel_args_find(channel_args, GRPC_ARG_SERVICE_CONFIG); - if (a != nullptr) { + const char* svc_cfg_str = grpc_channel_arg_get_string(a); + if (svc_cfg_str != nullptr) { enable = true; } if (enable) { @@ -376,7 +463,7 @@ static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder, void grpc_message_size_filter_init(void) { grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, - maybe_add_message_size_filter, nullptr); + add_message_size_filter, nullptr); grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_message_size_filter, nullptr); diff --git a/src/core/ext/filters/message_size/message_size_filter.h b/src/core/ext/filters/message_size/message_size_filter.h index f66636e5832..6f0f16ab67c 100644 --- a/src/core/ext/filters/message_size/message_size_filter.h +++ b/src/core/ext/filters/message_size/message_size_filter.h @@ -19,8 +19,21 @@ #include +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/channel/channel_stack.h" extern const grpc_channel_filter grpc_message_size_filter; +namespace grpc_core { +class MessageSizeParser : public ServiceConfigParser { + public: + UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) override; + + static void Register(); + + static size_t ParserIndex(); +}; +} // namespace grpc_core + #endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 21efd682871..59a19be99ea 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -321,6 +321,7 @@ CORE_SOURCE_FILES = [ '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/health/health_check_parser.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', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 1817be44bc3..2fbf8abb54f 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -892,6 +892,8 @@ 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 \ src/core/ext/filters/client_channel/health/health_check_client.h \ +src/core/ext/filters/client_channel/health/health_check_parser.cc \ +src/core/ext/filters/client_channel/health/health_check_parser.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 \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 1782e18eb1d..c2f869d7cbb 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8694,6 +8694,7 @@ "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/health/health_check_parser.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", @@ -8734,6 +8735,8 @@ "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/health/health_check_parser.cc", + "src/core/ext/filters/client_channel/health/health_check_parser.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", From 116ce0fb24ffa5ae471b3dc8bbc942fa24d904a1 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 18 Apr 2019 14:43:48 -0700 Subject: [PATCH 1892/2143] Use health check parser --- .../filters/client_channel/client_channel.cc | 12 +++-- .../client_channel/client_channel_factory.h | 6 ++- .../client_channel/client_channel_plugin.cc | 2 + .../ext/filters/client_channel/lb_policy.cc | 6 +++ .../ext/filters/client_channel/lb_policy.h | 6 ++- .../client_channel/lb_policy/grpclb/grpclb.cc | 11 +++-- .../lb_policy/pick_first/pick_first.cc | 8 ++-- .../lb_policy/round_robin/round_robin.cc | 8 ++-- .../lb_policy/subchannel_list.h | 7 +-- .../client_channel/lb_policy/xds/xds.cc | 10 +++-- .../client_channel/resolver_result_parsing.cc | 5 ++- .../client_channel/resolver_result_parsing.h | 3 ++ .../client_channel/resolving_lb_policy.cc | 20 ++++++--- .../client_channel/resolving_lb_policy.h | 6 ++- .../ext/filters/client_channel/subchannel.cc | 45 ++++--------------- .../ext/filters/client_channel/subchannel.h | 7 ++- .../message_size/message_size_filter.cc | 1 - .../chttp2/client/insecure/channel_create.cc | 6 ++- .../client/secure/secure_channel_create.cc | 6 ++- test/core/util/test_lb_policies.cc | 7 ++- test/cpp/microbenchmarks/bm_call_create.cc | 4 +- 21 files changed, 106 insertions(+), 80 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 262795b025c..f0847000b10 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -438,13 +438,15 @@ class ClientChannelControlHelper "ClientChannelControlHelper"); } - Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + Subchannel* CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) 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 = - chand_->client_channel_factory->CreateSubchannel(new_args); + Subchannel* subchannel = chand_->client_channel_factory->CreateSubchannel( + new_args, health_check); grpc_channel_args_destroy(new_args); return subchannel; } @@ -491,7 +493,8 @@ class ClientChannelControlHelper // result update. static bool process_resolver_result_locked( void* arg, grpc_core::Resolver::Result* result, const char** lb_policy_name, - const grpc_core::ParsedLoadBalancingConfig** lb_policy_config) { + const grpc_core::ParsedLoadBalancingConfig** lb_policy_config, + const grpc_core::HealthCheckParsedObject** health_check) { channel_data* chand = static_cast(arg); ProcessedResolverResult resolver_result(result, chand->enable_retries); const char* service_config_json = resolver_result.service_config_json(); @@ -517,6 +520,7 @@ 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(); + *health_check = resolver_result.health_check(); return service_config_changed; } 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 21f78a833df..43a696da983 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.h +++ b/src/core/ext/filters/client_channel/client_channel_factory.h @@ -23,6 +23,7 @@ #include +#include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/lib/gprpp/abstract.h" @@ -33,8 +34,9 @@ class ClientChannelFactory { virtual ~ClientChannelFactory() = default; // Creates a subchannel with the specified args. - virtual Subchannel* CreateSubchannel(const grpc_channel_args* args) - GRPC_ABSTRACT; + virtual Subchannel* CreateSubchannel( + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check) GRPC_ABSTRACT; // Creates a channel for the specified target with the specified args. virtual grpc_channel* CreateChannel( 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 b699f995b37..92b1fed61d1 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -27,6 +27,7 @@ #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/health/health_check_parser.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" @@ -53,6 +54,7 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { void grpc_service_config_register_parsers() { grpc_core::internal::ClientChannelServiceConfigParser::Register(); grpc_core::MessageSizeParser::Register(); + grpc_core::HealthCheckParser::Register(); } void grpc_client_channel_init(void) { diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 1cd5e6c9e98..cd6397a4ae2 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -117,12 +117,15 @@ grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( LoadBalancingPolicy::UpdateArgs::UpdateArgs(const UpdateArgs& other) { addresses = other.addresses; config = other.config; + health_check = other.health_check; args = grpc_channel_args_copy(other.args); } LoadBalancingPolicy::UpdateArgs::UpdateArgs(UpdateArgs&& other) { addresses = std::move(other.addresses); config = std::move(other.config); + health_check = other.health_check; + other.health_check = nullptr; // TODO(roth): Use std::move() once channel args is converted to C++. args = other.args; other.args = nullptr; @@ -132,6 +135,7 @@ LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=( const UpdateArgs& other) { addresses = other.addresses; config = other.config; + health_check = other.health_check; grpc_channel_args_destroy(args); args = grpc_channel_args_copy(other.args); return *this; @@ -141,6 +145,8 @@ LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=( UpdateArgs&& other) { addresses = std::move(other.addresses); config = std::move(other.config); + health_check = other.health_check; + other.health_check = nullptr; // TODO(roth): Use std::move() once channel args is converted to C++. grpc_channel_args_destroy(args); args = other.args; diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 30e6dca1cd9..a8857e9b6a7 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -175,8 +175,9 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual ~ChannelControlHelper() = default; /// Creates a new subchannel with the specified channel args. - virtual Subchannel* CreateSubchannel(const grpc_channel_args& args) - GRPC_ABSTRACT; + virtual Subchannel* CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) 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 @@ -201,6 +202,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { struct UpdateArgs { ServerAddressList addresses; const ParsedLoadBalancingConfig* config = nullptr; + const HealthCheckParsedObject* health_check = nullptr; const grpc_channel_args* args = nullptr; // TODO(roth): Remove everything below once channel args is 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 f8922bf7bcc..8e2dbfa8d5d 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,7 +295,9 @@ class GrpcLb : public LoadBalancingPolicy { explicit Helper(RefCountedPtr parent) : parent_(std::move(parent)) {} - Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + Subchannel* CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) override; grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, grpc_error* state_error, @@ -620,12 +622,15 @@ bool GrpcLb::Helper::CalledByCurrentChild() const { return child_ == parent_->child_policy_.get(); } -Subchannel* GrpcLb::Helper::CreateSubchannel(const grpc_channel_args& args) { +Subchannel* GrpcLb::Helper::CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) { if (parent_->shutting_down_ || (!CalledByPendingChild() && !CalledByCurrentChild())) { return nullptr; } - return parent_->channel_control_helper()->CreateSubchannel(args); + return parent_->channel_control_helper()->CreateSubchannel(args, + health_check); } grpc_channel* GrpcLb::Helper::CreateChannel(const char* target, 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 4b7b00237cb..ff58cee645e 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 @@ -88,9 +88,10 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - const grpc_channel_args& args) + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) : SubchannelList(policy, tracer, addresses, combiner, - policy->channel_control_helper(), args) { + policy->channel_control_helper(), args, health_check) { // 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. @@ -254,7 +255,8 @@ void PickFirst::UpdateLocked(UpdateArgs args) { grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args.args, &new_arg, 1); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args); + this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args, + args.health_check); 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 721844d689e..7284410ce09 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 @@ -109,9 +109,10 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelList(RoundRobin* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - const grpc_channel_args& args) + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) : SubchannelList(policy, tracer, addresses, combiner, - policy->channel_control_helper(), args) { + policy->channel_control_helper(), args, health_check) { // 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. @@ -488,7 +489,8 @@ void RoundRobin::UpdateLocked(UpdateArgs args) { } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args); + this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args, + args.health_check); 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 4fde90c2584..58aebb22909 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 @@ -233,7 +233,8 @@ class SubchannelList : public InternallyRefCounted { SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, LoadBalancingPolicy::ChannelControlHelper* helper, - const grpc_channel_args& args); + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check); virtual ~SubchannelList(); @@ -487,7 +488,7 @@ SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, LoadBalancingPolicy::ChannelControlHelper* helper, - const grpc_channel_args& args) + const grpc_channel_args& args, const HealthCheckParsedObject* health_check) : InternallyRefCounted(tracer), policy_(policy), tracer_(tracer), @@ -522,7 +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 = helper->CreateSubchannel(*new_args); + Subchannel* subchannel = helper->CreateSubchannel(*new_args, health_check); 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 73b5de8f15a..804417c177e 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 @@ -328,7 +328,9 @@ class XdsLb : public LoadBalancingPolicy { explicit Helper(RefCountedPtr entry) : entry_(std::move(entry)) {} - Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + Subchannel* CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) override; grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, grpc_error* state_error, @@ -1576,12 +1578,14 @@ bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByCurrentChild() const { } Subchannel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateSubchannel( - const grpc_channel_args& args) { + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) { if (entry_->parent_->shutting_down_ || (!CalledByPendingChild() && !CalledByCurrentChild())) { return nullptr; } - return entry_->parent_->channel_control_helper()->CreateSubchannel(args); + return entry_->parent_->channel_control_helper()->CreateSubchannel( + args, health_check); } grpc_channel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateChannel( 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 69aeaf9eb85..60b6288296a 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -108,6 +108,9 @@ grpc_error* CreateErrorFromVector(const char* desc, void ProcessedResolverResult::ProcessServiceConfig( const Resolver::Result& resolver_result, bool parse_retry) { if (service_config_ == nullptr) return; + health_check_ = static_cast( + service_config_->GetParsedGlobalServiceConfigObject( + HealthCheckParser::ParserIndex())); service_config_json_ = service_config_->service_config_json(); auto* parsed_object = static_cast( service_config_->GetParsedGlobalServiceConfigObject( @@ -559,12 +562,10 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, } *error = CreateErrorFromVector("Client channel parser", &error_list); if (*error == GRPC_ERROR_NONE) { - gpr_log(GPR_ERROR, "hura"); return UniquePtr( New(timeout, wait_for_ready, std::move(retry_policy))); } - gpr_log(GPR_ERROR, "hura"); return nullptr; } 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 41b5ccdcb65..6e73c43a779 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -140,6 +140,8 @@ class ProcessedResolverResult { const ParsedLoadBalancingConfig* lb_policy_config() { return lb_policy_config_; } + + const HealthCheckParsedObject* health_check() { return health_check_; } RefCountedPtr service_config() { return service_config_; } private: @@ -169,6 +171,7 @@ class ProcessedResolverResult { // Retry throttle data. char* server_name_ = nullptr; RefCountedPtr retry_throttle_data_; + const HealthCheckParsedObject* health_check_ = nullptr; }; } // namespace internal 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 2d0f72f8520..3eaae1cd39a 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -106,10 +106,13 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper RefCountedPtr parent) : parent_(std::move(parent)) {} - Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + Subchannel* CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) override { if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. if (!CalledByCurrentChild() && !CalledByPendingChild()) return nullptr; - return parent_->channel_control_helper()->CreateSubchannel(args); + return parent_->channel_control_helper()->CreateSubchannel(args, + health_check); } grpc_channel* CreateChannel(const char* target, @@ -343,7 +346,8 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, const ParsedLoadBalancingConfig* lb_policy_config, Resolver::Result result, - TraceStringVector* trace_strings) { + TraceStringVector* trace_strings, + const HealthCheckParsedObject* health_check) { // 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 @@ -436,6 +440,7 @@ void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( UpdateArgs update_args; update_args.addresses = std::move(result.addresses); update_args.config = std::move(lb_policy_config); + update_args.health_check = health_check; // TODO(roth): Once channel args is converted to C++, use std::move() here. update_args.args = result.args; result.args = nullptr; @@ -540,11 +545,12 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( // Process the resolver result. const char* lb_policy_name = nullptr; const ParsedLoadBalancingConfig* lb_policy_config = nullptr; + const HealthCheckParsedObject* health_check = nullptr; 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); + service_config_changed = process_resolver_result_( + process_resolver_result_user_data_, &result, &lb_policy_name, + &lb_policy_config, &health_check); } else { lb_policy_name = child_policy_name_.get(); lb_policy_config = child_lb_config_; @@ -552,7 +558,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( GPR_ASSERT(lb_policy_name != nullptr); // Create or update LB policy, as needed. CreateOrUpdateLbPolicyLocked(lb_policy_name, lb_policy_config, - std::move(result), &trace_strings); + std::move(result), &trace_strings, health_check); // Add channel trace event. if (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 d36ae627066..afbee184690 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -67,7 +67,8 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // Returns true if the service config has changed since the last result. typedef bool (*ProcessResolverResultCallback)( void* user_data, Resolver::Result* result, const char** lb_policy_name, - const ParsedLoadBalancingConfig** lb_policy_config); + const ParsedLoadBalancingConfig** lb_policy_config, + const HealthCheckParsedObject** health_check); // If error is set when this returns, then construction failed, and // the caller may not use the new object. ResolvingLoadBalancingPolicy( @@ -106,7 +107,8 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { void CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, const ParsedLoadBalancingConfig* lb_policy_config, - Resolver::Result result, TraceStringVector* trace_strings); + Resolver::Result result, TraceStringVector* trace_strings, + const HealthCheckParsedObject* health_check); OrphanablePtr CreateLbPolicyLocked( const char* lb_policy_name, const grpc_channel_args& args, TraceStringVector* trace_strings); diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index b38bd4b701e..a0831c117aa 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -532,29 +532,11 @@ BackOff::Options ParseArgsForBackoffValues( .set_max_backoff(max_backoff_ms); } -struct HealthCheckParams { - UniquePtr service_name; - - static void Parse(const grpc_json* field, HealthCheckParams* params) { - if (strcmp(field->key, "healthCheckConfig") == 0) { - if (field->type != GRPC_JSON_OBJECT) return; - for (grpc_json* sub_field = field->child; sub_field != nullptr; - sub_field = sub_field->next) { - if (sub_field->key == nullptr) return; - if (strcmp(sub_field->key, "serviceName") == 0) { - if (params->service_name != nullptr) return; // Duplicate. - if (sub_field->type != GRPC_JSON_STRING) return; - params->service_name.reset(gpr_strdup(sub_field->value)); - } - } - } - } -}; - } // namespace Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, - const grpc_channel_args* args) + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check) : key_(key), connector_(connector), backoff_(ParseArgsForBackoffValues(args, &min_connect_timeout_ms_)) { @@ -586,20 +568,10 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, "subchannel"); grpc_connectivity_state_init(&state_and_health_tracker_, GRPC_CHANNEL_IDLE, "subchannel"); - // 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)); - if (service_config_json != nullptr) { - grpc_error* service_config_error = GRPC_ERROR_NONE; - RefCountedPtr service_config = - ServiceConfig::Create(service_config_json, &service_config_error); - // service_config_error is currently unused. - GRPC_ERROR_UNREF(service_config_error); - if (service_config != nullptr) { - HealthCheckParams params; - service_config->ParseGlobalParams(HealthCheckParams::Parse, ¶ms); - health_check_service_name_ = std::move(params.service_name); - } + + if (health_check != nullptr) { + health_check_service_name_ = + UniquePtr(gpr_strdup(health_check->service_name())); } const grpc_arg* arg = grpc_channel_args_find(args_, GRPC_ARG_ENABLE_CHANNELZ); const bool channelz_enabled = @@ -635,7 +607,8 @@ Subchannel::~Subchannel() { } Subchannel* Subchannel::Create(grpc_connector* connector, - const grpc_channel_args* args) { + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check) { SubchannelKey* key = New(args); SubchannelPoolInterface* subchannel_pool = SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs(args); @@ -645,7 +618,7 @@ Subchannel* Subchannel::Create(grpc_connector* connector, Delete(key); return c; } - c = New(key, connector, args); + c = New(key, connector, args, health_check); // 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 diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 83b57dd7ff3..05bbf4585a3 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/health/health_check_parser.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" @@ -178,12 +179,14 @@ class Subchannel { public: // The ctor and dtor are not intended to use directly. Subchannel(SubchannelKey* key, grpc_connector* connector, - const grpc_channel_args* args); + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check); ~Subchannel(); // Creates a subchannel given \a connector and \a args. static Subchannel* Create(grpc_connector* connector, - const grpc_channel_args* args); + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check); // Strong and weak refcounting. Subchannel* Ref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); 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 26c78241b70..73579457065 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -127,7 +127,6 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( } void MessageSizeParser::Register() { - gpr_log(GPR_ERROR, "registered"); message_size_parser_index = ServiceConfig::RegisterParser( UniquePtr(New())); } 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 0d61abd2a01..ca5a7458e8d 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -37,11 +37,13 @@ namespace grpc_core { class Chttp2InsecureClientChannelFactory : public ClientChannelFactory { public: - Subchannel* CreateSubchannel(const grpc_channel_args* args) override { + Subchannel* CreateSubchannel( + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check) 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); + Subchannel* s = Subchannel::Create(connector, new_args, health_check); 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 bc38ff25c79..c10d1903dd4 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 @@ -44,7 +44,9 @@ namespace grpc_core { class Chttp2SecureClientChannelFactory : public ClientChannelFactory { public: - Subchannel* CreateSubchannel(const grpc_channel_args* args) override { + Subchannel* CreateSubchannel( + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check) override { grpc_channel_args* new_args = GetSecureNamingChannelArgs(args); if (new_args == nullptr) { gpr_log(GPR_ERROR, @@ -52,7 +54,7 @@ class Chttp2SecureClientChannelFactory : public ClientChannelFactory { return nullptr; } grpc_connector* connector = grpc_chttp2_connector_create(); - Subchannel* s = Subchannel::Create(connector, new_args); + Subchannel* s = Subchannel::Create(connector, new_args, health_check); grpc_connector_unref(connector); grpc_channel_args_destroy(new_args); return s; diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 05e25eb08bc..42dd9b38960 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -141,8 +141,11 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy 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); + Subchannel* CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) override { + return parent_->channel_control_helper()->CreateSubchannel(args, + health_check); } grpc_channel* CreateChannel(const char* target, diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index a11b55eb90c..b9a4324a2d3 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -30,6 +30,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/deadline/deadline_filter.h" #include "src/core/ext/filters/http/client/http_client_filter.h" #include "src/core/ext/filters/http/message_compress/message_compress_filter.h" @@ -321,7 +322,8 @@ static void DoNothing(void* arg, grpc_error* error) {} class FakeClientChannelFactory : public grpc_core::ClientChannelFactory { public: grpc_core::Subchannel* CreateSubchannel( - const grpc_channel_args* args) override { + const grpc_channel_args* args, + const grpc_core::HealthCheckParsedObject* health_check) override { return nullptr; } grpc_channel* CreateChannel(const char* target, From 576828696ad6d9be4d36de4802ad5998eec4b92a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 18 Apr 2019 19:51:12 -0700 Subject: [PATCH 1893/2143] Add parsing tests --- .../ext/filters/client_channel/lb_policy.cc | 41 +- .../ext/filters/client_channel/lb_policy.h | 1 + .../client_channel/lb_policy/grpclb/grpclb.cc | 2 +- .../client_channel/lb_policy/xds/xds.cc | 4 +- .../client_channel/lb_policy_registry.cc | 10 +- .../client_channel/lb_policy_registry.h | 2 +- .../client_channel/resolver_result_parsing.cc | 29 +- .../filters/client_channel/service_config.cc | 22 +- .../message_size/message_size_filter.cc | 91 +-- .../message_size/message_size_filter.h | 19 + .../client_channel/service_config_test.cc | 659 +++++++++++++++++- 11 files changed, 748 insertions(+), 132 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index cd6397a4ae2..19142e3f3b7 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -63,41 +63,51 @@ void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg, } grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( - const grpc_json* lb_config_array, grpc_error** error) { + const grpc_json* lb_config_array, const char* field_name, + grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + char* error_msg; if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig error:type should be array"); + gpr_asprintf(&error_msg, "field:%s error:type should be array", field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); 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) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig error:child entry should be of type " - "object"); + gpr_asprintf(&error_msg, + "field:%s error:child entry should be of type object", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); 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) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig error:child entry should be of type " - "object"); + gpr_asprintf(&error_msg, + "field:%s error:child entry should be of type object", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); return nullptr; } if (policy != nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig error:oneOf violation"); + gpr_asprintf(&error_msg, "field:%s error:oneOf violation", field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); return nullptr; } // Violate "oneof" type. policy = field; } if (policy == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig error:no policy found in child entry"); + gpr_asprintf(&error_msg, "field:%s error:no policy found in child entry", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); return nullptr; } // If we support this policy, then select it. @@ -105,8 +115,9 @@ grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( return policy; } } - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig error:No known policy"); + gpr_asprintf(&error_msg, "field:%s error:No known policy", field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); return nullptr; } diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index a8857e9b6a7..a0479b51de3 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -276,6 +276,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// 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, + const char* field_name, grpc_error** error); // A picker that returns PICK_QUEUE for all picks. 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 8e2dbfa8d5d..9c82a1bbbe6 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 @@ -1860,7 +1860,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, &parse_error); + field, "childPolicy", &parse_error); if (parse_error != GRPC_ERROR_NONE) { error_list.push_back(parse_error); } 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 804417c177e..e9b86405d93 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 @@ -1728,7 +1728,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, &parse_error); + field, "childPolicy", &parse_error); if (child_policy == nullptr) { GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); error_list.push_back(parse_error); @@ -1740,7 +1740,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { } grpc_error* parse_error = GRPC_ERROR_NONE; fallback_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, &parse_error); + field, "fallbackPolicy", &parse_error); if (fallback_policy == nullptr) { GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); error_list.push_back(parse_error); 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 e22a0a793de..f4cc115eefc 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -101,11 +101,12 @@ bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) { UniquePtr LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, + const char* field_name, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); GPR_ASSERT(g_state != nullptr); const grpc_json* policy = - LoadBalancingPolicy::ParseLoadBalancingConfig(json, error); + LoadBalancingPolicy::ParseLoadBalancingConfig(json, field_name, error); if (policy == nullptr) { return nullptr; } else { @@ -114,8 +115,11 @@ LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, LoadBalancingPolicyFactory* factory = g_state->GetLoadBalancingPolicyFactory(policy->key); if (factory == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig entry:Factory not found to create policy"); + char* msg; + gpr_asprintf(&msg, "field:%s error:Factory not found to create policy", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); return nullptr; } // Parse load balancing config via factory. 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 af85e511fbb..8ac845c59f1 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -53,7 +53,7 @@ class LoadBalancingPolicyRegistry { static bool LoadBalancingPolicyExists(const char* name); static UniquePtr ParseLoadBalancingConfig( - const grpc_json* json, grpc_error** error); + const grpc_json* json, const char* field_name, grpc_error** error); }; } // namespace grpc_core 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 60b6288296a..54b90cd4039 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -61,23 +61,6 @@ ProcessedResolverResult::ProcessedResolverResult( // Error is currently unused. GRPC_ERROR_UNREF(error); } - } 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); @@ -380,8 +363,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, } else { grpc_error* parse_error = GRPC_ERROR_NONE; parsed_lb_config = - LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(field, - &parse_error); + LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, "loadBalancingConfig", &parse_error); if (parsed_lb_config == nullptr) { error_list.push_back(parse_error); } @@ -398,7 +381,11 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, } else if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( field->value)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingPolicy error:Unrecognized lb policy")); + "field:loadBalancingPolicy error:Unknown lb policy")); + } else if (strcmp(field->value, "xds_experimental") == 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:xds not supported with this " + "field. Please use loadBalancingConfig")); } else { lb_policy_name = field->value; } @@ -535,7 +522,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, wait_for_ready.set(false); } else { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:waitForReady error:Type should be a true/false")); + "field:waitForReady error:Type should be true/false")); } } else if (strcmp(field->key, "timeout") == 0) { if (timeout > 0) { diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index 06a413a89af..9a246785820 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -37,7 +37,7 @@ namespace { typedef InlinedVector, ServiceConfig::kNumPreallocatedParsers> ServiceConfigParserList; -ServiceConfigParserList* registered_parsers; +ServiceConfigParserList* g_registered_parsers; // Consumes all the errors in the vector and forms a referencing error from // them. If the vector is empty, return GRPC_ERROR_NONE. @@ -107,10 +107,10 @@ grpc_error* ServiceConfig::ParseGlobalParams(const grpc_json* json_tree) { GPR_DEBUG_ASSERT(json_tree_->type == GRPC_JSON_OBJECT); GPR_DEBUG_ASSERT(json_tree_->key == nullptr); InlinedVector error_list; - for (size_t i = 0; i < registered_parsers->size(); i++) { + for (size_t i = 0; i < g_registered_parsers->size(); i++) { grpc_error* parser_error = GRPC_ERROR_NONE; auto parsed_obj = - (*registered_parsers)[i]->ParseGlobalParams(json_tree, &parser_error); + (*g_registered_parsers)[i]->ParseGlobalParams(json_tree, &parser_error); if (parser_error != GRPC_ERROR_NONE) { error_list.push_back(parser_error); } @@ -125,10 +125,10 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( size_t* idx) { auto objs_vector = MakeUnique(); InlinedVector error_list; - for (size_t i = 0; i < registered_parsers->size(); i++) { + for (size_t i = 0; i < g_registered_parsers->size(); i++) { grpc_error* parser_error = GRPC_ERROR_NONE; auto parsed_obj = - (*registered_parsers)[i]->ParsePerMethodParams(json, &parser_error); + (*g_registered_parsers)[i]->ParsePerMethodParams(json, &parser_error); if (parser_error != GRPC_ERROR_NONE) { error_list.push_back(parser_error); } @@ -332,18 +332,18 @@ ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) { } size_t ServiceConfig::RegisterParser(UniquePtr parser) { - registered_parsers->push_back(std::move(parser)); - return registered_parsers->size() - 1; + g_registered_parsers->push_back(std::move(parser)); + return g_registered_parsers->size() - 1; } void ServiceConfig::Init() { - GPR_ASSERT(registered_parsers == nullptr); - registered_parsers = New(); + GPR_ASSERT(g_registered_parsers == nullptr); + g_registered_parsers = New(); } void ServiceConfig::Shutdown() { - Delete(registered_parsers); - registered_parsers = nullptr; + Delete(g_registered_parsers); + g_registered_parsers = nullptr; } } // namespace grpc_core 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 73579457065..146cb5d23f3 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -35,11 +35,6 @@ #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel_init.h" -typedef struct { - int max_send_size; - int max_recv_size; -} message_size_limits; - namespace { size_t message_size_parser_index; @@ -64,19 +59,6 @@ grpc_error* CreateErrorFromVector( namespace grpc_core { -class MessageSizeParsedObject : public ServiceConfigParsedObject { - public: - MessageSizeParsedObject(int max_send_size, int max_recv_size) { - limits_.max_send_size = max_send_size; - limits_.max_recv_size = max_recv_size; - } - - const message_size_limits& limits() const { return limits_; } - - private: - message_size_limits limits_; -}; - UniquePtr MessageSizeParser::ParsePerMethodParams( const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); @@ -89,32 +71,32 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( if (max_request_message_bytes >= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxRequestMessageBytes error:Duplicate entry")); - continue; - } - if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { + } else if (field->type != GRPC_JSON_STRING && + field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxRequestMessageBytes error:should be of type number")); - continue; - } - max_request_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_request_message_bytes == -1) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:should be non-negative")); + } else { + max_request_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_request_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be non-negative")); + } } } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { + gpr_log(GPR_ERROR, "bla"); if (max_response_message_bytes >= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:Duplicate entry")); - continue; - } - if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { + } else if (field->type != GRPC_JSON_STRING && + field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:should be of type number")); - } - max_response_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_response_message_bytes == -1) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:should be non-negative")); + } else { + max_response_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_response_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be non-negative")); + } } } } @@ -132,25 +114,6 @@ void MessageSizeParser::Register() { } size_t MessageSizeParser::ParserIndex() { return message_size_parser_index; } - -class MessageSizeLimits : public RefCounted { - public: - static RefCountedPtr CreateFromJson(const grpc_json* json); - - const message_size_limits& limits() const { return limits_; } - - private: - // So New() can call our private ctor. - template - friend T* grpc_core::New(Args&&... args); - - MessageSizeLimits(int max_send_size, int max_recv_size) { - limits_.max_send_size = max_send_size; - limits_.max_recv_size = max_recv_size; - } - - message_size_limits limits_; -}; } // namespace grpc_core static void recv_message_ready(void* user_data, grpc_error* error); @@ -159,12 +122,8 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error); namespace { struct channel_data { - message_size_limits limits; + grpc_core::MessageSizeParsedObject::message_size_limits limits; grpc_core::RefCountedPtr svc_cfg; - // Maps path names to refcounted_message_size_limits structs. - grpc_core::RefCountedPtr>> - method_limit_table; }; struct call_data { @@ -213,7 +172,7 @@ struct call_data { ~call_data() { GRPC_ERROR_UNREF(error); } grpc_call_combiner* call_combiner; - message_size_limits limits; + grpc_core::MessageSizeParsedObject::message_size_limits limits; // Receive closures are chained: we inject this closure as the // recv_message_ready up-call on transport_stream_op, and remember to // call our next_recv_message_ready member after handling it. @@ -359,9 +318,9 @@ static int default_size(const grpc_channel_args* args, return without_minimal_stack; } -message_size_limits get_message_size_limits( +grpc_core::MessageSizeParsedObject::message_size_limits get_message_size_limits( const grpc_channel_args* channel_args) { - message_size_limits lim; + grpc_core::MessageSizeParsedObject::message_size_limits lim; lim.max_send_size = default_size(channel_args, GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH); lim.max_recv_size = @@ -409,10 +368,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, } // Destructor for channel_data. -static void destroy_channel_elem(grpc_channel_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - chand->method_limit_table.reset(); -} +static void destroy_channel_elem(grpc_channel_element* elem) {} const grpc_channel_filter grpc_message_size_filter = { start_transport_stream_op_batch, @@ -441,7 +397,8 @@ static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder, const grpc_channel_args* channel_args = grpc_channel_stack_builder_get_channel_arguments(builder); bool enable = false; - message_size_limits lim = get_message_size_limits(channel_args); + grpc_core::MessageSizeParsedObject::message_size_limits lim = + get_message_size_limits(channel_args); if (lim.max_send_size != -1 || lim.max_recv_size != -1) { enable = true; } diff --git a/src/core/ext/filters/message_size/message_size_filter.h b/src/core/ext/filters/message_size/message_size_filter.h index 6f0f16ab67c..a4aa79f70ac 100644 --- a/src/core/ext/filters/message_size/message_size_filter.h +++ b/src/core/ext/filters/message_size/message_size_filter.h @@ -25,6 +25,25 @@ extern const grpc_channel_filter grpc_message_size_filter; namespace grpc_core { + +class MessageSizeParsedObject : public ServiceConfigParsedObject { + public: + struct message_size_limits { + int max_send_size; + int max_recv_size; + }; + + MessageSizeParsedObject(int max_send_size, int max_recv_size) { + limits_.max_send_size = max_send_size; + limits_.max_recv_size = max_recv_size; + } + + const message_size_limits& limits() const { return limits_; } + + private: + message_size_limits limits_; +}; + class MessageSizeParser : public ServiceConfigParser { public: UniquePtr ParsePerMethodParams( diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index 229944435b0..be86400e32d 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -21,8 +21,10 @@ #include #include +#include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/service_config.h" +#include "src/core/ext/filters/message_size/message_size_filter.h" #include "src/core/lib/gpr/string.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -153,8 +155,10 @@ TEST_F(ServiceConfigTest, ErrorCheck1) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); ASSERT_TRUE(error != GRPC_ERROR_NONE); - EXPECT_TRUE(strstr(grpc_error_string(error), - "failed to parse JSON for service config") != nullptr); + std::regex e(std::string("failed to parse JSON for service config")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); GRPC_ERROR_UNREF(error); } @@ -171,7 +175,15 @@ TEST_F(ServiceConfigTest, ErrorNoNames) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); ASSERT_TRUE(error != GRPC_ERROR_NONE); - EXPECT_TRUE(strstr(grpc_error_string(error), "No names found") != nullptr); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(No names " + "found)(.*)(methodConfig)(.*)(referenced_errors)(.*)(No " + "names specified)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); GRPC_ERROR_UNREF(error); } @@ -182,7 +194,15 @@ TEST_F(ServiceConfigTest, ErrorNoNamesWithMultipleMethodConfigs) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); ASSERT_TRUE(error != GRPC_ERROR_NONE); - EXPECT_TRUE(strstr(grpc_error_string(error), "No names found") != nullptr); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(No names " + "found)(.*)(methodConfig)(.*)(referenced_errors)(.*)(No " + "names specified)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); GRPC_ERROR_UNREF(error); } @@ -225,7 +245,7 @@ TEST_F(ServiceConfigTest, Parser1ErrorInvalidType) { ASSERT_TRUE(error != GRPC_ERROR_NONE); std::regex e(std::string("(Service config parsing " "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)()(.*)") + + "Params)(.*)(referenced_errors)(.*)") + TestParser1::InvalidTypeErrorMessage()); std::smatch match; std::string s(grpc_error_string(error)); @@ -241,7 +261,7 @@ TEST_F(ServiceConfigTest, Parser1ErrorInvalidValue) { ASSERT_TRUE(error != GRPC_ERROR_NONE); std::regex e(std::string("(Service config parsing " "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)()(.*)") + + "Params)(.*)(referenced_errors)(.*)") + TestParser1::InvalidValueErrorMessage()); std::smatch match; std::string s(grpc_error_string(error)); @@ -273,7 +293,7 @@ TEST_F(ServiceConfigTest, Parser2ErrorInvalidType) { gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); std::regex e(std::string("(Service config parsing " "error)(.*)(referenced_errors\":\\[)(.*)(Method " - "Params)(.*)(referenced_errors)()(.*)(methodConfig)(" + "Params)(.*)(referenced_errors)(.*)(methodConfig)(" ".*)(referenced_errors)(.*)") + TestParser2::InvalidTypeErrorMessage()); std::smatch match; @@ -367,7 +387,7 @@ class ClientChannelParserTest : public ::testing::Test { } }; -TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig1) { +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigPickFirst) { const char* test_json = "{\"loadBalancingConfig\": [{\"pick_first\":{}}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); @@ -379,7 +399,7 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig1) { EXPECT_TRUE(strcmp(lb_config->name(), "pick_first") == 0); } -TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig2) { +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigRoundRobin) { const char* test_json = "{\"loadBalancingConfig\": [{\"round_robin\":{}}, {}]}"; grpc_error* error = GRPC_ERROR_NONE; @@ -392,13 +412,12 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig2) { EXPECT_TRUE(strcmp(lb_config->name(), "round_robin") == 0); } -TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig3) { +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigGrpclb) { const char* test_json = "{\"loadBalancingConfig\": " "[{\"grpclb\":{\"childPolicy\":[{\"pick_first\":{}}]}}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); ASSERT_TRUE(error == GRPC_ERROR_NONE); const auto* parsed_object = static_cast( @@ -407,6 +426,624 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig3) { EXPECT_TRUE(strcmp(lb_config->name(), "grpclb") == 0); } +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigXds) { + const char* test_json = + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"xds_experimental\":{ \"balancerName\": \"fake:///lb\" } }\n" + " ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto* lb_config = parsed_object->parsed_lb_config(); + EXPECT_TRUE(strcmp(lb_config->name(), "xds_experimental") == 0); +} + +TEST_F(ClientChannelParserTest, UnknownLoadBalancingConfig) { + const char* test_json = "{\"loadBalancingConfig\": [{\"unknown\":{}}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:" + "loadBalancingConfig error:No known policy)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidgRPCLbLoadBalancingConfig) { + const char* test_json = + "{\"loadBalancingConfig\": " + "[{\"grpclb\":{\"childPolicy\":[{\"unknown\":{}}]}}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(GrpcLb " + "Parser)(.*)(referenced_errors)(.*)(field:childPolicy " + "error:No known policy)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InalidLoadBalancingConfigXds) { + const char* test_json = + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"xds_experimental\":{} }\n" + " ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(Xds " + "Parser)(.*)(referenced_errors)(.*)(field:balancerName " + "error:not found)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicy) { + const char* test_json = "{\"loadBalancingPolicy\":\"pick_first\"}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto* lb_policy = parsed_object->parsed_deprecated_lb_policy(); + ASSERT_TRUE(lb_policy != nullptr); + EXPECT_TRUE(strcmp(lb_policy, "pick_first") == 0); +} + +TEST_F(ClientChannelParserTest, UnknownLoadBalancingPolicy) { + const char* test_json = "{\"loadBalancingPolicy\":\"unknown\"}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:" + "loadBalancingPolicy error:Unknown lb policy)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) { + const char* test_json = "{\"loadBalancingPolicy\":\"xds_experimental\"}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:" + "loadBalancingPolicy error:xds not supported)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, ValidRetryThrottling) { + const char* test_json = + "{\n" + " \"retryThrottling\": {\n" + " \"maxTokens\": 2,\n" + " \"tokenRatio\": 1.0\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto retryThrottling = parsed_object->retry_throttling(); + ASSERT_TRUE(retryThrottling.has_value()); + EXPECT_EQ(retryThrottling.value().max_milli_tokens, 2000); + EXPECT_EQ(retryThrottling.value().milli_token_ratio, 1000); +} + +TEST_F(ClientChannelParserTest, RetryThrottlingMissingFields) { + const char* test_json = + "{\n" + " \"retryThrottling\": {\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " + "field:maxTokens error:Not found)(.*)(field:retryThrottling " + "field:tokenRatio error:Not found)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidRetryThrottlingNegativeMaxTokens) { + const char* test_json = + "{\n" + " \"retryThrottling\": {\n" + " \"maxTokens\": -2,\n" + " \"tokenRatio\": 1.0\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " + "field:maxTokens error:should be greater than zero)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidRetryThrottlingInvalidTokenRatio) { + const char* test_json = + "{\n" + " \"retryThrottling\": {\n" + " \"maxTokens\": 2,\n" + " \"tokenRatio\": -1\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " + "field:tokenRatio error:Failed parsing)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, ValidTimeout) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"timeout\": \"5s\"\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + EXPECT_TRUE(vector_ptr != nullptr); + auto parsed_object = ((*vector_ptr)[0]).get(); + EXPECT_EQ((static_cast( + parsed_object)) + ->timeout(), + 5000); +} + +TEST_F(ClientChannelParserTest, InvalidTimeout) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"timeout\": \"5sec\"\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" + "referenced_errors)(.*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(field:timeout " + "error:Failed parsing)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, ValidWaitForReady) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"waitForReady\": true\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + EXPECT_TRUE(vector_ptr != nullptr); + auto parsed_object = ((*vector_ptr)[0]).get(); + EXPECT_TRUE( + (static_cast( + parsed_object)) + ->wait_for_ready() + .has_value()); + EXPECT_TRUE( + (static_cast( + parsed_object)) + ->wait_for_ready() + .value()); +} + +TEST_F(ClientChannelParserTest, InvalidWaitForReady) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"waitForReady\": \"true\"\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" + "referenced_errors)(.*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(field:waitForReady " + "error:Type should be true/false)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, ValidRetryPolicy) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + EXPECT_TRUE(vector_ptr != nullptr); + const auto* parsed_object = + static_cast( + ((*vector_ptr)[0]).get()); + EXPECT_TRUE(parsed_object->retry_policy() != nullptr); + EXPECT_EQ(parsed_object->retry_policy()->max_attempts, 3); + EXPECT_EQ(parsed_object->retry_policy()->initial_backoff, 1000); + EXPECT_EQ(parsed_object->retry_policy()->max_backoff, 120000); + EXPECT_EQ(parsed_object->retry_policy()->backoff_multiplier, 1.6f); + EXPECT_TRUE(parsed_object->retry_policy()->retryable_status_codes.Contains( + GRPC_STATUS_ABORTED)); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxAttempts) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:maxAttempts error:should be atleast 2)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyInitialBackoff) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1sec\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:initialBackoff error:Failed to parse)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxBackoff) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120sec\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:maxBackoff error:failed to parse)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyBackoffMultiplier) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120sec\",\n" + " \"backoffMultiplier\": \"1.6\",\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:backoffMultiplier error:should be of type number)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120sec\",\n" + " \"backoffMultiplier\": \"1.6\",\n" + " \"retryableStatusCodes\": []\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:retryableStatusCodes error:should be non-empty)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +class MessageSizeParserTest : public ::testing::Test { + protected: + void SetUp() override { + ServiceConfig::Shutdown(); + ServiceConfig::Init(); + EXPECT_TRUE(ServiceConfig::RegisterParser(UniquePtr( + New())) == 0); + } +}; + +TEST_F(MessageSizeParserTest, Valid) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"maxRequestMessageBytes\": 1024,\n" + " \"maxResponseMessageBytes\": 1024\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + EXPECT_TRUE(vector_ptr != nullptr); + auto parsed_object = + static_cast(((*vector_ptr)[0]).get()); + ASSERT_TRUE(parsed_object != nullptr); + EXPECT_EQ(parsed_object->limits().max_send_size, 1024); + EXPECT_EQ(parsed_object->limits().max_recv_size, 1024); +} + +TEST_F(MessageSizeParserTest, InvalidMaxRequestMessageBytes) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"maxRequestMessageBytes\": -1024\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" + "referenced_errors)(.*)(Message size " + "parser)(.*)(referenced_errors)(.*)(field:" + "maxRequestMessageBytes error:should be non-negative)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"maxResponseMessageBytes\": {}\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" + "referenced_errors)(.*)(Message size " + "parser)(.*)(referenced_errors)(.*)(field:" + "maxResponseMessageBytes error:should be of type number)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} } // namespace testing } // namespace grpc_core From a09d705dbf6fe345016d3c411864cab05e22e4a1 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 19 Apr 2019 08:02:54 -0700 Subject: [PATCH 1894/2143] Convert client_channel call_data to C++. --- .../filters/client_channel/client_channel.cc | 2279 +++++++++-------- 1 file changed, 1157 insertions(+), 1122 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 0304a265a09..14eac3bed29 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -71,8 +71,6 @@ using grpc_core::internal::ClientChannelMethodParamsTable; using grpc_core::internal::ProcessedResolverResult; using grpc_core::internal::ServerRetryThrottleData; -using grpc_core::LoadBalancingPolicy; - // // Client channel filter // @@ -85,16 +83,21 @@ using grpc_core::LoadBalancingPolicy; // any even moderately compelling reason to do so. #define RETRY_BACKOFF_JITTER 0.2 -grpc_core::TraceFlag grpc_client_channel_call_trace(false, - "client_channel_call"); -grpc_core::TraceFlag grpc_client_channel_routing_trace( - false, "client_channel_routing"); - -// Forward declarations. -static void start_pick_locked(void* arg, grpc_error* error); -static void maybe_apply_service_config_to_call_locked(grpc_call_element* elem); +// Max number of batches that can be pending on a call at any given +// time. This includes one batch for each of the following ops: +// recv_initial_metadata +// send_initial_metadata +// recv_message +// send_message +// recv_trailing_metadata +// send_trailing_metadata +#define MAX_PENDING_BATCHES 6 namespace grpc_core { + +TraceFlag grpc_client_channel_call_trace(false, "client_channel_call"); +TraceFlag grpc_client_channel_routing_trace(false, "client_channel_routing"); + namespace { // @@ -278,6 +281,411 @@ class ChannelData { UniquePtr info_service_config_json_; }; +// +// CallData definition +// + +class CallData { + public: + static grpc_error* Init(grpc_call_element* elem, + const grpc_call_element_args* args); + static void Destroy(grpc_call_element* elem, + const grpc_call_final_info* final_info, + grpc_closure* then_schedule_closure); + static void StartTransportStreamOpBatch( + grpc_call_element* elem, grpc_transport_stream_op_batch* batch); + static void SetPollent(grpc_call_element* elem, grpc_polling_entity* pollent); + + RefCountedPtr subchannel_call() { return subchannel_call_; } + + // Invoked by channel for queued picks once resolver results are available. + void MaybeApplyServiceConfigToCallLocked(grpc_call_element* elem); + + // Invoked by channel for queued picks when the picker is updated. + static void StartPickLocked(void* arg, grpc_error* error); + + private: + class QueuedPickCanceller; + + // State used for starting a retryable batch on a subchannel call. + // This provides its own grpc_transport_stream_op_batch and other data + // structures needed to populate the ops in the batch. + // We allocate one struct on the arena for each attempt at starting a + // batch on a given subchannel call. + struct SubchannelCallBatchData { + // Creates a SubchannelCallBatchData object on the call's arena with the + // specified refcount. If set_on_complete is true, the batch's + // on_complete callback will be set to point to on_complete(); + // otherwise, the batch's on_complete callback will be null. + static SubchannelCallBatchData* Create(grpc_call_element* elem, + int refcount, bool set_on_complete); + + void Unref() { + if (gpr_unref(&refs)) Destroy(); + } + + SubchannelCallBatchData(grpc_call_element* elem, CallData* calld, + int refcount, bool set_on_complete); + // All dtor code must be added in `Destroy()`. This is because we may + // call closures in `SubchannelCallBatchData` after they are unrefed by + // `Unref()`, and msan would complain about accessing this class + // after calling dtor. As a result we cannot call the `dtor` in `Unref()`. + // TODO(soheil): We should try to call the dtor in `Unref()`. + ~SubchannelCallBatchData() { Destroy(); } + void Destroy(); + + gpr_refcount refs; + grpc_call_element* elem; + RefCountedPtr subchannel_call; + // The batch to use in the subchannel call. + // Its payload field points to SubchannelCallRetryState::batch_payload. + grpc_transport_stream_op_batch batch; + // For intercepting on_complete. + grpc_closure on_complete; + }; + + // Retry state associated with a subchannel call. + // Stored in the parent_data of the subchannel call object. + struct SubchannelCallRetryState { + explicit SubchannelCallRetryState(grpc_call_context_element* context) + : batch_payload(context), + started_send_initial_metadata(false), + completed_send_initial_metadata(false), + started_send_trailing_metadata(false), + completed_send_trailing_metadata(false), + started_recv_initial_metadata(false), + completed_recv_initial_metadata(false), + started_recv_trailing_metadata(false), + completed_recv_trailing_metadata(false), + retry_dispatched(false) {} + + // SubchannelCallBatchData.batch.payload points to this. + grpc_transport_stream_op_batch_payload batch_payload; + // For send_initial_metadata. + // Note that we need to make a copy of the initial metadata for each + // subchannel call instead of just referring to the copy in call_data, + // because filters in the subchannel stack will probably add entries, + // so we need to start in a pristine state for each attempt of the call. + grpc_linked_mdelem* send_initial_metadata_storage; + grpc_metadata_batch send_initial_metadata; + // For send_message. + // TODO(roth): Restructure this to eliminate use of ManualConstructor. + ManualConstructor send_message; + // For send_trailing_metadata. + grpc_linked_mdelem* send_trailing_metadata_storage; + grpc_metadata_batch send_trailing_metadata; + // For intercepting recv_initial_metadata. + grpc_metadata_batch recv_initial_metadata; + grpc_closure recv_initial_metadata_ready; + bool trailing_metadata_available = false; + // For intercepting recv_message. + grpc_closure recv_message_ready; + OrphanablePtr recv_message; + // For intercepting recv_trailing_metadata. + grpc_metadata_batch recv_trailing_metadata; + grpc_transport_stream_stats collect_stats; + grpc_closure recv_trailing_metadata_ready; + // These fields indicate which ops have been started and completed on + // this subchannel call. + size_t started_send_message_count = 0; + size_t completed_send_message_count = 0; + size_t started_recv_message_count = 0; + size_t completed_recv_message_count = 0; + bool started_send_initial_metadata : 1; + bool completed_send_initial_metadata : 1; + bool started_send_trailing_metadata : 1; + bool completed_send_trailing_metadata : 1; + bool started_recv_initial_metadata : 1; + bool completed_recv_initial_metadata : 1; + bool started_recv_trailing_metadata : 1; + bool completed_recv_trailing_metadata : 1; + // State for callback processing. + SubchannelCallBatchData* recv_initial_metadata_ready_deferred_batch = + nullptr; + grpc_error* recv_initial_metadata_error = GRPC_ERROR_NONE; + SubchannelCallBatchData* recv_message_ready_deferred_batch = nullptr; + grpc_error* recv_message_error = GRPC_ERROR_NONE; + SubchannelCallBatchData* recv_trailing_metadata_internal_batch = nullptr; + // NOTE: Do not move this next to the metadata bitfields above. That would + // save space but will also result in a data race because compiler + // will generate a 2 byte store which overwrites the meta-data + // fields upon setting this field. + bool retry_dispatched : 1; + }; + + // Pending batches stored in call data. + struct PendingBatch { + // The pending batch. If nullptr, this slot is empty. + grpc_transport_stream_op_batch* batch; + // Indicates whether payload for send ops has been cached in CallData. + bool send_ops_cached; + }; + + CallData(grpc_call_element* elem, const ChannelData& chand, + const grpc_call_element_args& args); + ~CallData(); + + // Caches data for send ops so that it can be retried later, if not + // already cached. + void MaybeCacheSendOpsForBatch(PendingBatch* pending); + void FreeCachedSendInitialMetadata(ChannelData* chand); + // Frees cached send_message at index idx. + void FreeCachedSendMessage(ChannelData* chand, size_t idx); + void FreeCachedSendTrailingMetadata(ChannelData* chand); + // Frees cached send ops that have already been completed after + // committing the call. + void FreeCachedSendOpDataAfterCommit(grpc_call_element* elem, + SubchannelCallRetryState* retry_state); + // Frees cached send ops that were completed by the completed batch in + // batch_data. Used when batches are completed after the call is committed. + void FreeCachedSendOpDataForCompletedBatch( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state); + + static void MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy( + const LoadBalancingPolicy::PickArgs& pick, + grpc_transport_stream_op_batch* batch); + + // Returns the index into pending_batches_ to be used for batch. + static size_t GetBatchIndex(grpc_transport_stream_op_batch* batch); + void PendingBatchesAdd(grpc_call_element* elem, + grpc_transport_stream_op_batch* batch); + void PendingBatchClear(PendingBatch* pending); + void MaybeClearPendingBatch(grpc_call_element* elem, PendingBatch* pending); + static void FailPendingBatchInCallCombiner(void* arg, grpc_error* error); + // A predicate type and some useful implementations for PendingBatchesFail(). + typedef bool (*YieldCallCombinerPredicate)( + const CallCombinerClosureList& closures); + static bool YieldCallCombiner(const CallCombinerClosureList& closures) { + return true; + } + static bool NoYieldCallCombiner(const CallCombinerClosureList& closures) { + return false; + } + static bool YieldCallCombinerIfPendingBatchesFound( + const CallCombinerClosureList& closures) { + return closures.size() > 0; + } + // Fails all pending batches. + // If yield_call_combiner_predicate returns true, assumes responsibility for + // yielding the call combiner. + void PendingBatchesFail( + grpc_call_element* elem, grpc_error* error, + YieldCallCombinerPredicate yield_call_combiner_predicate); + static void ResumePendingBatchInCallCombiner(void* arg, grpc_error* ignored); + // Resumes all pending batches on subchannel_call_. + void PendingBatchesResume(grpc_call_element* elem); + // Returns a pointer to the first pending batch for which predicate(batch) + // returns true, or null if not found. + template + PendingBatch* PendingBatchFind(grpc_call_element* elem, + const char* log_message, Predicate predicate); + + // Commits the call so that no further retry attempts will be performed. + void RetryCommit(grpc_call_element* elem, + SubchannelCallRetryState* retry_state); + // Starts a retry after appropriate back-off. + void DoRetry(grpc_call_element* elem, SubchannelCallRetryState* retry_state, + grpc_millis server_pushback_ms); + // Returns true if the call is being retried. + bool MaybeRetry(grpc_call_element* elem, SubchannelCallBatchData* batch_data, + grpc_status_code status, grpc_mdelem* server_pushback_md); + + // Invokes recv_initial_metadata_ready for a subchannel batch. + static void InvokeRecvInitialMetadataCallback(void* arg, grpc_error* error); + // Intercepts recv_initial_metadata_ready callback for retries. + // Commits the call and returns the initial metadata up the stack. + static void RecvInitialMetadataReady(void* arg, grpc_error* error); + + // Invokes recv_message_ready for a subchannel batch. + static void InvokeRecvMessageCallback(void* arg, grpc_error* error); + // Intercepts recv_message_ready callback for retries. + // Commits the call and returns the message up the stack. + static void RecvMessageReady(void* arg, grpc_error* error); + + // Sets *status and *server_pushback_md based on md_batch and error. + // Only sets *server_pushback_md if server_pushback_md != nullptr. + void GetCallStatus(grpc_call_element* elem, grpc_metadata_batch* md_batch, + grpc_error* error, grpc_status_code* status, + grpc_mdelem** server_pushback_md); + // Adds recv_trailing_metadata_ready closure to closures. + void AddClosureForRecvTrailingMetadataReady( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + grpc_error* error, CallCombinerClosureList* closures); + // Adds any necessary closures for deferred recv_initial_metadata and + // recv_message callbacks to closures. + static void AddClosuresForDeferredRecvCallbacks( + SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state, CallCombinerClosureList* closures); + // Returns true if any op in the batch was not yet started. + // Only looks at send ops, since recv ops are always started immediately. + bool PendingBatchIsUnstarted(PendingBatch* pending, + SubchannelCallRetryState* retry_state); + // For any pending batch containing an op that has not yet been started, + // adds the pending batch's completion closures to closures. + void AddClosuresToFailUnstartedPendingBatches( + grpc_call_element* elem, SubchannelCallRetryState* retry_state, + grpc_error* error, CallCombinerClosureList* closures); + // Runs necessary closures upon completion of a call attempt. + void RunClosuresForCompletedCall(SubchannelCallBatchData* batch_data, + grpc_error* error); + // Intercepts recv_trailing_metadata_ready callback for retries. + // Commits the call and returns the trailing metadata up the stack. + static void RecvTrailingMetadataReady(void* arg, grpc_error* error); + + // Adds the on_complete closure for the pending batch completed in + // batch_data to closures. + void AddClosuresForCompletedPendingBatch( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state, grpc_error* error, + CallCombinerClosureList* closures); + + // If there are any cached ops to replay or pending ops to start on the + // subchannel call, adds a closure to closures to invoke + // StartRetriableSubchannelBatches(). + void AddClosuresForReplayOrPendingSendOps( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state, CallCombinerClosureList* closures); + + // Callback used to intercept on_complete from subchannel calls. + // Called only when retries are enabled. + static void OnComplete(void* arg, grpc_error* error); + + static void StartBatchInCallCombiner(void* arg, grpc_error* ignored); + // Adds a closure to closures that will execute batch in the call combiner. + void AddClosureForSubchannelBatch(grpc_call_element* elem, + grpc_transport_stream_op_batch* batch, + CallCombinerClosureList* closures); + // Adds retriable send_initial_metadata op to batch_data. + void AddRetriableSendInitialMetadataOp(SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data); + // Adds retriable send_message op to batch_data. + void AddRetriableSendMessageOp(grpc_call_element* elem, + SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data); + // Adds retriable send_trailing_metadata op to batch_data. + void AddRetriableSendTrailingMetadataOp(SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data); + // Adds retriable recv_initial_metadata op to batch_data. + void AddRetriableRecvInitialMetadataOp(SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data); + // Adds retriable recv_message op to batch_data. + void AddRetriableRecvMessageOp(SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data); + // Adds retriable recv_trailing_metadata op to batch_data. + void AddRetriableRecvTrailingMetadataOp(SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data); + // Helper function used to start a recv_trailing_metadata batch. This + // is used in the case where a recv_initial_metadata or recv_message + // op fails in a way that we know the call is over but when the application + // has not yet started its own recv_trailing_metadata op. + void StartInternalRecvTrailingMetadata(grpc_call_element* elem); + // If there are any cached send ops that need to be replayed on the + // current subchannel call, creates and returns a new subchannel batch + // to replay those ops. Otherwise, returns nullptr. + SubchannelCallBatchData* MaybeCreateSubchannelBatchForReplay( + grpc_call_element* elem, SubchannelCallRetryState* retry_state); + // Adds subchannel batches for pending batches to closures. + void AddSubchannelBatchesForPendingBatches( + grpc_call_element* elem, SubchannelCallRetryState* retry_state, + CallCombinerClosureList* closures); + // Constructs and starts whatever subchannel batches are needed on the + // subchannel call. + static void StartRetriableSubchannelBatches(void* arg, grpc_error* ignored); + + void CreateSubchannelCall(grpc_call_element* elem); + // Invoked when a pick is completed, on both success or failure. + static void PickDone(void* arg, grpc_error* error); + // Removes the call from the channel's list of queued picks. + void RemoveCallFromQueuedPicksLocked(grpc_call_element* elem); + // Adds the call to the channel's list of queued picks. + void AddCallToQueuedPicksLocked(grpc_call_element* elem); + // Applies service config to the call. Must be invoked once we know + // that the resolver has returned results to the channel. + void ApplyServiceConfigToCallLocked(grpc_call_element* elem); + + // State for handling deadlines. + // The code in deadline_filter.c requires this to be the first field. + // TODO(roth): This is slightly sub-optimal in that grpc_deadline_state + // and this struct both independently store pointers to the call stack + // and call combiner. If/when we have time, find a way to avoid this + // without breaking the grpc_deadline_state abstraction. + grpc_deadline_state deadline_state_; + + grpc_slice path_; // Request path. + gpr_timespec call_start_time_; + grpc_millis deadline_; + gpr_arena* arena_; + grpc_call_stack* owning_call_; + grpc_call_combiner* call_combiner_; + grpc_call_context_element* call_context_; + + RefCountedPtr retry_throttle_data_; + RefCountedPtr method_params_; + + RefCountedPtr subchannel_call_; + + // Set when we get a cancel_stream op. + grpc_error* cancel_error_ = GRPC_ERROR_NONE; + + ChannelData::QueuedPick pick_; + bool pick_queued_ = false; + bool service_config_applied_ = false; + QueuedPickCanceller* pick_canceller_ = nullptr; + grpc_closure pick_closure_; + + grpc_polling_entity* pollent_ = nullptr; + + // Batches are added to this list when received from above. + // They are removed when we are done handling the batch (i.e., when + // either we have invoked all of the batch's callbacks or we have + // passed the batch down to the subchannel call and are not + // intercepting any of its callbacks). + PendingBatch pending_batches_[MAX_PENDING_BATCHES] = {}; + bool pending_send_initial_metadata_ : 1; + bool pending_send_message_ : 1; + bool pending_send_trailing_metadata_ : 1; + + // Retry state. + bool enable_retries_ : 1; + bool retry_committed_ : 1; + bool last_attempt_got_server_pushback_ : 1; + int num_attempts_completed_ = 0; + size_t bytes_buffered_for_retry_ = 0; + // TODO(roth): Restructure this to eliminate use of ManualConstructor. + ManualConstructor retry_backoff_; + grpc_timer retry_timer_; + + // The number of pending retriable subchannel batches containing send ops. + // We hold a ref to the call stack while this is non-zero, since replay + // batches may not complete until after all callbacks have been returned + // to the surface, and we need to make sure that the call is not destroyed + // until all of these batches have completed. + // Note that we actually only need to track replay batches, but it's + // easier to track all batches with send ops. + int num_pending_retriable_subchannel_send_batches_ = 0; + + // Cached data for retrying send ops. + // send_initial_metadata + bool seen_send_initial_metadata_ = false; + grpc_linked_mdelem* send_initial_metadata_storage_ = nullptr; + grpc_metadata_batch send_initial_metadata_; + uint32_t send_initial_metadata_flags_; + gpr_atm* peer_string_; + // send_message + // When we get a send_message op, we replace the original byte stream + // with a CachingByteStream that caches the slices to a local buffer for + // use in retries. + // Note: We inline the cache for the first 3 send_message ops and use + // dynamic allocation after that. This number was essentially picked + // at random; it could be changed in the future to tune performance. + InlinedVector send_messages_; + // send_trailing_metadata + bool seen_send_trailing_metadata_ = false; + grpc_linked_mdelem* send_trailing_metadata_storage_ = nullptr; + grpc_metadata_batch send_trailing_metadata_; +}; + // // ChannelData::ConnectivityStateAndPickerSetter // @@ -333,7 +741,7 @@ class ChannelData::ConnectivityStateAndPickerSetter { // Re-process queued picks. for (QueuedPick* pick = self->chand_->queued_picks_; pick != nullptr; pick = pick->next) { - start_pick_locked(pick->elem, GRPC_ERROR_NONE); + CallData::StartPickLocked(pick->elem, GRPC_ERROR_NONE); } // Clean up. GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack_, @@ -378,7 +786,8 @@ class ChannelData::ServiceConfigSetter { // 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); + CallData* calld = static_cast(pick->elem->call_data); + calld->MaybeApplyServiceConfigToCallLocked(pick->elem); } // Clean up. GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack_, @@ -877,24 +1286,9 @@ grpc_connectivity_state ChannelData::CheckConnectivityState( return out; } -} // namespace -} // namespace grpc_core - -/************************************************************************* - * PER-CALL FUNCTIONS - */ - -using grpc_core::ChannelData; - -// Max number of batches that can be pending on a call at any given -// time. This includes one batch for each of the following ops: -// recv_initial_metadata -// send_initial_metadata -// recv_message -// send_message -// recv_trailing_metadata -// send_trailing_metadata -#define MAX_PENDING_BATCHES 6 +// +// CallData implementation +// // Retry support: // @@ -931,362 +1325,247 @@ using grpc_core::ChannelData; // (census filter is on top of this one) // - add census stats for retries -namespace grpc_core { -namespace { -class QueuedPickCanceller; -} // namespace -} // namespace grpc_core +CallData::CallData(grpc_call_element* elem, const ChannelData& chand, + const grpc_call_element_args& args) + : deadline_state_(elem, args.call_stack, args.call_combiner, + GPR_LIKELY(chand.deadline_checking_enabled()) + ? args.deadline + : GRPC_MILLIS_INF_FUTURE), + path_(grpc_slice_ref_internal(args.path)), + call_start_time_(args.start_time), + deadline_(args.deadline), + 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), + enable_retries_(chand.enable_retries()), + retry_committed_(false), + last_attempt_got_server_pushback_(false) {} -namespace { - -struct call_data; - -// State used for starting a retryable batch on a subchannel call. -// This provides its own grpc_transport_stream_op_batch and other data -// structures needed to populate the ops in the batch. -// We allocate one struct on the arena for each attempt at starting a -// batch on a given subchannel call. -struct subchannel_batch_data { - subchannel_batch_data(grpc_call_element* elem, call_data* calld, int refcount, - bool set_on_complete); - // All dtor code must be added in `destroy`. This is because we may - // call closures in `subchannel_batch_data` after they are unrefed by - // `batch_data_unref`, and msan would complain about accessing this class - // after calling dtor. As a result we cannot call the `dtor` in - // `batch_data_unref`. - // TODO(soheil): We should try to call the dtor in `batch_data_unref`. - ~subchannel_batch_data() { destroy(); } - void destroy(); - - gpr_refcount refs; - grpc_call_element* elem; - 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; - // For intercepting on_complete. - grpc_closure on_complete; -}; - -// Retry state associated with a subchannel call. -// Stored in the parent_data of the subchannel call object. -struct subchannel_call_retry_state { - explicit subchannel_call_retry_state(grpc_call_context_element* context) - : batch_payload(context), - started_send_initial_metadata(false), - completed_send_initial_metadata(false), - started_send_trailing_metadata(false), - completed_send_trailing_metadata(false), - started_recv_initial_metadata(false), - completed_recv_initial_metadata(false), - started_recv_trailing_metadata(false), - completed_recv_trailing_metadata(false), - retry_dispatched(false) {} - - // subchannel_batch_data.batch.payload points to this. - grpc_transport_stream_op_batch_payload batch_payload; - // For send_initial_metadata. - // Note that we need to make a copy of the initial metadata for each - // subchannel call instead of just referring to the copy in call_data, - // because filters in the subchannel stack will probably add entries, - // so we need to start in a pristine state for each attempt of the call. - grpc_linked_mdelem* send_initial_metadata_storage; - grpc_metadata_batch send_initial_metadata; - // For send_message. - grpc_core::ManualConstructor - send_message; - // For send_trailing_metadata. - grpc_linked_mdelem* send_trailing_metadata_storage; - grpc_metadata_batch send_trailing_metadata; - // For intercepting recv_initial_metadata. - grpc_metadata_batch recv_initial_metadata; - grpc_closure recv_initial_metadata_ready; - bool trailing_metadata_available = false; - // For intercepting recv_message. - grpc_closure recv_message_ready; - grpc_core::OrphanablePtr recv_message; - // For intercepting recv_trailing_metadata. - grpc_metadata_batch recv_trailing_metadata; - grpc_transport_stream_stats collect_stats; - grpc_closure recv_trailing_metadata_ready; - // These fields indicate which ops have been started and completed on - // this subchannel call. - size_t started_send_message_count = 0; - size_t completed_send_message_count = 0; - size_t started_recv_message_count = 0; - size_t completed_recv_message_count = 0; - bool started_send_initial_metadata : 1; - bool completed_send_initial_metadata : 1; - bool started_send_trailing_metadata : 1; - bool completed_send_trailing_metadata : 1; - bool started_recv_initial_metadata : 1; - bool completed_recv_initial_metadata : 1; - bool started_recv_trailing_metadata : 1; - bool completed_recv_trailing_metadata : 1; - // State for callback processing. - subchannel_batch_data* recv_initial_metadata_ready_deferred_batch = nullptr; - grpc_error* recv_initial_metadata_error = GRPC_ERROR_NONE; - subchannel_batch_data* recv_message_ready_deferred_batch = nullptr; - grpc_error* recv_message_error = GRPC_ERROR_NONE; - subchannel_batch_data* recv_trailing_metadata_internal_batch = nullptr; - // NOTE: Do not move this next to the metadata bitfields above. That would - // save space but will also result in a data race because compiler will - // generate a 2 byte store which overwrites the meta-data fields upon - // setting this field. - bool retry_dispatched : 1; -}; - -// Pending batches stored in call data. -struct pending_batch { - // The pending batch. If nullptr, this slot is empty. - grpc_transport_stream_op_batch* batch; - // Indicates whether payload for send ops has been cached in call data. - bool send_ops_cached; -}; - -/** 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, - and handling cancellation gracefully. */ -struct call_data { - call_data(grpc_call_element* elem, const ChannelData& chand, - const grpc_call_element_args& args) - : deadline_state(elem, args.call_stack, args.call_combiner, - GPR_LIKELY(chand.deadline_checking_enabled()) - ? args.deadline - : GRPC_MILLIS_INF_FUTURE), - path(grpc_slice_ref_internal(args.path)), - call_start_time(args.start_time), - deadline(args.deadline), - 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), - enable_retries(chand.enable_retries()), - retry_committed(false), - last_attempt_got_server_pushback(false) {} - - ~call_data() { - grpc_slice_unref_internal(path); - GRPC_ERROR_UNREF(cancel_error); - for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches); ++i) { - GPR_ASSERT(pending_batches[i].batch == nullptr); - } +CallData::~CallData() { + grpc_slice_unref_internal(path_); + GRPC_ERROR_UNREF(cancel_error_); + // Make sure there are no remaining pending batches. + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + GPR_ASSERT(pending_batches_[i].batch == nullptr); } +} - // State for handling deadlines. - // The code in deadline_filter.c requires this to be the first field. - // TODO(roth): This is slightly sub-optimal in that grpc_deadline_state - // and this struct both independently store pointers to the call stack - // and call combiner. If/when we have time, find a way to avoid this - // without breaking the grpc_deadline_state abstraction. - grpc_deadline_state deadline_state; +grpc_error* CallData::Init(grpc_call_element* elem, + const grpc_call_element_args* args) { + ChannelData* chand = static_cast(elem->channel_data); + new (elem->call_data) CallData(elem, *chand, *args); + return GRPC_ERROR_NONE; +} - grpc_slice path; // Request path. - gpr_timespec call_start_time; - grpc_millis deadline; - gpr_arena* arena; - grpc_call_stack* owning_call; - grpc_call_combiner* call_combiner; - grpc_call_context_element* call_context; +void CallData::Destroy(grpc_call_element* elem, + const grpc_call_final_info* final_info, + grpc_closure* then_schedule_closure) { + CallData* calld = static_cast(elem->call_data); + if (GPR_LIKELY(calld->subchannel_call_ != nullptr)) { + calld->subchannel_call_->SetAfterCallStackDestroy(then_schedule_closure); + then_schedule_closure = nullptr; + } + calld->~CallData(); + GRPC_CLOSURE_SCHED(then_schedule_closure, GRPC_ERROR_NONE); +} - grpc_core::RefCountedPtr retry_throttle_data; - grpc_core::RefCountedPtr method_params; +void CallData::StartTransportStreamOpBatch( + grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { + GPR_TIMER_SCOPE("cc_start_transport_stream_op_batch", 0); + CallData* calld = static_cast(elem->call_data); + ChannelData* chand = static_cast(elem->channel_data); + if (GPR_LIKELY(chand->deadline_checking_enabled())) { + grpc_deadline_state_client_start_transport_stream_op_batch(elem, 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_call_trace.enabled()) { + gpr_log(GPR_INFO, "chand=%p calld=%p: failing batch with error: %s", + chand, calld, grpc_error_string(calld->cancel_error_)); + } + // 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_); + return; + } + // Handle cancellation. + if (GPR_UNLIKELY(batch->cancel_stream)) { + // Stash a copy of cancel_error in our call data, so that we can use + // it for subsequent operations. This ensures that if the call is + // cancelled before any batches are passed down (e.g., if the deadline + // is in the past when the call starts), we can return the right + // error to the caller when the first batch does get passed down. + GRPC_ERROR_UNREF(calld->cancel_error_); + calld->cancel_error_ = + GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error); + 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_)); + } + // If we do not have a subchannel call (i.e., a pick has not yet + // 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? + calld->PendingBatchesFail(elem, GRPC_ERROR_REF(calld->cancel_error_), + NoYieldCallCombiner); + // 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_); + } else { + // Note: This will release the call combiner. + calld->subchannel_call_->StartTransportStreamOpBatch(batch); + } + return; + } + // Add the batch to the pending list. + calld->PendingBatchesAdd(elem, batch); + // Check if we've already gotten a subchannel call. + // Note that once we have completed the pick, we do not need to enter + // the channel combiner, which is more efficient (especially for + // streaming calls). + if (calld->subchannel_call_ != nullptr) { + 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()); + } + calld->PendingBatchesResume(elem); + return; + } + // We do not yet have a subchannel call. + // 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_call_trace.enabled()) { + gpr_log(GPR_INFO, "chand=%p calld=%p: entering client_channel combiner", + chand, calld); + } + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_INIT( + &batch->handler_private.closure, StartPickLocked, elem, + grpc_combiner_scheduler(chand->data_plane_combiner())), + GRPC_ERROR_NONE); + } else { + // For all other batches, release the call combiner. + if (grpc_client_channel_call_trace.enabled()) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: saved batch, yielding call combiner", chand, + calld); + } + GRPC_CALL_COMBINER_STOP(calld->call_combiner_, + "batch does not include send_initial_metadata"); + } +} - grpc_core::RefCountedPtr subchannel_call; - - // Set when we get a cancel_stream op. - grpc_error* cancel_error = GRPC_ERROR_NONE; - - ChannelData::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; - - // Batches are added to this list when received from above. - // They are removed when we are done handling the batch (i.e., when - // either we have invoked all of the batch's callbacks or we have - // passed the batch down to the subchannel call and are not - // intercepting any of its callbacks). - pending_batch pending_batches[MAX_PENDING_BATCHES] = {}; - bool pending_send_initial_metadata : 1; - bool pending_send_message : 1; - bool pending_send_trailing_metadata : 1; - - // Retry state. - bool enable_retries : 1; - bool retry_committed : 1; - bool last_attempt_got_server_pushback : 1; - int num_attempts_completed = 0; - size_t bytes_buffered_for_retry = 0; - grpc_core::ManualConstructor retry_backoff; - grpc_timer retry_timer; - - // The number of pending retriable subchannel batches containing send ops. - // We hold a ref to the call stack while this is non-zero, since replay - // batches may not complete until after all callbacks have been returned - // to the surface, and we need to make sure that the call is not destroyed - // until all of these batches have completed. - // Note that we actually only need to track replay batches, but it's - // easier to track all batches with send ops. - int num_pending_retriable_subchannel_send_batches = 0; - - // Cached data for retrying send ops. - // send_initial_metadata - bool seen_send_initial_metadata = false; - grpc_linked_mdelem* send_initial_metadata_storage = nullptr; - grpc_metadata_batch send_initial_metadata; - uint32_t send_initial_metadata_flags; - gpr_atm* peer_string; - // send_message - // When we get a send_message op, we replace the original byte stream - // with a CachingByteStream that caches the slices to a local buffer for - // use in retries. - // Note: We inline the cache for the first 3 send_message ops and use - // dynamic allocation after that. This number was essentially picked - // at random; it could be changed in the future to tune performance. - grpc_core::InlinedVector send_messages; - // send_trailing_metadata - bool seen_send_trailing_metadata = false; - grpc_linked_mdelem* send_trailing_metadata_storage = nullptr; - grpc_metadata_batch send_trailing_metadata; -}; - -} // namespace - -// Forward declarations. -static void retry_commit(grpc_call_element* elem, - subchannel_call_retry_state* retry_state); -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); +void CallData::SetPollent(grpc_call_element* elem, + grpc_polling_entity* pollent) { + CallData* calld = static_cast(elem->call_data); + calld->pollent_ = pollent; +} // // send op data caching // -// Caches data for send ops so that it can be retried later, if not -// already cached. -static void maybe_cache_send_ops_for_batch(call_data* calld, - pending_batch* pending) { +void CallData::MaybeCacheSendOpsForBatch(PendingBatch* pending) { if (pending->send_ops_cached) return; pending->send_ops_cached = true; grpc_transport_stream_op_batch* batch = pending->batch; // Save a copy of metadata for send_initial_metadata ops. if (batch->send_initial_metadata) { - calld->seen_send_initial_metadata = true; - GPR_ASSERT(calld->send_initial_metadata_storage == nullptr); + seen_send_initial_metadata_ = true; + GPR_ASSERT(send_initial_metadata_storage_ == nullptr); grpc_metadata_batch* send_initial_metadata = batch->payload->send_initial_metadata.send_initial_metadata; - calld->send_initial_metadata_storage = (grpc_linked_mdelem*)gpr_arena_alloc( - calld->arena, - sizeof(grpc_linked_mdelem) * send_initial_metadata->list.count); - grpc_metadata_batch_copy(send_initial_metadata, - &calld->send_initial_metadata, - calld->send_initial_metadata_storage); - calld->send_initial_metadata_flags = + send_initial_metadata_storage_ = (grpc_linked_mdelem*)gpr_arena_alloc( + arena_, sizeof(grpc_linked_mdelem) * send_initial_metadata->list.count); + grpc_metadata_batch_copy(send_initial_metadata, &send_initial_metadata_, + send_initial_metadata_storage_); + send_initial_metadata_flags_ = batch->payload->send_initial_metadata.send_initial_metadata_flags; - calld->peer_string = batch->payload->send_initial_metadata.peer_string; + peer_string_ = batch->payload->send_initial_metadata.peer_string; } // Set up cache for send_message ops. if (batch->send_message) { - grpc_core::ByteStreamCache* cache = - static_cast( - gpr_arena_alloc(calld->arena, sizeof(grpc_core::ByteStreamCache))); - new (cache) grpc_core::ByteStreamCache( - std::move(batch->payload->send_message.send_message)); - calld->send_messages.push_back(cache); + ByteStreamCache* cache = static_cast( + gpr_arena_alloc(arena_, sizeof(ByteStreamCache))); + new (cache) + ByteStreamCache(std::move(batch->payload->send_message.send_message)); + send_messages_.push_back(cache); } // Save metadata batch for send_trailing_metadata ops. if (batch->send_trailing_metadata) { - calld->seen_send_trailing_metadata = true; - GPR_ASSERT(calld->send_trailing_metadata_storage == nullptr); + seen_send_trailing_metadata_ = true; + GPR_ASSERT(send_trailing_metadata_storage_ == nullptr); grpc_metadata_batch* send_trailing_metadata = batch->payload->send_trailing_metadata.send_trailing_metadata; - calld->send_trailing_metadata_storage = - (grpc_linked_mdelem*)gpr_arena_alloc( - calld->arena, - sizeof(grpc_linked_mdelem) * send_trailing_metadata->list.count); - grpc_metadata_batch_copy(send_trailing_metadata, - &calld->send_trailing_metadata, - calld->send_trailing_metadata_storage); + send_trailing_metadata_storage_ = (grpc_linked_mdelem*)gpr_arena_alloc( + arena_, + sizeof(grpc_linked_mdelem) * send_trailing_metadata->list.count); + grpc_metadata_batch_copy(send_trailing_metadata, &send_trailing_metadata_, + send_trailing_metadata_storage_); } } -// Frees cached send_initial_metadata. -static void free_cached_send_initial_metadata(ChannelData* chand, - call_data* calld) { +void CallData::FreeCachedSendInitialMetadata(ChannelData* chand) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: destroying calld->send_initial_metadata", chand, - calld); + this); } - grpc_metadata_batch_destroy(&calld->send_initial_metadata); + grpc_metadata_batch_destroy(&send_initial_metadata_); } -// Frees cached send_message at index idx. -static void free_cached_send_message(ChannelData* chand, call_data* calld, - size_t idx) { +void CallData::FreeCachedSendMessage(ChannelData* chand, size_t idx) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: destroying calld->send_messages[%" PRIuPTR "]", - chand, calld, idx); + chand, this, idx); } - calld->send_messages[idx]->Destroy(); + send_messages_[idx]->Destroy(); } -// Frees cached send_trailing_metadata. -static void free_cached_send_trailing_metadata(ChannelData* chand, - call_data* calld) { +void CallData::FreeCachedSendTrailingMetadata(ChannelData* chand) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: destroying calld->send_trailing_metadata", - chand, calld); + chand, this); } - grpc_metadata_batch_destroy(&calld->send_trailing_metadata); + grpc_metadata_batch_destroy(&send_trailing_metadata_); } -// Frees cached send ops that have already been completed after -// committing the call. -static void free_cached_send_op_data_after_commit( - grpc_call_element* elem, subchannel_call_retry_state* retry_state) { +void CallData::FreeCachedSendOpDataAfterCommit( + grpc_call_element* elem, SubchannelCallRetryState* retry_state) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); if (retry_state->completed_send_initial_metadata) { - free_cached_send_initial_metadata(chand, calld); + FreeCachedSendInitialMetadata(chand); } for (size_t i = 0; i < retry_state->completed_send_message_count; ++i) { - free_cached_send_message(chand, calld, i); + FreeCachedSendMessage(chand, i); } if (retry_state->completed_send_trailing_metadata) { - free_cached_send_trailing_metadata(chand, calld); + FreeCachedSendTrailingMetadata(chand); } } -// Frees cached send ops that were completed by the completed batch in -// batch_data. Used when batches are completed after the call is committed. -static void free_cached_send_op_data_for_completed_batch( - grpc_call_element* elem, subchannel_batch_data* batch_data, - subchannel_call_retry_state* retry_state) { +void CallData::FreeCachedSendOpDataForCompletedBatch( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); if (batch_data->batch.send_initial_metadata) { - free_cached_send_initial_metadata(chand, calld); + FreeCachedSendInitialMetadata(chand); } if (batch_data->batch.send_message) { - free_cached_send_message(chand, calld, - retry_state->completed_send_message_count - 1); + FreeCachedSendMessage(chand, retry_state->completed_send_message_count - 1); } if (batch_data->batch.send_trailing_metadata) { - free_cached_send_trailing_metadata(chand, calld); + FreeCachedSendTrailingMetadata(chand); } } @@ -1294,7 +1573,7 @@ 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( +void CallData::MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy( const LoadBalancingPolicy::PickArgs& pick, grpc_transport_stream_op_batch* batch) { if (pick.recv_trailing_metadata_ready != nullptr) { @@ -1313,8 +1592,7 @@ void maybe_inject_recv_trailing_metadata_ready_for_lb( // pending_batches management // -// Returns the index into calld->pending_batches to be used for batch. -static size_t get_batch_index(grpc_transport_stream_op_batch* batch) { +size_t CallData::GetBatchIndex(grpc_transport_stream_op_batch* batch) { // Note: It is important the send_initial_metadata be the first entry // here, since the code in pick_subchannel_locked() assumes it will be. if (batch->send_initial_metadata) return 0; @@ -1327,204 +1605,81 @@ static size_t get_batch_index(grpc_transport_stream_op_batch* batch) { } // This is called via the call combiner, so access to calld is synchronized. -static void pending_batches_add(grpc_call_element* elem, - grpc_transport_stream_op_batch* batch) { +void CallData::PendingBatchesAdd(grpc_call_element* elem, + grpc_transport_stream_op_batch* batch) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - const size_t idx = get_batch_index(batch); + const size_t idx = GetBatchIndex(batch); if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: adding pending batch at index %" PRIuPTR, chand, - calld, idx); + this, idx); } - pending_batch* pending = &calld->pending_batches[idx]; + PendingBatch* pending = &pending_batches_[idx]; GPR_ASSERT(pending->batch == nullptr); pending->batch = batch; pending->send_ops_cached = false; - if (calld->enable_retries) { + if (enable_retries_) { // Update state in calld about pending batches. // Also check if the batch takes us over the retry buffer limit. // Note: We don't check the size of trailing metadata here, because // gRPC clients do not send trailing metadata. if (batch->send_initial_metadata) { - calld->pending_send_initial_metadata = true; - calld->bytes_buffered_for_retry += grpc_metadata_batch_size( + pending_send_initial_metadata_ = true; + bytes_buffered_for_retry_ += grpc_metadata_batch_size( batch->payload->send_initial_metadata.send_initial_metadata); } if (batch->send_message) { - calld->pending_send_message = true; - calld->bytes_buffered_for_retry += + pending_send_message_ = true; + bytes_buffered_for_retry_ += batch->payload->send_message.send_message->length(); } if (batch->send_trailing_metadata) { - calld->pending_send_trailing_metadata = true; + pending_send_trailing_metadata_ = true; } - if (GPR_UNLIKELY(calld->bytes_buffered_for_retry > + if (GPR_UNLIKELY(bytes_buffered_for_retry_ > chand->per_rpc_retry_buffer_size())) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: exceeded retry buffer size, committing", - chand, calld); + chand, this); } - subchannel_call_retry_state* retry_state = - calld->subchannel_call == nullptr - ? nullptr - : static_cast( - - calld->subchannel_call->GetParentData()); - retry_commit(elem, retry_state); + SubchannelCallRetryState* retry_state = + subchannel_call_ == nullptr ? nullptr + : static_cast( + subchannel_call_->GetParentData()); + RetryCommit(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. - if (calld->num_attempts_completed == 0) { + if (num_attempts_completed_ == 0) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: disabling retries before first attempt", - chand, calld); + chand, this); } - calld->enable_retries = false; + enable_retries_ = false; } } } } -static void pending_batch_clear(call_data* calld, pending_batch* pending) { - if (calld->enable_retries) { +void CallData::PendingBatchClear(PendingBatch* pending) { + if (enable_retries_) { if (pending->batch->send_initial_metadata) { - calld->pending_send_initial_metadata = false; + pending_send_initial_metadata_ = false; } if (pending->batch->send_message) { - calld->pending_send_message = false; + pending_send_message_ = false; } if (pending->batch->send_trailing_metadata) { - calld->pending_send_trailing_metadata = false; + pending_send_trailing_metadata_ = false; } } pending->batch = nullptr; } -// This is called via the call combiner, so access to calld is synchronized. -static void fail_pending_batch_in_call_combiner(void* arg, grpc_error* error) { - grpc_transport_stream_op_batch* batch = - static_cast(arg); - call_data* calld = static_cast(batch->handler_private.extra_arg); - // Note: This will release the call combiner. - grpc_transport_stream_op_batch_finish_with_failure( - batch, GRPC_ERROR_REF(error), calld->call_combiner); -} - -// 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) { - GPR_ASSERT(error != GRPC_ERROR_NONE); - call_data* calld = static_cast(elem->call_data); - 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; - } - gpr_log(GPR_INFO, - "chand=%p calld=%p: failing %" PRIuPTR " pending batches: %s", - elem->channel_data, calld, num_batches, grpc_error_string(error)); - } - grpc_core::CallCombinerClosureList closures; - for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { - 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); - } - batch->handler_private.extra_arg = calld; - GRPC_CLOSURE_INIT(&batch->handler_private.closure, - fail_pending_batch_in_call_combiner, batch, - grpc_schedule_on_exec_ctx); - closures.Add(&batch->handler_private.closure, GRPC_ERROR_REF(error), - "pending_batches_fail"); - pending_batch_clear(calld, pending); - } - } - if (yield_call_combiner_predicate(closures)) { - closures.RunClosures(calld->call_combiner); - } else { - closures.RunClosuresWithoutYielding(calld->call_combiner); - } - GRPC_ERROR_UNREF(error); -} - -// This is called via the call combiner, so access to calld is synchronized. -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); - // Note: This will release the call combiner. - subchannel_call->StartTransportStreamOpBatch(batch); -} - -// This is called via the call combiner, so access to calld is synchronized. -static void pending_batches_resume(grpc_call_element* elem) { +void CallData::MaybeClearPendingBatch(grpc_call_element* elem, + PendingBatch* pending) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (calld->enable_retries) { - start_retriable_subchannel_batches(elem, GRPC_ERROR_NONE); - return; - } - // Retries not enabled; send down batches as-is. - 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; - } - gpr_log(GPR_INFO, - "chand=%p calld=%p: starting %" PRIuPTR - " pending batches on subchannel_call=%p", - 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) { - 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); - } - 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); - closures.Add(&batch->handler_private.closure, GRPC_ERROR_NONE, - "pending_batches_resume"); - pending_batch_clear(calld, pending); - } - } - // Note: This will release the call combiner. - closures.RunClosures(calld->call_combiner); -} - -static void maybe_clear_pending_batch(grpc_call_element* elem, - pending_batch* pending) { - ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); grpc_transport_stream_op_batch* batch = pending->batch; // We clear the pending batch if all of its callbacks have been // scheduled and reset to nullptr. @@ -1539,28 +1694,126 @@ static void maybe_clear_pending_batch(grpc_call_element* elem, nullptr)) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: clearing pending batch", chand, - calld); + this); } - pending_batch_clear(calld, pending); + PendingBatchClear(pending); } } -// Returns a pointer to the first pending batch for which predicate(batch) -// returns true, or null if not found. -template -static pending_batch* pending_batch_find(grpc_call_element* elem, - const char* log_message, - Predicate predicate) { +// This is called via the call combiner, so access to calld is synchronized. +void CallData::FailPendingBatchInCallCombiner(void* arg, grpc_error* error) { + grpc_transport_stream_op_batch* batch = + static_cast(arg); + CallData* calld = static_cast(batch->handler_private.extra_arg); + // Note: This will release the call combiner. + grpc_transport_stream_op_batch_finish_with_failure( + batch, GRPC_ERROR_REF(error), calld->call_combiner_); +} + +// This is called via the call combiner, so access to calld is synchronized. +void CallData::PendingBatchesFail( + grpc_call_element* elem, grpc_error* error, + YieldCallCombinerPredicate yield_call_combiner_predicate) { + GPR_ASSERT(error != GRPC_ERROR_NONE); + if (grpc_client_channel_call_trace.enabled()) { + size_t num_batches = 0; + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + if (pending_batches_[i].batch != nullptr) ++num_batches; + } + gpr_log(GPR_INFO, + "chand=%p calld=%p: failing %" PRIuPTR " pending batches: %s", + elem->channel_data, this, num_batches, grpc_error_string(error)); + } + CallCombinerClosureList closures; + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + PendingBatch* pending = &pending_batches_[i]; + grpc_transport_stream_op_batch* batch = pending->batch; + if (batch != nullptr) { + if (batch->recv_trailing_metadata) { + MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy(pick_.pick, + batch); + } + batch->handler_private.extra_arg = this; + GRPC_CLOSURE_INIT(&batch->handler_private.closure, + FailPendingBatchInCallCombiner, batch, + grpc_schedule_on_exec_ctx); + closures.Add(&batch->handler_private.closure, GRPC_ERROR_REF(error), + "PendingBatchesFail"); + PendingBatchClear(pending); + } + } + if (yield_call_combiner_predicate(closures)) { + closures.RunClosures(call_combiner_); + } else { + closures.RunClosuresWithoutYielding(call_combiner_); + } + GRPC_ERROR_UNREF(error); +} + +// This is called via the call combiner, so access to calld is synchronized. +void CallData::ResumePendingBatchInCallCombiner(void* arg, + grpc_error* ignored) { + grpc_transport_stream_op_batch* batch = + static_cast(arg); + SubchannelCall* subchannel_call = + static_cast(batch->handler_private.extra_arg); + // Note: This will release the call combiner. + subchannel_call->StartTransportStreamOpBatch(batch); +} + +// This is called via the call combiner, so access to calld is synchronized. +void CallData::PendingBatchesResume(grpc_call_element* elem) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { - pending_batch* pending = &calld->pending_batches[i]; + if (enable_retries_) { + StartRetriableSubchannelBatches(elem, GRPC_ERROR_NONE); + return; + } + // Retries not enabled; send down batches as-is. + if (grpc_client_channel_call_trace.enabled()) { + size_t num_batches = 0; + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + if (pending_batches_[i].batch != nullptr) ++num_batches; + } + gpr_log(GPR_INFO, + "chand=%p calld=%p: starting %" PRIuPTR + " pending batches on subchannel_call=%p", + chand, this, num_batches, subchannel_call_.get()); + } + CallCombinerClosureList closures; + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + PendingBatch* pending = &pending_batches_[i]; + grpc_transport_stream_op_batch* batch = pending->batch; + if (batch != nullptr) { + if (batch->recv_trailing_metadata) { + MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy(pick_.pick, + batch); + } + batch->handler_private.extra_arg = subchannel_call_.get(); + GRPC_CLOSURE_INIT(&batch->handler_private.closure, + ResumePendingBatchInCallCombiner, batch, + grpc_schedule_on_exec_ctx); + closures.Add(&batch->handler_private.closure, GRPC_ERROR_NONE, + "PendingBatchesResume"); + PendingBatchClear(pending); + } + } + // Note: This will release the call combiner. + closures.RunClosures(call_combiner_); +} + +template +CallData::PendingBatch* CallData::PendingBatchFind(grpc_call_element* elem, + const char* log_message, + Predicate predicate) { + ChannelData* chand = static_cast(elem->channel_data); + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + PendingBatch* pending = &pending_batches_[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr && predicate(batch)) { 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); + this, log_message, i); } return pending; } @@ -1572,99 +1825,92 @@ static pending_batch* pending_batch_find(grpc_call_element* elem, // retry code // -// Commits the call so that no further retry attempts will be performed. -static void retry_commit(grpc_call_element* elem, - subchannel_call_retry_state* retry_state) { +void CallData::RetryCommit(grpc_call_element* elem, + SubchannelCallRetryState* retry_state) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (calld->retry_committed) return; - calld->retry_committed = true; + if (retry_committed_) return; + retry_committed_ = true; if (grpc_client_channel_call_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: committing retries", chand, calld); + gpr_log(GPR_INFO, "chand=%p calld=%p: committing retries", chand, this); } if (retry_state != nullptr) { - free_cached_send_op_data_after_commit(elem, retry_state); + FreeCachedSendOpDataAfterCommit(elem, retry_state); } } -// Starts a retry after appropriate back-off. -static void do_retry(grpc_call_element* elem, - subchannel_call_retry_state* retry_state, - grpc_millis server_pushback_ms) { +void CallData::DoRetry(grpc_call_element* elem, + SubchannelCallRetryState* retry_state, + grpc_millis server_pushback_ms) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - GPR_ASSERT(calld->method_params != nullptr); + GPR_ASSERT(method_params_ != nullptr); const ClientChannelMethodParams::RetryPolicy* retry_policy = - calld->method_params->retry_policy(); + 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(); + subchannel_call_.reset(); + pick_.pick.connected_subchannel.reset(); // Compute backoff delay. grpc_millis next_attempt_time; if (server_pushback_ms >= 0) { next_attempt_time = grpc_core::ExecCtx::Get()->Now() + server_pushback_ms; - calld->last_attempt_got_server_pushback = true; + last_attempt_got_server_pushback_ = true; } else { - if (calld->num_attempts_completed == 1 || - calld->last_attempt_got_server_pushback) { - calld->retry_backoff.Init( - grpc_core::BackOff::Options() + if (num_attempts_completed_ == 1 || last_attempt_got_server_pushback_) { + retry_backoff_.Init( + BackOff::Options() .set_initial_backoff(retry_policy->initial_backoff) .set_multiplier(retry_policy->backoff_multiplier) .set_jitter(RETRY_BACKOFF_JITTER) .set_max_backoff(retry_policy->max_backoff)); - calld->last_attempt_got_server_pushback = false; + last_attempt_got_server_pushback_ = false; } - next_attempt_time = calld->retry_backoff->NextAttemptTime(); + next_attempt_time = retry_backoff_->NextAttemptTime(); } 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()); + this, next_attempt_time - grpc_core::ExecCtx::Get()->Now()); } // Schedule retry after computed delay. - GRPC_CLOSURE_INIT(&calld->pick_closure, start_pick_locked, elem, + GRPC_CLOSURE_INIT(&pick_closure_, StartPickLocked, elem, grpc_combiner_scheduler(chand->data_plane_combiner())); - grpc_timer_init(&calld->retry_timer, next_attempt_time, &calld->pick_closure); + grpc_timer_init(&retry_timer_, next_attempt_time, &pick_closure_); // Update bookkeeping. if (retry_state != nullptr) retry_state->retry_dispatched = true; } -// Returns true if the call is being retried. -static bool maybe_retry(grpc_call_element* elem, - subchannel_batch_data* batch_data, - grpc_status_code status, - grpc_mdelem* server_pushback_md) { +bool CallData::MaybeRetry(grpc_call_element* elem, + SubchannelCallBatchData* batch_data, + grpc_status_code status, + grpc_mdelem* server_pushback_md) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); // Get retry policy. - if (calld->method_params == nullptr) return false; + if (method_params_ == nullptr) return false; const ClientChannelMethodParams::RetryPolicy* retry_policy = - calld->method_params->retry_policy(); + method_params_->retry_policy(); if (retry_policy == nullptr) return false; // If we've already dispatched a retry from this call, return true. // This catches the case where the batch has multiple callbacks // (i.e., it includes either recv_message or recv_initial_metadata). - subchannel_call_retry_state* retry_state = nullptr; + SubchannelCallRetryState* retry_state = nullptr; if (batch_data != nullptr) { - retry_state = static_cast( + retry_state = static_cast( batch_data->subchannel_call->GetParentData()); if (retry_state->retry_dispatched) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: retry already dispatched", chand, - calld); + this); } return true; } } // Check status. if (GPR_LIKELY(status == GRPC_STATUS_OK)) { - if (calld->retry_throttle_data != nullptr) { - calld->retry_throttle_data->RecordSuccess(); + if (retry_throttle_data_ != nullptr) { + retry_throttle_data_->RecordSuccess(); } if (grpc_client_channel_call_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: call succeeded", chand, calld); + gpr_log(GPR_INFO, "chand=%p calld=%p: call succeeded", chand, this); } return false; } @@ -1673,7 +1919,7 @@ static bool maybe_retry(grpc_call_element* elem, 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)); + this, grpc_status_code_to_string(status)); } return false; } @@ -1684,36 +1930,36 @@ static bool maybe_retry(grpc_call_element* elem, // things like failures due to malformed requests (INVALID_ARGUMENT). // Conversely, it's important for this to come before the remaining // 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 (retry_throttle_data_ != nullptr && + !retry_throttle_data_->RecordFailure()) { if (grpc_client_channel_call_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: retries throttled", chand, calld); + gpr_log(GPR_INFO, "chand=%p calld=%p: retries throttled", chand, this); } return false; } // Check whether the call is committed. - if (calld->retry_committed) { + if (retry_committed_) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: retries already committed", chand, - calld); + this); } return false; } // Check whether we have retries remaining. - ++calld->num_attempts_completed; - if (calld->num_attempts_completed >= retry_policy->max_attempts) { + ++num_attempts_completed_; + if (num_attempts_completed_ >= retry_policy->max_attempts) { 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); + this, retry_policy->max_attempts); } return false; } // If the call was cancelled from the surface, don't retry. - if (calld->cancel_error != GRPC_ERROR_NONE) { + if (cancel_error_ != GRPC_ERROR_NONE) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: call cancelled from surface, not retrying", - chand, calld); + chand, this); } return false; } @@ -1726,48 +1972,54 @@ static bool maybe_retry(grpc_call_element* elem, if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: not retrying due to server push-back", - chand, calld); + chand, this); } return false; } else { 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); + chand, this, ms); } server_pushback_ms = (grpc_millis)ms; } } - do_retry(elem, retry_state, server_pushback_ms); + DoRetry(elem, retry_state, server_pushback_ms); return true; } // -// subchannel_batch_data +// CallData::SubchannelCallBatchData // -namespace { +CallData::SubchannelCallBatchData* CallData::SubchannelCallBatchData::Create( + grpc_call_element* elem, int refcount, bool set_on_complete) { + CallData* calld = static_cast(elem->call_data); + SubchannelCallBatchData* batch_data = + new (gpr_arena_alloc(calld->arena_, sizeof(*batch_data))) + SubchannelCallBatchData(elem, calld, refcount, set_on_complete); + return batch_data; +} -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) { - subchannel_call_retry_state* retry_state = - static_cast( - calld->subchannel_call->GetParentData()); +CallData::SubchannelCallBatchData::SubchannelCallBatchData( + grpc_call_element* elem, CallData* calld, int refcount, + bool set_on_complete) + : elem(elem), subchannel_call(calld->subchannel_call_) { + SubchannelCallRetryState* retry_state = + static_cast( + calld->subchannel_call_->GetParentData()); batch.payload = &retry_state->batch_payload; gpr_ref_init(&refs, refcount); if (set_on_complete) { - GRPC_CLOSURE_INIT(&on_complete, ::on_complete, this, + GRPC_CLOSURE_INIT(&on_complete, CallData::OnComplete, this, grpc_schedule_on_exec_ctx); batch.on_complete = &on_complete; } - GRPC_CALL_STACK_REF(calld->owning_call, "batch_data"); + GRPC_CALL_STACK_REF(calld->owning_call_, "batch_data"); } -void subchannel_batch_data::destroy() { - subchannel_call_retry_state* retry_state = - static_cast( - subchannel_call->GetParentData()); +void CallData::SubchannelCallBatchData::Destroy() { + SubchannelCallRetryState* retry_state = + static_cast(subchannel_call->GetParentData()); if (batch.send_initial_metadata) { grpc_metadata_batch_destroy(&retry_state->send_initial_metadata); } @@ -1781,42 +2033,20 @@ void subchannel_batch_data::destroy() { grpc_metadata_batch_destroy(&retry_state->recv_trailing_metadata); } subchannel_call.reset(); - call_data* calld = static_cast(elem->call_data); - GRPC_CALL_STACK_UNREF(calld->owning_call, "batch_data"); -} - -} // namespace - -// Creates a subchannel_batch_data object on the call's arena with the -// specified refcount. If set_on_complete is true, the batch's -// on_complete callback will be set to point to on_complete(); -// otherwise, the batch's on_complete callback will be null. -static subchannel_batch_data* batch_data_create(grpc_call_element* elem, - int refcount, - bool set_on_complete) { - call_data* calld = static_cast(elem->call_data); - subchannel_batch_data* batch_data = - new (gpr_arena_alloc(calld->arena, sizeof(*batch_data))) - subchannel_batch_data(elem, calld, refcount, set_on_complete); - return batch_data; -} - -static void batch_data_unref(subchannel_batch_data* batch_data) { - if (gpr_unref(&batch_data->refs)) { - batch_data->destroy(); - } + CallData* calld = static_cast(elem->call_data); + GRPC_CALL_STACK_UNREF(calld->owning_call_, "batch_data"); } // // recv_initial_metadata callback handling // -// Invokes recv_initial_metadata_ready for a subchannel batch. -static void invoke_recv_initial_metadata_callback(void* arg, - grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); +void CallData::InvokeRecvInitialMetadataCallback(void* arg, grpc_error* error) { + SubchannelCallBatchData* batch_data = + static_cast(arg); + CallData* calld = static_cast(batch_data->elem->call_data); // Find pending batch. - pending_batch* pending = pending_batch_find( + PendingBatch* pending = calld->PendingBatchFind( batch_data->elem, "invoking recv_initial_metadata_ready for", [](grpc_transport_stream_op_batch* batch) { return batch->recv_initial_metadata && @@ -1825,8 +2055,8 @@ static void invoke_recv_initial_metadata_callback(void* arg, }); GPR_ASSERT(pending != nullptr); // Return metadata. - subchannel_call_retry_state* retry_state = - static_cast( + SubchannelCallRetryState* retry_state = + static_cast( batch_data->subchannel_call->GetParentData()); grpc_metadata_batch_move( &retry_state->recv_initial_metadata, @@ -1839,33 +2069,32 @@ static void invoke_recv_initial_metadata_callback(void* arg, .recv_initial_metadata_ready; pending->batch->payload->recv_initial_metadata.recv_initial_metadata_ready = nullptr; - maybe_clear_pending_batch(batch_data->elem, pending); - batch_data_unref(batch_data); + calld->MaybeClearPendingBatch(batch_data->elem, pending); + batch_data->Unref(); // Invoke callback. GRPC_CLOSURE_RUN(recv_initial_metadata_ready, GRPC_ERROR_REF(error)); } -// Intercepts recv_initial_metadata_ready callback for retries. -// Commits the call and returns the initial metadata up the stack. -static void recv_initial_metadata_ready(void* arg, grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); +void CallData::RecvInitialMetadataReady(void* arg, grpc_error* error) { + SubchannelCallBatchData* batch_data = + static_cast(arg); grpc_call_element* elem = batch_data->elem; ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); + CallData* calld = static_cast(elem->call_data); 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)); } - subchannel_call_retry_state* retry_state = - static_cast( + SubchannelCallRetryState* retry_state = + static_cast( 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. if (retry_state->retry_dispatched) { GRPC_CALL_COMBINER_STOP( - calld->call_combiner, + calld->call_combiner_, "recv_initial_metadata_ready after retry dispatched"); return; } @@ -1887,30 +2116,31 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { if (!retry_state->started_recv_trailing_metadata) { // recv_trailing_metadata not yet started by application; start it // ourselves to get status. - start_internal_recv_trailing_metadata(elem); + calld->StartInternalRecvTrailingMetadata(elem); } else { GRPC_CALL_COMBINER_STOP( - calld->call_combiner, + calld->call_combiner_, "recv_initial_metadata_ready trailers-only or error"); } return; } // Received valid initial metadata, so commit the call. - retry_commit(elem, retry_state); + calld->RetryCommit(elem, retry_state); // Invoke the callback to return the result to the surface. // Manually invoking a callback function; it does not take ownership of error. - invoke_recv_initial_metadata_callback(batch_data, error); + calld->InvokeRecvInitialMetadataCallback(batch_data, error); } // // recv_message callback handling // -// Invokes recv_message_ready for a subchannel batch. -static void invoke_recv_message_callback(void* arg, grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); +void CallData::InvokeRecvMessageCallback(void* arg, grpc_error* error) { + SubchannelCallBatchData* batch_data = + static_cast(arg); + CallData* calld = static_cast(batch_data->elem->call_data); // Find pending op. - pending_batch* pending = pending_batch_find( + PendingBatch* pending = calld->PendingBatchFind( batch_data->elem, "invoking recv_message_ready for", [](grpc_transport_stream_op_batch* batch) { return batch->recv_message && @@ -1918,8 +2148,8 @@ static void invoke_recv_message_callback(void* arg, grpc_error* error) { }); GPR_ASSERT(pending != nullptr); // Return payload. - subchannel_call_retry_state* retry_state = - static_cast( + SubchannelCallRetryState* retry_state = + static_cast( batch_data->subchannel_call->GetParentData()); *pending->batch->payload->recv_message.recv_message = std::move(retry_state->recv_message); @@ -1929,31 +2159,30 @@ static void invoke_recv_message_callback(void* arg, grpc_error* error) { grpc_closure* recv_message_ready = pending->batch->payload->recv_message.recv_message_ready; pending->batch->payload->recv_message.recv_message_ready = nullptr; - maybe_clear_pending_batch(batch_data->elem, pending); - batch_data_unref(batch_data); + calld->MaybeClearPendingBatch(batch_data->elem, pending); + batch_data->Unref(); // Invoke callback. GRPC_CLOSURE_RUN(recv_message_ready, GRPC_ERROR_REF(error)); } -// Intercepts recv_message_ready callback for retries. -// Commits the call and returns the message up the stack. -static void recv_message_ready(void* arg, grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); +void CallData::RecvMessageReady(void* arg, grpc_error* error) { + SubchannelCallBatchData* batch_data = + static_cast(arg); grpc_call_element* elem = batch_data->elem; ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); + CallData* calld = static_cast(elem->call_data); 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)); } - subchannel_call_retry_state* retry_state = - static_cast( + SubchannelCallRetryState* retry_state = + static_cast( 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. if (retry_state->retry_dispatched) { - GRPC_CALL_COMBINER_STOP(calld->call_combiner, + GRPC_CALL_COMBINER_STOP(calld->call_combiner_, "recv_message_ready after retry dispatched"); return; } @@ -1975,33 +2204,29 @@ static void recv_message_ready(void* arg, grpc_error* error) { if (!retry_state->started_recv_trailing_metadata) { // recv_trailing_metadata not yet started by application; start it // ourselves to get status. - start_internal_recv_trailing_metadata(elem); + calld->StartInternalRecvTrailingMetadata(elem); } else { - GRPC_CALL_COMBINER_STOP(calld->call_combiner, "recv_message_ready null"); + GRPC_CALL_COMBINER_STOP(calld->call_combiner_, "recv_message_ready null"); } return; } // Received a valid message, so commit the call. - retry_commit(elem, retry_state); + calld->RetryCommit(elem, retry_state); // Invoke the callback to return the result to the surface. // Manually invoking a callback function; it does not take ownership of error. - invoke_recv_message_callback(batch_data, error); + calld->InvokeRecvMessageCallback(batch_data, error); } // // recv_trailing_metadata handling // -// Sets *status and *server_pushback_md based on md_batch and error. -// Only sets *server_pushback_md if server_pushback_md != nullptr. -static void get_call_status(grpc_call_element* elem, - grpc_metadata_batch* md_batch, grpc_error* error, - grpc_status_code* status, - grpc_mdelem** server_pushback_md) { - call_data* calld = static_cast(elem->call_data); +void CallData::GetCallStatus(grpc_call_element* elem, + grpc_metadata_batch* md_batch, grpc_error* error, + grpc_status_code* status, + grpc_mdelem** server_pushback_md) { if (error != GRPC_ERROR_NONE) { - grpc_error_get_status(error, calld->deadline, status, nullptr, nullptr, - nullptr); + grpc_error_get_status(error, deadline_, status, nullptr, nullptr, nullptr); } else { GPR_ASSERT(md_batch->idx.named.grpc_status != nullptr); *status = @@ -2014,12 +2239,11 @@ static void get_call_status(grpc_call_element* elem, GRPC_ERROR_UNREF(error); } -// Adds recv_trailing_metadata_ready closure to closures. -static void add_closure_for_recv_trailing_metadata_ready( - grpc_call_element* elem, subchannel_batch_data* batch_data, - grpc_error* error, grpc_core::CallCombinerClosureList* closures) { +void CallData::AddClosureForRecvTrailingMetadataReady( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + grpc_error* error, CallCombinerClosureList* closures) { // Find pending batch. - pending_batch* pending = pending_batch_find( + PendingBatch* pending = PendingBatchFind( elem, "invoking recv_trailing_metadata for", [](grpc_transport_stream_op_batch* batch) { return batch->recv_trailing_metadata && @@ -2027,15 +2251,14 @@ static void add_closure_for_recv_trailing_metadata_ready( .recv_trailing_metadata_ready != nullptr; }); // If we generated the recv_trailing_metadata op internally via - // start_internal_recv_trailing_metadata(), then there will be no - // pending batch. + // StartInternalRecvTrailingMetadata(), then there will be no pending batch. if (pending == nullptr) { GRPC_ERROR_UNREF(error); return; } // Return metadata. - subchannel_call_retry_state* retry_state = - static_cast( + SubchannelCallRetryState* retry_state = + static_cast( batch_data->subchannel_call->GetParentData()); grpc_metadata_batch_move( &retry_state->recv_trailing_metadata, @@ -2047,20 +2270,18 @@ static void add_closure_for_recv_trailing_metadata_ready( // Update bookkeeping. pending->batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = nullptr; - maybe_clear_pending_batch(elem, pending); + MaybeClearPendingBatch(elem, pending); } -// Adds any necessary closures for deferred recv_initial_metadata and -// recv_message callbacks to closures. -static void add_closures_for_deferred_recv_callbacks( - subchannel_batch_data* batch_data, subchannel_call_retry_state* retry_state, - grpc_core::CallCombinerClosureList* closures) { +void CallData::AddClosuresForDeferredRecvCallbacks( + SubchannelCallBatchData* batch_data, SubchannelCallRetryState* retry_state, + CallCombinerClosureList* closures) { if (batch_data->batch.recv_trailing_metadata) { // Add closure for deferred recv_initial_metadata_ready. if (GPR_UNLIKELY(retry_state->recv_initial_metadata_ready_deferred_batch != nullptr)) { GRPC_CLOSURE_INIT(&retry_state->recv_initial_metadata_ready, - invoke_recv_initial_metadata_callback, + InvokeRecvInitialMetadataCallback, retry_state->recv_initial_metadata_ready_deferred_batch, grpc_schedule_on_exec_ctx); closures->Add(&retry_state->recv_initial_metadata_ready, @@ -2072,7 +2293,7 @@ static void add_closures_for_deferred_recv_callbacks( if (GPR_UNLIKELY(retry_state->recv_message_ready_deferred_batch != nullptr)) { GRPC_CLOSURE_INIT(&retry_state->recv_message_ready, - invoke_recv_message_callback, + InvokeRecvMessageCallback, retry_state->recv_message_ready_deferred_batch, grpc_schedule_on_exec_ctx); closures->Add(&retry_state->recv_message_ready, @@ -2083,11 +2304,8 @@ static void add_closures_for_deferred_recv_callbacks( } } -// Returns true if any op in the batch was not yet started. -// Only looks at send ops, since recv ops are always started immediately. -static bool pending_batch_is_unstarted( - pending_batch* pending, call_data* calld, - subchannel_call_retry_state* retry_state) { +bool CallData::PendingBatchIsUnstarted(PendingBatch* pending, + SubchannelCallRetryState* retry_state) { if (pending->batch == nullptr || pending->batch->on_complete == nullptr) { return false; } @@ -2096,7 +2314,7 @@ static bool pending_batch_is_unstarted( return true; } if (pending->batch->send_message && - retry_state->started_send_message_count < calld->send_messages.size()) { + retry_state->started_send_message_count < send_messages_.size()) { return true; } if (pending->batch->send_trailing_metadata && @@ -2106,72 +2324,66 @@ static bool pending_batch_is_unstarted( return false; } -// For any pending batch containing an op that has not yet been started, -// adds the pending batch's completion closures to closures. -static void add_closures_to_fail_unstarted_pending_batches( - grpc_call_element* elem, subchannel_call_retry_state* retry_state, - grpc_error* error, grpc_core::CallCombinerClosureList* closures) { +void CallData::AddClosuresToFailUnstartedPendingBatches( + grpc_call_element* elem, SubchannelCallRetryState* retry_state, + grpc_error* error, CallCombinerClosureList* closures) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - 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)) { + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + PendingBatch* pending = &pending_batches_[i]; + if (PendingBatchIsUnstarted(pending, retry_state)) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: failing unstarted pending batch at index " "%" PRIuPTR, - chand, calld, i); + chand, this, i); } closures->Add(pending->batch->on_complete, GRPC_ERROR_REF(error), "failing on_complete for pending batch"); pending->batch->on_complete = nullptr; - maybe_clear_pending_batch(elem, pending); + MaybeClearPendingBatch(elem, pending); } } GRPC_ERROR_UNREF(error); } -// Runs necessary closures upon completion of a call attempt. -static void run_closures_for_completed_call(subchannel_batch_data* batch_data, - grpc_error* error) { +void CallData::RunClosuresForCompletedCall(SubchannelCallBatchData* batch_data, + grpc_error* error) { grpc_call_element* elem = batch_data->elem; - call_data* calld = static_cast(elem->call_data); - subchannel_call_retry_state* retry_state = - static_cast( + SubchannelCallRetryState* retry_state = + static_cast( batch_data->subchannel_call->GetParentData()); // Construct list of closures to execute. - grpc_core::CallCombinerClosureList closures; + CallCombinerClosureList closures; // First, add closure for recv_trailing_metadata_ready. - add_closure_for_recv_trailing_metadata_ready( - elem, batch_data, GRPC_ERROR_REF(error), &closures); + AddClosureForRecvTrailingMetadataReady(elem, batch_data, + GRPC_ERROR_REF(error), &closures); // If there are deferred recv_initial_metadata_ready or recv_message_ready // callbacks, add them to closures. - add_closures_for_deferred_recv_callbacks(batch_data, retry_state, &closures); + AddClosuresForDeferredRecvCallbacks(batch_data, retry_state, &closures); // Add closures to fail any pending batches that have not yet been started. - add_closures_to_fail_unstarted_pending_batches( - elem, retry_state, GRPC_ERROR_REF(error), &closures); + AddClosuresToFailUnstartedPendingBatches(elem, retry_state, + GRPC_ERROR_REF(error), &closures); // Don't need batch_data anymore. - batch_data_unref(batch_data); + batch_data->Unref(); // Schedule all of the closures identified above. // Note: This will release the call combiner. - closures.RunClosures(calld->call_combiner); + closures.RunClosures(call_combiner_); GRPC_ERROR_UNREF(error); } -// 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) { - subchannel_batch_data* batch_data = static_cast(arg); +void CallData::RecvTrailingMetadataReady(void* arg, grpc_error* error) { + SubchannelCallBatchData* batch_data = + static_cast(arg); grpc_call_element* elem = batch_data->elem; ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); + CallData* calld = static_cast(elem->call_data); 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)); } - subchannel_call_retry_state* retry_state = - static_cast( + SubchannelCallRetryState* retry_state = + static_cast( batch_data->subchannel_call->GetParentData()); retry_state->completed_recv_trailing_metadata = true; // Get the call's status and check for server pushback metadata. @@ -2179,44 +2391,42 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { grpc_mdelem* server_pushback_md = nullptr; grpc_metadata_batch* md_batch = batch_data->batch.payload->recv_trailing_metadata.recv_trailing_metadata; - get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, - &server_pushback_md); + calld->GetCallStatus(elem, md_batch, GRPC_ERROR_REF(error), &status, + &server_pushback_md); 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)); } // Check if we should retry. - if (maybe_retry(elem, batch_data, status, server_pushback_md)) { + if (calld->MaybeRetry(elem, batch_data, status, server_pushback_md)) { // Unref batch_data for deferred recv_initial_metadata_ready or // recv_message_ready callbacks, if any. if (retry_state->recv_initial_metadata_ready_deferred_batch != nullptr) { - batch_data_unref(batch_data); + batch_data->Unref(); GRPC_ERROR_UNREF(retry_state->recv_initial_metadata_error); } if (retry_state->recv_message_ready_deferred_batch != nullptr) { - batch_data_unref(batch_data); + batch_data->Unref(); GRPC_ERROR_UNREF(retry_state->recv_message_error); } - batch_data_unref(batch_data); + batch_data->Unref(); return; } // Not retrying, so commit the call. - retry_commit(elem, retry_state); + calld->RetryCommit(elem, retry_state); // Run any necessary closures. - run_closures_for_completed_call(batch_data, GRPC_ERROR_REF(error)); + calld->RunClosuresForCompletedCall(batch_data, GRPC_ERROR_REF(error)); } // // on_complete callback handling // -// Adds the on_complete closure for the pending batch completed in -// batch_data to closures. -static void add_closure_for_completed_pending_batch( - grpc_call_element* elem, subchannel_batch_data* batch_data, - subchannel_call_retry_state* retry_state, grpc_error* error, - grpc_core::CallCombinerClosureList* closures) { - pending_batch* pending = pending_batch_find( +void CallData::AddClosuresForCompletedPendingBatch( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state, grpc_error* error, + CallCombinerClosureList* closures) { + PendingBatch* pending = PendingBatchFind( elem, "completed", [batch_data](grpc_transport_stream_op_batch* batch) { // Match the pending batch with the same set of send ops as the // subchannel batch we've just completed. @@ -2237,27 +2447,22 @@ static void add_closure_for_completed_pending_batch( closures->Add(pending->batch->on_complete, error, "on_complete for pending batch"); pending->batch->on_complete = nullptr; - maybe_clear_pending_batch(elem, pending); + MaybeClearPendingBatch(elem, pending); } -// If there are any cached ops to replay or pending ops to start on the -// subchannel call, adds a closure to closures to invoke -// start_retriable_subchannel_batches(). -static void add_closures_for_replay_or_pending_send_ops( - grpc_call_element* elem, subchannel_batch_data* batch_data, - subchannel_call_retry_state* retry_state, - grpc_core::CallCombinerClosureList* closures) { +void CallData::AddClosuresForReplayOrPendingSendOps( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state, CallCombinerClosureList* closures) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); bool have_pending_send_message_ops = - retry_state->started_send_message_count < calld->send_messages.size(); + retry_state->started_send_message_count < send_messages_.size(); bool have_pending_send_trailing_metadata_op = - calld->seen_send_trailing_metadata && + seen_send_trailing_metadata_ && !retry_state->started_send_trailing_metadata; if (!have_pending_send_message_ops && !have_pending_send_trailing_metadata_op) { - for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { - pending_batch* pending = &calld->pending_batches[i]; + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + PendingBatch* pending = &pending_batches_[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch == nullptr || pending->send_ops_cached) continue; if (batch->send_message) have_pending_send_message_ops = true; @@ -2270,31 +2475,30 @@ static void add_closures_for_replay_or_pending_send_ops( 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); + chand, this); } GRPC_CLOSURE_INIT(&batch_data->batch.handler_private.closure, - start_retriable_subchannel_batches, elem, + StartRetriableSubchannelBatches, elem, grpc_schedule_on_exec_ctx); closures->Add(&batch_data->batch.handler_private.closure, GRPC_ERROR_NONE, "starting next batch for send_* op(s)"); } } -// Callback used to intercept on_complete from subchannel calls. -// Called only when retries are enabled. -static void on_complete(void* arg, grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); +void CallData::OnComplete(void* arg, grpc_error* error) { + SubchannelCallBatchData* batch_data = + static_cast(arg); grpc_call_element* elem = batch_data->elem; ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); + CallData* calld = static_cast(elem->call_data); 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); gpr_free(batch_str); } - subchannel_call_retry_state* retry_state = - static_cast( + SubchannelCallRetryState* retry_state = + static_cast( batch_data->subchannel_call->GetParentData()); // Update bookkeeping in retry_state. if (batch_data->batch.send_initial_metadata) { @@ -2308,38 +2512,38 @@ static void on_complete(void* arg, grpc_error* error) { } // If the call is committed, free cached data for send ops that we've just // completed. - if (calld->retry_committed) { - free_cached_send_op_data_for_completed_batch(elem, batch_data, retry_state); + if (calld->retry_committed_) { + calld->FreeCachedSendOpDataForCompletedBatch(elem, batch_data, retry_state); } // Construct list of closures to execute. - grpc_core::CallCombinerClosureList closures; + CallCombinerClosureList closures; // If a retry was already dispatched, that means we saw // recv_trailing_metadata before this, so we do nothing here. // Otherwise, invoke the callback to return the result to the surface. if (!retry_state->retry_dispatched) { // Add closure for the completed pending batch, if any. - add_closure_for_completed_pending_batch(elem, batch_data, retry_state, - GRPC_ERROR_REF(error), &closures); + calld->AddClosuresForCompletedPendingBatch( + elem, batch_data, retry_state, GRPC_ERROR_REF(error), &closures); // If needed, add a callback to start any replay or pending send ops on // the subchannel call. if (!retry_state->completed_recv_trailing_metadata) { - add_closures_for_replay_or_pending_send_ops(elem, batch_data, retry_state, + calld->AddClosuresForReplayOrPendingSendOps(elem, batch_data, retry_state, &closures); } } // Track number of pending subchannel send batches and determine if this // was the last one. - --calld->num_pending_retriable_subchannel_send_batches; + --calld->num_pending_retriable_subchannel_send_batches_; const bool last_send_batch_complete = - calld->num_pending_retriable_subchannel_send_batches == 0; + calld->num_pending_retriable_subchannel_send_batches_ == 0; // Don't need batch_data anymore. - batch_data_unref(batch_data); + batch_data->Unref(); // Schedule all of the closures identified above. // Note: This yeilds the call combiner. - closures.RunClosures(calld->call_combiner); + closures.RunClosures(calld->call_combiner_); // If this was the last subchannel send batch, unref the call stack. if (last_send_batch_complete) { - GRPC_CALL_STACK_UNREF(calld->owning_call, "subchannel_send_batches"); + GRPC_CALL_STACK_UNREF(calld->owning_call_, "subchannel_send_batches"); } } @@ -2347,40 +2551,35 @@ static void on_complete(void* arg, grpc_error* error) { // subchannel batch construction // -// Helper function used to start a subchannel batch in the call combiner. -static void start_batch_in_call_combiner(void* arg, grpc_error* ignored) { +void CallData::StartBatchInCallCombiner(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); + SubchannelCall* subchannel_call = + static_cast(batch->handler_private.extra_arg); // Note: This will release the call combiner. subchannel_call->StartTransportStreamOpBatch(batch); } -// Adds a closure to closures that will execute batch in the call combiner. -static void add_closure_for_subchannel_batch( +void CallData::AddClosureForSubchannelBatch( grpc_call_element* elem, grpc_transport_stream_op_batch* batch, - grpc_core::CallCombinerClosureList* closures) { + CallCombinerClosureList* closures) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - 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); + batch->handler_private.extra_arg = subchannel_call_.get(); + GRPC_CLOSURE_INIT(&batch->handler_private.closure, StartBatchInCallCombiner, + batch, grpc_schedule_on_exec_ctx); 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); + this, batch_str); gpr_free(batch_str); } closures->Add(&batch->handler_private.closure, GRPC_ERROR_NONE, "start_subchannel_batch"); } -// Adds retriable send_initial_metadata op to batch_data. -static void add_retriable_send_initial_metadata_op( - call_data* calld, subchannel_call_retry_state* retry_state, - subchannel_batch_data* batch_data) { +void CallData::AddRetriableSendInitialMetadataOp( + SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data) { // Maps the number of retries to the corresponding metadata value slice. static const grpc_slice* retry_count_strings[] = { &GRPC_MDSTR_1, &GRPC_MDSTR_2, &GRPC_MDSTR_3, &GRPC_MDSTR_4}; @@ -2390,12 +2589,11 @@ static void add_retriable_send_initial_metadata_op( // // If we've already completed one or more attempts, add the // grpc-retry-attempts header. - retry_state->send_initial_metadata_storage = - static_cast(gpr_arena_alloc( - calld->arena, sizeof(grpc_linked_mdelem) * - (calld->send_initial_metadata.list.count + - (calld->num_attempts_completed > 0)))); - grpc_metadata_batch_copy(&calld->send_initial_metadata, + retry_state->send_initial_metadata_storage = static_cast( + gpr_arena_alloc(arena_, sizeof(grpc_linked_mdelem) * + (send_initial_metadata_.list.count + + (num_attempts_completed_ > 0)))); + grpc_metadata_batch_copy(&send_initial_metadata_, &retry_state->send_initial_metadata, retry_state->send_initial_metadata_storage); if (GPR_UNLIKELY(retry_state->send_initial_metadata.idx.named @@ -2404,14 +2602,14 @@ static void add_retriable_send_initial_metadata_op( retry_state->send_initial_metadata.idx.named .grpc_previous_rpc_attempts); } - if (GPR_UNLIKELY(calld->num_attempts_completed > 0)) { + if (GPR_UNLIKELY(num_attempts_completed_ > 0)) { grpc_mdelem retry_md = grpc_mdelem_create( GRPC_MDSTR_GRPC_PREVIOUS_RPC_ATTEMPTS, - *retry_count_strings[calld->num_attempts_completed - 1], nullptr); + *retry_count_strings[num_attempts_completed_ - 1], nullptr); grpc_error* error = grpc_metadata_batch_add_tail( &retry_state->send_initial_metadata, - &retry_state->send_initial_metadata_storage[calld->send_initial_metadata - .list.count], + &retry_state + ->send_initial_metadata_storage[send_initial_metadata_.list.count], retry_md); if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { gpr_log(GPR_ERROR, "error adding retry metadata: %s", @@ -2424,24 +2622,21 @@ static void add_retriable_send_initial_metadata_op( batch_data->batch.payload->send_initial_metadata.send_initial_metadata = &retry_state->send_initial_metadata; batch_data->batch.payload->send_initial_metadata.send_initial_metadata_flags = - calld->send_initial_metadata_flags; - batch_data->batch.payload->send_initial_metadata.peer_string = - calld->peer_string; + send_initial_metadata_flags_; + batch_data->batch.payload->send_initial_metadata.peer_string = peer_string_; } -// Adds retriable send_message op to batch_data. -static void add_retriable_send_message_op( - grpc_call_element* elem, subchannel_call_retry_state* retry_state, - subchannel_batch_data* batch_data) { +void CallData::AddRetriableSendMessageOp(grpc_call_element* elem, + SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); 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); + chand, this, retry_state->started_send_message_count); } - grpc_core::ByteStreamCache* cache = - calld->send_messages[retry_state->started_send_message_count]; + ByteStreamCache* cache = + send_messages_[retry_state->started_send_message_count]; ++retry_state->started_send_message_count; retry_state->send_message.Init(cache); batch_data->batch.send_message = true; @@ -2449,18 +2644,17 @@ static void add_retriable_send_message_op( retry_state->send_message.get()); } -// Adds retriable send_trailing_metadata op to batch_data. -static void add_retriable_send_trailing_metadata_op( - call_data* calld, subchannel_call_retry_state* retry_state, - subchannel_batch_data* batch_data) { +void CallData::AddRetriableSendTrailingMetadataOp( + SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data) { // We need to make a copy of the metadata batch for each attempt, since // the filters in the subchannel stack may modify this batch, and we don't // want those modifications to be passed forward to subsequent attempts. retry_state->send_trailing_metadata_storage = static_cast(gpr_arena_alloc( - calld->arena, sizeof(grpc_linked_mdelem) * - calld->send_trailing_metadata.list.count)); - grpc_metadata_batch_copy(&calld->send_trailing_metadata, + arena_, + sizeof(grpc_linked_mdelem) * send_trailing_metadata_.list.count)); + grpc_metadata_batch_copy(&send_trailing_metadata_, &retry_state->send_trailing_metadata, retry_state->send_trailing_metadata_storage); retry_state->started_send_trailing_metadata = true; @@ -2469,10 +2663,9 @@ static void add_retriable_send_trailing_metadata_op( &retry_state->send_trailing_metadata; } -// Adds retriable recv_initial_metadata op to batch_data. -static void add_retriable_recv_initial_metadata_op( - call_data* calld, subchannel_call_retry_state* retry_state, - subchannel_batch_data* batch_data) { +void CallData::AddRetriableRecvInitialMetadataOp( + SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data) { retry_state->started_recv_initial_metadata = true; batch_data->batch.recv_initial_metadata = true; grpc_metadata_batch_init(&retry_state->recv_initial_metadata); @@ -2481,30 +2674,27 @@ static void add_retriable_recv_initial_metadata_op( batch_data->batch.payload->recv_initial_metadata.trailing_metadata_available = &retry_state->trailing_metadata_available; GRPC_CLOSURE_INIT(&retry_state->recv_initial_metadata_ready, - recv_initial_metadata_ready, batch_data, + RecvInitialMetadataReady, batch_data, grpc_schedule_on_exec_ctx); batch_data->batch.payload->recv_initial_metadata.recv_initial_metadata_ready = &retry_state->recv_initial_metadata_ready; } -// Adds retriable recv_message op to batch_data. -static void add_retriable_recv_message_op( - call_data* calld, subchannel_call_retry_state* retry_state, - subchannel_batch_data* batch_data) { +void CallData::AddRetriableRecvMessageOp(SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data) { ++retry_state->started_recv_message_count; batch_data->batch.recv_message = true; batch_data->batch.payload->recv_message.recv_message = &retry_state->recv_message; - GRPC_CLOSURE_INIT(&retry_state->recv_message_ready, recv_message_ready, + GRPC_CLOSURE_INIT(&retry_state->recv_message_ready, RecvMessageReady, batch_data, grpc_schedule_on_exec_ctx); batch_data->batch.payload->recv_message.recv_message_ready = &retry_state->recv_message_ready; } -// Adds retriable recv_trailing_metadata op to batch_data. -static void add_retriable_recv_trailing_metadata_op( - call_data* calld, subchannel_call_retry_state* retry_state, - subchannel_batch_data* batch_data) { +void CallData::AddRetriableRecvTrailingMetadataOp( + SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data) { retry_state->started_recv_trailing_metadata = true; batch_data->batch.recv_trailing_metadata = true; grpc_metadata_batch_init(&retry_state->recv_trailing_metadata); @@ -2513,115 +2703,105 @@ 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, + RecvTrailingMetadataReady, 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->pick.pick, - &batch_data->batch); + MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy( + pick_.pick, &batch_data->batch); } -// Helper function used to start a recv_trailing_metadata batch. This -// is used in the case where a recv_initial_metadata or recv_message -// op fails in a way that we know the call is over but when the application -// has not yet started its own recv_trailing_metadata op. -static void start_internal_recv_trailing_metadata(grpc_call_element* elem) { +void CallData::StartInternalRecvTrailingMetadata(grpc_call_element* elem) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); 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", - chand, calld); + chand, this); } - subchannel_call_retry_state* retry_state = - static_cast( - calld->subchannel_call->GetParentData()); + SubchannelCallRetryState* retry_state = + static_cast(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 // op from the surface. - subchannel_batch_data* batch_data = - batch_data_create(elem, 2, false /* set_on_complete */); - add_retriable_recv_trailing_metadata_op(calld, retry_state, batch_data); + SubchannelCallBatchData* batch_data = + SubchannelCallBatchData::Create(elem, 2, false /* set_on_complete */); + AddRetriableRecvTrailingMetadataOp(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); + subchannel_call_->StartTransportStreamOpBatch(&batch_data->batch); } // If there are any cached send ops that need to be replayed on the // current subchannel call, creates and returns a new subchannel batch // to replay those ops. Otherwise, returns nullptr. -static subchannel_batch_data* maybe_create_subchannel_batch_for_replay( - grpc_call_element* elem, subchannel_call_retry_state* retry_state) { +CallData::SubchannelCallBatchData* +CallData::MaybeCreateSubchannelBatchForReplay( + grpc_call_element* elem, SubchannelCallRetryState* retry_state) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - subchannel_batch_data* replay_batch_data = nullptr; + SubchannelCallBatchData* replay_batch_data = nullptr; // send_initial_metadata. - if (calld->seen_send_initial_metadata && + if (seen_send_initial_metadata_ && !retry_state->started_send_initial_metadata && - !calld->pending_send_initial_metadata) { + !pending_send_initial_metadata_) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: replaying previously completed " "send_initial_metadata op", - chand, calld); + chand, this); } - replay_batch_data = batch_data_create(elem, 1, true /* set_on_complete */); - add_retriable_send_initial_metadata_op(calld, retry_state, - replay_batch_data); + replay_batch_data = + SubchannelCallBatchData::Create(elem, 1, true /* set_on_complete */); + AddRetriableSendInitialMetadataOp(retry_state, replay_batch_data); } // send_message. // Note that we can only have one send_message op in flight at a time. - if (retry_state->started_send_message_count < calld->send_messages.size() && + if (retry_state->started_send_message_count < send_messages_.size() && retry_state->started_send_message_count == retry_state->completed_send_message_count && - !calld->pending_send_message) { + !pending_send_message_) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: replaying previously completed " "send_message op", - chand, calld); + chand, this); } if (replay_batch_data == nullptr) { replay_batch_data = - batch_data_create(elem, 1, true /* set_on_complete */); + SubchannelCallBatchData::Create(elem, 1, true /* set_on_complete */); } - add_retriable_send_message_op(elem, retry_state, replay_batch_data); + AddRetriableSendMessageOp(elem, retry_state, replay_batch_data); } // send_trailing_metadata. // Note that we only add this op if we have no more send_message ops // to start, since we can't send down any more send_message ops after // send_trailing_metadata. - if (calld->seen_send_trailing_metadata && - retry_state->started_send_message_count == calld->send_messages.size() && + if (seen_send_trailing_metadata_ && + retry_state->started_send_message_count == send_messages_.size() && !retry_state->started_send_trailing_metadata && - !calld->pending_send_trailing_metadata) { + !pending_send_trailing_metadata_) { if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: replaying previously completed " "send_trailing_metadata op", - chand, calld); + chand, this); } if (replay_batch_data == nullptr) { replay_batch_data = - batch_data_create(elem, 1, true /* set_on_complete */); + SubchannelCallBatchData::Create(elem, 1, true /* set_on_complete */); } - add_retriable_send_trailing_metadata_op(calld, retry_state, - replay_batch_data); + AddRetriableSendTrailingMetadataOp(retry_state, replay_batch_data); } return replay_batch_data; } -// Adds subchannel batches for pending batches to batches, updating -// *num_batches as needed. -static void add_subchannel_batches_for_pending_batches( - grpc_call_element* elem, subchannel_call_retry_state* retry_state, - grpc_core::CallCombinerClosureList* closures) { - call_data* calld = static_cast(elem->call_data); - for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { - pending_batch* pending = &calld->pending_batches[i]; +void CallData::AddSubchannelBatchesForPendingBatches( + grpc_call_element* elem, SubchannelCallRetryState* retry_state, + CallCombinerClosureList* closures) { + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + PendingBatch* pending = &pending_batches_[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch == nullptr) continue; // Skip any batch that either (a) has already been started on this @@ -2647,7 +2827,7 @@ static void add_subchannel_batches_for_pending_batches( // send_message ops after send_trailing_metadata. if (batch->send_trailing_metadata && (retry_state->started_send_message_count + batch->send_message < - calld->send_messages.size() || + send_messages_.size() || retry_state->started_send_trailing_metadata)) { continue; } @@ -2662,7 +2842,7 @@ static void add_subchannel_batches_for_pending_batches( if (batch->recv_trailing_metadata && retry_state->started_recv_trailing_metadata) { // If we previously completed a recv_trailing_metadata op - // initiated by start_internal_recv_trailing_metadata(), use the + // initiated by StartInternalRecvTrailingMetadata(), use the // result of that instead of trying to re-start this op. if (GPR_UNLIKELY((retry_state->recv_trailing_metadata_internal_batch != nullptr))) { @@ -2678,18 +2858,17 @@ static void add_subchannel_batches_for_pending_batches( "re-executing recv_trailing_metadata_ready to propagate " "internally triggered result"); } else { - batch_data_unref(retry_state->recv_trailing_metadata_internal_batch); + retry_state->recv_trailing_metadata_internal_batch->Unref(); } retry_state->recv_trailing_metadata_internal_batch = nullptr; } continue; } // If we're not retrying, just send the batch as-is. - if (calld->method_params == nullptr || - calld->method_params->retry_policy() == nullptr || - calld->retry_committed) { - add_closure_for_subchannel_batch(elem, batch, closures); - pending_batch_clear(calld, pending); + if (method_params_ == nullptr || + method_params_->retry_policy() == nullptr || retry_committed_) { + AddClosureForSubchannelBatch(elem, batch, closures); + PendingBatchClear(pending); continue; } // Create batch with the right number of callbacks. @@ -2699,183 +2878,168 @@ static void add_subchannel_batches_for_pending_batches( const int num_callbacks = has_send_ops + batch->recv_initial_metadata + batch->recv_message + batch->recv_trailing_metadata; - subchannel_batch_data* batch_data = batch_data_create( + SubchannelCallBatchData* batch_data = SubchannelCallBatchData::Create( elem, num_callbacks, has_send_ops /* set_on_complete */); // Cache send ops if needed. - maybe_cache_send_ops_for_batch(calld, pending); + MaybeCacheSendOpsForBatch(pending); // send_initial_metadata. if (batch->send_initial_metadata) { - add_retriable_send_initial_metadata_op(calld, retry_state, batch_data); + AddRetriableSendInitialMetadataOp(retry_state, batch_data); } // send_message. if (batch->send_message) { - add_retriable_send_message_op(elem, retry_state, batch_data); + AddRetriableSendMessageOp(elem, retry_state, batch_data); } // send_trailing_metadata. if (batch->send_trailing_metadata) { - add_retriable_send_trailing_metadata_op(calld, retry_state, batch_data); + AddRetriableSendTrailingMetadataOp(retry_state, batch_data); } // recv_initial_metadata. if (batch->recv_initial_metadata) { // recv_flags is only used on the server side. GPR_ASSERT(batch->payload->recv_initial_metadata.recv_flags == nullptr); - add_retriable_recv_initial_metadata_op(calld, retry_state, batch_data); + AddRetriableRecvInitialMetadataOp(retry_state, batch_data); } // recv_message. if (batch->recv_message) { - add_retriable_recv_message_op(calld, retry_state, batch_data); + AddRetriableRecvMessageOp(retry_state, batch_data); } // recv_trailing_metadata. if (batch->recv_trailing_metadata) { - add_retriable_recv_trailing_metadata_op(calld, retry_state, batch_data); + AddRetriableRecvTrailingMetadataOp(retry_state, batch_data); } - add_closure_for_subchannel_batch(elem, &batch_data->batch, closures); + AddClosureForSubchannelBatch(elem, &batch_data->batch, closures); // Track number of pending subchannel send batches. // If this is the first one, take a ref to the call stack. if (batch->send_initial_metadata || batch->send_message || batch->send_trailing_metadata) { - if (calld->num_pending_retriable_subchannel_send_batches == 0) { - GRPC_CALL_STACK_REF(calld->owning_call, "subchannel_send_batches"); + if (num_pending_retriable_subchannel_send_batches_ == 0) { + GRPC_CALL_STACK_REF(owning_call_, "subchannel_send_batches"); } - ++calld->num_pending_retriable_subchannel_send_batches; + ++num_pending_retriable_subchannel_send_batches_; } } } -// Constructs and starts whatever subchannel batches are needed on the -// subchannel call. -static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { +void CallData::StartRetriableSubchannelBatches(void* arg, grpc_error* ignored) { grpc_call_element* elem = static_cast(arg); ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); + CallData* calld = static_cast(elem->call_data); if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: constructing retriable batches", chand, calld); } - subchannel_call_retry_state* retry_state = - static_cast( - calld->subchannel_call->GetParentData()); + SubchannelCallRetryState* retry_state = + static_cast( + calld->subchannel_call_->GetParentData()); // Construct list of closures to execute, one for each pending batch. - grpc_core::CallCombinerClosureList closures; + CallCombinerClosureList closures; // Replay previously-returned send_* ops if needed. - subchannel_batch_data* replay_batch_data = - maybe_create_subchannel_batch_for_replay(elem, retry_state); + SubchannelCallBatchData* replay_batch_data = + calld->MaybeCreateSubchannelBatchForReplay(elem, retry_state); if (replay_batch_data != nullptr) { - add_closure_for_subchannel_batch(elem, &replay_batch_data->batch, - &closures); + calld->AddClosureForSubchannelBatch(elem, &replay_batch_data->batch, + &closures); // Track number of pending subchannel send batches. // If this is the first one, take a ref to the call stack. - if (calld->num_pending_retriable_subchannel_send_batches == 0) { - GRPC_CALL_STACK_REF(calld->owning_call, "subchannel_send_batches"); + if (calld->num_pending_retriable_subchannel_send_batches_ == 0) { + GRPC_CALL_STACK_REF(calld->owning_call_, "subchannel_send_batches"); } - ++calld->num_pending_retriable_subchannel_send_batches; + ++calld->num_pending_retriable_subchannel_send_batches_; } // Now add pending batches. - add_subchannel_batches_for_pending_batches(elem, retry_state, &closures); + calld->AddSubchannelBatchesForPendingBatches(elem, retry_state, &closures); // Start batches on subchannel call. if (grpc_client_channel_call_trace.enabled()) { 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_.get()); } // Note: This will yield the call combiner. - closures.RunClosures(calld->call_combiner); + closures.RunClosures(calld->call_combiner_); } // // LB pick // -static void create_subchannel_call(grpc_call_element* elem) { +void CallData::CreateSubchannelCall(grpc_call_element* elem) { ChannelData* 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 + enable_retries_ ? sizeof(SubchannelCallRetryState) : 0; + const ConnectedSubchannel::CallArgs call_args = { + pollent_, path_, call_start_time_, deadline_, 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 - }; + call_context_, call_combiner_, parent_data_size}; grpc_error* error = GRPC_ERROR_NONE; - calld->subchannel_call = - calld->pick.pick.connected_subchannel->CreateCall(call_args, &error); + subchannel_call_ = + pick_.pick.connected_subchannel->CreateCall(call_args, &error); 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)); + chand, this, subchannel_call_.get(), grpc_error_string(error)); } if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - pending_batches_fail(elem, error, yield_call_combiner); + PendingBatchesFail(elem, error, YieldCallCombiner); } else { if (parent_data_size > 0) { - new (calld->subchannel_call->GetParentData()) - subchannel_call_retry_state(calld->call_context); + new (subchannel_call_->GetParentData()) + SubchannelCallRetryState(call_context_); } - pending_batches_resume(elem); + PendingBatchesResume(elem); } } -// Invoked when a pick is completed, on both success or failure. -static void pick_done(void* arg, grpc_error* error) { +void CallData::PickDone(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); + CallData* calld = static_cast(elem->call_data); if (error != GRPC_ERROR_NONE) { 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)); } - pending_batches_fail(elem, GRPC_ERROR_REF(error), yield_call_combiner); + calld->PendingBatchesFail(elem, GRPC_ERROR_REF(error), YieldCallCombiner); return; } - create_subchannel_call(elem); + calld->CreateSubchannelCall(elem); } -namespace grpc_core { -namespace { - // A class to handle the call combiner cancellation callback for a // queued pick. -class QueuedPickCanceller { +class CallData::QueuedPickCanceller { public: explicit QueuedPickCanceller(grpc_call_element* elem) : elem_(elem) { - auto* calld = static_cast(elem->call_data); + auto* calld = static_cast(elem->call_data); auto* chand = static_cast(elem->channel_data); - GRPC_CALL_STACK_REF(calld->owning_call, "QueuedPickCanceller"); + GRPC_CALL_STACK_REF(calld->owning_call_, "QueuedPickCanceller"); GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this, grpc_combiner_scheduler(chand->data_plane_combiner())); - grpc_call_combiner_set_notify_on_cancel(calld->call_combiner, &closure_); + 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); + auto* calld = static_cast(self->elem_->call_data); 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", chand, calld, grpc_error_string(error), self, - calld->pick_canceller); + calld->pick_canceller_); } - if (calld->pick_canceller == self && error != GRPC_ERROR_NONE) { + if (calld->pick_canceller_ == self && error != GRPC_ERROR_NONE) { // Remove pick from list of queued picks. - remove_call_from_queued_picks_locked(self->elem_); + calld->RemoveCallFromQueuedPicksLocked(self->elem_); // Fail pending batches on the call. - pending_batches_fail(self->elem_, GRPC_ERROR_REF(error), - yield_call_combiner_if_pending_batches_found); + calld->PendingBatchesFail(self->elem_, GRPC_ERROR_REF(error), + YieldCallCombinerIfPendingBatchesFound); } - GRPC_CALL_STACK_UNREF(calld->owning_call, "QueuedPickCanceller"); + GRPC_CALL_STACK_UNREF(calld->owning_call_, "QueuedPickCanceller"); Delete(self); } @@ -2883,72 +3047,61 @@ class QueuedPickCanceller { 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) { +void CallData::RemoveCallFromQueuedPicksLocked(grpc_call_element* elem) { auto* chand = static_cast(elem->channel_data); - auto* calld = static_cast(elem->call_data); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: removing from queued picks list", - chand, calld); + chand, this); } - chand->RemoveQueuedPick(&calld->pick, calld->pollent); - calld->pick_queued = false; + chand->RemoveQueuedPick(&pick_, pollent_); + pick_queued_ = false; // Lame the call combiner canceller. - calld->pick_canceller = nullptr; + pick_canceller_ = nullptr; } -// Adds the call to the channel's list of queued picks. -static void add_call_to_queued_picks_locked(grpc_call_element* elem) { +void CallData::AddCallToQueuedPicksLocked(grpc_call_element* elem) { auto* chand = static_cast(elem->channel_data); - auto* calld = static_cast(elem->call_data); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: adding to queued picks list", chand, - calld); + this); } - calld->pick_queued = true; - calld->pick.elem = elem; - chand->AddQueuedPick(&calld->pick, calld->pollent); + pick_queued_ = true; + pick_.elem = elem; + chand->AddQueuedPick(&pick_, pollent_); // Register call combiner cancellation callback. - calld->pick_canceller = grpc_core::New(elem); + pick_canceller_ = New(elem); } -// Applies service config to the call. Must be invoked once we know -// that the resolver has returned results to the channel. -static void apply_service_config_to_call_locked(grpc_call_element* elem) { +void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) { ChannelData* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call", - chand, calld); + chand, this); } - calld->retry_throttle_data = chand->retry_throttle_data(); - calld->method_params = chand->GetMethodParams(calld->path); - if (calld->method_params != nullptr) { + retry_throttle_data_ = chand->retry_throttle_data(); + method_params_ = chand->GetMethodParams(path_); + if (method_params_ != nullptr) { // If the deadline from the service config is shorter than the one // from the client API, reset the deadline timer. - if (chand->deadline_checking_enabled() && - calld->method_params->timeout() != 0) { + if (chand->deadline_checking_enabled() && method_params_->timeout() != 0) { const grpc_millis per_method_deadline = - grpc_timespec_to_millis_round_up(calld->call_start_time) + - calld->method_params->timeout(); - if (per_method_deadline < calld->deadline) { - calld->deadline = per_method_deadline; - grpc_deadline_state_reset(elem, calld->deadline); + grpc_timespec_to_millis_round_up(call_start_time_) + + method_params_->timeout(); + if (per_method_deadline < deadline_) { + deadline_ = per_method_deadline; + grpc_deadline_state_reset(elem, deadline_); } } // If the service config set wait_for_ready and the application // did not explicitly set it, use the value from the service config. uint32_t* send_initial_metadata_flags = - &calld->pending_batches[0] + &pending_batches_[0] .batch->payload->send_initial_metadata.send_initial_metadata_flags; - if (GPR_UNLIKELY(calld->method_params->wait_for_ready() != + if (GPR_UNLIKELY(method_params_->wait_for_ready() != ClientChannelMethodParams::WAIT_FOR_READY_UNSET && !(*send_initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET))) { - if (calld->method_params->wait_for_ready() == + if (method_params_->wait_for_ready() == ClientChannelMethodParams::WAIT_FOR_READY_TRUE) { *send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY; } else { @@ -2958,26 +3111,23 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) { } // If no retry policy, disable retries. // TODO(roth): Remove this when adding support for transparent retries. - if (calld->method_params == nullptr || - calld->method_params->retry_policy() == nullptr) { - calld->enable_retries = false; + if (method_params_ == nullptr || method_params_->retry_policy() == nullptr) { + enable_retries_ = false; } } -// Invoked once resolver results are available. -static void maybe_apply_service_config_to_call_locked(grpc_call_element* elem) { +void CallData::MaybeApplyServiceConfigToCallLocked(grpc_call_element* elem) { ChannelData* chand = static_cast(elem->channel_data); - 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->received_service_config_data() && - !calld->service_config_applied)) { - calld->service_config_applied = true; - apply_service_config_to_call_locked(elem); + !service_config_applied_)) { + service_config_applied_ = true; + ApplyServiceConfigToCallLocked(elem); } } -static const char* pick_result_name(LoadBalancingPolicy::PickResult result) { +const char* PickResultName(LoadBalancingPolicy::PickResult result) { switch (result) { case LoadBalancingPolicy::PICK_COMPLETE: return "COMPLETE"; @@ -2989,47 +3139,47 @@ static const char* pick_result_name(LoadBalancingPolicy::PickResult result) { GPR_UNREACHABLE_CODE(return "UNKNOWN"); } -static void start_pick_locked(void* arg, grpc_error* error) { +void CallData::StartPickLocked(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); - call_data* calld = static_cast(elem->call_data); + CallData* calld = static_cast(elem->call_data); ChannelData* chand = static_cast(elem->channel_data); - GPR_ASSERT(calld->pick.pick.connected_subchannel == nullptr); - GPR_ASSERT(calld->subchannel_call == nullptr); + GPR_ASSERT(calld->pick_.pick.connected_subchannel == nullptr); + GPR_ASSERT(calld->subchannel_call_ == nullptr); // 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 - // list, as set by get_batch_index() above. + // list, as set by GetBatchIndex() above. // TODO(roth): What if the LB policy needs to add something to the // call's initial metadata, and then there's a retry? We don't want // the new metadata to be added twice. We might need to somehow // 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 = - calld->seen_send_initial_metadata - ? &calld->send_initial_metadata - : calld->pending_batches[0] + 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* send_initial_metadata_flags = - calld->seen_send_initial_metadata - ? &calld->send_initial_metadata_flags - : &calld->pending_batches[0] + 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); + calld->MaybeApplyServiceConfigToCallLocked(elem); // When done, we schedule this closure to leave the data plane combiner. - GRPC_CLOSURE_INIT(&calld->pick_closure, pick_done, elem, + GRPC_CLOSURE_INIT(&calld->pick_closure_, PickDone, elem, grpc_schedule_on_exec_ctx); // Attempt pick. error = GRPC_ERROR_NONE; - auto pick_result = chand->picker()->Pick(&calld->pick.pick, &error); + auto pick_result = chand->picker()->Pick(&calld->pick_.pick, &error); if (grpc_client_channel_routing_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(), + chand, calld, PickResultName(pick_result), + calld->pick_.pick.connected_subchannel.get(), grpc_error_string(error)); } switch (pick_result) { @@ -3038,7 +3188,7 @@ static void start_pick_locked(void* arg, grpc_error* error) { grpc_error* disconnect_error = chand->disconnect_error(); if (disconnect_error != GRPC_ERROR_NONE) { GRPC_ERROR_UNREF(error); - GRPC_CLOSURE_SCHED(&calld->pick_closure, + GRPC_CLOSURE_SCHED(&calld->pick_closure_, GRPC_ERROR_REF(disconnect_error)); break; } @@ -3048,18 +3198,18 @@ static void start_pick_locked(void* arg, grpc_error* error) { 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_get_status(error, calld->deadline_, &status, nullptr, + nullptr, nullptr); + if (!calld->enable_retries_ || + !calld->MaybeRetry(elem, nullptr /* batch_data */, status, + nullptr /* server_pushback_md */)) { grpc_error* new_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Failed to pick subchannel", &error, 1); GRPC_ERROR_UNREF(error); - GRPC_CLOSURE_SCHED(&calld->pick_closure, new_error); + GRPC_CLOSURE_SCHED(&calld->pick_closure_, new_error); } - if (calld->pick_queued) remove_call_from_queued_picks_locked(elem); + if (calld->pick_queued_) calld->RemoveCallFromQueuedPicksLocked(elem); break; } // If wait_for_ready is true, then queue to retry when we get a new @@ -3068,151 +3218,36 @@ static void start_pick_locked(void* arg, grpc_error* error) { } // Fallthrough case LoadBalancingPolicy::PICK_QUEUE: - if (!calld->pick_queued) add_call_to_queued_picks_locked(elem); + if (!calld->pick_queued_) calld->AddCallToQueuedPicksLocked(elem); break; default: // PICK_COMPLETE // Handle drops. - if (GPR_UNLIKELY(calld->pick.pick.connected_subchannel == nullptr)) { + 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); + GRPC_CLOSURE_SCHED(&calld->pick_closure_, error); + if (calld->pick_queued_) calld->RemoveCallFromQueuedPicksLocked(elem); } } -// -// filter call vtable functions -// - -static void cc_start_transport_stream_op_batch( - grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { - GPR_TIMER_SCOPE("cc_start_transport_stream_op_batch", 0); - call_data* calld = static_cast(elem->call_data); - ChannelData* chand = static_cast(elem->channel_data); - if (GPR_LIKELY(chand->deadline_checking_enabled())) { - grpc_deadline_state_client_start_transport_stream_op_batch(elem, 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_call_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: failing batch with error: %s", - chand, calld, grpc_error_string(calld->cancel_error)); - } - // 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); - return; - } - // Handle cancellation. - if (GPR_UNLIKELY(batch->cancel_stream)) { - // Stash a copy of cancel_error in our call data, so that we can use - // it for subsequent operations. This ensures that if the call is - // cancelled before any batches are passed down (e.g., if the deadline - // is in the past when the call starts), we can return the right - // error to the caller when the first batch does get passed down. - GRPC_ERROR_UNREF(calld->cancel_error); - calld->cancel_error = - GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error); - 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)); - } - // If we do not have a subchannel call (i.e., a pick has not yet - // 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); - // 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); - } else { - // Note: This will release the call combiner. - calld->subchannel_call->StartTransportStreamOpBatch(batch); - } - return; - } - // Add the batch to the pending list. - pending_batches_add(elem, batch); - // Check if we've already gotten a subchannel call. - // Note that once we have completed the pick, we do not need to enter - // the channel combiner, which is more efficient (especially for - // streaming calls). - if (calld->subchannel_call != nullptr) { - 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()); - } - pending_batches_resume(elem); - return; - } - // We do not yet have a subchannel call. - // 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_call_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: entering client_channel combiner", - chand, calld); - } - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_INIT( - &batch->handler_private.closure, start_pick_locked, elem, - grpc_combiner_scheduler(chand->data_plane_combiner())), - GRPC_ERROR_NONE); - } else { - // For all other batches, release the call combiner. - if (grpc_client_channel_call_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: saved batch, yielding call combiner", chand, - calld); - } - GRPC_CALL_COMBINER_STOP(calld->call_combiner, - "batch does not include send_initial_metadata"); - } -} - -/* Constructor for call_data */ -static grpc_error* cc_init_call_elem(grpc_call_element* elem, - const grpc_call_element_args* args) { - ChannelData* chand = static_cast(elem->channel_data); - new (elem->call_data) call_data(elem, *chand, *args); - return GRPC_ERROR_NONE; -} - -/* Destructor for call_data */ -static void cc_destroy_call_elem(grpc_call_element* elem, - const grpc_call_final_info* final_info, - 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); - then_schedule_closure = nullptr; - } - calld->~call_data(); - GRPC_CLOSURE_SCHED(then_schedule_closure, GRPC_ERROR_NONE); -} - -static void cc_set_pollset_or_pollset_set(grpc_call_element* elem, - grpc_polling_entity* pollent) { - call_data* calld = static_cast(elem->call_data); - calld->pollent = pollent; -} +} // namespace +} // namespace grpc_core /************************************************************************* * EXPORTED SYMBOLS */ +using grpc_core::CallData; +using grpc_core::ChannelData; + const grpc_channel_filter grpc_client_channel_filter = { - cc_start_transport_stream_op_batch, + CallData::StartTransportStreamOpBatch, ChannelData::StartTransportOp, - sizeof(call_data), - cc_init_call_elem, - cc_set_pollset_or_pollset_set, - cc_destroy_call_elem, + sizeof(CallData), + CallData::Init, + CallData::SetPollent, + CallData::Destroy, sizeof(ChannelData), ChannelData::Init, ChannelData::Destroy, @@ -3257,6 +3292,6 @@ void grpc_client_channel_watch_connectivity_state( 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; + auto* calld = static_cast(elem->call_data); + return calld->subchannel_call(); } From 2f2899203bd1059f47aea91d5ddccc0611f44b79 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 19 Apr 2019 09:41:23 -0700 Subject: [PATCH 1895/2143] Make cares resolver opt-in with libuv --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 8 ++++++++ 1 file changed, 8 insertions(+) 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 3f1a700c3d6..ee7929b8d39 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 @@ -429,10 +429,18 @@ static grpc_error* blocking_resolve_address_ares( static grpc_address_resolver_vtable ares_resolver = { grpc_resolve_address_ares, blocking_resolve_address_ares}; +#ifdef GRPC_UV +/* TODO(murgatroid99): Remove this when we want the cares resolver to be the + * default when using libuv */ +static bool should_use_ares(const char* resolver_env) { + return resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0; +} +#else /* GRPC_UV */ static bool should_use_ares(const char* resolver_env) { return resolver_env == nullptr || strlen(resolver_env) == 0 || gpr_stricmp(resolver_env, "ares") == 0; } +#endif /* GRPC_UV */ void grpc_resolver_dns_ares_init() { char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); From d48b0d2879b62b02c747fdac814c65fcb3c30de2 Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Fri, 19 Apr 2019 10:01:50 -0700 Subject: [PATCH 1896/2143] Created consolidated xds picker that stored and picks from the locality pickers --- .../client_channel/lb_policy/xds/xds.cc | 161 ++++++++++++++++-- 1 file changed, 143 insertions(+), 18 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 dd782ac53c3..000de59448b 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,6 +118,7 @@ namespace { constexpr char kXds[] = "xds_experimental"; constexpr char kDefaultLocalityName[] = "xds_default_locality"; +constexpr uint32_t kDefaultLocalityWeight = 3; class XdsLb : public LoadBalancingPolicy { public: @@ -259,26 +260,51 @@ class XdsLb : public LoadBalancingPolicy { bool retry_timer_callback_pending_ = false; }; + // Since pickers are UniquePtrs we use this RefCounted wrapper + // to control references to it by the xds picker and the locality + // entry + class PickerRef : public RefCounted { + public: + explicit PickerRef(UniquePtr picker) + : picker_(std::move(picker)) {} + PickResult Pick(PickArgs* pick, grpc_error** error) { + return picker_->Pick(pick, error); + } + + private: + UniquePtr picker_; + }; + + // The picker will use a stateless weighting algorithm to pick the locality to + // use for each request. class Picker : public SubchannelPicker { public: - Picker(UniquePtr child_picker, - RefCountedPtr client_stats) - : child_picker_(std::move(child_picker)), - client_stats_(std::move(client_stats)) {} + // Maintains a weighted list of pickers from each locality that is in ready + // state. The first element in the pair represents the end of a range + // proportional to the locality's weight. The start of the range is the + // previous value in the vector and is 0 for the first element. + using PickerList = + InlinedVector>, 1>; + Picker(RefCountedPtr client_stats, PickerList pickers) + : client_stats_(std::move(client_stats)), + pickers_(std::move(pickers)) {} PickResult Pick(PickArgs* pick, grpc_error** error) override; private: - UniquePtr child_picker_; + // Calls the picker of the locality that the key falls within + PickResult PickFromLocality(const uint32_t key, PickArgs* pick, + grpc_error** error); RefCountedPtr client_stats_; + PickerList pickers_; }; class LocalityMap { public: class LocalityEntry : public InternallyRefCounted { public: - explicit LocalityEntry(RefCountedPtr parent) - : parent_(std::move(parent)) {} + LocalityEntry(RefCountedPtr parent, uint32_t locality_weight) + : parent_(std::move(parent)), locality_weight_(locality_weight) {} ~LocalityEntry() = default; void UpdateLocked(xds_grpclb_serverlist* serverlist, @@ -323,6 +349,9 @@ class XdsLb : public LoadBalancingPolicy { // pending_child_policy_. Mutex child_policy_mu_; RefCountedPtr parent_; + RefCountedPtr picker_ref_; + grpc_connectivity_state connectivity_state_; + uint32_t locality_weight_; }; void UpdateLocked(const LocalityList& locality_list, @@ -346,7 +375,9 @@ class XdsLb : public LoadBalancingPolicy { gpr_free(locality_name); xds_grpclb_destroy_serverlist(serverlist); } + char* locality_name; + uint32_t locality_weight; // The deserialized response from the balancer. May be nullptr until one // such response has arrived. xds_grpclb_serverlist* serverlist; @@ -412,6 +443,8 @@ class XdsLb : public LoadBalancingPolicy { RefCountedPtr child_policy_config_; // Map of policies to use in the backend LocalityMap locality_map_; + // TODO(mhaidry) : Add support for multiple maps of localities + // with different priorities LocalityList locality_serverlist_; // TODO(mhaidry) : Add a pending locality map that may be swapped with the // the current one when new localities in the pending map are ready @@ -424,8 +457,12 @@ class XdsLb : public LoadBalancingPolicy { 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); + // Generate a random number between 0 and the total weight + const uint32_t key = + (rand() * pickers_[pickers_.size() - 1].first) / RAND_MAX; + // Forward pick to whichever locality maps to the range in which the + // random number falls in. + PickResult result = PickFromLocality(key, pick, error); // If pick succeeded, add client stats. if (result == PickResult::PICK_COMPLETE && pick->connected_subchannel != nullptr && client_stats_ != nullptr) { @@ -434,6 +471,29 @@ XdsLb::PickResult XdsLb::Picker::Pick(PickArgs* pick, grpc_error** error) { return result; } +XdsLb::PickResult XdsLb::Picker::PickFromLocality(const uint32_t key, + PickArgs* pick, + grpc_error** error) { + size_t mid = 0; + size_t start_index = 0; + size_t end_index = pickers_.size() - 1; + size_t index = 0; + while (end_index > start_index) { + mid = (start_index + end_index) / 2; + if (pickers_[mid].first > key) { + end_index = mid; + } else if (pickers_[mid].first < key) { + start_index = mid + 1; + } else { + index = mid + 1; + break; + } + } + if (index == 0) index = start_index; + GPR_ASSERT(pickers_[index].first > key); + return pickers_[index].second->Pick(pick, error); +} + // // serverlist parsing code // @@ -935,6 +995,8 @@ void XdsLb::BalancerChannelState::BalancerCallState:: MakeUnique()); xdslb_policy->locality_serverlist_[0]->locality_name = static_cast(gpr_strdup(kDefaultLocalityName)); + xdslb_policy->locality_serverlist_[0]->locality_weight = + kDefaultLocalityWeight; } // and update the copy in the XdsLb instance. This // serverlist instance will be destroyed either upon the next @@ -1316,8 +1378,8 @@ void XdsLb::LocalityMap::UpdateLocked( gpr_strdup(locality_serverlist[i]->locality_name)); auto iter = map_.find(locality_name); if (iter == map_.end()) { - OrphanablePtr new_entry = - MakeOrphanable(parent->Ref()); + OrphanablePtr new_entry = MakeOrphanable( + parent->Ref(), locality_serverlist[i]->locality_weight); MutexLock lock(&child_refs_mu_); iter = map_.emplace(std::move(locality_name), std::move(new_entry)).first; } @@ -1335,8 +1397,8 @@ void grpc_core::XdsLb::LocalityMap::ShutdownLocked() { } void grpc_core::XdsLb::LocalityMap::ResetBackoffLocked() { - for (auto iter = map_.begin(); iter != map_.end(); iter++) { - iter->second->ResetBackoffLocked(); + for (auto& p : map_) { + p.second->ResetBackoffLocked(); } } @@ -1344,8 +1406,8 @@ void grpc_core::XdsLb::LocalityMap::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { MutexLock lock(&child_refs_mu_); - for (auto iter = map_.begin(); iter != map_.end(); iter++) { - iter->second->FillChildRefsForChannelz(child_subchannels, child_channels); + for (auto& p : map_) { + p.second->FillChildRefsForChannelz(child_subchannels, child_channels); } } @@ -1617,9 +1679,72 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState( entry_->parent_->lb_chand_->lb_calld() == nullptr ? nullptr : entry_->parent_->lb_chand_->lb_calld()->client_stats(); - entry_->parent_->channel_control_helper()->UpdateState( - state, UniquePtr( - New(std::move(picker), std::move(client_stats)))); + // Cache the picker and its state in the entry + entry_->picker_ref_ = MakeRefCounted(std::move(picker)); + entry_->connectivity_state_ = state; + // Construct a new xds picker which maintains a map of all locality pickers + // that are ready. Each locality is represented by a portion of the range + // proportional to its weight, such that the total range is the sum of the + // weights of all localities + uint32_t end = 0; + size_t num_connecting = 0; + size_t num_idle = 0; + size_t num_transient_failures = 0; + auto& locality_map = this->entry_->parent_->locality_map_.map_; + Picker::PickerList pickers; + for (auto& p : locality_map) { + const LocalityEntry* entry = p.second.get(); + grpc_connectivity_state connectivity_state = entry->connectivity_state_; + switch (connectivity_state) { + case GRPC_CHANNEL_READY: { + end += entry->locality_weight_; + pickers.push_back(MakePair(end, entry->picker_ref_)); + break; + } + case GRPC_CHANNEL_CONNECTING: { + num_connecting++; + break; + } + case GRPC_CHANNEL_IDLE: { + num_idle++; + break; + } + case GRPC_CHANNEL_TRANSIENT_FAILURE: { + num_transient_failures++; + break; + } + default: { + gpr_log(GPR_ERROR, "Invalid locality connectivity state - %d", + connectivity_state); + } + } + } + // Pass on the constructed xds picker if it has any ready pickers in their map + // otherwise pass a QueuePicker if any of the locality pickers are in a + // connecting or idle state, finally return a transient failure picker if all + // locality pickers are in transient failure + if (pickers.size() > 0) { + entry_->parent_->channel_control_helper()->UpdateState( + GRPC_CHANNEL_READY, + UniquePtr( + New(std::move(client_stats), std::move(pickers)))); + } else if (num_connecting > 0) { + entry_->parent_->channel_control_helper()->UpdateState( + GRPC_CHANNEL_CONNECTING, + UniquePtr(New(this->entry_->parent_))); + } else if (num_idle > 0) { + entry_->parent_->channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, + UniquePtr(New(this->entry_->parent_))); + } else { + GPR_ASSERT(num_transient_failures == locality_map.size()); + grpc_error* error = + grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "connections to all localities failing"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + entry_->parent_->channel_control_helper()->UpdateState( + state, UniquePtr(New(error))); + } } void XdsLb::LocalityMap::LocalityEntry::Helper::RequestReresolution() { From a36040d51c5f413a8987a508a60527e897531ece Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 19 Apr 2019 10:25:45 -0700 Subject: [PATCH 1897/2143] Clang format --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 2 +- .../dns/c_ares/grpc_ares_ev_driver_libuv.cc | 22 +++++++++---------- .../dns/c_ares/grpc_ares_wrapper_libuv.cc | 6 ++--- 3 files changed, 14 insertions(+), 16 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 ee7929b8d39..ec662b1416d 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 @@ -435,7 +435,7 @@ static grpc_address_resolver_vtable ares_resolver = { static bool should_use_ares(const char* resolver_env) { return resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0; } -#else /* GRPC_UV */ +#else /* GRPC_UV */ static bool should_use_ares(const char* resolver_env) { return resolver_env == nullptr || strlen(resolver_env) == 0 || gpr_stricmp(resolver_env, "ares") == 0; diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc index fd09d899187..6993edf8a01 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -36,22 +36,18 @@ namespace grpc_core { void ares_uv_poll_cb(uv_poll_t* handle, int status, int events); -void ares_uv_poll_close_cb(uv_handle_t *handle) { - Delete(handle); -} +void ares_uv_poll_close_cb(uv_handle_t* handle) { Delete(handle); } class GrpcPolledFdLibuv : public GrpcPolledFd { public: - GrpcPolledFdLibuv(ares_socket_t as): as_(as) { + GrpcPolledFdLibuv(ares_socket_t as) : as_(as) { gpr_asprintf(&name_, "c-ares socket: %" PRIdPTR, (intptr_t)as); handle_ = New(); uv_poll_init_socket(uv_default_loop(), handle_, as); handle_->data = this; } - ~GrpcPolledFdLibuv() { - gpr_free(name_); - } + ~GrpcPolledFdLibuv() { gpr_free(name_); } void RegisterForOnReadableLocked(grpc_closure* read_closure) override { GPR_ASSERT(read_closure_ == nullptr); @@ -94,12 +90,14 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { grpc_core::ExecCtx exec_ctx; - GrpcPolledFdLibuv* polled_fd = reinterpret_cast(handle->data); - grpc_error *error = GRPC_ERROR_NONE; + GrpcPolledFdLibuv* polled_fd = + reinterpret_cast(handle->data); + grpc_error* error = GRPC_ERROR_NONE; if (status < 0) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("cares polling error"); - error = grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, - grpc_slice_from_static_string(uv_strerror(status))); + error = + grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, + grpc_slice_from_static_string(uv_strerror(status))); } if ((events & UV_READABLE) && polled_fd->read_closure_) { GRPC_CLOSURE_SCHED(polled_fd->read_closure_, error); @@ -129,6 +127,6 @@ UniquePtr NewGrpcPolledFdFactory(grpc_combiner* combiner) { return UniquePtr(New()); } -} // namespace grpc_core +} // namespace grpc_core #endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ \ No newline at end of file diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc index eb8d7e5e900..08f3d9ce30d 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -29,11 +29,11 @@ #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -bool grpc_ares_query_ipv6() { +bool grpc_ares_query_ipv6() { /* The libuv grpc code currently does not have the code to probe for this, - * so we assume for nowthat IPv6 is always available in contexts where this + * so we assume for now that IPv6 is always available in contexts where this * code will be used. */ - return true; + return true; } /* The following two functions were copied entirely from the Windows file. This From 1ab9ffe5c030b88bd10f70d7bab3cff6ffd0e7a9 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 19 Apr 2019 11:34:19 -0700 Subject: [PATCH 1898/2143] Do not add message size filter for minimal stack --- .../message_size/message_size_filter.cc | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) 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 146cb5d23f3..dca3f2e2fd2 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -368,7 +368,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); + chand->svc_cfg.reset(); +} const grpc_channel_filter grpc_message_size_filter = { start_transport_stream_op_batch, @@ -384,8 +387,13 @@ const grpc_channel_filter grpc_message_size_filter = { "message_size"}; // Used for GRPC_CLIENT_SUBCHANNEL -static bool add_message_size_filter(grpc_channel_stack_builder* builder, - void* arg) { +static bool maybe_add_message_size_filter_subchannel( + grpc_channel_stack_builder* builder, void* arg) { + const grpc_channel_args* channel_args = + grpc_channel_stack_builder_get_channel_arguments(builder); + if (grpc_channel_args_want_minimal_stack(channel_args)) { + return true; + } return grpc_channel_stack_builder_prepend_filter( builder, &grpc_message_size_filter, nullptr, nullptr); } @@ -417,9 +425,9 @@ static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder, } void grpc_message_size_filter_init(void) { - grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, - GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, - add_message_size_filter, nullptr); + grpc_channel_init_register_stage( + GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + maybe_add_message_size_filter_subchannel, nullptr); grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_message_size_filter, nullptr); From 7f42728fd9ac4b00e6c505c99ca0a16458d67b17 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Thu, 18 Apr 2019 16:01:48 -0700 Subject: [PATCH 1899/2143] Fast-pathed grpc_mdelem_eq for known static cases. --- .../filters/http/client/http_client_filter.cc | 8 ++-- .../filters/http/server/http_server_filter.cc | 39 +++++++++++-------- .../chttp2/transport/chttp2_transport.cc | 4 +- src/core/lib/transport/metadata.h | 4 ++ src/core/lib/transport/status_metadata.cc | 6 +-- 5 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/core/ext/filters/http/client/http_client_filter.cc b/src/core/ext/filters/http/client/http_client_filter.cc index bf9a01f659b..15a69de74f7 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -107,7 +107,8 @@ static grpc_error* client_filter_incoming_metadata(grpc_call_element* elem, * https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md. */ if (b->idx.named.grpc_status != nullptr || - grpc_mdelem_eq(b->idx.named.status->md, GRPC_MDELEM_STATUS_200)) { + grpc_mdelem_eq_static(b->idx.named.status->md, + GRPC_MDELEM_STATUS_200)) { grpc_metadata_batch_remove(b, b->idx.named.status); } else { char* val = grpc_dump_slice(GRPC_MDVALUE(b->idx.named.status->md), @@ -140,8 +141,9 @@ static grpc_error* client_filter_incoming_metadata(grpc_call_element* elem, } if (b->idx.named.content_type != nullptr) { - if (!grpc_mdelem_eq(b->idx.named.content_type->md, - GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) { + if (!grpc_mdelem_eq_static( + b->idx.named.content_type->md, + GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) { if (grpc_slice_buf_start_eq(GRPC_MDVALUE(b->idx.named.content_type->md), EXPECTED_CONTENT_TYPE, EXPECTED_CONTENT_TYPE_LENGTH) && diff --git a/src/core/ext/filters/http/server/http_server_filter.cc b/src/core/ext/filters/http/server/http_server_filter.cc index ce1be8370c6..da32fe6bdb9 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -131,22 +131,23 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, static const char* error_name = "Failed processing incoming headers"; if (b->idx.named.method != nullptr) { - if (grpc_mdelem_eq(b->idx.named.method->md, GRPC_MDELEM_METHOD_POST)) { - *calld->recv_initial_metadata_flags &= - ~(GRPC_INITIAL_METADATA_CACHEABLE_REQUEST | - GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST); - } else if (grpc_mdelem_eq(b->idx.named.method->md, - GRPC_MDELEM_METHOD_PUT)) { - *calld->recv_initial_metadata_flags &= - ~GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; - *calld->recv_initial_metadata_flags |= - GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; - } else if (grpc_mdelem_eq(b->idx.named.method->md, + if (grpc_mdelem_eq_static(b->idx.named.method->md, GRPC_MDELEM_METHOD_GET)) { *calld->recv_initial_metadata_flags |= GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; *calld->recv_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; + } else if (grpc_mdelem_eq_static(b->idx.named.method->md, + GRPC_MDELEM_METHOD_POST)) { + *calld->recv_initial_metadata_flags &= + ~(GRPC_INITIAL_METADATA_CACHEABLE_REQUEST | + GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST); + } else if (grpc_mdelem_eq_static(b->idx.named.method->md, + GRPC_MDELEM_METHOD_PUT)) { + *calld->recv_initial_metadata_flags &= + ~GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; + *calld->recv_initial_metadata_flags |= + GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; } else { hs_add_error(error_name, &error, grpc_attach_md_to_error( @@ -163,7 +164,7 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, } if (b->idx.named.te != nullptr) { - if (!grpc_mdelem_eq(b->idx.named.te->md, GRPC_MDELEM_TE_TRAILERS)) { + if (!grpc_mdelem_eq_static(b->idx.named.te->md, GRPC_MDELEM_TE_TRAILERS)) { hs_add_error(error_name, &error, grpc_attach_md_to_error( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"), @@ -178,9 +179,12 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, } if (b->idx.named.scheme != nullptr) { - if (!grpc_mdelem_eq(b->idx.named.scheme->md, GRPC_MDELEM_SCHEME_HTTP) && - !grpc_mdelem_eq(b->idx.named.scheme->md, GRPC_MDELEM_SCHEME_HTTPS) && - !grpc_mdelem_eq(b->idx.named.scheme->md, GRPC_MDELEM_SCHEME_GRPC)) { + if (!grpc_mdelem_eq_static(b->idx.named.scheme->md, + GRPC_MDELEM_SCHEME_HTTP) && + !grpc_mdelem_eq_static(b->idx.named.scheme->md, + GRPC_MDELEM_SCHEME_HTTPS) && + !grpc_mdelem_eq_static(b->idx.named.scheme->md, + GRPC_MDELEM_SCHEME_GRPC)) { hs_add_error(error_name, &error, grpc_attach_md_to_error( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"), @@ -196,8 +200,9 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, } if (b->idx.named.content_type != nullptr) { - if (!grpc_mdelem_eq(b->idx.named.content_type->md, - GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) { + if (!grpc_mdelem_eq_static( + b->idx.named.content_type->md, + GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) { if (grpc_slice_buf_start_eq(GRPC_MDVALUE(b->idx.named.content_type->md), EXPECTED_CONTENT_TYPE, EXPECTED_CONTENT_TYPE_LENGTH) && diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 07659bb09bb..addac7ab6ef 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1281,8 +1281,8 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, static bool contains_non_ok_status(grpc_metadata_batch* batch) { if (batch->idx.named.grpc_status != nullptr) { - return !grpc_mdelem_eq(batch->idx.named.grpc_status->md, - GRPC_MDELEM_GRPC_STATUS_0); + return !grpc_mdelem_eq_static(batch->idx.named.grpc_status->md, + GRPC_MDELEM_GRPC_STATUS_0); } return false; } diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 989c7544c1f..b58189fb2bf 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -126,6 +126,10 @@ grpc_mdelem grpc_mdelem_create( bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b); +inline bool grpc_mdelem_eq_static(grpc_mdelem a_static, grpc_mdelem b_static) { + return a_static.payload == b_static.payload; +} + /* Mutator and accessor for grpc_mdelem user data. The destructor function is used as a type tag and is checked during user_data fetch. */ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*if_destroy_func)(void*)); diff --git a/src/core/lib/transport/status_metadata.cc b/src/core/lib/transport/status_metadata.cc index f896053e4da..8b46fe29f1f 100644 --- a/src/core/lib/transport/status_metadata.cc +++ b/src/core/lib/transport/status_metadata.cc @@ -31,13 +31,13 @@ static void destroy_status(void* ignored) {} grpc_status_code grpc_get_status_code_from_metadata(grpc_mdelem md) { - if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { + if (grpc_mdelem_eq_static(md, GRPC_MDELEM_GRPC_STATUS_0)) { return GRPC_STATUS_OK; } - if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_1)) { + if (grpc_mdelem_eq_static(md, GRPC_MDELEM_GRPC_STATUS_1)) { return GRPC_STATUS_CANCELLED; } - if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_2)) { + if (grpc_mdelem_eq_static(md, GRPC_MDELEM_GRPC_STATUS_2)) { return GRPC_STATUS_UNKNOWN; } void* user_data = grpc_mdelem_get_user_data(md, destroy_status); From 4e24b0e4dce7cdd9f45ee0e2178721f08cfed86a Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Thu, 18 Apr 2019 17:53:56 -0700 Subject: [PATCH 1900/2143] Bugfix - fixed assumptions --- src/core/lib/transport/metadata.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index b58189fb2bf..949870f2a89 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -126,10 +126,6 @@ grpc_mdelem grpc_mdelem_create( bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b); -inline bool grpc_mdelem_eq_static(grpc_mdelem a_static, grpc_mdelem b_static) { - return a_static.payload == b_static.payload; -} - /* Mutator and accessor for grpc_mdelem user data. The destructor function is used as a type tag and is checked during user_data fetch. */ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*if_destroy_func)(void*)); @@ -164,4 +160,9 @@ void grpc_mdelem_unref(grpc_mdelem md); void grpc_mdctx_global_init(void); void grpc_mdctx_global_shutdown(); +inline bool grpc_mdelem_eq_static(grpc_mdelem a_static, grpc_mdelem b_static) { + if (a_static.payload == b_static.payload) return true; + return grpc_slice_eq(GRPC_MDVALUE(a_static), GRPC_MDVALUE(b_static)); +} + #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */ From e9a79f928c1c820b6661cc2e4a5343931c38fab7 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Fri, 19 Apr 2019 12:13:11 -0700 Subject: [PATCH 1901/2143] Address initial comments --- .../filters/http/client/http_client_filter.cc | 6 +-- .../filters/http/server/http_server_filter.cc | 37 ++++++++++--------- .../chttp2/transport/chttp2_transport.cc | 4 +- src/core/lib/transport/metadata.h | 19 ++++++---- src/core/lib/transport/status_metadata.cc | 6 +-- 5 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/core/ext/filters/http/client/http_client_filter.cc b/src/core/ext/filters/http/client/http_client_filter.cc index 15a69de74f7..ed90be23e4b 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -107,8 +107,8 @@ static grpc_error* client_filter_incoming_metadata(grpc_call_element* elem, * https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md. */ if (b->idx.named.grpc_status != nullptr || - grpc_mdelem_eq_static(b->idx.named.status->md, - GRPC_MDELEM_STATUS_200)) { + grpc_mdelem_static_value_eq(b->idx.named.status->md, + GRPC_MDELEM_STATUS_200)) { grpc_metadata_batch_remove(b, b->idx.named.status); } else { char* val = grpc_dump_slice(GRPC_MDVALUE(b->idx.named.status->md), @@ -141,7 +141,7 @@ static grpc_error* client_filter_incoming_metadata(grpc_call_element* elem, } if (b->idx.named.content_type != nullptr) { - if (!grpc_mdelem_eq_static( + if (!grpc_mdelem_static_value_eq( b->idx.named.content_type->md, GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) { if (grpc_slice_buf_start_eq(GRPC_MDVALUE(b->idx.named.content_type->md), diff --git a/src/core/ext/filters/http/server/http_server_filter.cc b/src/core/ext/filters/http/server/http_server_filter.cc index da32fe6bdb9..443a356452a 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -131,23 +131,23 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, static const char* error_name = "Failed processing incoming headers"; if (b->idx.named.method != nullptr) { - if (grpc_mdelem_eq_static(b->idx.named.method->md, - GRPC_MDELEM_METHOD_GET)) { - *calld->recv_initial_metadata_flags |= - GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; - *calld->recv_initial_metadata_flags &= - ~GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; - } else if (grpc_mdelem_eq_static(b->idx.named.method->md, - GRPC_MDELEM_METHOD_POST)) { + if (grpc_mdelem_static_value_eq(b->idx.named.method->md, + GRPC_MDELEM_METHOD_POST)) { *calld->recv_initial_metadata_flags &= ~(GRPC_INITIAL_METADATA_CACHEABLE_REQUEST | GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST); - } else if (grpc_mdelem_eq_static(b->idx.named.method->md, - GRPC_MDELEM_METHOD_PUT)) { + } else if (grpc_mdelem_static_value_eq(b->idx.named.method->md, + GRPC_MDELEM_METHOD_PUT)) { *calld->recv_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; *calld->recv_initial_metadata_flags |= GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; + } else if (grpc_mdelem_static_value_eq(b->idx.named.method->md, + GRPC_MDELEM_METHOD_GET)) { + *calld->recv_initial_metadata_flags |= + GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; + *calld->recv_initial_metadata_flags &= + ~GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; } else { hs_add_error(error_name, &error, grpc_attach_md_to_error( @@ -164,7 +164,8 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, } if (b->idx.named.te != nullptr) { - if (!grpc_mdelem_eq_static(b->idx.named.te->md, GRPC_MDELEM_TE_TRAILERS)) { + if (!grpc_mdelem_static_value_eq(b->idx.named.te->md, + GRPC_MDELEM_TE_TRAILERS)) { hs_add_error(error_name, &error, grpc_attach_md_to_error( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"), @@ -179,12 +180,12 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, } if (b->idx.named.scheme != nullptr) { - if (!grpc_mdelem_eq_static(b->idx.named.scheme->md, - GRPC_MDELEM_SCHEME_HTTP) && - !grpc_mdelem_eq_static(b->idx.named.scheme->md, - GRPC_MDELEM_SCHEME_HTTPS) && - !grpc_mdelem_eq_static(b->idx.named.scheme->md, - GRPC_MDELEM_SCHEME_GRPC)) { + if (!grpc_mdelem_static_value_eq(b->idx.named.scheme->md, + GRPC_MDELEM_SCHEME_HTTP) && + !grpc_mdelem_static_value_eq(b->idx.named.scheme->md, + GRPC_MDELEM_SCHEME_HTTPS) && + !grpc_mdelem_static_value_eq(b->idx.named.scheme->md, + GRPC_MDELEM_SCHEME_GRPC)) { hs_add_error(error_name, &error, grpc_attach_md_to_error( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"), @@ -200,7 +201,7 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, } if (b->idx.named.content_type != nullptr) { - if (!grpc_mdelem_eq_static( + if (!grpc_mdelem_static_value_eq( b->idx.named.content_type->md, GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) { if (grpc_slice_buf_start_eq(GRPC_MDVALUE(b->idx.named.content_type->md), diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index addac7ab6ef..857f7d0d34c 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1281,8 +1281,8 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, static bool contains_non_ok_status(grpc_metadata_batch* batch) { if (batch->idx.named.grpc_status != nullptr) { - return !grpc_mdelem_eq_static(batch->idx.named.grpc_status->md, - GRPC_MDELEM_GRPC_STATUS_0); + return !grpc_mdelem_static_value_eq(batch->idx.named.grpc_status->md, + GRPC_MDELEM_GRPC_STATUS_0); } return false; } diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 949870f2a89..5e016567eb2 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -124,7 +124,18 @@ grpc_mdelem grpc_mdelem_create( const grpc_slice& key, const grpc_slice& value, grpc_mdelem_data* compatible_external_backing_store); +#define GRPC_MDKEY(md) (GRPC_MDELEM_DATA(md)->key) +#define GRPC_MDVALUE(md) (GRPC_MDELEM_DATA(md)->value) + bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b); +/* Often we compare metadata where we know a-priori that the second parameter is + * static, and that the keys match. This most commonly happens when processing + * metadata batch callouts in initial/trailing filters. In this case, fastpath + * grpc_mdelem_eq and remove unnecessary checks. */ +inline bool grpc_mdelem_static_value_eq(grpc_mdelem a, grpc_mdelem b_static) { + if (a.payload == b_static.payload) return true; + return grpc_slice_eq(GRPC_MDVALUE(a), GRPC_MDVALUE(b_static)); +} /* Mutator and accessor for grpc_mdelem user data. The destructor function is used as a type tag and is checked during user_data fetch. */ @@ -144,9 +155,6 @@ grpc_mdelem grpc_mdelem_ref(grpc_mdelem md); void grpc_mdelem_unref(grpc_mdelem md); #endif -#define GRPC_MDKEY(md) (GRPC_MDELEM_DATA(md)->key) -#define GRPC_MDVALUE(md) (GRPC_MDELEM_DATA(md)->value) - #define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL) #define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL) @@ -160,9 +168,4 @@ void grpc_mdelem_unref(grpc_mdelem md); void grpc_mdctx_global_init(void); void grpc_mdctx_global_shutdown(); -inline bool grpc_mdelem_eq_static(grpc_mdelem a_static, grpc_mdelem b_static) { - if (a_static.payload == b_static.payload) return true; - return grpc_slice_eq(GRPC_MDVALUE(a_static), GRPC_MDVALUE(b_static)); -} - #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */ diff --git a/src/core/lib/transport/status_metadata.cc b/src/core/lib/transport/status_metadata.cc index 8b46fe29f1f..8ef96821c3d 100644 --- a/src/core/lib/transport/status_metadata.cc +++ b/src/core/lib/transport/status_metadata.cc @@ -31,13 +31,13 @@ static void destroy_status(void* ignored) {} grpc_status_code grpc_get_status_code_from_metadata(grpc_mdelem md) { - if (grpc_mdelem_eq_static(md, GRPC_MDELEM_GRPC_STATUS_0)) { + if (grpc_mdelem_static_value_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { return GRPC_STATUS_OK; } - if (grpc_mdelem_eq_static(md, GRPC_MDELEM_GRPC_STATUS_1)) { + if (grpc_mdelem_static_value_eq(md, GRPC_MDELEM_GRPC_STATUS_1)) { return GRPC_STATUS_CANCELLED; } - if (grpc_mdelem_eq_static(md, GRPC_MDELEM_GRPC_STATUS_2)) { + if (grpc_mdelem_static_value_eq(md, GRPC_MDELEM_GRPC_STATUS_2)) { return GRPC_STATUS_UNKNOWN; } void* user_data = grpc_mdelem_get_user_data(md, destroy_status); From 4080e7b65ff00e0c6d0edd743cb6ee4550c10048 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 17 Apr 2019 15:26:07 -0400 Subject: [PATCH 1902/2143] Retire the GRPC_ARENA_INIT_STRATEGY env variable. This is in the hot path and it is not needed anymore. Remove it for good. --- doc/environment_variables.md | 10 -------- src/core/lib/gpr/arena.cc | 50 ++++-------------------------------- src/core/lib/gpr/arena.h | 2 -- src/core/lib/surface/init.cc | 1 - 4 files changed, 5 insertions(+), 58 deletions(-) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index e8d0dbd25f8..43dcd7616e7 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -145,13 +145,3 @@ some configuration as environment variables that can be set. * grpc_cfstream set to 1 to turn on CFStream experiment. With this experiment gRPC uses CFStream API to make TCP connections. The option is only available on iOS platform and when macro GRPC_CFSTREAM is defined. - -* GRPC_ARENA_INIT_STRATEGY - Selects the initialization strategy for blocks allocated in the arena. Valid - values are: - - 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. - - NOTE: This environment variable is experimental and will be removed. Thus, it - should not be relied upon. diff --git a/src/core/lib/gpr/arena.cc b/src/core/lib/gpr/arena.cc index 836a7ca793d..ede5cc48050 100644 --- a/src/core/lib/gpr/arena.cc +++ b/src/core/lib/gpr/arena.cc @@ -29,49 +29,10 @@ #include #include "src/core/lib/gpr/alloc.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/memory.h" -namespace { -enum init_strategy { - NO_INIT, // Do not initialize the arena blocks. - ZERO_INIT, // Initialize arena blocks with 0. - NON_ZERO_INIT, // Initialize arena blocks with a non-zero value. -}; - -gpr_once g_init_strategy_once = GPR_ONCE_INIT; -init_strategy g_init_strategy = NO_INIT; -} // namespace - -static void set_strategy_from_env() { - char* str = gpr_getenv("GRPC_ARENA_INIT_STRATEGY"); - if (str == nullptr) { - g_init_strategy = NO_INIT; - } else if (strcmp(str, "zero_init") == 0) { - g_init_strategy = ZERO_INIT; - } else if (strcmp(str, "non_zero_init") == 0) { - g_init_strategy = NON_ZERO_INIT; - } else { - g_init_strategy = NO_INIT; - } - gpr_free(str); -} - -static void* gpr_arena_alloc_maybe_init(size_t size) { - void* mem = gpr_malloc_aligned(size, GPR_MAX_ALIGNMENT); - gpr_once_init(&g_init_strategy_once, set_strategy_from_env); - if (GPR_UNLIKELY(g_init_strategy != NO_INIT)) { - if (g_init_strategy == ZERO_INIT) { - memset(mem, 0, size); - } else { // NON_ZERO_INIT. - memset(mem, 0xFE, size); - } - } - return mem; -} - -void gpr_arena_init() { - gpr_once_init(&g_init_strategy_once, set_strategy_from_env); +static void* gpr_arena_malloc(size_t size) { + return gpr_malloc_aligned(size, GPR_MAX_ALIGNMENT); } // Uncomment this to use a simple arena that simply allocates the @@ -109,8 +70,7 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) { gpr_mu_lock(&arena->mu); arena->ptrs = (void**)gpr_realloc(arena->ptrs, sizeof(void*) * (arena->num_ptrs + 1)); - void* retval = arena->ptrs[arena->num_ptrs++] = - gpr_arena_alloc_maybe_init(size); + void* retval = arena->ptrs[arena->num_ptrs++] = gpr_arena_malloc(size); gpr_mu_unlock(&arena->mu); return retval; } @@ -154,7 +114,7 @@ struct gpr_arena { gpr_arena* gpr_arena_create(size_t initial_size) { initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size); - return new (gpr_arena_alloc_maybe_init( + return new (gpr_arena_malloc( GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size)) gpr_arena(initial_size); } @@ -179,7 +139,7 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) { // sizing historesis (that is, most calls should have a large enough initial // zone and will not need to grow the arena). gpr_mu_lock(&arena->arena_growth_mutex); - zone* z = new (gpr_arena_alloc_maybe_init( + zone* z = new (gpr_arena_malloc( GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + size)) zone(); arena->last_zone->next = z; arena->last_zone = z; diff --git a/src/core/lib/gpr/arena.h b/src/core/lib/gpr/arena.h index 069892b2282..6d2a073dd58 100644 --- a/src/core/lib/gpr/arena.h +++ b/src/core/lib/gpr/arena.h @@ -37,7 +37,5 @@ gpr_arena* gpr_arena_create(size_t initial_size); void* gpr_arena_alloc(gpr_arena* arena, size_t size); // Destroy an arena, returning the total number of bytes allocated size_t gpr_arena_destroy(gpr_arena* arena); -// Initializes the Arena component. -void gpr_arena_init(); #endif /* GRPC_CORE_LIB_GPR_ARENA_H */ diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 57d975564b1..1ed1a66b184 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -133,7 +133,6 @@ void grpc_init(void) { } grpc_core::Fork::GlobalInit(); grpc_fork_handlers_auto_register(); - gpr_arena_init(); grpc_stats_init(); grpc_slice_intern_init(); grpc_mdctx_global_init(); From c4a2069d9c5317f67c98689a1db43df5fa94c72f Mon Sep 17 00:00:00 2001 From: SataQiu Date: Tue, 16 Apr 2019 11:45:42 +0800 Subject: [PATCH 1903/2143] fix spelling errors of include/* --- include/grpc/grpc_security.h | 2 +- include/grpc/slice.h | 2 +- include/grpcpp/impl/codegen/completion_queue.h | 10 +++++----- include/grpcpp/impl/codegen/server_interface.h | 2 +- include/grpcpp/impl/codegen/sync_stream.h | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index f1185d2b2a6..53189097b9b 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -264,7 +264,7 @@ GRPCAPI grpc_call_credentials* grpc_google_refresh_token_credentials_create( const char* json_refresh_token, void* reserved); /** Creates an Oauth2 Access Token credentials with an access token that was - aquired by an out of band mechanism. */ + acquired by an out of band mechanism. */ GRPCAPI grpc_call_credentials* grpc_access_token_credentials_create( const char* access_token, void* reserved); diff --git a/include/grpc/slice.h b/include/grpc/slice.h index ce482922afa..192a8cfeef4 100644 --- a/include/grpc/slice.h +++ b/include/grpc/slice.h @@ -147,7 +147,7 @@ GPRAPI int grpc_slice_buf_start_eq(grpc_slice a, const void* b, size_t blen); GPRAPI int grpc_slice_rchr(grpc_slice s, char c); GPRAPI int grpc_slice_chr(grpc_slice s, char c); -/** return the index of the first occurance of \a needle in \a haystack, or -1 +/** return the index of the first occurrence of \a needle in \a haystack, or -1 if it's not found */ GPRAPI int grpc_slice_slice(grpc_slice haystack, grpc_slice needle); diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 73556ce9899..49c281b807d 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -183,8 +183,8 @@ class CompletionQueue : private GrpcLibraryCodegen { /// within the \a deadline). A \a tag points to an arbitrary location usually /// employed to uniquely identify an event. /// - /// \param tag [out] Upon sucess, updated to point to the event's tag. - /// \param ok [out] Upon sucess, true if a successful event, false otherwise + /// \param tag [out] Upon success, updated to point to the event's tag. + /// \param ok [out] Upon success, true if a successful event, false otherwise /// See documentation for CompletionQueue::Next for explanation of ok /// \param deadline [in] How long to block in wait for an event. /// @@ -203,8 +203,8 @@ class CompletionQueue : private GrpcLibraryCodegen { /// employed to uniquely identify an event. /// /// \param f [in] Function to execute before calling AsyncNext on this queue. - /// \param tag [out] Upon sucess, updated to point to the event's tag. - /// \param ok [out] Upon sucess, true if read a regular event, false + /// \param tag [out] Upon success, updated to point to the event's tag. + /// \param ok [out] Upon success, true if read a regular event, false /// otherwise. /// \param deadline [in] How long to block in wait for an event. /// @@ -362,7 +362,7 @@ class CompletionQueue : private GrpcLibraryCodegen { /// queue should not really shutdown until all avalanching operations have /// been finalized. Note that we maintain the requirement that an avalanche /// registration must take place before CQ shutdown (which must be maintained - /// elsehwere) + /// elsewhere) void InitialAvalanching() { gpr_atm_rel_store(&avalanches_in_flight_, static_cast(1)); } diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index a0b0a580979..328f4389628 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -149,7 +149,7 @@ class ServerInterface : public internal::CallHook { /// 192.168.1.1:31416, [::1]:27182, etc.). /// \params creds The credentials associated with the server. /// - /// \return bound port number on sucess, 0 on failure. + /// \return bound port number on success, 0 on failure. /// /// \warning It's an error to call this method on an already started server. virtual int AddListeningPort(const grpc::string& addr, diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index d9edad42153..0d3fdfcb8dc 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -180,7 +180,7 @@ class ClientReader final : public ClientReaderInterface { /// // Side effect: /// Once complete, the initial metadata read from - /// the server will be accessable through the \a ClientContext used to + /// the server will be accessible through the \a ClientContext used to /// construct this object. void WaitForInitialMetadata() override { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -298,7 +298,7 @@ class ClientWriter : public ClientWriterInterface { /// // Side effect: /// Once complete, the initial metadata read from the server will be - /// accessable through the \a ClientContext used to construct this object. + /// accessible through the \a ClientContext used to construct this object. void WaitForInitialMetadata() { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -449,7 +449,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { /// with or after the \a Finish method. /// /// Once complete, the initial metadata read from the server will be - /// accessable through the \a ClientContext used to construct this object. + /// accessible through the \a ClientContext used to construct this object. void WaitForInitialMetadata() override { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); From 7d946633ea97fce796578543013a205ca9810bb5 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Wed, 27 Mar 2019 11:58:11 -0700 Subject: [PATCH 1904/2143] grpc_slice_refcount devirtualization --- include/grpc/impl/codegen/slice.h | 22 +- .../chttp2/transport/hpack_encoder.cc | 2 +- .../ext/transport/chttp2/transport/writing.cc | 11 +- src/core/lib/gprpp/ref_counted.h | 16 ++ src/core/lib/iomgr/resource_quota.cc | 57 ++--- src/core/lib/slice/slice.cc | 215 ++++++++--------- src/core/lib/slice/slice_intern.cc | 133 +++-------- src/core/lib/slice/slice_internal.h | 204 +++++++++++++++- src/core/lib/transport/static_metadata.cc | 224 +++++++++--------- src/core/lib/transport/static_metadata.h | 3 +- src/core/lib/transport/transport.cc | 92 +++---- src/core/lib/transport/transport.h | 37 ++- test/core/slice/slice_test.cc | 7 - .../core/transport/stream_owned_slice_test.cc | 3 - tools/codegen/core/gen_static_metadata.py | 22 +- 15 files changed, 561 insertions(+), 487 deletions(-) diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h index 62339daae5e..3567b1e88b3 100644 --- a/include/grpc/impl/codegen/slice.h +++ b/include/grpc/impl/codegen/slice.h @@ -40,27 +40,6 @@ typedef struct grpc_slice grpc_slice; reference ownership semantics (who should call unref?) and mutability constraints (is the callee allowed to modify the slice?) */ -typedef struct grpc_slice_refcount_vtable { - void (*ref)(void*); - void (*unref)(void*); - int (*eq)(grpc_slice a, grpc_slice b); - uint32_t (*hash)(grpc_slice slice); -} grpc_slice_refcount_vtable; - -/** Reference count container for grpc_slice. Contains function pointers to - increment and decrement reference counts. Implementations should cleanup - when the reference count drops to zero. - Typically client code should not touch this, and use grpc_slice_malloc, - grpc_slice_new, or grpc_slice_new_with_len instead. */ -typedef struct grpc_slice_refcount { - const grpc_slice_refcount_vtable* vtable; - /** If a subset of this slice is taken, use this pointer for the refcount. - Typically points back to the refcount itself, however iterning - implementations can use this to avoid a verification step on each hash - or equality check */ - struct grpc_slice_refcount* sub_refcount; -} grpc_slice_refcount; - /* Inlined half of grpc_slice is allowed to expand the size of the overall type by this many bytes */ #define GRPC_SLICE_INLINE_EXTRA_SIZE sizeof(void*) @@ -68,6 +47,7 @@ typedef struct grpc_slice_refcount { #define GRPC_SLICE_INLINED_SIZE \ (sizeof(size_t) + sizeof(uint8_t*) - 1 + GRPC_SLICE_INLINE_EXTRA_SIZE) +struct grpc_slice_refcount; /** A grpc_slice s, if initialized, represents the byte range s.bytes[0..s.length-1]. diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index 9b4c3ce7e11..1ae81fe37ff 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -56,7 +56,7 @@ /* don't consider adding anything bigger than this to the hpack table */ #define MAX_DECODER_SPACE_USAGE 512 -static grpc_slice_refcount terminal_slice_refcount = {nullptr, nullptr}; +static grpc_slice_refcount terminal_slice_refcount; static const grpc_slice terminal_slice = { &terminal_slice_refcount, /* refcount */ {{0, nullptr}} /* data.refcounted */ diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index bc8968a0209..3d1db0aa144 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -163,15 +163,6 @@ static void report_stall(grpc_chttp2_transport* t, grpc_chttp2_stream* s, } } -static bool stream_ref_if_not_destroyed(gpr_refcount* r) { - gpr_atm count; - do { - count = gpr_atm_acq_load(&r->count); - if (count == 0) return false; - } while (!gpr_atm_rel_cas(&r->count, count, count + 1)); - return true; -} - /* How many bytes would we like to put on the wire during a single syscall */ static uint32_t target_write_size(grpc_chttp2_transport* t) { return 1024 * 1024; @@ -254,7 +245,7 @@ class WriteContext { while (grpc_chttp2_list_pop_stalled_by_transport(t_, &s)) { if (t_->closed_with_error == GRPC_ERROR_NONE && grpc_chttp2_list_add_writable_stream(t_, s)) { - if (!stream_ref_if_not_destroyed(&s->refcount->refs)) { + if (!s->refcount->refs.RefIfNonZero()) { grpc_chttp2_list_remove_writable_stream(t_, s); } } diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index 4937f311bba..87b342e0093 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -123,6 +123,22 @@ class RefCount { RefNonZero(); } + bool RefIfNonZero() { return value_.IncrementIfNonzero(); } + + bool RefIfNonZero(const DebugLocation& location, const char* reason) { +#ifndef NDEBUG + if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { + const RefCount::Value old_refs = get(); + gpr_log(GPR_INFO, + "%s:%p %s:%d ref_if_non_zero " + "%" PRIdPTR " -> %" PRIdPTR " %s", + trace_flag_->name(), this, location.file(), location.line(), + old_refs, old_refs + 1, reason); + } +#endif + return RefIfNonZero(); + } + // Decrements the ref-count and returns true if the ref-count reaches 0. bool Unref() { const Value prior = value_.FetchSub(1, MemoryOrder::ACQ_REL); diff --git a/src/core/lib/iomgr/resource_quota.cc b/src/core/lib/iomgr/resource_quota.cc index 61c366098e1..06e19d71e0c 100644 --- a/src/core/lib/iomgr/resource_quota.cc +++ b/src/core/lib/iomgr/resource_quota.cc @@ -32,6 +32,7 @@ #include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/slice/slice_internal.h" grpc_core::TraceFlag grpc_resource_quota_trace(false, "resource_quota"); @@ -430,41 +431,43 @@ static bool rq_reclaim(grpc_resource_quota* resource_quota, bool destructive) { * ru_slice: a slice implementation that is backed by a grpc_resource_user */ -typedef struct { - grpc_slice_refcount base; - gpr_refcount refs; - grpc_resource_user* resource_user; - size_t size; -} ru_slice_refcount; +namespace grpc_core { -static void ru_slice_ref(void* p) { - ru_slice_refcount* rc = static_cast(p); - gpr_ref(&rc->refs); -} - -static void ru_slice_unref(void* p) { - ru_slice_refcount* rc = static_cast(p); - if (gpr_unref(&rc->refs)) { - grpc_resource_user_free(rc->resource_user, rc->size); +class RuSliceRefcount { + public: + static void Destroy(void* p) { + auto* rc = static_cast(p); + rc->~RuSliceRefcount(); gpr_free(rc); } -} + RuSliceRefcount(grpc_resource_user* resource_user, size_t size) + : base_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, + &base_), + resource_user_(resource_user), + size_(size) { + // Nothing to do here. + } + ~RuSliceRefcount() { grpc_resource_user_free(resource_user_, size_); } -static const grpc_slice_refcount_vtable ru_slice_vtable = { - ru_slice_ref, ru_slice_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; + grpc_slice_refcount* base_refcount() { return &base_; } + + private: + grpc_slice_refcount base_; + RefCount refs_; + grpc_resource_user* resource_user_; + size_t size_; +}; + +} // namespace grpc_core static grpc_slice ru_slice_create(grpc_resource_user* resource_user, size_t size) { - ru_slice_refcount* rc = static_cast( - gpr_malloc(sizeof(ru_slice_refcount) + size)); - rc->base.vtable = &ru_slice_vtable; - rc->base.sub_refcount = &rc->base; - gpr_ref_init(&rc->refs, 1); - rc->resource_user = resource_user; - rc->size = size; + auto* rc = static_cast( + gpr_malloc(sizeof(grpc_core::RuSliceRefcount) + size)); + new (rc) grpc_core::RuSliceRefcount(resource_user, size); grpc_slice slice; - slice.refcount = &rc->base; + + slice.refcount = rc->base_refcount(); slice.data.refcounted.bytes = reinterpret_cast(rc + 1); slice.data.refcounted.length = size; return slice; diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index ac935f13e28..2bf2b0f499f 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/memory.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/iomgr/exec_ctx.h" @@ -67,17 +68,10 @@ void grpc_slice_unref(grpc_slice slice) { /* grpc_slice_from_static_string support structure - a refcount that does nothing */ -static void noop_ref(void* unused) {} -static void noop_unref(void* unused) {} - -static const grpc_slice_refcount_vtable noop_refcount_vtable = { - noop_ref, noop_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; -static grpc_slice_refcount noop_refcount = {&noop_refcount_vtable, - &noop_refcount}; +static grpc_slice_refcount NoopRefcount; size_t grpc_slice_memory_usage(grpc_slice s) { - if (s.refcount == nullptr || s.refcount == &noop_refcount) { + if (s.refcount == nullptr || s.refcount == &NoopRefcount) { return 0; } else { return s.data.refcounted.length; @@ -86,7 +80,7 @@ size_t grpc_slice_memory_usage(grpc_slice s) { grpc_slice grpc_slice_from_static_buffer(const void* s, size_t len) { grpc_slice slice; - slice.refcount = &noop_refcount; + slice.refcount = &NoopRefcount; slice.data.refcounted.bytes = (uint8_t*)s; slice.data.refcounted.length = len; return slice; @@ -96,45 +90,43 @@ grpc_slice grpc_slice_from_static_string(const char* s) { return grpc_slice_from_static_buffer(s, strlen(s)); } +namespace grpc_core { + /* grpc_slice_new support structures - we create a refcount object extended with the user provided data pointer & destroy function */ -typedef struct new_slice_refcount { - grpc_slice_refcount rc; - gpr_refcount refs; - void (*user_destroy)(void*); - void* user_data; -} new_slice_refcount; - -static void new_slice_ref(void* p) { - new_slice_refcount* r = static_cast(p); - gpr_ref(&r->refs); -} - -static void new_slice_unref(void* p) { - new_slice_refcount* r = static_cast(p); - if (gpr_unref(&r->refs)) { - r->user_destroy(r->user_data); - gpr_free(r); +class NewSliceRefcount { + public: + static void Destroy(void* arg) { + Delete(static_cast(arg)); } -} -static const grpc_slice_refcount_vtable new_slice_vtable = { - new_slice_ref, new_slice_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; + NewSliceRefcount(void (*destroy)(void*), void* user_data) + : rc_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, &rc_), + user_destroy_(destroy), + user_data_(user_data) {} + + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + + grpc_slice_refcount* base_refcount() { return &rc_; } + + private: + ~NewSliceRefcount() { user_destroy_(user_data_); } + + grpc_slice_refcount rc_; + RefCount refs_; + void (*user_destroy_)(void*); + void* user_data_; +}; + +} // namespace grpc_core grpc_slice grpc_slice_new_with_user_data(void* p, size_t len, void (*destroy)(void*), void* user_data) { grpc_slice slice; - new_slice_refcount* rc = - static_cast(gpr_malloc(sizeof(new_slice_refcount))); - gpr_ref_init(&rc->refs, 1); - rc->rc.vtable = &new_slice_vtable; - rc->rc.sub_refcount = &rc->rc; - rc->user_destroy = destroy; - rc->user_data = user_data; - - slice.refcount = &rc->rc; + slice.refcount = + grpc_core::New(destroy, user_data) + ->base_refcount(); slice.data.refcounted.bytes = static_cast(p); slice.data.refcounted.length = len; return slice; @@ -145,46 +137,45 @@ grpc_slice grpc_slice_new(void* p, size_t len, void (*destroy)(void*)) { return grpc_slice_new_with_user_data(p, len, destroy, p); } +namespace grpc_core { /* grpc_slice_new_with_len support structures - we create a refcount object extended with the user provided data pointer & destroy function */ -typedef struct new_with_len_slice_refcount { - grpc_slice_refcount rc; - gpr_refcount refs; - void* user_data; - size_t user_length; - void (*user_destroy)(void*, size_t); -} new_with_len_slice_refcount; -static void new_with_len_ref(void* p) { - new_with_len_slice_refcount* r = static_cast(p); - gpr_ref(&r->refs); -} - -static void new_with_len_unref(void* p) { - new_with_len_slice_refcount* r = static_cast(p); - if (gpr_unref(&r->refs)) { - r->user_destroy(r->user_data, r->user_length); - gpr_free(r); +class NewWithLenSliceRefcount { + public: + static void Destroy(void* arg) { + Delete(static_cast(arg)); } -} -static const grpc_slice_refcount_vtable new_with_len_vtable = { - new_with_len_ref, new_with_len_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; + NewWithLenSliceRefcount(void (*destroy)(void*, size_t), void* user_data, + size_t user_length) + : rc_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, &rc_), + user_data_(user_data), + user_length_(user_length), + user_destroy_(destroy) {} + + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + + grpc_slice_refcount* base_refcount() { return &rc_; } + + private: + ~NewWithLenSliceRefcount() { user_destroy_(user_data_, user_length_); } + + grpc_slice_refcount rc_; + RefCount refs_; + void* user_data_; + size_t user_length_; + void (*user_destroy_)(void*, size_t); +}; + +} // namespace grpc_core grpc_slice grpc_slice_new_with_len(void* p, size_t len, void (*destroy)(void*, size_t)) { grpc_slice slice; - new_with_len_slice_refcount* rc = static_cast( - gpr_malloc(sizeof(new_with_len_slice_refcount))); - gpr_ref_init(&rc->refs, 1); - rc->rc.vtable = &new_with_len_vtable; - rc->rc.sub_refcount = &rc->rc; - rc->user_destroy = destroy; - rc->user_data = p; - rc->user_length = len; - - slice.refcount = &rc->rc; + slice.refcount = + grpc_core::New(destroy, p, len) + ->base_refcount(); slice.data.refcounted.bytes = static_cast(p); slice.data.refcounted.length = len; return slice; @@ -203,39 +194,28 @@ grpc_slice grpc_slice_from_copied_string(const char* source) { namespace { -struct MallocRefCount { - MallocRefCount(const grpc_slice_refcount_vtable* vtable) { - base.vtable = vtable; - base.sub_refcount = &base; +class MallocRefCount { + public: + static void Destroy(void* arg) { + MallocRefCount* r = static_cast(arg); + r->~MallocRefCount(); + gpr_free(r); } - void Ref() { refs.Ref(); } - void Unref() { - if (refs.Unref()) { - gpr_free(this); - } - } + MallocRefCount() + : base_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, + &base_) {} + ~MallocRefCount() = default; - grpc_slice_refcount base; - grpc_core::RefCount refs; + grpc_slice_refcount* base_refcount() { return &base_; } + + private: + grpc_slice_refcount base_; + grpc_core::RefCount refs_; }; } // namespace -static void malloc_ref(void* p) { - MallocRefCount* r = static_cast(p); - r->Ref(); -} - -static void malloc_unref(void* p) { - MallocRefCount* r = static_cast(p); - r->Unref(); -} - -static const grpc_slice_refcount_vtable malloc_vtable = { - malloc_ref, malloc_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; - grpc_slice grpc_slice_malloc_large(size_t length) { grpc_slice slice; @@ -248,14 +228,16 @@ 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 */ - void* data = + auto* rc = static_cast(gpr_malloc(sizeof(MallocRefCount) + length)); - auto* rc = new (data) MallocRefCount(&malloc_vtable); + /* Initial refcount on rc is 1 - and it's up to the caller to release + this reference. */ + new (rc) MallocRefCount(); /* Build up the slice to be returned. */ /* The slices refcount points back to the allocated block. */ - slice.refcount = &rc->base; + slice.refcount = rc->base_refcount(); /* The data bytes are placed immediately after the refcount struct */ slice.data.refcounted.bytes = reinterpret_cast(rc + 1); /* And the length of the block is set to the requested length */ @@ -286,7 +268,7 @@ grpc_slice grpc_slice_sub_no_ref(grpc_slice source, size_t begin, size_t end) { GPR_ASSERT(source.data.refcounted.length >= end); /* Build the result */ - subset.refcount = source.refcount->sub_refcount; + subset.refcount = source.refcount->sub_refcount(); /* Point into the source array */ subset.data.refcounted.bytes = source.data.refcounted.bytes + begin; subset.data.refcounted.length = end - begin; @@ -312,7 +294,7 @@ grpc_slice grpc_slice_sub(grpc_slice source, size_t begin, size_t end) { } else { subset = grpc_slice_sub_no_ref(source, begin, end); /* Bump the refcount */ - subset.refcount->vtable->ref(subset.refcount); + subset.refcount->Ref(); } return subset; } @@ -340,23 +322,23 @@ grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice* source, size_t split, tail.data.inlined.length = static_cast(tail_length); memcpy(tail.data.inlined.bytes, source->data.refcounted.bytes + split, tail_length); - source->refcount = source->refcount->sub_refcount; + source->refcount = source->refcount->sub_refcount(); } else { /* Build the result */ switch (ref_whom) { case GRPC_SLICE_REF_TAIL: - tail.refcount = source->refcount->sub_refcount; - source->refcount = &noop_refcount; + tail.refcount = source->refcount->sub_refcount(); + source->refcount = &NoopRefcount; break; case GRPC_SLICE_REF_HEAD: - tail.refcount = &noop_refcount; - source->refcount = source->refcount->sub_refcount; + tail.refcount = &NoopRefcount; + source->refcount = source->refcount->sub_refcount(); break; case GRPC_SLICE_REF_BOTH: - tail.refcount = source->refcount->sub_refcount; - source->refcount = source->refcount->sub_refcount; + tail.refcount = source->refcount->sub_refcount(); + source->refcount = source->refcount->sub_refcount(); /* Bump the refcount */ - tail.refcount->vtable->ref(tail.refcount); + tail.refcount->Ref(); break; } /* Point into the source array */ @@ -392,20 +374,20 @@ grpc_slice grpc_slice_split_head(grpc_slice* source, size_t split) { head.refcount = nullptr; head.data.inlined.length = static_cast(split); memcpy(head.data.inlined.bytes, source->data.refcounted.bytes, split); - source->refcount = source->refcount->sub_refcount; + source->refcount = source->refcount->sub_refcount(); source->data.refcounted.bytes += split; source->data.refcounted.length -= split; } else { GPR_ASSERT(source->data.refcounted.length >= split); /* Build the result */ - head.refcount = source->refcount->sub_refcount; + head.refcount = source->refcount->sub_refcount(); /* Bump the refcount */ - head.refcount->vtable->ref(head.refcount); + head.refcount->Ref(); /* Point into the source array */ head.data.refcounted.bytes = source->data.refcounted.bytes; head.data.refcounted.length = split; - source->refcount = source->refcount->sub_refcount; + source->refcount = source->refcount->sub_refcount(); source->data.refcounted.bytes += split; source->data.refcounted.length -= split; } @@ -421,8 +403,9 @@ int grpc_slice_default_eq_impl(grpc_slice a, grpc_slice b) { } int grpc_slice_eq(grpc_slice a, grpc_slice b) { - if (a.refcount && b.refcount && a.refcount->vtable == b.refcount->vtable) { - return a.refcount->vtable->eq(a, b); + if (a.refcount && b.refcount && + a.refcount->GetType() == b.refcount->GetType()) { + return a.refcount->Eq(a, b); } return grpc_slice_default_eq_impl(a, b); } diff --git a/src/core/lib/slice/slice_intern.cc b/src/core/lib/slice/slice_intern.cc index 0eef38d3f35..0f190c186fa 100644 --- a/src/core/lib/slice/slice_intern.cc +++ b/src/core/lib/slice/slice_intern.cc @@ -27,6 +27,7 @@ #include #include "src/core/lib/gpr/murmur_hash.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/iomgr_internal.h" /* for iomgr_abort_on_leaks() */ #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_string_helpers.h" @@ -39,24 +40,17 @@ #define TABLE_IDX(hash, capacity) (((hash) >> LOG2_SHARD_COUNT) % (capacity)) #define SHARD_IDX(hash) ((hash) & ((1 << LOG2_SHARD_COUNT) - 1)) -typedef struct interned_slice_refcount { - grpc_slice_refcount base; - grpc_slice_refcount sub; - size_t length; - gpr_atm refcnt; - uint32_t hash; - struct interned_slice_refcount* bucket_next; -} interned_slice_refcount; +using grpc_core::InternedSliceRefcount; typedef struct slice_shard { gpr_mu mu; - interned_slice_refcount** strs; + InternedSliceRefcount** strs; size_t count; size_t capacity; } slice_shard; /* hash seed: decided at initialization time */ -static uint32_t g_hash_seed; +uint32_t g_hash_seed; static int g_forced_hash_seed = 0; static slice_shard g_shards[SHARD_COUNT]; @@ -69,73 +63,35 @@ typedef struct { static static_metadata_hash_ent static_metadata_hash[4 * GRPC_STATIC_MDSTR_COUNT]; static uint32_t max_static_metadata_hash_probe; -static uint32_t static_metadata_hash_values[GRPC_STATIC_MDSTR_COUNT]; +uint32_t grpc_static_metadata_hash_values[GRPC_STATIC_MDSTR_COUNT]; -static void interned_slice_ref(void* p) { - interned_slice_refcount* s = static_cast(p); - GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&s->refcnt, 1) > 0); -} +namespace grpc_core { -static void interned_slice_destroy(interned_slice_refcount* s) { - slice_shard* shard = &g_shards[SHARD_IDX(s->hash)]; - gpr_mu_lock(&shard->mu); - GPR_ASSERT(0 == gpr_atm_no_barrier_load(&s->refcnt)); - interned_slice_refcount** prev_next; - interned_slice_refcount* cur; - for (prev_next = &shard->strs[TABLE_IDX(s->hash, shard->capacity)], +InternedSliceRefcount::~InternedSliceRefcount() { + slice_shard* shard = &g_shards[SHARD_IDX(this->hash)]; + MutexLock lock(&shard->mu); + InternedSliceRefcount** prev_next; + InternedSliceRefcount* cur; + for (prev_next = &shard->strs[TABLE_IDX(this->hash, shard->capacity)], cur = *prev_next; - cur != s; prev_next = &cur->bucket_next, cur = cur->bucket_next) + cur != this; prev_next = &cur->bucket_next, cur = cur->bucket_next) ; *prev_next = cur->bucket_next; shard->count--; - gpr_free(s); - gpr_mu_unlock(&shard->mu); } -static void interned_slice_unref(void* p) { - interned_slice_refcount* s = static_cast(p); - if (1 == gpr_atm_full_fetch_add(&s->refcnt, -1)) { - interned_slice_destroy(s); - } -} - -static void interned_slice_sub_ref(void* p) { - interned_slice_ref((static_cast(p)) - - offsetof(interned_slice_refcount, sub)); -} - -static void interned_slice_sub_unref(void* p) { - interned_slice_unref((static_cast(p)) - - offsetof(interned_slice_refcount, sub)); -} - -static uint32_t interned_slice_hash(grpc_slice slice) { - interned_slice_refcount* s = - reinterpret_cast(slice.refcount); - return s->hash; -} - -static int interned_slice_eq(grpc_slice a, grpc_slice b) { - return a.refcount == b.refcount; -} - -static const grpc_slice_refcount_vtable interned_slice_vtable = { - interned_slice_ref, interned_slice_unref, interned_slice_eq, - interned_slice_hash}; -static const grpc_slice_refcount_vtable interned_slice_sub_vtable = { - interned_slice_sub_ref, interned_slice_sub_unref, - grpc_slice_default_eq_impl, grpc_slice_default_hash_impl}; +} // namespace grpc_core static void grow_shard(slice_shard* shard) { GPR_TIMER_SCOPE("grow_strtab", 0); size_t capacity = shard->capacity * 2; size_t i; - interned_slice_refcount** strtab; - interned_slice_refcount *s, *next; + InternedSliceRefcount** strtab; + InternedSliceRefcount *s, *next; - strtab = static_cast( - gpr_zalloc(sizeof(interned_slice_refcount*) * capacity)); + strtab = static_cast( + gpr_zalloc(sizeof(InternedSliceRefcount*) * capacity)); for (i = 0; i < shard->capacity; i++) { for (s = shard->strs[i]; s; s = next) { @@ -150,7 +106,7 @@ static void grow_shard(slice_shard* shard) { shard->capacity = capacity; } -static grpc_slice materialize(interned_slice_refcount* s) { +static grpc_slice materialize(InternedSliceRefcount* s) { grpc_slice slice; slice.refcount = &s->base; slice.data.refcounted.bytes = reinterpret_cast(s + 1); @@ -164,7 +120,7 @@ uint32_t grpc_slice_default_hash_impl(grpc_slice s) { } uint32_t grpc_static_slice_hash(grpc_slice s) { - return static_metadata_hash_values[GRPC_STATIC_METADATA_INDEX(s)]; + return grpc_static_metadata_hash_values[GRPC_STATIC_METADATA_INDEX(s)]; } int grpc_static_slice_eq(grpc_slice a, grpc_slice b) { @@ -173,7 +129,7 @@ int grpc_static_slice_eq(grpc_slice a, grpc_slice b) { uint32_t grpc_slice_hash(grpc_slice s) { return s.refcount == nullptr ? grpc_slice_default_hash_impl(s) - : s.refcount->vtable->hash(s); + : s.refcount->Hash(s); } grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice, @@ -197,8 +153,9 @@ grpc_slice grpc_slice_maybe_static_intern(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); + return (slice.refcount && + (slice.refcount->GetType() == grpc_slice_refcount::Type::INTERNED || + GRPC_IS_STATIC_METADATA_STRING(slice))); } grpc_slice grpc_slice_intern(grpc_slice slice) { @@ -208,6 +165,7 @@ grpc_slice grpc_slice_intern(grpc_slice slice) { } uint32_t hash = grpc_slice_hash(slice); + for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) { static_metadata_hash_ent ent = static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)]; @@ -217,7 +175,7 @@ grpc_slice grpc_slice_intern(grpc_slice slice) { } } - interned_slice_refcount* s; + InternedSliceRefcount* s; slice_shard* shard = &g_shards[SHARD_IDX(hash)]; gpr_mu_lock(&shard->mu); @@ -226,14 +184,7 @@ grpc_slice grpc_slice_intern(grpc_slice slice) { size_t idx = TABLE_IDX(hash, shard->capacity); for (s = shard->strs[idx]; s; s = s->bucket_next) { if (s->hash == hash && grpc_slice_eq(slice, materialize(s))) { - if (gpr_atm_no_barrier_fetch_add(&s->refcnt, 1) == 0) { - /* If we get here, we've added a ref to something that was about to - * die - drop it immediately. - * The *only* possible path here (given the shard mutex) should be to - * drop from one ref back to zero - assert that with a CAS */ - GPR_ASSERT(gpr_atm_rel_cas(&s->refcnt, 1, 0)); - /* and treat this as if we were never here... sshhh */ - } else { + if (s->refcnt.RefIfNonZero()) { gpr_mu_unlock(&shard->mu); return materialize(s); } @@ -242,27 +193,20 @@ grpc_slice grpc_slice_intern(grpc_slice slice) { /* not found: create a new string */ /* string data goes after the internal_string header */ - s = static_cast( + s = static_cast( gpr_malloc(sizeof(*s) + GRPC_SLICE_LENGTH(slice))); - gpr_atm_rel_store(&s->refcnt, 1); - s->length = GRPC_SLICE_LENGTH(slice); - s->hash = hash; - s->base.vtable = &interned_slice_vtable; - s->base.sub_refcount = &s->sub; - s->sub.vtable = &interned_slice_sub_vtable; - s->sub.sub_refcount = &s->sub; - s->bucket_next = shard->strs[idx]; + + new (s) grpc_core::InternedSliceRefcount(GRPC_SLICE_LENGTH(slice), hash, + shard->strs[idx]); + memcpy(reinterpret_cast(s + 1), GRPC_SLICE_START_PTR(slice), + GRPC_SLICE_LENGTH(slice)); shard->strs[idx] = s; - memcpy(s + 1, GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice)); - shard->count++; - if (shard->count > shard->capacity * 2) { grow_shard(shard); } gpr_mu_unlock(&shard->mu); - return materialize(s); } @@ -280,7 +224,7 @@ void grpc_slice_intern_init(void) { gpr_mu_init(&shard->mu); shard->count = 0; shard->capacity = INITIAL_SHARD_CAPACITY; - shard->strs = static_cast( + shard->strs = static_cast( gpr_zalloc(sizeof(*shard->strs) * shard->capacity)); } for (size_t i = 0; i < GPR_ARRAY_SIZE(static_metadata_hash); i++) { @@ -289,13 +233,13 @@ void grpc_slice_intern_init(void) { } max_static_metadata_hash_probe = 0; for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) { - static_metadata_hash_values[i] = + grpc_static_metadata_hash_values[i] = grpc_slice_default_hash_impl(grpc_static_slice_table[i]); for (size_t j = 0; j < GPR_ARRAY_SIZE(static_metadata_hash); j++) { - size_t slot = (static_metadata_hash_values[i] + j) % + size_t slot = (grpc_static_metadata_hash_values[i] + j) % GPR_ARRAY_SIZE(static_metadata_hash); if (static_metadata_hash[slot].idx == GRPC_STATIC_MDSTR_COUNT) { - static_metadata_hash[slot].hash = static_metadata_hash_values[i]; + static_metadata_hash[slot].hash = grpc_static_metadata_hash_values[i]; static_metadata_hash[slot].idx = static_cast(i); if (j > max_static_metadata_hash_probe) { max_static_metadata_hash_probe = static_cast(j); @@ -315,8 +259,7 @@ void grpc_slice_intern_shutdown(void) { gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata strings were leaked", shard->count); for (size_t j = 0; j < shard->capacity; j++) { - for (interned_slice_refcount* s = shard->strs[j]; s; - s = s->bucket_next) { + for (InternedSliceRefcount* s = shard->strs[j]; s; s = s->bucket_next) { char* text = grpc_dump_slice(materialize(s), GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_DEBUG, "LEAKED: %s", text); diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index 0e50866b70e..db8c8e5c7cc 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -23,17 +23,215 @@ #include #include +#include -inline const grpc_slice& grpc_slice_ref_internal(const grpc_slice& slice) { +#include "src/core/lib/gpr/murmur_hash.h" +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/transport/static_metadata.h" + +// Interned slices have specific fast-path operations for hashing. To inline +// these operations, we need to forward declare them here. +extern uint32_t grpc_static_metadata_hash_values[GRPC_STATIC_MDSTR_COUNT]; +extern uint32_t g_hash_seed; + +// grpc_slice_refcount : A reference count for grpc_slice. +// +// Non-inlined grpc_slice objects are refcounted. Historically this was +// implemented via grpc_slice_refcount, a C-style polymorphic class using a +// manually managed vtable of operations. Subclasses would define their own +// vtable; the 'virtual' methods (ref, unref, equals and hash) would simply call +// the function pointers in the vtable as necessary. +// +// Unfortunately, this leads to some inefficiencies in the generated code that +// can be improved upon. For example, equality checking for interned slices is a +// simple equality check on the refcount pointer. With the vtable approach, this +// would translate to roughly the following (high-level) instructions: +// +// grpc_slice_equals(slice1, slice2): +// load vtable->eq -> eq_func +// call eq_func(slice1, slice2) +// +// interned_slice_equals(slice1, slice2) +// load slice1.ref -> r1 +// load slice2.ref -> r2 +// cmp r1, r2 -> retval +// ret retval +// +// This leads to a function call for a function defined in another translation +// unit, which imposes memory barriers, which reduces the compiler's ability to +// optimize (in addition to the added overhead of call/ret). Additionally, it +// may be harder to reason about branch prediction when we're jumping to +// essentially arbitrarily provided function pointers. +// +// In addition, it is arguable that while virtualization was helpful for +// Equals()/Hash() methods, that it was fundamentally unnecessary for +// Ref()/Unref(). +// +// Instead, grpc_slice_refcount provides the same functionality as the C-style +// virtual class, but in a de-virtualized manner - Eq(), Hash(), Ref() and +// Unref() are provided within this header file. Fastpaths for Eq()/Hash() +// (interned and static metadata slices), as well as the Ref() operation, can +// all be inlined without any memory barriers. +// +// It does this by: +// 1. Using grpc_core::RefCount<> (header-only) for Ref/Unref. Two special cases +// need support: No-op ref/unref (eg. static metadata slices) and stream +// slice references (where all the slices share the streamref). This is in +// addition to the normal case of '1 slice, 1 ref'. +// To support these cases, we explicitly track a nullable pointer to the +// underlying RefCount<>. No-op ref/unref is used by checking the pointer for +// null, and doing nothing if it is. Both stream slice refs and 'normal' +// slices use the same path for Ref/Unref (by targeting the non-null +// pointer). +// +// 2. introducing the notion of grpc_slice_refcount::Type. This describes if a +// slice ref is used by a static metadata slice, an interned slice, or other +// slices. We switch on the slice ref type in order to provide fastpaths for +// Equals() and Hash(). +// +// In total, this saves us roughly 1-2% latency for unary calls, with smaller +// calls benefitting. The effect is present, but not as useful, for larger calls +// where the cost of sending the data dominates. +struct grpc_slice_refcount { + public: + enum class Type { + STATIC, // Refcount for a static metadata slice. + INTERNED, // Refcount for an interned slice. + REGULAR // Refcount for non-static-metadata, non-interned slices. + }; + typedef void (*DestroyerFn)(void*); + + grpc_slice_refcount() = default; + + explicit grpc_slice_refcount(grpc_slice_refcount* sub) : sub_refcount_(sub) {} + // Regular constructor for grpc_slice_refcount. + // + // Parameters: + // 1. grpc_slice_refcount::Type type + // Whether we are the refcount for a static + // metadata slice, an interned slice, or any other kind of slice. + // + // 2. RefCount* ref + // The pointer to the actual underlying grpc_core::RefCount. Rather than + // performing struct offset computations as in the original implementation to + // get to the refcount, which requires a virtual method, we devirtualize by + // using a nullable pointer to allow a single pair of Ref/Unref methods. + // + // 3. DestroyerFn destroyer_fn + // Called when the refcount goes to 0, with destroyer_arg as parameter. + // + // 4. void* destroyer_arg + // Argument for the virtualized destructor. + // + // 5. grpc_slice_refcount* sub + // Argument used for interned slices. + grpc_slice_refcount(grpc_slice_refcount::Type type, grpc_core::RefCount* ref, + DestroyerFn destroyer_fn, void* destroyer_arg, + grpc_slice_refcount* sub) + : ref_(ref), + ref_type_(type), + sub_refcount_(sub), + dest_fn_(destroyer_fn), + destroy_fn_arg_(destroyer_arg) {} + // Initializer for static refcounts. + grpc_slice_refcount(grpc_slice_refcount* sub, Type type) + : ref_type_(type), sub_refcount_(sub) {} + + Type GetType() const { return ref_type_; } + + int Eq(const grpc_slice& a, const grpc_slice& b); + + uint32_t Hash(const grpc_slice& slice); + void Ref() { + if (ref_ == nullptr) return; + ref_->RefNonZero(); + } + void Unref() { + if (ref_ == nullptr) return; + if (ref_->Unref()) { + dest_fn_(destroy_fn_arg_); + } + } + + grpc_slice_refcount* sub_refcount() const { return sub_refcount_; } + + private: + grpc_core::RefCount* ref_ = nullptr; + const Type ref_type_ = Type::REGULAR; + grpc_slice_refcount* sub_refcount_ = this; + DestroyerFn dest_fn_ = nullptr; + void* destroy_fn_arg_ = nullptr; +}; + +namespace grpc_core { + +struct InternedSliceRefcount { + static void Destroy(void* arg) { + auto* rc = static_cast(arg); + rc->~InternedSliceRefcount(); + gpr_free(rc); + } + + InternedSliceRefcount(size_t length, uint32_t hash, + InternedSliceRefcount* bucket_next) + : base(grpc_slice_refcount::Type::INTERNED, &refcnt, Destroy, this, &sub), + sub(grpc_slice_refcount::Type::REGULAR, &refcnt, Destroy, this, &sub), + length(length), + hash(hash), + bucket_next(bucket_next) {} + + ~InternedSliceRefcount(); + + grpc_slice_refcount base; + grpc_slice_refcount sub; + const size_t length; + RefCount refcnt; + const uint32_t hash; + InternedSliceRefcount* bucket_next; +}; + +} // namespace grpc_core + +inline int grpc_slice_refcount::Eq(const grpc_slice& a, const grpc_slice& b) { + switch (ref_type_) { + case Type::STATIC: + return GRPC_STATIC_METADATA_INDEX(a) == GRPC_STATIC_METADATA_INDEX(b); + case Type::INTERNED: + return a.refcount == b.refcount; + case Type::REGULAR: + break; + } + if (GRPC_SLICE_LENGTH(a) != GRPC_SLICE_LENGTH(b)) return false; + if (GRPC_SLICE_LENGTH(a) == 0) return true; + return 0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b), + GRPC_SLICE_LENGTH(a)); +} + +inline uint32_t grpc_slice_refcount::Hash(const grpc_slice& slice) { + switch (ref_type_) { + case Type::STATIC: + return ::grpc_static_metadata_hash_values[GRPC_STATIC_METADATA_INDEX( + slice)]; + case Type::INTERNED: + return reinterpret_cast(slice.refcount) + ->hash; + case Type::REGULAR: + break; + } + return gpr_murmur_hash3(GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice), + g_hash_seed); +} + +inline grpc_slice grpc_slice_ref_internal(const grpc_slice& slice) { if (slice.refcount) { - slice.refcount->vtable->ref(slice.refcount); + slice.refcount->Ref(); } return slice; } inline void grpc_slice_unref_internal(const grpc_slice& slice) { if (slice.refcount) { - slice.refcount->vtable->unref(slice.refcount); + slice.refcount->Unref(); } } diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 963626a9dc9..fc5bb647573 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -116,123 +116,115 @@ static uint8_t g_bytes[] = { 103, 122, 105, 112, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, 112}; -static void static_ref(void* unused) {} -static void static_unref(void* unused) {} -static const grpc_slice_refcount_vtable static_sub_vtable = { - static_ref, static_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; -const grpc_slice_refcount_vtable grpc_static_metadata_vtable = { - static_ref, static_unref, grpc_static_slice_eq, grpc_static_slice_hash}; -static grpc_slice_refcount static_sub_refcnt = {&static_sub_vtable, - &static_sub_refcnt}; +static grpc_slice_refcount static_sub_refcnt; grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = { - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), }; const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 4f9670232c3..88293ae0613 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -256,12 +256,11 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ (grpc_static_slice_table[106]) -extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable; extern grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT]; #define GRPC_IS_STATIC_METADATA_STRING(slice) \ ((slice).refcount != NULL && \ - (slice).refcount->vtable == &grpc_static_metadata_vtable) + (slice).refcount->GetType() == grpc_slice_refcount::Type::STATIC) #define GRPC_STATIC_METADATA_INDEX(static_slice) \ ((int)((static_slice).refcount - grpc_static_metadata_refcounts)) diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index 09306110c63..9f666b382e9 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -39,72 +39,39 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_stream_refcount(false, "stream_refcount"); -#ifndef NDEBUG -void grpc_stream_ref(grpc_stream_refcount* refcount, const char* reason) { - if (grpc_trace_stream_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count); - gpr_log(GPR_DEBUG, "%s %p:%p REF %" PRIdPTR "->%" PRIdPTR " %s", - refcount->object_type, refcount, refcount->destroy.cb_arg, val, - val + 1, reason); +void grpc_stream_destroy(grpc_stream_refcount* refcount) { + 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 + thread, which is a tangled mess that we just don't want to ever have to + cope with. + Throw this over to the executor (on a core-owned thread) and process it + there. */ + refcount->destroy.scheduler = + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT); } -#else -void grpc_stream_ref(grpc_stream_refcount* refcount) { -#endif - gpr_ref_non_zero(&refcount->refs); + GRPC_CLOSURE_SCHED(&refcount->destroy, GRPC_ERROR_NONE); } -#ifndef NDEBUG -void grpc_stream_unref(grpc_stream_refcount* refcount, const char* reason) { - if (grpc_trace_stream_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count); - gpr_log(GPR_DEBUG, "%s %p:%p UNREF %" PRIdPTR "->%" PRIdPTR " %s", - refcount->object_type, refcount, refcount->destroy.cb_arg, val, - val - 1, reason); - } -#else -void grpc_stream_unref(grpc_stream_refcount* refcount) { -#endif - if (gpr_unref(&refcount->refs)) { - 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 - thread, which is a tangled mess that we just don't want to ever have to - cope with. - Throw this over to the executor (on a core-owned thread) and process it - there. */ - refcount->destroy.scheduler = - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT); - } - GRPC_CLOSURE_SCHED(&refcount->destroy, GRPC_ERROR_NONE); - } +void slice_stream_destroy(void* arg) { + grpc_stream_destroy(static_cast(arg)); } #define STREAM_REF_FROM_SLICE_REF(p) \ ((grpc_stream_refcount*)(((uint8_t*)p) - \ offsetof(grpc_stream_refcount, slice_refcount))) -static void slice_stream_ref(void* p) { -#ifndef NDEBUG - grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p), "slice"); -#else - grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p)); -#endif -} - -static void slice_stream_unref(void* p) { -#ifndef NDEBUG - grpc_stream_unref(STREAM_REF_FROM_SLICE_REF(p), "slice"); -#else - grpc_stream_unref(STREAM_REF_FROM_SLICE_REF(p)); -#endif -} - grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount* refcount, void* buffer, size_t length) { - slice_stream_ref(&refcount->slice_refcount); +#ifndef NDEBUG + grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(&refcount->slice_refcount), + "slice"); +#else + grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(&refcount->slice_refcount)); +#endif grpc_slice res; res.refcount = &refcount->slice_refcount; res.data.refcounted.bytes = static_cast(buffer); @@ -112,13 +79,6 @@ grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount* refcount, return res; } -static const grpc_slice_refcount_vtable stream_ref_slice_vtable = { - slice_stream_ref, /* ref */ - slice_stream_unref, /* unref */ - grpc_slice_default_eq_impl, /* eq */ - grpc_slice_default_hash_impl /* hash */ -}; - #ifndef NDEBUG void grpc_stream_ref_init(grpc_stream_refcount* refcount, int initial_refs, grpc_iomgr_cb_func cb, void* cb_arg, @@ -128,10 +88,12 @@ void grpc_stream_ref_init(grpc_stream_refcount* refcount, int initial_refs, void grpc_stream_ref_init(grpc_stream_refcount* refcount, int initial_refs, grpc_iomgr_cb_func cb, void* cb_arg) { #endif - gpr_ref_init(&refcount->refs, initial_refs); GRPC_CLOSURE_INIT(&refcount->destroy, cb, cb_arg, grpc_schedule_on_exec_ctx); - refcount->slice_refcount.vtable = &stream_ref_slice_vtable; - refcount->slice_refcount.sub_refcount = &refcount->slice_refcount; + + new (&refcount->refs) grpc_core::RefCount(); + new (&refcount->slice_refcount) grpc_slice_refcount( + grpc_slice_refcount::Type::REGULAR, &refcount->refs, slice_stream_destroy, + refcount, &refcount->slice_refcount); } static void move64(uint64_t* from, uint64_t* to) { diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 8631a1af81f..c372003902a 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -30,6 +30,7 @@ #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/byte_stream.h" #include "src/core/lib/transport/metadata_batch.h" @@ -51,7 +52,7 @@ typedef struct grpc_stream grpc_stream; extern grpc_core::DebugOnlyTraceFlag grpc_trace_stream_refcount; typedef struct grpc_stream_refcount { - gpr_refcount refs; + grpc_core::RefCount refs; grpc_closure destroy; #ifndef NDEBUG const char* object_type; @@ -63,19 +64,45 @@ typedef struct grpc_stream_refcount { void grpc_stream_ref_init(grpc_stream_refcount* refcount, int initial_refs, grpc_iomgr_cb_func cb, void* cb_arg, const char* object_type); -void grpc_stream_ref(grpc_stream_refcount* refcount, const char* reason); -void grpc_stream_unref(grpc_stream_refcount* refcount, const char* reason); #define GRPC_STREAM_REF_INIT(rc, ir, cb, cb_arg, objtype) \ grpc_stream_ref_init(rc, ir, cb, cb_arg, objtype) #else void grpc_stream_ref_init(grpc_stream_refcount* refcount, int initial_refs, grpc_iomgr_cb_func cb, void* cb_arg); -void grpc_stream_ref(grpc_stream_refcount* refcount); -void grpc_stream_unref(grpc_stream_refcount* refcount); #define GRPC_STREAM_REF_INIT(rc, ir, cb, cb_arg, objtype) \ grpc_stream_ref_init(rc, ir, cb, cb_arg) #endif +#ifndef NDEBUG +inline void grpc_stream_ref(grpc_stream_refcount* refcount, + const char* reason) { + if (grpc_trace_stream_refcount.enabled()) { + gpr_log(GPR_DEBUG, "%s %p:%p REF %s", refcount->object_type, refcount, + refcount->destroy.cb_arg, reason); + } +#else +inline void grpc_stream_ref(grpc_stream_refcount* refcount) { +#endif + refcount->refs.RefNonZero(); +} + +void grpc_stream_destroy(grpc_stream_refcount* refcount); + +#ifndef NDEBUG +inline void grpc_stream_unref(grpc_stream_refcount* refcount, + const char* reason) { + if (grpc_trace_stream_refcount.enabled()) { + gpr_log(GPR_DEBUG, "%s %p:%p UNREF %s", refcount->object_type, refcount, + refcount->destroy.cb_arg, reason); + } +#else +inline void grpc_stream_unref(grpc_stream_refcount* refcount) { +#endif + if (refcount->refs.Unref()) { + grpc_stream_destroy(refcount); + } +} + /* Wrap a buffer that is owned by some stream object into a slice that shares the same refcount */ grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount* refcount, diff --git a/test/core/slice/slice_test.cc b/test/core/slice/slice_test.cc index 1e53a1951c4..6ed02366fe2 100644 --- a/test/core/slice/slice_test.cc +++ b/test/core/slice/slice_test.cc @@ -51,13 +51,6 @@ static void test_slice_malloc_returns_something_sensible(void) { } /* Returned slice length must be what was requested. */ GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == length); - /* If the slice has a refcount, it must be destroyable. */ - if (slice.refcount) { - GPR_ASSERT(slice.refcount->vtable != nullptr); - GPR_ASSERT(slice.refcount->vtable->ref != nullptr); - GPR_ASSERT(slice.refcount->vtable->unref != nullptr); - GPR_ASSERT(slice.refcount->vtable->hash != nullptr); - } /* We must be able to write to every byte of the data */ for (i = 0; i < length; i++) { GRPC_SLICE_START_PTR(slice)[i] = static_cast(i); diff --git a/test/core/transport/stream_owned_slice_test.cc b/test/core/transport/stream_owned_slice_test.cc index 48a77db9a50..c489b11c185 100644 --- a/test/core/transport/stream_owned_slice_test.cc +++ b/test/core/transport/stream_owned_slice_test.cc @@ -32,14 +32,11 @@ int main(int argc, char** argv) { uint8_t buffer[] = "abc123"; grpc_stream_refcount r; GRPC_STREAM_REF_INIT(&r, 1, do_nothing, nullptr, "test"); - GPR_ASSERT(r.refs.count == 1); grpc_slice slice = grpc_slice_from_stream_owned_buffer(&r, buffer, sizeof(buffer)); GPR_ASSERT(GRPC_SLICE_START_PTR(slice) == buffer); GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == sizeof(buffer)); - GPR_ASSERT(r.refs.count == 2); grpc_slice_unref(slice); - GPR_ASSERT(r.refs.count == 1); grpc_shutdown(); return 0; diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index ab288a00909..5545e871117 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -394,7 +394,7 @@ for i, elem in enumerate(all_strs): def slice_def(i): return ('{&grpc_static_metadata_refcounts[%d],' - ' {{g_bytes+%d, %d}}}') % (i, id2strofs[i], len(all_strs[i])) + ' {{%d, g_bytes+%d}}}') % (i, len(all_strs[i]), id2strofs[i]) # validate configuration @@ -412,29 +412,19 @@ print >> H print >> C, 'static uint8_t g_bytes[] = {%s};' % (','.join( '%d' % ord(c) for c in ''.join(all_strs))) print >> C -print >> C, 'static void static_ref(void *unused) {}' -print >> C, 'static void static_unref(void *unused) {}' -print >> C, ('static const grpc_slice_refcount_vtable static_sub_vtable = ' - '{static_ref, static_unref, grpc_slice_default_eq_impl, ' - 'grpc_slice_default_hash_impl};') -print >> H, ('extern const grpc_slice_refcount_vtable ' - 'grpc_static_metadata_vtable;') -print >> C, ('const grpc_slice_refcount_vtable grpc_static_metadata_vtable = ' - '{static_ref, static_unref, grpc_static_slice_eq, ' - 'grpc_static_slice_hash};') -print >> C, ('static grpc_slice_refcount static_sub_refcnt = ' - '{&static_sub_vtable, &static_sub_refcnt};') +print >> C, ('static grpc_slice_refcount static_sub_refcnt;') print >> H, ('extern grpc_slice_refcount ' 'grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT];') print >> C, ('grpc_slice_refcount ' 'grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = {') for i, elem in enumerate(all_strs): - print >> C, ' {&grpc_static_metadata_vtable, &static_sub_refcnt},' + print >> C, (' grpc_slice_refcount(&static_sub_refcnt, ' + 'grpc_slice_refcount::Type::STATIC), ') print >> C, '};' print >> C print >> H, '#define GRPC_IS_STATIC_METADATA_STRING(slice) \\' -print >> H, (' ((slice).refcount != NULL && (slice).refcount->vtable == ' - '&grpc_static_metadata_vtable)') +print >> H, (' ((slice).refcount != NULL && (slice).refcount->GetType() == ' + 'grpc_slice_refcount::Type::STATIC)') print >> H print >> C, ('const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]' ' = {') From 3b65effb826a26dd474408a04602b3017b6d719f Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 19 Apr 2019 12:42:40 -0700 Subject: [PATCH 1905/2143] Cleanup --- .../health/health_check_parser.cc | 8 ++++---- .../client_channel/lb_policy/grpclb/grpclb.cc | 10 ++++------ .../lb_policy/pick_first/pick_first.cc | 10 +--------- .../lb_policy/round_robin/round_robin.cc | 10 +--------- .../filters/client_channel/lb_policy/xds/xds.cc | 15 +++++---------- .../client_channel/resolver_result_parsing.cc | 17 +++++++++++++++-- .../client_channel/resolver_result_parsing.h | 14 ++------------ .../filters/message_size/message_size_filter.cc | 1 - 8 files changed, 32 insertions(+), 53 deletions(-) diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.cc b/src/core/ext/filters/client_channel/health/health_check_parser.cc index b9ccc3cb3b6..1dcef527861 100644 --- a/src/core/ext/filters/client_channel/health/health_check_parser.cc +++ b/src/core/ext/filters/client_channel/health/health_check_parser.cc @@ -22,7 +22,7 @@ namespace grpc_core { namespace { -size_t health_check_parser_index; +size_t g_health_check_parser_index; } UniquePtr HealthCheckParser::ParseGlobalParams( @@ -66,10 +66,10 @@ UniquePtr HealthCheckParser::ParseGlobalParams( } void HealthCheckParser::Register() { - health_check_parser_index = ServiceConfig::RegisterParser( + g_health_check_parser_index = ServiceConfig::RegisterParser( UniquePtr(New())); } -size_t HealthCheckParser::ParserIndex() { return health_check_parser_index; } +size_t HealthCheckParser::ParserIndex() { return g_health_check_parser_index; } -} // namespace grpc_core \ No newline at end of file +} // 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 2146f0620e0..a4c28d8d431 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 @@ -120,19 +120,16 @@ constexpr char kGrpclb[] = "grpclb"; class ParsedGrpcLbConfig : public ParsedLoadBalancingConfig { public: - ParsedGrpcLbConfig(UniquePtr child_policy, - const grpc_json* json) - : child_policy_(std::move(child_policy)), json_(json) {} + ParsedGrpcLbConfig(UniquePtr child_policy) + : child_policy_(std::move(child_policy)) {} const char* name() const override { return kGrpclb; } const ParsedLoadBalancingConfig* child_policy() const { return child_policy_.get(); } - const grpc_json* config() const { return json_; } private: UniquePtr child_policy_; - const grpc_json* json_ = nullptr; }; class GrpcLb : public LoadBalancingPolicy { @@ -1847,6 +1844,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { if (child_policy != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:childPolicy error:Duplicate entry")); + continue; } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( @@ -1858,7 +1856,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { } if (error_list.empty()) { return UniquePtr( - New(std::move(child_policy), json)); + New(std::move(child_policy))); } else { *error = CreateErrorFromVector("GrpcLb Parser", &error_list); return 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 9e9f9bbdb91..21fda23ab71 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 @@ -530,14 +530,7 @@ void PickFirst::PickFirstSubchannelData:: class ParsedPickFirstConfig : public ParsedLoadBalancingConfig { public: - ParsedPickFirstConfig(const grpc_json* json) : json_(json) {} - const char* name() const override { return kPickFirst; } - - const grpc_json* config() const { return json_; } - - private: - const grpc_json* json_; }; // @@ -557,8 +550,7 @@ class PickFirstFactory : public LoadBalancingPolicyFactory { const grpc_json* json, grpc_error** error) const override { GPR_DEBUG_ASSERT(json != nullptr); GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); - return UniquePtr( - New(json)); + return UniquePtr(New()); } }; 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 6fe007a9796..193e383a433 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 @@ -507,14 +507,7 @@ void RoundRobin::UpdateLocked(UpdateArgs args) { class ParsedRoundRobinConfig : public ParsedLoadBalancingConfig { public: - ParsedRoundRobinConfig(const grpc_json* json) : json_(json) {} - const char* name() const override { return kRoundRobin; } - - const grpc_json* config() const { return json_; } - - private: - const grpc_json* json_; }; // @@ -534,8 +527,7 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory { const grpc_json* json, grpc_error** error) const override { GPR_DEBUG_ASSERT(json != nullptr); GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); - return UniquePtr( - New(json)); + return UniquePtr(New()); } }; 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 0368c8dbb30..7d222558f4d 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 @@ -123,12 +123,10 @@ class ParsedXdsConfig : public ParsedLoadBalancingConfig { public: ParsedXdsConfig(const char* balancer_name, UniquePtr child_policy, - UniquePtr fallback_policy, - const grpc_json* json) + UniquePtr fallback_policy) : balancer_name_(balancer_name), child_policy_(std::move(child_policy)), - fallback_policy_(std::move(fallback_policy)), - json_(json) {} + fallback_policy_(std::move(fallback_policy)) {} const char* name() const override { return kXds; } @@ -142,13 +140,10 @@ class ParsedXdsConfig : public ParsedLoadBalancingConfig { return fallback_policy_.get(); } - const grpc_json* config() const { return json_; } - private: const char* balancer_name_ = nullptr; UniquePtr child_policy_; UniquePtr fallback_policy_; - const grpc_json* json_ = nullptr; }; class XdsLb : public LoadBalancingPolicy { @@ -1729,6 +1724,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { if (fallback_policy != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:fallbackPolicy error:Duplicate entry")); + continue; } grpc_error* parse_error = GRPC_ERROR_NONE; fallback_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( @@ -1744,9 +1740,8 @@ class XdsFactory : public LoadBalancingPolicyFactory { "field:balancerName error:not found")); } if (error_list.empty()) { - return UniquePtr( - New(balancer_name, std::move(child_policy), - std::move(fallback_policy), json)); + return UniquePtr(New( + balancer_name, std::move(child_policy), std::move(fallback_policy))); } else { *error = CreateErrorFromVector("Xds Parser", &error_list); return nullptr; 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 54b90cd4039..1756917b391 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -44,8 +44,19 @@ namespace grpc_core { namespace internal { -size_t ClientChannelServiceConfigParser:: - client_channel_service_config_parser_index_; +namespace { +size_t g_client_channel_service_config_parser_index; +} + +size_t +ClientChannelServiceConfigParser::client_channel_service_config_parser_index() { + return g_client_channel_service_config_parser_index; +} + +void ClientChannelServiceConfigParser::Register() { + g_client_channel_service_config_parser_index = ServiceConfig::RegisterParser( + UniquePtr(New())); +} ProcessedResolverResult::ProcessedResolverResult( Resolver::Result* resolver_result, bool parse_retry) @@ -333,6 +344,8 @@ UniquePtr ParseRetryPolicy( retry_policy->max_backoff == 0 || retry_policy->backoff_multiplier == 0 || retry_policy->retryable_status_codes.Empty()) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryPolicy error:Missing required field(s)"); return nullptr; } } 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 6e73c43a779..327818f668d 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -107,18 +107,8 @@ class ClientChannelServiceConfigParser : public ServiceConfigParser { UniquePtr ParsePerMethodParams( const grpc_json* json, grpc_error** error) override; - static size_t client_channel_service_config_parser_index() { - return client_channel_service_config_parser_index_; - } - - static void Register() { - client_channel_service_config_parser_index_ = - ServiceConfig::RegisterParser(UniquePtr( - New())); - } - - private: - static size_t client_channel_service_config_parser_index_; + static size_t client_channel_service_config_parser_index(); + static void Register(); }; // A container of processed fields from the resolver result. Simplifies the 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 dca3f2e2fd2..ac1984f6929 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -83,7 +83,6 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( } } } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { - gpr_log(GPR_ERROR, "bla"); if (max_response_message_bytes >= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:Duplicate entry")); From 9e593f721ffcbe6d0dbb0b56b0116014702ac0d8 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Apr 2019 14:14:48 -0700 Subject: [PATCH 1906/2143] build system fix for default CFStream --- BUILD.gn | 11 ++++++ CMakeLists.txt | 30 +++++++++++++++ Makefile | 30 +++++++++++++++ build.yaml | 22 ++++------- config.m4 | 5 +++ config.w32 | 5 +++ gRPC-C++.podspec | 6 +++ gRPC-Core.podspec | 26 ++++++------- grpc.gemspec | 8 ++++ grpc.gyp | 20 ++++++++++ package.xml | 8 ++++ src/python/grpcio/grpc_core_dependencies.py | 5 +++ templates/gRPC-Core.podspec.template | 12 +----- tools/doxygen/Doxyfile.c++.internal | 3 ++ tools/doxygen/Doxyfile.core.internal | 8 ++++ .../generated/sources_and_headers.json | 38 ++++++------------- 16 files changed, 173 insertions(+), 64 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index 10b514f8f2e..a1933c125cf 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -481,18 +481,24 @@ config("grpc_config") { "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/cfstream_handle.cc", + "src/core/lib/iomgr/cfstream_handle.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_cfstream.cc", + "src/core/lib/iomgr/endpoint_cfstream.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_cfstream.cc", + "src/core/lib/iomgr/error_cfstream.h", "src/core/lib/iomgr/error_internal.h", "src/core/lib/iomgr/ev_epoll1_linux.cc", "src/core/lib/iomgr/ev_epoll1_linux.h", @@ -528,6 +534,7 @@ config("grpc_config") { "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_posix_cfstream.cc", "src/core/lib/iomgr/iomgr_uv.cc", "src/core/lib/iomgr/iomgr_windows.cc", "src/core/lib/iomgr/is_epollexclusive_available.cc", @@ -583,6 +590,7 @@ config("grpc_config") { "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_cfstream.cc", "src/core/lib/iomgr/tcp_client_custom.cc", "src/core/lib/iomgr/tcp_client_posix.cc", "src/core/lib/iomgr/tcp_client_posix.h", @@ -1175,12 +1183,15 @@ config("grpc_config") { "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/cfstream_handle.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_cfstream.h", "src/core/lib/iomgr/endpoint_pair.h", "src/core/lib/iomgr/error.h", + "src/core/lib/iomgr/error_cfstream.h", "src/core/lib/iomgr/error_internal.h", "src/core/lib/iomgr/ev_epoll1_linux.h", "src/core/lib/iomgr/ev_epollex_linux.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index ee8712f1d38..1947ac038e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -996,12 +996,15 @@ add_library(grpc src/core/lib/http/parser.cc src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.cc 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_cfstream.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc src/core/lib/iomgr/ev_poll_posix.cc @@ -1022,6 +1025,7 @@ add_library(grpc src/core/lib/iomgr/iomgr_custom.cc src/core/lib/iomgr/iomgr_internal.cc src/core/lib/iomgr/iomgr_posix.cc + src/core/lib/iomgr/iomgr_posix_cfstream.cc src/core/lib/iomgr/iomgr_uv.cc src/core/lib/iomgr/iomgr_windows.cc src/core/lib/iomgr/is_epollexclusive_available.cc @@ -1050,6 +1054,7 @@ add_library(grpc src/core/lib/iomgr/socket_utils_windows.cc src/core/lib/iomgr/socket_windows.cc src/core/lib/iomgr/tcp_client.cc + src/core/lib/iomgr/tcp_client_cfstream.cc src/core/lib/iomgr/tcp_client_custom.cc src/core/lib/iomgr/tcp_client_posix.cc src/core/lib/iomgr/tcp_client_windows.cc @@ -1423,12 +1428,15 @@ add_library(grpc_cronet src/core/lib/http/parser.cc src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.cc 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_cfstream.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc src/core/lib/iomgr/ev_poll_posix.cc @@ -1449,6 +1457,7 @@ add_library(grpc_cronet src/core/lib/iomgr/iomgr_custom.cc src/core/lib/iomgr/iomgr_internal.cc src/core/lib/iomgr/iomgr_posix.cc + src/core/lib/iomgr/iomgr_posix_cfstream.cc src/core/lib/iomgr/iomgr_uv.cc src/core/lib/iomgr/iomgr_windows.cc src/core/lib/iomgr/is_epollexclusive_available.cc @@ -1477,6 +1486,7 @@ add_library(grpc_cronet src/core/lib/iomgr/socket_utils_windows.cc src/core/lib/iomgr/socket_windows.cc src/core/lib/iomgr/tcp_client.cc + src/core/lib/iomgr/tcp_client_cfstream.cc src/core/lib/iomgr/tcp_client_custom.cc src/core/lib/iomgr/tcp_client_posix.cc src/core/lib/iomgr/tcp_client_windows.cc @@ -1835,12 +1845,15 @@ add_library(grpc_test_util src/core/lib/http/parser.cc src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.cc 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_cfstream.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc src/core/lib/iomgr/ev_poll_posix.cc @@ -1861,6 +1874,7 @@ add_library(grpc_test_util src/core/lib/iomgr/iomgr_custom.cc src/core/lib/iomgr/iomgr_internal.cc src/core/lib/iomgr/iomgr_posix.cc + src/core/lib/iomgr/iomgr_posix_cfstream.cc src/core/lib/iomgr/iomgr_uv.cc src/core/lib/iomgr/iomgr_windows.cc src/core/lib/iomgr/is_epollexclusive_available.cc @@ -1889,6 +1903,7 @@ add_library(grpc_test_util src/core/lib/iomgr/socket_utils_windows.cc src/core/lib/iomgr/socket_windows.cc src/core/lib/iomgr/tcp_client.cc + src/core/lib/iomgr/tcp_client_cfstream.cc src/core/lib/iomgr/tcp_client_custom.cc src/core/lib/iomgr/tcp_client_posix.cc src/core/lib/iomgr/tcp_client_windows.cc @@ -2160,12 +2175,15 @@ add_library(grpc_test_util_unsecure src/core/lib/http/parser.cc src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.cc 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_cfstream.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc src/core/lib/iomgr/ev_poll_posix.cc @@ -2186,6 +2204,7 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/iomgr_custom.cc src/core/lib/iomgr/iomgr_internal.cc src/core/lib/iomgr/iomgr_posix.cc + src/core/lib/iomgr/iomgr_posix_cfstream.cc src/core/lib/iomgr/iomgr_uv.cc src/core/lib/iomgr/iomgr_windows.cc src/core/lib/iomgr/is_epollexclusive_available.cc @@ -2214,6 +2233,7 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/socket_utils_windows.cc src/core/lib/iomgr/socket_windows.cc src/core/lib/iomgr/tcp_client.cc + src/core/lib/iomgr/tcp_client_cfstream.cc src/core/lib/iomgr/tcp_client_custom.cc src/core/lib/iomgr/tcp_client_posix.cc src/core/lib/iomgr/tcp_client_windows.cc @@ -2461,12 +2481,15 @@ add_library(grpc_unsecure src/core/lib/http/parser.cc src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.cc 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_cfstream.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc src/core/lib/iomgr/ev_poll_posix.cc @@ -2487,6 +2510,7 @@ add_library(grpc_unsecure src/core/lib/iomgr/iomgr_custom.cc src/core/lib/iomgr/iomgr_internal.cc src/core/lib/iomgr/iomgr_posix.cc + src/core/lib/iomgr/iomgr_posix_cfstream.cc src/core/lib/iomgr/iomgr_uv.cc src/core/lib/iomgr/iomgr_windows.cc src/core/lib/iomgr/is_epollexclusive_available.cc @@ -2515,6 +2539,7 @@ add_library(grpc_unsecure src/core/lib/iomgr/socket_utils_windows.cc src/core/lib/iomgr/socket_windows.cc src/core/lib/iomgr/tcp_client.cc + src/core/lib/iomgr/tcp_client_cfstream.cc src/core/lib/iomgr/tcp_client_custom.cc src/core/lib/iomgr/tcp_client_posix.cc src/core/lib/iomgr/tcp_client_windows.cc @@ -3361,12 +3386,15 @@ add_library(grpc++_cronet src/core/lib/http/parser.cc src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.cc 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_cfstream.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc src/core/lib/iomgr/ev_poll_posix.cc @@ -3387,6 +3415,7 @@ add_library(grpc++_cronet src/core/lib/iomgr/iomgr_custom.cc src/core/lib/iomgr/iomgr_internal.cc src/core/lib/iomgr/iomgr_posix.cc + src/core/lib/iomgr/iomgr_posix_cfstream.cc src/core/lib/iomgr/iomgr_uv.cc src/core/lib/iomgr/iomgr_windows.cc src/core/lib/iomgr/is_epollexclusive_available.cc @@ -3415,6 +3444,7 @@ add_library(grpc++_cronet src/core/lib/iomgr/socket_utils_windows.cc src/core/lib/iomgr/socket_windows.cc src/core/lib/iomgr/tcp_client.cc + src/core/lib/iomgr/tcp_client_cfstream.cc src/core/lib/iomgr/tcp_client_custom.cc src/core/lib/iomgr/tcp_client_posix.cc src/core/lib/iomgr/tcp_client_windows.cc diff --git a/Makefile b/Makefile index c7fbca51225..aa221d60889 100644 --- a/Makefile +++ b/Makefile @@ -3452,12 +3452,15 @@ LIBGRPC_SRC = \ src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.cc \ 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_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -3478,6 +3481,7 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/iomgr_custom.cc \ src/core/lib/iomgr/iomgr_internal.cc \ src/core/lib/iomgr/iomgr_posix.cc \ + src/core/lib/iomgr/iomgr_posix_cfstream.cc \ src/core/lib/iomgr/iomgr_uv.cc \ src/core/lib/iomgr/iomgr_windows.cc \ src/core/lib/iomgr/is_epollexclusive_available.cc \ @@ -3506,6 +3510,7 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/socket_utils_windows.cc \ src/core/lib/iomgr/socket_windows.cc \ src/core/lib/iomgr/tcp_client.cc \ + src/core/lib/iomgr/tcp_client_cfstream.cc \ src/core/lib/iomgr/tcp_client_custom.cc \ src/core/lib/iomgr/tcp_client_posix.cc \ src/core/lib/iomgr/tcp_client_windows.cc \ @@ -3873,12 +3878,15 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.cc \ 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_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -3899,6 +3907,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/iomgr_custom.cc \ src/core/lib/iomgr/iomgr_internal.cc \ src/core/lib/iomgr/iomgr_posix.cc \ + src/core/lib/iomgr/iomgr_posix_cfstream.cc \ src/core/lib/iomgr/iomgr_uv.cc \ src/core/lib/iomgr/iomgr_windows.cc \ src/core/lib/iomgr/is_epollexclusive_available.cc \ @@ -3927,6 +3936,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/socket_utils_windows.cc \ src/core/lib/iomgr/socket_windows.cc \ src/core/lib/iomgr/tcp_client.cc \ + src/core/lib/iomgr/tcp_client_cfstream.cc \ src/core/lib/iomgr/tcp_client_custom.cc \ src/core/lib/iomgr/tcp_client_posix.cc \ src/core/lib/iomgr/tcp_client_windows.cc \ @@ -4278,12 +4288,15 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.cc \ 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_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -4304,6 +4317,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/iomgr_custom.cc \ src/core/lib/iomgr/iomgr_internal.cc \ src/core/lib/iomgr/iomgr_posix.cc \ + src/core/lib/iomgr/iomgr_posix_cfstream.cc \ src/core/lib/iomgr/iomgr_uv.cc \ src/core/lib/iomgr/iomgr_windows.cc \ src/core/lib/iomgr/is_epollexclusive_available.cc \ @@ -4332,6 +4346,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/socket_utils_windows.cc \ src/core/lib/iomgr/socket_windows.cc \ src/core/lib/iomgr/tcp_client.cc \ + src/core/lib/iomgr/tcp_client_cfstream.cc \ src/core/lib/iomgr/tcp_client_custom.cc \ src/core/lib/iomgr/tcp_client_posix.cc \ src/core/lib/iomgr/tcp_client_windows.cc \ @@ -4590,12 +4605,15 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.cc \ 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_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -4616,6 +4634,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/iomgr_custom.cc \ src/core/lib/iomgr/iomgr_internal.cc \ src/core/lib/iomgr/iomgr_posix.cc \ + src/core/lib/iomgr/iomgr_posix_cfstream.cc \ src/core/lib/iomgr/iomgr_uv.cc \ src/core/lib/iomgr/iomgr_windows.cc \ src/core/lib/iomgr/is_epollexclusive_available.cc \ @@ -4644,6 +4663,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/socket_utils_windows.cc \ src/core/lib/iomgr/socket_windows.cc \ src/core/lib/iomgr/tcp_client.cc \ + src/core/lib/iomgr/tcp_client_cfstream.cc \ src/core/lib/iomgr/tcp_client_custom.cc \ src/core/lib/iomgr/tcp_client_posix.cc \ src/core/lib/iomgr/tcp_client_windows.cc \ @@ -4865,12 +4885,15 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.cc \ 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_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -4891,6 +4914,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/iomgr_custom.cc \ src/core/lib/iomgr/iomgr_internal.cc \ src/core/lib/iomgr/iomgr_posix.cc \ + src/core/lib/iomgr/iomgr_posix_cfstream.cc \ src/core/lib/iomgr/iomgr_uv.cc \ src/core/lib/iomgr/iomgr_windows.cc \ src/core/lib/iomgr/is_epollexclusive_available.cc \ @@ -4919,6 +4943,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/socket_utils_windows.cc \ src/core/lib/iomgr/socket_windows.cc \ src/core/lib/iomgr/tcp_client.cc \ + src/core/lib/iomgr/tcp_client_cfstream.cc \ src/core/lib/iomgr/tcp_client_custom.cc \ src/core/lib/iomgr/tcp_client_posix.cc \ src/core/lib/iomgr/tcp_client_windows.cc \ @@ -5741,12 +5766,15 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.cc \ 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_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -5767,6 +5795,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/iomgr_custom.cc \ src/core/lib/iomgr/iomgr_internal.cc \ src/core/lib/iomgr/iomgr_posix.cc \ + src/core/lib/iomgr/iomgr_posix_cfstream.cc \ src/core/lib/iomgr/iomgr_uv.cc \ src/core/lib/iomgr/iomgr_windows.cc \ src/core/lib/iomgr/is_epollexclusive_available.cc \ @@ -5795,6 +5824,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/socket_utils_windows.cc \ src/core/lib/iomgr/socket_windows.cc \ src/core/lib/iomgr/tcp_client.cc \ + src/core/lib/iomgr/tcp_client_cfstream.cc \ src/core/lib/iomgr/tcp_client_custom.cc \ src/core/lib/iomgr/tcp_client_posix.cc \ src/core/lib/iomgr/tcp_client_windows.cc \ diff --git a/build.yaml b/build.yaml index 4593be986bf..e098a1876cb 100644 --- a/build.yaml +++ b/build.yaml @@ -258,12 +258,15 @@ filegroups: - src/core/lib/http/parser.cc - src/core/lib/iomgr/buffer_list.cc - src/core/lib/iomgr/call_combiner.cc + - src/core/lib/iomgr/cfstream_handle.cc - src/core/lib/iomgr/combiner.cc - src/core/lib/iomgr/endpoint.cc + - src/core/lib/iomgr/endpoint_cfstream.cc - 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_cfstream.cc - src/core/lib/iomgr/ev_epoll1_linux.cc - src/core/lib/iomgr/ev_epollex_linux.cc - src/core/lib/iomgr/ev_poll_posix.cc @@ -284,6 +287,7 @@ filegroups: - src/core/lib/iomgr/iomgr_custom.cc - src/core/lib/iomgr/iomgr_internal.cc - src/core/lib/iomgr/iomgr_posix.cc + - src/core/lib/iomgr/iomgr_posix_cfstream.cc - src/core/lib/iomgr/iomgr_uv.cc - src/core/lib/iomgr/iomgr_windows.cc - src/core/lib/iomgr/is_epollexclusive_available.cc @@ -312,6 +316,7 @@ filegroups: - src/core/lib/iomgr/socket_utils_windows.cc - src/core/lib/iomgr/socket_windows.cc - src/core/lib/iomgr/tcp_client.cc + - src/core/lib/iomgr/tcp_client_cfstream.cc - src/core/lib/iomgr/tcp_client_custom.cc - src/core/lib/iomgr/tcp_client_posix.cc - src/core/lib/iomgr/tcp_client_windows.cc @@ -439,12 +444,15 @@ filegroups: - 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/cfstream_handle.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_cfstream.h - src/core/lib/iomgr/endpoint_pair.h - src/core/lib/iomgr/error.h + - src/core/lib/iomgr/error_cfstream.h - src/core/lib/iomgr/error_internal.h - src/core/lib/iomgr/ev_epoll1_linux.h - src/core/lib/iomgr/ev_epollex_linux.h @@ -545,20 +553,6 @@ filegroups: uses: - grpc_codegen - grpc_trace_headers -- name: grpc_cfstream - headers: - - src/core/lib/iomgr/cfstream_handle.h - - src/core/lib/iomgr/endpoint_cfstream.h - - src/core/lib/iomgr/error_cfstream.h - src: - - src/core/lib/iomgr/cfstream_handle.cc - - src/core/lib/iomgr/endpoint_cfstream.cc - - src/core/lib/iomgr/error_cfstream.cc - - src/core/lib/iomgr/iomgr_posix_cfstream.cc - - src/core/lib/iomgr/tcp_client_cfstream.cc - uses: - - grpc_base_headers - - gpr_base_headers - name: grpc_client_authority_filter headers: - src/core/ext/filters/http/client_authority_filter.h diff --git a/config.m4 b/config.m4 index ab2a717cbcd..92a86eb9962 100644 --- a/config.m4 +++ b/config.m4 @@ -110,12 +110,15 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.cc \ 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_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -136,6 +139,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/iomgr_custom.cc \ src/core/lib/iomgr/iomgr_internal.cc \ src/core/lib/iomgr/iomgr_posix.cc \ + src/core/lib/iomgr/iomgr_posix_cfstream.cc \ src/core/lib/iomgr/iomgr_uv.cc \ src/core/lib/iomgr/iomgr_windows.cc \ src/core/lib/iomgr/is_epollexclusive_available.cc \ @@ -164,6 +168,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/socket_utils_windows.cc \ src/core/lib/iomgr/socket_windows.cc \ src/core/lib/iomgr/tcp_client.cc \ + src/core/lib/iomgr/tcp_client_cfstream.cc \ src/core/lib/iomgr/tcp_client_custom.cc \ src/core/lib/iomgr/tcp_client_posix.cc \ src/core/lib/iomgr/tcp_client_windows.cc \ diff --git a/config.w32 b/config.w32 index 02eb773ebb8..81d3ff3daf8 100644 --- a/config.w32 +++ b/config.w32 @@ -85,12 +85,15 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\http\\parser.cc " + "src\\core\\lib\\iomgr\\buffer_list.cc " + "src\\core\\lib\\iomgr\\call_combiner.cc " + + "src\\core\\lib\\iomgr\\cfstream_handle.cc " + "src\\core\\lib\\iomgr\\combiner.cc " + "src\\core\\lib\\iomgr\\endpoint.cc " + + "src\\core\\lib\\iomgr\\endpoint_cfstream.cc " + "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_cfstream.cc " + "src\\core\\lib\\iomgr\\ev_epoll1_linux.cc " + "src\\core\\lib\\iomgr\\ev_epollex_linux.cc " + "src\\core\\lib\\iomgr\\ev_poll_posix.cc " + @@ -111,6 +114,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\iomgr_custom.cc " + "src\\core\\lib\\iomgr\\iomgr_internal.cc " + "src\\core\\lib\\iomgr\\iomgr_posix.cc " + + "src\\core\\lib\\iomgr\\iomgr_posix_cfstream.cc " + "src\\core\\lib\\iomgr\\iomgr_uv.cc " + "src\\core\\lib\\iomgr\\iomgr_windows.cc " + "src\\core\\lib\\iomgr\\is_epollexclusive_available.cc " + @@ -139,6 +143,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\socket_utils_windows.cc " + "src\\core\\lib\\iomgr\\socket_windows.cc " + "src\\core\\lib\\iomgr\\tcp_client.cc " + + "src\\core\\lib\\iomgr\\tcp_client_cfstream.cc " + "src\\core\\lib\\iomgr\\tcp_client_custom.cc " + "src\\core\\lib\\iomgr\\tcp_client_posix.cc " + "src\\core\\lib\\iomgr\\tcp_client_windows.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 74f758e6487..2f28c081851 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -431,12 +431,15 @@ Pod::Spec.new do |s| '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/cfstream_handle.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_cfstream.h', 'src/core/lib/iomgr/endpoint_pair.h', 'src/core/lib/iomgr/error.h', + 'src/core/lib/iomgr/error_cfstream.h', 'src/core/lib/iomgr/error_internal.h', 'src/core/lib/iomgr/ev_epoll1_linux.h', 'src/core/lib/iomgr/ev_epollex_linux.h', @@ -624,12 +627,15 @@ Pod::Spec.new do |s| '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/cfstream_handle.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_cfstream.h', 'src/core/lib/iomgr/endpoint_pair.h', 'src/core/lib/iomgr/error.h', + 'src/core/lib/iomgr/error_cfstream.h', 'src/core/lib/iomgr/error_internal.h', 'src/core/lib/iomgr/ev_epoll1_linux.h', 'src/core/lib/iomgr/ev_epollex_linux.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 5cf45c63cef..5874d9ad14b 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -413,12 +413,15 @@ Pod::Spec.new do |s| '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/cfstream_handle.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_cfstream.h', 'src/core/lib/iomgr/endpoint_pair.h', 'src/core/lib/iomgr/error.h', + 'src/core/lib/iomgr/error_cfstream.h', 'src/core/lib/iomgr/error_internal.h', 'src/core/lib/iomgr/ev_epoll1_linux.h', 'src/core/lib/iomgr/ev_epollex_linux.h', @@ -561,12 +564,15 @@ Pod::Spec.new do |s| 'src/core/lib/http/parser.cc', 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.cc', '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_cfstream.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', @@ -587,6 +593,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/iomgr_custom.cc', 'src/core/lib/iomgr/iomgr_internal.cc', 'src/core/lib/iomgr/iomgr_posix.cc', + 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', 'src/core/lib/iomgr/iomgr_uv.cc', 'src/core/lib/iomgr/iomgr_windows.cc', 'src/core/lib/iomgr/is_epollexclusive_available.cc', @@ -615,6 +622,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/socket_utils_windows.cc', 'src/core/lib/iomgr/socket_windows.cc', 'src/core/lib/iomgr/tcp_client.cc', + 'src/core/lib/iomgr/tcp_client_cfstream.cc', 'src/core/lib/iomgr/tcp_client_custom.cc', 'src/core/lib/iomgr/tcp_client_posix.cc', 'src/core/lib/iomgr/tcp_client_windows.cc', @@ -859,15 +867,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/http/client_authority_filter.cc', 'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc', 'src/core/ext/filters/workarounds/workaround_utils.cc', - 'src/core/plugin_registry/grpc_plugin_registry.cc', - 'src/core/lib/iomgr/cfstream_handle.cc', - 'src/core/lib/iomgr/endpoint_cfstream.cc', - 'src/core/lib/iomgr/error_cfstream.cc', - 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', - 'src/core/lib/iomgr/tcp_client_cfstream.cc', - 'src/core/lib/iomgr/cfstream_handle.h', - 'src/core/lib/iomgr/endpoint_cfstream.h', - 'src/core/lib/iomgr/error_cfstream.h' + 'src/core/plugin_registry/grpc_plugin_registry.cc' ss.private_header_files = 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', @@ -1055,12 +1055,15 @@ Pod::Spec.new do |s| '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/cfstream_handle.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_cfstream.h', 'src/core/lib/iomgr/endpoint_pair.h', 'src/core/lib/iomgr/error.h', + 'src/core/lib/iomgr/error_cfstream.h', 'src/core/lib/iomgr/error_internal.h', 'src/core/lib/iomgr/ev_epoll1_linux.h', 'src/core/lib/iomgr/ev_epollex_linux.h', @@ -1175,10 +1178,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', 'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h', - 'src/core/ext/filters/workarounds/workaround_utils.h', - 'src/core/lib/iomgr/cfstream_handle.h', - 'src/core/lib/iomgr/endpoint_cfstream.h', - 'src/core/lib/iomgr/error_cfstream.h' + 'src/core/ext/filters/workarounds/workaround_utils.h' end # CFStream is now default. Leaving this subspec only for compatibility purpose. diff --git a/grpc.gemspec b/grpc.gemspec index 15c26f11569..3fcaeb60657 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -347,12 +347,15 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/block_annotate.h ) s.files += %w( src/core/lib/iomgr/buffer_list.h ) s.files += %w( src/core/lib/iomgr/call_combiner.h ) + s.files += %w( src/core/lib/iomgr/cfstream_handle.h ) s.files += %w( src/core/lib/iomgr/closure.h ) s.files += %w( src/core/lib/iomgr/combiner.h ) s.files += %w( src/core/lib/iomgr/dynamic_annotations.h ) s.files += %w( src/core/lib/iomgr/endpoint.h ) + s.files += %w( src/core/lib/iomgr/endpoint_cfstream.h ) s.files += %w( src/core/lib/iomgr/endpoint_pair.h ) s.files += %w( src/core/lib/iomgr/error.h ) + s.files += %w( src/core/lib/iomgr/error_cfstream.h ) s.files += %w( src/core/lib/iomgr/error_internal.h ) s.files += %w( src/core/lib/iomgr/ev_epoll1_linux.h ) s.files += %w( src/core/lib/iomgr/ev_epollex_linux.h ) @@ -495,12 +498,15 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/http/parser.cc ) s.files += %w( src/core/lib/iomgr/buffer_list.cc ) s.files += %w( src/core/lib/iomgr/call_combiner.cc ) + s.files += %w( src/core/lib/iomgr/cfstream_handle.cc ) s.files += %w( src/core/lib/iomgr/combiner.cc ) s.files += %w( src/core/lib/iomgr/endpoint.cc ) + s.files += %w( src/core/lib/iomgr/endpoint_cfstream.cc ) s.files += %w( src/core/lib/iomgr/endpoint_pair_posix.cc ) s.files += %w( src/core/lib/iomgr/endpoint_pair_uv.cc ) s.files += %w( src/core/lib/iomgr/endpoint_pair_windows.cc ) s.files += %w( src/core/lib/iomgr/error.cc ) + s.files += %w( src/core/lib/iomgr/error_cfstream.cc ) s.files += %w( src/core/lib/iomgr/ev_epoll1_linux.cc ) s.files += %w( src/core/lib/iomgr/ev_epollex_linux.cc ) s.files += %w( src/core/lib/iomgr/ev_poll_posix.cc ) @@ -521,6 +527,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/iomgr_custom.cc ) s.files += %w( src/core/lib/iomgr/iomgr_internal.cc ) s.files += %w( src/core/lib/iomgr/iomgr_posix.cc ) + s.files += %w( src/core/lib/iomgr/iomgr_posix_cfstream.cc ) s.files += %w( src/core/lib/iomgr/iomgr_uv.cc ) s.files += %w( src/core/lib/iomgr/iomgr_windows.cc ) s.files += %w( src/core/lib/iomgr/is_epollexclusive_available.cc ) @@ -549,6 +556,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/socket_utils_windows.cc ) s.files += %w( src/core/lib/iomgr/socket_windows.cc ) s.files += %w( src/core/lib/iomgr/tcp_client.cc ) + s.files += %w( src/core/lib/iomgr/tcp_client_cfstream.cc ) s.files += %w( src/core/lib/iomgr/tcp_client_custom.cc ) s.files += %w( src/core/lib/iomgr/tcp_client_posix.cc ) s.files += %w( src/core/lib/iomgr/tcp_client_windows.cc ) diff --git a/grpc.gyp b/grpc.gyp index 40dc88d7474..61b0aa16666 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -292,12 +292,15 @@ 'src/core/lib/http/parser.cc', 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.cc', '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_cfstream.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', @@ -318,6 +321,7 @@ 'src/core/lib/iomgr/iomgr_custom.cc', 'src/core/lib/iomgr/iomgr_internal.cc', 'src/core/lib/iomgr/iomgr_posix.cc', + 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', 'src/core/lib/iomgr/iomgr_uv.cc', 'src/core/lib/iomgr/iomgr_windows.cc', 'src/core/lib/iomgr/is_epollexclusive_available.cc', @@ -346,6 +350,7 @@ 'src/core/lib/iomgr/socket_utils_windows.cc', 'src/core/lib/iomgr/socket_windows.cc', 'src/core/lib/iomgr/tcp_client.cc', + 'src/core/lib/iomgr/tcp_client_cfstream.cc', 'src/core/lib/iomgr/tcp_client_custom.cc', 'src/core/lib/iomgr/tcp_client_posix.cc', 'src/core/lib/iomgr/tcp_client_windows.cc', @@ -660,12 +665,15 @@ 'src/core/lib/http/parser.cc', 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.cc', '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_cfstream.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', @@ -686,6 +694,7 @@ 'src/core/lib/iomgr/iomgr_custom.cc', 'src/core/lib/iomgr/iomgr_internal.cc', 'src/core/lib/iomgr/iomgr_posix.cc', + 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', 'src/core/lib/iomgr/iomgr_uv.cc', 'src/core/lib/iomgr/iomgr_windows.cc', 'src/core/lib/iomgr/is_epollexclusive_available.cc', @@ -714,6 +723,7 @@ 'src/core/lib/iomgr/socket_utils_windows.cc', 'src/core/lib/iomgr/socket_windows.cc', 'src/core/lib/iomgr/tcp_client.cc', + 'src/core/lib/iomgr/tcp_client_cfstream.cc', 'src/core/lib/iomgr/tcp_client_custom.cc', 'src/core/lib/iomgr/tcp_client_posix.cc', 'src/core/lib/iomgr/tcp_client_windows.cc', @@ -905,12 +915,15 @@ 'src/core/lib/http/parser.cc', 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.cc', '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_cfstream.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', @@ -931,6 +944,7 @@ 'src/core/lib/iomgr/iomgr_custom.cc', 'src/core/lib/iomgr/iomgr_internal.cc', 'src/core/lib/iomgr/iomgr_posix.cc', + 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', 'src/core/lib/iomgr/iomgr_uv.cc', 'src/core/lib/iomgr/iomgr_windows.cc', 'src/core/lib/iomgr/is_epollexclusive_available.cc', @@ -959,6 +973,7 @@ 'src/core/lib/iomgr/socket_utils_windows.cc', 'src/core/lib/iomgr/socket_windows.cc', 'src/core/lib/iomgr/tcp_client.cc', + 'src/core/lib/iomgr/tcp_client_cfstream.cc', 'src/core/lib/iomgr/tcp_client_custom.cc', 'src/core/lib/iomgr/tcp_client_posix.cc', 'src/core/lib/iomgr/tcp_client_windows.cc', @@ -1126,12 +1141,15 @@ 'src/core/lib/http/parser.cc', 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.cc', '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_cfstream.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', @@ -1152,6 +1170,7 @@ 'src/core/lib/iomgr/iomgr_custom.cc', 'src/core/lib/iomgr/iomgr_internal.cc', 'src/core/lib/iomgr/iomgr_posix.cc', + 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', 'src/core/lib/iomgr/iomgr_uv.cc', 'src/core/lib/iomgr/iomgr_windows.cc', 'src/core/lib/iomgr/is_epollexclusive_available.cc', @@ -1180,6 +1199,7 @@ 'src/core/lib/iomgr/socket_utils_windows.cc', 'src/core/lib/iomgr/socket_windows.cc', 'src/core/lib/iomgr/tcp_client.cc', + 'src/core/lib/iomgr/tcp_client_cfstream.cc', 'src/core/lib/iomgr/tcp_client_custom.cc', 'src/core/lib/iomgr/tcp_client_posix.cc', 'src/core/lib/iomgr/tcp_client_windows.cc', diff --git a/package.xml b/package.xml index c3f4e17dd12..99dd96adcee 100644 --- a/package.xml +++ b/package.xml @@ -352,12 +352,15 @@ + + + @@ -500,12 +503,15 @@ + + + @@ -526,6 +532,7 @@ + @@ -554,6 +561,7 @@ + diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 12a47e71d7e..77a079519e9 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -84,12 +84,15 @@ CORE_SOURCE_FILES = [ 'src/core/lib/http/parser.cc', 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.cc', '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_cfstream.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', @@ -110,6 +113,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/iomgr_custom.cc', 'src/core/lib/iomgr/iomgr_internal.cc', 'src/core/lib/iomgr/iomgr_posix.cc', + 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', 'src/core/lib/iomgr/iomgr_uv.cc', 'src/core/lib/iomgr/iomgr_windows.cc', 'src/core/lib/iomgr/is_epollexclusive_available.cc', @@ -138,6 +142,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/socket_utils_windows.cc', 'src/core/lib/iomgr/socket_windows.cc', 'src/core/lib/iomgr/tcp_client.cc', + 'src/core/lib/iomgr/tcp_client_cfstream.cc', 'src/core/lib/iomgr/tcp_client_custom.cc', 'src/core/lib/iomgr/tcp_client_posix.cc', 'src/core/lib/iomgr/tcp_client_windows.cc', diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 93939735c56..89a1e9188ff 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -70,14 +70,6 @@ excl = grpc_private_files(libs) return [file for file in out if not file in excl] - def cfstream_private_headers(libs): - out = grpc_lib_files(libs, ("grpc_cfstream",), ("own_headers",)) - return out - - def cfstream_private_files(libs): - out = grpc_lib_files(libs, ("grpc_cfstream",), ("own_src", "own_headers")) - return out - def ruby_multiline_list(files, indent): return (',\n' + indent*' ').join('\'%s\'' % f for f in files) %> @@ -183,9 +175,9 @@ ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS' # To save you from scrolling, this is the last part of the podspec. - ss.source_files = ${ruby_multiline_list(grpc_private_files(libs) + cfstream_private_files(filegroups), 22)} + ss.source_files = ${ruby_multiline_list(grpc_private_files(libs), 22)} - ss.private_header_files = ${ruby_multiline_list(grpc_private_headers(libs) + cfstream_private_headers(filegroups), 30)} + ss.private_header_files = ${ruby_multiline_list(grpc_private_headers(libs), 30)} end # CFStream is now default. Leaving this subspec only for compatibility purpose. diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c48c15bd1f5..c6fde9b12ed 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1100,12 +1100,15 @@ 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/cfstream_handle.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_cfstream.h \ src/core/lib/iomgr/endpoint_pair.h \ src/core/lib/iomgr/error.h \ +src/core/lib/iomgr/error_cfstream.h \ src/core/lib/iomgr/error_internal.h \ src/core/lib/iomgr/ev_epoll1_linux.h \ src/core/lib/iomgr/ev_epollex_linux.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index dad6c98269d..d150caf6480 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1190,18 +1190,24 @@ 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/cfstream_handle.cc \ +src/core/lib/iomgr/cfstream_handle.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_cfstream.cc \ +src/core/lib/iomgr/endpoint_cfstream.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_cfstream.cc \ +src/core/lib/iomgr/error_cfstream.h \ src/core/lib/iomgr/error_internal.h \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epoll1_linux.h \ @@ -1237,6 +1243,7 @@ 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_posix_cfstream.cc \ src/core/lib/iomgr/iomgr_uv.cc \ src/core/lib/iomgr/iomgr_windows.cc \ src/core/lib/iomgr/is_epollexclusive_available.cc \ @@ -1292,6 +1299,7 @@ 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_cfstream.cc \ src/core/lib/iomgr/tcp_client_custom.cc \ src/core/lib/iomgr/tcp_client_posix.cc \ src/core/lib/iomgr/tcp_client_posix.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index bd6d68bc5c3..99b47036dd5 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8214,12 +8214,15 @@ "src/core/lib/http/parser.cc", "src/core/lib/iomgr/buffer_list.cc", "src/core/lib/iomgr/call_combiner.cc", + "src/core/lib/iomgr/cfstream_handle.cc", "src/core/lib/iomgr/combiner.cc", "src/core/lib/iomgr/endpoint.cc", + "src/core/lib/iomgr/endpoint_cfstream.cc", "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_cfstream.cc", "src/core/lib/iomgr/ev_epoll1_linux.cc", "src/core/lib/iomgr/ev_epollex_linux.cc", "src/core/lib/iomgr/ev_poll_posix.cc", @@ -8240,6 +8243,7 @@ "src/core/lib/iomgr/iomgr_custom.cc", "src/core/lib/iomgr/iomgr_internal.cc", "src/core/lib/iomgr/iomgr_posix.cc", + "src/core/lib/iomgr/iomgr_posix_cfstream.cc", "src/core/lib/iomgr/iomgr_uv.cc", "src/core/lib/iomgr/iomgr_windows.cc", "src/core/lib/iomgr/is_epollexclusive_available.cc", @@ -8268,6 +8272,7 @@ "src/core/lib/iomgr/socket_utils_windows.cc", "src/core/lib/iomgr/socket_windows.cc", "src/core/lib/iomgr/tcp_client.cc", + "src/core/lib/iomgr/tcp_client_cfstream.cc", "src/core/lib/iomgr/tcp_client_custom.cc", "src/core/lib/iomgr/tcp_client_posix.cc", "src/core/lib/iomgr/tcp_client_windows.cc", @@ -8396,12 +8401,15 @@ "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/cfstream_handle.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_cfstream.h", "src/core/lib/iomgr/endpoint_pair.h", "src/core/lib/iomgr/error.h", + "src/core/lib/iomgr/error_cfstream.h", "src/core/lib/iomgr/error_internal.h", "src/core/lib/iomgr/ev_epoll1_linux.h", "src/core/lib/iomgr/ev_epollex_linux.h", @@ -8549,12 +8557,15 @@ "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/cfstream_handle.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_cfstream.h", "src/core/lib/iomgr/endpoint_pair.h", "src/core/lib/iomgr/error.h", + "src/core/lib/iomgr/error_cfstream.h", "src/core/lib/iomgr/error_internal.h", "src/core/lib/iomgr/ev_epoll1_linux.h", "src/core/lib/iomgr/ev_epollex_linux.h", @@ -8654,33 +8665,6 @@ "third_party": false, "type": "filegroup" }, - { - "deps": [ - "gpr", - "gpr_base_headers", - "grpc_base_headers" - ], - "headers": [ - "src/core/lib/iomgr/cfstream_handle.h", - "src/core/lib/iomgr/endpoint_cfstream.h", - "src/core/lib/iomgr/error_cfstream.h" - ], - "is_filegroup": true, - "language": "c", - "name": "grpc_cfstream", - "src": [ - "src/core/lib/iomgr/cfstream_handle.cc", - "src/core/lib/iomgr/cfstream_handle.h", - "src/core/lib/iomgr/endpoint_cfstream.cc", - "src/core/lib/iomgr/endpoint_cfstream.h", - "src/core/lib/iomgr/error_cfstream.cc", - "src/core/lib/iomgr/error_cfstream.h", - "src/core/lib/iomgr/iomgr_posix_cfstream.cc", - "src/core/lib/iomgr/tcp_client_cfstream.cc" - ], - "third_party": false, - "type": "filegroup" - }, { "deps": [ "gpr", From 07e899f5f3fbb9cc8c0831cc867cf0466780664a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 19 Apr 2019 14:15:59 -0700 Subject: [PATCH 1907/2143] Separate out message size parsing into a different file to avoid build issues --- BUILD | 2 + BUILD.gn | 2 + CMakeLists.txt | 6 ++ Makefile | 6 ++ build.yaml | 2 + config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + grpc.gyp | 4 + package.xml | 2 + .../client_channel/client_channel_plugin.cc | 2 +- .../message_size/message_size_filter.cc | 96 ++--------------- .../message_size/message_size_filter.h | 31 ------ .../message_size/message_size_parser.cc | 101 ++++++++++++++++++ .../message_size/message_size_parser.h | 55 ++++++++++ src/python/grpcio/grpc_core_dependencies.py | 1 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 7 +- 20 files changed, 206 insertions(+), 121 deletions(-) create mode 100644 src/core/ext/filters/message_size/message_size_parser.cc create mode 100644 src/core/ext/filters/message_size/message_size_parser.h diff --git a/BUILD b/BUILD index 7f99bcdfaca..07db0019138 100644 --- a/BUILD +++ b/BUILD @@ -1099,6 +1099,7 @@ grpc_cc_library( "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/message_size/message_size_parser.cc", ], hdrs = [ "src/core/ext/filters/client_channel/backup_poller.h", @@ -1128,6 +1129,7 @@ grpc_cc_library( "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/message_size/message_size_parser.h", ], language = "c++", deps = [ diff --git a/BUILD.gn b/BUILD.gn index e83def5507d..d75dce49080 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -354,6 +354,8 @@ config("grpc_config") { "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/message_size/message_size_parser.cc", + "src/core/ext/filters/message_size/message_size_parser.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", diff --git a/CMakeLists.txt b/CMakeLists.txt index b221b4e7cd1..56ccbffd0c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1252,6 +1252,7 @@ add_library(grpc 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/message_size/message_size_parser.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 @@ -1608,6 +1609,7 @@ add_library(grpc_cronet 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/message_size/message_size_parser.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 @@ -1989,6 +1991,7 @@ add_library(grpc_test_util 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/message_size/message_size_parser.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 @@ -2315,6 +2318,7 @@ add_library(grpc_test_util_unsecure 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/message_size/message_size_parser.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 @@ -2652,6 +2656,7 @@ add_library(grpc_unsecure 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/message_size/message_size_parser.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 @@ -3523,6 +3528,7 @@ add_library(grpc++_cronet 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/message_size/message_size_parser.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 4f9acb9fc1f..1b371a8431f 100644 --- a/Makefile +++ b/Makefile @@ -3708,6 +3708,7 @@ LIBGRPC_SRC = \ 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/message_size/message_size_parser.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 \ @@ -4058,6 +4059,7 @@ LIBGRPC_CRONET_SRC = \ 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/message_size/message_size_parser.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 \ @@ -4432,6 +4434,7 @@ LIBGRPC_TEST_UTIL_SRC = \ 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/message_size/message_size_parser.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 \ @@ -4745,6 +4748,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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/message_size/message_size_parser.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 \ @@ -5056,6 +5060,7 @@ LIBGRPC_UNSECURE_SRC = \ 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/message_size/message_size_parser.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 \ @@ -5903,6 +5908,7 @@ LIBGRPC++_CRONET_SRC = \ 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/message_size/message_size_parser.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 a180c8c1d28..936cd911b31 100644 --- a/build.yaml +++ b/build.yaml @@ -596,6 +596,7 @@ filegroups: - 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/message_size/message_size_parser.h src: - src/core/ext/filters/client_channel/backup_poller.cc - src/core/ext/filters/client_channel/channel_connectivity.cc @@ -624,6 +625,7 @@ filegroups: - 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/message_size/message_size_parser.cc plugin: grpc_client_channel uses: - grpc_base diff --git a/config.m4 b/config.m4 index e7d3a5daf4e..0710e1e8341 100644 --- a/config.m4 +++ b/config.m4 @@ -366,6 +366,7 @@ if test "$PHP_GRPC" != "no"; then 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/message_size/message_size_parser.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 8a6529faae2..e69f71dbfb3 100644 --- a/config.w32 +++ b/config.w32 @@ -341,6 +341,7 @@ if (PHP_GRPC != "no") { "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\\message_size\\message_size_parser.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 782d86a6fcb..d4f4b626011 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -385,6 +385,7 @@ Pod::Spec.new do |s| '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/message_size/message_size_parser.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 13c2a2cf9d0..aa38487e194 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -367,6 +367,7 @@ Pod::Spec.new do |s| '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/message_size/message_size_parser.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', @@ -815,6 +816,7 @@ Pod::Spec.new do |s| '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/message_size/message_size_parser.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', @@ -1011,6 +1013,7 @@ Pod::Spec.new do |s| '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/message_size/message_size_parser.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 bca4674c761..9749cc69e47 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -301,6 +301,7 @@ Gem::Specification.new do |s| 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/message_size/message_size_parser.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 ) @@ -752,6 +753,7 @@ Gem::Specification.new do |s| 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/message_size/message_size_parser.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 d4db059dc0a..874cc5a52bf 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -548,6 +548,7 @@ '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/message_size/message_size_parser.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', @@ -813,6 +814,7 @@ '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/message_size/message_size_parser.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', @@ -1059,6 +1061,7 @@ '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/message_size/message_size_parser.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', @@ -1316,6 +1319,7 @@ '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/message_size/message_size_parser.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/package.xml b/package.xml index 3af95c9a727..66bf5ee8863 100644 --- a/package.xml +++ b/package.xml @@ -306,6 +306,7 @@ + @@ -757,6 +758,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 92b1fed61d1..729043bebfc 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -35,7 +35,7 @@ #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/retry_throttle.h" -#include "src/core/ext/filters/message_size/message_size_filter.h" +#include "src/core/ext/filters/message_size/message_size_parser.h" #include "src/core/lib/surface/channel_init.h" static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { 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 ac1984f6929..f3976cb783f 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -26,7 +26,7 @@ #include #include -#include "src/core/ext/filters/client_channel/service_config.h" +#include "src/core/ext/filters/message_size/message_size_parser.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" @@ -35,91 +35,10 @@ #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel_init.h" -namespace { -size_t message_size_parser_index; - -// Consumes all the errors in the vector and forms a referencing error from -// them. If the vector is empty, return GRPC_ERROR_NONE. -template -grpc_error* CreateErrorFromVector( - const char* desc, grpc_core::InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; -} -} // namespace - -namespace grpc_core { - -UniquePtr MessageSizeParser::ParsePerMethodParams( - const grpc_json* json, grpc_error** error) { - GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); - int max_request_message_bytes = -1; - int max_response_message_bytes = -1; - InlinedVector error_list; - for (grpc_json* field = json->child; field != nullptr; field = field->next) { - if (field->key == nullptr) continue; - if (strcmp(field->key, "maxRequestMessageBytes") == 0) { - if (max_request_message_bytes >= 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:Duplicate entry")); - } else if (field->type != GRPC_JSON_STRING && - field->type != GRPC_JSON_NUMBER) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:should be of type number")); - } else { - max_request_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_request_message_bytes == -1) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:should be non-negative")); - } - } - } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { - if (max_response_message_bytes >= 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:Duplicate entry")); - } else if (field->type != GRPC_JSON_STRING && - field->type != GRPC_JSON_NUMBER) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:should be of type number")); - } else { - max_response_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_response_message_bytes == -1) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:should be non-negative")); - } - } - } - } - if (!error_list.empty()) { - *error = CreateErrorFromVector("Message size parser", &error_list); - return nullptr; - } - return UniquePtr(New( - max_request_message_bytes, max_response_message_bytes)); -} - -void MessageSizeParser::Register() { - message_size_parser_index = ServiceConfig::RegisterParser( - UniquePtr(New())); -} - -size_t MessageSizeParser::ParserIndex() { return message_size_parser_index; } -} // namespace grpc_core - static void recv_message_ready(void* user_data, grpc_error* error); static void recv_trailing_metadata_ready(void* user_data, grpc_error* error); namespace { - struct channel_data { grpc_core::MessageSizeParsedObject::message_size_limits limits; grpc_core::RefCountedPtr svc_cfg; @@ -140,18 +59,21 @@ struct call_data { // size to the receive limit. const grpc_core::MessageSizeParsedObject* limits = nullptr; const grpc_core::ServiceConfig::ServiceConfigObjectsVector* objs_vector = - static_cast< - const grpc_core::ServiceConfig::ServiceConfigObjectsVector*>( - args.context[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value); + nullptr; + if (args.context != nullptr) { + objs_vector = static_cast< + const grpc_core::ServiceConfig::ServiceConfigObjectsVector*>( + args.context[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value); + } if (objs_vector != nullptr) { limits = static_cast( - (*objs_vector)[message_size_parser_index].get()); + (*objs_vector)[grpc_core::MessageSizeParser::ParserIndex()].get()); } else if (chand.svc_cfg != nullptr) { objs_vector = chand.svc_cfg->GetMethodServiceConfigObjectsVector(args.path); if (objs_vector != nullptr) { limits = static_cast( - (*objs_vector)[message_size_parser_index].get()); + (*objs_vector)[grpc_core::MessageSizeParser::ParserIndex()].get()); } } if (limits != nullptr) { diff --git a/src/core/ext/filters/message_size/message_size_filter.h b/src/core/ext/filters/message_size/message_size_filter.h index a4aa79f70ac..b916bdd83f6 100644 --- a/src/core/ext/filters/message_size/message_size_filter.h +++ b/src/core/ext/filters/message_size/message_size_filter.h @@ -24,35 +24,4 @@ extern const grpc_channel_filter grpc_message_size_filter; -namespace grpc_core { - -class MessageSizeParsedObject : public ServiceConfigParsedObject { - public: - struct message_size_limits { - int max_send_size; - int max_recv_size; - }; - - MessageSizeParsedObject(int max_send_size, int max_recv_size) { - limits_.max_send_size = max_send_size; - limits_.max_recv_size = max_recv_size; - } - - const message_size_limits& limits() const { return limits_; } - - private: - message_size_limits limits_; -}; - -class MessageSizeParser : public ServiceConfigParser { - public: - UniquePtr ParsePerMethodParams( - const grpc_json* json, grpc_error** error) override; - - static void Register(); - - static size_t ParserIndex(); -}; -} // namespace grpc_core - #endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H */ diff --git a/src/core/ext/filters/message_size/message_size_parser.cc b/src/core/ext/filters/message_size/message_size_parser.cc new file mode 100644 index 00000000000..534082ee6ff --- /dev/null +++ b/src/core/ext/filters/message_size/message_size_parser.cc @@ -0,0 +1,101 @@ +// +// 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 "src/core/ext/filters/message_size/message_size_parser.h" + +#include "src/core/lib/gpr/string.h" + +namespace { +size_t g_message_size_parser_index; + +// Consumes all the errors in the vector and forms a referencing error from +// them. If the vector is empty, return GRPC_ERROR_NONE. +template +grpc_error* CreateErrorFromVector( + const char* desc, grpc_core::InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; +} +} // namespace + +namespace grpc_core { + +UniquePtr MessageSizeParser::ParsePerMethodParams( + const grpc_json* json, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + int max_request_message_bytes = -1; + int max_response_message_bytes = -1; + InlinedVector error_list; + for (grpc_json* field = json->child; field != nullptr; field = field->next) { + if (field->key == nullptr) continue; + if (strcmp(field->key, "maxRequestMessageBytes") == 0) { + if (max_request_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:Duplicate entry")); + } else if (field->type != GRPC_JSON_STRING && + field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be of type number")); + } else { + max_request_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_request_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be non-negative")); + } + } + } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { + if (max_response_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:Duplicate entry")); + } else if (field->type != GRPC_JSON_STRING && + field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be of type number")); + } else { + max_response_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_response_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be non-negative")); + } + } + } + } + if (!error_list.empty()) { + *error = CreateErrorFromVector("Message size parser", &error_list); + return nullptr; + } + return UniquePtr(New( + max_request_message_bytes, max_response_message_bytes)); +} + +void MessageSizeParser::Register() { + g_message_size_parser_index = ServiceConfig::RegisterParser( + UniquePtr(New())); +} + +size_t MessageSizeParser::ParserIndex() { return g_message_size_parser_index; } +} // namespace grpc_core diff --git a/src/core/ext/filters/message_size/message_size_parser.h b/src/core/ext/filters/message_size/message_size_parser.h new file mode 100644 index 00000000000..4581cdf6226 --- /dev/null +++ b/src/core/ext/filters/message_size/message_size_parser.h @@ -0,0 +1,55 @@ +// +// 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_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_PARSER_H +#define GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_PARSER_H + +#include + +#include "src/core/ext/filters/client_channel/service_config.h" + +namespace grpc_core { + +class MessageSizeParsedObject : public ServiceConfigParsedObject { + public: + struct message_size_limits { + int max_send_size; + int max_recv_size; + }; + + MessageSizeParsedObject(int max_send_size, int max_recv_size) { + limits_.max_send_size = max_send_size; + limits_.max_recv_size = max_recv_size; + } + + const message_size_limits& limits() const { return limits_; } + + private: + message_size_limits limits_; +}; + +class MessageSizeParser : public ServiceConfigParser { + public: + UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) override; + + static void Register(); + + static size_t ParserIndex(); +}; +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_PARSER_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 8060b5a0a8c..6aa0a37826e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -340,6 +340,7 @@ CORE_SOURCE_FILES = [ '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/message_size/message_size_parser.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/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index eee3f777ea6..88e57036830 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -989,6 +989,8 @@ 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/message_size/message_size_parser.cc \ +src/core/ext/filters/message_size/message_size_parser.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 \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 6a0d47ab932..3b66e146262 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8733,7 +8733,8 @@ "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/client_channel/subchannel_pool_interface.h", + "src/core/ext/filters/message_size/message_size_parser.h" ], "is_filegroup": true, "language": "c", @@ -8792,7 +8793,9 @@ "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/client_channel/subchannel_pool_interface.h", + "src/core/ext/filters/message_size/message_size_parser.cc", + "src/core/ext/filters/message_size/message_size_parser.h" ], "third_party": false, "type": "filegroup" From f5262fe259a3df5b8d2a78be06637b145882ea97 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 12 Apr 2019 15:11:54 -0700 Subject: [PATCH 1908/2143] Update objc examples to use v2 API --- .../auth_sample/MakeRPCViewController.m | 48 ++-- examples/objective-c/helloworld/main.m | 35 ++- examples/objective-c/helloworld_macos/main.m | 33 ++- .../objective-c/route_guide/ViewControllers.m | 243 +++++++++++------- 4 files changed, 239 insertions(+), 120 deletions(-) diff --git a/examples/objective-c/auth_sample/MakeRPCViewController.m b/examples/objective-c/auth_sample/MakeRPCViewController.m index 545deb5fcad..648bbab7cec 100644 --- a/examples/objective-c/auth_sample/MakeRPCViewController.m +++ b/examples/objective-c/auth_sample/MakeRPCViewController.m @@ -46,8 +46,16 @@ static NSString * const kTestHostAddress = @"grpc-test.sandbox.googleapis.com"; } @end +@interface MakeRPCViewController () + +@end + @implementation MakeRPCViewController +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} + - (void)viewWillAppear:(BOOL)animated { // Create a service client and a proto request as usual. @@ -57,28 +65,30 @@ static NSString * const kTestHostAddress = @"grpc-test.sandbox.googleapis.com"; request.fillUsername = YES; request.fillOauthScope = YES; - // Create a not-yet-started RPC. We want to set the request headers on this object before starting - // it. - ProtoRPC *call = - [client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { - if (response) { - // This test server responds with the email and scope of the access token it receives. - self.mainLabel.text = [NSString stringWithFormat:@"Used scope: %@ on behalf of user %@", - response.oauthScope, response.username]; - - } else { - self.mainLabel.text = error.UIDescription; - } - }]; - - // Set the access token to be used. - NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken; - call.requestHeaders[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]; - - // Start the RPC. + // Set the request header with call options + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.oauth2AccessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken; + GRPCUnaryProtoCall *call = [client unaryCallWithMessage:request + responseHandler:self + callOptions:options]; [call start]; self.mainLabel.text = @"Waiting for RPC to complete..."; } +- (void)didReceiveProtoMessage:(GPBMessage *)message { + AUTHResponse *response = (AUTHResponse *)message; + if (response) { + // This test server responds with the email and scope of the access token it receives. + self.mainLabel.text = [NSString stringWithFormat:@"Used scope: %@ on behalf of user %@", + response.oauthScope, response.username]; + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (error) { + self.mainLabel.text = error.UIDescription; + } +} + @end diff --git a/examples/objective-c/helloworld/main.m b/examples/objective-c/helloworld/main.m index c771375d803..649e65bb5b2 100644 --- a/examples/objective-c/helloworld/main.m +++ b/examples/objective-c/helloworld/main.m @@ -25,20 +25,41 @@ static NSString * const kHostAddress = @"localhost:50051"; +@interface HLWResponseHandler : NSObject + +@end + +// A response handler object dispatching messages to main queue +@implementation HLWResponseHandler + +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + NSLog(@"%@", message); +} + +@end + int main(int argc, char * argv[]) { @autoreleasepool { - [GRPCCall useInsecureConnectionsForHost:kHostAddress]; - [GRPCCall setUserAgentPrefix:@"HelloWorld/1.0" forHost:kHostAddress]; - HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress]; HLWHelloRequest *request = [HLWHelloRequest message]; request.name = @"Objective-C"; - [client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { - NSLog(@"%@", response.message); - }]; - + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + // this example does not use TLS (secure channel); use insecure channel instead + options.transportType = GRPCTransportTypeInsecure; + options.userAgentPrefix = @"HelloWorld/1.0"; + + GRPCUnaryProtoCall *call = [client sayHelloWithMessage:request + responseHandler:[[HLWResponseHandler alloc] init] + callOptions:options]; + + [call start]; + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } diff --git a/examples/objective-c/helloworld_macos/main.m b/examples/objective-c/helloworld_macos/main.m index 2a98ec4966c..ce24a9b1466 100644 --- a/examples/objective-c/helloworld_macos/main.m +++ b/examples/objective-c/helloworld_macos/main.m @@ -24,19 +24,40 @@ static NSString * const kHostAddress = @"localhost:50051"; +@interface HLWResponseHandler : NSObject + +@end + +// A response handler object dispatching messages to main queue +@implementation HLWResponseHandler + +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + NSLog(@"%@", message); +} + +@end + int main(int argc, const char * argv[]) { @autoreleasepool { - [GRPCCall useInsecureConnectionsForHost:kHostAddress]; - [GRPCCall setUserAgentPrefix:@"HelloWorld/1.0" forHost:kHostAddress]; - HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress]; HLWHelloRequest *request = [HLWHelloRequest message]; request.name = @"Objective-C"; - [client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { - NSLog(@"%@", response.message); - }]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + // this example does not use TLS (secure channel); use insecure channel instead + options.transportType = GRPCTransportTypeInsecure; + options.userAgentPrefix = @"HelloWorld/1.0"; + + GRPCUnaryProtoCall *call = [client sayHelloWithMessage:request + responseHandler:[[HLWResponseHandler alloc] init] + callOptions:options]; + + [call start]; } return NSApplicationMain(argc, argv); diff --git a/examples/objective-c/route_guide/ViewControllers.m b/examples/objective-c/route_guide/ViewControllers.m index 0f116f3a235..43d2082f585 100644 --- a/examples/objective-c/route_guide/ViewControllers.m +++ b/examples/objective-c/route_guide/ViewControllers.m @@ -17,10 +17,7 @@ */ #import -#import #import -#import -#import static NSString * const kHostAddress = @"localhost:50051"; @@ -65,7 +62,7 @@ static NSString * const kHostAddress = @"localhost:50051"; * Run the getFeature demo. Calls getFeature with a point known to have a feature and a point known * not to have a feature. */ -@interface GetFeatureViewController : UIViewController +@interface GetFeatureViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *outputLabel; @@ -75,39 +72,56 @@ static NSString * const kHostAddress = @"localhost:50051"; RTGRouteGuide *_service; } -- (void)execRequest { - void (^handler)(RTGFeature *response, NSError *error) = ^(RTGFeature *response, NSError *error) { - // TODO(makdharma): Remove boilerplate by consolidating into one log function. - if (response.name.length) { - NSString *str =[NSString stringWithFormat:@"%@\nFound feature called %@ at %@.", self.outputLabel.text, response.location, response.name]; - self.outputLabel.text = str; - NSLog(@"Found feature called %@ at %@.", response.name, response.location); - } else if (response) { - NSString *str =[NSString stringWithFormat:@"%@\nFound no features at %@", self.outputLabel.text,response.location]; - self.outputLabel.text = str; - NSLog(@"Found no features at %@", response.location); - } else { - NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; - self.outputLabel.text = str; - NSLog(@"RPC error: %@", error); - } - }; +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} +- (void)didReceiveProtoMessage:(GPBMessage *)message { + RTGFeature *response = (RTGFeature *)message; + + // TODO(makdharma): Remove boilerplate by consolidating into one log function. + if (response.name.length != 0) { + NSString *str =[NSString stringWithFormat:@"%@\nFound feature called %@ at %@.", self.outputLabel.text, response.location, response.name]; + self.outputLabel.text = str; + NSLog(@"Found feature called %@ at %@.", response.name, response.location); + } else if (response) { + NSString *str =[NSString stringWithFormat:@"%@\nFound no features at %@", self.outputLabel.text,response.location]; + self.outputLabel.text = str; + NSLog(@"Found no features at %@", response.location); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (error) { + NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; + self.outputLabel.text = str; + NSLog(@"RPC error: %@", error); + } +} + +- (void)execRequest { RTGPoint *point = [RTGPoint message]; point.latitude = 409146138; point.longitude = -746188906; - [_service getFeatureWithRequest:point handler:handler]; - [_service getFeatureWithRequest:[RTGPoint message] handler:handler]; + GRPCUnaryProtoCall *call = [_service getFeatureWithMessage:point + responseHandler:self + callOptions:nil]; + [call start]; + call = [_service getFeatureWithMessage:[RTGPoint message] + responseHandler:self + callOptions:nil]; + [call start]; + } - (void)viewDidLoad { [super viewDidLoad]; - // This only needs to be done once per host, before creating service objects for that host. - [GRPCCall useInsecureConnectionsForHost:kHostAddress]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; - _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options]; } - (void)viewDidAppear:(BOOL)animated { @@ -126,7 +140,7 @@ static NSString * const kHostAddress = @"localhost:50051"; * Run the listFeatures demo. Calls listFeatures with a rectangle containing all of the features in * the pre-generated database. Prints each response as it comes in. */ -@interface ListFeaturesViewController : UIViewController +@interface ListFeaturesViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *outputLabel; @@ -136,6 +150,10 @@ static NSString * const kHostAddress = @"localhost:50051"; RTGRouteGuide *_service; } +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} + - (void)execRequest { RTGRectangle *rectangle = [RTGRectangle message]; rectangle.lo.latitude = 405E6; @@ -144,24 +162,36 @@ static NSString * const kHostAddress = @"localhost:50051"; rectangle.hi.longitude = -745E6; NSLog(@"Looking for features between %@ and %@", rectangle.lo, rectangle.hi); - [_service listFeaturesWithRequest:rectangle - eventHandler:^(BOOL done, RTGFeature *response, NSError *error) { - if (response) { - NSString *str =[NSString stringWithFormat:@"%@\nFound feature at %@ called %@.", self.outputLabel.text, response.location, response.name]; - self.outputLabel.text = str; - NSLog(@"Found feature at %@ called %@.", response.location, response.name); - } else if (error) { - NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; - self.outputLabel.text = str; - NSLog(@"RPC error: %@", error); - } - }]; + GRPCUnaryProtoCall *call = [_service listFeaturesWithMessage:rectangle + responseHandler:self + callOptions:nil]; + [call start]; +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + RTGFeature *response = (RTGFeature *)message; + if (response) { + NSString *str =[NSString stringWithFormat:@"%@\nFound feature at %@ called %@.", self.outputLabel.text, response.location, response.name]; + self.outputLabel.text = str; + NSLog(@"Found feature at %@ called %@.", response.location, response.name); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (error) { + NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; + self.outputLabel.text = str; + NSLog(@"RPC error: %@", error); + } } - (void)viewDidLoad { [super viewDidLoad]; - _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + + _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options]; } - (void)viewDidAppear:(BOOL)animated { @@ -173,7 +203,6 @@ static NSString * const kHostAddress = @"localhost:50051"; @end - #pragma mark Demo: Record Route /** @@ -181,7 +210,7 @@ static NSString * const kHostAddress = @"localhost:50051"; * database with a variable delay in between. Prints the statistics when they are sent from the * server. */ -@interface RecordRouteViewController : UIViewController +@interface RecordRouteViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *outputLabel; @@ -191,47 +220,71 @@ static NSString * const kHostAddress = @"localhost:50051"; RTGRouteGuide *_service; } +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} + - (void)execRequest { NSString *dataBasePath = [NSBundle.mainBundle pathForResource:@"route_guide_db" ofType:@"json"]; NSData *dataBaseContent = [NSData dataWithContentsOfFile:dataBasePath]; - NSArray *features = [NSJSONSerialization JSONObjectWithData:dataBaseContent options:0 error:NULL]; + NSError *error; + NSArray *features = [NSJSONSerialization JSONObjectWithData:dataBaseContent options:0 error:&error]; - GRXWriter *locations = [[GRXWriter writerWithContainer:features] map:^id(id feature) { + if (error) { + NSLog(@"Error reading database."); + NSString *str = @"Error reading database."; + self.outputLabel.text = str; + return; + } + + GRPCStreamingProtoCall *call = [_service recordRouteWithResponseHandler:self + callOptions:nil]; + [call start]; + for (id feature in features) { RTGPoint *location = [RTGPoint message]; location.longitude = [((NSNumber *) feature[@"location"][@"longitude"]) intValue]; location.latitude = [((NSNumber *) feature[@"location"][@"latitude"]) intValue]; NSString *str =[NSString stringWithFormat:@"%@\nVisiting point %@", self.outputLabel.text, location]; self.outputLabel.text = str; NSLog(@"Visiting point %@", location); - return location; - }]; + [call writeMessage:location]; + } + [call finish]; +} - [_service recordRouteWithRequestsWriter:locations - handler:^(RTGRouteSummary *response, NSError *error) { - if (response) { - NSString *str =[NSString stringWithFormat: - @"%@\nFinished trip with %i points\nPassed %i features\n" - "Travelled %i meters\nIt took %i seconds", - self.outputLabel.text, response.pointCount, response.featureCount, - response.distance, response.elapsedTime]; - self.outputLabel.text = str; - NSLog(@"Finished trip with %i points", response.pointCount); - NSLog(@"Passed %i features", response.featureCount); - NSLog(@"Travelled %i meters", response.distance); - NSLog(@"It took %i seconds", response.elapsedTime); - } else { - NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; - self.outputLabel.text = str; - NSLog(@"RPC error: %@", error); - } - }]; +- (void)didReceiveProtoMessage:(GPBMessage *)message { + RTGRouteSummary *response = (RTGRouteSummary *)message; + + if (response) { + NSString *str =[NSString stringWithFormat: + @"%@\nFinished trip with %i points\nPassed %i features\n" + "Travelled %i meters\nIt took %i seconds", + self.outputLabel.text, response.pointCount, response.featureCount, + response.distance, response.elapsedTime]; + self.outputLabel.text = str; + NSLog(@"Finished trip with %i points", response.pointCount); + NSLog(@"Passed %i features", response.featureCount); + NSLog(@"Travelled %i meters", response.distance); + NSLog(@"It took %i seconds", response.elapsedTime); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (error) { + NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; + self.outputLabel.text = str; + NSLog(@"RPC error: %@", error); + } } - (void)viewDidLoad { [super viewDidLoad]; - _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + + _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options]; } - (void)viewDidAppear:(BOOL)animated { @@ -250,7 +303,7 @@ static NSString * const kHostAddress = @"localhost:50051"; * Run the routeChat demo. Send some chat messages, and print any chat messages that are sent from * the server. */ -@interface RouteChatViewController : UIViewController +@interface RouteChatViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *outputLabel; @@ -260,38 +313,52 @@ static NSString * const kHostAddress = @"localhost:50051"; RTGRouteGuide *_service; } +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} + - (void)execRequest { NSArray *notes = @[[RTGRouteNote noteWithMessage:@"First message" latitude:0 longitude:0], [RTGRouteNote noteWithMessage:@"Second message" latitude:0 longitude:1], [RTGRouteNote noteWithMessage:@"Third message" latitude:1 longitude:0], [RTGRouteNote noteWithMessage:@"Fourth message" latitude:0 longitude:0]]; - GRXWriter *notesWriter = [[GRXWriter writerWithContainer:notes] map:^id(RTGRouteNote *note) { - NSLog(@"Sending message %@ at %@", note.message, note.location); - return note; - }]; - [_service routeChatWithRequestsWriter:notesWriter - eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) { - if (note) { - NSString *str =[NSString stringWithFormat:@"%@\nGot message %@ at %@", - self.outputLabel.text, note.message, note.location]; - self.outputLabel.text = str; - NSLog(@"Got message %@ at %@", note.message, note.location); - } else if (error) { - NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; - self.outputLabel.text = str; - NSLog(@"RPC error: %@", error); - } - if (done) { - NSLog(@"Chat ended."); - } - }]; + GRPCStreamingProtoCall *call = [_service routeChatWithResponseHandler:self + callOptions:nil]; + [call start]; + for (RTGRouteNote *note in notes) { + [call writeMessage:note]; + } + [call finish]; +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + RTGRouteNote *note = (RTGRouteNote *)message; + if (note) { + NSString *str =[NSString stringWithFormat:@"%@\nGot message %@ at %@", + self.outputLabel.text, note.message, note.location]; + self.outputLabel.text = str; + NSLog(@"Got message %@ at %@", note.message, note.location); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (!error) { + NSLog(@"Chat ended."); + } else { + NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; + self.outputLabel.text = str; + NSLog(@"RPC error: %@", error); + } } - (void)viewDidLoad { [super viewDidLoad]; - _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + + _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options]; } - (void)viewDidAppear:(BOOL)animated { From a4036b2d8cad28e373ab93922e344d109c1a80d7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 19 Apr 2019 14:34:37 -0700 Subject: [PATCH 1909/2143] Add tests for health check parsing too --- .../client_channel/service_config_test.cc | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index be86400e32d..7ea4a88e9bb 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -24,7 +24,7 @@ #include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/service_config.h" -#include "src/core/ext/filters/message_size/message_size_filter.h" +#include "src/core/ext/filters/message_size/message_size_parser.h" #include "src/core/lib/gpr/string.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -1044,6 +1044,59 @@ TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) { EXPECT_TRUE(std::regex_search(s, match, e)); GRPC_ERROR_UNREF(error); } + +class HealthCheckParserTest : public ::testing::Test { + protected: + void SetUp() override { + ServiceConfig::Shutdown(); + ServiceConfig::Init(); + EXPECT_TRUE(ServiceConfig::RegisterParser(UniquePtr( + New())) == 0); + } +}; + +TEST_F(HealthCheckParserTest, Valid) { + const char* test_json = + "{\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name\"\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + ASSERT_TRUE(parsed_object != nullptr); + EXPECT_EQ(strcmp(parsed_object->service_name(), "health_check_service_name"), + 0); +} + +TEST_F(HealthCheckParserTest, MultipleEntries) { + const char* test_json = + "{\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name\"\n" + " },\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name1\"\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(field:healthCheckConfig " + "field:serviceName error:Duplicate entry)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + } // namespace testing } // namespace grpc_core From 34737886219c41ea1469736964e60e9acfedd315 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 19 Apr 2019 14:45:20 -0700 Subject: [PATCH 1910/2143] Remove example build tests that do not depend on changes in a PR or master branch --- tools/run_tests/run_tests.py | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 1c4d20ef6da..a7a9dbd48d0 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1061,33 +1061,6 @@ class ObjCLanguage(object): shortname='objc-plugin-tests', cpu_cost=1e6, environ=_FORCE_ENVIRON_FOR_WRAPPERS), - self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='objc-build-example-helloworld', - cpu_cost=1e6, - environ={ - 'SCHEME': 'HelloWorld', - 'EXAMPLE_PATH': 'examples/objective-c/helloworld' - }), - self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='objc-build-example-routeguide', - cpu_cost=1e6, - environ={ - 'SCHEME': 'RouteGuideClient', - 'EXAMPLE_PATH': 'examples/objective-c/route_guide' - }), - self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='objc-build-example-authsample', - cpu_cost=1e6, - environ={ - 'SCHEME': 'AuthSample', - 'EXAMPLE_PATH': 'examples/objective-c/auth_sample' - }), self.config.job_spec( ['src/objective-c/tests/build_one_example.sh'], timeout_seconds=10 * 60, From baa52808f1e6b4ef3fb62127e989519ad3417e27 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 19 Apr 2019 15:46:16 -0700 Subject: [PATCH 1911/2143] Use a single copy of CreateErrorFromVector from ServiceConfig --- .../filters/client_channel/client_channel.cc | 3 ++ .../client_channel/lb_policy/grpclb/grpclb.cc | 21 ++------------ .../client_channel/lb_policy/xds/xds.cc | 20 +------------ .../client_channel/resolver_result_parsing.cc | 28 ++++--------------- .../filters/client_channel/service_config.cc | 18 ------------ .../filters/client_channel/service_config.h | 18 ++++++++++++ .../message_size/message_size_parser.cc | 21 ++------------ 7 files changed, 31 insertions(+), 98 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index a1029ef67a7..15fe9a8c70a 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -3080,6 +3080,9 @@ void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) { chand, this); } if (chand->service_config() != nullptr) { + // Store a ref to the service_config in CallData. Also, save pointers to the + // ServiceConfig and ServiceConfigObjectsVector (for this call) in the + // call_context so that all future filters can access it. service_config_ = chand->service_config(); call_context_[GRPC_SERVICE_CONFIG].value = &service_config_; const auto* method_params_vector_ptr = 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 a4c28d8d431..d8e942e6570 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 @@ -1798,24 +1798,6 @@ void GrpcLb::CreateOrUpdateChildPolicyLocked() { policy_to_update->UpdateLocked(std::move(update_args)); } -// Consumes all the errors in the vector and forms a referencing error from -// them. If the vector is empty, return GRPC_ERROR_NONE. -template -grpc_error* CreateErrorFromVector(const char* desc, - InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; -} - // // factory // @@ -1858,7 +1840,8 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { return UniquePtr( New(std::move(child_policy))); } else { - *error = CreateErrorFromVector("GrpcLb Parser", &error_list); + *error = + ServiceConfig::CreateErrorFromVector("GrpcLb Parser", &error_list); return 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 7d222558f4d..7b9c2b320fd 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 @@ -1652,24 +1652,6 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::RequestReresolution() { } } -// Consumes all the errors in the vector and forms a referencing error from -// them. If the vector is empty, return GRPC_ERROR_NONE. -template -grpc_error* CreateErrorFromVector(const char* desc, - InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; -} - // // factory // @@ -1743,7 +1725,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { return UniquePtr(New( balancer_name, std::move(child_policy), std::move(fallback_policy))); } else { - *error = CreateErrorFromVector("Xds Parser", &error_list); + *error = ServiceConfig::CreateErrorFromVector("Xds Parser", &error_list); return nullptr; } } 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 1756917b391..dea8c915856 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -79,26 +79,6 @@ ProcessedResolverResult::ProcessedResolverResult( if (lb_policy_name_ == nullptr) ProcessLbPolicyName(*resolver_result); } -namespace { -// Consumes all the errors in the vector and forms a referencing error from -// them. If the vector is empty, return GRPC_ERROR_NONE. -template -grpc_error* CreateErrorFromVector(const char* desc, - InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; -} -} // namespace - void ProcessedResolverResult::ProcessServiceConfig( const Resolver::Result& resolver_result, bool parse_retry) { if (service_config_ == nullptr) return; @@ -349,7 +329,7 @@ UniquePtr ParseRetryPolicy( return nullptr; } } - *error = CreateErrorFromVector("retryPolicy", &error_list); + *error = ServiceConfig::CreateErrorFromVector("retryPolicy", &error_list); return *error == GRPC_ERROR_NONE ? std::move(retry_policy) : nullptr; } @@ -504,7 +484,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, } } } - *error = CreateErrorFromVector("Client channel global parser", &error_list); + *error = ServiceConfig::CreateErrorFromVector("Client channel global parser", + &error_list); if (*error == GRPC_ERROR_NONE) { return UniquePtr( New(std::move(parsed_lb_config), @@ -560,7 +541,8 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, } } } - *error = CreateErrorFromVector("Client channel parser", &error_list); + *error = ServiceConfig::CreateErrorFromVector("Client channel parser", + &error_list); if (*error == GRPC_ERROR_NONE) { return UniquePtr( New(timeout, wait_for_ready, diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index 9a246785820..c6c6af35a68 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -38,24 +38,6 @@ typedef InlinedVector, ServiceConfig::kNumPreallocatedParsers> ServiceConfigParserList; ServiceConfigParserList* g_registered_parsers; - -// Consumes all the errors in the vector and forms a referencing error from -// them. If the vector is empty, return GRPC_ERROR_NONE. -template -grpc_error* CreateErrorFromVector(const char* desc, - InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; -} } // namespace RefCountedPtr ServiceConfig::Create(const char* json, diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 28e482bf2b7..f45cab9ee7d 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -150,6 +150,24 @@ class ServiceConfig : public RefCounted { static void Shutdown(); + // Consumes all the errors in the vector and forms a referencing error from + // them. If the vector is empty, return GRPC_ERROR_NONE. + template + static grpc_error* CreateErrorFromVector( + const char* desc, InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; + } + private: // So New() can call our private ctor. template diff --git a/src/core/ext/filters/message_size/message_size_parser.cc b/src/core/ext/filters/message_size/message_size_parser.cc index 534082ee6ff..a3444a984dd 100644 --- a/src/core/ext/filters/message_size/message_size_parser.cc +++ b/src/core/ext/filters/message_size/message_size_parser.cc @@ -22,24 +22,6 @@ namespace { size_t g_message_size_parser_index; - -// Consumes all the errors in the vector and forms a referencing error from -// them. If the vector is empty, return GRPC_ERROR_NONE. -template -grpc_error* CreateErrorFromVector( - const char* desc, grpc_core::InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; -} } // namespace namespace grpc_core { @@ -85,7 +67,8 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( } } if (!error_list.empty()) { - *error = CreateErrorFromVector("Message size parser", &error_list); + *error = ServiceConfig::CreateErrorFromVector("Message size parser", + &error_list); return nullptr; } return UniquePtr(New( From 20c08dbc7ae1be6bac21d313b465dfa5a940e2b8 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 12 Apr 2019 16:52:03 -0700 Subject: [PATCH 1912/2143] Add client-side unary reactor model --- include/grpcpp/generic/generic_stub_impl.h | 6 + .../grpcpp/impl/codegen/channel_interface.h | 2 + include/grpcpp/impl/codegen/client_callback.h | 155 +++++++++++++++++- include/grpcpp/impl/codegen/client_context.h | 2 + src/compiler/cpp_generator.cc | 42 ++++- src/proto/grpc/testing/echo_messages.proto | 1 + test/cpp/codegen/compiler_test_golden | 8 + .../end2end/client_callback_end2end_test.cc | 59 +++++++ test/cpp/end2end/test_service_impl.cc | 23 +++ 9 files changed, 290 insertions(+), 8 deletions(-) diff --git a/include/grpcpp/generic/generic_stub_impl.h b/include/grpcpp/generic/generic_stub_impl.h index 2d6a11de923..0a7338228c1 100644 --- a/include/grpcpp/generic/generic_stub_impl.h +++ b/include/grpcpp/generic/generic_stub_impl.h @@ -82,6 +82,12 @@ class GenericStub final { const grpc::ByteBuffer* request, grpc::ByteBuffer* response, std::function on_completion); + /// 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(grpc::ClientContext* context, const grpc::string& method, + const grpc::ByteBuffer* request, grpc::ByteBuffer* response, + grpc::experimental::ClientUnaryReactor* reactor); + /// 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. diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h index 5353f5feaa6..57555285e18 100644 --- a/include/grpcpp/impl/codegen/channel_interface.h +++ b/include/grpcpp/impl/codegen/channel_interface.h @@ -58,6 +58,7 @@ template class ClientCallbackReaderFactory; template class ClientCallbackWriterFactory; +class ClientCallbackUnaryFactory; class InterceptedChannel; } // namespace internal @@ -117,6 +118,7 @@ class ChannelInterface { friend class ::grpc::internal::ClientCallbackReaderFactory; template friend class ::grpc::internal::ClientCallbackWriterFactory; + friend class ::grpc::internal::ClientCallbackUnaryFactory; template friend class ::grpc::internal::BlockingUnaryCallImpl; template diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 53c57b55f7e..e973e23f891 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -100,6 +100,7 @@ template class ClientReadReactor; template class ClientWriteReactor; +class ClientUnaryReactor; // NOTE: The streaming objects are not actually implemented in the public API. // These interfaces are provided for mocking only. Typical applications @@ -157,6 +158,15 @@ class ClientCallbackWriter { } }; +class ClientCallbackUnary { + public: + virtual ~ClientCallbackUnary() {} + virtual void StartCall() = 0; + + protected: + void BindReactor(ClientUnaryReactor* reactor); +}; + // 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 @@ -346,6 +356,36 @@ class ClientWriteReactor { ClientCallbackWriter* writer_; }; +/// \a ClientUnaryReactor is a reactor-style interface for a unary RPC. +/// This is _not_ a common way of invoking a unary RPC. In practice, this +/// option should be used only if the unary RPC wants to receive initial +/// metadata without waiting for the response to complete. Most deployments of +/// RPC systems do not use this option, but it is needed for generality. +/// All public methods behave as in ClientBidiReactor. +/// StartCall is included for consistency with the other reactor flavors: even +/// though there are no StartRead or StartWrite operations to queue before the +/// call (that is part of the unary call itself) and there is no reactor object +/// being created as a result of this call, we keep a consistent 2-phase +/// initiation API among all the reactor flavors. +class ClientUnaryReactor { + public: + virtual ~ClientUnaryReactor() {} + + void StartCall() { call_->StartCall(); } + virtual void OnDone(const Status& s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + + private: + friend class ClientCallbackUnary; + void BindCall(ClientCallbackUnary* call) { call_ = call; } + ClientCallbackUnary* call_; +}; + +// Define function out-of-line from class to avoid forward declaration issue +inline void ClientCallbackUnary::BindReactor(ClientUnaryReactor* reactor) { + reactor->BindCall(this); +} + } // namespace experimental namespace internal { @@ -512,9 +552,9 @@ class ClientCallbackReaderWriterImpl this->BindReactor(reactor); } - ClientContext* context_; + ClientContext* const context_; Call call_; - ::grpc::experimental::ClientBidiReactor* reactor_; + ::grpc::experimental::ClientBidiReactor* const reactor_; CallOpSet start_ops_; CallbackWithSuccessTag start_tag_; @@ -651,9 +691,9 @@ class ClientCallbackReaderImpl start_ops_.ClientSendClose(); } - ClientContext* context_; + ClientContext* const context_; Call call_; - ::grpc::experimental::ClientReadReactor* reactor_; + ::grpc::experimental::ClientReadReactor* const reactor_; CallOpSet @@ -824,9 +864,9 @@ class ClientCallbackWriterImpl finish_ops_.AllowNoMessage(); } - ClientContext* context_; + ClientContext* const context_; Call call_; - ::grpc::experimental::ClientWriteReactor* reactor_; + ::grpc::experimental::ClientWriteReactor* const reactor_; CallOpSet start_ops_; CallbackWithSuccessTag start_tag_; @@ -867,6 +907,109 @@ class ClientCallbackWriterFactory { } }; +class ClientCallbackUnaryImpl final + : public ::grpc::experimental::ClientCallbackUnary { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackUnaryImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void StartCall() override { + // This call initiates two batches, each with a callback + // 1. Send initial metadata + write + writes done + recv initial metadata + // 2. Read message, recv trailing metadata + started_ = true; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_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_); + } + + void MaybeFinish() { + if (--callbacks_outstanding_ == 0) { + Status s = std::move(finish_status_); + auto* reactor = reactor_; + auto* call = call_.call(); + this->~ClientCallbackUnaryImpl(); + g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); + } + } + + private: + friend class ClientCallbackUnaryFactory; + + template + ClientCallbackUnaryImpl(Call call, ClientContext* context, Request* request, + Response* response, + ::grpc::experimental::ClientUnaryReactor* reactor) + : context_(context), call_(call), reactor_(reactor) { + this->BindReactor(reactor); + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok()); + start_ops_.ClientSendClose(); + finish_ops_.RecvMessage(response); + finish_ops_.AllowNoMessage(); + } + + ClientContext* const context_; + Call call_; + ::grpc::experimental::ClientUnaryReactor* const reactor_; + + CallOpSet + start_ops_; + CallbackWithSuccessTag start_tag_; + + CallOpSet finish_ops_; + CallbackWithSuccessTag finish_tag_; + Status finish_status_; + + // This call will have 2 callbacks: start and finish + std::atomic_int callbacks_outstanding_{2}; + bool started_{false}; +}; + +class ClientCallbackUnaryFactory { + public: + template + static void Create(ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ClientContext* context, const Request* request, + Response* response, + ::grpc::experimental::ClientUnaryReactor* reactor) { + Call call = channel->CreateCall(method, context, channel->CallbackCQ()); + + g_core_codegen_interface->grpc_call_ref(call.call()); + + new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackUnaryImpl))) + ClientCallbackUnaryImpl(call, context, request, response, reactor); + } +}; + } // namespace internal } // namespace grpc diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 85bbf36f06d..7f6956a0da4 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -79,6 +79,7 @@ template class ClientCallbackReaderImpl; template class ClientCallbackWriterImpl; +class ClientCallbackUnaryImpl; } // namespace internal template @@ -417,6 +418,7 @@ class ClientContext { friend class ::grpc::internal::ClientCallbackReaderImpl; template friend class ::grpc::internal::ClientCallbackWriterImpl; + friend class ::grpc::internal::ClientCallbackUnaryImpl; // Used by friend class CallOpClientRecvStatus void set_debug_error_string(const grpc::string& debug_error_string) { diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 1bb9c509bb5..97b84dd202a 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -607,6 +607,14 @@ void PrintHeaderClientMethodCallbackInterfaces( "virtual void $Method$(::grpc::ClientContext* context, " "const ::grpc::ByteBuffer* request, $Response$* response, " "std::function) = 0;\n"); + printer->Print(*vars, + "virtual void $Method$(::grpc::ClientContext* context, " + "const $Request$* request, $Response$* response, " + "::grpc::experimental::ClientUnaryReactor* reactor) = 0;\n"); + printer->Print(*vars, + "virtual void $Method$(::grpc::ClientContext* context, " + "const ::grpc::ByteBuffer* request, $Response$* response, " + "::grpc::experimental::ClientUnaryReactor* reactor) = 0;\n"); } else if (ClientOnlyStreaming(method)) { printer->Print(*vars, "virtual void $Method$(::grpc::ClientContext* context, " @@ -673,6 +681,16 @@ void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer, "void $Method$(::grpc::ClientContext* context, " "const ::grpc::ByteBuffer* request, $Response$* response, " "std::function) override;\n"); + printer->Print( + *vars, + "void $Method$(::grpc::ClientContext* context, " + "const $Request$* request, $Response$* response, " + "::grpc::experimental::ClientUnaryReactor* reactor) override;\n"); + printer->Print( + *vars, + "void $Method$(::grpc::ClientContext* context, " + "const ::grpc::ByteBuffer* request, $Response$* response, " + "::grpc::experimental::ClientUnaryReactor* reactor) override;\n"); } else if (ClientOnlyStreaming(method)) { printer->Print(*vars, "void $Method$(::grpc::ClientContext* context, " @@ -1671,7 +1689,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "const $Request$* request, $Response$* response, " "std::function f) {\n"); printer->Print(*vars, - " return ::grpc::internal::CallbackUnaryCall" + " ::grpc::internal::CallbackUnaryCall" "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " "context, request, response, std::move(f));\n}\n\n"); @@ -1681,10 +1699,30 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "const ::grpc::ByteBuffer* request, $Response$* response, " "std::function f) {\n"); printer->Print(*vars, - " return ::grpc::internal::CallbackUnaryCall" + " ::grpc::internal::CallbackUnaryCall" "(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 $Request$* request, $Response$* response, " + "::grpc::experimental::ClientUnaryReactor* reactor) {\n"); + printer->Print(*vars, + " ::grpc::internal::ClientCallbackUnaryFactory::Create" + "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " + "context, request, response, reactor);\n}\n\n"); + + printer->Print(*vars, + "void $ns$$Service$::Stub::experimental_async::$Method$(" + "::grpc::ClientContext* context, " + "const ::grpc::ByteBuffer* request, $Response$* response, " + "::grpc::experimental::ClientUnaryReactor* reactor) {\n"); + printer->Print(*vars, + " ::grpc::internal::ClientCallbackUnaryFactory::Create" + "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " + "context, request, response, reactor);\n}\n\n"); + for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncStart"] = async_prefix.start; diff --git a/src/proto/grpc/testing/echo_messages.proto b/src/proto/grpc/testing/echo_messages.proto index 2f935304ab2..df0b6801d3d 100644 --- a/src/proto/grpc/testing/echo_messages.proto +++ b/src/proto/grpc/testing/echo_messages.proto @@ -47,6 +47,7 @@ message RequestParams { ErrorStatus expected_error = 14; int32 server_sleep_us = 15; // Amount to sleep when invoking server int32 backend_channel_idx = 16; // which backend to send request to + bool echo_metadata_initially = 17; } message EchoRequest { diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 7f9fd29026e..1067dbbb98e 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -114,6 +114,8 @@ class ServiceA final { // 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; + virtual void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0; + virtual void MethodA1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0; // MethodA1 trailing comment 1 // MethodA2 detached leading comment 1 // @@ -184,6 +186,8 @@ class ServiceA final { 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 MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) override; + void MethodA1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) 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; @@ -717,6 +721,8 @@ class ServiceB final { // 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; + virtual void MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0; + virtual void MethodB1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0; // MethodB1 trailing comment 1 }; virtual class experimental_async_interface* experimental_async() { return nullptr; } @@ -739,6 +745,8 @@ class ServiceB final { 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; + void MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) override; + void MethodB1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) override; private: friend class Stub; explicit experimental_async(Stub* stub): stub_(stub) { } diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 821fcc2da6d..f0d159ba2a2 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -696,6 +696,65 @@ TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelAfterReads) { } } +TEST_P(ClientCallbackEnd2endTest, UnaryReactor) { + MAYBE_SKIP_TEST; + ResetStub(); + class UnaryClient : public grpc::experimental::ClientUnaryReactor { + public: + UnaryClient(grpc::testing::EchoTestService::Stub* stub) { + cli_ctx_.AddMetadata("key1", "val1"); + cli_ctx_.AddMetadata("key2", "val2"); + request_.mutable_param()->set_echo_metadata_initially(true); + request_.set_message("Hello metadata"); + stub->experimental_async()->Echo(&cli_ctx_, &request_, &response_, this); + StartCall(); + } + void OnReadInitialMetadataDone(bool ok) override { + EXPECT_TRUE(ok); + EXPECT_EQ(1u, cli_ctx_.GetServerInitialMetadata().count("key1")); + EXPECT_EQ( + "val1", + ToString(cli_ctx_.GetServerInitialMetadata().find("key1")->second)); + EXPECT_EQ(1u, cli_ctx_.GetServerInitialMetadata().count("key2")); + EXPECT_EQ( + "val2", + ToString(cli_ctx_.GetServerInitialMetadata().find("key2")->second)); + initial_metadata_done_ = true; + } + void OnDone(const Status& s) override { + EXPECT_TRUE(initial_metadata_done_); + EXPECT_EQ(0u, cli_ctx_.GetServerTrailingMetadata().size()); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(request_.message(), response_.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 cli_ctx_; + std::mutex mu_; + std::condition_variable cv_; + bool done_{false}; + bool initial_metadata_done_{false}; + }; + + UnaryClient test{stub_.get()}; + test.Await(); + // Make sure that the server interceptors were not notified of a cancel + if (GetParam().use_interceptors) { + EXPECT_EQ(0, DummyInterceptor::GetNumTimesCancel()); + } +} + class ReadClient : public grpc::experimental::ClientReadReactor { public: ReadClient(grpc::testing::EchoTestService::Stub* stub, diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 048715300ad..4078cdfb257 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -200,6 +200,17 @@ Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, EXPECT_FALSE(context->IsCancelled()); } + if (request->has_param() && request->param().echo_metadata_initially()) { + const std::multimap& client_metadata = + context->client_metadata(); + for (std::multimap::const_iterator + iter = client_metadata.begin(); + iter != client_metadata.end(); ++iter) { + context->AddInitialMetadata(ToString(iter->first), + ToString(iter->second)); + } + } + if (request->has_param() && request->param().echo_metadata()) { const std::multimap& client_metadata = context->client_metadata(); @@ -379,6 +390,18 @@ void CallbackTestServiceImpl::EchoNonDelayed( EXPECT_FALSE(context->IsCancelled()); } + if (request->has_param() && request->param().echo_metadata_initially()) { + const std::multimap& client_metadata = + context->client_metadata(); + for (std::multimap::const_iterator + iter = client_metadata.begin(); + iter != client_metadata.end(); ++iter) { + context->AddInitialMetadata(ToString(iter->first), + ToString(iter->second)); + } + controller->SendInitialMetadata([](bool ok) { EXPECT_TRUE(ok); }); + } + if (request->has_param() && request->param().echo_metadata()) { const std::multimap& client_metadata = context->client_metadata(); From bca4a6db2c9b08832417d90f3ff1660f3f8e7843 Mon Sep 17 00:00:00 2001 From: SataQiu Date: Sun, 21 Apr 2019 11:07:21 +0800 Subject: [PATCH 1913/2143] fix some spellings mistakes --- src/core/ext/filters/client_channel/http_connect_handshaker.h | 2 +- src/core/ext/filters/deadline/deadline_filter.cc | 2 +- src/core/ext/filters/http/client/http_client_filter.cc | 2 +- src/core/ext/filters/http/client/http_client_filter.h | 2 +- src/core/ext/transport/chttp2/alpn/alpn.h | 2 +- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 2 +- src/core/lib/surface/server.cc | 2 +- src/python/grpcio_tests/tests/stress/client.py | 4 ++-- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/ext/filters/client_channel/http_connect_handshaker.h b/src/core/ext/filters/client_channel/http_connect_handshaker.h index 928a23dc936..26c31f2a0ab 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.h +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.h @@ -25,7 +25,7 @@ /// Channel arg indicating HTTP CONNECT headers (string). /// Multiple headers are separated by newlines. Key/value pairs are -/// seperated by colons. +/// separated by colons. #define GRPC_ARG_HTTP_CONNECT_HEADERS "grpc.http_connect_headers" /// Registers handshaker factory. diff --git a/src/core/ext/filters/deadline/deadline_filter.cc b/src/core/ext/filters/deadline/deadline_filter.cc index b4cb07f0f92..e54f29ea3a7 100644 --- a/src/core/ext/filters/deadline/deadline_filter.cc +++ b/src/core/ext/filters/deadline/deadline_filter.cc @@ -124,7 +124,7 @@ static void cancel_timer_if_needed(grpc_deadline_state* deadline_state) { deadline_state->timer_state = GRPC_DEADLINE_STATE_FINISHED; grpc_timer_cancel(&deadline_state->timer); } else { - // timer was either in STATE_INITAL (nothing to cancel) + // timer was either in STATE_INITIAL (nothing to cancel) // OR in STATE_FINISHED (again nothing to cancel) } } diff --git a/src/core/ext/filters/http/client/http_client_filter.cc b/src/core/ext/filters/http/client/http_client_filter.cc index bf9a01f659b..5f3a15c7691 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -36,7 +36,7 @@ #define EXPECTED_CONTENT_TYPE "application/grpc" #define EXPECTED_CONTENT_TYPE_LENGTH sizeof(EXPECTED_CONTENT_TYPE) - 1 -/* default maximum size of payload eligable for GET request */ +/* default maximum size of payload eligible for GET request */ static constexpr size_t kMaxPayloadSizeForGet = 2048; static void recv_initial_metadata_ready(void* user_data, grpc_error* error); diff --git a/src/core/ext/filters/http/client/http_client_filter.h b/src/core/ext/filters/http/client/http_client_filter.h index b7cef33f5c7..a2f16ddbfbe 100644 --- a/src/core/ext/filters/http/client/http_client_filter.h +++ b/src/core/ext/filters/http/client/http_client_filter.h @@ -25,7 +25,7 @@ /* Processes metadata on the client side for HTTP2 transports */ extern const grpc_channel_filter grpc_http_client_filter; -/* Channel arg to determine maximum size of payload eligable for GET request */ +/* Channel arg to determine maximum size of payload eligible for GET request */ #define GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET "grpc.max_payload_size_for_get" #endif /* GRPC_CORE_EXT_FILTERS_HTTP_CLIENT_HTTP_CLIENT_FILTER_H */ diff --git a/src/core/ext/transport/chttp2/alpn/alpn.h b/src/core/ext/transport/chttp2/alpn/alpn.h index 0042eafd95a..e2ffe4e405e 100644 --- a/src/core/ext/transport/chttp2/alpn/alpn.h +++ b/src/core/ext/transport/chttp2/alpn/alpn.h @@ -23,7 +23,7 @@ #include -/* Retuns 1 if the version is supported, 0 otherwise. */ +/* Returns 1 if the version is supported, 0 otherwise. */ int grpc_chttp2_is_alpn_version_supported(const char* version, size_t size); /* Returns the number of protocol versions to advertise */ diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 07659bb09bb..cb251651a57 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1413,7 +1413,7 @@ static void perform_stream_op_locked(void* stream_op, // 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. + // the initial 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; } diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 1e0ac0e9237..f661012b528 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -123,7 +123,7 @@ typedef struct shutdown_tag { typedef enum { /* waiting for metadata */ NOT_STARTED, - /* inital metadata read, not flow controlled in yet */ + /* initial metadata read, not flow controlled in yet */ PENDING, /* flow controlled in, on completion queue */ ACTIVATED, diff --git a/src/python/grpcio_tests/tests/stress/client.py b/src/python/grpcio_tests/tests/stress/client.py index 4c35b05044a..11e46d4e720 100644 --- a/src/python/grpcio_tests/tests/stress/client.py +++ b/src/python/grpcio_tests/tests/stress/client.py @@ -34,12 +34,12 @@ def _args(): description='gRPC Python stress test client') parser.add_argument( '--server_addresses', - help='comma seperated list of hostname:port to run servers on', + help='comma separated list of hostname:port to run servers on', default='localhost:8080', type=str) parser.add_argument( '--test_cases', - help='comma seperated list of testcase:weighting of tests to run', + help='comma separated list of testcase:weighting of tests to run', default='large_unary:100', type=str) parser.add_argument( From 1a4f5e8ade7024c0c90fa6c19ba8f1947842bf22 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 22 Apr 2019 11:29:16 -0700 Subject: [PATCH 1914/2143] Fix typo in comment It's a ServerWriteReactor --- include/grpcpp/impl/codegen/server_callback.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index ce27b156283..782a942f56d 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -364,7 +364,7 @@ class ServerReadReactor : public internal::ServerReactor { ServerCallbackReader* reader_; }; -/// \a ServerReadReactor is the interface for a server-streaming RPC. +/// \a ServerWriteReactor is the interface for a server-streaming RPC. template class ServerWriteReactor : public internal::ServerReactor { public: From 6d0a7936bf4f7913914f299972d587972d1fa42e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 22 Apr 2019 14:19:20 -0700 Subject: [PATCH 1915/2143] minor fix in CFStream --- src/core/lib/iomgr/cfstream_handle.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/cfstream_handle.h b/src/core/lib/iomgr/cfstream_handle.h index 93ec5f044bb..4f4d15966e4 100644 --- a/src/core/lib/iomgr/cfstream_handle.h +++ b/src/core/lib/iomgr/cfstream_handle.h @@ -37,8 +37,8 @@ class CFStreamHandle final { static CFStreamHandle* CreateStreamHandle(CFReadStreamRef read_stream, CFWriteStreamRef write_stream); ~CFStreamHandle(); - CFStreamHandle(const CFReadStreamRef& ref) = delete; - CFStreamHandle(CFReadStreamRef&& ref) = delete; + CFStreamHandle(const CFStreamHandle& ref) = delete; + CFStreamHandle(CFStreamHandle&& ref) = delete; CFStreamHandle& operator=(const CFStreamHandle& rhs) = delete; void NotifyOnOpen(grpc_closure* closure); From b9a279c030df023f3ca8979d45708add4d7b0717 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 22 Apr 2019 23:53:53 +0200 Subject: [PATCH 1916/2143] Resolving ambiguous call to CreateCustomChannel. --- test/cpp/client/client_channel_stress_test.cc | 2 +- test/cpp/end2end/async_end2end_test.cc | 4 ++-- test/cpp/end2end/channelz_service_test.cc | 6 +++--- test/cpp/end2end/client_callback_end2end_test.cc | 4 ++-- test/cpp/end2end/client_lb_end2end_test.cc | 2 +- test/cpp/end2end/end2end_test.cc | 2 +- test/cpp/end2end/grpclb_end2end_test.cc | 2 +- test/cpp/end2end/shutdown_test.cc | 2 +- test/cpp/end2end/xds_end2end_test.cc | 2 +- test/cpp/microbenchmarks/fullstack_fixtures.h | 2 +- test/cpp/util/create_test_channel.cc | 8 ++++---- 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index 91419cb257b..195308c39b0 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -268,7 +268,7 @@ class ClientChannelStressTest { std::ostringstream uri; uri << "fake:///servername_not_used"; channel_ = - CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args); + ::grpc::CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index e09f54dcc3f..f8e65ecff41 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -295,7 +295,7 @@ class AsyncEnd2endTest : public ::testing::TestWithParam { GetParam().credentials_type, &args); std::shared_ptr channel = !(GetParam().inproc) - ? CreateCustomChannel(server_address_.str(), channel_creds, args) + ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args) : server_->InProcessChannel(args); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -1256,7 +1256,7 @@ TEST_P(AsyncEnd2endTest, UnimplementedRpc) { GetParam().credentials_type, &args); std::shared_ptr channel = !(GetParam().inproc) - ? CreateCustomChannel(server_address_.str(), channel_creds, args) + ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args) : server_->InProcessChannel(args); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index fe52a64db48..26ef59fbeb3 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -145,7 +145,7 @@ class ChannelzServerTest : public ::testing::Test { ChannelArguments args; args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 1); args.SetInt(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 1024); - std::shared_ptr channel_to_backend = CreateCustomChannel( + std::shared_ptr channel_to_backend = ::grpc::CreateCustomChannel( backend_server_address, InsecureChannelCredentials(), args); proxy_service_.AddChannelToBackend(channel_to_backend); } @@ -157,7 +157,7 @@ class ChannelzServerTest : public ::testing::Test { // disable channelz. We only want to focus on proxy to backend outbound. args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0); std::shared_ptr channel = - CreateCustomChannel(target, InsecureChannelCredentials(), args); + ::grpc::CreateCustomChannel(target, InsecureChannelCredentials(), args); channelz_stub_ = grpc::channelz::v1::Channelz::NewStub(channel); echo_stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -171,7 +171,7 @@ class ChannelzServerTest : public ::testing::Test { // This ensures that gRPC will not do connection sharing. args.SetInt("salt", salt++); std::shared_ptr channel = - CreateCustomChannel(target, InsecureChannelCredentials(), args); + ::grpc::CreateCustomChannel(target, InsecureChannelCredentials(), args); return grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 821fcc2da6d..cb1d734c800 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -143,7 +143,7 @@ class ClientCallbackEnd2endTest case Protocol::TCP: if (!GetParam().use_interceptors) { channel_ = - CreateCustomChannel(server_address_.str(), channel_creds, args); + ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args); } else { channel_ = CreateCustomChannelWithInterceptors( server_address_.str(), channel_creds, args, @@ -1094,7 +1094,7 @@ TEST_P(ClientCallbackEnd2endTest, UnimplementedRpc) { GetParam().credentials_type, &args); std::shared_ptr channel = (GetParam().protocol == Protocol::TCP) - ? CreateCustomChannel(server_address_.str(), channel_creds, args) + ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args) : server_->InProcessChannel(args); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 77f9db94acc..b6c4ad7bd2d 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -236,7 +236,7 @@ class ClientLbEnd2endTest : public ::testing::Test { } // else, default to pick first args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, response_generator_.get()); - return CreateCustomChannel("fake:///", creds_, args); + return ::grpc::CreateCustomChannel("fake:///", creds_, args); } bool SendRpc( diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 40023c72f62..0b4df97f4cb 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -341,7 +341,7 @@ class End2endTest : public ::testing::TestWithParam { if (!GetParam().inproc) { if (!GetParam().use_interceptors) { channel_ = - CreateCustomChannel(server_address_.str(), channel_creds, args); + ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args); } else { channel_ = CreateCustomChannelWithInterceptors( server_address_.str(), channel_creds, args, diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index ee8b3e1e52b..7477878faa0 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -433,7 +433,7 @@ class GrpclbEnd2endTest : public ::testing::Test { channel_creds, call_creds, nullptr))); call_creds->Unref(); channel_creds->Unref(); - channel_ = CreateCustomChannel(uri.str(), creds, args); + channel_ = ::grpc::CreateCustomChannel(uri.str(), creds, args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/shutdown_test.cc b/test/cpp/end2end/shutdown_test.cc index da42178d67c..9e925364b1f 100644 --- a/test/cpp/end2end/shutdown_test.cc +++ b/test/cpp/end2end/shutdown_test.cc @@ -86,7 +86,7 @@ class ShutdownTest : public ::testing::TestWithParam { ChannelArguments args; auto channel_creds = GetCredentialsProvider()->GetChannelCredentials(GetParam(), &args); - channel_ = CreateCustomChannel(target, channel_creds, args); + channel_ = ::grpc::CreateCustomChannel(target, channel_creds, args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index 11a64264494..04bec5a9ee8 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -432,7 +432,7 @@ class XdsEnd2endTest : public ::testing::Test { channel_creds, call_creds, nullptr))); call_creds->Unref(); channel_creds->Unref(); - channel_ = CreateCustomChannel(uri.str(), creds, args); + channel_ = ::grpc::CreateCustomChannel(uri.str(), creds, args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index 6bbf553bbd8..ed231752438 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -87,7 +87,7 @@ class FullstackFixture : public BaseFixture { config.ApplyCommonChannelArguments(&args); if (address.length() > 0) { channel_ = - CreateCustomChannel(address, InsecureChannelCredentials(), args); + ::grpc::CreateCustomChannel(address, InsecureChannelCredentials(), args); } else { channel_ = server_->InProcessChannel(args); } diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc index 79a5e13d993..d036e785360 100644 --- a/test/cpp/util/create_test_channel.cc +++ b/test/cpp/util/create_test_channel.cc @@ -118,7 +118,7 @@ std::shared_ptr CreateTestChannel( if (creds.get()) { channel_creds = CompositeChannelCredentials(channel_creds, creds); } - return CreateCustomChannel(server, channel_creds, channel_args); + return ::grpc::CreateCustomChannel(server, channel_creds, channel_args); } std::shared_ptr CreateTestChannel( @@ -132,7 +132,7 @@ std::shared_ptr CreateTestChannel( std::shared_ptr channel_creds; if (cred_type.empty()) { if (interceptor_creators.empty()) { - return CreateCustomChannel(server, InsecureChannelCredentials(), args); + return ::grpc::CreateCustomChannel(server, InsecureChannelCredentials(), args); } else { return experimental::CreateCustomChannelWithInterceptors( server, InsecureChannelCredentials(), args, @@ -159,7 +159,7 @@ std::shared_ptr CreateTestChannel( channel_creds = CompositeChannelCredentials(channel_creds, creds); } if (interceptor_creators.empty()) { - return CreateCustomChannel(connect_to, channel_creds, channel_args); + return ::grpc::CreateCustomChannel(connect_to, channel_creds, channel_args); } else { return experimental::CreateCustomChannelWithInterceptors( connect_to, channel_creds, channel_args, @@ -171,7 +171,7 @@ std::shared_ptr CreateTestChannel( GPR_ASSERT(channel_creds != nullptr); if (interceptor_creators.empty()) { - return CreateCustomChannel(server, channel_creds, args); + return ::grpc::CreateCustomChannel(server, channel_creds, args); } else { return experimental::CreateCustomChannelWithInterceptors( server, channel_creds, args, std::move(interceptor_creators)); From abcdf2d1832544f3e11775997ad847051a6f3809 Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Mon, 22 Apr 2019 16:32:26 -0600 Subject: [PATCH 1917/2143] Party like its 2015 --- src/ruby/spec/errors_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ruby/spec/errors_spec.rb b/src/ruby/spec/errors_spec.rb index 30e897700b3..9d64277290a 100644 --- a/src/ruby/spec/errors_spec.rb +++ b/src/ruby/spec/errors_spec.rb @@ -1,13 +1,13 @@ -# Copyright 2019 gRPC authors. +# Copyright 2015 gRPC authors. # -# Licensed under the Apache License, Version 2.0 (the 'License'); +# 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, +# 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 5f30da6dd128a311c92fc4b8df762caff8c4e11b Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Mon, 22 Apr 2019 16:35:07 -0600 Subject: [PATCH 1918/2143] Update variable names in spec --- src/ruby/spec/errors_spec.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ruby/spec/errors_spec.rb b/src/ruby/spec/errors_spec.rb index 9d64277290a..bf27a537405 100644 --- a/src/ruby/spec/errors_spec.rb +++ b/src/ruby/spec/errors_spec.rb @@ -128,13 +128,14 @@ describe GRPC::BadStatus do expect(exception.to_rpc_status).to be nil + error_msg = 'parse error: to_rpc_status failed' + error_desc = ' ' \ + 'Error occurred during parsing: Invalid wire type' + # Check that the parse error was logged correctly log_contents = @log_output.read - expected_line_1 = 'WARN GRPC : parse error: to_rpc_status failed' - expected_line_2 = 'WARN GRPC : ' \ - 'Error occurred during parsing: Invalid wire type' - expect(log_contents).to include expected_line_1 - expect(log_contents).to include expected_line_2 + expect(log_contents).to include "WARN GRPC : #{error_msg}" + expect(log_contents).to include "WARN GRPC : #{error_desc}" end end end From dc1bcf876225f93da86ea5916133e868c95adc3a Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 22 Apr 2019 17:31:55 -0700 Subject: [PATCH 1919/2143] Consolidate helper function from windows and libuv --- BUILD | 2 + BUILD.gn | 2 + CMakeLists.txt | 2 + Makefile | 2 + build.yaml | 2 + config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + grpc.gyp | 2 + package.xml | 2 + .../dns/c_ares/grpc_ares_wrapper_libuv.cc | 53 +----------- .../c_ares/grpc_ares_wrapper_libuv_windows.cc | 83 +++++++++++++++++++ .../c_ares/grpc_ares_wrapper_libuv_windows.h | 14 ++++ .../dns/c_ares/grpc_ares_wrapper_windows.cc | 50 ----------- src/python/grpcio/grpc_core_dependencies.py | 1 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 5 +- 19 files changed, 127 insertions(+), 103 deletions(-) create mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc create mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h diff --git a/BUILD b/BUILD index 58f0855961e..69ca8fb2adc 100644 --- a/BUILD +++ b/BUILD @@ -1558,12 +1558,14 @@ grpc_cc_library( "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_fallback.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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", ], hdrs = [ "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_wrapper.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", ], external_deps = [ "cares", diff --git a/BUILD.gn b/BUILD.gn index a188ed86ac3..4210d5f1f0c 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -316,6 +316,8 @@ config("grpc_config") { "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_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", "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", diff --git a/CMakeLists.txt b/CMakeLists.txt index dd32088e97f..9cbaf34f737 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1287,6 +1287,7 @@ add_library(grpc 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_fallback.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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 @@ -2658,6 +2659,7 @@ add_library(grpc_unsecure 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_fallback.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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 diff --git a/Makefile b/Makefile index b1dcc82c601..300e8d5890a 100644 --- a/Makefile +++ b/Makefile @@ -3742,6 +3742,7 @@ LIBGRPC_SRC = \ 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_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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 \ @@ -5061,6 +5062,7 @@ LIBGRPC_UNSECURE_SRC = \ 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_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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 \ diff --git a/build.yaml b/build.yaml index 48c45eb799d..d470c0a7eb5 100644 --- a/build.yaml +++ b/build.yaml @@ -778,6 +778,7 @@ filegroups: headers: - 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_wrapper.h + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h src: - 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 @@ -787,6 +788,7 @@ filegroups: - 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_fallback.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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 plugin: grpc_resolver_dns_ares diff --git a/config.m4 b/config.m4 index e255602a48d..93d90685f32 100644 --- a/config.m4 +++ b/config.m4 @@ -402,6 +402,7 @@ if test "$PHP_GRPC" != "no"; then 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_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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 \ diff --git a/config.w32 b/config.w32 index e83b3e3dd7f..352d1c446c8 100644 --- a/config.w32 +++ b/config.w32 @@ -377,6 +377,7 @@ if (PHP_GRPC != "no") { "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_fallback.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv.cc " + + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv_windows.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 " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index b8f3f56a83f..29a7c411a42 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -545,6 +545,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', '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_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 4a2ea853f29..5ca70a533da 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -528,6 +528,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', '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_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', @@ -849,6 +850,7 @@ Pod::Spec.new do |s| '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_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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', @@ -1170,6 +1172,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', '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_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', diff --git a/grpc.gemspec b/grpc.gemspec index b7e0d54eaab..31119577251 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -462,6 +462,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h ) s.files += %w( src/core/ext/filters/max_age/max_age_filter.h ) s.files += %w( src/core/ext/filters/message_size/message_size_filter.h ) s.files += %w( src/core/ext/filters/http/client_authority_filter.h ) @@ -786,6 +787,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc ) diff --git a/grpc.gyp b/grpc.gyp index 19427da3ca6..351d50411b7 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -584,6 +584,7 @@ '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_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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', @@ -1325,6 +1326,7 @@ '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_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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', diff --git a/package.xml b/package.xml index 26cc17756e8..c8ac7a47966 100644 --- a/package.xml +++ b/package.xml @@ -467,6 +467,7 @@ + @@ -791,6 +792,7 @@ + diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc index 08f3d9ce30d..cab74f8ba64 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -25,6 +25,7 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" @@ -36,58 +37,6 @@ bool grpc_ares_query_ipv6() { return true; } -/* The following two functions were copied entirely from the Windows file. This - * code can run on Windows so it can have the same problem. */ -static bool inner_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, char** host, - char** port) { - gpr_split_host_port(name, host, port); - if (*host == nullptr) { - gpr_log(GPR_ERROR, - "Failed to parse %s into host:port during Windows localhost " - "resolution check.", - name); - return false; - } - if (*port == nullptr) { - if (default_port == nullptr) { - gpr_log(GPR_ERROR, - "No port or default port for %s during Windows localhost " - "resolution check.", - name); - return false; - } - *port = gpr_strdup(default_port); - } - if (gpr_stricmp(*host, "localhost") == 0) { - GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_core::MakeUnique(); - uint16_t numeric_port = grpc_strhtons(*port); - // Append the ipv6 loopback address. - struct sockaddr_in6 ipv6_loopback_addr; - memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); - ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; - ipv6_loopback_addr.sin6_family = AF_INET6; - ipv6_loopback_addr.sin6_port = numeric_port; - (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), - nullptr /* args */); - // Append the ipv4 loopback address. - struct sockaddr_in ipv4_loopback_addr; - memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); - ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; - ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; - ipv4_loopback_addr.sin_family = AF_INET; - ipv4_loopback_addr.sin_port = numeric_port; - (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), - nullptr /* args */); - // Let the address sorter figure out which one should be tried first. - grpc_cares_wrapper_address_sorting_sort(addrs->get()); - return true; - } - return false; -} - bool grpc_ares_maybe_resolve_localhost_manually_locked( const char* name, const char* default_port, grpc_core::UniquePtr* addrs) { diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc new file mode 100644 index 00000000000..837593a62bc --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc @@ -0,0 +1,83 @@ +/* + * + * 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" +#if GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) + +#include + +#include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" + +bool inner_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port) { + gpr_split_host_port(name, host, port); + if (*host == nullptr) { + gpr_log(GPR_ERROR, + "Failed to parse %s into host:port during Windows localhost " + "resolution check.", + name); + return false; + } + if (*port == nullptr) { + if (default_port == nullptr) { + gpr_log(GPR_ERROR, + "No port or default port for %s during Windows localhost " + "resolution check.", + name); + return false; + } + *port = gpr_strdup(default_port); + } + if (gpr_stricmp(*host, "localhost") == 0) { + GPR_ASSERT(*addrs == nullptr); + *addrs = grpc_core::MakeUnique(); + uint16_t numeric_port = grpc_strhtons(*port); + // Append the ipv6 loopback address. + struct sockaddr_in6 ipv6_loopback_addr; + memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); + ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; + ipv6_loopback_addr.sin6_family = AF_INET6; + ipv6_loopback_addr.sin6_port = numeric_port; + (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), + nullptr /* args */); + // Append the ipv4 loopback address. + struct sockaddr_in ipv4_loopback_addr; + memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); + ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; + ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; + ipv4_loopback_addr.sin_family = AF_INET; + ipv4_loopback_addr.sin_port = numeric_port; + (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), + nullptr /* args */); + // Let the address sorter figure out which one should be tried first. + grpc_cares_wrapper_address_sorting_sort(addrs->get()); + return true; + } + return false; +} + +#endif /* GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) */ \ No newline at end of file diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h new file mode 100644 index 00000000000..07c0e37552b --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h @@ -0,0 +1,14 @@ +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H + +#include + +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" + +bool inner_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port); + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H \ + */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index 202452f1b2b..f3adc417793 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -32,56 +32,6 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } -static bool inner_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, char** host, - char** port) { - gpr_split_host_port(name, host, port); - if (*host == nullptr) { - gpr_log(GPR_ERROR, - "Failed to parse %s into host:port during Windows localhost " - "resolution check.", - name); - return false; - } - if (*port == nullptr) { - if (default_port == nullptr) { - gpr_log(GPR_ERROR, - "No port or default port for %s during Windows localhost " - "resolution check.", - name); - return false; - } - *port = gpr_strdup(default_port); - } - if (gpr_stricmp(*host, "localhost") == 0) { - GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_core::MakeUnique(); - uint16_t numeric_port = grpc_strhtons(*port); - // Append the ipv6 loopback address. - struct sockaddr_in6 ipv6_loopback_addr; - memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); - ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; - ipv6_loopback_addr.sin6_family = AF_INET6; - ipv6_loopback_addr.sin6_port = numeric_port; - (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), - nullptr /* args */); - // Append the ipv4 loopback address. - struct sockaddr_in ipv4_loopback_addr; - memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); - ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; - ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; - ipv4_loopback_addr.sin_family = AF_INET; - ipv4_loopback_addr.sin_port = numeric_port; - (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), - nullptr /* args */); - // Let the address sorter figure out which one should be tried first. - grpc_cares_wrapper_address_sorting_sort(addrs->get()); - return true; - } - return false; -} - bool grpc_ares_maybe_resolve_localhost_manually_locked( const char* name, const char* default_port, grpc_core::UniquePtr* addrs) { diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 9c375f5eb87..7f0a9ebc72e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -376,6 +376,7 @@ CORE_SOURCE_FILES = [ '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_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index a3869cd239c..4f13d987a6f 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -949,6 +949,8 @@ 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_libuv.cc \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h \ 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/README.md \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 52c69ad10b5..11b5e3ea4af 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9075,7 +9075,8 @@ ], "headers": [ "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_wrapper.h" + "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_libuv_windows.h" ], "is_filegroup": true, "language": "c", @@ -9091,6 +9092,8 @@ "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_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", "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" ], From 70839d966f1c481eadc7d27ac06bb1426bbde989 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 22 Apr 2019 19:12:11 -0700 Subject: [PATCH 1920/2143] Reviewer comments --- .../filters/client_channel/client_channel.cc | 28 +-- .../client_channel/client_channel_plugin.cc | 1 - .../ext/filters/client_channel/lb_policy.cc | 59 ------- .../ext/filters/client_channel/lb_policy.h | 18 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 8 +- .../lb_policy/pick_first/pick_first.cc | 5 +- .../lb_policy/round_robin/round_robin.cc | 5 +- .../client_channel/lb_policy/xds/xds.cc | 15 +- .../client_channel/lb_policy_factory.h | 9 - .../client_channel/lb_policy_registry.cc | 91 +++++++++- .../client_channel/lb_policy_registry.h | 8 +- .../client_channel/resolver_result_parsing.cc | 102 +++++------ .../client_channel/resolver_result_parsing.h | 19 +- .../client_channel/resolving_lb_policy.cc | 2 +- .../client_channel/resolving_lb_policy.h | 3 +- .../filters/client_channel/service_config.h | 162 ------------------ .../ext/filters/client_channel/subchannel.cc | 1 - .../message_size/message_size_filter.cc | 3 +- .../client_channel/service_config_test.cc | 13 +- 19 files changed, 214 insertions(+), 338 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 15fe9a8c70a..901655bd3df 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -223,7 +223,7 @@ class ChannelData { ~ChannelData(); static bool ProcessResolverResultLocked( - void* arg, Resolver::Result* result, const char** lb_policy_name, + void* arg, const Resolver::Result& result, const char** lb_policy_name, const ParsedLoadBalancingConfig** lb_policy_config, const HealthCheckParsedObject** health_check); @@ -252,8 +252,8 @@ class ChannelData { QueuedPick* queued_picks_ = nullptr; // Linked list of queued picks. // Data from service config. bool received_service_config_data_ = false; - grpc_core::RefCountedPtr retry_throttle_data_; - grpc_core::RefCountedPtr service_config_; + RefCountedPtr retry_throttle_data_; + RefCountedPtr service_config_; // // Fields used in the control plane. Guarded by combiner. @@ -619,7 +619,7 @@ class CallData { grpc_call_context_element* call_context_; RefCountedPtr retry_throttle_data_; - RefCountedPtr service_config_; + RefCountedPtr service_config_; const ClientChannelMethodParsedObject* method_params_ = nullptr; RefCountedPtr subchannel_call_; @@ -1110,11 +1110,11 @@ ChannelData::~ChannelData() { // Synchronous callback from ResolvingLoadBalancingPolicy to process a // resolver result update. bool ChannelData::ProcessResolverResultLocked( - void* arg, Resolver::Result* result, const char** lb_policy_name, + void* arg, const Resolver::Result& result, const char** lb_policy_name, const ParsedLoadBalancingConfig** lb_policy_config, - const grpc_core::HealthCheckParsedObject** health_check) { + const HealthCheckParsedObject** health_check) { ChannelData* chand = static_cast(arg); - ProcessedResolverResult resolver_result(result, chand->enable_retries_); + ProcessedResolverResult resolver_result(result); const char* service_config_json = resolver_result.service_config_json(); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", @@ -1854,7 +1854,7 @@ void CallData::DoRetry(grpc_call_element* elem, // Compute backoff delay. grpc_millis next_attempt_time; if (server_pushback_ms >= 0) { - next_attempt_time = grpc_core::ExecCtx::Get()->Now() + server_pushback_ms; + next_attempt_time = ExecCtx::Get()->Now() + server_pushback_ms; last_attempt_got_server_pushback_ = true; } else { if (num_attempts_completed_ == 1 || last_attempt_got_server_pushback_) { @@ -1871,7 +1871,7 @@ void CallData::DoRetry(grpc_call_element* elem, if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: retrying failed call in %" PRId64 " ms", chand, - this, next_attempt_time - grpc_core::ExecCtx::Get()->Now()); + this, next_attempt_time - ExecCtx::Get()->Now()); } // Schedule retry after computed delay. GRPC_CLOSURE_INIT(&pick_closure_, StartPickLocked, elem, @@ -3079,22 +3079,22 @@ void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) { gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call", chand, this); } - if (chand->service_config() != nullptr) { + service_config_ = chand->service_config(); + if (service_config_ != nullptr) { // Store a ref to the service_config in CallData. Also, save pointers to the // ServiceConfig and ServiceConfigObjectsVector (for this call) in the // call_context so that all future filters can access it. - service_config_ = chand->service_config(); call_context_[GRPC_SERVICE_CONFIG].value = &service_config_; const auto* method_params_vector_ptr = - chand->service_config()->GetMethodServiceConfigObjectsVector(path_); + service_config_->GetMethodServiceConfigObjectsVector(path_); if (method_params_vector_ptr != nullptr) { method_params_ = static_cast( ((*method_params_vector_ptr) - [grpc_core::internal::ClientChannelServiceConfigParser:: + [internal::ClientChannelServiceConfigParser:: client_channel_service_config_parser_index()]) .get()); call_context_[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value = - const_cast( + const_cast( method_params_vector_ptr); } } 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 729043bebfc..a5d2c83ecd3 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -53,7 +53,6 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { void grpc_service_config_register_parsers() { grpc_core::internal::ClientChannelServiceConfigParser::Register(); - grpc_core::MessageSizeParser::Register(); grpc_core::HealthCheckParser::Register(); } diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 19142e3f3b7..90ac4d786ca 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -62,65 +62,6 @@ void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg, policy->Unref(); } -grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( - const grpc_json* lb_config_array, const char* field_name, - grpc_error** error) { - GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); - char* error_msg; - if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) { - gpr_asprintf(&error_msg, "field:%s error:type should be array", field_name); - *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); - gpr_free(error_msg); - 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) { - gpr_asprintf(&error_msg, - "field:%s error:child entry should be of type object", - field_name); - *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); - gpr_free(error_msg); - 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) { - gpr_asprintf(&error_msg, - "field:%s error:child entry should be of type object", - field_name); - *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); - gpr_free(error_msg); - return nullptr; - } - if (policy != nullptr) { - gpr_asprintf(&error_msg, "field:%s error:oneOf violation", field_name); - *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); - gpr_free(error_msg); - return nullptr; - } // Violate "oneof" type. - policy = field; - } - if (policy == nullptr) { - gpr_asprintf(&error_msg, "field:%s error:no policy found in child entry", - field_name); - *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); - gpr_free(error_msg); - return nullptr; - } - // If we support this policy, then select it. - if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key)) { - return policy; - } - } - gpr_asprintf(&error_msg, "field:%s error:No known policy", field_name); - *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); - gpr_free(error_msg); - return nullptr; -} - // // LoadBalancingPolicy::UpdateArgs // diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 2ef968a616a..057222aa14a 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -36,7 +36,17 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount; namespace grpc_core { -class ParsedLoadBalancingConfig; +/// Interface for parsed forms of load balancing configs found in a service +/// config. +class ParsedLoadBalancingConfig { + public: + virtual ~ParsedLoadBalancingConfig() = default; + + // Returns the load balancing policy name + virtual const char* name() const GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS; +}; /// Interface for load balancing policies. /// @@ -272,12 +282,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { 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, - const char* field_name, - grpc_error** error); - // A picker that returns PICK_QUEUE for all picks. // Also calls the parent LB policy's ExitIdleLocked() method when the // first pick is seen. 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 d8e942e6570..98c9f81ddda 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 @@ -1814,8 +1814,10 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { UniquePtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); - GPR_DEBUG_ASSERT(json != nullptr); - GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + if (json == nullptr) { + return UniquePtr( + New(nullptr)); + } InlinedVector error_list; UniquePtr child_policy = nullptr; @@ -1830,7 +1832,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, "childPolicy", &parse_error); + field, &parse_error); if (parse_error != GRPC_ERROR_NONE) { error_list.push_back(parse_error); } 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 21fda23ab71..899c6f14b6c 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 @@ -548,8 +548,9 @@ class PickFirstFactory : public LoadBalancingPolicyFactory { UniquePtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { - GPR_DEBUG_ASSERT(json != nullptr); - GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + if (json != nullptr) { + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + } return UniquePtr(New()); } }; 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 193e383a433..76187d0978a 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 @@ -525,8 +525,9 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory { UniquePtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { - GPR_DEBUG_ASSERT(json != nullptr); - GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + if (json != nullptr) { + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + } return UniquePtr(New()); } }; 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 7b9c2b320fd..2a00543f593 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 @@ -1667,7 +1667,16 @@ class XdsFactory : public LoadBalancingPolicyFactory { UniquePtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { - GPR_DEBUG_ASSERT(json != nullptr); + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + if (json == nullptr) { + // xds was mentioned as a policy in the deprecated loadBalancingPolicy + // field. + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:Xds Parser has required field - " + "balancerName. Please use loadBalancingConfig instead of the " + "deprecated loadBalancingPolicy"); + return nullptr; + } GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); InlinedVector error_list; @@ -1697,7 +1706,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, "childPolicy", &parse_error); + field, &parse_error); if (child_policy == nullptr) { GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); error_list.push_back(parse_error); @@ -1710,7 +1719,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { } grpc_error* parse_error = GRPC_ERROR_NONE; fallback_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, "fallbackPolicy", &parse_error); + field, &parse_error); if (fallback_policy == nullptr) { GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); error_list.push_back(parse_error); 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 cb7b547f589..4aee5848c86 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -27,15 +27,6 @@ namespace grpc_core { -class ParsedLoadBalancingConfig { - public: - virtual ~ParsedLoadBalancingConfig() = default; - - virtual const char* name() const GRPC_ABSTRACT; - - GRPC_ABSTRACT_BASE_CLASS; -}; - class LoadBalancingPolicyFactory { public: /// Returns a new LB policy instance. 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 f4cc115eefc..78b8a6f706f 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -99,25 +99,87 @@ bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) { return g_state->GetLoadBalancingPolicyFactory(name) != nullptr; } +namespace { +// Returns the JSON node of policy (with both policy name and config content) +// given the JSON node of a LoadBalancingConfig array. +grpc_json* ParseLoadBalancingConfigHelper(const grpc_json* lb_config_array, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + char* error_msg; + if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) { + gpr_asprintf(&error_msg, "field:%s error:type should be array", + lb_config_array->key); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } + const char* field_name = lb_config_array->key; + // 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) { + gpr_asprintf(&error_msg, + "field:%s error:child entry should be of type object", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + 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) { + gpr_asprintf(&error_msg, + "field:%s error:child entry should be of type object", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } + if (policy != nullptr) { + gpr_asprintf(&error_msg, "field:%s error:oneOf violation", field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } // Violate "oneof" type. + policy = field; + } + if (policy == nullptr) { + gpr_asprintf(&error_msg, "field:%s error:no policy found in child entry", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } + // If we support this policy, then select it. + if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key)) { + return policy; + } + } + gpr_asprintf(&error_msg, "field:%s error:No known policy", field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; +} +} // namespace + UniquePtr LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, - const char* field_name, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); GPR_ASSERT(g_state != nullptr); - const grpc_json* policy = - LoadBalancingPolicy::ParseLoadBalancingConfig(json, field_name, error); + const grpc_json* policy = ParseLoadBalancingConfigHelper(json, error); if (policy == nullptr) { return nullptr; } else { - GPR_DEBUG_ASSERT(*error == GRPC_ERROR_NONE); + GPR_DEBUG_ASSERT(*error == GRPC_ERROR_NONE && json != nullptr); // Find factory. LoadBalancingPolicyFactory* factory = g_state->GetLoadBalancingPolicyFactory(policy->key); if (factory == nullptr) { char* msg; gpr_asprintf(&msg, "field:%s error:Factory not found to create policy", - field_name); + json->key); *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return nullptr; @@ -127,4 +189,23 @@ LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, } } +grpc_error* LoadBalancingPolicyRegistry::ParseDeprecatedLoadBalancingPolicy( + const grpc_json* json) { + GPR_DEBUG_ASSERT(g_state != nullptr); + GPR_DEBUG_ASSERT(json != nullptr); + if (json->type != GRPC_JSON_STRING) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:type should be string"); + } + auto* factory = g_state->GetLoadBalancingPolicyFactory(json->value); + if (factory == nullptr) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:Unknown lb policy"); + } + grpc_error* error = GRPC_ERROR_NONE; + // Check if the load balancing policy allows an empty config + factory->ParseLoadBalancingConfig(nullptr, &error); + return error; +} + } // namespace grpc_core 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 8ac845c59f1..ffeb44de9de 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -52,8 +52,14 @@ class LoadBalancingPolicyRegistry { /// registry. static bool LoadBalancingPolicyExists(const char* name); + /// Returns a parsed object of the load balancing policy to be used from a + /// LoadBalancingConfig array \a json. \a field_name specifies static UniquePtr ParseLoadBalancingConfig( - const grpc_json* json, const char* field_name, grpc_error** error); + const grpc_json* json, grpc_error** error); + + /// Validates if the deprecated loadBalancingPolicy field can be parsed. + /// Returns GRPC_ERROR_NONE if successfully parsed. + static grpc_error* ParseDeprecatedLoadBalancingPolicy(const grpc_json* json); }; } // namespace grpc_core 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 dea8c915856..2d5a5bb8e2d 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -59,13 +59,13 @@ void ClientChannelServiceConfigParser::Register() { } ProcessedResolverResult::ProcessedResolverResult( - Resolver::Result* resolver_result, bool parse_retry) - : service_config_(resolver_result->service_config) { + const Resolver::Result& resolver_result) + : 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)); + grpc_channel_args_find(resolver_result.args, GRPC_ARG_SERVICE_CONFIG)); if (service_config_json != nullptr) { grpc_error* error = GRPC_ERROR_NONE; service_config_ = ServiceConfig::Create(service_config_json, &error); @@ -74,60 +74,62 @@ ProcessedResolverResult::ProcessedResolverResult( } } // 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); + ProcessServiceConfig(resolver_result); + ProcessLbPolicy(resolver_result); } void ProcessedResolverResult::ProcessServiceConfig( - const Resolver::Result& resolver_result, bool parse_retry) { + const Resolver::Result& resolver_result) { if (service_config_ == nullptr) return; health_check_ = static_cast( service_config_->GetParsedGlobalServiceConfigObject( HealthCheckParser::ParserIndex())); service_config_json_ = service_config_->service_config_json(); - auto* parsed_object = static_cast( + auto* parsed_object = static_cast( service_config_->GetParsedGlobalServiceConfigObject( ClientChannelServiceConfigParser:: client_channel_service_config_parser_index())); - if (!parsed_object) { return; } - 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; - if (parsed_object->retry_throttling().has_value()) { - retry_throttle_data_ = - grpc_core::internal::ServerRetryThrottleMap::GetDataForServer( - server_name_, - parsed_object->retry_throttling().value().max_milli_tokens, - parsed_object->retry_throttling().value().milli_token_ratio); - } - grpc_uri_destroy(uri); - } - if (parsed_object->parsed_lb_config()) { - lb_policy_name_.reset( - gpr_strdup(parsed_object->parsed_lb_config()->name())); - lb_policy_config_ = parsed_object->parsed_lb_config(); - } else { - lb_policy_name_.reset( - gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); + 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'); + if (parsed_object->retry_throttling().has_value()) { + char* server_name = uri->path[0] == '/' ? uri->path + 1 : uri->path; + retry_throttle_data_ = internal::ServerRetryThrottleMap::GetDataForServer( + server_name, parsed_object->retry_throttling().value().max_milli_tokens, + parsed_object->retry_throttling().value().milli_token_ratio); } + grpc_uri_destroy(uri); } -void ProcessedResolverResult::ProcessLbPolicyName( +void ProcessedResolverResult::ProcessLbPolicy( const Resolver::Result& resolver_result) { // Prefer the LB policy name found in the service config. - if (lb_policy_name_ != nullptr) { - char* lb_policy_name = lb_policy_name_.get(); - for (size_t i = 0; i < strlen(lb_policy_name); ++i) { - lb_policy_name[i] = tolower(lb_policy_name[i]); + if (service_config_ != nullptr) { + auto* parsed_object = static_cast( + service_config_->GetParsedGlobalServiceConfigObject( + ClientChannelServiceConfigParser:: + client_channel_service_config_parser_index())); + if (parsed_object != nullptr) { + if (parsed_object->parsed_lb_config()) { + lb_policy_name_.reset( + gpr_strdup(parsed_object->parsed_lb_config()->name())); + lb_policy_config_ = parsed_object->parsed_lb_config(); + } else { + lb_policy_name_.reset( + gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); + if (lb_policy_name_ != nullptr) { + char* lb_policy_name = lb_policy_name_.get(); + for (size_t i = 0; i < strlen(lb_policy_name); ++i) { + lb_policy_name[i] = tolower(lb_policy_name[i]); + } + } + } } } // Otherwise, find the LB policy name set by the client API. @@ -342,8 +344,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, InlinedVector error_list; UniquePtr parsed_lb_config; const char* lb_policy_name = nullptr; - grpc_core::Optional - retry_throttling; + Optional retry_throttling; for (grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) { continue; // Not the LB config global parameter @@ -356,8 +357,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, } else { grpc_error* parse_error = GRPC_ERROR_NONE; parsed_lb_config = - LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, "loadBalancingConfig", &parse_error); + LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(field, + &parse_error); if (parsed_lb_config == nullptr) { error_list.push_back(parse_error); } @@ -375,12 +376,15 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, field->value)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:Unknown lb policy")); - } else if (strcmp(field->value, "xds_experimental") == 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingPolicy error:xds not supported with this " - "field. Please use loadBalancingConfig")); } else { - lb_policy_name = field->value; + grpc_error* parsing_error = + LoadBalancingPolicyRegistry::ParseDeprecatedLoadBalancingPolicy( + field); + if (parsing_error != GRPC_ERROR_NONE) { + error_list.push_back(parsing_error); + } else { + lb_policy_name = field->value; + } } } // Parse retry throttling @@ -392,8 +396,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling error:Duplicate entry")); } else { - grpc_core::Optional max_milli_tokens(false, 0); - grpc_core::Optional milli_token_ratio(false, 0); + Optional max_milli_tokens(false, 0); + Optional milli_token_ratio(false, 0); for (grpc_json* sub_field = field->child; sub_field != nullptr; sub_field = sub_field->next) { if (sub_field->key == nullptr) continue; 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 327818f668d..02a49bad2e9 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -47,12 +47,12 @@ class ClientChannelGlobalParsedObject : public ServiceConfigParsedObject { ClientChannelGlobalParsedObject( UniquePtr parsed_lb_config, const char* parsed_deprecated_lb_policy, - const grpc_core::Optional& retry_throttling) + const Optional& retry_throttling) : parsed_lb_config_(std::move(parsed_lb_config)), parsed_deprecated_lb_policy_(parsed_deprecated_lb_policy), retry_throttling_(retry_throttling) {} - grpc_core::Optional retry_throttling() const { + Optional retry_throttling() const { return retry_throttling_; } @@ -67,7 +67,7 @@ class ClientChannelGlobalParsedObject : public ServiceConfigParsedObject { private: UniquePtr parsed_lb_config_; const char* parsed_deprecated_lb_policy_ = nullptr; - grpc_core::Optional retry_throttling_; + Optional retry_throttling_; }; class ClientChannelMethodParsedObject : public ServiceConfigParsedObject { @@ -116,9 +116,8 @@ class ClientChannelServiceConfigParser : public ServiceConfigParser { class ProcessedResolverResult { public: // Processes the resolver result and populates the relative members - // for later consumption. Tries to parse retry parameters only if parse_retry - // is true. - ProcessedResolverResult(Resolver::Result* resolver_result, bool parse_retry); + // for later consumption. + ProcessedResolverResult(const Resolver::Result& resolver_result); // Getters. Any managed object's ownership is transferred. const char* service_config_json() { return service_config_json_; } @@ -137,11 +136,10 @@ class ProcessedResolverResult { private: // Finds the service config; extracts LB config and (maybe) retry throttle // params from it. - void ProcessServiceConfig(const Resolver::Result& resolver_result, - bool parse_retry); + void ProcessServiceConfig(const Resolver::Result& resolver_result); - // Finds the LB policy name (when no LB config was found). - void ProcessLbPolicyName(const Resolver::Result& resolver_result); + // Extracts the LB policy. + void ProcessLbPolicy(const Resolver::Result& resolver_result); // Parses the service config. Intended to be used by // ServiceConfig::ParseGlobalParams. @@ -159,7 +157,6 @@ class ProcessedResolverResult { UniquePtr lb_policy_name_; const ParsedLoadBalancingConfig* lb_policy_config_ = nullptr; // Retry throttle data. - char* server_name_ = nullptr; RefCountedPtr retry_throttle_data_; const HealthCheckParsedObject* health_check_ = nullptr; }; 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 29e87e8aefd..97f5e5fda80 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -539,7 +539,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( 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, + process_resolver_result_user_data_, result, &lb_policy_name, &lb_policy_config, &health_check); } else { lb_policy_name = child_policy_name_.get(); 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 afbee184690..84d134254d0 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -66,7 +66,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, Resolver::Result* result, const char** lb_policy_name, + void* user_data, const Resolver::Result& result, + const char** lb_policy_name, const ParsedLoadBalancingConfig** lb_policy_config, const HealthCheckParsedObject** health_check); // If error is set when this returns, then construction failed, and diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index f45cab9ee7d..0b7a8d33855 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -100,33 +100,6 @@ class ServiceConfig : public RefCounted { 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 - using ProcessJson = void (*)(const grpc_json*, T*); - template - void ParseGlobalParams(ProcessJson process_json, T* arg) const; - - /// Creates a method config table based on the data in \a json. - /// The table's keys are request paths. The table's value type is - /// returned by \a create_value(), based on data parsed from the JSON tree. - /// Returns null on error. - template - using CreateValue = RefCountedPtr (*)(const grpc_json* method_config_json); - template - RefCountedPtr>> CreateMethodConfigTable( - CreateValue create_value) const; - - /// A helper function for looking up values in the table returned by - /// \a CreateMethodConfigTable(). - /// Gets the method config for the specified \a path, which should be of - /// the form "/service/method". - /// Returns null if the method has no config. - /// Caller does NOT own a reference to the result. - template - static RefCountedPtr MethodConfigTableLookup( - const SliceHashTable>& table, const grpc_slice& path); - /// Retrieves the parsed global service config object at index \a index. ServiceConfigParsedObject* GetParsedGlobalServiceConfigObject(size_t index) { GPR_DEBUG_ASSERT(index < parsed_global_service_config_objects_.size()); @@ -190,14 +163,6 @@ class ServiceConfig : public RefCounted { static UniquePtr ParseJsonMethodName(grpc_json* json, grpc_error** error); - // Parses the method config from \a json. Adds an entry to \a entries for - // each name found, incrementing \a idx for each entry added. - // Returns false on error. - template - static bool ParseJsonMethodConfig( - grpc_json* json, CreateValue create_value, - typename SliceHashTable>::Entry* entries, size_t* idx); - grpc_error* ParseJsonMethodConfigToServiceConfigObjectsTable( const grpc_json* json, SliceHashTable::Entry* entries, @@ -220,133 +185,6 @@ class ServiceConfig : public RefCounted { service_config_objects_vectors_storage_; }; -// -// implementation -- no user-serviceable parts below -// - -template -void ServiceConfig::ParseGlobalParams(ProcessJson process_json, - T* arg) const { - if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) { - return; - } - for (grpc_json* field = json_tree_->child; field != nullptr; - field = field->next) { - if (field->key == nullptr) return; - if (strcmp(field->key, "methodConfig") == 0) continue; - process_json(field, arg); - } -} - -template -bool ServiceConfig::ParseJsonMethodConfig( - grpc_json* json, CreateValue create_value, - typename SliceHashTable>::Entry* entries, size_t* idx) { - // Construct value. - RefCountedPtr method_config = create_value(json); - if (method_config == nullptr) return false; - // Construct list of paths. - InlinedVector, 10> paths; - for (grpc_json* child = json->child; child != nullptr; child = child->next) { - if (child->key == nullptr) continue; - if (strcmp(child->key, "name") == 0) { - if (child->type != GRPC_JSON_ARRAY) return false; - for (grpc_json* name = child->child; name != nullptr; name = name->next) { - grpc_error* error = GRPC_ERROR_NONE; - UniquePtr path = ParseJsonMethodName(name, &error); - // We are not reporting the error here. - GRPC_ERROR_UNREF(error); - if (path == nullptr) return false; - paths.push_back(std::move(path)); - } - } - } - if (paths.size() == 0) return false; // No names specified. - // Add entry for each path. - for (size_t i = 0; i < paths.size(); ++i) { - entries[*idx].key = grpc_slice_from_copied_string(paths[i].get()); - entries[*idx].value = method_config; // Takes a new ref. - ++*idx; - } - // Success. - return true; -} - -template -RefCountedPtr>> -ServiceConfig::CreateMethodConfigTable(CreateValue create_value) const { - // Traverse parsed JSON tree. - if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) { - return nullptr; - } - size_t num_entries = 0; - typename SliceHashTable>::Entry* entries = nullptr; - for (grpc_json* field = json_tree_->child; field != nullptr; - field = field->next) { - if (field->key == nullptr) return nullptr; - if (strcmp(field->key, "methodConfig") == 0) { - if (entries != nullptr) return nullptr; // Duplicate. - if (field->type != GRPC_JSON_ARRAY) return nullptr; - // Find number of entries. - for (grpc_json* method = field->child; method != nullptr; - method = method->next) { - int count = CountNamesInMethodConfig(method); - if (count <= 0) return nullptr; - num_entries += static_cast(count); - } - // Populate method config table entries. - entries = static_cast>::Entry*>( - gpr_zalloc(num_entries * - sizeof(typename SliceHashTable>::Entry))); - size_t idx = 0; - for (grpc_json* method = field->child; method != nullptr; - method = method->next) { - if (!ParseJsonMethodConfig(method, create_value, entries, &idx)) { - for (size_t i = 0; i < idx; ++i) { - grpc_slice_unref_internal(entries[i].key); - entries[i].value.reset(); - } - gpr_free(entries); - return nullptr; - } - } - GPR_ASSERT(idx == num_entries); - } - } - // Instantiate method config table. - RefCountedPtr>> method_config_table; - if (entries != nullptr) { - method_config_table = - SliceHashTable>::Create(num_entries, entries, nullptr); - gpr_free(entries); - } - return method_config_table; -} - -template -RefCountedPtr ServiceConfig::MethodConfigTableLookup( - 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/*"). - if (value == nullptr) { - char* path_str = grpc_slice_to_c_string(path); - const char* sep = strrchr(path_str, '/') + 1; - const size_t len = (size_t)(sep - path_str); - char* buf = (char*)gpr_malloc(len + 2); // '*' and NUL - memcpy(buf, path_str, len); - buf[len] = '*'; - buf[len + 1] = '\0'; - grpc_slice wildcard_path = grpc_slice_from_copied_string(buf); - gpr_free(buf); - value = table.Get(wildcard_path); - grpc_slice_unref_internal(wildcard_path); - gpr_free(path_str); - if (value == nullptr) return nullptr; - } - return RefCountedPtr(*value); -} - } // namespace grpc_core #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 ec2b01c65a8..b21fec7cc3f 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -565,7 +565,6 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, "subchannel"); grpc_connectivity_state_init(&state_and_health_tracker_, GRPC_CHANNEL_IDLE, "subchannel"); - if (health_check != nullptr) { health_check_service_name_ = UniquePtr(gpr_strdup(health_check->service_name())); 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 f3976cb783f..d7bfa28fee1 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -291,7 +291,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, // Destructor for channel_data. static void destroy_channel_elem(grpc_channel_element* elem) { channel_data* chand = static_cast(elem->channel_data); - chand->svc_cfg.reset(); + chand->~channel_data(); } const grpc_channel_filter grpc_message_size_filter = { @@ -355,6 +355,7 @@ void grpc_message_size_filter_init(void) { grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_message_size_filter, nullptr); + grpc_core::MessageSizeParser::Register(); } void grpc_message_size_filter_shutdown(void) {} diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index 7ea4a88e9bb..544d91ec02e 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -546,12 +546,13 @@ TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:" - "loadBalancingPolicy error:xds not supported)")); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:loadBalancingPolicy error:Xds " + "Parser has required field - balancerName. Please use " + "loadBalancingConfig instead of the deprecated loadBalancingPolicy)")); std::smatch match; std::string s(grpc_error_string(error)); EXPECT_TRUE(std::regex_search(s, match, e)); From 4309a98b66279a5393d2f69bccd6eed3397b8201 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 22 Apr 2019 21:18:47 -0700 Subject: [PATCH 1921/2143] Health checking service name to be passed as a channel arg for now --- .../filters/client_channel/client_channel.cc | 32 ++++++++++++------- .../client_channel/client_channel_factory.h | 5 ++- .../health/health_check_parser.cc | 1 + .../ext/filters/client_channel/lb_policy.cc | 6 ---- .../ext/filters/client_channel/lb_policy.h | 6 ++-- .../client_channel/lb_policy/grpclb/grpclb.cc | 11 ++----- .../lb_policy/pick_first/pick_first.cc | 8 ++--- .../lb_policy/round_robin/round_robin.cc | 8 ++--- .../lb_policy/subchannel_list.h | 7 ++-- .../client_channel/lb_policy/xds/xds.cc | 10 ++---- .../client_channel/resolving_lb_policy.cc | 20 ++++-------- .../client_channel/resolving_lb_policy.h | 6 ++-- .../ext/filters/client_channel/subchannel.cc | 15 ++++----- .../ext/filters/client_channel/subchannel.h | 6 ++-- .../chttp2/client/insecure/channel_create.cc | 6 ++-- .../client/secure/secure_channel_create.cc | 6 ++-- test/core/util/test_lb_policies.cc | 7 ++-- test/cpp/microbenchmarks/bm_call_create.cc | 3 +- 18 files changed, 64 insertions(+), 99 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 901655bd3df..ffb2b9a904b 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -224,8 +224,7 @@ class ChannelData { static bool ProcessResolverResultLocked( void* arg, const Resolver::Result& result, const char** lb_policy_name, - const ParsedLoadBalancingConfig** lb_policy_config, - const HealthCheckParsedObject** health_check); + const ParsedLoadBalancingConfig** lb_policy_config); grpc_error* DoPingLocked(grpc_transport_op* op); @@ -932,15 +931,26 @@ class ChannelData::ClientChannelControlHelper "ClientChannelControlHelper"); } - Subchannel* CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) override { - grpc_arg arg = SubchannelPoolInterface::CreateChannelArg( + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + grpc_arg args_to_add[2]; + int num_args_to_add = 0; + if (chand_->service_config_ != nullptr) { + /*const auto* health_check_object = static_cast( + chand_->service_config_->GetParsedGlobalServiceConfigObject( + HealthCheckParser::ParserIndex())); + if (health_check_object != nullptr) { + args_to_add[0] = grpc_channel_arg_string_create( + const_cast("grpc.temp.health_check"), + const_cast(health_check_object->service_name())); + num_args_to_add++; + }*/ + } + args_to_add[num_args_to_add++] = SubchannelPoolInterface::CreateChannelArg( chand_->subchannel_pool_.get()); grpc_channel_args* new_args = - grpc_channel_args_copy_and_add(&args, &arg, 1); - Subchannel* subchannel = chand_->client_channel_factory_->CreateSubchannel( - new_args, health_check); + grpc_channel_args_copy_and_add(&args, args_to_add, num_args_to_add); + Subchannel* subchannel = + chand_->client_channel_factory_->CreateSubchannel(new_args); grpc_channel_args_destroy(new_args); return subchannel; } @@ -1111,8 +1121,7 @@ ChannelData::~ChannelData() { // resolver result update. bool ChannelData::ProcessResolverResultLocked( void* arg, const Resolver::Result& result, const char** lb_policy_name, - const ParsedLoadBalancingConfig** lb_policy_config, - const HealthCheckParsedObject** health_check) { + const ParsedLoadBalancingConfig** lb_policy_config) { ChannelData* chand = static_cast(arg); ProcessedResolverResult resolver_result(result); const char* service_config_json = resolver_result.service_config_json(); @@ -1140,7 +1149,6 @@ bool ChannelData::ProcessResolverResultLocked( // Return results. *lb_policy_name = chand->info_lb_policy_name_.get(); *lb_policy_config = resolver_result.lb_policy_config(); - *health_check = resolver_result.health_check(); return service_config_changed; } 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 43a696da983..883409fbee8 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.h +++ b/src/core/ext/filters/client_channel/client_channel_factory.h @@ -34,9 +34,8 @@ class ClientChannelFactory { virtual ~ClientChannelFactory() = default; // Creates a subchannel with the specified args. - virtual Subchannel* CreateSubchannel( - const grpc_channel_args* args, - const HealthCheckParsedObject* health_check) GRPC_ABSTRACT; + virtual Subchannel* CreateSubchannel(const grpc_channel_args* args) + GRPC_ABSTRACT; // Creates a channel for the specified target with the specified args. virtual grpc_channel* CreateChannel( diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.cc b/src/core/ext/filters/client_channel/health/health_check_parser.cc index 1dcef527861..13bad49c5b6 100644 --- a/src/core/ext/filters/client_channel/health/health_check_parser.cc +++ b/src/core/ext/filters/client_channel/health/health_check_parser.cc @@ -61,6 +61,7 @@ UniquePtr HealthCheckParser::ParseGlobalParams( } } } + if (service_name == nullptr) return nullptr; return UniquePtr( New(service_name)); } diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 90ac4d786ca..6fa799343ca 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -69,15 +69,12 @@ void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg, LoadBalancingPolicy::UpdateArgs::UpdateArgs(const UpdateArgs& other) { addresses = other.addresses; config = other.config; - health_check = other.health_check; args = grpc_channel_args_copy(other.args); } LoadBalancingPolicy::UpdateArgs::UpdateArgs(UpdateArgs&& other) { addresses = std::move(other.addresses); config = std::move(other.config); - health_check = other.health_check; - other.health_check = nullptr; // TODO(roth): Use std::move() once channel args is converted to C++. args = other.args; other.args = nullptr; @@ -87,7 +84,6 @@ LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=( const UpdateArgs& other) { addresses = other.addresses; config = other.config; - health_check = other.health_check; grpc_channel_args_destroy(args); args = grpc_channel_args_copy(other.args); return *this; @@ -97,8 +93,6 @@ LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=( UpdateArgs&& other) { addresses = std::move(other.addresses); config = std::move(other.config); - health_check = other.health_check; - other.health_check = nullptr; // TODO(roth): Use std::move() once channel args is converted to C++. grpc_channel_args_destroy(args); args = other.args; diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 057222aa14a..b23f77bee7c 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -185,9 +185,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual ~ChannelControlHelper() = default; /// Creates a new subchannel with the specified channel args. - virtual Subchannel* CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) GRPC_ABSTRACT; + virtual Subchannel* CreateSubchannel(const grpc_channel_args& args) + 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 @@ -211,7 +210,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { struct UpdateArgs { ServerAddressList addresses; const ParsedLoadBalancingConfig* config = nullptr; - const HealthCheckParsedObject* health_check = nullptr; const grpc_channel_args* args = nullptr; // TODO(roth): Remove everything below once channel args is 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 98c9f81ddda..ba7276747fd 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 @@ -292,9 +292,7 @@ class GrpcLb : public LoadBalancingPolicy { explicit Helper(RefCountedPtr parent) : parent_(std::move(parent)) {} - Subchannel* CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) override; + Subchannel* CreateSubchannel(const grpc_channel_args& args) override; grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, @@ -619,15 +617,12 @@ bool GrpcLb::Helper::CalledByCurrentChild() const { return child_ == parent_->child_policy_.get(); } -Subchannel* GrpcLb::Helper::CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) { +Subchannel* GrpcLb::Helper::CreateSubchannel(const grpc_channel_args& args) { if (parent_->shutting_down_ || (!CalledByPendingChild() && !CalledByCurrentChild())) { return nullptr; } - return parent_->channel_control_helper()->CreateSubchannel(args, - health_check); + return parent_->channel_control_helper()->CreateSubchannel(args); } grpc_channel* GrpcLb::Helper::CreateChannel(const char* target, 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 899c6f14b6c..398c8efd524 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 @@ -88,10 +88,9 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) + const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, - policy->channel_control_helper(), args, health_check) { + 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. @@ -256,8 +255,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) { grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args.args, &new_arg, 1); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args, - args.health_check); + 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 76187d0978a..089f57827c7 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 @@ -109,10 +109,9 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelList(RoundRobin* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) + const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, - policy->channel_control_helper(), args, health_check) { + 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. @@ -481,8 +480,7 @@ void RoundRobin::UpdateLocked(UpdateArgs args) { } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args, - args.health_check); + 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 51c45d9f87a..004ee04459b 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,8 +232,7 @@ class SubchannelList : public InternallyRefCounted { SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, LoadBalancingPolicy::ChannelControlHelper* helper, - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check); + const grpc_channel_args& args); virtual ~SubchannelList(); @@ -486,7 +485,7 @@ SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, LoadBalancingPolicy::ChannelControlHelper* helper, - const grpc_channel_args& args, const HealthCheckParsedObject* health_check) + const grpc_channel_args& args) : InternallyRefCounted(tracer), policy_(policy), tracer_(tracer), @@ -521,7 +520,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 = helper->CreateSubchannel(*new_args, health_check); + 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 2a00543f593..ce752adaeef 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 @@ -323,9 +323,7 @@ class XdsLb : public LoadBalancingPolicy { explicit Helper(RefCountedPtr entry) : entry_(std::move(entry)) {} - Subchannel* CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) override; + Subchannel* CreateSubchannel(const grpc_channel_args& args) override; grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, @@ -1574,14 +1572,12 @@ bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByCurrentChild() const { } Subchannel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) { + const grpc_channel_args& args) { if (entry_->parent_->shutting_down_ || (!CalledByPendingChild() && !CalledByCurrentChild())) { return nullptr; } - return entry_->parent_->channel_control_helper()->CreateSubchannel( - args, health_check); + return entry_->parent_->channel_control_helper()->CreateSubchannel(args); } grpc_channel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateChannel( 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 97f5e5fda80..34a58358716 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -106,13 +106,10 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper RefCountedPtr parent) : parent_(std::move(parent)) {} - Subchannel* CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) override { + 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, - health_check); + return parent_->channel_control_helper()->CreateSubchannel(args); } grpc_channel* CreateChannel(const char* target, @@ -336,8 +333,7 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, const ParsedLoadBalancingConfig* lb_policy_config, Resolver::Result result, - TraceStringVector* trace_strings, - const HealthCheckParsedObject* health_check) { + 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 @@ -430,7 +426,6 @@ void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( UpdateArgs update_args; update_args.addresses = std::move(result.addresses); update_args.config = std::move(lb_policy_config); - update_args.health_check = health_check; // TODO(roth): Once channel args is converted to C++, use std::move() here. update_args.args = result.args; result.args = nullptr; @@ -535,12 +530,11 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( // Process the resolver result. const char* lb_policy_name = nullptr; const ParsedLoadBalancingConfig* lb_policy_config = nullptr; - const HealthCheckParsedObject* health_check = nullptr; 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, &health_check); + service_config_changed = + process_resolver_result_(process_resolver_result_user_data_, result, + &lb_policy_name, &lb_policy_config); } else { lb_policy_name = child_policy_name_.get(); lb_policy_config = child_lb_config_; @@ -548,7 +542,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( GPR_ASSERT(lb_policy_name != nullptr); // Create or update LB policy, as needed. CreateOrUpdateLbPolicyLocked(lb_policy_name, lb_policy_config, - std::move(result), &trace_strings, health_check); + std::move(result), &trace_strings); // Add channel trace event. if (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 84d134254d0..85fad3093e0 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -68,8 +68,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { typedef bool (*ProcessResolverResultCallback)( void* user_data, const Resolver::Result& result, const char** lb_policy_name, - const ParsedLoadBalancingConfig** lb_policy_config, - const HealthCheckParsedObject** health_check); + const ParsedLoadBalancingConfig** lb_policy_config); // If error is set when this returns, then construction failed, and // the caller may not use the new object. ResolvingLoadBalancingPolicy( @@ -108,8 +107,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { void CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, const ParsedLoadBalancingConfig* lb_policy_config, - Resolver::Result result, TraceStringVector* trace_strings, - const HealthCheckParsedObject* health_check); + Resolver::Result result, TraceStringVector* trace_strings); OrphanablePtr CreateLbPolicyLocked( const char* lb_policy_name, const grpc_channel_args& args, TraceStringVector* trace_strings); diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index b21fec7cc3f..639d0ec79f4 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -532,8 +532,7 @@ BackOff::Options ParseArgsForBackoffValues( } // namespace Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, - const grpc_channel_args* args, - const HealthCheckParsedObject* health_check) + const grpc_channel_args* args) : key_(key), connector_(connector), backoff_(ParseArgsForBackoffValues(args, &min_connect_timeout_ms_)) { @@ -565,10 +564,9 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, "subchannel"); grpc_connectivity_state_init(&state_and_health_tracker_, GRPC_CHANNEL_IDLE, "subchannel"); - if (health_check != nullptr) { - health_check_service_name_ = - UniquePtr(gpr_strdup(health_check->service_name())); - } + health_check_service_name_ = + UniquePtr(gpr_strdup(grpc_channel_arg_get_string( + grpc_channel_args_find(args_, "grpc.temp.health_check")))); 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); @@ -603,8 +601,7 @@ Subchannel::~Subchannel() { } Subchannel* Subchannel::Create(grpc_connector* connector, - const grpc_channel_args* args, - const HealthCheckParsedObject* health_check) { + const grpc_channel_args* args) { SubchannelKey* key = New(args); SubchannelPoolInterface* subchannel_pool = SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs(args); @@ -614,7 +611,7 @@ Subchannel* Subchannel::Create(grpc_connector* connector, Delete(key); return c; } - c = New(key, connector, args, health_check); + 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 diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index fb378150160..c67b51a8fa4 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -179,14 +179,12 @@ class Subchannel { public: // The ctor and dtor are not intended to use directly. Subchannel(SubchannelKey* key, grpc_connector* connector, - const grpc_channel_args* args, - const HealthCheckParsedObject* health_check); + 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, - const HealthCheckParsedObject* health_check); + const grpc_channel_args* args); // Strong and weak refcounting. Subchannel* Ref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); 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 ca5a7458e8d..0d61abd2a01 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -37,13 +37,11 @@ namespace grpc_core { class Chttp2InsecureClientChannelFactory : public ClientChannelFactory { public: - Subchannel* CreateSubchannel( - const grpc_channel_args* args, - const HealthCheckParsedObject* health_check) override { + 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, health_check); + Subchannel* s = 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 c10d1903dd4..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 @@ -44,9 +44,7 @@ namespace grpc_core { class Chttp2SecureClientChannelFactory : public ClientChannelFactory { public: - Subchannel* CreateSubchannel( - const grpc_channel_args* args, - const HealthCheckParsedObject* health_check) override { + Subchannel* CreateSubchannel(const grpc_channel_args* args) override { grpc_channel_args* new_args = GetSecureNamingChannelArgs(args); if (new_args == nullptr) { gpr_log(GPR_ERROR, @@ -54,7 +52,7 @@ class Chttp2SecureClientChannelFactory : public ClientChannelFactory { return nullptr; } grpc_connector* connector = grpc_chttp2_connector_create(); - Subchannel* s = Subchannel::Create(connector, new_args, health_check); + Subchannel* s = Subchannel::Create(connector, new_args); grpc_connector_unref(connector); grpc_channel_args_destroy(new_args); return s; diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 3daa2733267..b871f04bc9e 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -141,11 +141,8 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy InterceptRecvTrailingMetadataCallback cb, void* user_data) : parent_(std::move(parent)), cb_(cb), user_data_(user_data) {} - Subchannel* CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) override { - return parent_->channel_control_helper()->CreateSubchannel(args, - health_check); + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + return parent_->channel_control_helper()->CreateSubchannel(args); } grpc_channel* CreateChannel(const char* target, diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 075a296dc5b..177b0187cc6 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -322,8 +322,7 @@ static void DoNothing(void* arg, grpc_error* error) {} class FakeClientChannelFactory : public grpc_core::ClientChannelFactory { public: grpc_core::Subchannel* CreateSubchannel( - const grpc_channel_args* args, - const grpc_core::HealthCheckParsedObject* health_check) override { + const grpc_channel_args* args) override { return nullptr; } grpc_channel* CreateChannel(const char* target, From 9af9f117602d73c27d08034517fd8b7464848807 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 23 Apr 2019 08:19:41 +0200 Subject: [PATCH 1922/2143] Revert "Enable SIO_LOOPBACK_FAST_PATH on Windows" This reverts commit f5f5ee31a25e37d6a19939f837f0089431f9951c. --- src/core/lib/iomgr/tcp_windows.cc | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 7b464651ea1..1fb0ef8f7ec 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -74,28 +74,12 @@ static grpc_error* set_dualstack(SOCKET sock) { : GRPC_WSA_ERROR(WSAGetLastError(), "setsockopt(IPV6_V6ONLY)"); } -static grpc_error* enable_loopback_fast_path(SOCKET sock) { - int status; - uint32_t param = 1; - DWORD ret; - status = WSAIoctl(sock, /*SIO_LOOPBACK_FAST_PATH==*/_WSAIOW(IOC_VENDOR, 16), - ¶m, sizeof(param), NULL, 0, &ret, 0, 0); - if (status == SOCKET_ERROR) { - status = WSAGetLastError(); - } - return status == 0 || status == WSAEOPNOTSUPP - ? GRPC_ERROR_NONE - : GRPC_WSA_ERROR(status, "WSAIoctl(SIO_LOOPBACK_FAST_PATH)"); -} - grpc_error* grpc_tcp_prepare_socket(SOCKET sock) { grpc_error* err; err = grpc_tcp_set_non_block(sock); if (err != GRPC_ERROR_NONE) return err; err = set_dualstack(sock); if (err != GRPC_ERROR_NONE) return err; - err = enable_loopback_fast_path(sock); - if (err != GRPC_ERROR_NONE) return err; return GRPC_ERROR_NONE; } From f2f27a0e6455cba89669fca257650268ebe8f282 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 16 Apr 2019 10:20:08 -0400 Subject: [PATCH 1923/2143] add non-internal build.cfg files for bazel RBE jobs --- .../internal_ci/linux/grpc_bazel_rbe_asan.cfg | 30 +++++++++++++++++ .../internal_ci/linux/grpc_bazel_rbe_dbg.cfg | 30 +++++++++++++++++ .../grpc_bazel_rbe_incompatible_changes.cfg | 30 +++++++++++++++++ .../internal_ci/linux/grpc_bazel_rbe_msan.cfg | 30 +++++++++++++++++ .../internal_ci/linux/grpc_bazel_rbe_opt.cfg | 30 +++++++++++++++++ .../internal_ci/linux/grpc_bazel_rbe_tsan.cfg | 30 +++++++++++++++++ .../linux/grpc_bazel_rbe_ubsan.cfg | 30 +++++++++++++++++ .../pull_request/grpc_bazel_rbe_asan.cfg | 30 +++++++++++++++++ .../linux/pull_request/grpc_bazel_rbe_dbg.cfg | 30 +++++++++++++++++ .../pull_request/grpc_bazel_rbe_msan.cfg | 30 +++++++++++++++++ .../linux/pull_request/grpc_bazel_rbe_opt.cfg | 30 +++++++++++++++++ .../pull_request/grpc_bazel_rbe_tsan.cfg | 30 +++++++++++++++++ .../pull_request/grpc_bazel_rbe_ubsan.cfg | 30 +++++++++++++++++ .../windows/grpc_bazel_rbe_dbg.cfg | 32 +++++++++++++++++++ 14 files changed, 422 insertions(+) create mode 100644 tools/internal_ci/linux/grpc_bazel_rbe_asan.cfg create mode 100644 tools/internal_ci/linux/grpc_bazel_rbe_dbg.cfg create mode 100644 tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.cfg create mode 100644 tools/internal_ci/linux/grpc_bazel_rbe_msan.cfg create mode 100644 tools/internal_ci/linux/grpc_bazel_rbe_opt.cfg create mode 100644 tools/internal_ci/linux/grpc_bazel_rbe_tsan.cfg create mode 100644 tools/internal_ci/linux/grpc_bazel_rbe_ubsan.cfg create mode 100644 tools/internal_ci/linux/pull_request/grpc_bazel_rbe_asan.cfg create mode 100644 tools/internal_ci/linux/pull_request/grpc_bazel_rbe_dbg.cfg create mode 100644 tools/internal_ci/linux/pull_request/grpc_bazel_rbe_msan.cfg create mode 100644 tools/internal_ci/linux/pull_request/grpc_bazel_rbe_opt.cfg create mode 100644 tools/internal_ci/linux/pull_request/grpc_bazel_rbe_tsan.cfg create mode 100644 tools/internal_ci/linux/pull_request/grpc_bazel_rbe_ubsan.cfg create mode 100644 tools/internal_ci/windows/grpc_bazel_rbe_dbg.cfg diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_asan.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_asan.cfg new file mode 100644 index 00000000000..21afbd04ee3 --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_asan.cfg @@ -0,0 +1,30 @@ +# 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_asan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_dbg.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_dbg.cfg new file mode 100644 index 00000000000..e80321b9a8a --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_dbg.cfg @@ -0,0 +1,30 @@ +# 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_on_foundry_dbg.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.cfg new file mode 100644 index 00000000000..ee883392f4b --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.cfg @@ -0,0 +1,30 @@ +# 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_rbe_incompatible_changes.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_msan.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_msan.cfg new file mode 100644 index 00000000000..be939bbff55 --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_msan.cfg @@ -0,0 +1,30 @@ +# 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_msan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_opt.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_opt.cfg new file mode 100644 index 00000000000..48a6d91f123 --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_opt.cfg @@ -0,0 +1,30 @@ +# 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_on_foundry_opt.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} \ No newline at end of file diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_tsan.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_tsan.cfg new file mode 100644 index 00000000000..f45a4c2da2d --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_tsan.cfg @@ -0,0 +1,30 @@ +# 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_tsan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_ubsan.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_ubsan.cfg new file mode 100644 index 00000000000..f0cf94ad142 --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_ubsan.cfg @@ -0,0 +1,30 @@ +# 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_ubsan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_asan.cfg b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_asan.cfg new file mode 100644 index 00000000000..f978c730b7c --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_asan.cfg @@ -0,0 +1,30 @@ +# 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/pull_request/grpc_asan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_dbg.cfg b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_dbg.cfg new file mode 100644 index 00000000000..ab47a30b247 --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_dbg.cfg @@ -0,0 +1,30 @@ +# 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/pull_request/grpc_bazel_on_foundry_dbg.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} \ No newline at end of file diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_msan.cfg b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_msan.cfg new file mode 100644 index 00000000000..24b19f23e62 --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_msan.cfg @@ -0,0 +1,30 @@ +# 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/pull_request/grpc_msan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_opt.cfg b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_opt.cfg new file mode 100644 index 00000000000..65395f0bf6f --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_opt.cfg @@ -0,0 +1,30 @@ +# 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/pull_request/grpc_bazel_on_foundry_opt.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} \ No newline at end of file diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_tsan.cfg b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_tsan.cfg new file mode 100644 index 00000000000..cf65606f3cd --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_tsan.cfg @@ -0,0 +1,30 @@ +# 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/pull_request/grpc_tsan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_ubsan.cfg b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_ubsan.cfg new file mode 100644 index 00000000000..a943b89509d --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_ubsan.cfg @@ -0,0 +1,30 @@ +# 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/pull_request/grpc_ubsan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/windows/grpc_bazel_rbe_dbg.cfg b/tools/internal_ci/windows/grpc_bazel_rbe_dbg.cfg new file mode 100644 index 00000000000..f958fed33dd --- /dev/null +++ b/tools/internal_ci/windows/grpc_bazel_rbe_dbg.cfg @@ -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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/windows/bazel_rbe.bat" + +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/rbe-windows-credentials.json" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} From 296f42c3e6d4190b2e1cddc933b302379bd1c248 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 23 Apr 2019 03:29:37 -0400 Subject: [PATCH 1924/2143] improve windows RBE build --- tools/internal_ci/windows/bazel_rbe.bat | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tools/internal_ci/windows/bazel_rbe.bat b/tools/internal_ci/windows/bazel_rbe.bat index e15bce48f0e..535125fcca9 100644 --- a/tools/internal_ci/windows/bazel_rbe.bat +++ b/tools/internal_ci/windows/bazel_rbe.bat @@ -12,7 +12,19 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. -choco install bazel -y --version 0.23.2 +@rem TODO(jtattermusch): make this generate less output +choco install bazel -y --version 0.23.2 --limit-output + cd github/grpc -set PATH=%PATH%;C:\python27\ -bazel --bazelrc=tools/remote_build/windows.bazelrc build :all --incompatible_disallow_filetype=false --google_credentials=%KOKORO_GFILE_DIR%/rbe-windows-credentials.json \ No newline at end of file +set PATH=C:\tools\msys64\usr\bin;C:\Python27;%PATH% + +@rem Generate a random UUID and store in "bazel_invocation_ids" artifact file +powershell -Command "[guid]::NewGuid().ToString()" >%KOKORO_ARTIFACTS_DIR%/bazel_invocation_ids +set /p BAZEL_INVOCATION_ID=<%KOKORO_ARTIFACTS_DIR%/bazel_invocation_ids + +bazel --bazelrc=tools/remote_build/windows.bazelrc build --invocation_id="%BAZEL_INVOCATION_ID%" --workspace_status_command=tools/remote_build/workspace_status_kokoro.sh :all --incompatible_disallow_filetype=false --google_credentials=%KOKORO_GFILE_DIR%/rbe-windows-credentials.json +set BAZEL_EXITCODE=%errorlevel% + +@rem TODO(jtattermusch): upload results to bigquery + +exit /b %BAZEL_EXITCODE% From 92a7d4b6152073437aaa98bc491c437525d254f1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 23 Apr 2019 06:55:43 -0400 Subject: [PATCH 1925/2143] standardize bazel rbe credentials --- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 7 +------ tools/remote_build/kokoro.bazelrc | 3 --- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index dd34eac7b38..93399f81e79 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -15,12 +15,6 @@ set -ex -# A temporary solution to give Kokoro credentials. -# The file name 4321_grpc-testing-service needs to match auth_credential in -# the build config. -mkdir -p ${KOKORO_KEYSTORE_DIR} -cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service - # Download bazel temp_dir="$(mktemp -d)" wget -q https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-linux-x86_64 -O "${temp_dir}/bazel" @@ -45,6 +39,7 @@ bazel \ test \ --invocation_id="${BAZEL_INVOCATION_ID}" \ --workspace_status_command=tools/remote_build/workspace_status_kokoro.sh \ + --google_credentials="${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json" \ $@ \ -- //test/... || FAILED="true" diff --git a/tools/remote_build/kokoro.bazelrc b/tools/remote_build/kokoro.bazelrc index 2fbdd3ce020..064e94b2e15 100644 --- a/tools/remote_build/kokoro.bazelrc +++ b/tools/remote_build/kokoro.bazelrc @@ -21,9 +21,6 @@ build --remote_executor=remotebuildexecution.googleapis.com build --tls_enabled=true build --auth_enabled=true -# magic location where kokoro script puts the credentials -build --auth_credentials=/tmpfs/src/keystore/4321_grpc-testing-service -build --auth_scope=https://www.googleapis.com/auth/cloud-source-tools build --bes_backend=buildeventservice.googleapis.com build --bes_timeout=600s From 284597c9cfa0cf489cb0ed40082ea79a88d178b6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 23 Apr 2019 07:09:10 -0400 Subject: [PATCH 1926/2143] standardize bazel rbe credentials 2 --- tools/internal_ci/windows/bazel_rbe.bat | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/internal_ci/windows/bazel_rbe.bat b/tools/internal_ci/windows/bazel_rbe.bat index 535125fcca9..8f2c534c5ef 100644 --- a/tools/internal_ci/windows/bazel_rbe.bat +++ b/tools/internal_ci/windows/bazel_rbe.bat @@ -22,6 +22,7 @@ set PATH=C:\tools\msys64\usr\bin;C:\Python27;%PATH% powershell -Command "[guid]::NewGuid().ToString()" >%KOKORO_ARTIFACTS_DIR%/bazel_invocation_ids set /p BAZEL_INVOCATION_ID=<%KOKORO_ARTIFACTS_DIR%/bazel_invocation_ids +@rem TODO(jtattermusch): windows RBE should be able to use the same credentials as Linux RBE. bazel --bazelrc=tools/remote_build/windows.bazelrc build --invocation_id="%BAZEL_INVOCATION_ID%" --workspace_status_command=tools/remote_build/workspace_status_kokoro.sh :all --incompatible_disallow_filetype=false --google_credentials=%KOKORO_GFILE_DIR%/rbe-windows-credentials.json set BAZEL_EXITCODE=%errorlevel% From 41824319fa53479a4e8e79050db4769edeca9a98 Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 23 Apr 2019 08:54:36 -0700 Subject: [PATCH 1927/2143] Resolve review comments --- .../grpcpp/impl/codegen/message_allocator.h | 2 ++ include/grpcpp/impl/codegen/server_callback.h | 33 ++++++++++++------ include/grpcpp/impl/codegen/service_type.h | 5 +++ src/compiler/cpp_generator.cc | 28 ++++++--------- src/cpp/server/server_cc.cc | 2 +- test/cpp/codegen/compiler_test_golden | 32 +++++++---------- .../end2end/message_allocator_end2end_test.cc | 34 ++++++++++++------- 7 files changed, 75 insertions(+), 61 deletions(-) diff --git a/include/grpcpp/impl/codegen/message_allocator.h b/include/grpcpp/impl/codegen/message_allocator.h index 28702a4500f..53ea05efe8e 100644 --- a/include/grpcpp/impl/codegen/message_allocator.h +++ b/include/grpcpp/impl/codegen/message_allocator.h @@ -20,6 +20,7 @@ #define GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H namespace grpc { +namespace experimental { // This is per rpc struct for the allocator. We can potentially put the grpc // call arena in here in the future. @@ -48,6 +49,7 @@ class MessageAllocator { RpcAllocatorInfo* info) = 0; }; +} // namespace experimental } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 359472bc392..5f7f396f08d 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -137,7 +137,12 @@ class ServerCallbackRpcController { virtual void SetCancelCallback(std::function callback) = 0; virtual void ClearCancelCallback() = 0; + // NOTE: This is an API for advanced users who need custom allocators. + // Optionally deallocate request early to reduce the size of working set. + // A custom MessageAllocator needs to be registered to make use of this. virtual void FreeRequest() = 0; + // NOTE: This is an API for advanced users who need custom allocators. + // Get and maybe mutate the allocator state associated with the current RPC. virtual void* GetAllocatorState() = 0; }; @@ -449,15 +454,19 @@ class CallbackUnaryHandler : public MethodHandler { CallbackUnaryHandler( std::function - func, - MessageAllocator* allocator) - : func_(func), allocator_(allocator) {} + func) + : func_(func) {} + + void SetMessageAllocator( + experimental::MessageAllocator* allocator) { + allocator_ = allocator; + } void RunHandler(const HandlerParameter& param) final { // Arena allocate a controller structure (that includes request/response) g_core_codegen_interface->grpc_call_ref(param.call->call()); auto* allocator_info = - static_cast*>( + static_cast*>( param.internal_data); auto* controller = new (g_core_codegen_interface->grpc_call_arena_alloc( param.call->call(), sizeof(ServerCallbackRpcControllerImpl))) @@ -480,10 +489,10 @@ class CallbackUnaryHandler : public MethodHandler { ByteBuffer buf; buf.set_buffer(req); RequestType* request = nullptr; - RpcAllocatorInfo* allocator_info = + experimental::RpcAllocatorInfo* allocator_info = new (g_core_codegen_interface->grpc_call_arena_alloc( call, sizeof(*allocator_info))) - RpcAllocatorInfo(); + experimental::RpcAllocatorInfo(); if (allocator_ != nullptr) { allocator_->AllocateMessages(allocator_info); } else { @@ -517,7 +526,8 @@ class CallbackUnaryHandler : public MethodHandler { std::function func_; - MessageAllocator* allocator_; + experimental::MessageAllocator* allocator_ = + nullptr; // The implementation class of ServerCallbackRpcController is a private member // of CallbackUnaryHandler since it is never exposed anywhere, and this allows @@ -593,8 +603,9 @@ class CallbackUnaryHandler : public MethodHandler { ServerCallbackRpcControllerImpl( ServerContext* ctx, Call* call, - RpcAllocatorInfo* allocator_info, - MessageAllocator* allocator, + experimental::RpcAllocatorInfo* + allocator_info, + experimental::MessageAllocator* allocator, std::function call_requester) : ctx_(ctx), call_(*call), @@ -636,8 +647,8 @@ class CallbackUnaryHandler : public MethodHandler { ServerContext* ctx_; Call call_; - RpcAllocatorInfo* allocator_info_; - MessageAllocator* allocator_; + experimental::RpcAllocatorInfo* allocator_info_; + experimental::MessageAllocator* allocator_; std::function call_requester_; std::atomic_int callbacks_outstanding_{ 2}; // reserve for Finish and CompletionOp diff --git a/include/grpcpp/impl/codegen/service_type.h b/include/grpcpp/impl/codegen/service_type.h index 332a04c294f..198bc7244b4 100644 --- a/include/grpcpp/impl/codegen/service_type.h +++ b/include/grpcpp/impl/codegen/service_type.h @@ -132,6 +132,11 @@ class Service { internal::RpcServiceMethod::ApiType::RAW_CALL_BACK); } + internal::MethodHandler* GetHandler(int index) { + size_t idx = static_cast(index); + return service_->methods_[idx]->handler(); + } + private: Service* service_; }; diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 86f4e3c5df9..da95ee7ffe2 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -155,8 +155,10 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, params.grpc_search_path); printer->Print(vars, "\n"); printer->Print(vars, "namespace grpc {\n"); + printer->Print(vars, "namespace experimental {\n"); printer->Print(vars, "template \n"); printer->Print(vars, "class MessageAllocator;\n"); + printer->Print(vars, "} // namespace experimental\n"); printer->Print(vars, "class CompletionQueue;\n"); printer->Print(vars, "class Channel;\n"); printer->Print(vars, "class ServerCompletionQueue;\n"); @@ -995,23 +997,15 @@ void PrintHeaderServerMethodCallback( "controller) {\n" " return this->$" "Method$(context, request, response, controller);\n" - " }, nullptr));\n}\n"); - printer->Print( - *vars, - "void SetMessageAllocatorFor_$Method$(\n" - " ::grpc::MessageAllocator<$RealRequest$, $RealResponse$>* " - "allocator) {\n" - " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" - " new ::grpc::internal::CallbackUnaryHandler< " - "$RealRequest$, $RealResponse$>(\n" - " [this](::grpc::ServerContext* context,\n" - " const $RealRequest$* request,\n" - " $RealResponse$* response,\n" - " ::grpc::experimental::ServerCallbackRpcController* " - "controller) {\n" - " return this->$" - "Method$(context, request, response, controller);\n" - " }, allocator));\n"); + " }));\n}\n"); + printer->Print(*vars, + "void SetMessageAllocatorFor_$Method$(\n" + " ::grpc::experimental::MessageAllocator< " + "$RealRequest$, $RealResponse$>* allocator) {\n" + " dynamic_cast<::grpc::internal::CallbackUnaryHandler< " + "$RealRequest$, $RealResponse$>*>(\n" + " ::grpc::Service::experimental().GetHandler($Idx$))\n" + " ->SetMessageAllocator(allocator);\n"); } else if (ClientOnlyStreaming(method)) { printer->Print( *vars, diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 836435c86a9..de85806c8c8 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -590,7 +590,7 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { const bool has_request_payload_; grpc_byte_buffer* request_payload_; void* request_; - void* handler_data_ = nullptr; + void* handler_data_; Status request_status_; grpc_call_details* call_details_ = nullptr; grpc_call* call_; diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 175ab821858..91335bf2c0c 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -41,8 +41,10 @@ #include namespace grpc { +namespace experimental { template class MessageAllocator; +} // namespace experimental class CompletionQueue; class Channel; class ServerCompletionQueue; @@ -332,18 +334,13 @@ class ServiceA final { ::grpc::testing::Response* response, ::grpc::experimental::ServerCallbackRpcController* controller) { return this->MethodA1(context, request, response, controller); - }, nullptr)); + })); } void SetMessageAllocatorFor_MethodA1( - ::grpc::MessageAllocator<::grpc::testing::Request, ::grpc::testing::Response>* allocator) { - ::grpc::Service::experimental().MarkMethodCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( - [this](::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response, - ::grpc::experimental::ServerCallbackRpcController* controller) { - return this->MethodA1(context, request, response, controller); - }, allocator)); + ::grpc::experimental::MessageAllocator< ::grpc::testing::Request, ::grpc::testing::Response>* allocator) { + dynamic_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( + ::grpc::Service::experimental().GetHandler(0)) + ->SetMessageAllocator(allocator); } ~ExperimentalWithCallbackMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); @@ -811,18 +808,13 @@ class ServiceB final { ::grpc::testing::Response* response, ::grpc::experimental::ServerCallbackRpcController* controller) { return this->MethodB1(context, request, response, controller); - }, nullptr)); + })); } void SetMessageAllocatorFor_MethodB1( - ::grpc::MessageAllocator<::grpc::testing::Request, ::grpc::testing::Response>* allocator) { - ::grpc::Service::experimental().MarkMethodCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( - [this](::grpc::ServerContext* context, - const ::grpc::testing::Request* request, - ::grpc::testing::Response* response, - ::grpc::experimental::ServerCallbackRpcController* controller) { - return this->MethodB1(context, request, response, controller); - }, allocator)); + ::grpc::experimental::MessageAllocator< ::grpc::testing::Request, ::grpc::testing::Response>* allocator) { + dynamic_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( + ::grpc::Service::experimental().GetHandler(0)) + ->SetMessageAllocator(allocator); } ~ExperimentalWithCallbackMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); diff --git a/test/cpp/end2end/message_allocator_end2end_test.cc b/test/cpp/end2end/message_allocator_end2end_test.cc index 995318ce8d9..55f792aa3bf 100644 --- a/test/cpp/end2end/message_allocator_end2end_test.cc +++ b/test/cpp/end2end/message_allocator_end2end_test.cc @@ -129,7 +129,8 @@ class MessageAllocatorEnd2endTestBase ~MessageAllocatorEnd2endTestBase() = default; - void CreateServer(MessageAllocator* allocator) { + void CreateServer( + experimental::MessageAllocator* allocator) { ServerBuilder builder; auto server_creds = GetCredentialsProvider()->GetServerCredentials( @@ -180,7 +181,7 @@ class MessageAllocatorEnd2endTestBase EchoResponse response; ClientContext cli_ctx; - test_string += "Hello world. "; + test_string += grpc::string(1024, 'x'); request.set_message(test_string); grpc::string val; cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); @@ -226,20 +227,24 @@ TEST_P(NullAllocatorTest, SimpleRpc) { class SimpleAllocatorTest : public MessageAllocatorEnd2endTestBase { public: - class SimpleAllocator : public MessageAllocator { + class SimpleAllocator + : public experimental::MessageAllocator { public: - void AllocateMessages(RpcAllocatorInfo* info) { + void AllocateMessages( + experimental::RpcAllocatorInfo* info) { allocation_count++; info->request = new EchoRequest; info->response = new EchoResponse; info->allocator_state = info; } - void DeallocateRequest(RpcAllocatorInfo* info) { + void DeallocateRequest( + experimental::RpcAllocatorInfo* info) { request_deallocation_count++; delete info->request; info->request = nullptr; } - void DeallocateMessages(RpcAllocatorInfo* info) { + void DeallocateMessages( + experimental::RpcAllocatorInfo* info) { messages_deallocation_count++; delete info->request; delete info->response; @@ -284,8 +289,9 @@ TEST_P(SimpleAllocatorTest, RpcWithReleaseRequest) { auto mutator = [&released_requests](void* allocator_state, const EchoRequest* req, EchoResponse* resp) { - auto* info = static_cast*>( - allocator_state); + auto* info = + static_cast*>( + allocator_state); EXPECT_EQ(req, info->request); EXPECT_EQ(resp, info->response); EXPECT_EQ(allocator_state, info->allocator_state); @@ -307,9 +313,11 @@ TEST_P(SimpleAllocatorTest, RpcWithReleaseRequest) { class ArenaAllocatorTest : public MessageAllocatorEnd2endTestBase { public: - class ArenaAllocator : public MessageAllocator { + class ArenaAllocator + : public experimental::MessageAllocator { public: - void AllocateMessages(RpcAllocatorInfo* info) { + void AllocateMessages( + experimental::RpcAllocatorInfo* info) { allocation_count++; auto* arena = new google::protobuf::Arena; info->allocator_state = arena; @@ -318,10 +326,12 @@ class ArenaAllocatorTest : public MessageAllocatorEnd2endTestBase { info->response = google::protobuf::Arena::CreateMessage(arena); } - void DeallocateRequest(RpcAllocatorInfo* info) { + void DeallocateRequest( + experimental::RpcAllocatorInfo* info) { GPR_ASSERT(0); } - void DeallocateMessages(RpcAllocatorInfo* info) { + void DeallocateMessages( + experimental::RpcAllocatorInfo* info) { deallocation_count++; auto* arena = static_cast(info->allocator_state); From 59e31bc30b27c5df160f3aa19ec5d839fdb35226 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Apr 2019 09:50:01 -0700 Subject: [PATCH 1928/2143] PR comments addressed --- src/objective-c/GRPCClient/GRPCCall.h | 4 ++++ src/objective-c/GRPCClient/GRPCCall.m | 12 ++++++------ src/objective-c/ProtoRPC/ProtoRPC.h | 5 +++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index decafd5c58e..8e02ada38d5 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -183,6 +183,10 @@ extern NSString *const kGRPCTrailersKey; - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; +/** + * Issued when flow control is enabled for the call and a message written with writeData: method of + * GRPCCall2 is passed to gRPC core with SEND_MESSAGE operation. + */ - (void)didWriteData; @end diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 0e8bb469f78..86cad30c704 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -680,14 +680,14 @@ const char *kCFStreamVarName = "grpc_cfstream"; __weak GRPCCall *weakSelf = self; [self startReadWithHandler:^(grpc_byte_buffer *message) { __strong GRPCCall *strongSelf = weakSelf; - if (strongSelf == nil) { - grpc_byte_buffer_destroy(message); - return; - } if (message == NULL) { // No more messages from the server return; } + if (strongSelf == nil) { + grpc_byte_buffer_destroy(message); + return; + } NSData *data = [NSData grpc_dataWithByteBuffer:message]; grpc_byte_buffer_destroy(message); if (!data) { @@ -696,7 +696,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // that's on the hands of any server to have. Instead we finish and ask // the server to cancel. @synchronized(strongSelf) { - strongSelf->_pendingReceiveNextMessages--; + strongSelf->_pendingCoreRead = NO; [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeResourceExhausted @@ -872,7 +872,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Response headers received. __strong GRPCCall *strongSelf = weakSelf; if (strongSelf) { - @synchronized(self) { + @synchronized(strongSelf) { strongSelf.responseHeaders = headers; strongSelf->_pendingCoreRead = NO; [strongSelf maybeStartNextRead]; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 68dec445c71..78d1bd3df37 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -58,8 +58,9 @@ NS_ASSUME_NONNULL_BEGIN error:(nullable NSError *)error; /** - * Issued when a write action is completed. To get a correct flow control behavior, the user of a - * call should not make more than one writeMessage: call before receiving this callback. + * Issued when flow control is enabled for the call and a message (written with writeMessage: method + * of GRPCStreamingProtoCall or the initializer of GRPCUnaryProtoCall) is passed to gRPC core with + * SEND_MESSAGE operation. */ - (void)didWriteMessage; From ac5e05cc2924ac485b0e97a73a3f40f626c8a825 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Apr 2019 09:54:29 -0700 Subject: [PATCH 1929/2143] Revert a change --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 634cd2a8511..eb20c364275 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -683,11 +683,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_async(_callQueue, ^{ __weak GRPCCall *weakSelf = self; [self startReadWithHandler:^(grpc_byte_buffer *message) { - __strong GRPCCall *strongSelf = weakSelf; if (message == NULL) { // No more messages from the server return; } + __strong GRPCCall *strongSelf = weakSelf; if (strongSelf == nil) { grpc_byte_buffer_destroy(message); return; From 89f0323744dcbc1f386c651c0ae8123c8053a651 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Tue, 16 Apr 2019 16:43:47 -0700 Subject: [PATCH 1930/2143] Added objective C stress tests --- src/objective-c/tests/InteropTests.m | 84 +++++++ src/objective-c/tests/MacTests/StressTests.h | 56 +++++ src/objective-c/tests/MacTests/StressTests.m | 237 ++++++++++++++++++ .../tests/MacTests/StressTestsCleartext.m | 68 +++++ .../tests/MacTests/StressTestsSSL.m | 71 ++++++ src/objective-c/tests/Podfile | 2 +- .../tests/Tests.xcodeproj/project.pbxproj | 14 ++ .../xcshareddata/xcschemes/MacTests.xcscheme | 3 + 8 files changed, 534 insertions(+), 1 deletion(-) create mode 100644 src/objective-c/tests/MacTests/StressTests.h create mode 100644 src/objective-c/tests/MacTests/StressTests.m create mode 100644 src/objective-c/tests/MacTests/StressTestsCleartext.m create mode 100644 src/objective-c/tests/MacTests/StressTestsSSL.m diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index d5429bf302d..0d2c409f6f3 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -341,6 +341,90 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testConcurrentRPCsWithErrorsWithV2API { + NSMutableArray *completeExpectations = [NSMutableArray array]; + NSMutableArray *calls = [NSMutableArray array]; + int num_rpcs = 10; + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = 314159; + request.payload.body = [NSMutableData dataWithLength:271828]; + if (i % 3 == 0) { + request.responseStatus.code = GRPC_STATUS_UNAVAILABLE; + } else if (i % 7 == 0) { + request.responseStatus.code = GRPC_STATUS_CANCELLED; + } + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + + GRPCUnaryProtoCall *call = [_service + unaryCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + if (message) { + RMTSimpleResponse *expectedResponse = + [RMTSimpleResponse message]; + expectedResponse.payload.type = RMTPayloadType_Compressable; + expectedResponse.payload.body = + [NSMutableData dataWithLength:314159]; + XCTAssertEqualObjects(message, expectedResponse); + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + [completeExpectations[i] fulfill]; + }] + callOptions:options]; + [calls addObject:call]; + } + + for (int i = 0; i < num_rpcs; ++i) { + GRPCUnaryProtoCall *call = calls[i]; + [call start]; + } + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testConcurrentRPCsWithErrors { + NSMutableArray *completeExpectations = [NSMutableArray array]; + int num_rpcs = 10; + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = 314159; + request.payload.body = [NSMutableData dataWithLength:271828]; + if (i % 3 == 0) { + request.responseStatus.code = GRPC_STATUS_UNAVAILABLE; + } else if (i % 7 == 0) { + request.responseStatus.code = GRPC_STATUS_CANCELLED; + } + + [_service unaryCallWithRequest:request + handler:^(RMTSimpleResponse *response, NSError *error) { + if (error == nil) { + RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message]; + expectedResponse.payload.type = RMTPayloadType_Compressable; + expectedResponse.payload.body = + [NSMutableData dataWithLength:314159]; + XCTAssertEqualObjects(response, expectedResponse); + } + [completeExpectations[i] fulfill]; + }]; + } + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testPacketCoalescing { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; diff --git a/src/objective-c/tests/MacTests/StressTests.h b/src/objective-c/tests/MacTests/StressTests.h new file mode 100644 index 00000000000..8bee0e66274 --- /dev/null +++ b/src/objective-c/tests/MacTests/StressTests.h @@ -0,0 +1,56 @@ +/* + * + * 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 + +@interface StressTests : XCTestCase +/** + * Host to send the RPCs to. The base implementation returns nil, which would make all tests to + * fail. + * Override in a subclass to perform these tests against a specific address. + */ ++ (NSString *)host; + +/** + * Bytes of overhead of test proto responses due to encoding. This is used to excercise the behavior + * when responses are just above or below the max response size. For some reason, the local and + * remote servers enconde responses with different overhead (?), so this is defined per-subclass. + */ +- (int32_t)encodingOverhead; + +/** + * The type of transport to be used. The base implementation returns default. Subclasses should + * override to appropriate settings. + */ ++ (GRPCTransportType)transportType; + +/** + * The root certificates to be used. The base implementation returns nil. Subclasses should override + * to appropriate settings. + */ ++ (NSString *)PEMRootCertificates; + +/** + * The root certificates to be used. The base implementation returns nil. Subclasses should override + * to appropriate settings. + */ ++ (NSString *)hostNameOverride; + +@end diff --git a/src/objective-c/tests/MacTests/StressTests.m b/src/objective-c/tests/MacTests/StressTests.m new file mode 100644 index 00000000000..22174b58665 --- /dev/null +++ b/src/objective-c/tests/MacTests/StressTests.m @@ -0,0 +1,237 @@ +/* + * + * 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 "StressTests.h" + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#define TEST_TIMEOUT 32 + +extern const char *kCFStreamVarName; + +// Convenience class to use blocks as callbacks +@interface MacTestsBlockCallbacks : NSObject + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; + +@end + +@implementation MacTestsBlockCallbacks { + void (^_initialMetadataCallback)(NSDictionary *); + void (^_messageCallback)(id); + void (^_closeCallback)(NSDictionary *, NSError *); + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + if ((self = [super init])) { + _initialMetadataCallback = initialMetadataCallback; + _messageCallback = messageCallback; + _closeCallback = closeCallback; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + if (_messageCallback) { + _messageCallback(message); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + +@implementation StressTests { + RMTTestService *_service; +} + ++ (NSString *)host { + return nil; +} + ++ (NSString *)hostAddress { + return nil; +} + ++ (NSString *)PEMRootCertificates { + return nil; +} + ++ (NSString *)hostNameOverride { + return nil; +} + +- (int32_t)encodingOverhead { + return 0; +} + ++ (void)setUp { + setenv(kCFStreamVarName, "1", 1); +} + +- (void)setUp { + self.continueAfterFailure = NO; + + [GRPCCall resetHostSettings]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + _service = [RMTTestService serviceWithHost:[[self class] host] callOptions:options]; + system([[NSString stringWithFormat:@"sudo ifconfig lo0 alias %@", [[self class] hostAddress]] + UTF8String]); +} + +- (void)tearDown { + system([[NSString stringWithFormat:@"sudo ifconfig lo0 -alias %@", [[self class] hostAddress]] + UTF8String]); +} + ++ (GRPCTransportType)transportType { + return GRPCTransportTypeChttp2BoringSSL; +} + +- (void)testNetworkFlapWithV2API { + NSMutableArray *completeExpectations = [NSMutableArray array]; + NSMutableArray *calls = [NSMutableArray array]; + int num_rpcs = 100; + __block BOOL address_removed = FALSE; + __block BOOL address_readded = FALSE; + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = 314159; + request.payload.body = [NSMutableData dataWithLength:271828]; + + GRPCUnaryProtoCall *call = [_service + unaryCallWithMessage:request + responseHandler:[[MacTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + if (message) { + RMTSimpleResponse *expectedResponse = + [RMTSimpleResponse message]; + expectedResponse.payload.type = RMTPayloadType_Compressable; + expectedResponse.payload.body = + [NSMutableData dataWithLength:314159]; + XCTAssertEqualObjects(message, expectedResponse); + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + + @synchronized(self) { + if (error == nil && !address_removed) { + system([[NSString + stringWithFormat:@"sudo ifconfig lo0 -alias %@", + [[self class] hostAddress]] + UTF8String]); + address_removed = YES; + } else if (error != nil && !address_readded) { + system([ + [NSString stringWithFormat:@"sudo ifconfig lo0 alias %@", + [[self class] hostAddress]] + UTF8String]); + address_readded = YES; + } + } + [completeExpectations[i] fulfill]; + }] + callOptions:nil]; + [calls addObject:call]; + } + + for (int i = 0; i < num_rpcs; ++i) { + GRPCUnaryProtoCall *call = calls[i]; + [call start]; + [NSThread sleepForTimeInterval:0.1f]; + } + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testNetworkFlapWithV1API { + NSMutableArray *completeExpectations = [NSMutableArray array]; + int num_rpcs = 100; + __block BOOL address_removed = FALSE; + __block BOOL address_readded = FALSE; + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received response for RPC %d", i]]]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = 314159; + request.payload.body = [NSMutableData dataWithLength:271828]; + + [_service unaryCallWithRequest:request + handler:^(RMTSimpleResponse *response, NSError *error) { + @synchronized(self) { + if (error == nil && !address_removed) { + system([[NSString stringWithFormat:@"sudo ifconfig lo0 -alias %@", + [[self class] hostAddress]] + UTF8String]); + address_removed = YES; + } else if (error != nil && !address_readded) { + system([[NSString stringWithFormat:@"sudo ifconfig lo0 alias %@", + [[self class] hostAddress]] + UTF8String]); + address_readded = YES; + } + } + + [completeExpectations[i] fulfill]; + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; + } +} + +@end diff --git a/src/objective-c/tests/MacTests/StressTestsCleartext.m b/src/objective-c/tests/MacTests/StressTestsCleartext.m new file mode 100644 index 00000000000..2b3a8614705 --- /dev/null +++ b/src/objective-c/tests/MacTests/StressTestsCleartext.m @@ -0,0 +1,68 @@ + +/* + * + * 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 "StressTests.h" + +static NSString *const kHostAddress = @"10.0.0.1"; + +// The Protocol Buffers encoding overhead of local interop server. Acquired +// by experiment. Adjust this when server's proto file changes. +static int32_t kLocalInteropServerOverhead = 10; + +/** Tests in InteropTests.m, sending the RPCs to a local cleartext server. */ +@interface StressTestsCleartext : StressTests +@end + +@implementation StressTestsCleartext + ++ (NSString *)host { + return [NSString stringWithFormat:@"%@:5050", kHostAddress]; +} + ++ (NSString *)hostAddress { + return kHostAddress; +} + ++ (NSString *)PEMRootCertificates { + return nil; +} + ++ (NSString *)hostNameOverride { + return nil; +} + +- (int32_t)encodingOverhead { + return kLocalInteropServerOverhead; // bytes +} + +- (void)setUp { + [super setUp]; + + // Register test server as non-SSL. + [GRPCCall useInsecureConnectionsForHost:[[self class] host]]; +} + ++ (GRPCTransportType)transportType { + return GRPCTransportTypeInsecure; +} + +@end diff --git a/src/objective-c/tests/MacTests/StressTestsSSL.m b/src/objective-c/tests/MacTests/StressTestsSSL.m new file mode 100644 index 00000000000..c5d79fe0ae8 --- /dev/null +++ b/src/objective-c/tests/MacTests/StressTestsSSL.m @@ -0,0 +1,71 @@ +/* + * + * 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 + +#include "StressTests.h" + +static NSString *const kHostAddress = @"10.0.0.1"; +// The Protocol Buffers encoding overhead of local interop server. Acquired +// by experiment. Adjust this when server's proto file changes. +static int32_t kLocalInteropServerOverhead = 10; + +@interface StressTestsSSL : StressTests +@end + +@implementation StressTestsSSL + ++ (NSString *)host { + return [NSString stringWithFormat:@"%@:5051", kHostAddress]; +} + ++ (NSString *)hostAddress { + return kHostAddress; +} + ++ (NSString *)PEMRootCertificates { + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSString *certsPath = + [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; + NSError *error; + return [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error]; +} + ++ (NSString *)hostNameOverride { + return @"foo.test.google.fr"; +} + +- (int32_t)encodingOverhead { + return kLocalInteropServerOverhead; // bytes +} + ++ (GRPCTransportType)transportType { + return GRPCTransportTypeChttp2BoringSSL; +} + +- (void)setUp { + [super setUp]; + + // Register test server certificates and name. + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSString *certsPath = + [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; + [GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:[[self class] host]]; +} +@end diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 4906e5b45a4..34ed6680195 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -127,7 +127,7 @@ post_install do |installer| # 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' + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1 GRPC_CFSTREAM=1' end end diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index d4f93b516fa..27a617c83b4 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -68,6 +68,7 @@ 91D4B3C85B6D8562F409CB48 /* libPods-InteropTestsLocalSSLCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */; }; 953CD2942A3A6D6CE695BE87 /* libPods-MacTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 276873A05AC5479B60DF6079 /* libPods-MacTests.a */; }; 98478C9F42329DF769A45B6C /* libPods-APIv2Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */; }; + B071230B22669EED004B64A1 /* StressTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B071230A22669EED004B64A1 /* StressTests.m */; }; B0BB3F02225E7A3C008DA580 /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; }; B0BB3F03225E7A44008DA580 /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; }; B0BB3F04225E7A8D008DA580 /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; }; @@ -77,6 +78,8 @@ B0BB3F08225E7ABA008DA580 /* UnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* UnitTests.m */; }; B0BB3F0A225EA511008DA580 /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; B0BB3F0B225EB110008DA580 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; + B0D39B9A2266F3CB00A4078D /* StressTestsSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D39B992266F3CB00A4078D /* StressTestsSSL.m */; }; + B0D39B9C2266FF9800A4078D /* StressTestsCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D39B9B2266FF9800A4078D /* StressTestsCleartext.m */; }; BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */; }; C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */; }; CCF5C0719EF608276AE16374 /* libPods-UnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */; }; @@ -288,8 +291,12 @@ AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.cronet.xcconfig"; sourceTree = ""; }; AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.release.xcconfig"; sourceTree = ""; }; AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsCallOptions.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + B071230A22669EED004B64A1 /* StressTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StressTests.m; sourceTree = ""; }; B0BB3EF7225E795F008DA580 /* MacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MacTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; B0BB3EFB225E795F008DA580 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B0C5FC172267C77200F192BE /* StressTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StressTests.h; sourceTree = ""; }; + B0D39B992266F3CB00A4078D /* StressTestsSSL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StressTestsSSL.m; sourceTree = ""; }; + B0D39B9B2266FF9800A4078D /* StressTestsCleartext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StressTestsCleartext.m; sourceTree = ""; }; B226619DC4E709E0FFFF94B8 /* Pods-CronetUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.test.xcconfig"; sourceTree = ""; }; B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-APIv2Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.debug.xcconfig"; sourceTree = ""; }; @@ -728,6 +735,10 @@ isa = PBXGroup; children = ( B0BB3EFB225E795F008DA580 /* Info.plist */, + B071230A22669EED004B64A1 /* StressTests.m */, + B0D39B992266F3CB00A4078D /* StressTestsSSL.m */, + B0D39B9B2266FF9800A4078D /* StressTestsCleartext.m */, + B0C5FC172267C77200F192BE /* StressTests.h */, ); path = MacTests; sourceTree = ""; @@ -2149,9 +2160,12 @@ files = ( B0BB3F07225E7AB5008DA580 /* APIv2Tests.m in Sources */, B0BB3F08225E7ABA008DA580 /* UnitTests.m in Sources */, + B071230B22669EED004B64A1 /* StressTests.m in Sources */, B0BB3F05225E7A9F008DA580 /* InteropTestsRemote.m in Sources */, + B0D39B9A2266F3CB00A4078D /* StressTestsSSL.m in Sources */, B0BB3F03225E7A44008DA580 /* InteropTestsLocalCleartext.m in Sources */, B0BB3F04225E7A8D008DA580 /* RxLibraryUnitTests.m in Sources */, + B0D39B9C2266FF9800A4078D /* StressTestsCleartext.m in Sources */, B0BB3F0B225EB110008DA580 /* InteropTests.m in Sources */, B0BB3F02225E7A3C008DA580 /* InteropTestsLocalSSL.m in Sources */, B0BB3F06225E7AAD008DA580 /* GRPCClientTests.m in Sources */, diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/MacTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/MacTests.xcscheme index 7c3763206bd..f84ac7fc741 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/MacTests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/MacTests.xcscheme @@ -41,6 +41,9 @@ + + From 9f2258c2b6a92629ced1a768f57b3cf9e995e592 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Wed, 10 Apr 2019 11:58:03 -0700 Subject: [PATCH 1931/2143] Fix some iOS UI test flakes --- .../GrpcIosTestUITests/GrpcIosTestUITests.m | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/objective-c/manual_tests/GrpcIosTestUITests/GrpcIosTestUITests.m b/src/objective-c/manual_tests/GrpcIosTestUITests/GrpcIosTestUITests.m index b5e19657ce7..a75b6322148 100644 --- a/src/objective-c/manual_tests/GrpcIosTestUITests/GrpcIosTestUITests.m +++ b/src/objective-c/manual_tests/GrpcIosTestUITests/GrpcIosTestUITests.m @@ -90,6 +90,15 @@ int const kNumIterations = 1; XCTAssert([testApp.staticTexts[@"Call failed"] waitForExistenceWithTimeout:kWaitTime]); } +- (void)expectCallSuccessOrFailed { + NSDate *startTime = [NSDate date]; + while (![testApp.staticTexts[@"Call done"] exists] && + ![testApp.staticTexts[@"Call failed"] exists]) { + XCTAssertLessThan([[NSDate date] timeIntervalSinceDate:startTime], kWaitTime); + [NSThread sleepForTimeInterval:1]; + } +} + - (void)setAirplaneMode:(BOOL)to { [settingsApp activate]; XCUIElement *mySwitch = settingsApp.tables.element.cells.switches[@"Airplane Mode"]; @@ -118,13 +127,6 @@ int const kNumIterations = 1; [backButton tap]; } -- (void)typeText:(NSString *)text inApp:(XCUIApplication *)app { - [app typeText:text]; - // Wait until all events in run loop have been processed - while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, true) == kCFRunLoopRunHandledSource) - ; -} - - (int)getRandomNumberBetween:(int)min max:(int)max { return min + arc4random_uniform((max - min + 1)); } @@ -216,24 +218,17 @@ int const kNumIterations = 1; // Send test app to background [XCUIDevice.sharedDevice pressButton:XCUIDeviceButtonHome]; - // Open safari and goto a URL - XCUIApplication *safari = - [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.mobilesafari"]; - [safari activate]; - // Ensure that safari is running in the foreground - XCTAssert([safari waitForState:XCUIApplicationStateRunningForeground timeout:5]); - // Move cursor to address bar - [safari.buttons[@"URL"] tap]; - // Wait for keyboard to appear - [NSThread sleepForTimeInterval:2]; - // Enter URL - [self typeText:@"http://maps.google.com" inApp:safari]; - // Presses return key - [self typeText:@"\n" inApp:safari]; + // Open stocks app + XCUIApplication *stocksApp = + [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.stocks"]; + [stocksApp activate]; + // Ensure that stocks app is running in the foreground + XCTAssert([stocksApp waitForState:XCUIApplicationStateRunningForeground timeout:5]); // Wait a bit int sleepTime = [self getRandomNumberBetween:5 max:10]; NSLog(@"Sleeping for %d seconds", sleepTime); [NSThread sleepForTimeInterval:sleepTime]; + [stocksApp terminate]; // Make another unary call [self doUnaryCall]; @@ -256,8 +251,13 @@ int const kNumIterations = 1; [self setWifi:YES]; [testApp activate]; - // We expect the call to have failed because the network flapped - [self expectCallFailed]; + [self pressButton:@"Stop streaming call"]; + // The call will fail if the stream gets a read error, else the call will succeed. + [self expectCallSuccessOrFailed]; + + // Make another unary call, it should succeed + [self doUnaryCall]; + [self expectCallSuccess]; } - (void)testConcurrentCalls { From 858b5cca20785f71139281599e523d7ed976efef Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 23 Apr 2019 11:45:11 -0700 Subject: [PATCH 1932/2143] Fix clang_format_code.sh issues and move the internal calls to new name --- include/grpcpp/create_channel.h | 4 ++-- include/grpcpp/create_channel_impl.h | 4 ++-- include/grpcpp/security/credentials.h | 6 +++--- src/cpp/client/create_channel.cc | 8 ++++---- src/cpp/client/insecure_credentials.cc | 2 +- src/cpp/client/secure_credentials.cc | 2 +- src/cpp/client/secure_credentials.h | 2 +- test/cpp/client/client_channel_stress_test.cc | 4 ++-- test/cpp/end2end/async_end2end_test.cc | 12 ++++++------ test/cpp/end2end/client_callback_end2end_test.cc | 7 ++++--- test/cpp/end2end/end2end_test.cc | 4 ++-- test/cpp/microbenchmarks/fullstack_fixtures.h | 4 ++-- test/cpp/util/create_test_channel.cc | 6 ++++-- 13 files changed, 34 insertions(+), 31 deletions(-) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index 6d444be9803..d9d7d432c3f 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -26,14 +26,14 @@ namespace grpc { static inline std::shared_ptr CreateChannel( const grpc::string& target, const std::shared_ptr& creds) { - return ::grpc_impl::CreateChannel(target, creds); + return ::grpc_impl::CreateChannelImpl(target, creds); } static inline std::shared_ptr CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args) { - return ::grpc_impl::CreateCustomChannel(target, creds, args); + return ::grpc_impl::CreateCustomChannelImpl(target, creds, args); } namespace experimental { diff --git a/include/grpcpp/create_channel_impl.h b/include/grpcpp/create_channel_impl.h index 214a537a3cb..84dd2f7c765 100644 --- a/include/grpcpp/create_channel_impl.h +++ b/include/grpcpp/create_channel_impl.h @@ -35,7 +35,7 @@ namespace grpc_impl { /// \param creds Credentials to use for the created channel. If it does not /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. -std::shared_ptr CreateChannel( +std::shared_ptr CreateChannelImpl( const grpc::string& target, const std::shared_ptr& creds); @@ -49,7 +49,7 @@ std::shared_ptr CreateChannel( /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannel( +std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 8662b068a59..03f1f217c18 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -38,7 +38,7 @@ class CallCredentials; class ChannelCredentials; } // namespace grpc namespace grpc_impl { -std::shared_ptr CreateCustomChannel( +std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); @@ -77,7 +77,7 @@ class ChannelCredentials : private GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr grpc_impl::CreateCustomChannel( + friend std::shared_ptr grpc_impl::CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); @@ -91,7 +91,7 @@ class ChannelCredentials : private GrpcLibraryCodegen { grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators); - virtual std::shared_ptr CreateChannel( + virtual std::shared_ptr CreateChannelImpl( const grpc::string& target, const ChannelArguments& args) = 0; // This function should have been a pure virtual function, but it is diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index c5417de35ea..c366693eced 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -26,19 +26,19 @@ #include "src/cpp/client/create_channel_internal.h" namespace grpc_impl { -std::shared_ptr CreateChannel( +std::shared_ptr CreateChannelImpl( const grpc::string& target, const std::shared_ptr& creds) { - return CreateCustomChannel(target, creds, grpc::ChannelArguments()); + return CreateCustomChannelImpl(target, creds, grpc::ChannelArguments()); } -std::shared_ptr CreateCustomChannel( +std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args) { grpc::GrpcLibraryCodegen init_lib; // We need to call init in case of a bad creds. - return creds ? creds->CreateChannel(target, args) + return creds ? creds->CreateChannelImpl(target, args) : grpc::CreateChannelInternal( "", grpc_lame_client_channel_create( diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 241ce918034..1b0fa6faea9 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -30,7 +30,7 @@ namespace grpc { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: - std::shared_ptr CreateChannel( + std::shared_ptr CreateChannelImpl( const string& target, const grpc::ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 4d0ed355aba..f490f6e6f9a 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -34,7 +34,7 @@ SecureChannelCredentials::SecureChannelCredentials( g_gli_initializer.summon(); } -std::shared_ptr SecureChannelCredentials::CreateChannel( +std::shared_ptr SecureChannelCredentials::CreateChannelImpl( const string& target, const grpc::ChannelArguments& args) { return CreateChannelWithInterceptors( target, args, diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 4918bd5a4d7..fa2f64ed1d8 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -37,7 +37,7 @@ class SecureChannelCredentials final : public ChannelCredentials { } grpc_channel_credentials* GetRawCreds() { return c_creds_; } - std::shared_ptr CreateChannel( + std::shared_ptr CreateChannelImpl( const string& target, const grpc::ChannelArguments& args) override; SecureChannelCredentials* AsSecureCredentials() override { return this; } diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index fe9aed1766e..7b4d47276ef 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -268,8 +268,8 @@ class ClientChannelStressTest { response_generator_.get()); std::ostringstream uri; uri << "fake:///servername_not_used"; - channel_ = - ::grpc::CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args); + channel_ = ::grpc::CreateCustomChannel(uri.str(), + InsecureChannelCredentials(), args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index f8e65ecff41..b16da4c9345 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -294,9 +294,9 @@ class AsyncEnd2endTest : public ::testing::TestWithParam { auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( GetParam().credentials_type, &args); std::shared_ptr channel = - !(GetParam().inproc) - ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args) - : server_->InProcessChannel(args); + !(GetParam().inproc) ? ::grpc::CreateCustomChannel( + server_address_.str(), channel_creds, args) + : server_->InProcessChannel(args); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -1255,9 +1255,9 @@ TEST_P(AsyncEnd2endTest, UnimplementedRpc) { const auto& channel_creds = GetCredentialsProvider()->GetChannelCredentials( GetParam().credentials_type, &args); std::shared_ptr channel = - !(GetParam().inproc) - ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args) - : server_->InProcessChannel(args); + !(GetParam().inproc) ? ::grpc::CreateCustomChannel(server_address_.str(), + channel_creds, args) + : server_->InProcessChannel(args); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); EchoRequest send_request; diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index fa116b5519e..4e11fc71ca3 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -142,8 +142,8 @@ class ClientCallbackEnd2endTest switch (GetParam().protocol) { case Protocol::TCP: if (!GetParam().use_interceptors) { - channel_ = - ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args); + channel_ = ::grpc::CreateCustomChannel(server_address_.str(), + channel_creds, args); } else { channel_ = CreateCustomChannelWithInterceptors( server_address_.str(), channel_creds, args, @@ -1153,7 +1153,8 @@ TEST_P(ClientCallbackEnd2endTest, UnimplementedRpc) { GetParam().credentials_type, &args); std::shared_ptr channel = (GetParam().protocol == Protocol::TCP) - ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args) + ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, + args) : server_->InProcessChannel(args); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index d3f5c3e9187..47231058d17 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -340,8 +340,8 @@ class End2endTest : public ::testing::TestWithParam { if (!GetParam().inproc) { if (!GetParam().use_interceptors) { - channel_ = - ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args); + channel_ = ::grpc::CreateCustomChannel(server_address_.str(), + channel_creds, args); } else { channel_ = CreateCustomChannelWithInterceptors( server_address_.str(), channel_creds, args, diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index ed231752438..80ccab3e6ef 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -86,8 +86,8 @@ class FullstackFixture : public BaseFixture { ChannelArguments args; config.ApplyCommonChannelArguments(&args); if (address.length() > 0) { - channel_ = - ::grpc::CreateCustomChannel(address, InsecureChannelCredentials(), args); + channel_ = ::grpc::CreateCustomChannel( + address, InsecureChannelCredentials(), args); } else { channel_ = server_->InProcessChannel(args); } diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc index d036e785360..c0b999b511c 100644 --- a/test/cpp/util/create_test_channel.cc +++ b/test/cpp/util/create_test_channel.cc @@ -132,7 +132,8 @@ std::shared_ptr CreateTestChannel( std::shared_ptr channel_creds; if (cred_type.empty()) { if (interceptor_creators.empty()) { - return ::grpc::CreateCustomChannel(server, InsecureChannelCredentials(), args); + return ::grpc::CreateCustomChannel(server, InsecureChannelCredentials(), + args); } else { return experimental::CreateCustomChannelWithInterceptors( server, InsecureChannelCredentials(), args, @@ -159,7 +160,8 @@ std::shared_ptr CreateTestChannel( channel_creds = CompositeChannelCredentials(channel_creds, creds); } if (interceptor_creators.empty()) { - return ::grpc::CreateCustomChannel(connect_to, channel_creds, channel_args); + return ::grpc::CreateCustomChannel(connect_to, channel_creds, + channel_args); } else { return experimental::CreateCustomChannelWithInterceptors( connect_to, channel_creds, channel_args, From edd817a46fe0f6a257ecdc28745494ce9668de68 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 23 Apr 2019 12:10:08 -0700 Subject: [PATCH 1933/2143] Reviewer comments --- BUILD | 2 - BUILD.gn | 2 - CMakeLists.txt | 6 -- Makefile | 6 -- build.yaml | 2 - config.m4 | 1 - config.w32 | 1 - gRPC-C++.podspec | 1 - gRPC-Core.podspec | 3 - grpc.gemspec | 2 - grpc.gyp | 4 - package.xml | 2 - .../filters/client_channel/client_channel.cc | 35 ++++---- .../client_channel/client_channel_plugin.cc | 1 - .../client_channel/resolver_result_parsing.cc | 9 +- .../client_channel/resolver_result_parsing.h | 2 +- .../filters/client_channel/service_config.h | 27 ++++++ .../ext/filters/client_channel/subchannel.cc | 1 + .../message_size/message_size_filter.cc | 80 ++++++++++++++++-- .../message_size/message_size_filter.h | 32 +++++++ .../message_size/message_size_parser.cc | 84 ------------------- .../message_size/message_size_parser.h | 55 ------------ src/core/lib/channel/context.h | 5 +- src/core/lib/iomgr/error.h | 1 - src/python/grpcio/grpc_core_dependencies.py | 1 - tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 7 +- 27 files changed, 153 insertions(+), 221 deletions(-) delete mode 100644 src/core/ext/filters/message_size/message_size_parser.cc delete mode 100644 src/core/ext/filters/message_size/message_size_parser.h diff --git a/BUILD b/BUILD index 07db0019138..7f99bcdfaca 100644 --- a/BUILD +++ b/BUILD @@ -1099,7 +1099,6 @@ grpc_cc_library( "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/message_size/message_size_parser.cc", ], hdrs = [ "src/core/ext/filters/client_channel/backup_poller.h", @@ -1129,7 +1128,6 @@ grpc_cc_library( "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/message_size/message_size_parser.h", ], language = "c++", deps = [ diff --git a/BUILD.gn b/BUILD.gn index d75dce49080..e83def5507d 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -354,8 +354,6 @@ config("grpc_config") { "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/message_size/message_size_parser.cc", - "src/core/ext/filters/message_size/message_size_parser.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", diff --git a/CMakeLists.txt b/CMakeLists.txt index 56ccbffd0c1..b221b4e7cd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1252,7 +1252,6 @@ add_library(grpc 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/message_size/message_size_parser.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 @@ -1609,7 +1608,6 @@ add_library(grpc_cronet 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/message_size/message_size_parser.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 @@ -1991,7 +1989,6 @@ add_library(grpc_test_util 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/message_size/message_size_parser.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 @@ -2318,7 +2315,6 @@ add_library(grpc_test_util_unsecure 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/message_size/message_size_parser.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 @@ -2656,7 +2652,6 @@ add_library(grpc_unsecure 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/message_size/message_size_parser.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 @@ -3528,7 +3523,6 @@ add_library(grpc++_cronet 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/message_size/message_size_parser.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 1b371a8431f..4f9acb9fc1f 100644 --- a/Makefile +++ b/Makefile @@ -3708,7 +3708,6 @@ LIBGRPC_SRC = \ 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/message_size/message_size_parser.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 \ @@ -4059,7 +4058,6 @@ LIBGRPC_CRONET_SRC = \ 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/message_size/message_size_parser.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 \ @@ -4434,7 +4432,6 @@ LIBGRPC_TEST_UTIL_SRC = \ 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/message_size/message_size_parser.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 \ @@ -4748,7 +4745,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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/message_size/message_size_parser.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 \ @@ -5060,7 +5056,6 @@ LIBGRPC_UNSECURE_SRC = \ 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/message_size/message_size_parser.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 \ @@ -5908,7 +5903,6 @@ LIBGRPC++_CRONET_SRC = \ 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/message_size/message_size_parser.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 936cd911b31..a180c8c1d28 100644 --- a/build.yaml +++ b/build.yaml @@ -596,7 +596,6 @@ filegroups: - 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/message_size/message_size_parser.h src: - src/core/ext/filters/client_channel/backup_poller.cc - src/core/ext/filters/client_channel/channel_connectivity.cc @@ -625,7 +624,6 @@ filegroups: - 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/message_size/message_size_parser.cc plugin: grpc_client_channel uses: - grpc_base diff --git a/config.m4 b/config.m4 index 0710e1e8341..e7d3a5daf4e 100644 --- a/config.m4 +++ b/config.m4 @@ -366,7 +366,6 @@ if test "$PHP_GRPC" != "no"; then 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/message_size/message_size_parser.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 e69f71dbfb3..8a6529faae2 100644 --- a/config.w32 +++ b/config.w32 @@ -341,7 +341,6 @@ if (PHP_GRPC != "no") { "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\\message_size\\message_size_parser.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 d4f4b626011..782d86a6fcb 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -385,7 +385,6 @@ Pod::Spec.new do |s| '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/message_size/message_size_parser.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 aa38487e194..13c2a2cf9d0 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -367,7 +367,6 @@ Pod::Spec.new do |s| '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/message_size/message_size_parser.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', @@ -816,7 +815,6 @@ Pod::Spec.new do |s| '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/message_size/message_size_parser.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', @@ -1013,7 +1011,6 @@ Pod::Spec.new do |s| '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/message_size/message_size_parser.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 9749cc69e47..bca4674c761 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -301,7 +301,6 @@ Gem::Specification.new do |s| 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/message_size/message_size_parser.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 ) @@ -753,7 +752,6 @@ Gem::Specification.new do |s| 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/message_size/message_size_parser.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 874cc5a52bf..d4db059dc0a 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -548,7 +548,6 @@ '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/message_size/message_size_parser.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', @@ -814,7 +813,6 @@ '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/message_size/message_size_parser.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', @@ -1061,7 +1059,6 @@ '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/message_size/message_size_parser.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', @@ -1319,7 +1316,6 @@ '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/message_size/message_size_parser.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/package.xml b/package.xml index 66bf5ee8863..3af95c9a727 100644 --- a/package.xml +++ b/package.xml @@ -306,7 +306,6 @@ - @@ -758,7 +757,6 @@ - diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index ffb2b9a904b..99ffeeaa522 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -618,7 +618,7 @@ class CallData { grpc_call_context_element* call_context_; RefCountedPtr retry_throttle_data_; - RefCountedPtr service_config_; + ServiceConfig::CallData service_config_call_data_; const ClientChannelMethodParsedObject* method_params_ = nullptr; RefCountedPtr subchannel_call_; @@ -935,7 +935,7 @@ class ChannelData::ClientChannelControlHelper grpc_arg args_to_add[2]; int num_args_to_add = 0; if (chand_->service_config_ != nullptr) { - /*const auto* health_check_object = static_cast( + const auto* health_check_object = static_cast( chand_->service_config_->GetParsedGlobalServiceConfigObject( HealthCheckParser::ParserIndex())); if (health_check_object != nullptr) { @@ -943,7 +943,7 @@ class ChannelData::ClientChannelControlHelper const_cast("grpc.temp.health_check"), const_cast(health_check_object->service_name())); num_args_to_add++; - }*/ + } } args_to_add[num_args_to_add++] = SubchannelPoolInterface::CreateChannelArg( chand_->subchannel_pool_.get()); @@ -3087,24 +3087,17 @@ void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) { gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call", chand, this); } - service_config_ = chand->service_config(); - if (service_config_ != nullptr) { - // Store a ref to the service_config in CallData. Also, save pointers to the - // ServiceConfig and ServiceConfigObjectsVector (for this call) in the - // call_context so that all future filters can access it. - call_context_[GRPC_SERVICE_CONFIG].value = &service_config_; - const auto* method_params_vector_ptr = - service_config_->GetMethodServiceConfigObjectsVector(path_); - if (method_params_vector_ptr != nullptr) { - method_params_ = static_cast( - ((*method_params_vector_ptr) - [internal::ClientChannelServiceConfigParser:: - client_channel_service_config_parser_index()]) - .get()); - call_context_[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value = - const_cast( - method_params_vector_ptr); - } + // Store a ref to the service_config in service_config_call_data_. Also, save + // a pointer to this in the call_context so that all future filters can access + // it. + service_config_call_data_ = + ServiceConfig::CallData(chand->service_config(), path_); + if (!service_config_call_data_.empty()) { + call_context_[GRPC_SERVICE_CONFIG_CALL_DATA].value = + &service_config_call_data_; + method_params_ = static_cast( + service_config_call_data_.GetMethodParsedObject( + internal::ClientChannelServiceConfigParser::ParserIndex())); } retry_throttle_data_ = chand->retry_throttle_data(); if (method_params_ != nullptr) { 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 a5d2c83ecd3..877111b8a38 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -35,7 +35,6 @@ #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/retry_throttle.h" -#include "src/core/ext/filters/message_size/message_size_parser.h" #include "src/core/lib/surface/channel_init.h" static bool append_filter(grpc_channel_stack_builder* builder, 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 2d5a5bb8e2d..e4a36119c3f 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -48,8 +48,7 @@ namespace { size_t g_client_channel_service_config_parser_index; } -size_t -ClientChannelServiceConfigParser::client_channel_service_config_parser_index() { +size_t ClientChannelServiceConfigParser::ParserIndex() { return g_client_channel_service_config_parser_index; } @@ -87,8 +86,7 @@ void ProcessedResolverResult::ProcessServiceConfig( service_config_json_ = service_config_->service_config_json(); auto* parsed_object = static_cast( service_config_->GetParsedGlobalServiceConfigObject( - ClientChannelServiceConfigParser:: - client_channel_service_config_parser_index())); + ClientChannelServiceConfigParser::ParserIndex())); if (!parsed_object) { return; } @@ -113,8 +111,7 @@ void ProcessedResolverResult::ProcessLbPolicy( if (service_config_ != nullptr) { auto* parsed_object = static_cast( service_config_->GetParsedGlobalServiceConfigObject( - ClientChannelServiceConfigParser:: - client_channel_service_config_parser_index())); + ClientChannelServiceConfigParser::ParserIndex())); if (parsed_object != nullptr) { if (parsed_object->parsed_lb_config()) { lb_policy_name_.reset( 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 02a49bad2e9..0369e0b704f 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -107,7 +107,7 @@ class ClientChannelServiceConfigParser : public ServiceConfigParser { UniquePtr ParsePerMethodParams( const grpc_json* json, grpc_error** error) override; - static size_t client_channel_service_config_parser_index(); + static size_t ParserIndex(); static void Register(); }; diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 0b7a8d33855..85a49855f96 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -91,6 +91,33 @@ class ServiceConfig : public RefCounted { kNumPreallocatedParsers> ServiceConfigObjectsVector; + class CallData { + public: + CallData() = default; + CallData(RefCountedPtr svc_cfg, const grpc_slice& path) + : service_config_(std::move(svc_cfg)) { + if (service_config_ != nullptr) { + method_params_vector_ = + service_config_->GetMethodServiceConfigObjectsVector(path); + } + } + + RefCountedPtr service_config() { return service_config_; } + + ServiceConfigParsedObject* GetMethodParsedObject(int index) const { + return method_params_vector_ != nullptr + ? (*method_params_vector_)[index].get() + : nullptr; + } + + bool empty() const { return service_config_ == nullptr; } + + private: + RefCountedPtr service_config_; + const ServiceConfig::ServiceConfigObjectsVector* method_params_vector_ = + nullptr; + }; + /// Creates a new service config from parsing \a json_string. /// Returns null on parse error. static RefCountedPtr Create(const char* json, diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 639d0ec79f4..e7f22b07ae9 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -567,6 +567,7 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, health_check_service_name_ = UniquePtr(gpr_strdup(grpc_channel_arg_get_string( grpc_channel_args_find(args_, "grpc.temp.health_check")))); + gpr_log(GPR_ERROR, "healthcheck %s", health_check_service_name_.get()); 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); 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 d7bfa28fee1..e19accbe8a7 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -26,7 +26,7 @@ #include #include -#include "src/core/ext/filters/message_size/message_size_parser.h" +#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" @@ -38,6 +38,69 @@ static void recv_message_ready(void* user_data, grpc_error* error); static void recv_trailing_metadata_ready(void* user_data, grpc_error* error); +namespace { +size_t g_message_size_parser_index; +} // namespace + +namespace grpc_core { + +UniquePtr MessageSizeParser::ParsePerMethodParams( + const grpc_json* json, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + int max_request_message_bytes = -1; + int max_response_message_bytes = -1; + InlinedVector error_list; + for (grpc_json* field = json->child; field != nullptr; field = field->next) { + if (field->key == nullptr) continue; + if (strcmp(field->key, "maxRequestMessageBytes") == 0) { + if (max_request_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:Duplicate entry")); + } else if (field->type != GRPC_JSON_STRING && + field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be of type number")); + } else { + max_request_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_request_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be non-negative")); + } + } + } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { + if (max_response_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:Duplicate entry")); + } else if (field->type != GRPC_JSON_STRING && + field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be of type number")); + } else { + max_response_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_response_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be non-negative")); + } + } + } + } + if (!error_list.empty()) { + *error = ServiceConfig::CreateErrorFromVector("Message size parser", + &error_list); + return nullptr; + } + return UniquePtr(New( + max_request_message_bytes, max_response_message_bytes)); +} + +void MessageSizeParser::Register() { + g_message_size_parser_index = ServiceConfig::RegisterParser( + UniquePtr(New())); +} + +size_t MessageSizeParser::ParserIndex() { return g_message_size_parser_index; } +} // namespace grpc_core + namespace { struct channel_data { grpc_core::MessageSizeParsedObject::message_size_limits limits; @@ -58,18 +121,17 @@ struct call_data { // apply the max request size to the send limit and the max response // size to the receive limit. const grpc_core::MessageSizeParsedObject* limits = nullptr; - const grpc_core::ServiceConfig::ServiceConfigObjectsVector* objs_vector = - nullptr; + grpc_core::ServiceConfig::CallData* svc_cfg_call_data = nullptr; if (args.context != nullptr) { - objs_vector = static_cast< - const grpc_core::ServiceConfig::ServiceConfigObjectsVector*>( - args.context[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value); + svc_cfg_call_data = static_cast( + args.context[GRPC_SERVICE_CONFIG_CALL_DATA].value); } - if (objs_vector != nullptr) { + if (svc_cfg_call_data != nullptr) { limits = static_cast( - (*objs_vector)[grpc_core::MessageSizeParser::ParserIndex()].get()); + svc_cfg_call_data->GetMethodParsedObject( + grpc_core::MessageSizeParser::ParserIndex())); } else if (chand.svc_cfg != nullptr) { - objs_vector = + const auto* objs_vector = chand.svc_cfg->GetMethodServiceConfigObjectsVector(args.path); if (objs_vector != nullptr) { limits = static_cast( diff --git a/src/core/ext/filters/message_size/message_size_filter.h b/src/core/ext/filters/message_size/message_size_filter.h index b916bdd83f6..e43d7be61b5 100644 --- a/src/core/ext/filters/message_size/message_size_filter.h +++ b/src/core/ext/filters/message_size/message_size_filter.h @@ -24,4 +24,36 @@ extern const grpc_channel_filter grpc_message_size_filter; +namespace grpc_core { + +class MessageSizeParsedObject : public ServiceConfigParsedObject { + public: + struct message_size_limits { + int max_send_size; + int max_recv_size; + }; + + MessageSizeParsedObject(int max_send_size, int max_recv_size) { + limits_.max_send_size = max_send_size; + limits_.max_recv_size = max_recv_size; + } + + const message_size_limits& limits() const { return limits_; } + + private: + message_size_limits limits_; +}; + +class MessageSizeParser : public ServiceConfigParser { + public: + UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) override; + + static void Register(); + + static size_t ParserIndex(); +}; + +} // namespace grpc_core + #endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H */ diff --git a/src/core/ext/filters/message_size/message_size_parser.cc b/src/core/ext/filters/message_size/message_size_parser.cc deleted file mode 100644 index a3444a984dd..00000000000 --- a/src/core/ext/filters/message_size/message_size_parser.cc +++ /dev/null @@ -1,84 +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 "src/core/ext/filters/message_size/message_size_parser.h" - -#include "src/core/lib/gpr/string.h" - -namespace { -size_t g_message_size_parser_index; -} // namespace - -namespace grpc_core { - -UniquePtr MessageSizeParser::ParsePerMethodParams( - const grpc_json* json, grpc_error** error) { - GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); - int max_request_message_bytes = -1; - int max_response_message_bytes = -1; - InlinedVector error_list; - for (grpc_json* field = json->child; field != nullptr; field = field->next) { - if (field->key == nullptr) continue; - if (strcmp(field->key, "maxRequestMessageBytes") == 0) { - if (max_request_message_bytes >= 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:Duplicate entry")); - } else if (field->type != GRPC_JSON_STRING && - field->type != GRPC_JSON_NUMBER) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:should be of type number")); - } else { - max_request_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_request_message_bytes == -1) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:should be non-negative")); - } - } - } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { - if (max_response_message_bytes >= 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:Duplicate entry")); - } else if (field->type != GRPC_JSON_STRING && - field->type != GRPC_JSON_NUMBER) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:should be of type number")); - } else { - max_response_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_response_message_bytes == -1) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:should be non-negative")); - } - } - } - } - if (!error_list.empty()) { - *error = ServiceConfig::CreateErrorFromVector("Message size parser", - &error_list); - return nullptr; - } - return UniquePtr(New( - max_request_message_bytes, max_response_message_bytes)); -} - -void MessageSizeParser::Register() { - g_message_size_parser_index = ServiceConfig::RegisterParser( - UniquePtr(New())); -} - -size_t MessageSizeParser::ParserIndex() { return g_message_size_parser_index; } -} // namespace grpc_core diff --git a/src/core/ext/filters/message_size/message_size_parser.h b/src/core/ext/filters/message_size/message_size_parser.h deleted file mode 100644 index 4581cdf6226..00000000000 --- a/src/core/ext/filters/message_size/message_size_parser.h +++ /dev/null @@ -1,55 +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 GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_PARSER_H -#define GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_PARSER_H - -#include - -#include "src/core/ext/filters/client_channel/service_config.h" - -namespace grpc_core { - -class MessageSizeParsedObject : public ServiceConfigParsedObject { - public: - struct message_size_limits { - int max_send_size; - int max_recv_size; - }; - - MessageSizeParsedObject(int max_send_size, int max_recv_size) { - limits_.max_send_size = max_send_size; - limits_.max_recv_size = max_recv_size; - } - - const message_size_limits& limits() const { return limits_; } - - private: - message_size_limits limits_; -}; - -class MessageSizeParser : public ServiceConfigParser { - public: - UniquePtr ParsePerMethodParams( - const grpc_json* json, grpc_error** error) override; - - static void Register(); - - static size_t ParserIndex(); -}; -} // namespace grpc_core - -#endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_PARSER_H */ diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h index 3c91f9365f8..fd9d0ce711a 100644 --- a/src/core/lib/channel/context.h +++ b/src/core/lib/channel/context.h @@ -35,9 +35,8 @@ typedef enum { /// Reserved for traffic_class_context. GRPC_CONTEXT_TRAFFIC, - GRPC_SERVICE_CONFIG, - - GRPC_SERVICE_CONFIG_METHOD_PARAMS, + /// Holds a pointer to ServiceConfig::CallData associated with this call. + GRPC_SERVICE_CONFIG_CALL_DATA, GRPC_CONTEXT_COUNT } grpc_context_index; diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index 99a148ddc26..fcc6f0761b3 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -30,7 +30,6 @@ #include #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gprpp/inlined_vector.h" /// Opaque representation of an error. /// See https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md for a diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 6aa0a37826e..8060b5a0a8c 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -340,7 +340,6 @@ CORE_SOURCE_FILES = [ '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/message_size/message_size_parser.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/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 88e57036830..eee3f777ea6 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -989,8 +989,6 @@ 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/message_size/message_size_parser.cc \ -src/core/ext/filters/message_size/message_size_parser.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 \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 3b66e146262..6a0d47ab932 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8733,8 +8733,7 @@ "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/message_size/message_size_parser.h" + "src/core/ext/filters/client_channel/subchannel_pool_interface.h" ], "is_filegroup": true, "language": "c", @@ -8793,9 +8792,7 @@ "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/message_size/message_size_parser.cc", - "src/core/ext/filters/message_size/message_size_parser.h" + "src/core/ext/filters/client_channel/subchannel_pool_interface.h" ], "third_party": false, "type": "filegroup" From af2b170d8a9b50677856189079929656464da57c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 23 Apr 2019 12:14:52 -0700 Subject: [PATCH 1934/2143] Comment out names of unused arguments --- include/grpcpp/security/credentials.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 34d2e2ea463..134e688fa89 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -98,10 +98,10 @@ class ChannelCredentials : private GrpcLibraryCodegen { // 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( - const grpc::string& target, const ChannelArguments& args, + const grpc::string& /* target */, const ChannelArguments& /* args */, std::vector< std::unique_ptr> - interceptor_creators) { + /* interceptor_creators */) { return nullptr; } }; From 39cfbf9d4af5f23c3f4d5306097b60c43307e8a2 Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 23 Apr 2019 13:00:09 -0700 Subject: [PATCH 1935/2143] cast and default initializer --- include/grpcpp/impl/codegen/message_allocator.h | 6 +++--- src/compiler/cpp_generator.cc | 2 +- test/cpp/codegen/compiler_test_golden | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/grpcpp/impl/codegen/message_allocator.h b/include/grpcpp/impl/codegen/message_allocator.h index 53ea05efe8e..107bec62f1d 100644 --- a/include/grpcpp/impl/codegen/message_allocator.h +++ b/include/grpcpp/impl/codegen/message_allocator.h @@ -26,11 +26,11 @@ namespace experimental { // call arena in here in the future. template struct RpcAllocatorInfo { - RequestT* request = nullptr; - ResponseT* response = nullptr; + RequestT* request; + ResponseT* response; // per rpc allocator internal state. MessageAllocator can set it when // AllocateMessages is called and use it later. - void* allocator_state = nullptr; + void* allocator_state; }; // Implementations need to be thread-safe diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index da95ee7ffe2..25c1639b6e2 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -1002,7 +1002,7 @@ void PrintHeaderServerMethodCallback( "void SetMessageAllocatorFor_$Method$(\n" " ::grpc::experimental::MessageAllocator< " "$RealRequest$, $RealResponse$>* allocator) {\n" - " dynamic_cast<::grpc::internal::CallbackUnaryHandler< " + " static_cast<::grpc::internal::CallbackUnaryHandler< " "$RealRequest$, $RealResponse$>*>(\n" " ::grpc::Service::experimental().GetHandler($Idx$))\n" " ->SetMessageAllocator(allocator);\n"); diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 91335bf2c0c..9f59bb5d706 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -338,7 +338,7 @@ class ServiceA final { } void SetMessageAllocatorFor_MethodA1( ::grpc::experimental::MessageAllocator< ::grpc::testing::Request, ::grpc::testing::Response>* allocator) { - dynamic_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( + static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( ::grpc::Service::experimental().GetHandler(0)) ->SetMessageAllocator(allocator); } @@ -812,7 +812,7 @@ class ServiceB final { } void SetMessageAllocatorFor_MethodB1( ::grpc::experimental::MessageAllocator< ::grpc::testing::Request, ::grpc::testing::Response>* allocator) { - dynamic_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( + static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( ::grpc::Service::experimental().GetHandler(0)) ->SetMessageAllocator(allocator); } From cd4ed28b1e8a5fe1d0246ee6ef1427f03def4095 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 5 Apr 2019 10:57:16 -0700 Subject: [PATCH 1936/2143] Objc tests should use installed version of protoc Pod install should use the installed version of protoc if available, otherwise use protoc built from source. Fixes ##9570. --- .../tests/RemoteTestClient/RemoteTest.podspec | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec index ad834815951..93b56d56059 100644 --- a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec @@ -14,20 +14,34 @@ Pod::Spec.new do |s| s.dependency "!ProtoCompiler-gRPCPlugin" repo_root = '../../../..' - bin_dir = "#{repo_root}/bins/$CONFIG" + config = ENV['CONFIG'] || 'opt' + bin_dir = "#{repo_root}/bins/#{config}" protoc = "#{bin_dir}/protobuf/protoc" well_known_types_dir = "#{repo_root}/third_party/protobuf/src" plugin = "#{bin_dir}/grpc_objective_c_plugin" s.prepare_command = <<-CMD - #{protoc} \ - --plugin=protoc-gen-grpc=#{plugin} \ - --objc_out=. \ - --grpc_out=. \ - -I . \ - -I #{well_known_types_dir} \ - *.proto + if [ -f #{protoc} ]; then + #{protoc} \ + --plugin=protoc-gen-grpc=#{plugin} \ + --objc_out=. \ + --grpc_out=. \ + -I . \ + -I #{well_known_types_dir} \ + *.proto + else + # protoc was not found bin_dir, use installed version instead + (>&2 echo "\nWARNING: Using installed version of protoc. It might be incompatible with gRPC") + + protoc \ + --plugin=protoc-gen-grpc=#{plugin} \ + --objc_out=. \ + --grpc_out=. \ + -I . \ + -I #{well_known_types_dir} \ + *.proto + fi CMD s.subspec "Messages" do |ms| From 76d78eb82b59c2eae4f3669d464928d0071c519a Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 19 Mar 2019 14:27:30 -0700 Subject: [PATCH 1937/2143] Moving create_channel from grpc to grpc_impl --- include/grpcpp/security/credentials.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 03f1f217c18..e4cc1c7d501 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -35,6 +35,7 @@ struct grpc_call; namespace grpc { class CallCredentials; +class ChannelArguments; class ChannelCredentials; } // namespace grpc namespace grpc_impl { @@ -77,12 +78,12 @@ class ChannelCredentials : private GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr grpc_impl::CreateCustomChannelImpl( + friend std::shared_ptr grpc_impl::CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); - friend std::shared_ptr + friend std::shared_ptr grpc_impl::experimental::CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, @@ -91,12 +92,12 @@ class ChannelCredentials : private GrpcLibraryCodegen { grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators); - virtual std::shared_ptr CreateChannelImpl( + virtual std::shared_ptr CreateChannelImpl( 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 CreateChannelWithInterceptors( const grpc::string& target, const ChannelArguments& args, std::vector< std::unique_ptr> From 603d014f0e954e9eb5ea97dd162ffdc3627f79dc Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 19 Mar 2019 14:26:31 -0700 Subject: [PATCH 1938/2143] Changes to fold credentials into grpc_impl from grpc --- BUILD | 1 + include/grpcpp/impl/codegen/client_context.h | 9 +- include/grpcpp/security/credentials.h | 293 ++++-------------- include/grpcpp/security/credentials_impl.h | 285 +++++++++++++++++ src/cpp/client/create_channel.cc | 1 + src/cpp/client/credentials_cc.cc | 4 +- src/cpp/client/insecure_credentials.cc | 16 +- src/cpp/client/secure_credentials.cc | 62 ++-- src/cpp/client/secure_credentials.h | 10 +- test/cpp/end2end/client_crash_test.cc | 2 +- test/cpp/end2end/end2end_test.cc | 22 +- test/cpp/end2end/filter_end2end_test.cc | 2 +- test/cpp/end2end/generic_end2end_test.cc | 2 +- .../end2end/health_service_end2end_test.cc | 2 +- test/cpp/end2end/hybrid_end2end_test.cc | 6 +- test/cpp/end2end/mock_test.cc | 2 +- test/cpp/end2end/nonblocking_test.cc | 2 +- .../end2end/proto_server_reflection_test.cc | 2 +- test/cpp/end2end/raw_end2end_test.cc | 2 +- .../cpp/end2end/server_builder_plugin_test.cc | 2 +- test/cpp/end2end/server_early_return_test.cc | 2 +- .../server_interceptors_end2end_test.cc | 18 +- .../server_load_reporting_end2end_test.cc | 2 +- test/cpp/end2end/streaming_throughput_test.cc | 2 +- test/cpp/end2end/thread_stress_test.cc | 2 +- test/cpp/end2end/time_change_test.cc | 2 +- test/cpp/qps/driver.cc | 6 +- test/cpp/server/server_request_call_test.cc | 2 +- test/cpp/util/cli_call_test.cc | 2 +- test/cpp/util/create_test_channel.cc | 8 +- test/cpp/util/grpc_tool_test.cc | 2 +- test/cpp/util/test_credentials_provider.cc | 2 +- 32 files changed, 454 insertions(+), 323 deletions(-) create mode 100644 include/grpcpp/security/credentials_impl.h diff --git a/BUILD b/BUILD index 3c0974f3255..2f1ee9f2a5e 100644 --- a/BUILD +++ b/BUILD @@ -252,6 +252,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", + "include/grpcpp/security/credentials_impl.h", "include/grpcpp/security/server_credentials.h", "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 7f6956a0da4..f5bcdfa5403 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -57,12 +57,15 @@ struct census_context; struct grpc_call; +namespace grpc_impl { + +class CallCredentials; +} namespace grpc { class Channel; class ChannelInterface; class CompletionQueue; -class CallCredentials; class ClientContext; namespace internal { @@ -306,7 +309,7 @@ class ClientContext { /// call. /// /// \see https://grpc.io/docs/guides/auth.html - void set_credentials(const std::shared_ptr& creds) { + void set_credentials(const std::shared_ptr& creds) { creds_ = creds; } @@ -465,7 +468,7 @@ class ClientContext { bool call_canceled_; gpr_timespec deadline_; grpc::string authority_; - std::shared_ptr creds_; + std::shared_ptr creds_; mutable std::shared_ptr auth_context_; struct census_context* census_context_; std::multimap send_initial_metadata_; diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index e4cc1c7d501..8c99aab6c59 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -19,265 +19,92 @@ #ifndef GRPCPP_SECURITY_CREDENTIALS_H #define GRPCPP_SECURITY_CREDENTIALS_H -#include -#include -#include +#include -#include -#include -#include -#include -#include -#include -#include - -struct grpc_call; - -namespace grpc { -class CallCredentials; -class ChannelArguments; -class ChannelCredentials; -} // namespace grpc -namespace grpc_impl { -std::shared_ptr CreateCustomChannelImpl( - const grpc::string& target, - const std::shared_ptr& creds, - const grpc::ChannelArguments& args); - -namespace experimental { -std::shared_ptr CreateCustomChannelWithInterceptors( - const grpc::string& target, - const std::shared_ptr& creds, - const grpc::ChannelArguments& args, - std::vector< - std::unique_ptr> - interceptor_creators); -} // namespace experimental -} // namespace grpc_impl namespace grpc { class Channel; -class SecureChannelCredentials; -class SecureCallCredentials; -/// A channel credentials object encapsulates all the state needed by a client -/// to authenticate with a server for a given channel. -/// It can make various assertions, e.g., about the client’s identity, role -/// for all the calls on that channel. -/// -/// \see https://grpc.io/docs/guides/auth.html -class ChannelCredentials : private GrpcLibraryCodegen { - public: - ChannelCredentials(); - ~ChannelCredentials(); +typedef ::grpc_impl::ChannelCredentials ChannelCredentials; +typedef ::grpc_impl::CallCredentials CallCredentials; +typedef ::grpc_impl::SslCredentialsOptions SslCredentialsOptions; +typedef ::grpc_impl::SecureCallCredentials SecureCallCredentials; +typedef ::grpc_impl::SecureChannelCredentials SecureChannelCredentials; - protected: - friend std::shared_ptr CompositeChannelCredentials( - const std::shared_ptr& channel_creds, - const std::shared_ptr& call_creds); +static inline std::shared_ptr GoogleDefaultCredentials() { + return ::grpc_impl::GoogleDefaultCredentials(); +} - virtual SecureChannelCredentials* AsSecureCredentials() = 0; +static inline std::shared_ptr SslCredentials( + const SslCredentialsOptions& options) { + return ::grpc_impl::SslCredentials(options); +} - private: - friend std::shared_ptr grpc_impl::CreateCustomChannelImpl( - const grpc::string& target, - const std::shared_ptr& creds, - const grpc::ChannelArguments& args); +static inline std::shared_ptr GoogleComputeEngineCredentials() { + return ::grpc_impl::GoogleComputeEngineCredentials(); +} - friend std::shared_ptr - grpc_impl::experimental::CreateCustomChannelWithInterceptors( - const grpc::string& target, - const std::shared_ptr& creds, - const grpc::ChannelArguments& args, - std::vector> - interceptor_creators); - - virtual std::shared_ptr CreateChannelImpl( - 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( - const grpc::string& target, const ChannelArguments& args, - std::vector< - std::unique_ptr> - interceptor_creators) { - return nullptr; - } -}; - -/// A call credentials object encapsulates the state needed by a client to -/// authenticate with a server for a given call on a channel. -/// -/// \see https://grpc.io/docs/guides/auth.html -class CallCredentials : private GrpcLibraryCodegen { - public: - CallCredentials(); - ~CallCredentials(); - - /// Apply this instance's credentials to \a call. - virtual bool ApplyToCall(grpc_call* call) = 0; - - protected: - friend std::shared_ptr CompositeChannelCredentials( - const std::shared_ptr& channel_creds, - const std::shared_ptr& call_creds); - - friend std::shared_ptr CompositeCallCredentials( - const std::shared_ptr& creds1, - const std::shared_ptr& creds2); - - virtual SecureCallCredentials* AsSecureCredentials() = 0; -}; - -/// Options used to build SslCredentials. -struct SslCredentialsOptions { - /// The buffer containing the PEM encoding of the server root certificates. If - /// this parameter is empty, the default roots will be used. The default - /// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH - /// environment variable pointing to a file on the file system containing the - /// roots. - grpc::string pem_root_certs; - - /// The buffer containing the PEM encoding of the client's private key. This - /// parameter can be empty if the client does not have a private key. - grpc::string pem_private_key; - - /// The buffer containing the PEM encoding of the client's certificate chain. - /// This parameter can be empty if the client does not have a certificate - /// chain. - grpc::string pem_cert_chain; -}; - -// Factories for building different types of Credentials The functions may -// return empty shared_ptr when credentials cannot be created. If a -// Credentials pointer is returned, it can still be invalid when used to create -// a channel. A lame channel will be created then and all rpcs will fail on it. - -/// Builds credentials with reasonable defaults. -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr GoogleDefaultCredentials(); - -/// Builds SSL Credentials given SSL specific options -std::shared_ptr SslCredentials( - const SslCredentialsOptions& options); - -/// Builds credentials for use when running in GCE -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr GoogleComputeEngineCredentials(); - -/// Constant for maximum auth token lifetime. -constexpr long kMaxAuthTokenLifetimeSecs = 3600; - -/// Builds Service Account JWT Access credentials. -/// json_key is the JSON key string containing the client's private key. -/// token_lifetime_seconds is the lifetime in seconds of each Json Web Token -/// (JWT) created with this credentials. It should not exceed -/// \a kMaxAuthTokenLifetimeSecs or will be cropped to this value. -std::shared_ptr ServiceAccountJWTAccessCredentials( +static inline std::shared_ptr ServiceAccountJWTAccessCredentials( const grpc::string& json_key, - long token_lifetime_seconds = kMaxAuthTokenLifetimeSecs); + long token_lifetime_seconds = ::grpc_impl::kMaxAuthTokenLifetimeSecs) { + return ::grpc_impl::ServiceAccountJWTAccessCredentials(json_key, token_lifetime_seconds); +} -/// Builds refresh token credentials. -/// json_refresh_token is the JSON string containing the refresh token along -/// with a client_id and client_secret. -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr GoogleRefreshTokenCredentials( - const grpc::string& json_refresh_token); +static inline std::shared_ptr GoogleRefreshTokenCredentials( + const grpc::string& json_refresh_token) { + return ::grpc_impl::GoogleRefreshTokenCredentials(json_refresh_token); +} -/// Builds access token credentials. -/// access_token is an oauth2 access token that was fetched using an out of band -/// mechanism. -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr AccessTokenCredentials( - const grpc::string& access_token); +static inline std::shared_ptr AccessTokenCredentials( + const grpc::string& access_token) { + return ::grpc_impl::AccessTokenCredentials(access_token); +} -/// Builds IAM credentials. -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr GoogleIAMCredentials( +static inline std::shared_ptr GoogleIAMCredentials( const grpc::string& authorization_token, - const grpc::string& authority_selector); + const grpc::string& authority_selector) { + return ::grpc_impl::GoogleIAMCredentials(authorization_token, authority_selector); +} -/// Combines a channel credentials and a call credentials into a composite -/// channel credentials. -std::shared_ptr CompositeChannelCredentials( +static inline std::shared_ptr CompositeChannelCredentials( const std::shared_ptr& channel_creds, - const std::shared_ptr& call_creds); + const std::shared_ptr& call_creds) { + return ::grpc_impl::CompositeChannelCredentials(channel_creds, call_creds); +} -/// Combines two call credentials objects into a composite call credentials. -std::shared_ptr CompositeCallCredentials( +static inline std::shared_ptr CompositeCallCredentials( const std::shared_ptr& creds1, - const std::shared_ptr& creds2); + const std::shared_ptr& creds2) { + return ::grpc_impl::CompositeCallCredentials(creds1, creds2); +} -/// Credentials for an unencrypted, unauthenticated channel -std::shared_ptr InsecureChannelCredentials(); +static inline std::shared_ptr InsecureChannelCredentials() { + return ::grpc_impl::InsecureChannelCredentials(); +} -/// Credentials for a channel using Cronet. -std::shared_ptr CronetChannelCredentials(void* engine); +static inline std::shared_ptr CronetChannelCredentials(void* engine) { + return ::grpc_impl::CronetChannelCredentials(engine); +} -/// User defined metadata credentials. -class MetadataCredentialsPlugin { - public: - virtual ~MetadataCredentialsPlugin() {} +typedef ::grpc_impl::MetadataCredentialsPlugin MetadataCredentialsPlugin; - /// If this method returns true, the Process function will be scheduled in - /// a different thread from the one processing the call. - virtual bool IsBlocking() const { return true; } - - /// Type of credentials this plugin is implementing. - virtual const char* GetType() const { return ""; } - - /// Gets the auth metatada produced by this plugin. - /// The fully qualified method name is: - /// service_url + "/" + method_name. - /// The channel_auth_context contains (among other things), the identity of - /// the server. - virtual Status GetMetadata( - grpc::string_ref service_url, grpc::string_ref method_name, - const AuthContext& channel_auth_context, - std::multimap* metadata) = 0; -}; - -std::shared_ptr MetadataCredentialsFromPlugin( - std::unique_ptr plugin); +static inline std::shared_ptr MetadataCredentialsFromPlugin( + std::unique_ptr plugin) { + return ::grpc_impl::MetadataCredentialsFromPlugin(std::move(plugin)); +} namespace experimental { -/// Options used to build AltsCredentials. -struct AltsCredentialsOptions { - /// service accounts of target endpoint that will be acceptable - /// by the client. If service accounts are provided and none of them matches - /// that of the server, authentication will fail. - std::vector target_service_accounts; -}; +typedef ::grpc_impl::experimental::AltsCredentialsOptions AltsCredentialsOptions; -/// Builds ALTS Credentials given ALTS specific options -std::shared_ptr AltsCredentials( - const AltsCredentialsOptions& options); +static inline std::shared_ptr AltsCredentials( + const AltsCredentialsOptions& options) { + return ::grpc_impl::experimental::AltsCredentials(options); +} -/// Builds Local Credentials. -std::shared_ptr LocalCredentials( - grpc_local_connect_type type); +static inline std::shared_ptr LocalCredentials( + grpc_local_connect_type type) { + return ::grpc_impl::experimental::LocalCredentials(type); +} } // namespace experimental } // namespace grpc diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h new file mode 100644 index 00000000000..8ec339639b5 --- /dev/null +++ b/include/grpcpp/security/credentials_impl.h @@ -0,0 +1,285 @@ +/* + * + * 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_SECURITY_CREDENTIALS_IMPL_H +#define GRPCPP_SECURITY_CREDENTIALS_IMPL_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +struct grpc_call; + +namespace grpc { +class ChannelArguments; +class Channel; +} // namespace grpc + +namespace grpc_impl { + +class ChannelCredentials; +class CallCredentials; +class SecureCallCredentials; +class SecureChannelCredentials; + +std::shared_ptr CreateCustomChannel( + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args); + +namespace experimental { +std::shared_ptr CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators); +} + +/// A channel credentials object encapsulates all the state needed by a client +/// to authenticate with a server for a given channel. +/// It can make various assertions, e.g., about the client’s identity, role +/// for all the calls on that channel. +/// +/// \see https://grpc.io/docs/guides/auth.html +class ChannelCredentials : private grpc::GrpcLibraryCodegen { + public: + ChannelCredentials(); + ~ChannelCredentials(); + + protected: + friend std::shared_ptr CompositeChannelCredentials( + const std::shared_ptr& channel_creds, + const std::shared_ptr& call_creds); + + virtual SecureChannelCredentials* AsSecureCredentials() = 0; + + private: + friend std::shared_ptr CreateCustomChannel( + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args); + + friend std::shared_ptr + grpc_impl::experimental::CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators); + + virtual std::shared_ptr CreateChannel( + const grpc::string& target, const grpc::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( + const grpc::string& target, const grpc::ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators) { + return nullptr; + } +}; + +/// A call credentials object encapsulates the state needed by a client to +/// authenticate with a server for a given call on a channel. +/// +/// \see https://grpc.io/docs/guides/auth.html +class CallCredentials : private grpc::GrpcLibraryCodegen { + public: + CallCredentials(); + ~CallCredentials(); + + /// Apply this instance's credentials to \a call. + virtual bool ApplyToCall(grpc_call* call) = 0; + + protected: + friend std::shared_ptr CompositeChannelCredentials( + const std::shared_ptr& channel_creds, + const std::shared_ptr& call_creds); + + friend std::shared_ptr CompositeCallCredentials( + const std::shared_ptr& creds1, + const std::shared_ptr& creds2); + + virtual SecureCallCredentials* AsSecureCredentials() = 0; +}; + +/// Options used to build SslCredentials. +struct SslCredentialsOptions { + /// The buffer containing the PEM encoding of the server root certificates. If + /// this parameter is empty, the default roots will be used. The default + /// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH + /// environment variable pointing to a file on the file system containing the + /// roots. + grpc::string pem_root_certs; + + /// The buffer containing the PEM encoding of the client's private key. This + /// parameter can be empty if the client does not have a private key. + grpc::string pem_private_key; + + /// The buffer containing the PEM encoding of the client's certificate chain. + /// This parameter can be empty if the client does not have a certificate + /// chain. + grpc::string pem_cert_chain; +}; + +// Factories for building different types of Credentials The functions may +// return empty shared_ptr when credentials cannot be created. If a +// Credentials pointer is returned, it can still be invalid when used to create +// a channel. A lame channel will be created then and all rpcs will fail on it. + +/// Builds credentials with reasonable defaults. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr GoogleDefaultCredentials(); + +/// Builds SSL Credentials given SSL specific options +std::shared_ptr SslCredentials( + const SslCredentialsOptions& options); + +/// Builds credentials for use when running in GCE +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr GoogleComputeEngineCredentials(); + +/// Constant for maximum auth token lifetime. +constexpr long kMaxAuthTokenLifetimeSecs = 3600; + +/// Builds Service Account JWT Access credentials. +/// json_key is the JSON key string containing the client's private key. +/// token_lifetime_seconds is the lifetime in seconds of each Json Web Token +/// (JWT) created with this credentials. It should not exceed +/// \a kMaxAuthTokenLifetimeSecs or will be cropped to this value. +std::shared_ptr ServiceAccountJWTAccessCredentials( + const grpc::string& json_key, + long token_lifetime_seconds = kMaxAuthTokenLifetimeSecs); + +/// Builds refresh token credentials. +/// json_refresh_token is the JSON string containing the refresh token along +/// with a client_id and client_secret. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr GoogleRefreshTokenCredentials( + const grpc::string& json_refresh_token); + +/// Builds access token credentials. +/// access_token is an oauth2 access token that was fetched using an out of band +/// mechanism. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr AccessTokenCredentials( + const grpc::string& access_token); + +/// Builds IAM credentials. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr GoogleIAMCredentials( + const grpc::string& authorization_token, + const grpc::string& authority_selector); + +/// Combines a channel credentials and a call credentials into a composite +/// channel credentials. +std::shared_ptr CompositeChannelCredentials( + const std::shared_ptr& channel_creds, + const std::shared_ptr& call_creds); + +/// Combines two call credentials objects into a composite call credentials. +std::shared_ptr CompositeCallCredentials( + const std::shared_ptr& creds1, + const std::shared_ptr& creds2); + +/// Credentials for an unencrypted, unauthenticated channel +std::shared_ptr InsecureChannelCredentials(); + +/// Credentials for a channel using Cronet. +std::shared_ptr CronetChannelCredentials(void* engine); + +/// User defined metadata credentials. +class MetadataCredentialsPlugin { + public: + virtual ~MetadataCredentialsPlugin() {} + + /// If this method returns true, the Process function will be scheduled in + /// a different thread from the one processing the call. + virtual bool IsBlocking() const { return true; } + + /// Type of credentials this plugin is implementing. + virtual const char* GetType() const { return ""; } + + /// Gets the auth metatada produced by this plugin. + /// The fully qualified method name is: + /// service_url + "/" + method_name. + /// The channel_auth_context contains (among other things), the identity of + /// the server. + virtual grpc::Status GetMetadata( + grpc::string_ref service_url, grpc::string_ref method_name, + const grpc::AuthContext& channel_auth_context, + std::multimap* metadata) = 0; +}; + +std::shared_ptr MetadataCredentialsFromPlugin( + std::unique_ptr plugin); + +namespace experimental { + +/// Options used to build AltsCredentials. +struct AltsCredentialsOptions { + /// service accounts of target endpoint that will be acceptable + /// by the client. If service accounts are provided and none of them matches + /// that of the server, authentication will fail. + std::vector target_service_accounts; +}; + +/// Builds ALTS Credentials given ALTS specific options +std::shared_ptr AltsCredentials( + const AltsCredentialsOptions& options); + +/// Builds Local Credentials. +std::shared_ptr LocalCredentials( + grpc_local_connect_type type); + +} // namespace experimental +} // namespace grpc + +#endif // GRPCPP_SECURITY_CREDENTIALS_H diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index c366693eced..c217dccac9c 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "src/cpp/client/create_channel_internal.h" diff --git a/src/cpp/client/credentials_cc.cc b/src/cpp/client/credentials_cc.cc index 2a0f06f424e..4377be0f2d7 100644 --- a/src/cpp/client/credentials_cc.cc +++ b/src/cpp/client/credentials_cc.cc @@ -19,9 +19,9 @@ #include #include -namespace grpc { +namespace grpc_impl { -static internal::GrpcLibraryInitializer g_gli_initializer; +static grpc::internal::GrpcLibraryInitializer g_gli_initializer; ChannelCredentials::ChannelCredentials() { g_gli_initializer.summon(); } ChannelCredentials::~ChannelCredentials() {} diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 1b0fa6faea9..275c42ab74b 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -21,31 +21,37 @@ #include #include #include +#include #include #include #include "src/cpp/client/create_channel_internal.h" -namespace grpc { +namespace grpc_impl { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: +<<<<<<< HEAD std::shared_ptr CreateChannelImpl( const string& target, const grpc::ChannelArguments& args) override { +======= + std::shared_ptr CreateChannel( + const grpc::string& target, const grpc::ChannelArguments& args) override { +>>>>>>> Changes to fold credentials into grpc_impl from grpc return CreateChannelWithInterceptors( target, args, std::vector>()); + grpc::experimental::ClientInterceptorFactoryInterface>>()); } std::shared_ptr CreateChannelWithInterceptors( - const string& target, const grpc::ChannelArguments& args, + const grpc::string& target, const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return grpc::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 f490f6e6f9a..e91f7e6b477 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -25,9 +25,9 @@ #include "src/cpp/client/create_channel_internal.h" #include "src/cpp/common/secure_auth_context.h" -namespace grpc { +namespace grpc_impl { -static internal::GrpcLibraryInitializer g_gli_initializer; +static grpc::internal::GrpcLibraryInitializer g_gli_initializer; SecureChannelCredentials::SecureChannelCredentials( grpc_channel_credentials* c_creds) : c_creds_(c_creds) { @@ -39,18 +39,18 @@ std::shared_ptr SecureChannelCredentials::CreateChannelImpl( return CreateChannelWithInterceptors( target, args, std::vector< - std::unique_ptr>()); + std::unique_ptr>()); } std::shared_ptr SecureChannelCredentials::CreateChannelWithInterceptors( - const string& target, const grpc::ChannelArguments& args, + const grpc::string& target, const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators) { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return grpc::CreateChannelInternal( args.GetSslTargetNameOverride(), grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args, nullptr), @@ -83,14 +83,14 @@ std::shared_ptr WrapCallCredentials( } // namespace std::shared_ptr GoogleDefaultCredentials() { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapChannelCredentials(grpc_google_default_credentials_create()); } // Builds SSL Credentials given SSL specific options std::shared_ptr SslCredentials( const SslCredentialsOptions& options) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). grpc_ssl_pem_key_cert_pair pem_key_cert_pair = { options.pem_private_key.c_str(), options.pem_cert_chain.c_str()}; @@ -106,7 +106,7 @@ namespace experimental { // Builds ALTS Credentials given ALTS specific options std::shared_ptr AltsCredentials( const AltsCredentialsOptions& options) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). grpc_alts_credentials_options* c_options = grpc_alts_credentials_client_options_create(); for (auto service_account = options.target_service_accounts.begin(); @@ -123,7 +123,7 @@ std::shared_ptr AltsCredentials( // Builds Local Credentials std::shared_ptr LocalCredentials( grpc_local_connect_type type) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapChannelCredentials(grpc_local_credentials_create(type)); } @@ -131,7 +131,7 @@ std::shared_ptr LocalCredentials( // Builds credentials for use when running in GCE std::shared_ptr GoogleComputeEngineCredentials() { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapCallCredentials( grpc_google_compute_engine_credentials_create(nullptr)); } @@ -139,7 +139,7 @@ std::shared_ptr GoogleComputeEngineCredentials() { // Builds JWT credentials. std::shared_ptr ServiceAccountJWTAccessCredentials( const grpc::string& json_key, long token_lifetime_seconds) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). if (token_lifetime_seconds <= 0) { gpr_log(GPR_ERROR, "Trying to create JWTCredentials with non-positive lifetime"); @@ -154,7 +154,7 @@ std::shared_ptr ServiceAccountJWTAccessCredentials( // Builds refresh token credentials. std::shared_ptr GoogleRefreshTokenCredentials( const grpc::string& json_refresh_token) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapCallCredentials(grpc_google_refresh_token_credentials_create( json_refresh_token.c_str(), nullptr)); } @@ -162,7 +162,7 @@ std::shared_ptr GoogleRefreshTokenCredentials( // Builds access token credentials. std::shared_ptr AccessTokenCredentials( const grpc::string& access_token) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapCallCredentials( grpc_access_token_credentials_create(access_token.c_str(), nullptr)); } @@ -171,7 +171,7 @@ std::shared_ptr AccessTokenCredentials( std::shared_ptr GoogleIAMCredentials( const grpc::string& authorization_token, const grpc::string& authority_selector) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapCallCredentials(grpc_google_iam_credentials_create( authorization_token.c_str(), authority_selector.c_str(), nullptr)); } @@ -207,6 +207,23 @@ std::shared_ptr CompositeCallCredentials( return nullptr; } +std::shared_ptr MetadataCredentialsFromPlugin( + std::unique_ptr plugin) { + grpc::GrpcLibraryCodegen init; // To call grpc_init(). + const char* type = plugin->GetType(); + grpc::MetadataCredentialsPluginWrapper* wrapper = + new grpc::MetadataCredentialsPluginWrapper(std::move(plugin)); + grpc_metadata_credentials_plugin c_plugin = { + grpc::MetadataCredentialsPluginWrapper::GetMetadata, + grpc::MetadataCredentialsPluginWrapper::Destroy, wrapper, type}; + return WrapCallCredentials( + grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); +} + +} // namespace grpc_impl + +namespace grpc { + void MetadataCredentialsPluginWrapper::Destroy(void* wrapper) { if (wrapper == nullptr) return; MetadataCredentialsPluginWrapper* w = @@ -308,17 +325,4 @@ MetadataCredentialsPluginWrapper::MetadataCredentialsPluginWrapper( std::unique_ptr plugin) : thread_pool_(CreateDefaultThreadPool()), plugin_(std::move(plugin)) {} -std::shared_ptr MetadataCredentialsFromPlugin( - std::unique_ptr plugin) { - GrpcLibraryCodegen init; // To call grpc_init(). - const char* type = plugin->GetType(); - MetadataCredentialsPluginWrapper* wrapper = - new MetadataCredentialsPluginWrapper(std::move(plugin)); - grpc_metadata_credentials_plugin c_plugin = { - MetadataCredentialsPluginWrapper::GetMetadata, - MetadataCredentialsPluginWrapper::Destroy, wrapper, type}; - return WrapCallCredentials( - grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); -} - -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index fa2f64ed1d8..4e9f121d2ce 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -27,7 +27,7 @@ #include "src/core/lib/security/credentials/credentials.h" #include "src/cpp/server/thread_pool_interface.h" -namespace grpc { +namespace grpc_impl { class SecureChannelCredentials final : public ChannelCredentials { public: @@ -44,9 +44,9 @@ class SecureChannelCredentials final : public ChannelCredentials { private: std::shared_ptr CreateChannelWithInterceptors( - const string& target, const grpc::ChannelArguments& args, + const grpc::string& target, const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators) override; grpc_channel_credentials* const c_creds_; }; @@ -66,6 +66,10 @@ class SecureCallCredentials final : public CallCredentials { grpc_call_credentials* const c_creds_; }; +} // namespace grpc_impl + +namespace grpc { + class MetadataCredentialsPluginWrapper final : private GrpcLibraryCodegen { public: static void Destroy(void* wrapper); diff --git a/test/cpp/end2end/client_crash_test.cc b/test/cpp/end2end/client_crash_test.cc index 992f3c488f9..2d5c1b47b17 100644 --- a/test/cpp/end2end/client_crash_test.cc +++ b/test/cpp/end2end/client_crash_test.cc @@ -60,7 +60,7 @@ class CrashTest : public ::testing::Test { })); GPR_ASSERT(server_); return grpc::testing::EchoTestService::NewStub( - CreateChannel(addr, InsecureChannelCredentials())); + grpc::CreateChannel(addr, InsecureChannelCredentials())); } void KillServer() { server_.reset(); } diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 47231058d17..8438d57b643 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -129,7 +129,7 @@ class TestAuthMetadataProcessor : public AuthMetadataProcessor { TestAuthMetadataProcessor(bool is_blocking) : is_blocking_(is_blocking) {} std::shared_ptr GetCompatibleClientCreds() { - return MetadataCredentialsFromPlugin( + return grpc::MetadataCredentialsFromPlugin( std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, kGoodGuy, @@ -137,7 +137,7 @@ class TestAuthMetadataProcessor : public AuthMetadataProcessor { } std::shared_ptr GetIncompatibleClientCreds() { - return MetadataCredentialsFromPlugin( + return grpc::MetadataCredentialsFromPlugin( std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Mr Hyde", @@ -374,7 +374,7 @@ class End2endTest : public ::testing::TestWithParam { proxy_server_ = builder.BuildAndStart(); - channel_ = CreateChannel(proxyaddr.str(), InsecureChannelCredentials()); + channel_ = grpc::CreateChannel(proxyaddr.str(), InsecureChannelCredentials()); } stub_ = grpc::testing::EchoTestService::NewStub(channel_); @@ -1277,7 +1277,7 @@ TEST_P(End2endTest, ChannelStateTimeout) { server_address << "127.0.0.1:" << port; // Channel to non-existing server auto channel = - CreateChannel(server_address.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address.str(), InsecureChannelCredentials()); // Start IDLE EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true)); @@ -1826,7 +1826,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) { EchoResponse response; ClientContext context; context.set_credentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + grpc::MetadataCredentialsFromPlugin(std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kBadMetadataKey, "Does not matter, will fail the key is invalid.", false, true)))); @@ -1844,7 +1844,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { EchoResponse response; ClientContext context; context.set_credentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + grpc::MetadataCredentialsFromPlugin(std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "With illegal \n value.", false, true)))); @@ -1862,7 +1862,7 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { EchoResponse response; ClientContext context; context.set_credentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + grpc::MetadataCredentialsFromPlugin(std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Does not matter, will fail anyway (see 3rd param)", false, @@ -1926,7 +1926,7 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { EchoResponse response; ClientContext context; context.set_credentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + grpc::MetadataCredentialsFromPlugin(std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Does not matter, will fail anyway (see 3rd param)", true, @@ -1952,11 +1952,11 @@ TEST_P(SecureEnd2endTest, CompositeCallCreds) { const char kMetadataVal1[] = "call-creds-val1"; const char kMetadataVal2[] = "call-creds-val2"; - context.set_credentials(CompositeCallCredentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::CompositeCallCredentials( + grpc::MetadataCredentialsFromPlugin(std::unique_ptr( new TestMetadataCredentialsPlugin(kMetadataKey1, kMetadataVal1, true, true))), - MetadataCredentialsFromPlugin(std::unique_ptr( + grpc::MetadataCredentialsFromPlugin(std::unique_ptr( new TestMetadataCredentialsPlugin(kMetadataKey2, kMetadataVal2, true, true))))); request.set_message("Hello"); diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index ad67402e3df..a1d95644635 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -147,7 +147,7 @@ class FilterEnd2endTest : public ::testing::Test { void ResetStub() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); generic_stub_.reset(new GenericStub(channel)); ResetConnectionCounter(); ResetCallCounter(); diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index 8c4b3cf1fd3..0ea7deb9409 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -91,7 +91,7 @@ class GenericEnd2endTest : public ::testing::Test { void ResetStub() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); generic_stub_.reset(new GenericStub(channel)); } diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index b96ff53a3ea..0b85c62c8c4 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -125,7 +125,7 @@ class HealthServiceEnd2endTest : public ::testing::Test { void ResetStubs() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); hc_stub_ = grpc::health::v1::Health::NewStub(channel); } diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc index b0dd901cf11..dbd078c2d99 100644 --- a/test/cpp/end2end/hybrid_end2end_test.cc +++ b/test/cpp/end2end/hybrid_end2end_test.cc @@ -296,7 +296,7 @@ class HybridEnd2endTest : public ::testing::TestWithParam { void ResetStub() { std::shared_ptr channel = inproc_ ? server_->InProcessChannel(ChannelArguments()) - : CreateChannel(server_address_.str(), + : grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -322,7 +322,7 @@ class HybridEnd2endTest : public ::testing::TestWithParam { void SendEchoToDupService() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel); EchoRequest send_request; EchoResponse recv_response; @@ -374,7 +374,7 @@ class HybridEnd2endTest : public ::testing::TestWithParam { void SendSimpleServerStreamingToDupService() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel); EchoRequest request; EchoResponse response; diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc index 917ca28020a..e25286b8b64 100644 --- a/test/cpp/end2end/mock_test.cc +++ b/test/cpp/end2end/mock_test.cc @@ -245,7 +245,7 @@ class MockTest : public ::testing::Test { void ResetStub() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/nonblocking_test.cc b/test/cpp/end2end/nonblocking_test.cc index 36dea1fcb31..eb651df21df 100644 --- a/test/cpp/end2end/nonblocking_test.cc +++ b/test/cpp/end2end/nonblocking_test.cc @@ -106,7 +106,7 @@ class NonblockingTest : public ::testing::Test { } void ResetStub() { - std::shared_ptr channel = CreateChannel( + std::shared_ptr channel = grpc::CreateChannel( server_address_.str(), grpc::InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/proto_server_reflection_test.cc b/test/cpp/end2end/proto_server_reflection_test.cc index ff097aa9a77..d817438f41b 100644 --- a/test/cpp/end2end/proto_server_reflection_test.cc +++ b/test/cpp/end2end/proto_server_reflection_test.cc @@ -55,7 +55,7 @@ class ProtoServerReflectionTest : public ::testing::Test { void ResetStub() { string target = "dns:localhost:" + to_string(port_); std::shared_ptr channel = - CreateChannel(target, InsecureChannelCredentials()); + grpc::CreateChannel(target, InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); desc_db_.reset(new ProtoReflectionDescriptorDatabase(channel)); desc_pool_.reset(new protobuf::DescriptorPool(desc_db_.get())); diff --git a/test/cpp/end2end/raw_end2end_test.cc b/test/cpp/end2end/raw_end2end_test.cc index c8556bae954..184dc1e5f56 100644 --- a/test/cpp/end2end/raw_end2end_test.cc +++ b/test/cpp/end2end/raw_end2end_test.cc @@ -130,7 +130,7 @@ class RawEnd2EndTest : public ::testing::Test { void ResetStub() { ChannelArguments args; - std::shared_ptr channel = CreateChannel( + std::shared_ptr channel = grpc::CreateChannel( server_address_.str(), grpc::InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/server_builder_plugin_test.cc b/test/cpp/end2end/server_builder_plugin_test.cc index d744a93912e..43b00b95f49 100644 --- a/test/cpp/end2end/server_builder_plugin_test.cc +++ b/test/cpp/end2end/server_builder_plugin_test.cc @@ -185,7 +185,7 @@ class ServerBuilderPluginTest : public ::testing::TestWithParam { void ResetStub() { string target = "dns:localhost:" + to_string(port_); - channel_ = CreateChannel(target, InsecureChannelCredentials()); + channel_ = grpc::CreateChannel(target, InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/server_early_return_test.cc b/test/cpp/end2end/server_early_return_test.cc index c47e25052e2..fc3ce097b6f 100644 --- a/test/cpp/end2end/server_early_return_test.cc +++ b/test/cpp/end2end/server_early_return_test.cc @@ -123,7 +123,7 @@ class ServerEarlyReturnTest : public ::testing::Test { server_ = builder.BuildAndStart(); channel_ = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 028191c93c3..db7712b6c99 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -265,7 +265,7 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { TEST_F(ServerInterceptorsEnd2endSyncUnaryTest, UnaryTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -308,7 +308,7 @@ class ServerInterceptorsEnd2endSyncStreamingTest : public ::testing::Test { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ClientStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeClientStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -317,7 +317,7 @@ TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ClientStreamingTest) { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ServerStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeServerStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -326,7 +326,7 @@ TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ServerStreamingTest) { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, BidiStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeBidiStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -356,7 +356,7 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, UnaryTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address, InsecureChannelCredentials()); auto stub = grpc::testing::EchoTestService::NewStub(channel); EchoRequest send_request; @@ -428,7 +428,7 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, BidiStreamingTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address, InsecureChannelCredentials()); auto stub = grpc::testing::EchoTestService::NewStub(channel); EchoRequest send_request; @@ -509,7 +509,7 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address, InsecureChannelCredentials()); GenericStub generic_stub(channel); const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo"); @@ -612,7 +612,7 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, UnimplementedRpcTest) { ChannelArguments args; std::shared_ptr channel = - CreateChannel(server_address, InsecureChannelCredentials()); + grpc::CreateChannel(server_address, InsecureChannelCredentials()); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); EchoRequest send_request; @@ -665,7 +665,7 @@ TEST_F(ServerInterceptorsSyncUnimplementedEnd2endTest, UnimplementedRpcTest) { ChannelArguments args; std::shared_ptr channel = - CreateChannel(server_address, InsecureChannelCredentials()); + grpc::CreateChannel(server_address, InsecureChannelCredentials()); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); EchoRequest send_request; diff --git a/test/cpp/end2end/server_load_reporting_end2end_test.cc b/test/cpp/end2end/server_load_reporting_end2end_test.cc index 7bc9af2a6eb..8eba9127ec6 100644 --- a/test/cpp/end2end/server_load_reporting_end2end_test.cc +++ b/test/cpp/end2end/server_load_reporting_end2end_test.cc @@ -94,7 +94,7 @@ class ServerLoadReportingEnd2endTest : public ::testing::Test { const grpc::string& lb_tag, const grpc::string& message, size_t num_requests) { auto stub = EchoTestService::NewStub( - CreateChannel(server_address_, InsecureChannelCredentials())); + grpc::CreateChannel(server_address_, InsecureChannelCredentials())); grpc::string lb_token = lb_id + lb_tag; for (int i = 0; i < num_requests; ++i) { ClientContext ctx; diff --git a/test/cpp/end2end/streaming_throughput_test.cc b/test/cpp/end2end/streaming_throughput_test.cc index 440656588b2..a604ffdfbd8 100644 --- a/test/cpp/end2end/streaming_throughput_test.cc +++ b/test/cpp/end2end/streaming_throughput_test.cc @@ -146,7 +146,7 @@ class End2endTest : public ::testing::Test { void ResetStub() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index 5b8af61ee33..d2eca091149 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -97,7 +97,7 @@ class CommonStressTestInsecure : public CommonStressTest { public: void ResetStub() override { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); this->stub_ = grpc::testing::EchoTestService::NewStub(channel); } bool AllowExhaustion() override { return false; } diff --git a/test/cpp/end2end/time_change_test.cc b/test/cpp/end2end/time_change_test.cc index 7f4e3caf6f9..688549e5772 100644 --- a/test/cpp/end2end/time_change_test.cc +++ b/test/cpp/end2end/time_change_test.cc @@ -139,7 +139,7 @@ class TimeChangeTest : public ::testing::Test { "--address=" + addr, })); GPR_ASSERT(server_); - channel_ = CreateChannel(addr, InsecureChannelCredentials()); + channel_ = grpc::CreateChannel(addr, InsecureChannelCredentials()); GPR_ASSERT(channel_); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 181e11f12b2..7d4d5d99446 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -288,7 +288,7 @@ std::unique_ptr RunScenario( gpr_log(GPR_INFO, "Starting server on %s (worker #%" PRIuPTR ")", workers[i].c_str(), i); if (!run_inproc) { - servers[i].stub = WorkerService::NewStub(CreateChannel( + servers[i].stub = WorkerService::NewStub(grpc::CreateChannel( workers[i], GetCredentialsProvider()->GetChannelCredentials( GetCredType(workers[i], per_worker_credential_types, credential_type), @@ -349,7 +349,7 @@ std::unique_ptr RunScenario( gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")", worker.c_str(), i + num_servers); if (!run_inproc) { - clients[i].stub = WorkerService::NewStub(CreateChannel( + clients[i].stub = WorkerService::NewStub(grpc::CreateChannel( worker, GetCredentialsProvider()->GetChannelCredentials( GetCredType(worker, per_worker_credential_types, credential_type), @@ -557,7 +557,7 @@ bool RunQuit( ChannelArguments channel_args; for (size_t i = 0; i < workers.size(); i++) { - auto stub = WorkerService::NewStub(CreateChannel( + auto stub = WorkerService::NewStub(grpc::CreateChannel( workers[i], GetCredentialsProvider()->GetChannelCredentials( GetCredType(workers[i], per_worker_credential_types, credential_type), diff --git a/test/cpp/server/server_request_call_test.cc b/test/cpp/server/server_request_call_test.cc index 9831c061766..14b735cf13d 100644 --- a/test/cpp/server/server_request_call_test.cc +++ b/test/cpp/server/server_request_call_test.cc @@ -115,7 +115,7 @@ TEST(ServerRequestCallTest, ShortDeadlineDoesNotCauseOkayFalse) { }); auto stub = testing::EchoTestService::NewStub( - CreateChannel(address, InsecureChannelCredentials())); + grpc::CreateChannel(address, InsecureChannelCredentials())); for (int i = 0; i < 100; i++) { gpr_log(GPR_INFO, "Sending %d.", i); diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc index 1d641535e29..525a5be1f33 100644 --- a/test/cpp/util/cli_call_test.cc +++ b/test/cpp/util/cli_call_test.cc @@ -75,7 +75,7 @@ class CliCallTest : public ::testing::Test { void ResetStub() { channel_ = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc index c0b999b511c..5c32198bc3a 100644 --- a/test/cpp/util/create_test_channel.cc +++ b/test/cpp/util/create_test_channel.cc @@ -34,7 +34,7 @@ class SslCredentialProvider : public testing::CredentialTypeProvider { public: std::shared_ptr GetChannelCredentials( grpc::ChannelArguments* args) override { - return SslCredentials(SslCredentialsOptions()); + return grpc::SslCredentials(SslCredentialsOptions()); } std::shared_ptr GetServerCredentials() override { return nullptr; @@ -116,7 +116,7 @@ std::shared_ptr CreateTestChannel( &channel_args); GPR_ASSERT(channel_creds != nullptr); if (creds.get()) { - channel_creds = CompositeChannelCredentials(channel_creds, creds); + channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); } return ::grpc::CreateCustomChannel(server, channel_creds, channel_args); } @@ -157,7 +157,7 @@ std::shared_ptr CreateTestChannel( const grpc::string& connect_to = server.empty() ? override_hostname : server; if (creds.get()) { - channel_creds = CompositeChannelCredentials(channel_creds, creds); + channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); } if (interceptor_creators.empty()) { return ::grpc::CreateCustomChannel(connect_to, channel_creds, @@ -222,7 +222,7 @@ std::shared_ptr CreateTestChannel( &channel_args); GPR_ASSERT(channel_creds != nullptr); if (creds.get()) { - channel_creds = CompositeChannelCredentials(channel_creds, creds); + channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); } return experimental::CreateCustomChannelWithInterceptors( server, channel_creds, channel_args, std::move(interceptor_creators)); diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index 57cdbeb7b76..e44ada46c24 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -122,7 +122,7 @@ class TestCliCredentials final : public grpc::testing::CliCredentials { return InsecureChannelCredentials(); } SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; - return SslCredentials(grpc::SslCredentialsOptions(ssl_opts)); + return grpc::SslCredentials(grpc::SslCredentialsOptions(ssl_opts)); } const grpc::string GetCredentialUsage() const override { return ""; } diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc index 49688e5cf9b..455f94e33d4 100644 --- a/test/cpp/util/test_credentials_provider.cc +++ b/test/cpp/util/test_credentials_provider.cc @@ -63,7 +63,7 @@ class DefaultCredentialsProvider : public CredentialsProvider { } else if (type == grpc::testing::kTlsCredentialsType) { SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; args->SetSslTargetNameOverride("foo.test.google.fr"); - return SslCredentials(ssl_opts); + return grpc::SslCredentials(ssl_opts); } else if (type == grpc::testing::kGoogleDefaultCredentialsType) { return grpc::GoogleDefaultCredentials(); } else { From 8d2207da4d72d9fbbf4b512484a2458722e45459 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 21 Mar 2019 17:36:19 -0700 Subject: [PATCH 1939/2143] WIP: New changes to make namespace work --- include/grpcpp/create_channel.h | 5 +++-- include/grpcpp/create_channel_impl.h | 2 +- src/cpp/client/create_channel.cc | 4 ++-- src/cpp/client/create_channel_posix.cc | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index d9d7d432c3f..b9e31a63d39 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -19,6 +19,7 @@ #ifndef GRPCPP_CREATE_CHANNEL_H #define GRPCPP_CREATE_CHANNEL_H +#include #include namespace grpc { @@ -29,9 +30,9 @@ static inline std::shared_ptr CreateChannel( return ::grpc_impl::CreateChannelImpl(target, creds); } -static inline std::shared_ptr CreateCustomChannel( +static inline std::shared_ptr<::grpc::Channel> CreateCustomChannel( const grpc::string& target, - const std::shared_ptr& creds, + const std::shared_ptr& creds, const ChannelArguments& args) { return ::grpc_impl::CreateCustomChannelImpl(target, creds, args); } diff --git a/include/grpcpp/create_channel_impl.h b/include/grpcpp/create_channel_impl.h index 84dd2f7c765..e44a82b1426 100644 --- a/include/grpcpp/create_channel_impl.h +++ b/include/grpcpp/create_channel_impl.h @@ -49,7 +49,7 @@ std::shared_ptr CreateChannelImpl( /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannelImpl( +std::shared_ptr CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index c217dccac9c..bafdcec99a1 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -19,9 +19,9 @@ #include #include -#include -#include +#include #include +#include #include #include "src/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 6de373577eb..8f74794de79 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include "src/cpp/client/create_channel_internal.h" From e57182ab6160a6dbb7f76730b177b55a1e44cfbe Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 22 Mar 2019 14:15:36 -0700 Subject: [PATCH 1940/2143] Fix the compile errors for tests and namespace. --- include/grpcpp/security/credentials_impl.h | 4 ++-- test/cpp/util/grpc_tool.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index 8ec339639b5..a42dbabb155 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -44,7 +44,7 @@ class CallCredentials; class SecureCallCredentials; class SecureChannelCredentials; -std::shared_ptr CreateCustomChannel( +std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); @@ -78,7 +78,7 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr CreateCustomChannel( + friend std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc index 44b14bf617f..54ac8d2a884 100644 --- a/test/cpp/util/grpc_tool.cc +++ b/test/cpp/util/grpc_tool.cc @@ -217,7 +217,7 @@ std::shared_ptr CreateCliChannel( if (!cred.GetSslTargetNameOverride().empty()) { args.SetSslTargetNameOverride(cred.GetSslTargetNameOverride()); } - return grpc::CreateCustomChannel(server_address, cred.GetCredentials(), args); + return CreateCustomChannel(server_address, cred.GetCredentials(), args); } struct Command { From 60bdeef9f4377d328c62c2b79ecdf3ed0fcdb720 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 22 Mar 2019 15:09:30 -0700 Subject: [PATCH 1941/2143] Move Channel also to impl for now --- include/grpcpp/create_channel.h | 2 +- include/grpcpp/impl/codegen/client_context.h | 3 +- include/grpcpp/security/credentials.h | 41 +++++++++++-------- include/grpcpp/security/credentials_impl.h | 12 +++--- src/cpp/client/create_channel.cc | 2 +- src/cpp/client/create_channel_posix.cc | 2 +- src/cpp/client/credentials_cc.cc | 2 +- src/cpp/client/insecure_credentials.cc | 11 ++--- src/cpp/client/secure_credentials.cc | 10 ++--- src/cpp/client/secure_credentials.h | 8 ++-- test/cpp/end2end/end2end_test.cc | 33 ++++++++------- test/cpp/end2end/filter_end2end_test.cc | 4 +- test/cpp/end2end/generic_end2end_test.cc | 4 +- .../end2end/health_service_end2end_test.cc | 4 +- test/cpp/end2end/hybrid_end2end_test.cc | 10 ++--- test/cpp/end2end/mock_test.cc | 4 +- test/cpp/end2end/server_early_return_test.cc | 4 +- .../server_interceptors_end2end_test.cc | 21 ++++++---- test/cpp/end2end/streaming_throughput_test.cc | 4 +- test/cpp/end2end/thread_stress_test.cc | 4 +- test/cpp/util/cli_call_test.cc | 4 +- 21 files changed, 102 insertions(+), 87 deletions(-) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index b9e31a63d39..19a73563298 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -19,8 +19,8 @@ #ifndef GRPCPP_CREATE_CHANNEL_H #define GRPCPP_CREATE_CHANNEL_H -#include #include +#include namespace grpc { diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index f5bcdfa5403..7326648b46f 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -309,7 +309,8 @@ class ClientContext { /// call. /// /// \see https://grpc.io/docs/guides/auth.html - void set_credentials(const std::shared_ptr& creds) { + void set_credentials( + const std::shared_ptr& creds) { creds_ = creds; } diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 8c99aab6c59..8755d8384e3 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -30,7 +30,8 @@ typedef ::grpc_impl::SslCredentialsOptions SslCredentialsOptions; typedef ::grpc_impl::SecureCallCredentials SecureCallCredentials; typedef ::grpc_impl::SecureChannelCredentials SecureChannelCredentials; -static inline std::shared_ptr GoogleDefaultCredentials() { +static inline std::shared_ptr +GoogleDefaultCredentials() { return ::grpc_impl::GoogleDefaultCredentials(); } @@ -39,30 +40,34 @@ static inline std::shared_ptr SslCredentials( return ::grpc_impl::SslCredentials(options); } -static inline std::shared_ptr GoogleComputeEngineCredentials() { +static inline std::shared_ptr +GoogleComputeEngineCredentials() { return ::grpc_impl::GoogleComputeEngineCredentials(); } -static inline std::shared_ptr ServiceAccountJWTAccessCredentials( +static inline std::shared_ptr +ServiceAccountJWTAccessCredentials( const grpc::string& json_key, long token_lifetime_seconds = ::grpc_impl::kMaxAuthTokenLifetimeSecs) { - return ::grpc_impl::ServiceAccountJWTAccessCredentials(json_key, token_lifetime_seconds); + return ::grpc_impl::ServiceAccountJWTAccessCredentials( + json_key, token_lifetime_seconds); } -static inline std::shared_ptr GoogleRefreshTokenCredentials( - const grpc::string& json_refresh_token) { +static inline std::shared_ptr +GoogleRefreshTokenCredentials(const grpc::string& json_refresh_token) { return ::grpc_impl::GoogleRefreshTokenCredentials(json_refresh_token); } -static inline std::shared_ptr AccessTokenCredentials( - const grpc::string& access_token) { +static inline std::shared_ptr +AccessTokenCredentials(const grpc::string& access_token) { return ::grpc_impl::AccessTokenCredentials(access_token); } static inline std::shared_ptr GoogleIAMCredentials( const grpc::string& authorization_token, const grpc::string& authority_selector) { - return ::grpc_impl::GoogleIAMCredentials(authorization_token, authority_selector); + return ::grpc_impl::GoogleIAMCredentials(authorization_token, + authority_selector); } static inline std::shared_ptr CompositeChannelCredentials( @@ -71,30 +76,34 @@ static inline std::shared_ptr CompositeChannelCredentials( return ::grpc_impl::CompositeChannelCredentials(channel_creds, call_creds); } -static inline std::shared_ptr CompositeCallCredentials( - const std::shared_ptr& creds1, - const std::shared_ptr& creds2) { +static inline std::shared_ptr +CompositeCallCredentials(const std::shared_ptr& creds1, + const std::shared_ptr& creds2) { return ::grpc_impl::CompositeCallCredentials(creds1, creds2); } -static inline std::shared_ptr InsecureChannelCredentials() { +static inline std::shared_ptr +InsecureChannelCredentials() { return ::grpc_impl::InsecureChannelCredentials(); } -static inline std::shared_ptr CronetChannelCredentials(void* engine) { +static inline std::shared_ptr +CronetChannelCredentials(void* engine) { return ::grpc_impl::CronetChannelCredentials(engine); } typedef ::grpc_impl::MetadataCredentialsPlugin MetadataCredentialsPlugin; -static inline std::shared_ptr MetadataCredentialsFromPlugin( +static inline std::shared_ptr +MetadataCredentialsFromPlugin( std::unique_ptr plugin) { return ::grpc_impl::MetadataCredentialsFromPlugin(std::move(plugin)); } namespace experimental { -typedef ::grpc_impl::experimental::AltsCredentialsOptions AltsCredentialsOptions; +typedef ::grpc_impl::experimental::AltsCredentialsOptions + AltsCredentialsOptions; static inline std::shared_ptr AltsCredentials( const AltsCredentialsOptions& options) { diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index a42dbabb155..843b0e2f58e 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -88,19 +88,19 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args, - std::vector< - std::unique_ptr> + std::vector> interceptor_creators); - virtual std::shared_ptr CreateChannel( + virtual std::shared_ptr CreateChannelImpl( const grpc::string& target, const grpc::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( const grpc::string& target, const grpc::ChannelArguments& args, - std::vector< - std::unique_ptr> + std::vector> interceptor_creators) { return nullptr; } @@ -280,6 +280,6 @@ std::shared_ptr LocalCredentials( grpc_local_connect_type type); } // namespace experimental -} // namespace grpc +} // namespace grpc_impl #endif // GRPCPP_SECURITY_CREDENTIALS_H diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index bafdcec99a1..ca7038b8893 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -20,8 +20,8 @@ #include #include -#include #include +#include #include #include "src/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 8f74794de79..54b7148865b 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -19,8 +19,8 @@ #include #include #include -#include #include +#include #include "src/cpp/client/create_channel_internal.h" diff --git a/src/cpp/client/credentials_cc.cc b/src/cpp/client/credentials_cc.cc index 4377be0f2d7..62334bd9eba 100644 --- a/src/cpp/client/credentials_cc.cc +++ b/src/cpp/client/credentials_cc.cc @@ -30,4 +30,4 @@ CallCredentials::CallCredentials() { g_gli_initializer.summon(); } CallCredentials::~CallCredentials() {} -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 275c42ab74b..3a6b1aa6e05 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -31,13 +31,8 @@ namespace grpc_impl { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: -<<<<<<< HEAD std::shared_ptr CreateChannelImpl( - const string& target, const grpc::ChannelArguments& args) override { -======= - std::shared_ptr CreateChannel( const grpc::string& target, const grpc::ChannelArguments& args) override { ->>>>>>> Changes to fold credentials into grpc_impl from grpc return CreateChannelWithInterceptors( target, args, std::vector CreateChannelWithInterceptors( const grpc::string& target, const grpc::ChannelArguments& args, - std::vector< - std::unique_ptr> + std::vector> interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); @@ -66,4 +61,4 @@ std::shared_ptr InsecureChannelCredentials() { new InsecureChannelCredentialsImpl()); } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index e91f7e6b477..71ad5a73c3b 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -35,11 +35,11 @@ SecureChannelCredentials::SecureChannelCredentials( } std::shared_ptr SecureChannelCredentials::CreateChannelImpl( - const string& target, const grpc::ChannelArguments& args) { + const grpc::string& target, const grpc::ChannelArguments& args) { return CreateChannelWithInterceptors( target, args, - std::vector< - std::unique_ptr>()); + std::vector>()); } std::shared_ptr @@ -220,7 +220,7 @@ std::shared_ptr MetadataCredentialsFromPlugin( grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); } -} // namespace grpc_impl +} // namespace grpc_impl namespace grpc { @@ -325,4 +325,4 @@ MetadataCredentialsPluginWrapper::MetadataCredentialsPluginWrapper( std::unique_ptr plugin) : thread_pool_(CreateDefaultThreadPool()), plugin_(std::move(plugin)) {} -} // namespace grpc_impl +} // namespace grpc diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 4e9f121d2ce..1dc083fa0cf 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -38,15 +38,15 @@ class SecureChannelCredentials final : public ChannelCredentials { grpc_channel_credentials* GetRawCreds() { return c_creds_; } std::shared_ptr CreateChannelImpl( - const string& target, const grpc::ChannelArguments& args) override; + const grpc::string& target, const grpc::ChannelArguments& args) override; SecureChannelCredentials* AsSecureCredentials() override { return this; } private: std::shared_ptr CreateChannelWithInterceptors( const grpc::string& target, const grpc::ChannelArguments& args, - std::vector< - std::unique_ptr> + std::vector> interceptor_creators) override; grpc_channel_credentials* const c_creds_; }; @@ -66,7 +66,7 @@ class SecureCallCredentials final : public CallCredentials { grpc_call_credentials* const c_creds_; }; -} // namespace grpc_impl +} // namespace grpc_impl namespace grpc { diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 8438d57b643..a359701f7ab 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -374,7 +374,8 @@ class End2endTest : public ::testing::TestWithParam { proxy_server_ = builder.BuildAndStart(); - channel_ = grpc::CreateChannel(proxyaddr.str(), InsecureChannelCredentials()); + channel_ = + grpc::CreateChannel(proxyaddr.str(), InsecureChannelCredentials()); } stub_ = grpc::testing::EchoTestService::NewStub(channel_); @@ -1825,8 +1826,8 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) { EchoRequest request; EchoResponse response; ClientContext context; - context.set_credentials( - grpc::MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kBadMetadataKey, "Does not matter, will fail the key is invalid.", false, true)))); @@ -1843,8 +1844,8 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { EchoRequest request; EchoResponse response; ClientContext context; - context.set_credentials( - grpc::MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "With illegal \n value.", false, true)))); @@ -1861,8 +1862,8 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { EchoRequest request; EchoResponse response; ClientContext context; - context.set_credentials( - grpc::MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Does not matter, will fail anyway (see 3rd param)", false, @@ -1925,8 +1926,8 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { EchoRequest request; EchoResponse response; ClientContext context; - context.set_credentials( - grpc::MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Does not matter, will fail anyway (see 3rd param)", true, @@ -1953,12 +1954,14 @@ TEST_P(SecureEnd2endTest, CompositeCallCreds) { const char kMetadataVal2[] = "call-creds-val2"; context.set_credentials(grpc::CompositeCallCredentials( - grpc::MetadataCredentialsFromPlugin(std::unique_ptr( - new TestMetadataCredentialsPlugin(kMetadataKey1, kMetadataVal1, true, - true))), - grpc::MetadataCredentialsFromPlugin(std::unique_ptr( - new TestMetadataCredentialsPlugin(kMetadataKey2, kMetadataVal2, true, - true))))); + grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( + new TestMetadataCredentialsPlugin(kMetadataKey1, kMetadataVal1, + true, true))), + grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( + new TestMetadataCredentialsPlugin(kMetadataKey2, kMetadataVal2, + true, true))))); request.set_message("Hello"); request.mutable_param()->set_echo_metadata(true); diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index a1d95644635..a4c981a3eb1 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -146,8 +146,8 @@ class FilterEnd2endTest : public ::testing::Test { } void ResetStub() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); generic_stub_.reset(new GenericStub(channel)); ResetConnectionCounter(); ResetCallCounter(); diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index 0ea7deb9409..c2807310aa4 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -90,8 +90,8 @@ class GenericEnd2endTest : public ::testing::Test { } void ResetStub() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); generic_stub_.reset(new GenericStub(channel)); } diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index 0b85c62c8c4..13d5ea55c15 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -124,8 +124,8 @@ class HealthServiceEnd2endTest : public ::testing::Test { } void ResetStubs() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); hc_stub_ = grpc::health::v1::Health::NewStub(channel); } diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc index dbd078c2d99..75001f0ab27 100644 --- a/test/cpp/end2end/hybrid_end2end_test.cc +++ b/test/cpp/end2end/hybrid_end2end_test.cc @@ -297,7 +297,7 @@ class HybridEnd2endTest : public ::testing::TestWithParam { std::shared_ptr channel = inproc_ ? server_->InProcessChannel(ChannelArguments()) : grpc::CreateChannel(server_address_.str(), - InsecureChannelCredentials()); + InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -321,8 +321,8 @@ class HybridEnd2endTest : public ::testing::TestWithParam { } void SendEchoToDupService() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel); EchoRequest send_request; EchoResponse recv_response; @@ -373,8 +373,8 @@ class HybridEnd2endTest : public ::testing::TestWithParam { } void SendSimpleServerStreamingToDupService() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel); EchoRequest request; EchoResponse response; diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc index e25286b8b64..0196c9de7e0 100644 --- a/test/cpp/end2end/mock_test.cc +++ b/test/cpp/end2end/mock_test.cc @@ -244,8 +244,8 @@ class MockTest : public ::testing::Test { void TearDown() override { server_->Shutdown(); } void ResetStub() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/server_early_return_test.cc b/test/cpp/end2end/server_early_return_test.cc index fc3ce097b6f..6f35c3e7d93 100644 --- a/test/cpp/end2end/server_early_return_test.cc +++ b/test/cpp/end2end/server_early_return_test.cc @@ -122,8 +122,8 @@ class ServerEarlyReturnTest : public ::testing::Test { builder.RegisterService(&service_); server_ = builder.BuildAndStart(); - channel_ = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + channel_ = grpc::CreateChannel(server_address_.str(), + InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index db7712b6c99..68103f7ed34 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -265,7 +265,8 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { TEST_F(ServerInterceptorsEnd2endSyncUnaryTest, UnaryTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -308,7 +309,8 @@ class ServerInterceptorsEnd2endSyncStreamingTest : public ::testing::Test { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ClientStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeClientStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -317,7 +319,8 @@ TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ClientStreamingTest) { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ServerStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeServerStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -326,7 +329,8 @@ TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ServerStreamingTest) { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, BidiStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeBidiStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -356,7 +360,8 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, UnaryTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = grpc::CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address, InsecureChannelCredentials()); auto stub = grpc::testing::EchoTestService::NewStub(channel); EchoRequest send_request; @@ -428,7 +433,8 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, BidiStreamingTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = grpc::CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address, InsecureChannelCredentials()); auto stub = grpc::testing::EchoTestService::NewStub(channel); EchoRequest send_request; @@ -509,7 +515,8 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = grpc::CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address, InsecureChannelCredentials()); GenericStub generic_stub(channel); const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo"); diff --git a/test/cpp/end2end/streaming_throughput_test.cc b/test/cpp/end2end/streaming_throughput_test.cc index a604ffdfbd8..0c10957eb77 100644 --- a/test/cpp/end2end/streaming_throughput_test.cc +++ b/test/cpp/end2end/streaming_throughput_test.cc @@ -145,8 +145,8 @@ class End2endTest : public ::testing::Test { void TearDown() override { server_->Shutdown(); } void ResetStub() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index d2eca091149..eb8e7958b4b 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -96,8 +96,8 @@ template class CommonStressTestInsecure : public CommonStressTest { public: void ResetStub() override { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); this->stub_ = grpc::testing::EchoTestService::NewStub(channel); } bool AllowExhaustion() override { return false; } diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc index 525a5be1f33..a91705bd514 100644 --- a/test/cpp/util/cli_call_test.cc +++ b/test/cpp/util/cli_call_test.cc @@ -74,8 +74,8 @@ class CliCallTest : public ::testing::Test { void TearDown() override { server_->Shutdown(); } void ResetStub() { - channel_ = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + channel_ = grpc::CreateChannel(server_address_.str(), + InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } From be9479542c8862d7c92e73e6f1af908f9021b07a Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 29 Mar 2019 08:28:55 -0700 Subject: [PATCH 1942/2143] Fix include header issue --- include/grpcpp/security/credentials_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index 843b0e2f58e..49f7293a40a 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -282,4 +282,4 @@ std::shared_ptr LocalCredentials( } // namespace experimental } // namespace grpc_impl -#endif // GRPCPP_SECURITY_CREDENTIALS_H +#endif // GRPCPP_SECURITY_CREDENTIALS_IMPL_H From 2049b6c2bd7021676193ecd5734e86bd257ffe98 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 9 Apr 2019 14:27:23 -0700 Subject: [PATCH 1943/2143] Fix build errors --- include/grpcpp/security/credentials.h | 1 - include/grpcpp/security/credentials_impl.h | 14 +++++++------- src/cpp/client/insecure_credentials.cc | 2 +- src/cpp/client/secure_credentials.cc | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 8755d8384e3..5eb77096bd0 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -22,7 +22,6 @@ #include namespace grpc { -class Channel; typedef ::grpc_impl::ChannelCredentials ChannelCredentials; typedef ::grpc_impl::CallCredentials CallCredentials; diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index 49f7293a40a..a54519f358a 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -34,23 +34,23 @@ struct grpc_call; namespace grpc { class ChannelArguments; -class Channel; } // namespace grpc namespace grpc_impl { +class Channel; class ChannelCredentials; class CallCredentials; class SecureCallCredentials; class SecureChannelCredentials; -std::shared_ptr CreateCustomChannelImpl( +std::shared_ptr CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); namespace experimental { -std::shared_ptr CreateCustomChannelWithInterceptors( +std::shared_ptr CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args, @@ -78,12 +78,12 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr CreateCustomChannelImpl( + friend std::shared_ptr CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); - friend std::shared_ptr + friend std::shared_ptr grpc_impl::experimental::CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, @@ -92,12 +92,12 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators); - virtual std::shared_ptr CreateChannelImpl( + virtual std::shared_ptr CreateChannel( const grpc::string& target, const grpc::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 CreateChannelWithInterceptors( const grpc::string& target, const grpc::ChannelArguments& args, std::vector> diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 3a6b1aa6e05..fca757b66c8 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -31,7 +31,7 @@ namespace grpc_impl { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: - std::shared_ptr CreateChannelImpl( + std::shared_ptr CreateChannel( const grpc::string& target, const grpc::ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 71ad5a73c3b..df0f48df198 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -34,7 +34,7 @@ SecureChannelCredentials::SecureChannelCredentials( g_gli_initializer.summon(); } -std::shared_ptr SecureChannelCredentials::CreateChannelImpl( +std::shared_ptr SecureChannelCredentials::CreateChannel( const grpc::string& target, const grpc::ChannelArguments& args) { return CreateChannelWithInterceptors( target, args, From df2c2c114c07c36c9d161395f00f57b612019ccd Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 23 Apr 2019 13:36:04 -0700 Subject: [PATCH 1944/2143] Fix access to some CreateChannel/CreateCustomChannel methods --- include/grpcpp/create_channel.h | 4 ++-- include/grpcpp/security/credentials_impl.h | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index 19a73563298..2d5b85aa819 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -24,7 +24,7 @@ namespace grpc { -static inline std::shared_ptr CreateChannel( +static inline std::shared_ptr<::grpc::Channel> CreateChannel( const grpc::string& target, const std::shared_ptr& creds) { return ::grpc_impl::CreateChannelImpl(target, creds); @@ -39,7 +39,7 @@ static inline std::shared_ptr<::grpc::Channel> CreateCustomChannel( namespace experimental { -static inline std::shared_ptr CreateCustomChannelWithInterceptors( +static inline std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args, diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index a54519f358a..e233041afc3 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -44,13 +44,13 @@ class CallCredentials; class SecureCallCredentials; class SecureChannelCredentials; -std::shared_ptr CreateCustomChannel( +std::shared_ptr<::grpc::Channel> CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); namespace experimental { -std::shared_ptr CreateCustomChannelWithInterceptors( +std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args, @@ -78,12 +78,12 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr CreateCustomChannel( + friend std::shared_ptr<::grpc::Channel> CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); - friend std::shared_ptr + friend std::shared_ptr<::grpc::Channel> grpc_impl::experimental::CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, @@ -92,12 +92,12 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators); - virtual std::shared_ptr CreateChannel( + virtual std::shared_ptr<::grpc::Channel> CreateChannel( const grpc::string& target, const grpc::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::Channel> CreateChannelWithInterceptors( const grpc::string& target, const grpc::ChannelArguments& args, std::vector> From d20d46e9769dc28771a03988513e9532f70d3f1d Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Thu, 4 Apr 2019 13:53:02 -0700 Subject: [PATCH 1945/2143] Add C++ stress tests on mac --- test/cpp/end2end/cfstream_test.cc | 89 ++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 26 deletions(-) diff --git a/test/cpp/end2end/cfstream_test.cc b/test/cpp/end2end/cfstream_test.cc index 63d76e96f8b..59cf98ffc20 100644 --- a/test/cpp/end2end/cfstream_test.cc +++ b/test/cpp/end2end/cfstream_test.cc @@ -45,6 +45,7 @@ #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/test_credentials_provider.h" #ifdef GRPC_CFSTREAM using grpc::ClientAsyncResponseReader; @@ -57,13 +58,19 @@ namespace grpc { namespace testing { namespace { -class CFStreamTest : public ::testing::Test { +struct TestScenario { + TestScenario(const grpc::string& creds_type, const grpc::string& content) + : credentials_type(creds_type), message_content(content) {} + const grpc::string credentials_type; + const grpc::string message_content; +}; + +class CFStreamTest : public ::testing::TestWithParam { protected: CFStreamTest() : server_host_("grpctest"), interface_("lo0"), - ipv4_address_("10.0.0.1"), - kRequestMessage_("🖖") {} + ipv4_address_("10.0.0.1") {} void DNSUp() { std::ostringstream cmd; @@ -118,7 +125,7 @@ class CFStreamTest : public ::testing::Test { void StartServer() { port_ = grpc_pick_unused_port_or_die(); - server_.reset(new ServerData(port_)); + server_.reset(new ServerData(port_, GetParam().credentials_type)); server_->Start(server_host_); } void StopServer() { server_->Shutdown(); } @@ -131,8 +138,10 @@ class CFStreamTest : public ::testing::Test { std::shared_ptr BuildChannel() { std::ostringstream server_address; server_address << server_host_ << ":" << port_; - return CreateCustomChannel( - server_address.str(), InsecureChannelCredentials(), ChannelArguments()); + ChannelArguments args; + auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( + GetParam().credentials_type, &args); + return CreateCustomChannel(server_address.str(), channel_creds, args); } void SendRpc( @@ -140,11 +149,12 @@ class CFStreamTest : public ::testing::Test { bool expect_success = false) { auto response = std::unique_ptr(new EchoResponse()); EchoRequest request; - request.set_message(kRequestMessage_); + auto& msg = GetParam().message_content; + request.set_message(msg); 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()); + EXPECT_EQ(msg, response->message()); } else { gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); } @@ -156,9 +166,7 @@ class CFStreamTest : public ::testing::Test { const std::unique_ptr& stub, RequestParams param = RequestParams()) { EchoRequest request; - auto msg = std::to_string(ctr.load()); - request.set_message(msg); - ctr++; + request.set_message(GetParam().message_content); *request.mutable_param() = std::move(param); AsyncClientCall* call = new AsyncClientCall; @@ -166,7 +174,6 @@ class CFStreamTest : public ::testing::Test { 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); } @@ -206,12 +213,14 @@ class CFStreamTest : public ::testing::Test { private: struct ServerData { int port_; + const grpc::string creds_; std::unique_ptr server_; TestServiceImpl service_; std::unique_ptr thread_; bool server_ready_ = false; - explicit ServerData(int port) { port_ = port; } + ServerData(int port, const grpc::string& creds) + : port_(port), creds_(creds) {} void Start(const grpc::string& server_host) { gpr_log(GPR_INFO, "starting server on port %d", port_); @@ -230,8 +239,9 @@ class CFStreamTest : public ::testing::Test { std::ostringstream server_address; server_address << server_host << ":" << port_; ServerBuilder builder; - builder.AddListeningPort(server_address.str(), - InsecureServerCredentials()); + auto server_creds = + GetCredentialsProvider()->GetServerCredentials(creds_); + builder.AddListeningPort(server_address.str(), server_creds); builder.RegisterService(&service_); server_ = builder.BuildAndStart(); std::lock_guard lock(*mu); @@ -251,13 +261,44 @@ class CFStreamTest : public ::testing::Test { const grpc::string ipv4_address_; std::unique_ptr server_; int port_; - const grpc::string kRequestMessage_; - std::atomic_int ctr{0}; }; +std::vector CreateTestScenarios() { + std::vector scenarios; + std::vector credentials_types; + std::vector messages; + + credentials_types.push_back(kInsecureCredentialsType); + auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList(); + for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) { + credentials_types.push_back(*sec); + } + + messages.push_back("🖖"); + for (size_t k = 1; k < GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH / 1024; k *= 32) { + grpc::string big_msg; + for (size_t i = 0; i < k * 1024; ++i) { + char c = 'a' + (i % 26); + big_msg += c; + } + messages.push_back(big_msg); + } + for (auto cred = credentials_types.begin(); cred != credentials_types.end(); + ++cred) { + for (auto msg = messages.begin(); msg != messages.end(); msg++) { + scenarios.emplace_back(*cred, *msg); + } + } + + return scenarios; +} + +INSTANTIATE_TEST_CASE_P(CFStreamTest, CFStreamTest, + ::testing::ValuesIn(CreateTestScenarios())); + // gRPC should automatically detech network flaps (without enabling keepalives) // when CFStream is enabled -TEST_F(CFStreamTest, NetworkTransition) { +TEST_P(CFStreamTest, NetworkTransition) { auto channel = BuildChannel(); auto stub = BuildStub(channel); // Channel should be in READY state after we send an RPC @@ -293,7 +334,7 @@ TEST_F(CFStreamTest, NetworkTransition) { } // Network flaps while RPCs are in flight -TEST_F(CFStreamTest, NetworkFlapRpcsInFlight) { +TEST_P(CFStreamTest, NetworkFlapRpcsInFlight) { auto channel = BuildChannel(); auto stub = BuildStub(channel); std::atomic_int rpcs_sent{0}; @@ -318,9 +359,7 @@ TEST_F(CFStreamTest, NetworkFlapRpcsInFlight) { ++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 { + if (!call->status.ok()) { gpr_log(GPR_DEBUG, "RPC failed with error: %s", call->status.error_message().c_str()); // Bring network up when RPCs start failing @@ -347,7 +386,7 @@ TEST_F(CFStreamTest, NetworkFlapRpcsInFlight) { // 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) { +TEST_P(CFStreamTest, ConcurrentRpc) { auto channel = BuildChannel(); auto stub = BuildStub(channel); std::atomic_int rpcs_sent{0}; @@ -361,9 +400,7 @@ TEST_F(CFStreamTest, ConcurrentRpc) { ++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 { + if (!call->status.ok()) { gpr_log(GPR_DEBUG, "RPC failed: %s", call->status.error_message().c_str()); // Bring network up when RPCs start failing From f36e08e6dd5a5a463968b70649121495155f49c1 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Thu, 18 Apr 2019 13:48:24 -0700 Subject: [PATCH 1946/2143] Add trace flag in cronet transport --- doc/environment_variables.md | 1 + .../transport/cronet/transport/cronet_transport.cc | 11 +++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index 43dcd7616e7..778560d4273 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -50,6 +50,7 @@ some configuration as environment variables that can be set. resolver and load balancing policy interaction - compression - traces compression operations - connectivity_state - traces connectivity state changes to channels + - cronet - traces state in the cronet transport engine - executor - traces grpc's internal thread pool ('the executor') - fd_trace - traces fd create(), shutdown() and close() calls for channel fds. Also traces epoll fd create()/close() calls in epollex polling engine diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 76a32dc4049..e962be554c0 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -29,6 +29,7 @@ #include "src/core/ext/transport/chttp2/transport/bin_encoder.h" #include "src/core/ext/transport/chttp2/transport/incoming_metadata.h" #include "src/core/ext/transport/cronet/transport/cronet_transport.h" +#include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" @@ -45,14 +46,12 @@ #define GRPC_HEADER_SIZE_IN_BYTES 5 #define GRPC_FLUSH_READ_SIZE 4096 -#define CRONET_LOG(...) \ - do { \ - if (grpc_cronet_trace) gpr_log(__VA_ARGS__); \ +grpc_core::TraceFlag grpc_cronet_trace(false, "cronet"); +#define CRONET_LOG(...) \ + do { \ + if (grpc_cronet_trace.enabled()) gpr_log(__VA_ARGS__); \ } while (0) -/* TODO (makdharma): Hook up into the wider tracing mechanism */ -int grpc_cronet_trace = 0; - enum e_op_result { ACTION_TAKEN_WITH_CALLBACK, ACTION_TAKEN_NO_CALLBACK, From 5274deb32bc6f8ec064c3ce8ad1e84a067db2652 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 23 Apr 2019 14:11:23 -0700 Subject: [PATCH 1947/2143] Fix the rebase and build --- include/grpcpp/create_channel.h | 3 ++- include/grpcpp/create_channel_impl.h | 2 +- include/grpcpp/security/credentials_impl.h | 9 +++------ include/grpcpp/support/channel_arguments_impl.h | 5 ++--- src/cpp/client/insecure_credentials.cc | 2 +- src/cpp/client/secure_credentials.cc | 2 +- test/cpp/util/grpc_tool.cc | 3 ++- 7 files changed, 12 insertions(+), 14 deletions(-) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index 2d5b85aa819..e7336cb2adf 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -39,7 +39,8 @@ static inline std::shared_ptr<::grpc::Channel> CreateCustomChannel( namespace experimental { -static inline std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors( +static inline std::shared_ptr<::grpc::Channel> +CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args, diff --git a/include/grpcpp/create_channel_impl.h b/include/grpcpp/create_channel_impl.h index e44a82b1426..84dd2f7c765 100644 --- a/include/grpcpp/create_channel_impl.h +++ b/include/grpcpp/create_channel_impl.h @@ -49,7 +49,7 @@ std::shared_ptr CreateChannelImpl( /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannel( +std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index e233041afc3..19017093dd5 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -27,15 +27,12 @@ #include #include #include +#include #include #include struct grpc_call; -namespace grpc { -class ChannelArguments; -} // namespace grpc - namespace grpc_impl { class Channel; @@ -78,7 +75,7 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr<::grpc::Channel> CreateCustomChannel( + friend std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); @@ -92,7 +89,7 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators); - virtual std::shared_ptr<::grpc::Channel> CreateChannel( + virtual std::shared_ptr<::grpc::Channel> CreateChannelImpl( const grpc::string& target, const grpc::ChannelArguments& args) = 0; // This function should have been a pure virtual function, but it is diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h index 8276c1d9099..db85e9b07ad 100644 --- a/include/grpcpp/support/channel_arguments_impl.h +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -31,11 +31,10 @@ namespace grpc { namespace testing { class ChannelArgumentsTest; } // namespace testing - -class SecureChannelCredentials; } // namespace grpc namespace grpc_impl { +class SecureChannelCredentials; /// 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, @@ -126,7 +125,7 @@ class ChannelArguments { } private: - friend class grpc::SecureChannelCredentials; + friend class grpc_impl::SecureChannelCredentials; friend class grpc::testing::ChannelArgumentsTest; /// Default pointer argument operations. diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index fca757b66c8..3a6b1aa6e05 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -31,7 +31,7 @@ namespace grpc_impl { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: - std::shared_ptr CreateChannel( + std::shared_ptr CreateChannelImpl( const grpc::string& target, const grpc::ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index df0f48df198..71ad5a73c3b 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -34,7 +34,7 @@ SecureChannelCredentials::SecureChannelCredentials( g_gli_initializer.summon(); } -std::shared_ptr SecureChannelCredentials::CreateChannel( +std::shared_ptr SecureChannelCredentials::CreateChannelImpl( const grpc::string& target, const grpc::ChannelArguments& args) { return CreateChannelWithInterceptors( target, args, diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc index 54ac8d2a884..dbac31170f0 100644 --- a/test/cpp/util/grpc_tool.cc +++ b/test/cpp/util/grpc_tool.cc @@ -217,7 +217,8 @@ std::shared_ptr CreateCliChannel( if (!cred.GetSslTargetNameOverride().empty()) { args.SetSslTargetNameOverride(cred.GetSslTargetNameOverride()); } - return CreateCustomChannel(server_address, cred.GetCredentials(), args); + return ::grpc::CreateCustomChannel(server_address, cred.GetCredentials(), + args); } struct Command { From 87d0c8b377de0369401ccf646406e1e7d61068fa Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Thu, 18 Apr 2019 17:05:09 -0700 Subject: [PATCH 1948/2143] Added visual studio code files to .gitignore Let git ignore the local artifacts created by visual studio code. Reference: https://www.gitignore.io/api/visualstudiocode Deleted unncessary .vscode/launch.json --- .gitignore | 8 ++++++++ .vscode/launch.json | 30 ------------------------------ 2 files changed, 8 insertions(+), 30 deletions(-) delete mode 100644 .vscode/launch.json diff --git a/.gitignore b/.gitignore index cde82bc3d36..0d2647e61b6 100644 --- a/.gitignore +++ b/.gitignore @@ -134,3 +134,11 @@ bm_*.json # cmake build files /cmake/build + +# Visual Studio Code artifacts +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 700c61cceae..00000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "type": "node", - "request": "launch", - "name": "Mocha Tests", - "cwd": "${workspaceRoot}", - "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha", - "windows": { - "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha.cmd" - }, - "runtimeArgs": [ - "-u", - "tdd", - "--timeout", - "999999", - "--colors", - "${workspaceRoot}/src/node/test" - ], - "internalConsoleOptions": "openOnSessionStart" - }, - { - "type": "node", - "request": "attach", - "name": "Attach to Process", - "port": 5858 - } - ] -} From 6ec2c6cfb98346e76f8e94b69c1f07380e7e7f61 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 23 Apr 2019 15:25:24 -0700 Subject: [PATCH 1949/2143] Add Python/CXX/Csharp v1.20.0 to client matrix --- tools/interop_matrix/client_matrix.py | 7 +++- tools/interop_matrix/testcases/csharp__master | 2 +- .../testcases/csharpcoreclr__master | 38 +++++++++---------- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 013b9d0f1ee..36f926d491f 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -100,6 +100,7 @@ LANG_RELEASE_MATRIX = { ('v1.17.1', ReleaseInfo()), ('v1.18.0', ReleaseInfo()), ('v1.19.0', ReleaseInfo()), + ('v1.20.0', ReleaseInfo()), ]), 'go': OrderedDict([ @@ -166,6 +167,7 @@ LANG_RELEASE_MATRIX = { ('v1.17.1', ReleaseInfo(testcases_file='python__v1.11.1')), ('v1.18.0', ReleaseInfo()), ('v1.19.0', ReleaseInfo()), + ('v1.20.0', ReleaseInfo()), ]), 'node': OrderedDict([ @@ -264,7 +266,8 @@ LANG_RELEASE_MATRIX = { ('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()), - ('v1.19.0', ReleaseInfo()), + ('v1.18.0', ReleaseInfo(testcases_file='csharpcoreclr__v1.18.0')), + ('v1.19.0', ReleaseInfo(testcases_file='csharpcoreclr__v1.18.0')), + ('v1.20.0', ReleaseInfo()), ]), } diff --git a/tools/interop_matrix/testcases/csharp__master b/tools/interop_matrix/testcases/csharp__master index 9f1cd05b177..e526b3c1cfd 100755 --- a/tools/interop_matrix/testcases/csharp__master +++ b/tools/interop_matrix/testcases/csharp__master @@ -1,7 +1,7 @@ #!/bin/bash # 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}" +echo "Testing ${docker_image:=grpc_interop_csharp:9296f21a-f657-4bb0-82a7-24fc527abcbd}" 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" diff --git a/tools/interop_matrix/testcases/csharpcoreclr__master b/tools/interop_matrix/testcases/csharpcoreclr__master index 3ca145e4c11..e14ec047630 100755 --- a/tools/interop_matrix/testcases/csharpcoreclr__master +++ b/tools/interop_matrix/testcases/csharpcoreclr__master @@ -1,22 +1,22 @@ #!/bin/bash # 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" +echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:33395965-11d7-4b12-bcd6-a272d4015207}" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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/netcoreapp2.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 ce3ff86763abd26e377d37798ba6e13581d413a3 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 23 Apr 2019 15:27:06 -0700 Subject: [PATCH 1950/2143] Convert call_combiner to C++. --- .../filters/client_channel/client_channel.cc | 4 +- .../health/health_check_client.cc | 18 +- .../health/health_check_client.h | 2 +- .../ext/filters/client_channel/subchannel.h | 2 +- .../ext/filters/deadline/deadline_filter.cc | 5 +- .../ext/filters/deadline/deadline_filter.h | 5 +- .../filters/http/client/http_client_filter.cc | 2 +- .../filters/http/client_authority_filter.cc | 2 +- .../message_compress_filter.cc | 2 +- .../filters/http/server/http_server_filter.cc | 2 +- .../message_size/message_size_filter.cc | 2 +- src/core/lib/channel/channel_stack.h | 2 +- src/core/lib/channel/connected_channel.cc | 4 +- src/core/lib/iomgr/call_combiner.cc | 146 ++++++++--------- src/core/lib/iomgr/call_combiner.h | 155 +++++++++--------- .../security/transport/client_auth_filter.cc | 18 +- .../security/transport/server_auth_filter.cc | 5 +- src/core/lib/surface/call.cc | 8 +- src/core/lib/surface/lame_client.cc | 2 +- src/core/lib/surface/server.cc | 2 +- src/core/lib/transport/transport.cc | 2 +- src/core/lib/transport/transport.h | 2 +- test/cpp/microbenchmarks/bm_call_create.cc | 2 +- 23 files changed, 185 insertions(+), 209 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 412ac1662b8..1e407cd0625 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -617,7 +617,7 @@ class CallData { grpc_millis deadline_; gpr_arena* arena_; grpc_call_stack* owning_call_; - grpc_call_combiner* call_combiner_; + CallCombiner* call_combiner_; grpc_call_context_element* call_context_; RefCountedPtr retry_throttle_data_; @@ -3017,7 +3017,7 @@ class CallData::QueuedPickCanceller { GRPC_CALL_STACK_REF(calld->owning_call_, "QueuedPickCanceller"); GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this, grpc_combiner_scheduler(chand->data_plane_combiner())); - grpc_call_combiner_set_notify_on_cancel(calld->call_combiner_, &closure_); + calld->call_combiner_->SetNotifyOnCancel(&closure_); } private: 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 a99f1e54062..2dab43b499f 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 @@ -37,11 +37,10 @@ #define HEALTH_CHECK_RECONNECT_MAX_BACKOFF_SECONDS 120 #define HEALTH_CHECK_RECONNECT_JITTER 0.2 -grpc_core::TraceFlag grpc_health_check_client_trace(false, - "health_check_client"); - namespace grpc_core { +TraceFlag grpc_health_check_client_trace(false, "health_check_client"); + // // HealthCheckClient // @@ -50,7 +49,7 @@ HealthCheckClient::HealthCheckClient( const char* service_name, RefCountedPtr connected_subchannel, grpc_pollset_set* interested_parties, - grpc_core::RefCountedPtr channelz_node) + RefCountedPtr channelz_node) : InternallyRefCounted(&grpc_health_check_client_trace), service_name_(service_name), connected_subchannel_(std::move(connected_subchannel)), @@ -283,9 +282,7 @@ HealthCheckClient::CallState::CallState( pollent_(grpc_polling_entity_create_from_pollset_set(interested_parties)), arena_(gpr_arena_create(health_check_client_->connected_subchannel_ ->GetInitialCallSizeEstimate(0))), - payload_(context_) { - grpc_call_combiner_init(&call_combiner_); -} + payload_(context_) {} HealthCheckClient::CallState::~CallState() { if (grpc_health_check_client_trace.enabled()) { @@ -303,14 +300,13 @@ HealthCheckClient::CallState::~CallState() { // holding to the call stack. Also flush the closures on exec_ctx so that // filters that schedule cancel notification closures on exec_ctx do not // need to take a ref of the call stack to guarantee closure liveness. - grpc_call_combiner_set_notify_on_cancel(&call_combiner_, nullptr); - grpc_core::ExecCtx::Get()->Flush(); - grpc_call_combiner_destroy(&call_combiner_); + call_combiner_.SetNotifyOnCancel(nullptr); + ExecCtx::Get()->Flush(); gpr_arena_destroy(arena_); } void HealthCheckClient::CallState::Orphan() { - grpc_call_combiner_cancel(&call_combiner_, GRPC_ERROR_CANCELLED); + call_combiner_.Cancel(GRPC_ERROR_CANCELLED); 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 6e0123e4925..1a9fe47b02b 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 @@ -98,7 +98,7 @@ class HealthCheckClient : public InternallyRefCounted { grpc_polling_entity pollent_; gpr_arena* arena_; - grpc_call_combiner call_combiner_; + grpc_core::CallCombiner call_combiner_; grpc_call_context_element context_[GRPC_CONTEXT_COUNT] = {}; // The streaming call to the backend. Always non-NULL. diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 9c2e57d3e05..52175098f61 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -77,7 +77,7 @@ class ConnectedSubchannel : public RefCounted { grpc_millis deadline; gpr_arena* arena; grpc_call_context_element* context; - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; size_t parent_data_size; }; diff --git a/src/core/ext/filters/deadline/deadline_filter.cc b/src/core/ext/filters/deadline/deadline_filter.cc index b4cb07f0f92..960641dc168 100644 --- a/src/core/ext/filters/deadline/deadline_filter.cc +++ b/src/core/ext/filters/deadline/deadline_filter.cc @@ -68,8 +68,7 @@ static void timer_callback(void* arg, grpc_error* error) { error = grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Deadline Exceeded"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_DEADLINE_EXCEEDED); - grpc_call_combiner_cancel(deadline_state->call_combiner, - GRPC_ERROR_REF(error)); + deadline_state->call_combiner->Cancel(GRPC_ERROR_REF(error)); GRPC_CLOSURE_INIT(&deadline_state->timer_callback, send_cancel_op_in_call_combiner, elem, grpc_schedule_on_exec_ctx); @@ -183,7 +182,7 @@ static void start_timer_after_init(void* arg, grpc_error* error) { grpc_deadline_state::grpc_deadline_state(grpc_call_element* elem, grpc_call_stack* call_stack, - grpc_call_combiner* call_combiner, + grpc_core::CallCombiner* call_combiner, grpc_millis deadline) : call_stack(call_stack), call_combiner(call_combiner) { // Deadline will always be infinite on servers, so the timer will only be diff --git a/src/core/ext/filters/deadline/deadline_filter.h b/src/core/ext/filters/deadline/deadline_filter.h index e37032999c6..7c4e9aaed0e 100644 --- a/src/core/ext/filters/deadline/deadline_filter.h +++ b/src/core/ext/filters/deadline/deadline_filter.h @@ -32,12 +32,13 @@ enum grpc_deadline_timer_state { // Must be the first field in the filter's call_data. struct grpc_deadline_state { grpc_deadline_state(grpc_call_element* elem, grpc_call_stack* call_stack, - grpc_call_combiner* call_combiner, grpc_millis deadline); + grpc_core::CallCombiner* call_combiner, + grpc_millis deadline); ~grpc_deadline_state(); // We take a reference to the call stack for the timer callback. grpc_call_stack* call_stack; - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; grpc_deadline_timer_state timer_state = GRPC_DEADLINE_STATE_INITIAL; grpc_timer timer; grpc_closure timer_callback; diff --git a/src/core/ext/filters/http/client/http_client_filter.cc b/src/core/ext/filters/http/client/http_client_filter.cc index bf9a01f659b..3f6d464d5dd 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -62,7 +62,7 @@ struct call_data { ~call_data() { GRPC_ERROR_UNREF(recv_initial_metadata_error); } - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; // State for handling send_initial_metadata ops. grpc_linked_mdelem method; grpc_linked_mdelem scheme; diff --git a/src/core/ext/filters/http/client_authority_filter.cc b/src/core/ext/filters/http/client_authority_filter.cc index 125059c93a9..85b30bc13ca 100644 --- a/src/core/ext/filters/http/client_authority_filter.cc +++ b/src/core/ext/filters/http/client_authority_filter.cc @@ -40,7 +40,7 @@ namespace { struct call_data { grpc_linked_mdelem authority_storage; - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; }; struct channel_data { diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.cc b/src/core/ext/filters/http/message_compress/message_compress_filter.cc index 1527ea440c4..a53d813c3f0 100644 --- a/src/core/ext/filters/http/message_compress/message_compress_filter.cc +++ b/src/core/ext/filters/http/message_compress/message_compress_filter.cc @@ -72,7 +72,7 @@ struct call_data { GRPC_ERROR_UNREF(cancel_error); } - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; grpc_linked_mdelem compression_algorithm_storage; grpc_linked_mdelem stream_compression_algorithm_storage; grpc_linked_mdelem accept_encoding_storage; diff --git a/src/core/ext/filters/http/server/http_server_filter.cc b/src/core/ext/filters/http/server/http_server_filter.cc index ce1be8370c6..a27a51a90ff 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -61,7 +61,7 @@ struct call_data { } } - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; // Outgoing headers to add to send_initial_metadata. grpc_linked_mdelem status; 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 4d120c0eb76..ec506eaae52 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -137,7 +137,7 @@ struct call_data { ~call_data() { GRPC_ERROR_UNREF(error); } - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; message_size_limits limits; // Receive closures are chained: we inject this closure as the // recv_message_ready up-call on transport_stream_op, and remember to diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 580e1e55100..d5dc418991d 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -70,7 +70,7 @@ typedef struct { gpr_timespec start_time; grpc_millis deadline; gpr_arena* arena; - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; } grpc_call_element_args; typedef struct { diff --git a/src/core/lib/channel/connected_channel.cc b/src/core/lib/channel/connected_channel.cc index e2ea334dedf..bd30c3663a2 100644 --- a/src/core/lib/channel/connected_channel.cc +++ b/src/core/lib/channel/connected_channel.cc @@ -41,12 +41,12 @@ typedef struct connected_channel_channel_data { typedef struct { grpc_closure closure; grpc_closure* original_closure; - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; const char* reason; } callback_state; typedef struct connected_channel_call_data { - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; // Closures used for returning results on the call combiner. callback_state on_complete[6]; // Max number of pending batches. callback_state recv_initial_metadata_ready; diff --git a/src/core/lib/iomgr/call_combiner.cc b/src/core/lib/iomgr/call_combiner.cc index 6b5759a036f..a245ff04874 100644 --- a/src/core/lib/iomgr/call_combiner.cc +++ b/src/core/lib/iomgr/call_combiner.cc @@ -26,23 +26,43 @@ #include "src/core/lib/debug/stats.h" #include "src/core/lib/profiling/timers.h" -grpc_core::TraceFlag grpc_call_combiner_trace(false, "call_combiner"); +namespace grpc_core { -static grpc_error* decode_cancel_state_error(gpr_atm cancel_state) { +TraceFlag grpc_call_combiner_trace(false, "call_combiner"); + +namespace { + +grpc_error* DecodeCancelStateError(gpr_atm cancel_state) { if (cancel_state & 1) { return (grpc_error*)(cancel_state & ~static_cast(1)); } return GRPC_ERROR_NONE; } -static gpr_atm encode_cancel_state_error(grpc_error* error) { +gpr_atm EncodeCancelStateError(grpc_error* error) { return static_cast(1) | (gpr_atm)error; } +} // namespace + +CallCombiner::CallCombiner() { + gpr_atm_no_barrier_store(&cancel_state_, 0); + gpr_atm_no_barrier_store(&size_, 0); + gpr_mpscq_init(&queue_); #ifdef GRPC_TSAN_ENABLED -static void tsan_closure(void* user_data, grpc_error* error) { - grpc_call_combiner* call_combiner = - static_cast(user_data); + GRPC_CLOSURE_INIT(&tsan_closure_, TsanClosure, this, + grpc_schedule_on_exec_ctx); +#endif +} + +CallCombiner::~CallCombiner() { + gpr_mpscq_destroy(&queue_); + GRPC_ERROR_UNREF(DecodeCancelStateError(cancel_state_)); +} + +#ifdef GRPC_TSAN_ENABLED +void CallCombiner::TsanClosure(void* arg, grpc_error* error) { + CallCombiner* self = static_cast(arg); // We ref-count the lock, and check if it's already taken. // If it was taken, we should do nothing. Otherwise, we will mark it as // locked. Note that if two different threads try to do this, only one of @@ -51,18 +71,18 @@ static void tsan_closure(void* user_data, grpc_error* error) { // TSAN will correctly produce an error. // // TODO(soheil): This only covers the callbacks scheduled by - // grpc_call_combiner_(start|finish). If in the future, a - // callback gets scheduled using other mechanisms, we will need - // to add APIs to externally lock call combiners. - grpc_core::RefCountedPtr lock = - call_combiner->tsan_lock; + // CallCombiner::Start() and CallCombiner::Stop(). + // If in the future, a callback gets scheduled using other + // mechanisms, we will need to add APIs to externally lock + // call combiners. + RefCountedPtr lock = self->tsan_lock_; bool prev = false; if (lock->taken.compare_exchange_strong(prev, true)) { TSAN_ANNOTATE_RWLOCK_ACQUIRED(&lock->taken, true); } else { lock.reset(); } - GRPC_CLOSURE_RUN(call_combiner->original_closure, GRPC_ERROR_REF(error)); + GRPC_CLOSURE_RUN(self->original_closure_, GRPC_ERROR_REF(error)); if (lock != nullptr) { TSAN_ANNOTATE_RWLOCK_RELEASED(&lock->taken, true); bool prev = true; @@ -71,34 +91,17 @@ static void tsan_closure(void* user_data, grpc_error* error) { } #endif -static void call_combiner_sched_closure(grpc_call_combiner* call_combiner, - grpc_closure* closure, - grpc_error* error) { +void CallCombiner::ScheduleClosure(grpc_closure* closure, grpc_error* error) { #ifdef GRPC_TSAN_ENABLED - call_combiner->original_closure = closure; - GRPC_CLOSURE_SCHED(&call_combiner->tsan_closure, error); + original_closure_ = closure; + GRPC_CLOSURE_SCHED(&tsan_closure_, error); #else GRPC_CLOSURE_SCHED(closure, error); #endif } -void grpc_call_combiner_init(grpc_call_combiner* call_combiner) { - gpr_atm_no_barrier_store(&call_combiner->cancel_state, 0); - gpr_atm_no_barrier_store(&call_combiner->size, 0); - gpr_mpscq_init(&call_combiner->queue); -#ifdef GRPC_TSAN_ENABLED - GRPC_CLOSURE_INIT(&call_combiner->tsan_closure, tsan_closure, call_combiner, - grpc_schedule_on_exec_ctx); -#endif -} - -void grpc_call_combiner_destroy(grpc_call_combiner* call_combiner) { - gpr_mpscq_destroy(&call_combiner->queue); - GRPC_ERROR_UNREF(decode_cancel_state_error(call_combiner->cancel_state)); -} - #ifndef NDEBUG -#define DEBUG_ARGS , const char *file, int line +#define DEBUG_ARGS const char *file, int line, #define DEBUG_FMT_STR "%s:%d: " #define DEBUG_FMT_ARGS , file, line #else @@ -107,20 +110,17 @@ void grpc_call_combiner_destroy(grpc_call_combiner* call_combiner) { #define DEBUG_FMT_ARGS #endif -void grpc_call_combiner_start(grpc_call_combiner* call_combiner, - grpc_closure* closure, - grpc_error* error DEBUG_ARGS, - const char* reason) { - GPR_TIMER_SCOPE("call_combiner_start", 0); +void CallCombiner::Start(grpc_closure* closure, grpc_error* error, + DEBUG_ARGS const char* reason) { + GPR_TIMER_SCOPE("CallCombiner::Start", 0); if (grpc_call_combiner_trace.enabled()) { gpr_log(GPR_INFO, - "==> grpc_call_combiner_start() [%p] closure=%p [" DEBUG_FMT_STR + "==> CallCombiner::Start() [%p] closure=%p [" DEBUG_FMT_STR "%s] error=%s", - call_combiner, closure DEBUG_FMT_ARGS, reason, - grpc_error_string(error)); + this, closure DEBUG_FMT_ARGS, reason, grpc_error_string(error)); } - size_t prev_size = static_cast( - gpr_atm_full_fetch_add(&call_combiner->size, (gpr_atm)1)); + size_t prev_size = + static_cast(gpr_atm_full_fetch_add(&size_, (gpr_atm)1)); if (grpc_call_combiner_trace.enabled()) { gpr_log(GPR_INFO, " size: %" PRIdPTR " -> %" PRIdPTR, prev_size, prev_size + 1); @@ -128,34 +128,30 @@ void grpc_call_combiner_start(grpc_call_combiner* call_combiner, GRPC_STATS_INC_CALL_COMBINER_LOCKS_SCHEDULED_ITEMS(); if (prev_size == 0) { GRPC_STATS_INC_CALL_COMBINER_LOCKS_INITIATED(); - GPR_TIMER_MARK("call_combiner_initiate", 0); if (grpc_call_combiner_trace.enabled()) { gpr_log(GPR_INFO, " EXECUTING IMMEDIATELY"); } // Queue was empty, so execute this closure immediately. - call_combiner_sched_closure(call_combiner, closure, error); + ScheduleClosure(closure, error); } else { if (grpc_call_combiner_trace.enabled()) { gpr_log(GPR_INFO, " QUEUING"); } // Queue was not empty, so add closure to queue. closure->error_data.error = error; - gpr_mpscq_push(&call_combiner->queue, - reinterpret_cast(closure)); + gpr_mpscq_push(&queue_, reinterpret_cast(closure)); } } -void grpc_call_combiner_stop(grpc_call_combiner* call_combiner DEBUG_ARGS, - const char* reason) { - GPR_TIMER_SCOPE("call_combiner_stop", 0); +void CallCombiner::Stop(DEBUG_ARGS const char* reason) { + GPR_TIMER_SCOPE("CallCombiner::Stop", 0); if (grpc_call_combiner_trace.enabled()) { - gpr_log(GPR_INFO, - "==> grpc_call_combiner_stop() [%p] [" DEBUG_FMT_STR "%s]", - call_combiner DEBUG_FMT_ARGS, reason); + gpr_log(GPR_INFO, "==> CallCombiner::Stop() [%p] [" DEBUG_FMT_STR "%s]", + this DEBUG_FMT_ARGS, reason); } - size_t prev_size = static_cast( - gpr_atm_full_fetch_add(&call_combiner->size, (gpr_atm)-1)); + size_t prev_size = + static_cast(gpr_atm_full_fetch_add(&size_, (gpr_atm)-1)); if (grpc_call_combiner_trace.enabled()) { gpr_log(GPR_INFO, " size: %" PRIdPTR " -> %" PRIdPTR, prev_size, prev_size - 1); @@ -168,10 +164,10 @@ void grpc_call_combiner_stop(grpc_call_combiner* call_combiner DEBUG_ARGS, } bool empty; grpc_closure* closure = reinterpret_cast( - gpr_mpscq_pop_and_check_end(&call_combiner->queue, &empty)); + gpr_mpscq_pop_and_check_end(&queue_, &empty)); if (closure == nullptr) { // This can happen either due to a race condition within the mpscq - // code or because of a race with grpc_call_combiner_start(). + // code or because of a race with Start(). if (grpc_call_combiner_trace.enabled()) { gpr_log(GPR_INFO, " queue returned no result; checking again"); } @@ -181,8 +177,7 @@ void grpc_call_combiner_stop(grpc_call_combiner* call_combiner DEBUG_ARGS, gpr_log(GPR_INFO, " EXECUTING FROM QUEUE: closure=%p error=%s", closure, grpc_error_string(closure->error_data.error)); } - call_combiner_sched_closure(call_combiner, closure, - closure->error_data.error); + ScheduleClosure(closure, closure->error_data.error); break; } } else if (grpc_call_combiner_trace.enabled()) { @@ -190,13 +185,12 @@ void grpc_call_combiner_stop(grpc_call_combiner* call_combiner DEBUG_ARGS, } } -void grpc_call_combiner_set_notify_on_cancel(grpc_call_combiner* call_combiner, - grpc_closure* closure) { +void CallCombiner::SetNotifyOnCancel(grpc_closure* closure) { GRPC_STATS_INC_CALL_COMBINER_SET_NOTIFY_ON_CANCEL(); while (true) { // Decode original state. - gpr_atm original_state = gpr_atm_acq_load(&call_combiner->cancel_state); - grpc_error* original_error = decode_cancel_state_error(original_state); + gpr_atm original_state = gpr_atm_acq_load(&cancel_state_); + grpc_error* original_error = DecodeCancelStateError(original_state); // If error is set, invoke the cancellation closure immediately. // Otherwise, store the new closure. if (original_error != GRPC_ERROR_NONE) { @@ -204,16 +198,15 @@ void grpc_call_combiner_set_notify_on_cancel(grpc_call_combiner* call_combiner, gpr_log(GPR_INFO, "call_combiner=%p: scheduling notify_on_cancel callback=%p " "for pre-existing cancellation", - call_combiner, closure); + this, closure); } GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_REF(original_error)); break; } else { - if (gpr_atm_full_cas(&call_combiner->cancel_state, original_state, - (gpr_atm)closure)) { + if (gpr_atm_full_cas(&cancel_state_, original_state, (gpr_atm)closure)) { if (grpc_call_combiner_trace.enabled()) { gpr_log(GPR_INFO, "call_combiner=%p: setting notify_on_cancel=%p", - call_combiner, closure); + this, closure); } // If we replaced an earlier closure, invoke the original // closure with GRPC_ERROR_NONE. This allows callers to clean @@ -222,8 +215,8 @@ void grpc_call_combiner_set_notify_on_cancel(grpc_call_combiner* call_combiner, closure = (grpc_closure*)original_state; if (grpc_call_combiner_trace.enabled()) { gpr_log(GPR_INFO, - "call_combiner=%p: scheduling old cancel callback=%p", - call_combiner, closure); + "call_combiner=%p: scheduling old cancel callback=%p", this, + closure); } GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_NONE); } @@ -234,24 +227,23 @@ void grpc_call_combiner_set_notify_on_cancel(grpc_call_combiner* call_combiner, } } -void grpc_call_combiner_cancel(grpc_call_combiner* call_combiner, - grpc_error* error) { +void CallCombiner::Cancel(grpc_error* error) { GRPC_STATS_INC_CALL_COMBINER_CANCELLED(); while (true) { - gpr_atm original_state = gpr_atm_acq_load(&call_combiner->cancel_state); - grpc_error* original_error = decode_cancel_state_error(original_state); + gpr_atm original_state = gpr_atm_acq_load(&cancel_state_); + grpc_error* original_error = DecodeCancelStateError(original_state); if (original_error != GRPC_ERROR_NONE) { GRPC_ERROR_UNREF(error); break; } - if (gpr_atm_full_cas(&call_combiner->cancel_state, original_state, - encode_cancel_state_error(error))) { + if (gpr_atm_full_cas(&cancel_state_, original_state, + EncodeCancelStateError(error))) { if (original_state != 0) { grpc_closure* notify_on_cancel = (grpc_closure*)original_state; if (grpc_call_combiner_trace.enabled()) { gpr_log(GPR_INFO, "call_combiner=%p: scheduling notify_on_cancel callback=%p", - call_combiner, notify_on_cancel); + this, notify_on_cancel); } GRPC_CLOSURE_SCHED(notify_on_cancel, GRPC_ERROR_REF(error)); } @@ -260,3 +252,5 @@ void grpc_call_combiner_cancel(grpc_call_combiner* call_combiner, // cas failed, try again. } } + +} // namespace grpc_core diff --git a/src/core/lib/iomgr/call_combiner.h b/src/core/lib/iomgr/call_combiner.h index 4ec0044f056..ffcd0f7fb76 100644 --- a/src/core/lib/iomgr/call_combiner.h +++ b/src/core/lib/iomgr/call_combiner.h @@ -41,15 +41,78 @@ // when it is done with the action that was kicked off by the original // callback. -extern grpc_core::TraceFlag grpc_call_combiner_trace; +namespace grpc_core { -struct grpc_call_combiner { - gpr_atm size = 0; // size_t, num closures in queue or currently executing - gpr_mpscq queue; +extern TraceFlag grpc_call_combiner_trace; + +class CallCombiner { + public: + CallCombiner(); + ~CallCombiner(); + +#ifndef NDEBUG +#define GRPC_CALL_COMBINER_START(call_combiner, closure, error, reason) \ + (call_combiner)->Start((closure), (error), __FILE__, __LINE__, (reason)) +#define GRPC_CALL_COMBINER_STOP(call_combiner, reason) \ + (call_combiner)->Stop(__FILE__, __LINE__, (reason)) + /// Starts processing \a closure. + void Start(grpc_closure* closure, grpc_error* error, const char* file, + int line, const char* reason); + /// Yields the call combiner to the next closure in the queue, if any. + void Stop(const char* file, int line, const char* reason); +#else +#define GRPC_CALL_COMBINER_START(call_combiner, closure, error, reason) \ + (call_combiner)->Start((closure), (error), (reason)) +#define GRPC_CALL_COMBINER_STOP(call_combiner, reason) \ + (call_combiner)->Stop((reason)) + /// Starts processing \a closure. + void Start(grpc_closure* closure, grpc_error* error, const char* reason); + /// Yields the call combiner to the next closure in the queue, if any. + void Stop(const char* reason); +#endif + + /// Registers \a closure to be invoked when Cancel() is called. + /// + /// Once a closure is registered, it will always be scheduled exactly + /// once; this allows the closure to hold references that will be freed + /// regardless of whether or not the call was cancelled. If a cancellation + /// does occur, the closure will be scheduled with the cancellation error; + /// otherwise, it will be scheduled with GRPC_ERROR_NONE. + /// + /// The closure will be scheduled in the following cases: + /// - If Cancel() was called prior to registering the closure, it will be + /// scheduled immediately with the cancelation error. + /// - If Cancel() is called after registering the closure, the closure will + /// be scheduled with the cancellation error. + /// - If SetNotifyOnCancel() is called again to register a new cancellation + /// closure, the previous cancellation closure will be scheduled with + /// GRPC_ERROR_NONE. + /// + /// If \a closure is NULL, then no closure will be invoked on + /// cancellation; this effectively unregisters the previously set closure. + /// However, most filters will not need to explicitly unregister their + /// callbacks, as this is done automatically when the call is destroyed. + /// Filters that schedule the cancellation closure on ExecCtx do not need + /// to take a ref on the call stack to guarantee closure liveness. This is + /// done by explicitly flushing ExecCtx after the unregistration during + /// call destruction. + void SetNotifyOnCancel(grpc_closure* closure); + + /// Indicates that the call has been cancelled. + void Cancel(grpc_error* error); + + private: + void ScheduleClosure(grpc_closure* closure, grpc_error* error); +#ifdef GRPC_TSAN_ENABLED + static void TsanClosure(void* arg, grpc_error* error); +#endif + + gpr_atm size_ = 0; // size_t, num closures in queue or currently executing + gpr_mpscq queue_; // Either 0 (if not cancelled and no cancellation closure set), // a grpc_closure* (if the lowest bit is 0), // or a grpc_error* (if the lowest bit is 1). - gpr_atm cancel_state = 0; + gpr_atm cancel_state_ = 0; #ifdef GRPC_TSAN_ENABLED // A fake ref-counted lock that is kept alive after the destruction of // grpc_call_combiner, when we are running the original closure. @@ -58,90 +121,20 @@ struct grpc_call_combiner { // callback is called. However, original_closure is free to trigger // anything on the call combiner (including destruction of grpc_call). // Thus, we need a ref-counted structure that can outlive the call combiner. - struct TsanLock - : public grpc_core::RefCounted { + struct TsanLock : public RefCounted { TsanLock() { TSAN_ANNOTATE_RWLOCK_CREATE(&taken); } ~TsanLock() { TSAN_ANNOTATE_RWLOCK_DESTROY(&taken); } - // To avoid double-locking by the same thread, we should acquire/release // the lock only when taken is false. On each acquire taken must be set to // true. std::atomic taken{false}; }; - grpc_core::RefCountedPtr tsan_lock = - grpc_core::MakeRefCounted(); - grpc_closure tsan_closure; - grpc_closure* original_closure; + RefCountedPtr tsan_lock_ = MakeRefCounted(); + grpc_closure tsan_closure_; + grpc_closure* original_closure_; #endif }; -// Assumes memory was initialized to zero. -void grpc_call_combiner_init(grpc_call_combiner* call_combiner); - -void grpc_call_combiner_destroy(grpc_call_combiner* call_combiner); - -#ifndef NDEBUG -#define GRPC_CALL_COMBINER_START(call_combiner, closure, error, reason) \ - grpc_call_combiner_start((call_combiner), (closure), (error), __FILE__, \ - __LINE__, (reason)) -#define GRPC_CALL_COMBINER_STOP(call_combiner, reason) \ - grpc_call_combiner_stop((call_combiner), __FILE__, __LINE__, (reason)) -/// Starts processing \a closure on \a call_combiner. -void grpc_call_combiner_start(grpc_call_combiner* call_combiner, - grpc_closure* closure, grpc_error* error, - const char* file, int line, const char* reason); -/// Yields the call combiner to the next closure in the queue, if any. -void grpc_call_combiner_stop(grpc_call_combiner* call_combiner, - const char* file, int line, const char* reason); -#else -#define GRPC_CALL_COMBINER_START(call_combiner, closure, error, reason) \ - grpc_call_combiner_start((call_combiner), (closure), (error), (reason)) -#define GRPC_CALL_COMBINER_STOP(call_combiner, reason) \ - grpc_call_combiner_stop((call_combiner), (reason)) -/// Starts processing \a closure on \a call_combiner. -void grpc_call_combiner_start(grpc_call_combiner* call_combiner, - grpc_closure* closure, grpc_error* error, - const char* reason); -/// Yields the call combiner to the next closure in the queue, if any. -void grpc_call_combiner_stop(grpc_call_combiner* call_combiner, - const char* reason); -#endif - -/// Registers \a closure to be invoked by \a call_combiner when -/// grpc_call_combiner_cancel() is called. -/// -/// Once a closure is registered, it will always be scheduled exactly -/// once; this allows the closure to hold references that will be freed -/// regardless of whether or not the call was cancelled. If a cancellation -/// does occur, the closure will be scheduled with the cancellation error; -/// otherwise, it will be scheduled with GRPC_ERROR_NONE. -/// -/// The closure will be scheduled in the following cases: -/// - If grpc_call_combiner_cancel() was called prior to registering the -/// closure, it will be scheduled immediately with the cancelation error. -/// - If grpc_call_combiner_cancel() is called after registering the -/// closure, the closure will be scheduled with the cancellation error. -/// - If grpc_call_combiner_set_notify_on_cancel() is called again to -/// register a new cancellation closure, the previous cancellation -/// closure will be scheduled with GRPC_ERROR_NONE. -/// -/// If \a closure is NULL, then no closure will be invoked on -/// cancellation; this effectively unregisters the previously set closure. -/// However, most filters will not need to explicitly unregister their -/// callbacks, as this is done automatically when the call is destroyed. Filters -/// that schedule the cancellation closure on ExecCtx do not need to take a ref -/// on the call stack to guarantee closure liveness. This is done by explicitly -/// flushing ExecCtx after the unregistration during call destruction. -void grpc_call_combiner_set_notify_on_cancel(grpc_call_combiner* call_combiner, - grpc_closure* closure); - -/// Indicates that the call has been cancelled. -void grpc_call_combiner_cancel(grpc_call_combiner* call_combiner, - grpc_error* error); - -namespace grpc_core { - // Helper for running a list of closures in a call combiner. // // Each callback running in the call combiner will eventually be @@ -166,7 +159,7 @@ class CallCombinerClosureList { // scheduled via GRPC_CLOSURE_SCHED(), which will eventually result in // yielding the call combiner. If the list is empty, then the call // combiner will be yielded immediately. - void RunClosures(grpc_call_combiner* call_combiner) { + void RunClosures(CallCombiner* call_combiner) { if (closures_.empty()) { GRPC_CALL_COMBINER_STOP(call_combiner, "no closures to schedule"); return; @@ -190,7 +183,7 @@ class CallCombinerClosureList { // Runs all closures in the call combiner, but does NOT yield the call // combiner. All closures will be scheduled via GRPC_CALL_COMBINER_START(). - void RunClosuresWithoutYielding(grpc_call_combiner* call_combiner) { + void RunClosuresWithoutYielding(CallCombiner* call_combiner) { for (size_t i = 0; i < closures_.size(); ++i) { auto& closure = closures_[i]; GRPC_CALL_COMBINER_START(call_combiner, closure.closure, closure.error, diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index f90c92efdc2..0c40dd7ff1e 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -92,7 +92,7 @@ struct call_data { } grpc_call_stack* owning_call; - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; grpc_core::RefCountedPtr creds; grpc_slice host = grpc_empty_slice(); grpc_slice method = grpc_empty_slice(); @@ -270,11 +270,9 @@ static void send_security_metadata(grpc_call_element* elem, GRPC_ERROR_UNREF(error); } else { // Async return; register cancellation closure with call combiner. - grpc_call_combiner_set_notify_on_cancel( - calld->call_combiner, - GRPC_CLOSURE_INIT(&calld->get_request_metadata_cancel_closure, - cancel_get_request_metadata, elem, - grpc_schedule_on_exec_ctx)); + calld->call_combiner->SetNotifyOnCancel(GRPC_CLOSURE_INIT( + &calld->get_request_metadata_cancel_closure, + cancel_get_request_metadata, elem, grpc_schedule_on_exec_ctx)); } } @@ -345,11 +343,9 @@ static void auth_start_transport_stream_op_batch( GRPC_ERROR_UNREF(error); } else { // Async return; register cancellation closure with call combiner. - grpc_call_combiner_set_notify_on_cancel( - calld->call_combiner, - GRPC_CLOSURE_INIT(&calld->check_call_host_cancel_closure, - cancel_check_call_host, elem, - grpc_schedule_on_exec_ctx)); + calld->call_combiner->SetNotifyOnCancel(GRPC_CLOSURE_INIT( + &calld->check_call_host_cancel_closure, cancel_check_call_host, + elem, grpc_schedule_on_exec_ctx)); } gpr_free(call_host); return; /* early exit */ diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc index 81b9c2ce074..43509e6c61b 100644 --- a/src/core/lib/security/transport/server_auth_filter.cc +++ b/src/core/lib/security/transport/server_auth_filter.cc @@ -74,7 +74,7 @@ struct call_data { ~call_data() { GRPC_ERROR_UNREF(recv_initial_metadata_error); } - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; grpc_call_stack* owning_call; grpc_transport_stream_op_batch* recv_initial_metadata_batch; grpc_closure* original_recv_initial_metadata_ready; @@ -219,8 +219,7 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { // to drop the call combiner early if we get cancelled. GRPC_CLOSURE_INIT(&calld->cancel_closure, cancel_call, elem, grpc_schedule_on_exec_ctx); - grpc_call_combiner_set_notify_on_cancel(calld->call_combiner, - &calld->cancel_closure); + calld->call_combiner->SetNotifyOnCancel(&calld->cancel_closure); GRPC_CALL_STACK_REF(calld->owning_call, "server_auth_metadata"); calld->md = metadata_batch_to_md_array( batch->payload->recv_initial_metadata.recv_initial_metadata); diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 8aaff4a67d5..0b539b0d9b2 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -131,7 +131,6 @@ struct grpc_call { is_client(args.server_transport_data == nullptr), stream_op_payload(context) { gpr_ref_init(&ext_ref, 1); - grpc_call_combiner_init(&call_combiner); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { metadata_batch[i][j].deadline = GRPC_MILLIS_INF_FUTURE; @@ -141,12 +140,11 @@ struct grpc_call { ~grpc_call() { gpr_free(static_cast(const_cast(final_info.error_string))); - grpc_call_combiner_destroy(&call_combiner); } gpr_refcount ext_ref; gpr_arena* arena; - grpc_call_combiner call_combiner; + grpc_core::CallCombiner call_combiner; grpc_completion_queue* cq; grpc_polling_entity pollent; grpc_channel* channel; @@ -589,7 +587,7 @@ void grpc_call_unref(grpc_call* c) { // holding to the call stack. Also flush the closures on exec_ctx so that // filters that schedule cancel notification closures on exec_ctx do not // need to take a ref of the call stack to guarantee closure liveness. - grpc_call_combiner_set_notify_on_cancel(&c->call_combiner, nullptr); + c->call_combiner.SetNotifyOnCancel(nullptr); grpc_core::ExecCtx::Get()->Flush(); } GRPC_CALL_INTERNAL_UNREF(c, "destroy"); @@ -685,7 +683,7 @@ static void cancel_with_error(grpc_call* c, grpc_error* error) { // any in-flight asynchronous actions that may be holding the call // combiner. This ensures that the cancel_stream batch can be sent // down the filter stack in a timely manner. - grpc_call_combiner_cancel(&c->call_combiner, GRPC_ERROR_REF(error)); + c->call_combiner.Cancel(GRPC_ERROR_REF(error)); cancel_state* state = static_cast(gpr_malloc(sizeof(*state))); state->call = c; GRPC_CLOSURE_INIT(&state->finish_batch, done_termination, state, diff --git a/src/core/lib/surface/lame_client.cc b/src/core/lib/surface/lame_client.cc index 5f5f10d2ebf..dde39b8c681 100644 --- a/src/core/lib/surface/lame_client.cc +++ b/src/core/lib/surface/lame_client.cc @@ -39,7 +39,7 @@ namespace grpc_core { namespace { struct CallData { - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; grpc_linked_mdelem status; grpc_linked_mdelem details; grpc_core::Atomic filled_metadata; diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 1e0ac0e9237..e3fcf116c2a 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -190,7 +190,7 @@ struct call_data { grpc_closure publish; call_data* pending_next = nullptr; - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; }; struct request_matcher { diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index 9f666b382e9..5023c28ecca 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -174,7 +174,7 @@ grpc_endpoint* grpc_transport_get_endpoint(grpc_transport* transport) { // it's grpc_transport_stream_op_batch_finish_with_failure void grpc_transport_stream_op_batch_finish_with_failure( grpc_transport_stream_op_batch* batch, grpc_error* error, - grpc_call_combiner* call_combiner) { + grpc_core::CallCombiner* call_combiner) { if (batch->send_message) { batch->payload->send_message.send_message.reset(); } diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index c372003902a..cff39aacbca 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -379,7 +379,7 @@ void grpc_transport_destroy_stream(grpc_transport* transport, void grpc_transport_stream_op_batch_finish_with_failure( grpc_transport_stream_op_batch* op, grpc_error* error, - grpc_call_combiner* call_combiner); + grpc_core::CallCombiner* call_combiner); char* grpc_transport_stream_op_batch_string(grpc_transport_stream_op_batch* op); char* grpc_transport_op_string(grpc_transport_op* op); diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index e84999b213f..707732ba6ad 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -609,7 +609,7 @@ BENCHMARK_TEMPLATE(BM_IsolatedFilter, MessageSizeFilter, SendEmptyMetadata); namespace isolated_call_filter { typedef struct { - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; } call_data; static void StartTransportStreamOp(grpc_call_element* elem, From 33722ff1c6840ae8b32f3d82e6ea74a71262eb51 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 23 Apr 2019 15:31:30 -0700 Subject: [PATCH 1951/2143] Put callback behind a combiner, cancel callbacks in shutdown --- .../dns/c_ares/grpc_ares_ev_driver_libuv.cc | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc index 6993edf8a01..e69b824304d 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -31,6 +31,7 @@ #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/combiner.h" namespace grpc_core { @@ -40,7 +41,8 @@ void ares_uv_poll_close_cb(uv_handle_t* handle) { Delete(handle); } class GrpcPolledFdLibuv : public GrpcPolledFd { public: - GrpcPolledFdLibuv(ares_socket_t as) : as_(as) { + GrpcPolledFdLibuv(ares_socket_t as, grpc_combiner* combiner) + : as_(as), combiner_(combiner) { gpr_asprintf(&name_, "c-ares socket: %" PRIdPTR, (intptr_t)as); handle_ = New(); uv_poll_init_socket(uv_default_loop(), handle_, as); @@ -72,8 +74,15 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { } void ShutdownLocked(grpc_error* error) override { + grpc_core::ExecCtx exec_ctx; uv_poll_stop(handle_); uv_close(reinterpret_cast(handle_), ares_uv_poll_close_cb); + if (read_closure_) { + GRPC_CLOSURE_SCHED(read_closure_, GRPC_ERROR_CANCELLED); + } + if (write_closure_) { + GRPC_CLOSURE_SCHED(write_closure_, GRPC_ERROR_CANCELLED); + } } ares_socket_t GetWrappedAresSocketLocked() override { return as_; } @@ -86,13 +95,25 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { grpc_closure* read_closure_ = nullptr; grpc_closure* write_closure_ = nullptr; int poll_events_ = 0; + grpc_combiner* combiner_; }; -void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { - grpc_core::ExecCtx exec_ctx; +struct AresUvPollCbArg { + AresUvPollCbArg(uv_poll_t* handle, int status, int events) + : handle(handle), status(status), events(events) {} + + uv_poll_t* handle; + int status; + int events; +}; + +static void inner_callback(void* arg, grpc_error* error) { + AresUvPollCbArg* arg_struct = reinterpret_cast(arg); + uv_poll_t* handle = arg_struct->handle; + int status = arg_struct->status; + int events = arg_struct->events; GrpcPolledFdLibuv* polled_fd = reinterpret_cast(handle->data); - grpc_error* error = GRPC_ERROR_NONE; if (status < 0) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("cares polling error"); error = @@ -110,6 +131,18 @@ void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { polled_fd->poll_events_ &= ~UV_WRITABLE; } uv_poll_start(handle, polled_fd->poll_events_, ares_uv_poll_cb); + Delete(arg_struct); +} + +void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { + grpc_core::ExecCtx exec_ctx; + GrpcPolledFdLibuv* polled_fd = + reinterpret_cast(handle->data); + AresUvPollCbArg* arg = New(handle, status, events); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(inner_callback, arg, + grpc_combiner_scheduler(polled_fd->combiner_)), + GRPC_ERROR_NONE); } class GrpcPolledFdFactoryLibuv : public GrpcPolledFdFactory { @@ -117,7 +150,7 @@ class GrpcPolledFdFactoryLibuv : public GrpcPolledFdFactory { GrpcPolledFd* NewGrpcPolledFdLocked(ares_socket_t as, grpc_pollset_set* driver_pollset_set, grpc_combiner* combiner) override { - return New(as); + return New(as, combiner); } void ConfigureAresChannelLocked(ares_channel channel) override {} From 634cece3f35ed5affc52f1b7a32697949a630d15 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 23 Apr 2019 15:51:53 -0700 Subject: [PATCH 1952/2143] Fix sanity tests --- .../c_ares/grpc_ares_wrapper_libuv_windows.cc | 2 +- .../c_ares/grpc_ares_wrapper_libuv_windows.h | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc index 837593a62bc..706bc659582 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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. diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h index 07c0e37552b..ed40e58f7cc 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h @@ -1,6 +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. + * + */ + #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H +#include + #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" From 072fbc44a06490e1220fe3c779475ed02d9295c6 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 23 Apr 2019 16:37:51 -0700 Subject: [PATCH 1953/2143] Respect interval_us setting for TestServicer --- src/python/grpcio_tests/tests/interop/methods.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index 40341ca091b..08d8901a6b4 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -25,6 +25,7 @@ import enum import json import os import threading +import time from google import auth as google_auth from google.auth import environment_vars as google_auth_environment_vars @@ -38,6 +39,7 @@ from src.proto.grpc.testing import test_pb2_grpc _INITIAL_METADATA_KEY = "x-grpc-test-echo-initial" _TRAILING_METADATA_KEY = "x-grpc-test-echo-trailing-bin" +_US_IN_A_SECOND = 1000 * 1000 def _maybe_echo_metadata(servicer_context): @@ -77,6 +79,8 @@ class TestService(test_pb2_grpc.TestServiceServicer): def StreamingOutputCall(self, request, context): _maybe_echo_status_and_message(request, context) for response_parameters in request.response_parameters: + if response_parameters.interval_us != 0: + time.sleep(response_parameters.interval_us / _US_IN_A_SECOND) yield messages_pb2.StreamingOutputCallResponse( payload=messages_pb2.Payload( type=request.response_type, @@ -95,6 +99,9 @@ class TestService(test_pb2_grpc.TestServiceServicer): for request in request_iterator: _maybe_echo_status_and_message(request, context) for response_parameters in request.response_parameters: + if response_parameters.interval_us != 0: + time.sleep( + response_parameters.interval_us / _US_IN_A_SECOND) yield messages_pb2.StreamingOutputCallResponse( payload=messages_pb2.Payload( type=request.payload.type, From 8855c07c9f19a6c93392e64ae8c7c84d8ab56d4e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 23 Apr 2019 17:01:32 -0700 Subject: [PATCH 1954/2143] address comment --- src/objective-c/GRPCClient/GRPCCall.m | 10 ++++++++-- src/objective-c/GRPCClient/GRPCCallOptions.h | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index eb20c364275..cd37513c7fd 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -401,6 +401,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)receiveNextMessages:(NSUInteger)numberOfMessages { + // branching based on _callOptions.enableFlowControl is handled inside _call GRPCCall *copiedCall = nil; @synchronized(self) { copiedCall = _call; @@ -716,8 +717,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(strongSelf) { [strongSelf->_responseWriteable enqueueValue:data completionHandler:^{ - strongSelf->_pendingCoreRead = NO; - [strongSelf maybeStartNextRead]; + __strong GRPCCall *strongSelf = weakSelf; + if (strongSelf) { + @synchronized (strongSelf) { + strongSelf->_pendingCoreRead = NO; + [strongSelf maybeStartNextRead]; + } + } }]; } } diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 17abdc3fabf..121bc04c095 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -243,8 +243,13 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { /** * Enable flow control of a gRPC call. The option is default to NO. If set to YES, writeData: method * should only be called at most once before a didWriteData callback is issued, and - * receiveNextMessage: must be called each time before gRPC call issues a didReceiveMessage + * receiveNextMessage: must be called each time before gRPC call can issues a didReceiveMessage * callback. + * + * If writeData: method is called more than once before issuance of a didWriteData callback, gRPC + * will continue to queue the message and write them to gRPC core in order. However, the user + * assumes their own responsibility of flow control by keeping tracking of the pending writes in + * the call. */ @property(readwrite) BOOL enableFlowControl; From 438cb44378370afcf8afa3c2260798a4e586a822 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 23 Apr 2019 17:06:23 -0700 Subject: [PATCH 1955/2143] Add fallback-at-startup into xds --- include/grpc/impl/codegen/grpc_types.h | 4 +- .../ext/filters/client_channel/lb_policy.h | 3 + .../client_channel/lb_policy/grpclb/grpclb.cc | 32 +- .../client_channel/lb_policy/xds/xds.cc | 624 ++++++++++++++---- test/cpp/end2end/grpclb_end2end_test.cc | 68 +- test/cpp/end2end/xds_end2end_test.cc | 215 +++++- 6 files changed, 759 insertions(+), 187 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 078db2b90a8..4b3dff30404 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -315,11 +315,11 @@ typedef struct { #define GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS "grpc.grpclb_call_timeout_ms" /* Timeout in milliseconds to wait for the serverlist from the grpclb load balancer before using fallback backend addresses from the resolver. - If 0, fallback will never be used. Default value is 10000. */ + If 0, enter fallback mode immediately. 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. */ + If 0, enter fallback mode immediately. 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 \ diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index e369f591727..a8e4ede17cc 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -167,6 +167,9 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// A proxy object used by the LB policy to communicate with the client /// channel. + // TODO(juanlishen): Consider adding a mid-layer subclass that helps handle + // things like swapping in pending policy when it's ready. Currently, we are + // duplicating the logic in many subclasses. class ChannelControlHelper { public: ChannelControlHelper() = default; 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 4423e479d62..6bf45f8f4e2 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 @@ -1129,13 +1129,13 @@ 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()) { - // 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_) { + // If the fallback-at-startup checks are pending, go into fallback mode + // immediately. This short-circuits the timeout for the fallback-at-startup + // case. + if (grpclb_policy->fallback_at_startup_checks_pending_) { + GPR_ASSERT(!lb_calld->seen_serverlist_); gpr_log(GPR_INFO, - "[grpclb %p] balancer call finished without receiving " + "[grpclb %p] Balancer call finished without receiving " "serverlist; entering fallback mode", grpclb_policy); grpclb_policy->fallback_at_startup_checks_pending_ = false; @@ -1628,20 +1628,16 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { 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( - const_cast( - GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), - is_backend_from_grpclb_load_balancer), - }; - size_t num_args_to_add = 1; + InlinedVector args_to_add; + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), + is_backend_from_grpclb_load_balancer)); if (is_backend_from_grpclb_load_balancer) { - args_to_add[num_args_to_add++] = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1)); } - return grpc_channel_args_copy_and_add(args_, args_to_add, num_args_to_add); + return grpc_channel_args_copy_and_add(args_, args_to_add.data(), + args_to_add.size()); } OrphanablePtr GrpcLb::CreateChildPolicyLocked( 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 000de59448b..be29d4c360b 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 @@ -240,6 +240,10 @@ class XdsLb : public LoadBalancingPolicy { static void OnCallRetryTimerLocked(void* arg, grpc_error* error); void StartCallLocked(); + void StartConnectivityWatchLocked(); + void CancelConnectivityWatchLocked(); + static void OnConnectivityChangedLocked(void* arg, grpc_error* error); + private: // The owning LB policy. RefCountedPtr xdslb_policy_; @@ -247,6 +251,8 @@ class XdsLb : public LoadBalancingPolicy { // The channel and its status. grpc_channel* channel_; bool shutting_down_ = false; + grpc_connectivity_state connectivity_ = GRPC_CHANNEL_IDLE; + grpc_closure on_connectivity_changed_; // 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 @@ -299,6 +305,28 @@ class XdsLb : public LoadBalancingPolicy { PickerList pickers_; }; + class FallbackHelper : public ChannelControlHelper { + public: + explicit FallbackHelper(RefCountedPtr parent) + : parent_(std::move(parent)) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + grpc_channel* CreateChannel(const char* target, + const grpc_channel_args& args) override; + void UpdateState(grpc_connectivity_state state, + UniquePtr picker) override; + void RequestReresolution() override; + + void set_child(LoadBalancingPolicy* child) { child_ = child; } + + private: + bool CalledByPendingFallback() const; + bool CalledByCurrentFallback() const; + + RefCountedPtr parent_; + LoadBalancingPolicy* child_ = nullptr; + }; + class LocalityMap { public: class LocalityEntry : public InternallyRefCounted { @@ -402,8 +430,13 @@ class XdsLb : public LoadBalancingPolicy { : lb_chand_.get(); } - // Callback to enter fallback mode. + // Methods for dealing with fallback state. + void MaybeCancelFallbackAtStartupChecks(); static void OnFallbackTimerLocked(void* arg, grpc_error* error); + void UpdateFallbackPolicyLocked(); + OrphanablePtr CreateFallbackPolicyLocked( + const char* name, const grpc_channel_args* args); + void MaybeExitFallbackMode(); // Who the client is trying to communicate with. const char* server_name_ = nullptr; @@ -428,17 +461,33 @@ class XdsLb : public LoadBalancingPolicy { // Timeout in milliseconds for the LB call. 0 means no deadline. int lb_call_timeout_ms_ = 0; + // Whether the checks for fallback at startup are ALL pending. There are + // several cases where this can be reset: + // 1. The fallback timer fires, we enter fallback mode. + // 2. Before the fallback timer fires, the LB channel becomes + // TRANSIENT_FAILURE or the LB call fails, we enter fallback mode. + // 3. Before the fallback timer fires, we receive a response from the + // balancer, we cancel the fallback timer and use the response to update the + // locality map. + bool fallback_at_startup_checks_pending_ = false; // Timeout in milliseconds for before using fallback backend addresses. // 0 means not using fallback. - RefCountedPtr fallback_policy_config_; 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_; grpc_closure lb_on_fallback_; + // The policy to use for the fallback backends. + RefCountedPtr fallback_policy_config_; + // Lock held when modifying the value of fallback_policy_ or + // pending_fallback_policy_. + Mutex fallback_policy_mu_; + // Non-null iff we are in fallback mode. + OrphanablePtr fallback_policy_; + OrphanablePtr pending_fallback_policy_; + // The policy to use for the backends. RefCountedPtr child_policy_config_; // Map of policies to use in the backend @@ -494,17 +543,90 @@ XdsLb::PickResult XdsLb::Picker::PickFromLocality(const uint32_t key, return pickers_[index].second->Pick(pick, error); } +// +// XdsLb::FallbackHelper +// + +bool XdsLb::FallbackHelper::CalledByPendingFallback() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->pending_fallback_policy_.get(); +} + +bool XdsLb::FallbackHelper::CalledByCurrentFallback() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->fallback_policy_.get(); +} + +Subchannel* XdsLb::FallbackHelper::CreateSubchannel( + const grpc_channel_args& args) { + if (parent_->shutting_down_ || + (!CalledByPendingFallback() && !CalledByCurrentFallback())) { + return nullptr; + } + return parent_->channel_control_helper()->CreateSubchannel(args); +} + +grpc_channel* XdsLb::FallbackHelper::CreateChannel( + const char* target, const grpc_channel_args& args) { + if (parent_->shutting_down_ || + (!CalledByPendingFallback() && !CalledByCurrentFallback())) { + return nullptr; + } + return parent_->channel_control_helper()->CreateChannel(target, args); +} + +void XdsLb::FallbackHelper::UpdateState(grpc_connectivity_state state, + UniquePtr picker) { + if (parent_->shutting_down_) return; + // If this request is from the pending fallback policy, ignore it until + // it reports READY, at which point we swap it into place. + if (CalledByPendingFallback()) { + if (grpc_lb_xds_trace.enabled()) { + gpr_log( + GPR_INFO, + "[xdslb %p helper %p] pending fallback policy %p reports state=%s", + parent_.get(), this, parent_->pending_fallback_policy_.get(), + grpc_connectivity_state_name(state)); + } + if (state != GRPC_CHANNEL_READY) return; + grpc_pollset_set_del_pollset_set( + parent_->fallback_policy_->interested_parties(), + parent_->interested_parties()); + MutexLock lock(&parent_->fallback_policy_mu_); + parent_->fallback_policy_ = std::move(parent_->pending_fallback_policy_); + } else if (!CalledByCurrentFallback()) { + // This request is from an outdated fallback policy, so ignore it. + return; + } + parent_->channel_control_helper()->UpdateState(state, std::move(picker)); +} + +void XdsLb::FallbackHelper::RequestReresolution() { + if (parent_->shutting_down_) return; + const LoadBalancingPolicy* latest_fallback_policy = + parent_->pending_fallback_policy_ != nullptr + ? parent_->pending_fallback_policy_.get() + : parent_->fallback_policy_.get(); + if (child_ != latest_fallback_policy) return; + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, + "[xdslb %p] Re-resolution requested from the fallback policy (%p).", + parent_.get(), child_); + } + GPR_ASSERT(parent_->lb_chand_ != nullptr); + parent_->channel_control_helper()->RequestReresolution(); +} + // // serverlist parsing code // // Returns the backend addresses extracted from the given addresses. -UniquePtr ExtractBackendAddresses( - const ServerAddressList& addresses) { - auto backend_addresses = MakeUnique(); +ServerAddressList ExtractBackendAddresses(const ServerAddressList& addresses) { + ServerAddressList backend_addresses; for (size_t i = 0; i < addresses.size(); ++i) { if (!addresses[i].IsBalancer()) { - backend_addresses->emplace_back(addresses[i]); + backend_addresses.emplace_back(addresses[i]); } } return backend_addresses; @@ -584,6 +706,9 @@ XdsLb::BalancerChannelState::BalancerChannelState( .set_multiplier(GRPC_XDS_RECONNECT_BACKOFF_MULTIPLIER) .set_jitter(GRPC_XDS_RECONNECT_JITTER) .set_max_backoff(GRPC_XDS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { + GRPC_CLOSURE_INIT(&on_connectivity_changed_, + &XdsLb::BalancerChannelState::OnConnectivityChangedLocked, + this, grpc_combiner_scheduler(xdslb_policy_->combiner())); channel_ = xdslb_policy_->channel_control_helper()->CreateChannel( balancer_name, args); GPR_ASSERT(channel_ != nullptr); @@ -652,6 +777,62 @@ void XdsLb::BalancerChannelState::StartCallLocked() { lb_calld_->StartQuery(); } +void XdsLb::BalancerChannelState::StartConnectivityWatchLocked() { + grpc_channel_element* client_channel_elem = + grpc_channel_stack_last_element(grpc_channel_get_channel_stack(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( + xdslb_policy_->interested_parties()), + &connectivity_, &on_connectivity_changed_, nullptr); +} + +void XdsLb::BalancerChannelState::CancelConnectivityWatchLocked() { + grpc_channel_element* client_channel_elem = + grpc_channel_stack_last_element(grpc_channel_get_channel_stack(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()), + nullptr, &on_connectivity_changed_, nullptr); +} + +void XdsLb::BalancerChannelState::OnConnectivityChangedLocked( + void* arg, grpc_error* error) { + BalancerChannelState* self = static_cast(arg); + if (!self->shutting_down_ && + self->xdslb_policy_->fallback_at_startup_checks_pending_) { + if (self->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->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->xdslb_policy_->interested_parties()), + &self->connectivity_, &self->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, + "[xdslb %p] Balancer channel in state TRANSIENT_FAILURE; " + "entering fallback mode", + self); + self->xdslb_policy_->fallback_at_startup_checks_pending_ = false; + grpc_timer_cancel(&self->xdslb_policy_->lb_fallback_timer_); + self->xdslb_policy_->UpdateFallbackPolicyLocked(); + } + // Done watching connectivity state, so drop ref. + self->Unref(DEBUG_LOCATION, "watch_lb_channel_connectivity"); +} + // // XdsLb::BalancerChannelState::BalancerCallState // @@ -897,6 +1078,14 @@ void XdsLb::BalancerChannelState::BalancerCallState:: (initial_response = xds_grpclb_initial_response_parse(response_slice)) != nullptr) { // Have NOT seen initial response, look for initial response. + // TODO(juanlishen): When we convert this to use the xds protocol, the + // balancer will send us a fallback timeout such that we should go into + // fallback mode if we have lost contact with the balancer after a certain + // period of time. We will need to save the timeout value here, and then + // when the balancer call ends, we will need to start a timer for the + // specified period of time, and if the timer fires, we go into fallback + // mode. We will also need to cancel the timer when we receive a serverlist + // from the balancer. if (initial_response->has_client_stats_report_interval) { const grpc_millis interval = xds_grpclb_duration_to_millis( &initial_response->client_stats_report_interval); @@ -938,81 +1127,69 @@ void XdsLb::BalancerChannelState::BalancerCallState:: gpr_free(ipport); } } - /* 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 && - 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(); - lb_calld->ScheduleNextClientLoadReportLocked(); - } - if (!xdslb_policy->locality_serverlist_.empty() && - xds_grpclb_serverlist_equals( - xdslb_policy->locality_serverlist_[0]->serverlist, serverlist)) { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] Incoming server list identical to current, " - "ignoring.", - xdslb_policy); - } - xds_grpclb_destroy_serverlist(serverlist); - } else { /* new serverlist */ - if (!xdslb_policy->locality_serverlist_.empty()) { - /* dispose of the old serverlist */ - xds_grpclb_destroy_serverlist( - xdslb_policy->locality_serverlist_[0]->serverlist); - } else { - /* or dispose of the fallback */ - xdslb_policy->fallback_backend_addresses_.reset(); - if (xdslb_policy->fallback_timer_callback_pending_) { - grpc_timer_cancel(&xdslb_policy->lb_fallback_timer_); - } - /* Initialize locality serverlist, currently the list only handles - * one child */ - xdslb_policy->locality_serverlist_.emplace_back( - MakeUnique()); - xdslb_policy->locality_serverlist_[0]->locality_name = - static_cast(gpr_strdup(kDefaultLocalityName)); - xdslb_policy->locality_serverlist_[0]->locality_weight = - kDefaultLocalityWeight; - } - // and update the copy in the XdsLb instance. This - // serverlist instance will be destroyed either upon the next - // update or when the XdsLb instance is destroyed. - xdslb_policy->locality_serverlist_[0]->serverlist = serverlist; - xdslb_policy->locality_map_.UpdateLocked( - xdslb_policy->locality_serverlist_, - xdslb_policy->child_policy_config_.get(), xdslb_policy->args_, - xdslb_policy); - } - } else { + // 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] Received empty server list, ignoring.", + 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 && + lb_calld->client_stats_ == nullptr) { + lb_calld->client_stats_ = MakeRefCounted(); + lb_calld->Ref(DEBUG_LOCATION, "client_load_report").release(); + lb_calld->ScheduleNextClientLoadReportLocked(); + } + if (!xdslb_policy->locality_serverlist_.empty() && + xds_grpclb_serverlist_equals( + xdslb_policy->locality_serverlist_[0]->serverlist, serverlist)) { + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, + "[xdslb %p] Incoming server list identical to current, " + "ignoring.", xdslb_policy); } xds_grpclb_destroy_serverlist(serverlist); + } else { // New serverlist. + // If the balancer tells us to drop all the calls, we should exit fallback + // mode immediately. + // TODO(juanlishen): When we add EDS drop, we should change to check + // drop_percentage. + if (serverlist->num_servers == 0) xdslb_policy->MaybeExitFallbackMode(); + if (!xdslb_policy->locality_serverlist_.empty()) { + xds_grpclb_destroy_serverlist( + xdslb_policy->locality_serverlist_[0]->serverlist); + } else { + // This is the first serverlist we've received, don't enter fallback + // mode. + xdslb_policy->MaybeCancelFallbackAtStartupChecks(); + // Initialize locality serverlist, currently the list only handles + // one child. + xdslb_policy->locality_serverlist_.emplace_back( + MakeUnique()); + xdslb_policy->locality_serverlist_[0]->locality_name = + static_cast(gpr_strdup(kDefaultLocalityName)); + xdslb_policy->locality_serverlist_[0]->locality_weight = + kDefaultLocalityWeight; + } + // Update the serverlist in the XdsLb instance. This serverlist + // instance will be destroyed either upon the next update or when the + // XdsLb instance is destroyed. + xdslb_policy->locality_serverlist_[0]->serverlist = serverlist; + xdslb_policy->locality_map_.UpdateLocked( + xdslb_policy->locality_serverlist_, + xdslb_policy->child_policy_config_.get(), xdslb_policy->args_, + xdslb_policy); } } else { // No valid initial response or serverlist found. @@ -1089,6 +1266,18 @@ void XdsLb::BalancerChannelState::BalancerCallState:: lb_chand->StartCallRetryTimerLocked(); } xdslb_policy->channel_control_helper()->RequestReresolution(); + // If the fallback-at-startup checks are pending, go into fallback mode + // immediately. This short-circuits the timeout for the + // fallback-at-startup case. + if (xdslb_policy->fallback_at_startup_checks_pending_) { + gpr_log(GPR_INFO, + "[xdslb %p] Balancer call finished; entering fallback mode", + xdslb_policy); + xdslb_policy->fallback_at_startup_checks_pending_ = false; + grpc_timer_cancel(&xdslb_policy->lb_fallback_timer_); + lb_chand->CancelConnectivityWatchLocked(); + xdslb_policy->UpdateFallbackPolicyLocked(); + } } } lb_calld->Unref(DEBUG_LOCATION, "lb_call_ended"); @@ -1164,7 +1353,7 @@ XdsLb::XdsLb(Args args) 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. - arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS); + arg = grpc_channel_args_find(args.args, GRPC_ARG_XDS_FALLBACK_TIMEOUT_MS); lb_fallback_timeout_ms_ = grpc_channel_arg_get_integer( arg, {GRPC_XDS_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX}); } @@ -1177,14 +1366,25 @@ XdsLb::~XdsLb() { void XdsLb::ShutdownLocked() { shutting_down_ = true; - if (fallback_timer_callback_pending_) { + if (fallback_at_startup_checks_pending_) { grpc_timer_cancel(&lb_fallback_timer_); } locality_map_.ShutdownLocked(); - // 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 - // alive when that callback is invoked. + if (fallback_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set(fallback_policy_->interested_parties(), + interested_parties()); + } + if (pending_fallback_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set( + pending_fallback_policy_->interested_parties(), interested_parties()); + } + { + MutexLock lock(&fallback_policy_mu_); + fallback_policy_.reset(); + pending_fallback_policy_.reset(); + } + // We reset the LB channels here instead of in our destructor because they + // hold refs to XdsLb. { MutexLock lock(&lb_chand_mu_); lb_chand_.reset(); @@ -1204,12 +1404,31 @@ void XdsLb::ResetBackoffLocked() { grpc_channel_reset_connect_backoff(pending_lb_chand_->channel()); } locality_map_.ResetBackoffLocked(); + if (fallback_policy_ != nullptr) { + fallback_policy_->ResetBackoffLocked(); + } + if (pending_fallback_policy_ != nullptr) { + pending_fallback_policy_->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 locality_map_ to fill the children subchannels. locality_map_.FillChildRefsForChannelz(child_subchannels, child_channels); + { + // This must be done holding fallback_policy_mu_, since this method does not + // run in the combiner. + MutexLock lock(&fallback_policy_mu_); + if (fallback_policy_ != nullptr) { + fallback_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } + if (pending_fallback_policy_ != nullptr) { + pending_fallback_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } + } MutexLock lock(&lb_chand_mu_); if (lb_chand_ != nullptr) { grpc_core::channelz::ChannelNode* channel_node = @@ -1301,57 +1520,213 @@ void XdsLb::ParseLbConfig(Config* xds_config) { void XdsLb::UpdateLocked(UpdateArgs args) { const bool is_initial_update = lb_chand_ == nullptr; 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; } 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. - // TODO(vpowar): Handle the fallback_address changes when we add support for - // fallback in xDS. locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_.get(), args_, this); - // If this is the initial update, start the fallback timer. + // Update the existing fallback policy. The fallback policy config and/or the + // fallback addresses may be new. + if (fallback_policy_ != nullptr) UpdateFallbackPolicyLocked(); + // If this is the initial update, start the fallback-at-startup checks. if (is_initial_update) { - if (lb_fallback_timeout_ms_ > 0 && locality_serverlist_.empty() && - !fallback_timer_callback_pending_) { - grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; - 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; - 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. - } + grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; + Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Held by closure + GRPC_CLOSURE_INIT(&lb_on_fallback_, &XdsLb::OnFallbackTimerLocked, this, + grpc_combiner_scheduler(combiner())); + fallback_at_startup_checks_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. + lb_chand_->StartConnectivityWatchLocked(); } } // -// code for balancer channel and call +// fallback-related methods // +void XdsLb::MaybeCancelFallbackAtStartupChecks() { + if (!fallback_at_startup_checks_pending_) return; + gpr_log(GPR_INFO, + "[xdslb %p] Cancelling fallback timer and LB channel connectivity " + "watch", + this); + grpc_timer_cancel(&lb_fallback_timer_); + lb_chand_->CancelConnectivityWatchLocked(); + fallback_at_startup_checks_pending_ = false; +} + void XdsLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { XdsLb* xdslb_policy = static_cast(arg); - xdslb_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 (xdslb_policy->locality_serverlist_.empty() && + // If some fallback-at-startup check is done after the timer fires but before + // this callback actually runs, don't fall back. + if (xdslb_policy->fallback_at_startup_checks_pending_ && !xdslb_policy->shutting_down_ && error == GRPC_ERROR_NONE) { if (grpc_lb_xds_trace.enabled()) { gpr_log(GPR_INFO, - "[xdslb %p] Fallback timer fired. Not using fallback backends", + "[xdslb %p] Child policy not ready after fallback timeout; " + "entering fallback mode", xdslb_policy); } + xdslb_policy->fallback_at_startup_checks_pending_ = false; + xdslb_policy->UpdateFallbackPolicyLocked(); + xdslb_policy->lb_chand_->CancelConnectivityWatchLocked(); } xdslb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer"); } +void XdsLb::UpdateFallbackPolicyLocked() { + if (shutting_down_) return; + // Construct update args. + UpdateArgs update_args; + update_args.addresses = fallback_backend_addresses_; + update_args.config = fallback_policy_config_ == nullptr + ? nullptr + : fallback_policy_config_->Ref(); + update_args.args = grpc_channel_args_copy(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* fallback_policy_name = fallback_policy_config_ == nullptr + ? "round_robin" + : fallback_policy_config_->name(); + const bool create_policy = + // case 1 + fallback_policy_ == nullptr || + // case 2b + (pending_fallback_policy_ == nullptr && + strcmp(fallback_policy_->name(), fallback_policy_name) != 0) || + // case 3b + (pending_fallback_policy_ != nullptr && + strcmp(pending_fallback_policy_->name(), fallback_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] Creating new %sfallback policy %s", this, + fallback_policy_ == nullptr ? "" : "pending ", + fallback_policy_name); + } + auto new_policy = + CreateFallbackPolicyLocked(fallback_policy_name, update_args.args); + auto& lb_policy = fallback_policy_ == nullptr ? fallback_policy_ + : pending_fallback_policy_; + { + MutexLock lock(&fallback_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_fallback_policy_ != nullptr + ? pending_fallback_policy_.get() + : fallback_policy_.get(); + } + GPR_ASSERT(policy_to_update != nullptr); + // Update the policy. + if (grpc_lb_xds_trace.enabled()) { + gpr_log( + GPR_INFO, "[xdslb %p] Updating %sfallback policy %p", this, + policy_to_update == pending_fallback_policy_.get() ? "pending " : "", + policy_to_update); + } + policy_to_update->UpdateLocked(std::move(update_args)); +} + +OrphanablePtr XdsLb::CreateFallbackPolicyLocked( + const char* name, const grpc_channel_args* args) { + FallbackHelper* 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 fallback 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 fallback 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(lb_policy->interested_parties(), + interested_parties()); + return lb_policy; +} + +void XdsLb::MaybeExitFallbackMode() { + if (fallback_policy_ == nullptr) return; + gpr_log(GPR_INFO, "[xdslb %p] Exiting fallback mode", this); + fallback_policy_.reset(); + pending_fallback_policy_.reset(); +} + +// +// XdsLb::LocalityMap +// + void XdsLb::LocalityMap::PruneLocalities(const LocalityList& locality_list) { for (auto iter = map_.begin(); iter != map_.end();) { bool found = false; @@ -1391,18 +1766,18 @@ void XdsLb::LocalityMap::UpdateLocked( PruneLocalities(locality_serverlist); } -void grpc_core::XdsLb::LocalityMap::ShutdownLocked() { +void XdsLb::LocalityMap::ShutdownLocked() { MutexLock lock(&child_refs_mu_); map_.clear(); } -void grpc_core::XdsLb::LocalityMap::ResetBackoffLocked() { +void XdsLb::LocalityMap::ResetBackoffLocked() { for (auto& p : map_) { p.second->ResetBackoffLocked(); } } -void grpc_core::XdsLb::LocalityMap::FillChildRefsForChannelz( +void XdsLb::LocalityMap::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { MutexLock lock(&child_refs_mu_); @@ -1411,7 +1786,9 @@ void grpc_core::XdsLb::LocalityMap::FillChildRefsForChannelz( } } -// Locality Entry child policy methods +// +// XdsLb::LocalityMap::LocalityEntry +// grpc_channel_args* XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyArgsLocked( @@ -1466,18 +1843,12 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( LoadBalancingPolicy::Config* child_policy_config, const grpc_channel_args* args_in) { if (parent_->shutting_down_) return; - // 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 == nullptr ? nullptr : child_policy_config->Ref(); update_args.args = CreateChildPolicyArgsLocked(args_in); - // 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 @@ -1618,7 +1989,7 @@ void XdsLb::LocalityMap::LocalityEntry::Orphan() { } // -// LocalityEntry::Helper implementation +// XdsLb::LocalityEntry::Helper // bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByPendingChild() const { @@ -1671,9 +2042,10 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState( // This request is from an outdated child, so ignore it. 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?) + // At this point, child_ must be the current child policy. + if (state == GRPC_CHANNEL_READY) entry_->parent_->MaybeExitFallbackMode(); + // If we are in fallback mode, ignore update request from the child policy. + if (entry_->parent_->fallback_policy_ != nullptr) return; GPR_ASSERT(entry_->parent_->lb_chand_ != nullptr); RefCountedPtr client_stats = entry_->parent_->lb_chand_->lb_calld() == nullptr diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index f8d887dd24d..bd915b04eee 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -1034,12 +1034,12 @@ TEST_F(SingleBalancerTest, Fallback) { SetNextResolutionAllBalancers(); const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); - const size_t kNumBackendInResolution = backends_.size() / 2; + const size_t kNumBackendsInResolution = backends_.size() / 2; ResetStub(kFallbackTimeoutMs); std::vector addresses; addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); - for (size_t i = 0; i < kNumBackendInResolution; ++i) { + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); } SetNextResolution(addresses); @@ -1048,45 +1048,45 @@ TEST_F(SingleBalancerTest, Fallback) { ScheduleResponseForBalancer( 0, BalancerServiceImpl::BuildResponseForBackends( - GetBackendPorts(kNumBackendInResolution /* start_index */), {}), + GetBackendPorts(kNumBackendsInResolution /* start_index */), {}), kServerlistDelayMs); // Wait until all the fallback backends are reachable. - for (size_t i = 0; i < kNumBackendInResolution; ++i) { + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { WaitForBackend(i); } // The first request. gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(kNumBackendInResolution); + CheckRpcSendOk(kNumBackendsInResolution); gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // Fallback is used: each backend returned by the resolver should have // gotten one request. - for (size_t i = 0; i < kNumBackendInResolution; ++i) { + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { EXPECT_EQ(1U, backends_[i]->service_.request_count()); } - for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { EXPECT_EQ(0U, backends_[i]->service_.request_count()); } // Wait until the serverlist reception has been processed and all backends // in the serverlist are reachable. - for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { WaitForBackend(i); } // Send out the second request. gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); - CheckRpcSendOk(backends_.size() - kNumBackendInResolution); + CheckRpcSendOk(backends_.size() - kNumBackendsInResolution); gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // Serverlist is used: each backend returned by the balancer should // have gotten one request. - for (size_t i = 0; i < kNumBackendInResolution; ++i) { + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { EXPECT_EQ(0U, backends_[i]->service_.request_count()); } - for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { EXPECT_EQ(1U, backends_[i]->service_.request_count()); } @@ -1101,13 +1101,13 @@ TEST_F(SingleBalancerTest, FallbackUpdate) { SetNextResolutionAllBalancers(); const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); - const size_t kNumBackendInResolution = backends_.size() / 3; - const size_t kNumBackendInResolutionUpdate = backends_.size() / 3; + const size_t kNumBackendsInResolution = backends_.size() / 3; + const size_t kNumBackendsInResolutionUpdate = backends_.size() / 3; ResetStub(kFallbackTimeoutMs); std::vector addresses; addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); - for (size_t i = 0; i < kNumBackendInResolution; ++i) { + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); } SetNextResolution(addresses); @@ -1116,84 +1116,84 @@ TEST_F(SingleBalancerTest, FallbackUpdate) { ScheduleResponseForBalancer( 0, BalancerServiceImpl::BuildResponseForBackends( - GetBackendPorts(kNumBackendInResolution + - kNumBackendInResolutionUpdate /* start_index */), + GetBackendPorts(kNumBackendsInResolution + + kNumBackendsInResolutionUpdate /* start_index */), {}), kServerlistDelayMs); // Wait until all the fallback backends are reachable. - for (size_t i = 0; i < kNumBackendInResolution; ++i) { + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { WaitForBackend(i); } // The first request. gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(kNumBackendInResolution); + CheckRpcSendOk(kNumBackendsInResolution); gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // Fallback is used: each backend returned by the resolver should have // gotten one request. - for (size_t i = 0; i < kNumBackendInResolution; ++i) { + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { EXPECT_EQ(1U, backends_[i]->service_.request_count()); } - for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { EXPECT_EQ(0U, backends_[i]->service_.request_count()); } addresses.clear(); addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); - for (size_t i = kNumBackendInResolution; - i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { + for (size_t i = kNumBackendsInResolution; + i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); } SetNextResolution(addresses); // Wait until the resolution update has been processed and all the new // fallback backends are reachable. - for (size_t i = kNumBackendInResolution; - i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { + for (size_t i = kNumBackendsInResolution; + i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { WaitForBackend(i); } // Send out the second request. gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); - CheckRpcSendOk(kNumBackendInResolutionUpdate); + CheckRpcSendOk(kNumBackendsInResolutionUpdate); gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // The resolution update is used: each backend in the resolution update should // have gotten one request. - for (size_t i = 0; i < kNumBackendInResolution; ++i) { + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { EXPECT_EQ(0U, backends_[i]->service_.request_count()); } - for (size_t i = kNumBackendInResolution; - i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { + for (size_t i = kNumBackendsInResolution; + i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { EXPECT_EQ(1U, backends_[i]->service_.request_count()); } - for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate; + for (size_t i = kNumBackendsInResolution + kNumBackendsInResolutionUpdate; i < backends_.size(); ++i) { EXPECT_EQ(0U, backends_[i]->service_.request_count()); } // Wait until the serverlist reception has been processed and all backends // in the serverlist are reachable. - for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate; + for (size_t i = kNumBackendsInResolution + kNumBackendsInResolutionUpdate; i < backends_.size(); ++i) { WaitForBackend(i); } // Send out the third request. gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); - CheckRpcSendOk(backends_.size() - kNumBackendInResolution - - kNumBackendInResolutionUpdate); + CheckRpcSendOk(backends_.size() - kNumBackendsInResolution - + kNumBackendsInResolutionUpdate); gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); // Serverlist is used: each backend returned by the balancer should // have gotten one request. for (size_t i = 0; - i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { + i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { EXPECT_EQ(0U, backends_[i]->service_.request_count()); } - for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate; + for (size_t i = kNumBackendsInResolution + kNumBackendsInResolutionUpdate; i < backends_.size(); ++i) { EXPECT_EQ(1U, backends_[i]->service_.request_count()); } diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index ee248239909..2952c194d48 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -413,7 +413,9 @@ class XdsEnd2endTest : public ::testing::Test { const grpc::string& expected_targets = "") { ChannelArguments args; // TODO(juanlishen): Add setter to ChannelArguments. - args.SetInt(GRPC_ARG_XDS_FALLBACK_TIMEOUT_MS, fallback_timeout); + if (fallback_timeout > 0) { + 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()) { @@ -855,15 +857,214 @@ TEST_F(SingleBalancerTest, AllServersUnreachableFailFast) { EXPECT_EQ(1U, balancers_[0]->service_.response_count()); } -// The fallback tests are deferred because the fallback mode hasn't been -// supported yet. +TEST_F(SingleBalancerTest, Fallback) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); + const size_t kNumBackendsInResolution = backends_.size() / 2; + ResetStub(kFallbackTimeoutMs); + SetNextResolution(GetBackendPorts(0, kNumBackendsInResolution), + kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + // Send non-empty serverlist only after kServerlistDelayMs. + ScheduleResponseForBalancer( + 0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumBackendsInResolution /* start_index */), {}), + kServerlistDelayMs); + // Wait until all the fallback backends are reachable. + WaitForAllBackends(1 /* num_requests_multiple_of */, 0 /* start_index */, + kNumBackendsInResolution /* stop_index */); + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(kNumBackendsInResolution); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + // Fallback is used: each backend returned by the resolver should have + // gotten one request. + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); + } + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); + } + // Wait until the serverlist reception has been processed and all backends + // in the serverlist are reachable. + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumBackendsInResolution /* start_index */); + gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + CheckRpcSendOk(backends_.size() - kNumBackendsInResolution); + gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + // Serverlist is used: each backend returned by the balancer should + // have gotten one request. + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); + } + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); + } + // 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()); +} -// TODO(juanlishen): Add TEST_F(SingleBalancerTest, Fallback) +TEST_F(SingleBalancerTest, FallbackUpdate) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); + const size_t kNumBackendsInResolution = backends_.size() / 3; + const size_t kNumBackendsInResolutionUpdate = backends_.size() / 3; + ResetStub(kFallbackTimeoutMs); + SetNextResolution(GetBackendPorts(0, kNumBackendsInResolution), + kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + // Send non-empty serverlist only after kServerlistDelayMs. + ScheduleResponseForBalancer( + 0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumBackendsInResolution + + kNumBackendsInResolutionUpdate /* start_index */), + {}), + kServerlistDelayMs); + // Wait until all the fallback backends are reachable. + WaitForAllBackends(1 /* num_requests_multiple_of */, 0 /* start_index */, + kNumBackendsInResolution /* stop_index */); + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(kNumBackendsInResolution); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + // Fallback is used: each backend returned by the resolver should have + // gotten one request. + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); + } + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); + } + SetNextResolution(GetBackendPorts(kNumBackendsInResolution, + kNumBackendsInResolution + + kNumBackendsInResolutionUpdate), + kDefaultServiceConfig_.c_str()); + // Wait until the resolution update has been processed and all the new + // fallback backends are reachable. + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumBackendsInResolution /* start_index */, + kNumBackendsInResolution + + kNumBackendsInResolutionUpdate /* stop_index */); + gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + CheckRpcSendOk(kNumBackendsInResolutionUpdate); + gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + // The resolution update is used: each backend in the resolution update should + // have gotten one request. + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); + } + for (size_t i = kNumBackendsInResolution; + i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); + } + for (size_t i = kNumBackendsInResolution + kNumBackendsInResolutionUpdate; + i < backends_.size(); ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); + } + // Wait until the serverlist reception has been processed and all backends + // in the serverlist are reachable. + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumBackendsInResolution + + kNumBackendsInResolutionUpdate /* start_index */); + gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); + CheckRpcSendOk(backends_.size() - kNumBackendsInResolution - + kNumBackendsInResolutionUpdate); + gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); + // Serverlist is used: each backend returned by the balancer should + // have gotten one request. + for (size_t i = 0; + i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); + } + for (size_t i = kNumBackendsInResolution + kNumBackendsInResolutionUpdate; + i < backends_.size(); ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); + } + // 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()); +} -// TODO(juanlishen): Add TEST_F(SingleBalancerTest, FallbackUpdate) +TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerChannelFails) { + const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + // Return an unreachable balancer and one fallback backend. + SetNextResolution({backends_[0]->port_}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannel({grpc_pick_unused_port_or_die()}); + // Send RPC with deadline less than the fallback timeout and make sure it + // succeeds. + CheckRpcSendOk(/* times */ 1, /* timeout_ms */ 1000, + /* wait_for_ready */ false); +} -// TODO(juanlishen): Add TEST_F(SingleBalancerTest, -// FallbackEarlyWhenBalancerChannelFails) +TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerCallFails) { + const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + // Return one balancer and one fallback backend. + SetNextResolution({backends_[0]->port_}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + // 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, FallbackModeIsExitedWhenBalancerSaysToDropAllCalls) { + // Return an unreachable balancer and one fallback backend. + SetNextResolution({backends_[0]->port_}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannel({grpc_pick_unused_port_or_die()}); + // Enter fallback mode because the LB channel fails to connect. + WaitForBackend(0); + // Return a new balancer that sends an empty serverlist. + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends({}, {}), 0); + SetNextResolutionForLbChannelAllBalancers(); + // Send RPCs until failure. + gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(5000, GPR_TIMESPAN)); + do { + auto status = SendRpc(); + if (!status.ok()) break; + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + CheckRpcSendFailure(); +} + +TEST_F(SingleBalancerTest, FallbackModeIsExitedAfterChildRready) { + // Return an unreachable balancer and one fallback backend. + SetNextResolution({backends_[0]->port_}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannel({grpc_pick_unused_port_or_die()}); + // Enter fallback mode because the LB channel fails to connect. + WaitForBackend(0); + // Return a new balancer that sends a dead backend. + ShutdownBackend(1); + ScheduleResponseForBalancer( + 0, + BalancerServiceImpl::BuildResponseForBackends({backends_[1]->port_}, {}), + 0); + SetNextResolutionForLbChannelAllBalancers(); + // The state (TRANSIENT_FAILURE) update from the child policy will be ignored + // because we are still in fallback mode. + gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(5000, GPR_TIMESPAN)); + // Send 5 seconds worth of RPCs. + do { + CheckRpcSendOk(); + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + // After the backend is restarted, the child policy will eventually be READY, + // and we will exit fallback mode. + StartBackend(1); + WaitForBackend(1); + // We have exited fallback mode, so calls will go to the child policy + // exclusively. + CheckRpcSendOk(100); + EXPECT_EQ(0U, backends_[0]->service_.request_count()); + EXPECT_EQ(100U, backends_[1]->service_.request_count()); +} TEST_F(SingleBalancerTest, BackendsRestart) { SetNextResolution({}, kDefaultServiceConfig_.c_str()); From 47921d6e544fc998ee6f1a3caeccb3061f5c62e6 Mon Sep 17 00:00:00 2001 From: John Luo Date: Tue, 23 Apr 2019 18:09:15 -0700 Subject: [PATCH 1956/2143] Workaround a different CPS bug --- .../build/_protobuf/Google.Protobuf.Tools.targets | 9 +++++++++ 1 file changed, 9 insertions(+) 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 b1030ba1f8b..befff4d41c0 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets @@ -39,6 +39,15 @@ + + + + + + + + + - From 76e3489216204951f0115f4f007a782272876286 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 12 Jul 2018 16:36:35 +0200 Subject: [PATCH 1985/2143] csharp: support slice-by-slice deserialization --- .../Grpc.Core.Api/DeserializationContext.cs | 19 +- src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 8 + .../Grpc.Core.Tests/Grpc.Core.Tests.csproj | 4 + .../Internal/AsyncCallServerTest.cs | 12 +- .../Grpc.Core.Tests/Internal/AsyncCallTest.cs | 49 ++-- .../DefaultDeserializationContextTest.cs | 240 ++++++++++++++++++ .../Internal/FakeBufferReaderManager.cs | 118 +++++++++ .../Internal/FakeBufferReaderManagerTest.cs | 121 +++++++++ .../Internal/ReusableSliceBufferTest.cs | 151 +++++++++++ .../Grpc.Core.Tests/Internal/SliceTest.cs | 83 ++++++ src/csharp/Grpc.Core/Grpc.Core.csproj | 9 + src/csharp/Grpc.Core/Internal/AsyncCall.cs | 10 +- .../Grpc.Core/Internal/AsyncCallBase.cs | 15 +- .../Internal/BatchContextSafeHandle.cs | 42 ++- .../Grpc.Core/Internal/CallSafeHandle.cs | 4 +- .../Internal/DefaultDeserializationContext.cs | 64 ++++- src/csharp/Grpc.Core/Internal/INativeCall.cs | 4 +- .../Internal/NativeMethods.Generated.cs | 11 + .../Grpc.Core/Internal/ReusableSliceBuffer.cs | 148 +++++++++++ src/csharp/Grpc.Core/Internal/Slice.cs | 68 +++++ src/csharp/ext/grpc_csharp_ext.c | 46 ++++ src/csharp/tests.json | 4 + .../runtimes/grpc_csharp_ext_dummy_stubs.c | 4 + .../Grpc.Core/Internal/native_methods.include | 1 + 24 files changed, 1181 insertions(+), 54 deletions(-) create mode 100644 src/csharp/Grpc.Core.Tests/Internal/DefaultDeserializationContextTest.cs create mode 100644 src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManager.cs create mode 100644 src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManagerTest.cs create mode 100644 src/csharp/Grpc.Core.Tests/Internal/ReusableSliceBufferTest.cs create mode 100644 src/csharp/Grpc.Core.Tests/Internal/SliceTest.cs create mode 100644 src/csharp/Grpc.Core/Internal/ReusableSliceBuffer.cs create mode 100644 src/csharp/Grpc.Core/Internal/Slice.cs diff --git a/src/csharp/Grpc.Core.Api/DeserializationContext.cs b/src/csharp/Grpc.Core.Api/DeserializationContext.cs index d69e0db5bdf..966bcfa8c8e 100644 --- a/src/csharp/Grpc.Core.Api/DeserializationContext.cs +++ b/src/csharp/Grpc.Core.Api/DeserializationContext.cs @@ -39,7 +39,7 @@ namespace Grpc.Core /// Also, allocating a new buffer each time can put excessive pressure on GC, especially if /// the payload is more than 86700 bytes large (which means the newly allocated buffer will be placed in LOH, /// and LOH object can only be garbage collected via a full ("stop the world") GC run). - /// NOTE: Deserializers are expected not to call this method more than once per received message + /// NOTE: Deserializers are expected not to call this method (or other payload accessor methods) more than once per received message /// (as there is no practical reason for doing so) and DeserializationContext implementations are free to assume so. /// /// byte array containing the entire payload. @@ -47,5 +47,22 @@ namespace Grpc.Core { throw new NotImplementedException(); } + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + /// + /// Gets the entire payload as a ReadOnlySequence. + /// The ReadOnlySequence is only valid for the duration of the deserializer routine and the caller must not access it after the deserializer returns. + /// Using the read only sequence is the most efficient way to access the message payload. Where possible it allows directly + /// accessing the received payload without needing to perform any buffer copying or buffer allocations. + /// NOTE: This method is only available in the netstandard2.0 build of the library. + /// NOTE: Deserializers are expected not to call this method (or other payload accessor methods) more than once per received message + /// (as there is no practical reason for doing so) and DeserializationContext implementations are free to assume so. + /// + /// read only sequence containing the entire payload. + public virtual System.Buffers.ReadOnlySequence PayloadAsReadOnlySequence() + { + throw new NotImplementedException(); + } +#endif } } diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index 6c29530402c..8a32bc757df 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -19,12 +19,20 @@ true + + $(DefineConstants);GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + + + + + + diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index 23e5d7f65ef..7fef2c77091 100755 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -8,6 +8,10 @@ true + + $(DefineConstants);GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + + diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs index 5c7d48f786c..fd221613c04 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs @@ -35,6 +35,7 @@ namespace Grpc.Core.Internal.Tests Server server; FakeNativeCall fakeCall; AsyncCallServer asyncCallServer; + FakeBufferReaderManager fakeBufferReaderManager; [SetUp] public void Init() @@ -52,11 +53,13 @@ namespace Grpc.Core.Internal.Tests Marshallers.StringMarshaller.ContextualSerializer, Marshallers.StringMarshaller.ContextualDeserializer, server); asyncCallServer.InitializeForTesting(fakeCall); + fakeBufferReaderManager = new FakeBufferReaderManager(); } [TearDown] public void Cleanup() { + fakeBufferReaderManager.Dispose(); server.ShutdownAsync().Wait(); } @@ -77,7 +80,7 @@ namespace Grpc.Core.Internal.Tests var moveNextTask = requestStream.MoveNext(); fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); Assert.IsFalse(moveNextTask.Result); AssertFinished(asyncCallServer, fakeCall, finishedTask); @@ -107,7 +110,7 @@ namespace Grpc.Core.Internal.Tests // if a read completion's success==false, the request stream will silently finish // and we rely on C core cancelling the call. var moveNextTask = requestStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(false, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(false, CreateNullResponse()); Assert.IsFalse(moveNextTask.Result); fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true); @@ -182,5 +185,10 @@ namespace Grpc.Core.Internal.Tests Assert.IsTrue(finishedTask.IsCompleted); Assert.DoesNotThrow(() => finishedTask.Wait()); } + + IBufferReader CreateNullResponse() + { + return fakeBufferReaderManager.CreateNullPayloadBufferReader(); + } } } diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs index 775849d89b6..78c7f3ad5bb 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Grpc.Core.Internal; +using Grpc.Core.Utils; using NUnit.Framework; namespace Grpc.Core.Internal.Tests @@ -33,6 +34,7 @@ namespace Grpc.Core.Internal.Tests Channel channel; FakeNativeCall fakeCall; AsyncCall asyncCall; + FakeBufferReaderManager fakeBufferReaderManager; [SetUp] public void Init() @@ -43,12 +45,14 @@ namespace Grpc.Core.Internal.Tests var callDetails = new CallInvocationDetails(channel, "someMethod", null, Marshallers.StringMarshaller, Marshallers.StringMarshaller, new CallOptions()); asyncCall = new AsyncCall(callDetails, fakeCall); + fakeBufferReaderManager = new FakeBufferReaderManager(); } [TearDown] public void Cleanup() { channel.ShutdownAsync().Wait(); + fakeBufferReaderManager.Dispose(); } [Test] @@ -87,7 +91,7 @@ namespace Grpc.Core.Internal.Tests var resultTask = asyncCall.UnaryCallAsync("request1"); fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.InvalidArgument), - null, + CreateNullResponse(), new Metadata()); AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument); @@ -168,7 +172,7 @@ namespace Grpc.Core.Internal.Tests var resultTask = asyncCall.ClientStreamingCallAsync(); fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.InvalidArgument), - null, + CreateNullResponse(), new Metadata()); AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument); @@ -214,7 +218,7 @@ namespace Grpc.Core.Internal.Tests fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.Internal), - null, + CreateNullResponse(), new Metadata()); var ex = Assert.ThrowsAsync(async () => await writeTask); @@ -233,7 +237,7 @@ namespace Grpc.Core.Internal.Tests fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.Internal), - null, + CreateNullResponse(), new Metadata()); fakeCall.SendCompletionCallback.OnSendCompletion(false); @@ -259,7 +263,7 @@ namespace Grpc.Core.Internal.Tests fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.Internal), - null, + CreateNullResponse(), new Metadata()); var ex = Assert.ThrowsAsync(async () => await writeTask); @@ -357,7 +361,7 @@ namespace Grpc.Core.Internal.Tests fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.Cancelled), - null, + CreateNullResponse(), new Metadata()); AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Cancelled); @@ -390,7 +394,7 @@ namespace Grpc.Core.Internal.Tests fakeCall.ReceivedResponseHeadersCallback.OnReceivedResponseHeaders(true, new Metadata()); Assert.AreEqual(0, asyncCall.ResponseHeadersAsync.Result.Count); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); @@ -405,7 +409,7 @@ namespace Grpc.Core.Internal.Tests // try alternative order of completions fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); } @@ -417,7 +421,7 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ClientResponseStream(asyncCall); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(false, null); // after a failed read, we rely on C core to deliver appropriate status code. + fakeCall.ReceivedMessageCallback.OnReceivedMessage(false, CreateNullResponse()); // after a failed read, we rely on C core to deliver appropriate status code. fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Internal)); AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.Internal); @@ -441,7 +445,7 @@ namespace Grpc.Core.Internal.Tests var readTask3 = responseStream.MoveNext(); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask3); } @@ -479,7 +483,7 @@ namespace Grpc.Core.Internal.Tests Assert.DoesNotThrowAsync(async () => await writeTask1); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); @@ -493,7 +497,7 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ClientResponseStream(asyncCall); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); @@ -511,7 +515,7 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ClientResponseStream(asyncCall); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); @@ -533,7 +537,7 @@ namespace Grpc.Core.Internal.Tests Assert.IsFalse(writeTask.IsCompleted); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.PermissionDenied)); var ex = Assert.ThrowsAsync(async () => await writeTask); @@ -552,7 +556,7 @@ namespace Grpc.Core.Internal.Tests var writeTask = requestStream.WriteAsync("request1"); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.PermissionDenied)); fakeCall.SendCompletionCallback.OnSendCompletion(false); @@ -576,7 +580,7 @@ namespace Grpc.Core.Internal.Tests Assert.ThrowsAsync(typeof(TaskCanceledException), async () => await writeTask); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled)); AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.Cancelled); @@ -597,7 +601,7 @@ namespace Grpc.Core.Internal.Tests Assert.AreEqual("response1", responseStream.Current); var readTask2 = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled)); AssertStreamingResponseError(asyncCall, fakeCall, readTask2, StatusCode.Cancelled); @@ -618,7 +622,7 @@ namespace Grpc.Core.Internal.Tests Assert.AreEqual("response1", responseStream.Current); var readTask2 = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled)); AssertStreamingResponseError(asyncCall, fakeCall, readTask2, StatusCode.Cancelled); @@ -638,9 +642,14 @@ namespace Grpc.Core.Internal.Tests return new ClientSideStatus(new Status(statusCode, ""), new Metadata()); } - byte[] CreateResponsePayload() + IBufferReader CreateResponsePayload() { - return Marshallers.StringMarshaller.Serializer("response1"); + return fakeBufferReaderManager.CreateSingleSegmentBufferReader(Marshallers.StringMarshaller.Serializer("response1")); + } + + IBufferReader CreateNullResponse() + { + return fakeBufferReaderManager.CreateNullPayloadBufferReader(); } static void AssertUnaryResponseSuccess(AsyncCall asyncCall, FakeNativeCall fakeCall, Task resultTask) diff --git a/src/csharp/Grpc.Core.Tests/Internal/DefaultDeserializationContextTest.cs b/src/csharp/Grpc.Core.Tests/Internal/DefaultDeserializationContextTest.cs new file mode 100644 index 00000000000..63baab31624 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/Internal/DefaultDeserializationContextTest.cs @@ -0,0 +1,240 @@ +#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 Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Utils; +using NUnit.Framework; + +using System.Runtime.InteropServices; + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY +using System.Buffers; +#endif + +namespace Grpc.Core.Internal.Tests +{ + public class DefaultDeserializationContextTest + { + FakeBufferReaderManager fakeBufferReaderManager; + + [SetUp] + public void Init() + { + fakeBufferReaderManager = new FakeBufferReaderManager(); + } + + [TearDown] + public void Cleanup() + { + fakeBufferReaderManager.Dispose(); + } + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + [TestCase] + public void PayloadAsReadOnlySequence_ZeroSegmentPayload() + { + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List {})); + + Assert.AreEqual(0, context.PayloadLength); + + var sequence = context.PayloadAsReadOnlySequence(); + + Assert.AreEqual(ReadOnlySequence.Empty, sequence); + Assert.IsTrue(sequence.IsEmpty); + Assert.IsTrue(sequence.IsSingleSegment); + } + + [TestCase(0)] + [TestCase(1)] + [TestCase(10)] + [TestCase(100)] + [TestCase(1000)] + public void PayloadAsReadOnlySequence_SingleSegmentPayload(int segmentLength) + { + var origBuffer = GetTestBuffer(segmentLength); + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer)); + + Assert.AreEqual(origBuffer.Length, context.PayloadLength); + + var sequence = context.PayloadAsReadOnlySequence(); + + Assert.AreEqual(origBuffer.Length, sequence.Length); + Assert.AreEqual(origBuffer.Length, sequence.First.Length); + Assert.IsTrue(sequence.IsSingleSegment); + CollectionAssert.AreEqual(origBuffer, sequence.First.ToArray()); + } + + [TestCase(0, 5, 10)] + [TestCase(1, 1, 1)] + [TestCase(10, 100, 1000)] + [TestCase(100, 100, 10)] + [TestCase(1000, 1000, 1000)] + public void PayloadAsReadOnlySequence_MultiSegmentPayload(int segmentLen1, int segmentLen2, int segmentLen3) + { + var origBuffer1 = GetTestBuffer(segmentLen1); + var origBuffer2 = GetTestBuffer(segmentLen2); + var origBuffer3 = GetTestBuffer(segmentLen3); + int totalLen = origBuffer1.Length + origBuffer2.Length + origBuffer3.Length; + + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List { origBuffer1, origBuffer2, origBuffer3 })); + + Assert.AreEqual(totalLen, context.PayloadLength); + + var sequence = context.PayloadAsReadOnlySequence(); + + Assert.AreEqual(totalLen, sequence.Length); + + var segmentEnumerator = sequence.GetEnumerator(); + + Assert.IsTrue(segmentEnumerator.MoveNext()); + CollectionAssert.AreEqual(origBuffer1, segmentEnumerator.Current.ToArray()); + + Assert.IsTrue(segmentEnumerator.MoveNext()); + CollectionAssert.AreEqual(origBuffer2, segmentEnumerator.Current.ToArray()); + + Assert.IsTrue(segmentEnumerator.MoveNext()); + CollectionAssert.AreEqual(origBuffer3, segmentEnumerator.Current.ToArray()); + + Assert.IsFalse(segmentEnumerator.MoveNext()); + } +#endif + + [TestCase] + public void NullPayloadNotAllowed() + { + var context = new DefaultDeserializationContext(); + Assert.Throws(typeof(InvalidOperationException), () => context.Initialize(fakeBufferReaderManager.CreateNullPayloadBufferReader())); + } + + [TestCase] + public void PayloadAsNewByteBuffer_ZeroSegmentPayload() + { + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List {})); + + Assert.AreEqual(0, context.PayloadLength); + + var payload = context.PayloadAsNewBuffer(); + Assert.AreEqual(0, payload.Length); + } + + [TestCase(0)] + [TestCase(1)] + [TestCase(10)] + [TestCase(100)] + [TestCase(1000)] + public void PayloadAsNewByteBuffer_SingleSegmentPayload(int segmentLength) + { + var origBuffer = GetTestBuffer(segmentLength); + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer)); + + Assert.AreEqual(origBuffer.Length, context.PayloadLength); + + var payload = context.PayloadAsNewBuffer(); + CollectionAssert.AreEqual(origBuffer, payload); + } + + [TestCase(0, 5, 10)] + [TestCase(1, 1, 1)] + [TestCase(10, 100, 1000)] + [TestCase(100, 100, 10)] + [TestCase(1000, 1000, 1000)] + public void PayloadAsNewByteBuffer_MultiSegmentPayload(int segmentLen1, int segmentLen2, int segmentLen3) + { + var origBuffer1 = GetTestBuffer(segmentLen1); + var origBuffer2 = GetTestBuffer(segmentLen2); + var origBuffer3 = GetTestBuffer(segmentLen3); + + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List { origBuffer1, origBuffer2, origBuffer3 })); + + var payload = context.PayloadAsNewBuffer(); + + var concatenatedOrigBuffers = new List(); + concatenatedOrigBuffers.AddRange(origBuffer1); + concatenatedOrigBuffers.AddRange(origBuffer2); + concatenatedOrigBuffers.AddRange(origBuffer3); + + Assert.AreEqual(concatenatedOrigBuffers.Count, context.PayloadLength); + Assert.AreEqual(concatenatedOrigBuffers.Count, payload.Length); + CollectionAssert.AreEqual(concatenatedOrigBuffers, payload); + } + + [TestCase] + public void GetPayloadMultipleTimesIsIllegal() + { + var origBuffer = GetTestBuffer(100); + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer)); + + Assert.AreEqual(origBuffer.Length, context.PayloadLength); + + var payload = context.PayloadAsNewBuffer(); + CollectionAssert.AreEqual(origBuffer, payload); + + // Getting payload multiple times is illegal + Assert.Throws(typeof(InvalidOperationException), () => context.PayloadAsNewBuffer()); +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + Assert.Throws(typeof(InvalidOperationException), () => context.PayloadAsReadOnlySequence()); +#endif + } + + [TestCase] + public void ResetContextAndReinitialize() + { + var origBuffer = GetTestBuffer(100); + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer)); + + Assert.AreEqual(origBuffer.Length, context.PayloadLength); + + // Reset invalidates context + context.Reset(); + + Assert.AreEqual(0, context.PayloadLength); + Assert.Throws(typeof(NullReferenceException), () => context.PayloadAsNewBuffer()); +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + Assert.Throws(typeof(NullReferenceException), () => context.PayloadAsReadOnlySequence()); +#endif + + // Previously reset context can be initialized again + var origBuffer2 = GetTestBuffer(50); + context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer2)); + + Assert.AreEqual(origBuffer2.Length, context.PayloadLength); + CollectionAssert.AreEqual(origBuffer2, context.PayloadAsNewBuffer()); + } + + private byte[] GetTestBuffer(int length) + { + var testBuffer = new byte[length]; + for (int i = 0; i < testBuffer.Length; i++) + { + testBuffer[i] = (byte) i; + } + return testBuffer; + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManager.cs b/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManager.cs new file mode 100644 index 00000000000..d8d0c0a6354 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManager.cs @@ -0,0 +1,118 @@ +#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; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +using Grpc.Core.Internal; +using Grpc.Core.Utils; + +namespace Grpc.Core.Internal.Tests +{ + // Creates instances of fake IBufferReader. All created instances will become invalid once Dispose is called. + internal class FakeBufferReaderManager : IDisposable + { + List pinnedHandles = new List(); + bool disposed = false; + public IBufferReader CreateSingleSegmentBufferReader(byte[] data) + { + return CreateMultiSegmentBufferReader(new List { data }); + } + + public IBufferReader CreateMultiSegmentBufferReader(IEnumerable dataSegments) + { + GrpcPreconditions.CheckState(!disposed); + GrpcPreconditions.CheckNotNull(dataSegments); + var segments = new List(); + foreach (var data in dataSegments) + { + GrpcPreconditions.CheckNotNull(data); + segments.Add(GCHandle.Alloc(data, GCHandleType.Pinned)); + } + pinnedHandles.AddRange(segments); // all the allocated GCHandles will be freed on Dispose() + return new FakeBufferReader(segments); + } + + public IBufferReader CreateNullPayloadBufferReader() + { + GrpcPreconditions.CheckState(!disposed); + return new FakeBufferReader(null); + } + + public void Dispose() + { + if (!disposed) + { + disposed = true; + for (int i = 0; i < pinnedHandles.Count; i++) + { + pinnedHandles[i].Free(); + } + } + } + + private class FakeBufferReader : IBufferReader + { + readonly List bufferSegments; + readonly int? totalLength; + readonly IEnumerator segmentEnumerator; + + public FakeBufferReader(List bufferSegments) + { + this.bufferSegments = bufferSegments; + this.totalLength = ComputeTotalLength(bufferSegments); + this.segmentEnumerator = bufferSegments?.GetEnumerator(); + } + + public int? TotalLength => totalLength; + + public bool TryGetNextSlice(out Slice slice) + { + GrpcPreconditions.CheckNotNull(bufferSegments); + if (!segmentEnumerator.MoveNext()) + { + slice = default(Slice); + return false; + } + + var segment = segmentEnumerator.Current; + int sliceLen = ((byte[]) segment.Target).Length; + slice = new Slice(segment.AddrOfPinnedObject(), sliceLen); + return true; + } + + static int? ComputeTotalLength(List bufferSegments) + { + if (bufferSegments == null) + { + return null; + } + + int sum = 0; + foreach (var segment in bufferSegments) + { + var data = (byte[]) segment.Target; + sum += data.Length; + } + return sum; + } + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManagerTest.cs b/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManagerTest.cs new file mode 100644 index 00000000000..7c4ff652bd3 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManagerTest.cs @@ -0,0 +1,121 @@ +#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; +using System.Collections.Generic; +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Utils; +using NUnit.Framework; + +namespace Grpc.Core.Internal.Tests +{ + public class FakeBufferReaderManagerTest + { + FakeBufferReaderManager fakeBufferReaderManager; + + [SetUp] + public void Init() + { + fakeBufferReaderManager = new FakeBufferReaderManager(); + } + + [TearDown] + public void Cleanup() + { + fakeBufferReaderManager.Dispose(); + } + + [TestCase] + public void NullPayload() + { + var fakeBufferReader = fakeBufferReaderManager.CreateNullPayloadBufferReader(); + Assert.IsFalse(fakeBufferReader.TotalLength.HasValue); + Assert.Throws(typeof(ArgumentNullException), () => fakeBufferReader.TryGetNextSlice(out Slice slice)); + } + [TestCase] + public void ZeroSegmentPayload() + { + var fakeBufferReader = fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List {}); + Assert.AreEqual(0, fakeBufferReader.TotalLength.Value); + Assert.IsFalse(fakeBufferReader.TryGetNextSlice(out Slice slice)); + } + + [TestCase(0)] + [TestCase(1)] + [TestCase(10)] + [TestCase(30)] + [TestCase(100)] + [TestCase(1000)] + public void SingleSegmentPayload(int bufferLen) + { + var origBuffer = GetTestBuffer(bufferLen); + var fakeBufferReader = fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer); + Assert.AreEqual(origBuffer.Length, fakeBufferReader.TotalLength.Value); + + Assert.IsTrue(fakeBufferReader.TryGetNextSlice(out Slice slice)); + AssertSliceDataEqual(origBuffer, slice); + + Assert.IsFalse(fakeBufferReader.TryGetNextSlice(out Slice slice2)); + } + + [TestCase(0, 5, 10)] + [TestCase(1, 1, 1)] + [TestCase(10, 100, 1000)] + [TestCase(100, 100, 10)] + [TestCase(1000, 1000, 1000)] + public void MultiSegmentPayload(int segmentLen1, int segmentLen2, int segmentLen3) + { + var origBuffer1 = GetTestBuffer(segmentLen1); + var origBuffer2 = GetTestBuffer(segmentLen2); + var origBuffer3 = GetTestBuffer(segmentLen3); + var fakeBufferReader = fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List { origBuffer1, origBuffer2, origBuffer3 }); + + Assert.AreEqual(origBuffer1.Length + origBuffer2.Length + origBuffer3.Length, fakeBufferReader.TotalLength.Value); + + Assert.IsTrue(fakeBufferReader.TryGetNextSlice(out Slice slice1)); + AssertSliceDataEqual(origBuffer1, slice1); + + Assert.IsTrue(fakeBufferReader.TryGetNextSlice(out Slice slice2)); + AssertSliceDataEqual(origBuffer2, slice2); + + Assert.IsTrue(fakeBufferReader.TryGetNextSlice(out Slice slice3)); + AssertSliceDataEqual(origBuffer3, slice3); + + Assert.IsFalse(fakeBufferReader.TryGetNextSlice(out Slice slice4)); + } + + private void AssertSliceDataEqual(byte[] expected, Slice actual) + { + var actualSliceData = new byte[actual.Length]; + actual.CopyTo(new ArraySegment(actualSliceData)); + CollectionAssert.AreEqual(expected, actualSliceData); + } + + // create a buffer of given size and fill it with some data + private byte[] GetTestBuffer(int length) + { + var testBuffer = new byte[length]; + for (int i = 0; i < testBuffer.Length; i++) + { + testBuffer[i] = (byte) i; + } + return testBuffer; + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/Internal/ReusableSliceBufferTest.cs b/src/csharp/Grpc.Core.Tests/Internal/ReusableSliceBufferTest.cs new file mode 100644 index 00000000000..7630785aef4 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/Internal/ReusableSliceBufferTest.cs @@ -0,0 +1,151 @@ +#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; +using System.Collections.Generic; +using System.Linq; +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Utils; +using NUnit.Framework; + +using System.Runtime.InteropServices; + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY +using System.Buffers; +#endif + +namespace Grpc.Core.Internal.Tests +{ + // Converts IBufferReader into instances of ReadOnlySequence + // Objects representing the sequence segments are cached to decrease GC load. + public class ReusableSliceBufferTest + { + FakeBufferReaderManager fakeBufferReaderManager; + + [SetUp] + public void Init() + { + fakeBufferReaderManager = new FakeBufferReaderManager(); + } + + [TearDown] + public void Cleanup() + { + fakeBufferReaderManager.Dispose(); + } + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + [TestCase] + public void NullPayload() + { + var sliceBuffer = new ReusableSliceBuffer(); + Assert.Throws(typeof(ArgumentNullException), () => sliceBuffer.PopulateFrom(fakeBufferReaderManager.CreateNullPayloadBufferReader())); + } + + [TestCase] + public void ZeroSegmentPayload() + { + var sliceBuffer = new ReusableSliceBuffer(); + var sequence = sliceBuffer.PopulateFrom(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List {})); + + Assert.AreEqual(ReadOnlySequence.Empty, sequence); + Assert.IsTrue(sequence.IsEmpty); + Assert.IsTrue(sequence.IsSingleSegment); + } + + [TestCase] + public void SegmentsAreCached() + { + var bufferSegments1 = Enumerable.Range(0, 100).Select((_) => GetTestBuffer(50)).ToList(); + var bufferSegments2 = Enumerable.Range(0, 100).Select((_) => GetTestBuffer(50)).ToList(); + + var sliceBuffer = new ReusableSliceBuffer(); + + var sequence1 = sliceBuffer.PopulateFrom(fakeBufferReaderManager.CreateMultiSegmentBufferReader(bufferSegments1)); + var memoryManagers1 = GetMemoryManagersForSequenceSegments(sequence1); + + sliceBuffer.Invalidate(); + + var sequence2 = sliceBuffer.PopulateFrom(fakeBufferReaderManager.CreateMultiSegmentBufferReader(bufferSegments2)); + var memoryManagers2 = GetMemoryManagersForSequenceSegments(sequence2); + + // check memory managers are identical objects (i.e. they've been reused) + CollectionAssert.AreEquivalent(memoryManagers1, memoryManagers2); + } + + [TestCase] + public void MultiSegmentPayload_LotsOfSegments() + { + var bufferSegments = Enumerable.Range(0, ReusableSliceBuffer.MaxCachedSegments + 100).Select((_) => GetTestBuffer(10)).ToList(); + + var sliceBuffer = new ReusableSliceBuffer(); + var sequence = sliceBuffer.PopulateFrom(fakeBufferReaderManager.CreateMultiSegmentBufferReader(bufferSegments)); + + int index = 0; + foreach (var memory in sequence) + { + CollectionAssert.AreEqual(bufferSegments[index], memory.ToArray()); + index ++; + } + } + + [TestCase] + public void InvalidateMakesSequenceUnusable() + { + var origBuffer = GetTestBuffer(100); + + var sliceBuffer = new ReusableSliceBuffer(); + var sequence = sliceBuffer.PopulateFrom(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List { origBuffer })); + + Assert.AreEqual(origBuffer.Length, sequence.Length); + + sliceBuffer.Invalidate(); + + // Invalidate with make the returned sequence completely unusable and broken, users must not use it beyond the deserializer functions. + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { var first = sequence.First; }); + } + + private List> GetMemoryManagersForSequenceSegments(ReadOnlySequence sequence) + { + var result = new List>(); + foreach (var memory in sequence) + { + Assert.IsTrue(MemoryMarshal.TryGetMemoryManager(memory, out MemoryManager memoryManager)); + result.Add(memoryManager); + } + return result; + } +#else + [TestCase] + public void OnlySupportedOnNetCore() + { + // Test case needs to exist to make C# sanity test happy. + } +#endif + private byte[] GetTestBuffer(int length) + { + var testBuffer = new byte[length]; + for (int i = 0; i < testBuffer.Length; i++) + { + testBuffer[i] = (byte) i; + } + return testBuffer; + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/Internal/SliceTest.cs b/src/csharp/Grpc.Core.Tests/Internal/SliceTest.cs new file mode 100644 index 00000000000..eb090bbfa50 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/Internal/SliceTest.cs @@ -0,0 +1,83 @@ +#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; +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Utils; +using NUnit.Framework; + +using System.Runtime.InteropServices; + +namespace Grpc.Core.Internal.Tests +{ + public class SliceTest + { + [TestCase(0)] + [TestCase(1)] + [TestCase(10)] + [TestCase(100)] + [TestCase(1000)] + public void SliceFromNativePtr_CopyToArraySegment(int bufferLength) + { + var origBuffer = GetTestBuffer(bufferLength); + var gcHandle = GCHandle.Alloc(origBuffer, GCHandleType.Pinned); + try + { + var slice = new Slice(gcHandle.AddrOfPinnedObject(), origBuffer.Length); + Assert.AreEqual(bufferLength, slice.Length); + + var newBuffer = new byte[bufferLength]; + slice.CopyTo(new ArraySegment(newBuffer)); + CollectionAssert.AreEqual(origBuffer, newBuffer); + } + finally + { + gcHandle.Free(); + } + } + + [TestCase] + public void SliceFromNativePtr_CopyToArraySegmentTooSmall() + { + var origBuffer = GetTestBuffer(100); + var gcHandle = GCHandle.Alloc(origBuffer, GCHandleType.Pinned); + try + { + var slice = new Slice(gcHandle.AddrOfPinnedObject(), origBuffer.Length); + var tooSmall = new byte[origBuffer.Length - 1]; + Assert.Catch(typeof(ArgumentException), () => slice.CopyTo(new ArraySegment(tooSmall))); + } + finally + { + gcHandle.Free(); + } + } + + // create a buffer of given size and fill it with some data + private byte[] GetTestBuffer(int length) + { + var testBuffer = new byte[length]; + for (int i = 0; i < testBuffer.Length; i++) + { + testBuffer[i] = (byte) i; + } + return testBuffer; + } + } +} diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index b7c191ea6a9..afd60e73a21 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -19,6 +19,15 @@ true + + true + + + + 7.2 + $(DefineConstants);GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + + diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 785081c341a..a1c688140d1 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -111,7 +111,7 @@ namespace Grpc.Core.Internal { using (profiler.NewScope("AsyncCall.UnaryCall.HandleBatch")) { - HandleUnaryResponse(success, ctx.GetReceivedStatusOnClient(), ctx.GetReceivedMessage(), ctx.GetReceivedInitialMetadata()); + HandleUnaryResponse(success, ctx.GetReceivedStatusOnClient(), ctx.GetReceivedMessageReader(), ctx.GetReceivedInitialMetadata()); } } catch (Exception e) @@ -537,14 +537,14 @@ namespace Grpc.Core.Internal /// /// Handler for unary response completion. /// - private void HandleUnaryResponse(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders) + private void HandleUnaryResponse(bool success, ClientSideStatus receivedStatus, IBufferReader receivedMessageReader, Metadata responseHeaders) { // NOTE: because this event is a result of batch containing GRPC_OP_RECV_STATUS_ON_CLIENT, // success will be always set to true. TaskCompletionSource delayedStreamingWriteTcs = null; TResponse msg = default(TResponse); - var deserializeException = TryDeserialize(receivedMessage, out msg); + var deserializeException = TryDeserialize(receivedMessageReader, out msg); bool releasedResources; lock (myLock) @@ -634,9 +634,9 @@ namespace Grpc.Core.Internal IUnaryResponseClientCallback UnaryResponseClientCallback => this; - void IUnaryResponseClientCallback.OnUnaryResponseClient(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders) + void IUnaryResponseClientCallback.OnUnaryResponseClient(bool success, ClientSideStatus receivedStatus, IBufferReader receivedMessageReader, Metadata responseHeaders) { - HandleUnaryResponse(success, receivedStatus, receivedMessage, responseHeaders); + HandleUnaryResponse(success, receivedStatus, receivedMessageReader, responseHeaders); } IReceivedStatusOnClientCallback ReceivedStatusOnClientCallback => this; diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs index 39c9f7c6160..9497371cc1b 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs @@ -228,12 +228,12 @@ namespace Grpc.Core.Internal } } - protected Exception TryDeserialize(byte[] payload, out TRead msg) + protected Exception TryDeserialize(IBufferReader reader, out TRead msg) { DefaultDeserializationContext context = null; try { - context = DefaultDeserializationContext.GetInitializedThreadLocal(payload); + context = DefaultDeserializationContext.GetInitializedThreadLocal(reader); msg = deserializer(context); return null; } @@ -245,7 +245,6 @@ namespace Grpc.Core.Internal finally { context?.Reset(); - } } @@ -333,21 +332,21 @@ namespace Grpc.Core.Internal /// /// Handles streaming read completion. /// - protected void HandleReadFinished(bool success, byte[] receivedMessage) + protected void HandleReadFinished(bool success, IBufferReader receivedMessageReader) { // if success == false, received message will be null. It that case we will // treat this completion as the last read an rely on C core to handle the failed // read (e.g. deliver approriate statusCode on the clientside). TRead msg = default(TRead); - var deserializeException = (success && receivedMessage != null) ? TryDeserialize(receivedMessage, out msg) : null; + var deserializeException = (success && receivedMessageReader.TotalLength.HasValue) ? TryDeserialize(receivedMessageReader, out msg) : null; TaskCompletionSource origTcs = null; bool releasedResources; lock (myLock) { origTcs = streamingReadTcs; - if (receivedMessage == null) + if (!receivedMessageReader.TotalLength.HasValue) { // This was the last read. readingDone = true; @@ -391,9 +390,9 @@ namespace Grpc.Core.Internal IReceivedMessageCallback ReceivedMessageCallback => this; - void IReceivedMessageCallback.OnReceivedMessage(bool success, byte[] receivedMessage) + void IReceivedMessageCallback.OnReceivedMessage(bool success, IBufferReader receivedMessageReader) { - HandleReadFinished(success, receivedMessage); + HandleReadFinished(success, receivedMessageReader); } } } diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs index 085e7faf595..61af26e9f90 100644 --- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs @@ -30,10 +30,17 @@ namespace Grpc.Core.Internal void OnComplete(bool success); } + internal interface IBufferReader + { + int? TotalLength { get; } + + bool TryGetNextSlice(out Slice slice); + } + /// /// grpcsharp_batch_context /// - internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback, IPooledObject + internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback, IPooledObject, IBufferReader { static readonly NativeMethods Native = NativeMethods.Get(); static readonly ILogger Logger = GrpcEnvironment.Logger.ForType(); @@ -106,6 +113,25 @@ namespace Grpc.Core.Internal return data; } + public bool GetReceivedMessageNextSlicePeek(out Slice slice) + { + UIntPtr sliceLen; + IntPtr sliceDataPtr; + + if (0 == Native.grpcsharp_batch_context_recv_message_next_slice_peek(this, out sliceLen, out sliceDataPtr)) + { + slice = default(Slice); + return false; + } + slice = new Slice(sliceDataPtr, (int) sliceLen); + return true; + } + + public IBufferReader GetReceivedMessageReader() + { + return this; + } + // Gets data of receive_close_on_server completion. public bool GetReceivedCloseOnServerCancelled() { @@ -153,6 +179,20 @@ namespace Grpc.Core.Internal } } + int? IBufferReader.TotalLength + { + get + { + var len = Native.grpcsharp_batch_context_recv_message_length(this); + return len != new IntPtr(-1) ? (int?) len : null; + } + } + + bool IBufferReader.TryGetNextSlice(out Slice slice) + { + return GetReceivedMessageNextSlicePeek(out slice); + } + struct CompletionCallbackData { public CompletionCallbackData(BatchCompletionDelegate callback, object state) diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index a3ef3e61ee1..858d2a69605 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -35,11 +35,11 @@ namespace Grpc.Core.Internal // Completion handlers are pre-allocated to avoid unneccessary delegate allocations. // The "state" field is used to store the actual callback to invoke. static readonly BatchCompletionDelegate CompletionHandler_IUnaryResponseClientCallback = - (success, context, state) => ((IUnaryResponseClientCallback)state).OnUnaryResponseClient(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()); + (success, context, state) => ((IUnaryResponseClientCallback)state).OnUnaryResponseClient(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessageReader(), context.GetReceivedInitialMetadata()); static readonly BatchCompletionDelegate CompletionHandler_IReceivedStatusOnClientCallback = (success, context, state) => ((IReceivedStatusOnClientCallback)state).OnReceivedStatusOnClient(success, context.GetReceivedStatusOnClient()); static readonly BatchCompletionDelegate CompletionHandler_IReceivedMessageCallback = - (success, context, state) => ((IReceivedMessageCallback)state).OnReceivedMessage(success, context.GetReceivedMessage()); + (success, context, state) => ((IReceivedMessageCallback)state).OnReceivedMessage(success, context.GetReceivedMessageReader()); static readonly BatchCompletionDelegate CompletionHandler_IReceivedResponseHeadersCallback = (success, context, state) => ((IReceivedResponseHeadersCallback)state).OnReceivedResponseHeaders(success, context.GetReceivedInitialMetadata()); static readonly BatchCompletionDelegate CompletionHandler_ISendCompletionCallback = diff --git a/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs index 7ace80e8d53..bac7bbe4c59 100644 --- a/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs @@ -20,6 +20,10 @@ using Grpc.Core.Utils; using System; using System.Threading; +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY +using System.Buffers; +#endif + namespace Grpc.Core.Internal { internal class DefaultDeserializationContext : DeserializationContext @@ -27,40 +31,74 @@ namespace Grpc.Core.Internal static readonly ThreadLocal threadLocalInstance = new ThreadLocal(() => new DefaultDeserializationContext(), false); - byte[] payload; - bool alreadyCalledPayloadAsNewBuffer; + IBufferReader bufferReader; + int payloadLength; +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + ReusableSliceBuffer cachedSliceBuffer = new ReusableSliceBuffer(); +#endif public DefaultDeserializationContext() { Reset(); } - public override int PayloadLength => payload.Length; + public override int PayloadLength => payloadLength; public override byte[] PayloadAsNewBuffer() { - GrpcPreconditions.CheckState(!alreadyCalledPayloadAsNewBuffer); - alreadyCalledPayloadAsNewBuffer = true; - return payload; + var buffer = new byte[payloadLength]; + FillContinguousBuffer(bufferReader, buffer); + return buffer; } - public void Initialize(byte[] payload) +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + public override ReadOnlySequence PayloadAsReadOnlySequence() { - this.payload = GrpcPreconditions.CheckNotNull(payload); - this.alreadyCalledPayloadAsNewBuffer = false; + var sequence = cachedSliceBuffer.PopulateFrom(bufferReader); + GrpcPreconditions.CheckState(sequence.Length == payloadLength); + return sequence; + } +#endif + + public void Initialize(IBufferReader bufferReader) + { + this.bufferReader = GrpcPreconditions.CheckNotNull(bufferReader); + this.payloadLength = bufferReader.TotalLength.Value; // payload must not be null } public void Reset() { - this.payload = null; - this.alreadyCalledPayloadAsNewBuffer = true; // mark payload as read + this.bufferReader = null; + this.payloadLength = 0; +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + this.cachedSliceBuffer.Invalidate(); +#endif } - public static DefaultDeserializationContext GetInitializedThreadLocal(byte[] payload) + public static DefaultDeserializationContext GetInitializedThreadLocal(IBufferReader bufferReader) { var instance = threadLocalInstance.Value; - instance.Initialize(payload); + instance.Initialize(bufferReader); return instance; } + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + private void FillContinguousBuffer(IBufferReader reader, byte[] destination) + { + PayloadAsReadOnlySequence().CopyTo(new Span(destination)); + } +#else + private void FillContinguousBuffer(IBufferReader reader, byte[] destination) + { + int offset = 0; + while (reader.TryGetNextSlice(out Slice slice)) + { + slice.CopyTo(new ArraySegment(destination, offset, (int)slice.Length)); + offset += (int)slice.Length; + } + // check that we filled the entire destination + GrpcPreconditions.CheckState(offset == payloadLength); + } +#endif } } diff --git a/src/csharp/Grpc.Core/Internal/INativeCall.cs b/src/csharp/Grpc.Core/Internal/INativeCall.cs index 5c35b2ba461..98117c6988a 100644 --- a/src/csharp/Grpc.Core/Internal/INativeCall.cs +++ b/src/csharp/Grpc.Core/Internal/INativeCall.cs @@ -22,7 +22,7 @@ namespace Grpc.Core.Internal { internal interface IUnaryResponseClientCallback { - void OnUnaryResponseClient(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders); + void OnUnaryResponseClient(bool success, ClientSideStatus receivedStatus, IBufferReader receivedMessageReader, Metadata responseHeaders); } // Received status for streaming response calls. @@ -33,7 +33,7 @@ namespace Grpc.Core.Internal internal interface IReceivedMessageCallback { - void OnReceivedMessage(bool success, byte[] receivedMessage); + void OnReceivedMessage(bool success, IBufferReader receivedMessageReader); } internal interface IReceivedResponseHeadersCallback diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs index a1387aff562..9752a8e5a05 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs @@ -41,6 +41,7 @@ namespace Grpc.Core.Internal public readonly Delegates.grpcsharp_batch_context_recv_initial_metadata_delegate grpcsharp_batch_context_recv_initial_metadata; public readonly Delegates.grpcsharp_batch_context_recv_message_length_delegate grpcsharp_batch_context_recv_message_length; public readonly Delegates.grpcsharp_batch_context_recv_message_to_buffer_delegate grpcsharp_batch_context_recv_message_to_buffer; + public readonly Delegates.grpcsharp_batch_context_recv_message_next_slice_peek_delegate grpcsharp_batch_context_recv_message_next_slice_peek; public readonly Delegates.grpcsharp_batch_context_recv_status_on_client_status_delegate grpcsharp_batch_context_recv_status_on_client_status; public readonly Delegates.grpcsharp_batch_context_recv_status_on_client_details_delegate grpcsharp_batch_context_recv_status_on_client_details; public readonly Delegates.grpcsharp_batch_context_recv_status_on_client_trailing_metadata_delegate grpcsharp_batch_context_recv_status_on_client_trailing_metadata; @@ -142,6 +143,7 @@ namespace Grpc.Core.Internal this.grpcsharp_batch_context_recv_initial_metadata = GetMethodDelegate(library); this.grpcsharp_batch_context_recv_message_length = GetMethodDelegate(library); this.grpcsharp_batch_context_recv_message_to_buffer = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_message_next_slice_peek = GetMethodDelegate(library); this.grpcsharp_batch_context_recv_status_on_client_status = GetMethodDelegate(library); this.grpcsharp_batch_context_recv_status_on_client_details = GetMethodDelegate(library); this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = GetMethodDelegate(library); @@ -242,6 +244,7 @@ namespace Grpc.Core.Internal this.grpcsharp_batch_context_recv_initial_metadata = DllImportsFromStaticLib.grpcsharp_batch_context_recv_initial_metadata; this.grpcsharp_batch_context_recv_message_length = DllImportsFromStaticLib.grpcsharp_batch_context_recv_message_length; this.grpcsharp_batch_context_recv_message_to_buffer = DllImportsFromStaticLib.grpcsharp_batch_context_recv_message_to_buffer; + this.grpcsharp_batch_context_recv_message_next_slice_peek = DllImportsFromStaticLib.grpcsharp_batch_context_recv_message_next_slice_peek; this.grpcsharp_batch_context_recv_status_on_client_status = DllImportsFromStaticLib.grpcsharp_batch_context_recv_status_on_client_status; this.grpcsharp_batch_context_recv_status_on_client_details = DllImportsFromStaticLib.grpcsharp_batch_context_recv_status_on_client_details; this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = DllImportsFromStaticLib.grpcsharp_batch_context_recv_status_on_client_trailing_metadata; @@ -342,6 +345,7 @@ namespace Grpc.Core.Internal this.grpcsharp_batch_context_recv_initial_metadata = DllImportsFromSharedLib.grpcsharp_batch_context_recv_initial_metadata; this.grpcsharp_batch_context_recv_message_length = DllImportsFromSharedLib.grpcsharp_batch_context_recv_message_length; this.grpcsharp_batch_context_recv_message_to_buffer = DllImportsFromSharedLib.grpcsharp_batch_context_recv_message_to_buffer; + this.grpcsharp_batch_context_recv_message_next_slice_peek = DllImportsFromSharedLib.grpcsharp_batch_context_recv_message_next_slice_peek; this.grpcsharp_batch_context_recv_status_on_client_status = DllImportsFromSharedLib.grpcsharp_batch_context_recv_status_on_client_status; this.grpcsharp_batch_context_recv_status_on_client_details = DllImportsFromSharedLib.grpcsharp_batch_context_recv_status_on_client_details; this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = DllImportsFromSharedLib.grpcsharp_batch_context_recv_status_on_client_trailing_metadata; @@ -445,6 +449,7 @@ namespace Grpc.Core.Internal public delegate IntPtr grpcsharp_batch_context_recv_initial_metadata_delegate(BatchContextSafeHandle ctx); public delegate IntPtr grpcsharp_batch_context_recv_message_length_delegate(BatchContextSafeHandle ctx); public delegate void grpcsharp_batch_context_recv_message_to_buffer_delegate(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen); + public delegate int grpcsharp_batch_context_recv_message_next_slice_peek_delegate(BatchContextSafeHandle ctx, out UIntPtr sliceLen, out IntPtr sliceDataPtr); public delegate StatusCode grpcsharp_batch_context_recv_status_on_client_status_delegate(BatchContextSafeHandle ctx); public delegate IntPtr grpcsharp_batch_context_recv_status_on_client_details_delegate(BatchContextSafeHandle ctx, out UIntPtr detailsLength); public delegate IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata_delegate(BatchContextSafeHandle ctx); @@ -564,6 +569,9 @@ namespace Grpc.Core.Internal [DllImport(ImportName)] public static extern void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen); + [DllImport(ImportName)] + public static extern int grpcsharp_batch_context_recv_message_next_slice_peek(BatchContextSafeHandle ctx, out UIntPtr sliceLen, out IntPtr sliceDataPtr); + [DllImport(ImportName)] public static extern StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx); @@ -860,6 +868,9 @@ namespace Grpc.Core.Internal [DllImport(ImportName)] public static extern void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen); + [DllImport(ImportName)] + public static extern int grpcsharp_batch_context_recv_message_next_slice_peek(BatchContextSafeHandle ctx, out UIntPtr sliceLen, out IntPtr sliceDataPtr); + [DllImport(ImportName)] public static extern StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx); diff --git a/src/csharp/Grpc.Core/Internal/ReusableSliceBuffer.cs b/src/csharp/Grpc.Core/Internal/ReusableSliceBuffer.cs new file mode 100644 index 00000000000..fb8d2e720de --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/ReusableSliceBuffer.cs @@ -0,0 +1,148 @@ +#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 + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + +using Grpc.Core.Utils; +using System; +using System.Threading; + +using System.Buffers; + +namespace Grpc.Core.Internal +{ + internal class ReusableSliceBuffer + { + public const int MaxCachedSegments = 1024; // ~4MB payload for 4K slices + + readonly SliceSegment[] cachedSegments = new SliceSegment[MaxCachedSegments]; + int populatedSegmentCount = 0; + + public ReadOnlySequence PopulateFrom(IBufferReader bufferReader) + { + long offset = 0; + int index = 0; + SliceSegment prevSegment = null; + while (bufferReader.TryGetNextSlice(out Slice slice)) + { + // Initialize cached segment if still null or just allocate a new segment if we already reached MaxCachedSegments + var current = index < cachedSegments.Length ? cachedSegments[index] : new SliceSegment(); + if (current == null) + { + current = cachedSegments[index] = new SliceSegment(); + } + + current.Reset(slice, offset); + prevSegment?.SetNext(current); + + index ++; + offset += slice.Length; + prevSegment = current; + } + populatedSegmentCount = index; + + // Not necessary for ending the ReadOnlySequence, but for making sure we + // don't keep more than MaxCachedSegments alive. + prevSegment?.SetNext(null); + + if (index == 0) + { + return ReadOnlySequence.Empty; + } + + var firstSegment = cachedSegments[0]; + var lastSegment = prevSegment; + return new ReadOnlySequence(firstSegment, 0, lastSegment, lastSegment.Memory.Length); + } + + public void Invalidate() + { + if (populatedSegmentCount == 0) + { + return; + } + var segment = cachedSegments[0]; + while (segment != null) + { + segment.Reset(new Slice(IntPtr.Zero, 0), 0); + segment.SetNext(null); + segment = (SliceSegment) segment.Next; + } + populatedSegmentCount = 0; + } + + // Represents a segment in ReadOnlySequence + // Segment is backed by Slice and the instances are reusable. + private class SliceSegment : ReadOnlySequenceSegment + { + readonly SliceMemoryManager pointerMemoryManager = new SliceMemoryManager(); + + public void Reset(Slice slice, long runningIndex) + { + pointerMemoryManager.Reset(slice); + Memory = pointerMemoryManager.Memory; // maybe not always necessary + RunningIndex = runningIndex; + } + + public void SetNext(ReadOnlySequenceSegment next) + { + Next = next; + } + } + + // Allow creating instances of Memory from Slice. + // Represents a chunk of native memory, but doesn't manage its lifetime. + // Instances of this class are reuseable - they can be reset to point to a different memory chunk. + // That is important to make the instances cacheable (rather then creating new instances + // the old ones will be reused to reduce GC pressure). + private class SliceMemoryManager : MemoryManager + { + private Slice slice; + + public void Reset(Slice slice) + { + this.slice = slice; + } + + public void Reset() + { + Reset(new Slice(IntPtr.Zero, 0)); + } + + public override Span GetSpan() + { + return slice.ToSpanUnsafe(); + } + + public override MemoryHandle Pin(int elementIndex = 0) + { + throw new NotSupportedException(); + } + + public override void Unpin() + { + } + + protected override void Dispose(bool disposing) + { + // NOP + } + } + } +} +#endif diff --git a/src/csharp/Grpc.Core/Internal/Slice.cs b/src/csharp/Grpc.Core/Internal/Slice.cs new file mode 100644 index 00000000000..22eb9537951 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/Slice.cs @@ -0,0 +1,68 @@ +#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.Runtime.InteropServices; +using System.Threading; +using Grpc.Core.Utils; + +namespace Grpc.Core.Internal +{ + /// + /// Slice of native memory. + /// Rough equivalent of grpc_slice (but doesn't support inlined slices, just a pointer to data and length) + /// + internal struct Slice + { + private readonly IntPtr dataPtr; + private readonly int length; + + public Slice(IntPtr dataPtr, int length) + { + this.dataPtr = dataPtr; + this.length = length; + } + + public int Length => length; + + // copies data of the slice to given span. + // there needs to be enough space in the destination buffer + public void CopyTo(ArraySegment destination) + { + Marshal.Copy(dataPtr, destination.Array, destination.Offset, length); + } + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + public Span ToSpanUnsafe() + { + unsafe + { + return new Span((byte*) dataPtr, length); + } + } +#endif + + /// + /// Returns a that represents the current . + /// + public override string ToString() + { + return string.Format("[Slice: dataPtr={0}, length={1}]", dataPtr, length); + } + } +} diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 91d3957dbf0..b42e1e875d2 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -59,12 +59,16 @@ typedef struct grpcsharp_batch_context { } send_status_from_server; grpc_metadata_array recv_initial_metadata; grpc_byte_buffer* recv_message; + grpc_byte_buffer_reader* recv_message_reader; struct { grpc_metadata_array trailing_metadata; grpc_status_code status; grpc_slice status_details; } recv_status_on_client; int recv_close_on_server_cancelled; + + /* reserve space for byte_buffer_reader */ + grpc_byte_buffer_reader reserved_recv_message_reader; } grpcsharp_batch_context; GPR_EXPORT grpcsharp_batch_context* GPR_CALLTYPE @@ -206,6 +210,9 @@ grpcsharp_batch_context_reset(grpcsharp_batch_context* ctx) { grpcsharp_metadata_array_destroy_metadata_only(&(ctx->recv_initial_metadata)); + if (ctx->recv_message_reader) { + grpc_byte_buffer_reader_destroy(ctx->recv_message_reader); + } grpc_byte_buffer_destroy(ctx->recv_message); grpcsharp_metadata_array_destroy_metadata_only( @@ -287,6 +294,45 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_batch_context_recv_message_to_buffer( grpc_byte_buffer_reader_destroy(&reader); } +/* + * Gets the next slice from recv_message byte buffer. + * Returns 1 if a slice was get successfully, 0 if there are no more slices to + * read. Set slice_len to the length of the slice and the slice_data_ptr to + * point to slice's data. Caller must ensure that the byte buffer being read + * from stays alive as long as the data of the slice are being accessed + * (grpc_byte_buffer_reader_peek method is used internally) + * + * Remarks: + * Slices can only be iterated once. + * Initializes recv_message_buffer_reader if it was not initialized yet. + */ +GPR_EXPORT int GPR_CALLTYPE +grpcsharp_batch_context_recv_message_next_slice_peek( + grpcsharp_batch_context* ctx, size_t* slice_len, uint8_t** slice_data_ptr) { + *slice_len = 0; + *slice_data_ptr = NULL; + + if (!ctx->recv_message) { + return 0; + } + + if (!ctx->recv_message_reader) { + ctx->recv_message_reader = &ctx->reserved_recv_message_reader; + GPR_ASSERT(grpc_byte_buffer_reader_init(ctx->recv_message_reader, + ctx->recv_message)); + } + + grpc_slice* slice_ptr; + if (!grpc_byte_buffer_reader_peek(ctx->recv_message_reader, &slice_ptr)) { + return 0; + } + + /* recv_message buffer must not be deleted before all the data is read */ + *slice_len = GRPC_SLICE_LENGTH(*slice_ptr); + *slice_data_ptr = GRPC_SLICE_START_PTR(*slice_ptr); + return 1; +} + GPR_EXPORT grpc_status_code GPR_CALLTYPE grpcsharp_batch_context_recv_status_on_client_status( const grpcsharp_batch_context* ctx) { diff --git a/src/csharp/tests.json b/src/csharp/tests.json index c1e7fc1a6bf..cacdb305d2e 100644 --- a/src/csharp/tests.json +++ b/src/csharp/tests.json @@ -7,8 +7,12 @@ "Grpc.Core.Internal.Tests.ChannelArgsSafeHandleTest", "Grpc.Core.Internal.Tests.CompletionQueueEventTest", "Grpc.Core.Internal.Tests.CompletionQueueSafeHandleTest", + "Grpc.Core.Internal.Tests.DefaultDeserializationContextTest", "Grpc.Core.Internal.Tests.DefaultObjectPoolTest", + "Grpc.Core.Internal.Tests.FakeBufferReaderManagerTest", "Grpc.Core.Internal.Tests.MetadataArraySafeHandleTest", + "Grpc.Core.Internal.Tests.ReusableSliceBufferTest", + "Grpc.Core.Internal.Tests.SliceTest", "Grpc.Core.Internal.Tests.TimespecTest", "Grpc.Core.Tests.AppDomainUnloadTest", "Grpc.Core.Tests.AuthContextTest", 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 0e9d56f5bdf..1da79e2bcad 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 @@ -50,6 +50,10 @@ void grpcsharp_batch_context_recv_message_to_buffer() { fprintf(stderr, "Should never reach here"); abort(); } +void grpcsharp_batch_context_recv_message_next_slice_peek() { + fprintf(stderr, "Should never reach here"); + abort(); +} void grpcsharp_batch_context_recv_status_on_client_status() { 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 e8ec4c87b06..dab95991bca 100644 --- a/templates/src/csharp/Grpc.Core/Internal/native_methods.include +++ b/templates/src/csharp/Grpc.Core/Internal/native_methods.include @@ -7,6 +7,7 @@ native_method_signatures = [ '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)', + 'int grpcsharp_batch_context_recv_message_next_slice_peek(BatchContextSafeHandle ctx, out UIntPtr sliceLen, out IntPtr sliceDataPtr)', '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)', From ffe2057487262e36c57a3540413851572e36094b Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 16 Apr 2019 14:13:04 -0700 Subject: [PATCH 1986/2143] Revert "Revert "Merge pull request #18547 from lidizheng/fix-gevent"" This reverts commit a922bd7a03a35af0aaceb8f79e71f234e3fb418c. --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 8 ++- src/core/lib/iomgr/iomgr_custom.cc | 3 + src/core/lib/iomgr/iomgr_custom.h | 2 + src/python/grpcio_tests/commands.py | 8 ++- src/python/grpcio_tests/tests/tests.json | 1 + .../grpcio_tests/tests/unit/BUILD.bazel | 1 + .../tests/unit/_dns_resolver_test.py | 63 +++++++++++++++++++ 7 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 src/python/grpcio_tests/tests/unit/_dns_resolver_test.py 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 7de1c221a13..13fde4aeccd 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 @@ -43,6 +43,7 @@ #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/gethostname.h" +#include "src/core/lib/iomgr/iomgr_custom.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/json/json.h" @@ -426,8 +427,11 @@ 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; + // TODO(lidiz): Remove the "g_custom_iomgr_enabled" flag once c-ares support + // custom IO managers (e.g. gevent). + return !g_custom_iomgr_enabled && + (resolver_env == nullptr || strlen(resolver_env) == 0 || + gpr_stricmp(resolver_env, "ares") == 0); } void grpc_resolver_dns_ares_init() { diff --git a/src/core/lib/iomgr/iomgr_custom.cc b/src/core/lib/iomgr/iomgr_custom.cc index 56363c35fd6..f5ac8a0670a 100644 --- a/src/core/lib/iomgr/iomgr_custom.cc +++ b/src/core/lib/iomgr/iomgr_custom.cc @@ -49,6 +49,8 @@ static bool iomgr_platform_add_closure_to_background_poller( return false; } +bool g_custom_iomgr_enabled = false; + static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, @@ -61,6 +63,7 @@ void grpc_custom_iomgr_init(grpc_socket_vtable* socket, grpc_custom_resolver_vtable* resolver, grpc_custom_timer_vtable* timer, grpc_custom_poller_vtable* poller) { + g_custom_iomgr_enabled = true; grpc_custom_endpoint_init(socket); grpc_custom_timer_init(timer); grpc_custom_pollset_init(poller); diff --git a/src/core/lib/iomgr/iomgr_custom.h b/src/core/lib/iomgr/iomgr_custom.h index 57cc2f9b923..e6a88843e5c 100644 --- a/src/core/lib/iomgr/iomgr_custom.h +++ b/src/core/lib/iomgr/iomgr_custom.h @@ -39,6 +39,8 @@ extern gpr_thd_id g_init_thread; #define GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD() #endif /* GRPC_CUSTOM_IOMGR_THREAD_CHECK */ +extern bool g_custom_iomgr_enabled; + void grpc_custom_iomgr_init(grpc_socket_vtable* socket, grpc_custom_resolver_vtable* resolver, grpc_custom_timer_vtable* timer, diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 7a441feb84e..8f27ab5ac51 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -153,6 +153,9 @@ class TestGevent(setuptools.Command): # TODO(https://github.com/grpc/grpc/issues/15411) enable this test 'unit._cython._channel_test.ChannelTest.test_negative_deadline_connectivity' ) + BANNED_WINDOWS_TESTS = ( + # TODO(https://github.com/grpc/grpc/pull/15411) enable this test + 'unit._dns_resolver_test.DNSResolverTest.test_connect_loopback',) description = 'run tests with gevent. Assumes grpc/gevent are installed' user_options = [] @@ -178,7 +181,10 @@ class TestGevent(setuptools.Command): loader = tests.Loader() loader.loadTestsFromNames(['tests']) runner = tests.Runner() - runner.skip_tests(self.BANNED_TESTS) + if sys.platform == 'win32': + runner.skip_tests(self.BANNED_TESTS + self.BANNED_WINDOWS_TESTS) + else: + runner.skip_tests(self.BANNED_TESTS) result = gevent.spawn(runner.run, loader.suite) result.join() if not result.value.wasSuccessful(): diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index 7729ca01d53..cc08d56248a 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -46,6 +46,7 @@ "unit._cython.cygrpc_test.InsecureServerInsecureClient", "unit._cython.cygrpc_test.SecureServerSecureClient", "unit._cython.cygrpc_test.TypeSmokeTest", + "unit._dns_resolver_test.DNSResolverTest", "unit._empty_message_test.EmptyMessageTest", "unit._error_message_encoding_test.ErrorMessageEncodingTest", "unit._exit_test.ExitTest", diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel index 54b3c9b6f6a..9c9887b3b73 100644 --- a/src/python/grpcio_tests/tests/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel @@ -14,6 +14,7 @@ GRPCIO_TESTS_UNIT = [ "_channel_ready_future_test.py", "_compression_test.py", "_credentials_test.py", + "_dns_resolver_test.py", "_empty_message_test.py", "_exit_test.py", "_interceptor_test.py", diff --git a/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py b/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py new file mode 100644 index 00000000000..d119707b19d --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py @@ -0,0 +1,63 @@ +# 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. +"""Tests for an actual dns resolution.""" + +import unittest +import logging +import six + +import grpc +from tests.unit import test_common +from tests.unit.framework.common import test_constants + +_METHOD = '/ANY/METHOD' +_REQUEST = b'\x00\x00\x00' +_RESPONSE = _REQUEST + + +class GenericHandler(grpc.GenericRpcHandler): + + def service(self, unused_handler_details): + return grpc.unary_unary_rpc_method_handler( + lambda request, unused_context: request, + ) + + +class DNSResolverTest(unittest.TestCase): + + def setUp(self): + self._server = test_common.test_server() + self._server.add_generic_rpc_handlers((GenericHandler(),)) + self._port = self._server.add_insecure_port('[::]:0') + self._server.start() + + def tearDown(self): + self._server.stop(None) + + def test_connect_loopback(self): + # NOTE(https://github.com/grpc/grpc/issues/18422) + # In short, Gevent + C-Ares = Segfault. The C-Ares driver is not + # supported by custom io manager like "gevent" or "libuv". + with grpc.insecure_channel( + 'loopback4.unittest.grpc.io:%d' % self._port) as channel: + self.assertEqual( + channel.unary_unary(_METHOD)( + _REQUEST, + timeout=test_constants.SHORT_TIMEOUT, + ), _RESPONSE) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) From 365c118967c81ada37770d47fce550d454e6c432 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 25 Apr 2019 07:25:26 -0700 Subject: [PATCH 1987/2143] Bump version to v1.20.1 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index fcd1bcd8fbe..9157f5af0f4 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "godric" core_version = "7.0.0" -version = "1.20.0" +version = "1.20.1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 7520f9de6f7..f647e423749 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: godric - version: 1.20.0 + version: 1.20.1 filegroups: - name: alts_proto headers: From ee47d5ee75eea5ac046485312f8106a561a3d3ed Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 25 Apr 2019 07:28:33 -0700 Subject: [PATCH 1988/2143] 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.Api/VersionInfo.cs | 4 ++-- src/csharp/build/dependencies.props | 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/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 23eeae53a65..e8207372018 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.20.0") +set(PACKAGE_VERSION "1.20.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 34d8b6d9047..53e70c95ba2 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.20.0 -CSHARP_VERSION = 1.20.0 +CPP_VERSION = 1.20.1 +CSHARP_VERSION = 1.20.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 6556b8f40a4..f031cbf5851 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.20.0' + # version = '1.20.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.20.0' + grpc_version = '1.20.1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 9cad88f98b8..50fb324e9fb 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.20.0' + version = '1.20.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 6f9359b5329..89c367cc425 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.20.0' + version = '1.20.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 34dd3b67877..2dc3fe68227 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.20.0' + version = '1.20.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 e2e6e7f0b03..ec9cd77f457 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.20.0' + version = '1.20.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 908a9d71cc6..91671644549 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.20.0 - 1.20.0 + 1.20.1 + 1.20.1 stable diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index d9e9f1b7168..2c17f47c471 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.20.0"; } +grpc::string Version() { return "1.20.1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index bcf41de4320..402b6c3adbb 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.20.0.0"; + public const string CurrentAssemblyFileVersion = "1.20.1.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.20.0"; + public const string CurrentVersion = "1.20.1"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index 72bd8bcdb72..17fb31eb7b8 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.20.0 + 1.20.1 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index d0230757628..cd77d55713a 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.20.0 +set VERSION=1.20.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 f1529fbd3fb..558a16390b0 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.20.0' + v = '1.20.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 d7c7e65bd46..2f624405a19 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.20.0" +#define GRPC_OBJC_VERSION_STRING @"1.20.1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 6c547e15bee..39d38a9c094 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.20.0" +#define GRPC_OBJC_VERSION_STRING @"1.20.1" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index e8106db7288..3ae0ce5749f 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.20.0", + "version": "1.20.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 0333c8d17a6..3aaf1d835cd 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.20.0" +#define PHP_GRPC_VERSION "1.20.1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index d2b7655ed4a..79e68cfb480 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.20.0""" +__version__ = """1.20.1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index b28450deab7..443a2dcf5a8 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.20.0' +VERSION = '1.20.1' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 85c468277c3..a10aa7846ea 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.20.0' +VERSION = '1.20.1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index eecc1fe5eb0..75014274bbb 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.20.0' +VERSION = '1.20.1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 892b4010e90..64ec5494b3b 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.20.0' +VERSION = '1.20.1' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 6c042c2aace..456fcde3ce3 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.20.0' +VERSION = '1.20.1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 8af49a7c801..ed767b6eeb0 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.20.0' +VERSION = '1.20.1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index df1ab623e79..8c8ee0c6938 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.20.0' +VERSION = '1.20.1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 9ea2b99566c..620f67fdb29 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.20.0' + VERSION = '1.20.1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index b13415996e9..5860fbcc85a 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.20.0' + VERSION = '1.20.1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index d864b7bede5..7d2fc484239 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.20.0' +VERSION = '1.20.1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 26840372f34..fac989c9ec3 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.20.0 +PROJECT_NUMBER = 1.20.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 5d359830eab..5c481526207 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.20.0 +PROJECT_NUMBER = 1.20.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 83c5981d150edea81aafa7d98a034b4b23020ac3 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 25 Apr 2019 08:14:54 -0700 Subject: [PATCH 1989/2143] Fix the oversight from #18841 --- tools/interop_matrix/client_matrix.py | 4 ++-- .../interop_matrix/testcases/csharp__v1.18.0 | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100755 tools/interop_matrix/testcases/csharp__v1.18.0 diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 36f926d491f..6b6502b3e23 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -266,8 +266,8 @@ LANG_RELEASE_MATRIX = { ('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(testcases_file='csharpcoreclr__v1.18.0')), - ('v1.19.0', ReleaseInfo(testcases_file='csharpcoreclr__v1.18.0')), + ('v1.18.0', ReleaseInfo(testcases_file='csharp__v1.18.0')), + ('v1.19.0', ReleaseInfo(testcases_file='csharp__v1.18.0')), ('v1.20.0', ReleaseInfo()), ]), } diff --git a/tools/interop_matrix/testcases/csharp__v1.18.0 b/tools/interop_matrix/testcases/csharp__v1.18.0 new file mode 100755 index 00000000000..3ca145e4c11 --- /dev/null +++ b/tools/interop_matrix/testcases/csharp__v1.18.0 @@ -0,0 +1,22 @@ +#!/bin/bash +# 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 9cac231163d37d6b57ed9e01c878df9f0529d7eb Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 25 Apr 2019 09:06:28 -0700 Subject: [PATCH 1990/2143] Inline start the tcp servers --- src/core/lib/surface/server.cc | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index c6983ea9c95..89188be8176 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -1098,20 +1098,6 @@ void* grpc_server_register_method( return m; } -static void start_listeners(void* s, grpc_error* error) { - grpc_server* server = static_cast(s); - for (listener* l = server->listeners; l; l = l->next) { - l->start(server, l->arg, server->pollsets, server->pollset_count); - } - - gpr_mu_lock(&server->mu_global); - server->starting = false; - gpr_cv_signal(&server->starting_cv); - gpr_mu_unlock(&server->mu_global); - - server_unref(server); -} - void grpc_server_start(grpc_server* server) { size_t i; grpc_core::ExecCtx exec_ctx; @@ -1133,13 +1119,18 @@ void grpc_server_start(grpc_server* server) { request_matcher_init(&rm->matcher, server); } - server_ref(server); + gpr_mu_lock(&server->mu_global); server->starting = true; - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE( - start_listeners, server, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_NONE); + gpr_mu_unlock(&server->mu_global); + + for (listener* l = server->listeners; l; l = l->next) { + l->start(server, l->arg, server->pollsets, server->pollset_count); + } + + gpr_mu_lock(&server->mu_global); + server->starting = false; + gpr_cv_signal(&server->starting_cv); + gpr_mu_unlock(&server->mu_global); } void grpc_server_get_pollsets(grpc_server* server, grpc_pollset*** pollsets, From 371c0a483d4350406052610f8711f38b7e72d5a7 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 25 Apr 2019 08:37:11 -0700 Subject: [PATCH 1991/2143] Correct the testcase file for different runtimes --- .../interop_matrix/testcases/csharp__v1.18.0 | 39 ++++++++++--------- .../testcases/csharpcoreclr__v1.18.0 | 22 +++++++++++ 2 files changed, 42 insertions(+), 19 deletions(-) mode change 100755 => 100644 tools/interop_matrix/testcases/csharp__v1.18.0 create mode 100755 tools/interop_matrix/testcases/csharpcoreclr__v1.18.0 diff --git a/tools/interop_matrix/testcases/csharp__v1.18.0 b/tools/interop_matrix/testcases/csharp__v1.18.0 old mode 100755 new mode 100644 index 3ca145e4c11..34444c71025 --- a/tools/interop_matrix/testcases/csharp__v1.18.0 +++ b/tools/interop_matrix/testcases/csharp__v1.18.0 @@ -1,22 +1,23 @@ #!/bin/bash # 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" +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__v1.18.0 b/tools/interop_matrix/testcases/csharpcoreclr__v1.18.0 new file mode 100755 index 00000000000..3ca145e4c11 --- /dev/null +++ b/tools/interop_matrix/testcases/csharpcoreclr__v1.18.0 @@ -0,0 +1,22 @@ +#!/bin/bash +# 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 4de4a7da7b45b988c13cd6529ed034b7fff74ef2 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 25 Apr 2019 10:27:01 -0700 Subject: [PATCH 1992/2143] Reenable python bazel tests --- .../python/wait_for_ready/wait_for_ready_example.py | 4 ++-- .../linux/grpc_python_bazel_test_in_docker.sh | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py index 7c16b9bd4a1..effafd88ee5 100644 --- a/examples/python/wait_for_ready/wait_for_ready_example.py +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -22,8 +22,8 @@ import threading import grpc -from examples.protos import helloworld_pb2 -from examples.protos import helloworld_pb2_grpc +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc _LOGGER = logging.getLogger(__name__) _LOGGER.setLevel(logging.INFO) 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 3ca4673ca08..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 @@ -23,10 +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}') -#TODO(yfen): temporarily disabled all python bazel tests due to incompatibility with bazel 0.23.2 -#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/... +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 ff397acf559e599799e5679b47f49c6fc9818d8c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 25 Apr 2019 19:34:33 +0200 Subject: [PATCH 1993/2143] Upload C# nightly nugets to Artifactory dev nuget feed --- tools/internal_ci/linux/grpc_publish_packages.cfg | 2 ++ tools/internal_ci/linux/grpc_publish_packages.sh | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/tools/internal_ci/linux/grpc_publish_packages.cfg b/tools/internal_ci/linux/grpc_publish_packages.cfg index dc9fe7d0a7a..54e03a94b60 100644 --- a/tools/internal_ci/linux/grpc_publish_packages.cfg +++ b/tools/internal_ci/linux/grpc_publish_packages.cfg @@ -24,3 +24,5 @@ action { regex: "github/grpc/artifacts/**" } } + +gfile_resources: "/bigstore/grpc-testing-secrets/nuget_credentials/artifactory_grpc_nuget_dev_api_key" diff --git a/tools/internal_ci/linux/grpc_publish_packages.sh b/tools/internal_ci/linux/grpc_publish_packages.sh index 14492301cc9..87684214d84 100755 --- a/tools/internal_ci/linux/grpc_publish_packages.sh +++ b/tools/internal_ci/linux/grpc_publish_packages.sh @@ -233,3 +233,16 @@ gsutil -m cp -r "$LOCAL_STAGING_TEMPDIR/${BUILD_RELPATH%%/*}" "$GCS_ARCHIVE_ROOT ) # Upload the new /index.xml gsutil -h "Content-Type:application/xml" cp "$NEW_INDEX" "$GCS_INDEX" + +# Upload C# nugets to the dev nuget feed +pushd "$UNZIPPED_CSHARP_PACKAGES" +docker pull mcr.microsoft.com/dotnet/core/sdk:2.1 +for nugetfile in *.nupkg +do + echo "Going to push $nugetfile" + # use nuget from a docker container to push the nupkg + set +x # IMPORTANT: avoid revealing the nuget api key by the command echo + docker run -v "$(pwd):/nugets:ro" --rm=true mcr.microsoft.com/dotnet/core/sdk:2.1 bash -c "dotnet nuget push /nugets/$nugetfile -k $(cat ${KOKORO_GFILE_DIR}/artifactory_grpc_nuget_dev_api_key) --source https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev" + set -ex +done +popd From e457584c05fbbdecc6f4fe9356cea2450c4fd5d3 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 25 Apr 2019 11:07:36 -0700 Subject: [PATCH 1994/2143] Address comments --- .../dns/c_ares/grpc_ares_ev_driver_libuv.cc | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc index e69b824304d..c29fa44a353 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -47,9 +47,13 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { handle_ = New(); uv_poll_init_socket(uv_default_loop(), handle_, as); handle_->data = this; + GRPC_COMBINER_REF(combiner_, "libuv ares event driver"); } - ~GrpcPolledFdLibuv() { gpr_free(name_); } + ~GrpcPolledFdLibuv() { + gpr_free(name_); + GRPC_COMBINER_UNREF(combiner_, "libuv ares event driver"); + } void RegisterForOnReadableLocked(grpc_closure* read_closure) override { GPR_ASSERT(read_closure_ == nullptr); @@ -73,18 +77,26 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { return false; } - void ShutdownLocked(grpc_error* error) override { - grpc_core::ExecCtx exec_ctx; + void ShutdownInternal(grpc_error* error) { uv_poll_stop(handle_); uv_close(reinterpret_cast(handle_), ares_uv_poll_close_cb); - if (read_closure_) { + if (read_closure_ != nullptr) { GRPC_CLOSURE_SCHED(read_closure_, GRPC_ERROR_CANCELLED); } - if (write_closure_) { + if (write_closure_ != nullptr) { GRPC_CLOSURE_SCHED(write_closure_, GRPC_ERROR_CANCELLED); } } + void ShutdownLocked(grpc_error* error) override { + if (grpc_core::ExecCtx::Get() == nullptr) { + grpc_core::ExecCtx exec_ctx; + ShutdownInternal(error); + } else { + ShutdownInternal(error); + } + } + ares_socket_t GetWrappedAresSocketLocked() override { return as_; } const char* GetName() override { return name_; } @@ -107,8 +119,9 @@ struct AresUvPollCbArg { int events; }; -static void inner_callback(void* arg, grpc_error* error) { - AresUvPollCbArg* arg_struct = reinterpret_cast(arg); +static void ares_uv_poll_cb_locked(void* arg, grpc_error* error) { + grpc_core::UniquePtr arg_struct( + reinterpret_cast(arg)); uv_poll_t* handle = arg_struct->handle; int status = arg_struct->status; int events = arg_struct->events; @@ -120,18 +133,19 @@ static void inner_callback(void* arg, grpc_error* error) { grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, grpc_slice_from_static_string(uv_strerror(status))); } - if ((events & UV_READABLE) && polled_fd->read_closure_) { + if (events & UV_READABLE) { + GPR_ASSERT(polled_fd->read_closure_ != nullptr); GRPC_CLOSURE_SCHED(polled_fd->read_closure_, error); polled_fd->read_closure_ = nullptr; polled_fd->poll_events_ &= ~UV_READABLE; } - if ((events & UV_WRITABLE) && polled_fd->write_closure_) { + if (events & UV_WRITABLE) { + GPR_ASSERT(polled_fd->write_closure_ != nullptr); GRPC_CLOSURE_SCHED(polled_fd->write_closure_, error); polled_fd->write_closure_ = nullptr; polled_fd->poll_events_ &= ~UV_WRITABLE; } uv_poll_start(handle, polled_fd->poll_events_, ares_uv_poll_cb); - Delete(arg_struct); } void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { @@ -140,7 +154,7 @@ void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { reinterpret_cast(handle->data); AresUvPollCbArg* arg = New(handle, status, events); GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(inner_callback, arg, + GRPC_CLOSURE_CREATE(ares_uv_poll_cb_locked, arg, grpc_combiner_scheduler(polled_fd->combiner_)), GRPC_ERROR_NONE); } From 3377e49bc7784514f0bc9d593531c30d39fe5250 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 25 Apr 2019 11:40:56 -0700 Subject: [PATCH 1995/2143] Fix build errors --- BUILD.gn | 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.gn b/BUILD.gn index 2518db149d7..b55e1389a43 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1087,6 +1087,7 @@ config("grpc_config") { "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", + "include/grpcpp/security/credentials_impl.h", "include/grpcpp/security/server_credentials.h", "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 3479d17ad06..4e13c541d9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3039,6 +3039,7 @@ foreach(_hdr include/grpcpp/security/auth_metadata_processor.h include/grpcpp/security/auth_metadata_processor_impl.h include/grpcpp/security/credentials.h + include/grpcpp/security/credentials_impl.h include/grpcpp/security/server_credentials.h include/grpcpp/security/server_credentials_impl.h include/grpcpp/server.h @@ -3646,6 +3647,7 @@ foreach(_hdr include/grpcpp/security/auth_metadata_processor.h include/grpcpp/security/auth_metadata_processor_impl.h include/grpcpp/security/credentials.h + include/grpcpp/security/credentials_impl.h include/grpcpp/security/server_credentials.h include/grpcpp/security/server_credentials_impl.h include/grpcpp/server.h @@ -4630,6 +4632,7 @@ foreach(_hdr include/grpcpp/security/auth_metadata_processor.h include/grpcpp/security/auth_metadata_processor_impl.h include/grpcpp/security/credentials.h + include/grpcpp/security/credentials_impl.h include/grpcpp/security/server_credentials.h include/grpcpp/security/server_credentials_impl.h include/grpcpp/server.h diff --git a/Makefile b/Makefile index 5d10bd9f4b7..e87513c4067 100644 --- a/Makefile +++ b/Makefile @@ -5379,6 +5379,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ + include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ @@ -5994,6 +5995,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ + include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ @@ -6927,6 +6929,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ + include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ diff --git a/build.yaml b/build.yaml index f7d2e8be0e9..9e9b388e047 100644 --- a/build.yaml +++ b/build.yaml @@ -1381,6 +1381,7 @@ filegroups: - include/grpcpp/security/auth_metadata_processor.h - include/grpcpp/security/auth_metadata_processor_impl.h - include/grpcpp/security/credentials.h + - include/grpcpp/security/credentials_impl.h - include/grpcpp/security/server_credentials.h - include/grpcpp/security/server_credentials_impl.h - include/grpcpp/server.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 3141ecdbe17..ef12a33ad33 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -116,6 +116,7 @@ Pod::Spec.new do |s| 'include/grpcpp/security/auth_metadata_processor.h', 'include/grpcpp/security/auth_metadata_processor_impl.h', 'include/grpcpp/security/credentials.h', + 'include/grpcpp/security/credentials_impl.h', 'include/grpcpp/security/server_credentials.h', 'include/grpcpp/security/server_credentials_impl.h', 'include/grpcpp/server.h', diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 2a71e73a839..56b3fb0e3df 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -1008,6 +1008,7 @@ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ +include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 438cd023166..4bd0150c304 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1010,6 +1010,7 @@ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ +include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 4e5f268b38f..0a084411829 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10186,6 +10186,7 @@ "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", + "include/grpcpp/security/credentials_impl.h", "include/grpcpp/security/server_credentials.h", "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", @@ -10308,6 +10309,7 @@ "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", + "include/grpcpp/security/credentials_impl.h", "include/grpcpp/security/server_credentials.h", "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", From 1c65fd19e835264b0c040ac6a41ac76a3f66970a Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 25 Apr 2019 12:55:58 -0700 Subject: [PATCH 1996/2143] Fix wait_for_ready example for ipv4-only environments like Kokoro --- examples/python/wait_for_ready/wait_for_ready_example.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py index effafd88ee5..d2f6f2f7ba1 100644 --- a/examples/python/wait_for_ready/wait_for_ready_example.py +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -33,8 +33,12 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24 @contextmanager def get_free_loopback_tcp_port(): - tcp_socket = socket.socket(socket.AF_INET6) - tcp_socket.bind(('', 0)) + if socket.has_ipv6: + tcp_socket = socket.socket(socket.AF_INET6) + tcp_socket.bind(('', 0)) + else: + tcp_socket = socket.socket(socket.AF_INET) + tcp_socket.bind(('', 0)) address_tuple = tcp_socket.getsockname() yield "[::1]:%s" % (address_tuple[1]) tcp_socket.close() From aec0860ebf861c24c13595b96563a1bebb34988f Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 25 Apr 2019 12:56:46 -0700 Subject: [PATCH 1997/2143] Remove redundant line --- examples/python/wait_for_ready/wait_for_ready_example.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py index d2f6f2f7ba1..3875c2e75b5 100644 --- a/examples/python/wait_for_ready/wait_for_ready_example.py +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -35,10 +35,9 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24 def get_free_loopback_tcp_port(): if socket.has_ipv6: tcp_socket = socket.socket(socket.AF_INET6) - tcp_socket.bind(('', 0)) else: tcp_socket = socket.socket(socket.AF_INET) - tcp_socket.bind(('', 0)) + tcp_socket.bind(('', 0)) address_tuple = tcp_socket.getsockname() yield "[::1]:%s" % (address_tuple[1]) tcp_socket.close() From 5391d8427e015cea24ea6d24888f893c51f1b121 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 25 Apr 2019 13:53:23 -0700 Subject: [PATCH 1998/2143] Moar ipv6 --- examples/python/wait_for_ready/wait_for_ready_example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py index 3875c2e75b5..a0f076e894a 100644 --- a/examples/python/wait_for_ready/wait_for_ready_example.py +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -39,7 +39,7 @@ def get_free_loopback_tcp_port(): tcp_socket = socket.socket(socket.AF_INET) tcp_socket.bind(('', 0)) address_tuple = tcp_socket.getsockname() - yield "[::1]:%s" % (address_tuple[1]) + yield "localhost:%s" % (address_tuple[1]) tcp_socket.close() From cf9301f96481e14b6a8ae7afd4db209ae454f97f Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Wed, 24 Apr 2019 17:13:06 -0700 Subject: [PATCH 1999/2143] Removed some unnecessary memset operations in core. --- include/grpc/impl/codegen/grpc_types.h | 3 ++- src/core/lib/surface/call.cc | 12 +++++++----- src/core/lib/surface/call_details.cc | 1 - src/core/lib/surface/completion_queue.cc | 14 +++++++------- src/core/lib/surface/server.cc | 5 +++-- .../Internal/CompletionQueueSafeHandleTest.cs | 1 - test/core/bad_connection/close_fd_test.cc | 5 ----- 7 files changed, 19 insertions(+), 22 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 4b3dff30404..33c160b4240 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -494,7 +494,8 @@ typedef struct grpc_event { field is guaranteed to be 0 */ int success; /** The tag passed to grpc_call_start_batch etc to start this operation. - Only GRPC_OP_COMPLETE has a tag. */ + *Only* GRPC_OP_COMPLETE has a tag. For all other grpc_completion_type + values, tag is uninitialized. */ void* tag; } grpc_event; diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 0b539b0d9b2..ff3df2605f3 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -1557,7 +1557,10 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, goto done_with_error; } /* process compression level */ - memset(&call->compression_md, 0, sizeof(call->compression_md)); + grpc_metadata& compression_md = call->compression_md; + compression_md.key = grpc_empty_slice(); + compression_md.value = grpc_empty_slice(); + compression_md.flags = 0; size_t additional_metadata_count = 0; grpc_compression_level effective_compression_level = GRPC_COMPRESS_LEVEL_NONE; @@ -1580,8 +1583,8 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, call, effective_compression_level); /* the following will be picked up by the compress filter and used * as the call's compression algorithm. */ - call->compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST; - call->compression_md.value = grpc_compression_algorithm_slice(calgo); + compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST; + compression_md.value = grpc_compression_algorithm_slice(calgo); additional_metadata_count++; } @@ -1595,8 +1598,7 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, if (!prepare_application_metadata( call, static_cast(op->data.send_initial_metadata.count), op->data.send_initial_metadata.metadata, 0, call->is_client, - &call->compression_md, - static_cast(additional_metadata_count))) { + &compression_md, static_cast(additional_metadata_count))) { error = GRPC_CALL_ERROR_INVALID_METADATA; goto done_with_error; } diff --git a/src/core/lib/surface/call_details.cc b/src/core/lib/surface/call_details.cc index 7f20b1dae74..55e9e3425f2 100644 --- a/src/core/lib/surface/call_details.cc +++ b/src/core/lib/surface/call_details.cc @@ -29,7 +29,6 @@ void grpc_call_details_init(grpc_call_details* cd) { GRPC_API_TRACE("grpc_call_details_init(cd=%p)", 1, (cd)); - memset(cd, 0, sizeof(*cd)); cd->method = grpc_empty_slice(); cd->host = grpc_empty_slice(); } diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 7d679204bac..3a32d292a7b 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -1002,15 +1002,15 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, continue; } - memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_SHUTDOWN; + ret.success = 0; break; } if (!is_finished_arg.first_loop && grpc_core::ExecCtx::Get()->Now() >= deadline_millis) { - memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + ret.success = 0; dump_pending_tags(cq); break; } @@ -1027,8 +1027,8 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, gpr_log(GPR_ERROR, "Completion queue next failed: %s", msg); GRPC_ERROR_UNREF(err); - memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + ret.success = 0; dump_pending_tags(cq); break; } @@ -1234,8 +1234,8 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, } if (cqd->shutdown.Load(grpc_core::MemoryOrder::RELAXED)) { gpr_mu_unlock(cq->mu); - memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_SHUTDOWN; + ret.success = 0; break; } if (!add_plucker(cq, tag, &worker)) { @@ -1244,9 +1244,9 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, "is %d", GRPC_MAX_COMPLETION_QUEUE_PLUCKERS); gpr_mu_unlock(cq->mu); - memset(&ret, 0, sizeof(ret)); /* TODO(ctiller): should we use a different result here */ ret.type = GRPC_QUEUE_TIMEOUT; + ret.success = 0; dump_pending_tags(cq); break; } @@ -1254,8 +1254,8 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, grpc_core::ExecCtx::Get()->Now() >= deadline_millis) { del_plucker(cq, tag, &worker); gpr_mu_unlock(cq->mu); - memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + ret.success = 0; dump_pending_tags(cq); break; } @@ -1269,8 +1269,8 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, gpr_log(GPR_ERROR, "Completion queue pluck failed: %s", msg); GRPC_ERROR_UNREF(err); - memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + ret.success = 0; dump_pending_tags(cq); break; } diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index c6983ea9c95..c2b7e0436ef 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -347,8 +347,8 @@ static void channel_broadcaster_shutdown(channel_broadcaster* cb, */ static void request_matcher_init(request_matcher* rm, grpc_server* server) { - memset(rm, 0, sizeof(*rm)); rm->server = server; + rm->pending_head = rm->pending_tail = nullptr; rm->requests_per_cq = static_cast( gpr_malloc(sizeof(*rm->requests_per_cq) * server->cq_count)); for (size_t i = 0; i < server->cq_count; i++) { @@ -601,8 +601,9 @@ static void finish_start_new_rpc( break; case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: { grpc_op op; - memset(&op, 0, sizeof(op)); op.op = GRPC_OP_RECV_MESSAGE; + op.flags = 0; + op.reserved = nullptr; op.data.recv_message.recv_message = &calld->payload; GRPC_CLOSURE_INIT(&calld->publish, publish_new_rpc, elem, grpc_schedule_on_exec_ctx); diff --git a/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs b/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs index 7e4e2975c16..a0ea1cc4278 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs @@ -47,7 +47,6 @@ namespace Grpc.Core.Internal.Tests GrpcEnvironment.ReleaseAsync().Wait(); Assert.AreEqual(CompletionQueueEvent.CompletionType.Shutdown, ev.type); Assert.AreNotEqual(IntPtr.Zero, ev.success); - Assert.AreEqual(IntPtr.Zero, ev.tag); } } } diff --git a/test/core/bad_connection/close_fd_test.cc b/test/core/bad_connection/close_fd_test.cc index 317526a563a..e8f297e77ea 100644 --- a/test/core/bad_connection/close_fd_test.cc +++ b/test/core/bad_connection/close_fd_test.cc @@ -328,7 +328,6 @@ static void _test_close_before_server_recv(fd_type fdtype) { */ 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 { @@ -531,7 +530,6 @@ static void _test_close_before_server_send(fd_type fdtype) { } 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); } @@ -664,7 +662,6 @@ static void _test_close_before_client_send(fd_type fdtype) { 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); @@ -720,13 +717,11 @@ static void _test_close_before_call_create(fd_type fdtype) { 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(); From 156d743c3717130f0adcf2daf82f8cf45744e549 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 25 Apr 2019 16:38:10 -0700 Subject: [PATCH 2000/2143] Reviewer comments --- BUILD | 2 - BUILD.gn | 2 - CMakeLists.txt | 6 - Makefile | 6 - build.yaml | 2 - config.m4 | 1 - config.w32 | 1 - gRPC-C++.podspec | 1 - gRPC-Core.podspec | 3 - grpc.gemspec | 2 - grpc.gyp | 4 - package.xml | 2 - .../filters/client_channel/client_channel.cc | 26 +- .../client_channel/client_channel_plugin.cc | 8 +- .../health/health_check_parser.cc | 84 ----- .../health/health_check_parser.h | 3 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 39 ++- .../client_channel/lb_policy/xds/xds.cc | 32 +- .../client_channel/lb_policy_registry.cc | 34 +- .../client_channel/lb_policy_registry.h | 9 +- .../client_channel/resolver_result_parsing.cc | 312 ++++++++++-------- .../client_channel/resolver_result_parsing.h | 33 +- .../client_channel/resolving_lb_policy.cc | 2 +- .../client_channel/resolving_lb_policy.h | 2 +- .../filters/client_channel/service_config.cc | 8 +- .../filters/client_channel/service_config.h | 52 ++- .../message_size/message_size_filter.cc | 22 +- src/core/lib/gprpp/optional.h | 2 +- src/core/lib/iomgr/error.h | 19 ++ src/python/grpcio/grpc_core_dependencies.py | 1 - .../client_channel/service_config_test.cc | 116 +++---- tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 3 - 33 files changed, 371 insertions(+), 470 deletions(-) delete mode 100644 src/core/ext/filters/client_channel/health/health_check_parser.cc diff --git a/BUILD b/BUILD index c9ff663201e..1735961eb61 100644 --- a/BUILD +++ b/BUILD @@ -1082,7 +1082,6 @@ grpc_cc_library( "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/health/health_check_parser.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", @@ -1109,7 +1108,6 @@ grpc_cc_library( "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/health/health_check_parser.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", diff --git a/BUILD.gn b/BUILD.gn index 4452bfa2cae..10b0f1a7fdd 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -260,8 +260,6 @@ config("grpc_config") { "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/health/health_check_parser.cc", - "src/core/ext/filters/client_channel/health/health_check_parser.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", diff --git a/CMakeLists.txt b/CMakeLists.txt index 15a8697c9a0..0edd7fd54ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1235,7 +1235,6 @@ add_library(grpc 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/health/health_check_parser.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 @@ -1591,7 +1590,6 @@ add_library(grpc_cronet 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/health/health_check_parser.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 @@ -1972,7 +1970,6 @@ add_library(grpc_test_util 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/health/health_check_parser.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 @@ -2298,7 +2295,6 @@ add_library(grpc_test_util_unsecure 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/health/health_check_parser.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 @@ -2635,7 +2631,6 @@ add_library(grpc_unsecure 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/health/health_check_parser.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 @@ -3508,7 +3503,6 @@ add_library(grpc++_cronet 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/health/health_check_parser.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 diff --git a/Makefile b/Makefile index 7a80e4c0731..57530500b15 100644 --- a/Makefile +++ b/Makefile @@ -3695,7 +3695,6 @@ LIBGRPC_SRC = \ 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/health/health_check_parser.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 \ @@ -4045,7 +4044,6 @@ LIBGRPC_CRONET_SRC = \ 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/health/health_check_parser.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 \ @@ -4419,7 +4417,6 @@ LIBGRPC_TEST_UTIL_SRC = \ 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/health/health_check_parser.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 \ @@ -4732,7 +4729,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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/health/health_check_parser.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 \ @@ -5043,7 +5039,6 @@ LIBGRPC_UNSECURE_SRC = \ 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/health/health_check_parser.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 \ @@ -5892,7 +5887,6 @@ LIBGRPC++_CRONET_SRC = \ 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/health/health_check_parser.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 \ diff --git a/build.yaml b/build.yaml index 53fd95f5c06..80519946295 100644 --- a/build.yaml +++ b/build.yaml @@ -576,7 +576,6 @@ filegroups: - 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/health/health_check_parser.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 @@ -606,7 +605,6 @@ filegroups: - 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/health/health_check_parser.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 diff --git a/config.m4 b/config.m4 index e7d3a5daf4e..ab2a717cbcd 100644 --- a/config.m4 +++ b/config.m4 @@ -348,7 +348,6 @@ if test "$PHP_GRPC" != "no"; then 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/health/health_check_parser.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 \ diff --git a/config.w32 b/config.w32 index 8a6529faae2..02eb773ebb8 100644 --- a/config.w32 +++ b/config.w32 @@ -323,7 +323,6 @@ if (PHP_GRPC != "no") { "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\\health\\health_check_parser.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 " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 7ca1477a16b..de1bb0ae57f 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -367,7 +367,6 @@ Pod::Spec.new do |s| '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/health/health_check_parser.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', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 13c2a2cf9d0..5cf45c63cef 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -347,7 +347,6 @@ Pod::Spec.new do |s| '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/health/health_check_parser.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', @@ -797,7 +796,6 @@ Pod::Spec.new do |s| '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/health/health_check_parser.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', @@ -991,7 +989,6 @@ Pod::Spec.new do |s| '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/health/health_check_parser.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', diff --git a/grpc.gemspec b/grpc.gemspec index bca4674c761..15c26f11569 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -281,7 +281,6 @@ Gem::Specification.new do |s| 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/health/health_check_parser.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 ) @@ -734,7 +733,6 @@ Gem::Specification.new do |s| 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/health/health_check_parser.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 ) diff --git a/grpc.gyp b/grpc.gyp index d4db059dc0a..40dc88d7474 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -530,7 +530,6 @@ '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/health/health_check_parser.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', @@ -795,7 +794,6 @@ '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/health/health_check_parser.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', @@ -1041,7 +1039,6 @@ '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/health/health_check_parser.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', @@ -1298,7 +1295,6 @@ '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/health/health_check_parser.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', diff --git a/package.xml b/package.xml index 3af95c9a727..c3f4e17dd12 100644 --- a/package.xml +++ b/package.xml @@ -286,7 +286,6 @@ - @@ -739,7 +738,6 @@ - diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index f0972ef4c70..f0bc3417a2b 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -240,6 +240,7 @@ class ChannelData { const size_t per_rpc_retry_buffer_size_; grpc_channel_stack* owning_stack_; ClientChannelFactory* client_channel_factory_; + UniquePtr server_name_; // Initialized shortly after construction. channelz::ClientChannelNode* channelz_node_ = nullptr; @@ -263,7 +264,7 @@ class ChannelData { OrphanablePtr resolving_lb_policy_; grpc_connectivity_state_tracker state_tracker_; ExternalConnectivityWatcher::WatcherList external_connectivity_watcher_list_; - const char* health_check_service_name_ = nullptr; + UniquePtr health_check_service_name_; // // Fields accessed from both data plane and control plane combiners. @@ -762,12 +763,11 @@ class ChannelData::ConnectivityStateAndPickerSetter { class ChannelData::ServiceConfigSetter { public: ServiceConfigSetter( - ChannelData* chand, UniquePtr server_name, + ChannelData* chand, Optional retry_throttle_data, RefCountedPtr service_config) : chand_(chand), - server_name_(std::move(server_name)), retry_throttle_data_(retry_throttle_data), service_config_(std::move(service_config)) { GRPC_CHANNEL_STACK_REF(chand->owning_stack_, "ServiceConfigSetter"); @@ -785,7 +785,7 @@ class ChannelData::ServiceConfigSetter { if (self->retry_throttle_data_.has_value()) { chand->retry_throttle_data_ = internal::ServerRetryThrottleMap::GetDataForServer( - self->server_name_.get(), + chand->server_name_.get(), self->retry_throttle_data_.value().max_milli_tokens, self->retry_throttle_data_.value().milli_token_ratio); } @@ -803,7 +803,6 @@ class ChannelData::ServiceConfigSetter { } ChannelData* chand_; - UniquePtr server_name_; Optional retry_throttle_data_; RefCountedPtr service_config_; @@ -948,7 +947,7 @@ class ChannelData::ClientChannelControlHelper if (chand_->health_check_service_name_ != nullptr) { args_to_add[0] = grpc_channel_arg_string_create( const_cast("grpc.temp.health_check"), - const_cast(chand_->health_check_service_name_)); + const_cast(chand_->health_check_service_name_.get())); num_args_to_add++; } args_to_add[num_args_to_add++] = SubchannelPoolInterface::CreateChannelArg( @@ -1067,6 +1066,10 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) "filter"); return; } + grpc_uri* uri = grpc_uri_parse(server_uri, true); + GPR_ASSERT(uri->path[0] != '\0'); + server_name_.reset( + gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path)); char* proxy_name = nullptr; grpc_channel_args* new_args = nullptr; grpc_proxy_mappers_map_name(server_uri, args->channel_args, &proxy_name, @@ -1135,11 +1138,12 @@ bool ChannelData::ProcessResolverResultLocked( gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", chand, service_config_json); } + chand->health_check_service_name_.reset( + gpr_strdup(resolver_result.health_check_service_name())); // Create service config setter to update channel state in the data // plane combiner. Destroys itself when done. - New( - chand, UniquePtr(gpr_strdup(resolver_result.server_name())), - resolver_result.retry_throttle_data(), resolver_result.service_config()); + New(chand, resolver_result.retry_throttle_data(), + resolver_result.service_config()); // Swap out the data used by GetChannelInfo(). bool service_config_changed; { @@ -1156,8 +1160,6 @@ bool ChannelData::ProcessResolverResultLocked( // Return results. *lb_policy_name = chand->info_lb_policy_name_.get(); *lb_policy_config = resolver_result.lb_policy_config(); - chand->health_check_service_name_ = - resolver_result.health_check_service_name(); return service_config_changed; } @@ -3101,7 +3103,7 @@ void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) { // it. service_config_call_data_ = ServiceConfig::CallData(chand->service_config(), path_); - if (!service_config_call_data_.empty()) { + if (service_config_call_data_.service_config() != nullptr) { call_context_[GRPC_SERVICE_CONFIG_CALL_DATA].value = &service_config_call_data_; method_params_ = static_cast( 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 877111b8a38..e564df8be33 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -27,7 +27,6 @@ #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/health/health_check_parser.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" @@ -50,14 +49,9 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { builder, static_cast(arg), nullptr, nullptr); } -void grpc_service_config_register_parsers() { - grpc_core::internal::ClientChannelServiceConfigParser::Register(); - grpc_core::HealthCheckParser::Register(); -} - void grpc_client_channel_init(void) { grpc_core::ServiceConfig::Init(); - grpc_service_config_register_parsers(); + grpc_core::internal::ClientChannelServiceConfigParser::Register(); grpc_core::LoadBalancingPolicyRegistry::Builder::InitRegistry(); grpc_core::ResolverRegistry::Builder::InitRegistry(); grpc_core::internal::ServerRetryThrottleMap::Init(); diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.cc b/src/core/ext/filters/client_channel/health/health_check_parser.cc deleted file mode 100644 index 7760e22b686..00000000000 --- a/src/core/ext/filters/client_channel/health/health_check_parser.cc +++ /dev/null @@ -1,84 +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 "src/core/ext/filters/client_channel/health/health_check_parser.h" - -namespace grpc_core { -namespace { -size_t g_health_check_parser_index; -} - -UniquePtr HealthCheckParser::ParseGlobalParams( - const grpc_json* json, grpc_error** error) { - GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); - const char* service_name = nullptr; - InlinedVector error_list; - for (grpc_json* field = json->child; field != nullptr; field = field->next) { - if (field->key == nullptr) { - GPR_DEBUG_ASSERT(false); - continue; - } - if (strcmp(field->key, "healthCheckConfig") == 0) { - if (field->type != GRPC_JSON_OBJECT) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:healthCheckConfig error:should be of type object"); - return nullptr; - } - for (grpc_json* sub_field = field->child; sub_field != nullptr; - sub_field = sub_field->next) { - if (sub_field->key == nullptr) { - GPR_DEBUG_ASSERT(false); - continue; - } - if (strcmp(sub_field->key, "serviceName") == 0) { - if (service_name != nullptr) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:serviceName error:Duplicate " - "entry")); - continue; - } - if (sub_field->type != GRPC_JSON_STRING) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:serviceName error:should be of type string")); - continue; - } - service_name = sub_field->value; - } - } - } - } - if (error_list.empty()) { - if (service_name == nullptr) return nullptr; - return UniquePtr( - New(service_name)); - } - *error = ServiceConfig::CreateErrorFromVector("field:healthCheckConfig", - &error_list); - return nullptr; -} - -void HealthCheckParser::Register() { - g_health_check_parser_index = ServiceConfig::RegisterParser( - UniquePtr(New())); -} - -size_t HealthCheckParser::ParserIndex() { return g_health_check_parser_index; } - -} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.h b/src/core/ext/filters/client_channel/health/health_check_parser.h index 036cafc68b7..0143f147152 100644 --- a/src/core/ext/filters/client_channel/health/health_check_parser.h +++ b/src/core/ext/filters/client_channel/health/health_check_parser.h @@ -24,7 +24,7 @@ #include "src/core/ext/filters/client_channel/service_config.h" namespace grpc_core { - +#if 0 class HealthCheckParsedObject : public ServiceConfig::ParsedConfig { public: HealthCheckParsedObject(const char* service_name) @@ -47,5 +47,6 @@ class HealthCheckParser : public ServiceConfig::Parser { static size_t ParserIndex(); }; +#endif } // namespace grpc_core #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H */ 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 fe99e8bc7c0..4bf4dc0ac0b 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 @@ -120,7 +120,8 @@ constexpr char kGrpclb[] = "grpclb"; class ParsedGrpcLbConfig : public ParsedLoadBalancingConfig { public: - ParsedGrpcLbConfig(RefCountedPtr child_policy) + explicit ParsedGrpcLbConfig( + RefCountedPtr child_policy) : child_policy_(std::move(child_policy)) {} const char* name() const override { return kGrpclb; } @@ -1142,13 +1143,13 @@ 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()) { - // If the fallback-at-startup checks are pending, go into fallback mode - // immediately. This short-circuits the timeout for the fallback-at-startup - // case. - if (grpclb_policy->fallback_at_startup_checks_pending_) { - GPR_ASSERT(!lb_calld->seen_serverlist_); + // 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 " + "[grpclb %p] balancer call finished without receiving " "serverlist; entering fallback mode", grpclb_policy); grpclb_policy->fallback_at_startup_checks_pending_ = false; @@ -1393,7 +1394,6 @@ void GrpcLb::UpdateLocked(UpdateArgs args) { } else { child_policy_config_ = nullptr; } - ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); // Update the existing child policy. if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); @@ -1627,16 +1627,20 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked( bool is_backend_from_grpclb_load_balancer) { - InlinedVector args_to_add; - args_to_add.emplace_back(grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), - 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( + const_cast( + GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), + is_backend_from_grpclb_load_balancer), + }; + size_t num_args_to_add = 1; if (is_backend_from_grpclb_load_balancer) { - args_to_add.emplace_back(grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1)); + args_to_add[num_args_to_add++] = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); } - return grpc_channel_args_copy_and_add(args_, args_to_add.data(), - args_to_add.size()); + return grpc_channel_args_copy_and_add(args_, args_to_add, num_args_to_add); } OrphanablePtr GrpcLb::CreateChildPolicyLocked( @@ -1830,8 +1834,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { return RefCountedPtr( New(std::move(child_policy))); } else { - *error = - ServiceConfig::CreateErrorFromVector("GrpcLb Parser", &error_list); + *error = GRPC_ERROR_CREATE_FROM_VECTOR("GrpcLb Parser", &error_list); return 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 b25f66d1dfc..a71efa1f230 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 @@ -362,10 +362,9 @@ class XdsLb : public LoadBalancingPolicy { : parent_(std::move(parent)), locality_weight_(locality_weight) {} ~LocalityEntry() = default; - void UpdateLocked( - xds_grpclb_serverlist* serverlist, - const RefCountedPtr& child_policy_config, - const grpc_channel_args* args); + void UpdateLocked(xds_grpclb_serverlist* serverlist, + ParsedLoadBalancingConfig* child_policy_config, + const grpc_channel_args* args); void ShutdownLocked(); void ResetBackoffLocked(); void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -410,10 +409,9 @@ class XdsLb : public LoadBalancingPolicy { uint32_t locality_weight_; }; - void UpdateLocked( - const LocalityList& locality_list, - const RefCountedPtr& child_policy_config, - const grpc_channel_args* args, XdsLb* parent); + void UpdateLocked(const LocalityList& locality_list, + ParsedLoadBalancingConfig* child_policy_config, + const grpc_channel_args* args, XdsLb* parent); void ShutdownLocked(); void ResetBackoffLocked(); void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -1217,7 +1215,7 @@ void XdsLb::BalancerChannelState::BalancerCallState:: xdslb_policy->locality_serverlist_[0]->serverlist = serverlist; xdslb_policy->locality_map_.UpdateLocked( xdslb_policy->locality_serverlist_, - xdslb_policy->child_policy_config_, xdslb_policy->args_, + xdslb_policy->child_policy_config_.get(), xdslb_policy->args_, xdslb_policy); } } else { @@ -1530,8 +1528,8 @@ void XdsLb::UpdateLocked(UpdateArgs args) { return; } ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); - locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_, args_, - this); + locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_.get(), + args_, this); // Update the existing fallback policy. The fallback policy config and/or the // fallback addresses may be new. if (fallback_policy_ != nullptr) UpdateFallbackPolicyLocked(); @@ -1750,7 +1748,7 @@ void XdsLb::LocalityMap::PruneLocalities(const LocalityList& locality_list) { void XdsLb::LocalityMap::UpdateLocked( const LocalityList& locality_serverlist, - const RefCountedPtr& child_policy_config, + ParsedLoadBalancingConfig* child_policy_config, const grpc_channel_args* args, XdsLb* parent) { if (parent->shutting_down_) return; for (size_t i = 0; i < locality_serverlist.size(); i++) { @@ -1845,13 +1843,13 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked( void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( xds_grpclb_serverlist* serverlist, - const RefCountedPtr& child_policy_config, + ParsedLoadBalancingConfig* child_policy_config, const grpc_channel_args* args_in) { if (parent_->shutting_down_) return; // Construct update args. UpdateArgs update_args; update_args.addresses = ProcessServerlist(serverlist); - update_args.config = child_policy_config; + update_args.config = child_policy_config->Ref(); update_args.args = CreateChildPolicyArgsLocked(args_in); // 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 @@ -2176,8 +2174,8 @@ class XdsFactory : public LoadBalancingPolicyFactory { InlinedVector error_list; const char* balancer_name = nullptr; - RefCountedPtr child_policy = nullptr; - RefCountedPtr fallback_policy = nullptr; + RefCountedPtr child_policy; + RefCountedPtr fallback_policy; for (const grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) continue; @@ -2229,7 +2227,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { return RefCountedPtr(New( balancer_name, std::move(child_policy), std::move(fallback_policy))); } else { - *error = ServiceConfig::CreateErrorFromVector("Xds Parser", &error_list); + *error = GRPC_ERROR_CREATE_FROM_VECTOR("Xds Parser", &error_list); return nullptr; } } 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 b9ea97d4051..973aa26d0f6 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -94,9 +94,21 @@ LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( return factory->CreateLoadBalancingPolicy(std::move(args)); } -bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) { +bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( + const char* name, bool* requires_config) { GPR_ASSERT(g_state != nullptr); - return g_state->GetLoadBalancingPolicyFactory(name) != nullptr; + auto* factory = g_state->GetLoadBalancingPolicyFactory(name); + if (factory == nullptr) { + return false; + } + if (requires_config != nullptr) { + grpc_error* error = GRPC_ERROR_NONE; + // Check if the load balancing policy allows an empty config + *requires_config = + factory->ParseLoadBalancingConfig(nullptr, &error) == nullptr; + GRPC_ERROR_UNREF(error); + } + return true; } namespace { @@ -152,7 +164,8 @@ grpc_json* ParseLoadBalancingConfigHelper(const grpc_json* lb_config_array, return nullptr; } // If we support this policy, then select it. - if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key)) { + if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key, + nullptr)) { return policy; } } @@ -189,19 +202,4 @@ LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, } } -grpc_error* LoadBalancingPolicyRegistry::CanCreateLoadBalancingPolicy( - const char* lb_policy_name) { - GPR_DEBUG_ASSERT(g_state != nullptr); - gpr_log(GPR_ERROR, "%s", lb_policy_name); - auto* factory = g_state->GetLoadBalancingPolicyFactory(lb_policy_name); - if (factory == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingPolicy error:Unknown lb policy"); - } - grpc_error* error = GRPC_ERROR_NONE; - // Check if the load balancing policy allows an empty config - factory->ParseLoadBalancingConfig(nullptr, &error); - return error; -} - } // namespace grpc_core 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 7fa52914cd9..6820cfc9334 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -49,16 +49,15 @@ class LoadBalancingPolicyRegistry { const char* name, LoadBalancingPolicy::Args args); /// Returns true if the LB policy factory specified by \a name exists in this - /// registry. - static bool LoadBalancingPolicyExists(const char* name); + /// registry. If the load balancing policy requires a config to be specified + /// then sets \a requires_config to true. + static bool LoadBalancingPolicyExists(const char* name, + bool* requires_config); /// Returns a parsed object of the load balancing policy to be used from a /// LoadBalancingConfig array \a json. static RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error); - - /// Validates if a load balancing policy can be created from \a lb_policy_name - static grpc_error* CanCreateLoadBalancingPolicy(const char* lb_policy_name); }; } // namespace grpc_core 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 a3bb6b9969b..82fe3c71a5f 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -29,7 +29,6 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/ext/filters/client_channel/health/health_check_parser.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" @@ -88,25 +87,13 @@ ProcessedResolverResult::ProcessedResolverResult( void ProcessedResolverResult::ProcessServiceConfig( const Resolver::Result& resolver_result, const ClientChannelGlobalParsedObject* parsed_object) { - auto* health_check = static_cast( - service_config_->GetParsedGlobalServiceConfigObject( - HealthCheckParser::ParserIndex())); - health_check_service_name_ = - health_check != nullptr ? health_check->service_name() : nullptr; + health_check_service_name_ = parsed_object->health_check_service_name(); service_config_json_ = service_config_->service_config_json(); if (!parsed_object) { return; } if (parsed_object->retry_throttling().has_value()) { - 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; retry_throttle_data_ = parsed_object->retry_throttling(); - grpc_uri_destroy(uri); } } @@ -122,12 +109,6 @@ void ProcessedResolverResult::ProcessLbPolicy( } else { lb_policy_name_.reset( gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); - if (lb_policy_name_ != nullptr) { - char* lb_policy_name = lb_policy_name_.get(); - for (size_t i = 0; i < strlen(lb_policy_name); ++i) { - lb_policy_name[i] = tolower(lb_policy_name[i]); - } - } } } // Otherwise, find the LB policy name set by the client API. @@ -215,8 +196,7 @@ UniquePtr ParseRetryPolicy( if (retry_policy->max_attempts != 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxAttempts error:Duplicate entry")); - continue; - } // Duplicate. + } // Duplicate. Continue Parsing if (sub_field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxAttempts error:should be of type number")); @@ -238,8 +218,7 @@ UniquePtr ParseRetryPolicy( if (retry_policy->initial_backoff > 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:initialBackoff error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:initialBackoff error:Failed to parse")); @@ -253,8 +232,7 @@ UniquePtr ParseRetryPolicy( if (retry_policy->max_backoff > 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxBackoff error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. if (!ParseDuration(sub_field, &retry_policy->max_backoff)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxBackoff error:failed to parse")); @@ -268,8 +246,7 @@ UniquePtr ParseRetryPolicy( if (retry_policy->backoff_multiplier != 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:backoffMultiplier error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. if (sub_field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:backoffMultiplier error:should be of type number")); @@ -289,8 +266,7 @@ UniquePtr ParseRetryPolicy( if (!retry_policy->retryable_status_codes.Empty()) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryableStatusCodes error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. if (sub_field->type != GRPC_JSON_ARRAY) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryableStatusCodes error:should be of type array")); @@ -329,10 +305,48 @@ UniquePtr ParseRetryPolicy( return nullptr; } } - *error = ServiceConfig::CreateErrorFromVector("retryPolicy", &error_list); + *error = GRPC_ERROR_CREATE_FROM_VECTOR("retryPolicy", &error_list); return *error == GRPC_ERROR_NONE ? std::move(retry_policy) : nullptr; } +const char* ParseHealthCheckConfig(const grpc_json* field, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + const char* service_name = nullptr; + GPR_DEBUG_ASSERT(strcmp(field->key, "healthCheckConfig") == 0); + if (field->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:healthCheckConfig error:should be of type object"); + return nullptr; + } + InlinedVector error_list; + for (grpc_json* sub_field = field->child; sub_field != nullptr; + sub_field = sub_field->next) { + if (sub_field->key == nullptr) { + GPR_DEBUG_ASSERT(false); + continue; + } + if (strcmp(sub_field->key, "serviceName") == 0) { + if (service_name != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:serviceName error:Duplicate " + "entry")); + } // Duplicate. Continue parsing + if (sub_field->type != GRPC_JSON_STRING) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:serviceName error:should be of type string")); + continue; + } + service_name = sub_field->value; + } + } + if (!error_list.empty()) { + return nullptr; + } + *error = + GRPC_ERROR_CREATE_FROM_VECTOR("field:healthCheckConfig", &error_list); + return service_name; +} + } // namespace UniquePtr @@ -343,6 +357,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, RefCountedPtr parsed_lb_config; UniquePtr lb_policy_name; Optional retry_throttling; + const char* health_check_service_name = nullptr; for (grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) { continue; // Not the LB config global parameter @@ -352,14 +367,12 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, if (parsed_lb_config != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingConfig error:Duplicate entry")); - } else { - grpc_error* parse_error = GRPC_ERROR_NONE; - parsed_lb_config = - LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(field, - &parse_error); - if (parsed_lb_config == nullptr) { - error_list.push_back(parse_error); - } + } // Duplicate, continue parsing. + grpc_error* parse_error = GRPC_ERROR_NONE; + parsed_lb_config = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, &parse_error); + if (parsed_lb_config == nullptr) { + error_list.push_back(parse_error); } } // Parse deprecated loadBalancingPolicy @@ -367,8 +380,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, if (lb_policy_name != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:Duplicate entry")); - continue; - } else if (field->type != GRPC_JSON_STRING) { + } // Duplicate, continue parsing. + if (field->type != GRPC_JSON_STRING) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:type should be string")); continue; @@ -380,126 +393,141 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, lb_policy[i] = tolower(lb_policy[i]); } } - if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(lb_policy)) { + bool requires_config = false; + if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( + lb_policy, &requires_config)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:Unknown lb policy")); - } else { - grpc_error* parsing_error = - LoadBalancingPolicyRegistry::CanCreateLoadBalancingPolicy( - lb_policy); - if (parsing_error != GRPC_ERROR_NONE) { - error_list.push_back(parsing_error); - } + } else if (requires_config) { + char* error_msg; + gpr_asprintf(&error_msg, + "field:loadBalancingPolicy error:%s requires a config. " + "Please use loadBalancingConfig instead.", + lb_policy); + error_list.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg)); + gpr_free(error_msg); } } // Parse retry throttling if (strcmp(field->key, "retryThrottling") == 0) { + if (retry_throttling.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling error:Duplicate entry")); + } // Duplicate, continue parsing. if (field->type != GRPC_JSON_OBJECT) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling error:Type should be object")); - } else if (retry_throttling.has_value()) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling error:Duplicate entry")); - } else { - Optional max_milli_tokens; - Optional milli_token_ratio; - for (grpc_json* sub_field = field->child; sub_field != nullptr; - sub_field = sub_field->next) { - if (sub_field->key == nullptr) continue; - if (strcmp(sub_field->key, "maxTokens") == 0) { - if (max_milli_tokens.has_value()) { + continue; + } + Optional max_milli_tokens; + Optional milli_token_ratio; + for (grpc_json* sub_field = field->child; sub_field != nullptr; + sub_field = sub_field->next) { + if (sub_field->key == nullptr) continue; + if (strcmp(sub_field->key, "maxTokens") == 0) { + if (max_milli_tokens.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Duplicate " + "entry")); + } else if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Type should be " + "number")); + } else { + max_milli_tokens.set(gpr_parse_nonnegative_int(sub_field->value) * + 1000); + if (max_milli_tokens.value() <= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:maxTokens error:Duplicate " - "entry")); - } else if (sub_field->type != GRPC_JSON_NUMBER) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:maxTokens error:Type should be " - "number")); - } else { - max_milli_tokens.set(gpr_parse_nonnegative_int(sub_field->value) * - 1000); - if (max_milli_tokens.value() <= 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:maxTokens error:should be " - "greater than zero")); - } + "field:retryThrottling field:maxTokens error:should be " + "greater than zero")); } - } else if (strcmp(sub_field->key, "tokenRatio") == 0) { - if (milli_token_ratio.has_value()) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:tokenRatio error:Duplicate " - "entry")); - } else if (sub_field->type != GRPC_JSON_NUMBER) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:tokenRatio error:type should be " - "number")); - } else { - // We support up to 3 decimal digits. - size_t whole_len = strlen(sub_field->value); - uint32_t multiplier = 1; - uint32_t decimal_value = 0; - const char* decimal_point = strchr(sub_field->value, '.'); - if (decimal_point != nullptr) { - whole_len = - static_cast(decimal_point - sub_field->value); - multiplier = 1000; - size_t decimal_len = strlen(decimal_point + 1); - if (decimal_len > 3) decimal_len = 3; - if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len, - &decimal_value)) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:tokenRatio error:Failed " - "parsing")); - continue; - } - uint32_t decimal_multiplier = 1; - for (size_t i = 0; i < (3 - decimal_len); ++i) { - decimal_multiplier *= 10; - } - decimal_value *= decimal_multiplier; - } - uint32_t whole_value; - if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len, - &whole_value)) { + } + } else if (strcmp(sub_field->key, "tokenRatio") == 0) { + if (milli_token_ratio.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Duplicate " + "entry")); + } // Duplicate, continue parsing. + if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:type should be " + "number")); + } else { + // We support up to 3 decimal digits. + size_t whole_len = strlen(sub_field->value); + uint32_t multiplier = 1; + uint32_t decimal_value = 0; + const char* decimal_point = strchr(sub_field->value, '.'); + if (decimal_point != nullptr) { + whole_len = static_cast(decimal_point - sub_field->value); + multiplier = 1000; + size_t decimal_len = strlen(decimal_point + 1); + if (decimal_len > 3) decimal_len = 3; + if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len, + &decimal_value)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling field:tokenRatio error:Failed " "parsing")); continue; } - milli_token_ratio.set( - static_cast((whole_value * multiplier) + decimal_value)); - if (milli_token_ratio.value() <= 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:tokenRatio error:value should " - "be greater than 0")); + uint32_t decimal_multiplier = 1; + for (size_t i = 0; i < (3 - decimal_len); ++i) { + decimal_multiplier *= 10; } + decimal_value *= decimal_multiplier; + } + uint32_t whole_value; + if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len, + &whole_value)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Failed " + "parsing")); + continue; + } + milli_token_ratio.set( + static_cast((whole_value * multiplier) + decimal_value)); + if (milli_token_ratio.value() <= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:value should " + "be greater than 0")); } } } - if (!max_milli_tokens.has_value()) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:maxTokens error:Not found")); - } - if (!milli_token_ratio.has_value()) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:tokenRatio error:Not found")); - } - if (error_list.size() == 0) { - ClientChannelGlobalParsedObject::RetryThrottling data; - data.max_milli_tokens = max_milli_tokens.value(); - data.milli_token_ratio = milli_token_ratio.value(); - retry_throttling.set(data); - } + } + if (!max_milli_tokens.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Not found")); + } + if (!milli_token_ratio.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Not found")); + } + if (error_list.size() == 0) { + ClientChannelGlobalParsedObject::RetryThrottling data; + data.max_milli_tokens = max_milli_tokens.value(); + data.milli_token_ratio = milli_token_ratio.value(); + retry_throttling.set(data); + } + } + if (strcmp(field->key, "healthCheckConfig") == 0) { + if (health_check_service_name != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:healthCheckConfig error:Duplicate entry")); + } // Duplicate continue parsing + grpc_error* parsing_error = GRPC_ERROR_NONE; + health_check_service_name = ParseHealthCheckConfig(field, &parsing_error); + if (parsing_error != GRPC_ERROR_NONE) { + error_list.push_back(parsing_error); } } } - *error = ServiceConfig::CreateErrorFromVector("Client channel global parser", - &error_list); + *error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel global parser", + &error_list); if (*error == GRPC_ERROR_NONE) { return UniquePtr( - New(std::move(parsed_lb_config), - std::move(lb_policy_name), - retry_throttling)); + New( + std::move(parsed_lb_config), std::move(lb_policy_name), + retry_throttling, health_check_service_name)); } return nullptr; } @@ -518,8 +546,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, if (wait_for_ready.has_value()) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:waitForReady error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. if (field->type == GRPC_JSON_TRUE) { wait_for_ready.set(true); } else if (field->type == GRPC_JSON_FALSE) { @@ -532,8 +559,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, if (timeout > 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:timeout error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. if (!ParseDuration(field, &timeout)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:timeout error:Failed parsing")); @@ -542,8 +568,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, if (retry_policy != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryPolicy error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. grpc_error* error = GRPC_ERROR_NONE; retry_policy = ParseRetryPolicy(field, &error); if (retry_policy == nullptr) { @@ -551,8 +576,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, } } } - *error = ServiceConfig::CreateErrorFromVector("Client channel parser", - &error_list); + *error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel parser", &error_list); if (*error == GRPC_ERROR_NONE) { return UniquePtr( New(timeout, wait_for_ready, 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 25830dd4642..1a49fa7be8e 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -47,10 +47,12 @@ class ClientChannelGlobalParsedObject : public ServiceConfig::ParsedConfig { ClientChannelGlobalParsedObject( RefCountedPtr parsed_lb_config, UniquePtr parsed_deprecated_lb_policy, - const Optional& retry_throttling) + const Optional& retry_throttling, + const char* health_check_service_name) : parsed_lb_config_(std::move(parsed_lb_config)), parsed_deprecated_lb_policy_(std::move(parsed_deprecated_lb_policy)), - retry_throttling_(retry_throttling) {} + retry_throttling_(retry_throttling), + health_check_service_name_(health_check_service_name) {} Optional retry_throttling() const { return retry_throttling_; @@ -64,10 +66,15 @@ class ClientChannelGlobalParsedObject : public ServiceConfig::ParsedConfig { return parsed_deprecated_lb_policy_.get(); } + const char* health_check_service_name() const { + return health_check_service_name_; + } + private: RefCountedPtr parsed_lb_config_; UniquePtr parsed_deprecated_lb_policy_; Optional retry_throttling_; + const char* health_check_service_name_ = nullptr; }; class ClientChannelMethodParsedObject : public ServiceConfig::ParsedConfig { @@ -111,8 +118,9 @@ class ClientChannelServiceConfigParser : public ServiceConfig::Parser { static void Register(); }; -// A container of processed fields from the resolver result. Simplifies the -// usage of resolver result. +// TODO(yashykt): It would be cleaner to move this logic to the client_channel +// code. A container of processed fields from the resolver result. Simplifies +// the usage of resolver result. class ProcessedResolverResult { public: // Processes the resolver result and populates the relative members @@ -122,21 +130,19 @@ class ProcessedResolverResult { // Getters. Any managed object's ownership is transferred. const char* service_config_json() { return service_config_json_; } - const char* server_name() { return server_name_; } - - Optional - retry_throttle_data() { - return retry_throttle_data_; - } + RefCountedPtr service_config() { return service_config_; } UniquePtr lb_policy_name() { return std::move(lb_policy_name_); } RefCountedPtr lb_policy_config() { return lb_policy_config_; } - const char* health_check_service_name() { return health_check_service_name_; } + Optional + retry_throttle_data() { + return retry_throttle_data_; + } - RefCountedPtr service_config() { return service_config_; } + const char* health_check_service_name() { return health_check_service_name_; } private: // Finds the service config; extracts LB config and (maybe) retry throttle @@ -163,9 +169,8 @@ class ProcessedResolverResult { RefCountedPtr service_config_; // LB policy. UniquePtr lb_policy_name_; - RefCountedPtr lb_policy_config_ = nullptr; + RefCountedPtr lb_policy_config_; // Retry throttle data. - const char* server_name_ = nullptr; Optional retry_throttle_data_; const char* health_check_service_name_ = nullptr; 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 79d8cf43bc9..193c9e256ed 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -530,7 +530,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( const bool resolution_contains_addresses = result.addresses.size() > 0; // Process the resolver result. const char* lb_policy_name = nullptr; - RefCountedPtr lb_policy_config = nullptr; + RefCountedPtr lb_policy_config; bool service_config_changed = false; if (process_resolver_result_ != nullptr) { 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 9822c2d1dc2..dd8a1de6c7a 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -123,7 +123,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { ProcessResolverResultCallback process_resolver_result_ = nullptr; void* process_resolver_result_user_data_ = nullptr; UniquePtr child_policy_name_; - RefCountedPtr child_lb_config_ = nullptr; + RefCountedPtr child_lb_config_; // Resolver and associated state. OrphanablePtr resolver_; diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index 8db3df712e6..86d4f7368c0 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -98,7 +98,7 @@ grpc_error* ServiceConfig::ParseGlobalParams(const grpc_json* json_tree) { } parsed_global_service_config_objects_.push_back(std::move(parsed_obj)); } - return CreateErrorFromVector("Global Params", &error_list); + return GRPC_ERROR_CREATE_FROM_VECTOR("Global Params", &error_list); } grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( @@ -154,7 +154,7 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( ++*idx; } wrap_error: - return CreateErrorFromVector("methodConfig", &error_list); + return GRPC_ERROR_CREATE_FROM_VECTOR("methodConfig", &error_list); } grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { @@ -211,7 +211,7 @@ grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { num_entries, entries, nullptr); gpr_free(entries); } - return CreateErrorFromVector("Method Params", &error_list); + return GRPC_ERROR_CREATE_FROM_VECTOR("Method Params", &error_list); } ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); } @@ -313,7 +313,7 @@ ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) { return *value; } -size_t ServiceConfig::RegisterParser(UniquePtr parser) { +size_t ServiceConfig::RegisterParser(UniquePtr parser) { g_registered_parsers->push_back(std::move(parser)); return g_registered_parsers->size() - 1; } diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 1372b50eb2a..e6f855ad934 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -71,14 +71,14 @@ class ServiceConfig : public RefCounted { public: virtual ~Parser() = default; - virtual UniquePtr ParseGlobalParams( - const grpc_json* json, grpc_error** error) { + virtual UniquePtr ParseGlobalParams(const grpc_json* json, + grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr); return nullptr; } - virtual UniquePtr ParsePerMethodParams( - const grpc_json* json, grpc_error** error) { + virtual UniquePtr ParsePerMethodParams(const grpc_json* json, + grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr); return nullptr; } @@ -87,10 +87,14 @@ class ServiceConfig : public RefCounted { }; static constexpr int kNumPreallocatedParsers = 4; - typedef InlinedVector, - kNumPreallocatedParsers> + typedef InlinedVector, kNumPreallocatedParsers> ServiceConfigObjectsVector; + /// When a service config is applied to a call in the client_channel_filter, + /// we create an instance of this object and store it in the call_data for + /// client_channel. A pointer to this object is also stored in the + /// call_context, so that future filters can easily access method and global + /// parameters for the call. class CallData { public: CallData() = default; @@ -102,20 +106,21 @@ class ServiceConfig : public RefCounted { } } - RefCountedPtr service_config() { return service_config_; } + ServiceConfig* service_config() { return service_config_.get(); } - ServiceConfig::ParsedConfig* GetMethodParsedObject(int index) const { + ParsedConfig* GetMethodParsedObject(size_t index) const { return method_params_vector_ != nullptr ? (*method_params_vector_)[index].get() : nullptr; } - bool empty() const { return service_config_ == nullptr; } + ParsedConfig* GetGlobalParsedObject(size_t index) const { + return service_config_->GetParsedGlobalServiceConfigObject(index); + } private: RefCountedPtr service_config_; - const ServiceConfig::ServiceConfigObjectsVector* method_params_vector_ = - nullptr; + const ServiceConfigObjectsVector* method_params_vector_ = nullptr; }; /// Creates a new service config from parsing \a json_string. @@ -130,8 +135,7 @@ class ServiceConfig : public RefCounted { /// Retrieves the parsed global service config object at index \a index. The /// lifetime of the returned object is tied to the lifetime of the /// ServiceConfig object. - ServiceConfig::ParsedConfig* GetParsedGlobalServiceConfigObject( - size_t index) { + ParsedConfig* GetParsedGlobalServiceConfigObject(size_t index) { GPR_DEBUG_ASSERT(index < parsed_global_service_config_objects_.size()); return parsed_global_service_config_objects_[index].get(); } @@ -148,30 +152,12 @@ class ServiceConfig : public RefCounted { /// registered parser. Each parser is responsible for reading the service /// config json and returning a parsed object. This parsed object can later be /// retrieved using the same index that was returned at registration time. - static size_t RegisterParser(UniquePtr parser); + static size_t RegisterParser(UniquePtr parser); static void Init(); static void Shutdown(); - // Consumes all the errors in the vector and forms a referencing error from - // them. If the vector is empty, return GRPC_ERROR_NONE. - template - static grpc_error* CreateErrorFromVector( - const char* desc, InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; - } - private: // So New() can call our private ctor. template @@ -203,7 +189,7 @@ class ServiceConfig : public RefCounted { UniquePtr json_string_; // Underlying storage for json_tree. grpc_json* json_tree_; - InlinedVector, kNumPreallocatedParsers> + InlinedVector, kNumPreallocatedParsers> parsed_global_service_config_objects_; // A map from the method name to the service config objects vector. Note that // we are using a raw pointer and not a unique pointer so that we can use the 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 e9140a7b1c0..a92fc0e2991 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -38,12 +38,12 @@ static void recv_message_ready(void* user_data, grpc_error* error); static void recv_trailing_metadata_ready(void* user_data, grpc_error* error); +namespace grpc_core { + namespace { size_t g_message_size_parser_index; } // namespace -namespace grpc_core { - UniquePtr MessageSizeParser::ParsePerMethodParams( const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); @@ -56,8 +56,8 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( if (max_request_message_bytes >= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxRequestMessageBytes error:Duplicate entry")); - } else if (field->type != GRPC_JSON_STRING && - field->type != GRPC_JSON_NUMBER) { + } // Duplicate, continue parsing. + if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxRequestMessageBytes error:should be of type number")); } else { @@ -71,8 +71,8 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( if (max_response_message_bytes >= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:Duplicate entry")); - } else if (field->type != GRPC_JSON_STRING && - field->type != GRPC_JSON_NUMBER) { + } // Duplicate, conitnue parsing + if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:should be of type number")); } else { @@ -85,8 +85,7 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( } } if (!error_list.empty()) { - *error = ServiceConfig::CreateErrorFromVector("Message size parser", - &error_list); + *error = GRPC_ERROR_CREATE_FROM_VECTOR("Message size parser", &error_list); return nullptr; } return UniquePtr(New( @@ -332,7 +331,12 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, channel_data* chand = static_cast(elem->channel_data); new (chand) channel_data(); chand->limits = get_message_size_limits(args->channel_args); - // Get method config table from channel args. + // TODO(yashykt): We only need to read GRPC_ARG_SERVICE_CONFIG in the case of + // direct channels. (Service config is otherwise stored in the call_context by + // client_channel filter.) If we ever need a second filter that also needs to + // parse GRPC_ARG_SERVICE_CONFIG, we should refactor this code and add a + // separate filter that reads GRPC_ARG_SERVICE_CONFIG and saves the parsed + // config in the call_context. Get service config from channel args. const grpc_arg* channel_arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG); const char* service_config_str = grpc_channel_arg_get_string(channel_arg); diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index 5bead0c88ee..2166fe4763a 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -26,7 +26,7 @@ namespace grpc_core { template class Optional { public: - Optional() { value_ = {}; } + Optional() { value_ = T(); } void set(const T& val) { value_ = val; set_ = true; diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index fcc6f0761b3..a877f499fb1 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -30,6 +30,7 @@ #include #include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/inlined_vector.h" /// Opaque representation of an error. /// See https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md for a @@ -193,6 +194,24 @@ inline void grpc_error_unref(grpc_error* err) { #define GRPC_ERROR_UNREF(err) grpc_error_unref(err) #endif +// Consumes all the errors in the vector and forms a referencing error from +// them. If the vector is empty, return GRPC_ERROR_NONE. +template +static grpc_error* GRPC_ERROR_CREATE_FROM_VECTOR( + const char* desc, grpc_core::InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; +} + grpc_error* grpc_error_set_int(grpc_error* src, grpc_error_ints which, intptr_t value) GRPC_MUST_USE_RESULT; /// It is an error to pass nullptr as `p`. Caller should allocate a dummy diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 8060b5a0a8c..12a47e71d7e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -322,7 +322,6 @@ CORE_SOURCE_FILES = [ '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/health/health_check_parser.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', diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index 7a41283012e..9734304c9ac 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -21,7 +21,6 @@ #include #include -#include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/ext/filters/message_size/message_size_filter.h" @@ -528,13 +527,13 @@ TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string( - "(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:loadBalancingPolicy error:Xds " - "Parser has required field - balancerName. Please use " - "loadBalancingConfig field of service config instead.)")); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:" + "loadBalancingPolicy error:xds_experimental requires a " + "config. Please use loadBalancingConfig instead.)")); VerifyRegexMatch(error, e); } @@ -856,7 +855,7 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyBackoffMultiplier) { " \"retryPolicy\": {\n" " \"maxAttempts\": 1,\n" " \"initialBackoff\": \"1s\",\n" - " \"maxBackoff\": \"120sec\",\n" + " \"maxBackoff\": \"120s\",\n" " \"backoffMultiplier\": \"1.6\",\n" " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" " }\n" @@ -886,7 +885,7 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) { " \"retryPolicy\": {\n" " \"maxAttempts\": 1,\n" " \"initialBackoff\": \"1s\",\n" - " \"maxBackoff\": \"120sec\",\n" + " \"maxBackoff\": \"120s\",\n" " \"backoffMultiplier\": \"1.6\",\n" " \"retryableStatusCodes\": []\n" " }\n" @@ -906,6 +905,50 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) { VerifyRegexMatch(error, e); } +TEST_F(ClientChannelParserTest, ValidHealthCheck) { + const char* test_json = + "{\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name\"\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + ASSERT_TRUE(parsed_object != nullptr); + EXPECT_EQ(strcmp(parsed_object->health_check_service_name(), + "health_check_service_name"), + 0); +} + +TEST_F(ClientChannelParserTest, InvalidHealthCheckMultipleEntries) { + const char* test_json = + "{\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name\"\n" + " },\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name1\"\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(field:healthCheckConfig " + "error:Duplicate entry)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + class MessageSizeParserTest : public ::testing::Test { protected: void SetUp() override { @@ -989,59 +1032,6 @@ TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) { VerifyRegexMatch(error, e); } -class HealthCheckParserTest : public ::testing::Test { - protected: - void SetUp() override { - ServiceConfig::Shutdown(); - ServiceConfig::Init(); - EXPECT_TRUE(ServiceConfig::RegisterParser(UniquePtr( - New())) == 0); - } -}; - -TEST_F(HealthCheckParserTest, Valid) { - const char* test_json = - "{\n" - " \"healthCheckConfig\": {\n" - " \"serviceName\": \"health_check_service_name\"\n" - " }\n" - "}"; - grpc_error* error = GRPC_ERROR_NONE; - auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); - const auto* parsed_object = static_cast( - svc_cfg->GetParsedGlobalServiceConfigObject(0)); - ASSERT_TRUE(parsed_object != nullptr); - EXPECT_EQ(strcmp(parsed_object->service_name(), "health_check_service_name"), - 0); -} - -TEST_F(HealthCheckParserTest, MultipleEntries) { - const char* test_json = - "{\n" - " \"healthCheckConfig\": {\n" - " \"serviceName\": \"health_check_service_name\"\n" - " },\n" - " \"healthCheckConfig\": {\n" - " \"serviceName\": \"health_check_service_name1\"\n" - " }\n" - "}"; - grpc_error* error = GRPC_ERROR_NONE; - auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(field:healthCheckConfig)(" - ".*)(referenced_errors)(.*)" - "(field:serviceName error:Duplicate entry)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); -} - } // namespace testing } // namespace grpc_core diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index eee3f777ea6..dad6c98269d 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -892,8 +892,6 @@ 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 \ src/core/ext/filters/client_channel/health/health_check_client.h \ -src/core/ext/filters/client_channel/health/health_check_parser.cc \ -src/core/ext/filters/client_channel/health/health_check_parser.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 \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 0c2204a3f79..9b9ad7d430c 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8732,7 +8732,6 @@ "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/health/health_check_parser.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", @@ -8773,8 +8772,6 @@ "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/health/health_check_parser.cc", - "src/core/ext/filters/client_channel/health/health_check_parser.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", From 1214dff100aca0705855495798c473c78ac22000 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 25 Apr 2019 17:00:00 -0700 Subject: [PATCH 2001/2143] Clean up --- .../health/health_check_parser.h | 52 ------------------- .../client_channel/lb_policy/grpclb/grpclb.cc | 13 +++-- .../client_channel/lb_policy/xds/xds.cc | 6 +-- .../message_size/message_size_filter.cc | 2 +- 4 files changed, 9 insertions(+), 64 deletions(-) delete mode 100644 src/core/ext/filters/client_channel/health/health_check_parser.h diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.h b/src/core/ext/filters/client_channel/health/health_check_parser.h deleted file mode 100644 index 0143f147152..00000000000 --- a/src/core/ext/filters/client_channel/health/health_check_parser.h +++ /dev/null @@ -1,52 +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 GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H - -#include - -#include "src/core/ext/filters/client_channel/service_config.h" - -namespace grpc_core { -#if 0 -class HealthCheckParsedObject : public ServiceConfig::ParsedConfig { - public: - HealthCheckParsedObject(const char* service_name) - : service_name_(service_name) {} - - // Returns the service_name found in the health check config. The lifetime of - // the string is tied to the lifetime of the ServiceConfig object. - const char* service_name() const { return service_name_; } - - private: - const char* service_name_; -}; - -class HealthCheckParser : public ServiceConfig::Parser { - public: - UniquePtr ParseGlobalParams( - const grpc_json* json, grpc_error** error) override; - - static void Register(); - - static size_t ParserIndex(); -}; -#endif -} // namespace grpc_core -#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H */ 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 4bf4dc0ac0b..0bcd471f52f 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 @@ -1143,13 +1143,13 @@ 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()) { - // 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_) { + // If the fallback-at-startup checks are pending, go into fallback mode + // immediately. This short-circuits the timeout for the fallback-at-startup + // case. + if (grpclb_policy->fallback_at_startup_checks_pending_) { + GPR_ASSERT(!lb_calld->seen_serverlist_); gpr_log(GPR_INFO, - "[grpclb %p] balancer call finished without receiving " + "[grpclb %p] Balancer call finished without receiving " "serverlist; entering fallback mode", grpclb_policy); grpclb_policy->fallback_at_startup_checks_pending_ = false; @@ -1820,7 +1820,6 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { if (child_policy != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:childPolicy error:Duplicate entry")); - continue; } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( 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 a71efa1f230..f3806bdbde1 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 @@ -1849,7 +1849,8 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( // Construct update args. UpdateArgs update_args; update_args.addresses = ProcessServerlist(serverlist); - update_args.config = child_policy_config->Ref(); + update_args.config = + child_policy_config == nullptr ? nullptr : child_policy_config->Ref(); update_args.args = CreateChildPolicyArgsLocked(args_in); // 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 @@ -2183,7 +2184,6 @@ class XdsFactory : public LoadBalancingPolicyFactory { if (balancer_name != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:balancerName error:Duplicate entry")); - continue; } if (field->type != GRPC_JSON_STRING) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( @@ -2195,7 +2195,6 @@ class XdsFactory : public LoadBalancingPolicyFactory { if (child_policy != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:childPolicy error:Duplicate entry")); - continue; } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( @@ -2208,7 +2207,6 @@ class XdsFactory : public LoadBalancingPolicyFactory { if (fallback_policy != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:fallbackPolicy error:Duplicate entry")); - continue; } grpc_error* parse_error = GRPC_ERROR_NONE; fallback_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( 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 a92fc0e2991..d21ecb901ac 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -336,7 +336,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, // client_channel filter.) If we ever need a second filter that also needs to // parse GRPC_ARG_SERVICE_CONFIG, we should refactor this code and add a // separate filter that reads GRPC_ARG_SERVICE_CONFIG and saves the parsed - // config in the call_context. Get service config from channel args. + // config in the call_context. const grpc_arg* channel_arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG); const char* service_config_str = grpc_channel_arg_get_string(channel_arg); From ec76108df2edde74009408415809d04f6fc65d70 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 25 Apr 2019 17:09:19 -0700 Subject: [PATCH 2002/2143] Fix a small typo in Python health servicer test --- .../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 1098d38c83e..7a332b8390f 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 @@ -246,7 +246,7 @@ class HealthServicerTest(BaseWatchTests.WatchTests): resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status) - def test_check_unknown_serivce(self): + def test_check_unknown_service(self): request = health_pb2.HealthCheckRequest(service=_UNKNOWN_SERVICE) resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.UNKNOWN, resp.status) From 9345b7e27642a7a0616d92f046bb96b688909c19 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 25 Apr 2019 17:15:30 -0700 Subject: [PATCH 2003/2143] s/atleast/at\ least --- src/core/lib/iomgr/internal_errqueue.cc | 2 +- src/core/lib/iomgr/timer_generic.cc | 2 +- test/core/bad_client/bad_client.cc | 2 +- test/cpp/microbenchmarks/bm_cq_multiple_threads.cc | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/internal_errqueue.cc b/src/core/lib/iomgr/internal_errqueue.cc index 4e2bfe3ccd5..b68c66b7575 100644 --- a/src/core/lib/iomgr/internal_errqueue.cc +++ b/src/core/lib/iomgr/internal_errqueue.cc @@ -36,7 +36,7 @@ static bool errqueue_supported = false; 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 +/* Both-compile time and run-time linux kernel versions should be at least 4.0.0 */ #ifdef GRPC_LINUX_ERRQUEUE struct utsname buffer; diff --git a/src/core/lib/iomgr/timer_generic.cc b/src/core/lib/iomgr/timer_generic.cc index 6a925add80c..4bf86b79551 100644 --- a/src/core/lib/iomgr/timer_generic.cc +++ b/src/core/lib/iomgr/timer_generic.cc @@ -487,7 +487,7 @@ static void timer_cancel(grpc_timer* timer) { /* Rebalances the timer shard by computing a new 'queue_deadline_cap' and moving all relevant timers in shard->list (i.e timers with deadlines earlier than 'queue_deadline_cap') into into shard->heap. - Returns 'true' if shard->heap has atleast ONE element + Returns 'true' if shard->heap has at least ONE element REQUIRES: shard->mu locked */ static bool refill_heap(timer_shard* shard, grpc_millis now) { /* Compute the new queue window width and bound by the limits: */ diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc index 6b492523219..26550a2a701 100644 --- a/test/core/bad_client/bad_client.cc +++ b/test/core/bad_client/bad_client.cc @@ -257,7 +257,7 @@ bool client_connection_preface_validator(grpc_slice_buffer* incoming, return false; } grpc_slice slice = incoming->slices[0]; - /* There should be atleast a settings frame present */ + /* There should be at least one settings frame present */ if (GRPC_SLICE_LENGTH(slice) < MIN_HTTP2_FRAME_SIZE) { return false; } diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc index 54455350c24..329eaf2434e 100644 --- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc +++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc @@ -138,7 +138,7 @@ static void teardown() { Setup: The benchmark framework ensures that none of the threads proceed beyond the state.KeepRunning() call unless all the threads have called state.keepRunning - atleast once. So it is safe to do the initialization in one of the threads + at least once. So it is safe to do the initialization in one of the threads before state.KeepRunning() is called. Teardown: From 488e649781bb2a7cdc32dbbf7ac6dbbbded31793 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 26 Apr 2019 07:45:00 +0200 Subject: [PATCH 2004/2143] Add info about C# nightly nuget feed --- src/csharp/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/csharp/README.md b/src/csharp/README.md index 291772ff939..391671b34a8 100644 --- a/src/csharp/README.md +++ b/src/csharp/README.md @@ -40,6 +40,17 @@ See [Experimentally supported platforms](experimental) for instructions. See [Experimentally supported platforms](experimental) for instructions. +NUGET DEVELOPMENT FEED (NIGHTLY BUILDS) +-------------- + +In production, you should use officially released stable packages available on http://nuget.org, but if you want to test the newest upstream bug fixes and features early, you can can use the development nuget feed where new nuget builds are uploaded nightly. + +Feed URL (NuGet v2): https://grpc.jfrog.io/grpc/api/nuget/grpc-nuget-dev + +Feed URL (NuGet v3): Feed https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev + +The same development nuget packages and packages for other languages can also be found at https://packages.grpc.io/ + BUILD FROM SOURCE ----------------- From a96f2e860ce5ebcc283f6a830872676dceae7abd Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Fri, 26 Apr 2019 08:15:56 +0200 Subject: [PATCH 2005/2143] fix a nit Co-Authored-By: jtattermusch --- 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 391671b34a8..c01cae0422d 100644 --- a/src/csharp/README.md +++ b/src/csharp/README.md @@ -47,7 +47,7 @@ In production, you should use officially released stable packages available on h Feed URL (NuGet v2): https://grpc.jfrog.io/grpc/api/nuget/grpc-nuget-dev -Feed URL (NuGet v3): Feed https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev +Feed URL (NuGet v3): https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev The same development nuget packages and packages for other languages can also be found at https://packages.grpc.io/ From bbd4eb5028438ab84a50c2371874707615b94578 Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Fri, 26 Apr 2019 09:52:12 -0700 Subject: [PATCH 2006/2143] Add microbenchmark for callback unary ping pong and bidistreaming ping pong --- CMakeLists.txt | 147 +++++++++++++++++ Makefile | 148 +++++++++++++++++ build.yaml | 66 ++++++++ grpc.gyp | 15 ++ test/cpp/microbenchmarks/BUILD | 91 ++++++++-- .../bm_callback_streaming_ping_pong.cc | 155 ++++++++++++++++++ .../bm_callback_unary_ping_pong.cc | 148 +++++++++++++++++ .../callback_streaming_ping_pong.h | 53 ++++++ .../microbenchmarks/callback_test_service.cc | 111 +++++++++++++ .../microbenchmarks/callback_test_service.h | 95 +++++++++++ .../callback_unary_ping_pong.h | 84 ++++++++++ .../generated/sources_and_headers.json | 72 ++++++++ tools/run_tests/generated/tests.json | 52 ++++++ 13 files changed, 1219 insertions(+), 18 deletions(-) create mode 100644 test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc create mode 100644 test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc create mode 100644 test/cpp/microbenchmarks/callback_streaming_ping_pong.h create mode 100644 test/cpp/microbenchmarks/callback_test_service.cc create mode 100644 test/cpp/microbenchmarks/callback_test_service.h create mode 100644 test/cpp/microbenchmarks/callback_unary_ping_pong.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b93ab08af4..41427278646 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -556,6 +556,12 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_call_create) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_callback_streaming_ping_pong) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_callback_unary_ping_pong) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_channel) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -2896,6 +2902,55 @@ target_link_libraries(test_tcp_server ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_library(callback_test_service + test/cpp/microbenchmarks/callback_test_service.cc +) + +if(WIN32 AND MSVC) + set_target_properties(callback_test_service PROPERTIES COMPILE_PDB_NAME "callback_test_service" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if (gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/callback_test_service.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + + +target_include_directories(callback_test_service + 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(callback_test_service + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + ${_gRPC_BENCHMARK_LIBRARIES} + grpc++_test_util + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) add_library(grpc++ @@ -11479,6 +11534,98 @@ target_link_libraries(bm_call_create ) +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(bm_callback_streaming_ping_pong + test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bm_callback_streaming_ping_pong + 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_callback_streaming_ping_pong + ${_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 + callback_test_service + ${_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_callback_unary_ping_pong + test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bm_callback_unary_ping_pong + 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_callback_unary_ping_pong + ${_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 + callback_test_service + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 700e789265e..6e83616e243 100644 --- a/Makefile +++ b/Makefile @@ -1162,6 +1162,8 @@ 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 +bm_callback_streaming_ping_pong: $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong +bm_callback_unary_ping_pong: $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong bm_channel: $(BINDIR)/$(CONFIG)/bm_channel bm_chttp2_hpack: $(BINDIR)/$(CONFIG)/bm_chttp2_hpack bm_chttp2_transport: $(BINDIR)/$(CONFIG)/bm_chttp2_transport @@ -1638,6 +1640,8 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_arena \ $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ + $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong \ + $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_channel \ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \ $(BINDIR)/$(CONFIG)/bm_chttp2_transport \ @@ -1782,6 +1786,8 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_arena \ $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ + $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong \ + $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_channel \ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \ $(BINDIR)/$(CONFIG)/bm_chttp2_transport \ @@ -2232,6 +2238,10 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/bm_byte_buffer || ( echo test bm_byte_buffer failed ; exit 1 ) $(E) "[RUN] Testing bm_call_create" $(Q) $(BINDIR)/$(CONFIG)/bm_call_create || ( echo test bm_call_create failed ; exit 1 ) + $(E) "[RUN] Testing bm_callback_streaming_ping_pong" + $(Q) $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong || ( echo test bm_callback_streaming_ping_pong failed ; exit 1 ) + $(E) "[RUN] Testing bm_callback_unary_ping_pong" + $(Q) $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong || ( echo test bm_callback_unary_ping_pong failed ; exit 1 ) $(E) "[RUN] Testing bm_channel" $(Q) $(BINDIR)/$(CONFIG)/bm_channel || ( echo test bm_channel failed ; exit 1 ) $(E) "[RUN] Testing bm_chttp2_hpack" @@ -5273,6 +5283,55 @@ endif endif +LIBCALLBACK_TEST_SERVICE_SRC = \ + test/cpp/microbenchmarks/callback_test_service.cc \ + +PUBLIC_HEADERS_CXX += \ + +LIBCALLBACK_TEST_SERVICE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBCALLBACK_TEST_SERVICE_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libcallback_test_service.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)/libcallback_test_service.a: protobuf_dep_error + + +else + +$(LIBDIR)/$(CONFIG)/libcallback_test_service.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBCALLBACK_TEST_SERVICE_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libcallback_test_service.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libcallback_test_service.a $(LIBCALLBACK_TEST_SERVICE_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libcallback_test_service.a +endif + + + + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBCALLBACK_TEST_SERVICE_OBJS:.o=.dep) +endif +endif + + LIBGRPC++_SRC = \ src/cpp/client/insecure_credentials.cc \ src/cpp/client/secure_credentials.cc \ @@ -14407,6 +14466,94 @@ endif endif +BM_CALLBACK_STREAMING_PING_PONG_SRC = \ + test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc \ + +BM_CALLBACK_STREAMING_PING_PONG_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CALLBACK_STREAMING_PING_PONG_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong: 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_callback_streaming_ping_pong: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong: $(PROTOBUF_DEP) $(BM_CALLBACK_STREAMING_PING_PONG_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 $(LIBDIR)/$(CONFIG)/libcallback_test_service.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_CALLBACK_STREAMING_PING_PONG_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 $(LIBDIR)/$(CONFIG)/libcallback_test_service.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong + +endif + +endif + +$(BM_CALLBACK_STREAMING_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.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 $(LIBDIR)/$(CONFIG)/libcallback_test_service.a + +deps_bm_callback_streaming_ping_pong: $(BM_CALLBACK_STREAMING_PING_PONG_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_CALLBACK_STREAMING_PING_PONG_OBJS:.o=.dep) +endif +endif + + +BM_CALLBACK_UNARY_PING_PONG_SRC = \ + test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc \ + +BM_CALLBACK_UNARY_PING_PONG_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CALLBACK_UNARY_PING_PONG_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong: 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_callback_unary_ping_pong: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong: $(PROTOBUF_DEP) $(BM_CALLBACK_UNARY_PING_PONG_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 $(LIBDIR)/$(CONFIG)/libcallback_test_service.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_CALLBACK_UNARY_PING_PONG_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 $(LIBDIR)/$(CONFIG)/libcallback_test_service.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong + +endif + +endif + +$(BM_CALLBACK_UNARY_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.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 $(LIBDIR)/$(CONFIG)/libcallback_test_service.a + +deps_bm_callback_unary_ping_pong: $(BM_CALLBACK_UNARY_PING_PONG_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_CALLBACK_UNARY_PING_PONG_OBJS:.o=.dep) +endif +endif + + BM_CHANNEL_SRC = \ test/cpp/microbenchmarks/bm_channel.cc \ @@ -22067,6 +22214,7 @@ test/cpp/interop/interop_client.cc: $(OPENSSL_DEP) test/cpp/interop/interop_server.cc: $(OPENSSL_DEP) test/cpp/interop/interop_server_bootstrap.cc: $(OPENSSL_DEP) test/cpp/interop/server_helper.cc: $(OPENSSL_DEP) +test/cpp/microbenchmarks/callback_test_service.cc: $(OPENSSL_DEP) test/cpp/microbenchmarks/helpers.cc: $(OPENSSL_DEP) test/cpp/qps/benchmark_config.cc: $(OPENSSL_DEP) test/cpp/qps/client_async.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 848bf4ba072..25a476d44fe 100644 --- a/build.yaml +++ b/build.yaml @@ -1665,6 +1665,20 @@ libs: - grpc_test_util - grpc - gpr +- name: callback_test_service + build: test + language: c++ + headers: + - test/cpp/microbenchmarks/callback_test_service.h + src: + - test/cpp/microbenchmarks/callback_test_service.cc + deps: + - benchmark + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr - name: grpc++ build: all language: c++ @@ -4024,6 +4038,58 @@ targets: - linux - posix uses_polling: false +- name: bm_callback_streaming_ping_pong + build: test + language: c++ + headers: + - test/cpp/microbenchmarks/callback_streaming_ping_pong.h + src: + - test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc + deps: + - grpc_benchmark + - benchmark + - grpc++_test_util_unsecure + - grpc_test_util_unsecure + - grpc++_unsecure + - grpc_unsecure + - gpr + - grpc++_test_config + - callback_test_service + benchmark: true + defaults: benchmark + excluded_poll_engines: + - poll + platforms: + - mac + - linux + - posix + timeout_seconds: 1200 +- name: bm_callback_unary_ping_pong + build: test + language: c++ + headers: + - test/cpp/microbenchmarks/callback_unary_ping_pong.h + src: + - test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc + deps: + - grpc_benchmark + - benchmark + - grpc++_test_util_unsecure + - grpc_test_util_unsecure + - grpc++_unsecure + - grpc_unsecure + - gpr + - grpc++_test_config + - callback_test_service + benchmark: true + defaults: benchmark + excluded_poll_engines: + - poll + platforms: + - mac + - linux + - posix + timeout_seconds: 1200 - name: bm_channel build: test language: c++ diff --git a/grpc.gyp b/grpc.gyp index 5321658508a..fab5b010a4f 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1398,6 +1398,21 @@ 'test/core/util/test_tcp_server.cc', ], }, + { + 'target_name': 'callback_test_service', + 'type': 'static_library', + 'dependencies': [ + 'benchmark', + 'grpc++_test_util', + 'grpc_test_util', + 'grpc++', + 'grpc', + 'gpr', + ], + 'sources': [ + 'test/cpp/microbenchmarks/callback_test_service.cc', + ], + }, { 'target_name': 'grpc++', 'type': 'static_library', diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 6e844a6dc62..e28846fcf94 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -39,85 +39,85 @@ grpc_cc_library( external_deps = [ "benchmark", ], + tags = ["no_windows"], deps = [ "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", "//test/cpp/util:test_config", ], - tags = ["no_windows"], ) grpc_cc_binary( name = "bm_closure", testonly = 1, srcs = ["bm_closure.cc"], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], ) grpc_cc_binary( name = "bm_alarm", testonly = 1, srcs = ["bm_alarm.cc"], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], ) grpc_cc_binary( name = "bm_arena", testonly = 1, srcs = ["bm_arena.cc"], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], ) grpc_cc_binary( name = "bm_byte_buffer", testonly = 1, srcs = ["bm_byte_buffer.cc"], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], ) grpc_cc_binary( name = "bm_channel", testonly = 1, srcs = ["bm_channel.cc"], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], ) grpc_cc_binary( name = "bm_call_create", testonly = 1, srcs = ["bm_call_create.cc"], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], ) grpc_cc_binary( name = "bm_cq", testonly = 1, srcs = ["bm_cq.cc"], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], ) grpc_cc_binary( name = "bm_cq_multiple_threads", testonly = 1, srcs = ["bm_cq_multiple_threads.cc"], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], ) grpc_cc_binary( name = "bm_error", testonly = 1, srcs = ["bm_error.cc"], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], ) grpc_cc_library( @@ -126,8 +126,8 @@ grpc_cc_library( hdrs = [ "fullstack_streaming_ping_pong.h", ], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], ) grpc_cc_binary( @@ -136,8 +136,8 @@ grpc_cc_binary( srcs = [ "bm_fullstack_streaming_ping_pong.cc", ], - deps = [":fullstack_streaming_ping_pong_h"], tags = ["no_windows"], + deps = [":fullstack_streaming_ping_pong_h"], ) grpc_cc_library( @@ -155,16 +155,16 @@ grpc_cc_binary( srcs = [ "bm_fullstack_streaming_pump.cc", ], - deps = [":fullstack_streaming_pump_h"], tags = ["no_windows"], + deps = [":fullstack_streaming_pump_h"], ) grpc_cc_binary( name = "bm_fullstack_trickle", testonly = 1, srcs = ["bm_fullstack_trickle.cc"], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], ) grpc_cc_library( @@ -182,24 +182,24 @@ grpc_cc_binary( srcs = [ "bm_fullstack_unary_ping_pong.cc", ], - deps = [":fullstack_unary_ping_pong_h"], tags = ["no_windows"], + deps = [":fullstack_unary_ping_pong_h"], ) grpc_cc_binary( name = "bm_metadata", testonly = 1, srcs = ["bm_metadata.cc"], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], ) grpc_cc_binary( name = "bm_chttp2_hpack", testonly = 1, srcs = ["bm_chttp2_hpack.cc"], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], ) grpc_cc_binary( @@ -218,6 +218,61 @@ grpc_cc_binary( name = "bm_timer", testonly = 1, srcs = ["bm_timer.cc"], - deps = [":helpers"], tags = ["no_windows"], + deps = [":helpers"], +) + +grpc_cc_library( + name = "callback_test_service", + testonly = 1, + srcs = ["callback_test_service.cc"], + hdrs = ["callback_test_service.h"], + deps = [ + "//third_party/grpc/src/proto/grpc/testing:echo_proto", + "//third_party/grpc/test/cpp/util:test_util", + ], +) + +grpc_cc_library( + name = "callback_unary_ping_pong_h", + testonly = 1, + hdrs = [ + "callback_unary_ping_pong.h", + ], + deps = [ + ":callback_test_service", + ":helpers", + ], +) + +grpc_cc_binary( + name = "bm_callback_unary_ping_pong", + testonly = 1, + srcs = [ + "bm_callback_unary_ping_pong.cc", + ], + tags = ["no_windows"], + deps = [":callback_unary_ping_pong_h"], +) + +grpc_cc_library( + name = "callback_streaming_ping_pong_h", + testonly = 1, + hdrs = [ + "callback_streaming_ping_pong.h", + ], + deps = [ + ":callback_test_service", + ":helpers", + ], +) + +grpc_cc_binary( + name = "bm_callback_streaming_ping_pong", + testonly = 1, + srcs = [ + "bm_callback_streaming_ping_pong.cc", + ], + tags = ["no_windows"], + deps = [":callback_streaming_ping_pong_h"], ) diff --git a/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc new file mode 100644 index 00000000000..ad7c2f0ee3e --- /dev/null +++ b/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc @@ -0,0 +1,155 @@ +#include "test/cpp/microbenchmarks/callback_streaming_ping_pong.h" +#include "test/cpp/util/test_config.h" + +namespace grpc { +namespace testing { + +// force library initialization +auto& force_library_initialization = Library::get(); + +/******************************************************************************* + * CONFIGURATIONS + */ + +// Replace "benchmark::internal::Benchmark" with "::testing::Benchmark" to use +// internal microbenchmarking tooling +static void StreamingPingPongArgs(benchmark::internal::Benchmark* b) { + int msg_size = 0; + + b->Args({0, 0}); // spl case: 0 ping-pong msgs (msg_size doesn't matter here) + + for (msg_size = 0; msg_size <= 128 * 1024 * 1024; + msg_size == 0 ? msg_size++ : msg_size *= 8) { + b->Args({msg_size, 1}); + b->Args({msg_size, 2}); + } +} +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + NoOpMutator) + ->Apply(StreamingPingPongArgs); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, MinInProcess, NoOpMutator, + NoOpMutator) + ->Apply(StreamingPingPongArgs); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + NoOpMutator) + ->Apply(StreamingPingPongArgs); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, MinInProcessCHTTP2, NoOpMutator, + NoOpMutator) + ->Apply(StreamingPingPongArgs); + +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, + Client_AddMetadata, 1>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, + Client_AddMetadata, 2>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 100>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 1>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 2>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 100>) + ->Args({0, 0}); + +} // 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/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc new file mode 100644 index 00000000000..fee41ea8d1a --- /dev/null +++ b/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc @@ -0,0 +1,148 @@ +#include "test/cpp/microbenchmarks/callback_unary_ping_pong.h" +#include "test/cpp/util/test_config.h" + +namespace grpc { +namespace testing { + +// force library initialization +auto& force_library_initialization = Library::get(); + +/******************************************************************************* + * CONFIGURATIONS + */ + +// Replace "benchmark::internal::Benchmark" with "::testing::Benchmark" to use +// internal microbenchmarking tooling +static void SweepSizesArgs(benchmark::internal::Benchmark* b) { + b->Args({0, 0}); + for (int i = 1; i <= 128 * 1024 * 1024; i *= 8) { + b->Args({i, 0}); + b->Args({0, i}); + b->Args({i, i}); + } +} + +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, NoOpMutator) + ->Apply(SweepSizesArgs); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, MinInProcess, NoOpMutator, NoOpMutator) + ->Apply(SweepSizesArgs); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, NoOpMutator) + ->Apply(SweepSizesArgs); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, MinInProcessCHTTP2, NoOpMutator, + NoOpMutator) + ->Apply(SweepSizesArgs); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 1>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 2>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 100>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 2>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 100>) + ->Args({0, 0}); +} // 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/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h new file mode 100644 index 00000000000..13b4c155459 --- /dev/null +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -0,0 +1,53 @@ +#ifndef TEST_CPP_MICROBENCHMARKS_CALLBACK_STREAMING_PING_PONG_H +#define TEST_CPP_MICROBENCHMARKS_CALLBACK_STREAMING_PING_PONG_H + + +#include +#include +#include "src/core/lib/profiling/timers.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/microbenchmarks/fullstack_context_mutators.h" +#include "test/cpp/microbenchmarks/fullstack_fixtures.h" +#include "test/cpp/microbenchmarks/callback_test_service.h" + +namespace grpc { +namespace testing { + +/******************************************************************************* + * BENCHMARKING KERNELS + */ + +template +static void BM_CallbackBidiStreaming(benchmark::State& state) { + const int message_size = state.range(0); + const int max_ping_pongs = state.range(1) > 0 ? 1 : state.range(1); + CallbackStreamingTestService service; + std::unique_ptr fixture(new Fixture(&service)); + std::unique_ptr stub_( + EchoTestService::NewStub(fixture->channel())); + EchoRequest* request = new EchoRequest; + EchoResponse* response = new EchoResponse; + if (state.range(0) > 0) { + request->set_message(std::string(state.range(0), 'a')); + } else { + request->set_message(""); + } + while (state.KeepRunning()) { + GPR_TIMER_SCOPE("BenchmarkCycle", 0); + ClientContext* cli_ctx = new ClientContext; + cli_ctx->AddMetadata(kServerFinishAfterNReads, + grpc::to_string(max_ping_pongs)); + cli_ctx->AddMetadata(kServerResponseStreamsToSend, + grpc::to_string(message_size)); + BidiClient test{stub_.get(), request, response, cli_ctx, max_ping_pongs}; + test.Await(); + } + fixture->Finish(state); + fixture.reset(); + state.SetBytesProcessed(2 * state.range(0) * state.iterations() + * state.range(1)); +} + +} // namespace testing +} // namespace grpc +#endif // TEST_CPP_MICROBENCHMARKS_CALLBACK_STREAMING_PING_PONG_H diff --git a/test/cpp/microbenchmarks/callback_test_service.cc b/test/cpp/microbenchmarks/callback_test_service.cc new file mode 100644 index 00000000000..057517acf05 --- /dev/null +++ b/test/cpp/microbenchmarks/callback_test_service.cc @@ -0,0 +1,111 @@ +#include "test/cpp/microbenchmarks/callback_test_service.h" + +namespace grpc { +namespace testing { +namespace { + +grpc::string ToString(const grpc::string_ref& r) { + return grpc::string(r.data(), r.size()); +} + +int GetIntValueFromMetadataHelper( + const char* key, + const std::multimap& metadata, + int default_value) { + if (metadata.find(key) != metadata.end()) { + std::istringstream iss(ToString(metadata.find(key)->second)); + iss >> default_value; + } + + return default_value; +} + +int GetIntValueFromMetadata( + const char* key, + const std::multimap& metadata, + int default_value) { + return GetIntValueFromMetadataHelper(key, metadata, default_value); +} +} // namespace + +void CallbackStreamingTestService::Echo( + ServerContext* context, const EchoRequest* request, EchoResponse* response, + experimental::ServerCallbackRpcController* controller) { + controller->Finish(Status::OK); +} + +experimental::ServerBidiReactor* +CallbackStreamingTestService::BidiStream() { + class Reactor : public experimental::ServerBidiReactor { + public: + Reactor() {} + void OnStarted(ServerContext* context) override { + ctx_ = context; + server_write_last_ = GetIntValueFromMetadata( + kServerFinishAfterNReads, context->client_metadata(), 0); + message_size_ = GetIntValueFromMetadata( + kServerResponseStreamsToSend, context->client_metadata(), 0); +// EchoRequest* request = new EchoRequest; +// if (message_size_ > 0) { +// request->set_message(std::string(message_size_, 'a')); +// } else { +// request->set_message(""); +// } +// +// request_ = request; + StartRead(&request_); + on_started_done_ = true; + } + void OnDone() override { delete this; } + void OnCancel() override {} + void OnReadDone(bool ok) override { + if (ok) { + num_msgs_read_++; +// gpr_log(GPR_INFO, "recv msg %s", request_.message().c_str()); + if (message_size_ > 0) { + response_.set_message(std::string(message_size_, 'a')); + } else { + response_.set_message(""); + } + if (num_msgs_read_ == server_write_last_) { + StartWriteLast(&response_, WriteOptions()); + } else { + StartWrite(&response_); + return; + } + } + FinishOnce(Status::OK); + } + void OnWriteDone(bool ok) override { + std::lock_guard l(finish_mu_); + if (!finished_) { + StartRead(&request_); + } + } + + private: + void FinishOnce(const Status& s) { + std::lock_guard l(finish_mu_); + if (!finished_) { + Finish(s); + finished_ = true; + } + } + + ServerContext* ctx_; + EchoRequest request_; + EchoResponse response_; + int num_msgs_read_{0}; + int server_write_last_; + int message_size_; + std::mutex finish_mu_; + bool finished_{false}; + bool on_started_done_{false}; + }; + + return new Reactor; +} +} // namespace testing +} // namespace grpc + diff --git a/test/cpp/microbenchmarks/callback_test_service.h b/test/cpp/microbenchmarks/callback_test_service.h new file mode 100644 index 00000000000..3c43ecb2215 --- /dev/null +++ b/test/cpp/microbenchmarks/callback_test_service.h @@ -0,0 +1,95 @@ +#ifndef TEST_CPP_MICROBENCHMARKS_CALLBACK_TEST_SERVICE_H +#define TEST_CPP_MICROBENCHMARKS_CALLBACK_TEST_SERVICE_H + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/util/string_ref_helper.h" +#include +#include +#include +#include + +namespace grpc { +namespace testing { + +const char* const kServerFinishAfterNReads = "server_finish_after_n_reads"; +const char* const kServerResponseStreamsToSend = "server_responses_to_send"; + +class CallbackStreamingTestService + : public EchoTestService::ExperimentalCallbackService { + public: + CallbackStreamingTestService() {} + void Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response, + experimental::ServerCallbackRpcController* controller) override; + + experimental::ServerBidiReactor* BidiStream() override; +}; + +class BidiClient + : public grpc::experimental::ClientBidiReactor { + public: + BidiClient(EchoTestService::Stub* stub, EchoRequest* request, + EchoResponse* response, ClientContext* context, int num_msgs_to_send) + : request_{request}, + response_{response}, + context_{context}, + msgs_to_send_{num_msgs_to_send}{ + stub->experimental_async()->BidiStream(context_, this); + MaybeWrite(); + StartRead(response_); + StartCall(); + } + + void OnReadDone(bool ok) override { + if (ok && reads_complete_ < msgs_to_send_) { + reads_complete_++; + StartRead(response_); + } + } + + void OnWriteDone(bool ok) override { + if (!ok) { + return; + } + writes_complete_++; + MaybeWrite(); + } + + void OnDone(const Status& s) override { + GPR_ASSERT(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: + void MaybeWrite() { + if (writes_complete_ == msgs_to_send_) { + StartWritesDone(); + } else { + StartWrite(request_); + } + } + + EchoRequest* request_; + EchoResponse* response_; + ClientContext* context_; + int reads_complete_{0}; + int writes_complete_{0}; + const int msgs_to_send_; + std::mutex mu_; + std::condition_variable cv_; + bool done_ = false; +}; + + +} // namespace testing +} // namespace grpc +#endif // TEST_CPP_MICROBENCHMARKS_CALLBACK_TEST_SERVICE_H diff --git a/test/cpp/microbenchmarks/callback_unary_ping_pong.h b/test/cpp/microbenchmarks/callback_unary_ping_pong.h new file mode 100644 index 00000000000..7babb56287d --- /dev/null +++ b/test/cpp/microbenchmarks/callback_unary_ping_pong.h @@ -0,0 +1,84 @@ +/* + * + * 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. + * + */ + +/* Benchmark gRPC end2end in various configurations */ + +#ifndef TEST_CPP_MICROBENCHMARKS_CALLBACK_UNARY_PING_PONG_H +#define TEST_CPP_MICROBENCHMARKS_CALLBACK_UNARY_PING_PONG_H + +#include +#include +#include "src/core/lib/profiling/timers.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/microbenchmarks/fullstack_context_mutators.h" +#include "test/cpp/microbenchmarks/fullstack_fixtures.h" +#include "test/cpp/microbenchmarks/callback_test_service.h" + +namespace grpc { +namespace testing { + +/******************************************************************************* + * BENCHMARKING KERNELS + */ + +template +static void BM_CallbackUnaryPingPong(benchmark::State& state) { + CallbackStreamingTestService service; + std::unique_ptr fixture(new Fixture(&service)); + std::unique_ptr stub_( + EchoTestService::NewStub(fixture->channel())); + EchoRequest request; + EchoResponse response; + + if (state.range(0) > 0) { + request.set_message(std::string(state.range(0), 'a')); + } else { + request.set_message(""); + } + if (state.range(1) > 0) { + response.set_message(std::string(state.range(1), 'a')); + } else { + response.set_message(""); + } + + while (state.KeepRunning()) { + GPR_TIMER_SCOPE("BenchmarkCycle", 0); + ClientContext cli_ctx; + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub_->experimental_async()->Echo(&cli_ctx, &request, &response, + [&done, &mu, &cv](Status s) { + GPR_ASSERT(s.ok()); + std::lock_guard l(mu); + done = true; + cv.notify_one(); + }); + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } + } + fixture->Finish(state); + fixture.reset(); + state.SetBytesProcessed(state.range(0) * state.iterations() + state.range(1) * state.iterations()); +} +} // namespace testing +} // namespace grpc + +#endif // TEST_CPP_MICROBENCHMARKS_FULLSTACK_UNARY_PING_PONG_H diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 9778343cd94..486ff054794 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -2776,6 +2776,56 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "benchmark", + "callback_test_service", + "gpr", + "grpc++_test_config", + "grpc++_test_util_unsecure", + "grpc++_unsecure", + "grpc_benchmark", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [ + "test/cpp/microbenchmarks/callback_streaming_ping_pong.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "bm_callback_streaming_ping_pong", + "src": [ + "test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc", + "test/cpp/microbenchmarks/callback_streaming_ping_pong.h" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "benchmark", + "callback_test_service", + "gpr", + "grpc++_test_config", + "grpc++_test_util_unsecure", + "grpc++_unsecure", + "grpc_benchmark", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [ + "test/cpp/microbenchmarks/callback_unary_ping_pong.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "bm_callback_unary_ping_pong", + "src": [ + "test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc", + "test/cpp/microbenchmarks/callback_unary_ping_pong.h" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "benchmark", @@ -6573,6 +6623,28 @@ "third_party": false, "type": "lib" }, + { + "deps": [ + "benchmark", + "gpr", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [ + "test/cpp/microbenchmarks/callback_test_service.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "callback_test_service", + "src": [ + "test/cpp/microbenchmarks/callback_test_service.cc", + "test/cpp/microbenchmarks/callback_test_service.h" + ], + "third_party": false, + "type": "lib" + }, { "deps": [ "gpr", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index ec2e570bea7..d442c3b9744 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3479,6 +3479,58 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": true, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "excluded_poll_engines": [ + "poll" + ], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_callback_streaming_ping_pong", + "platforms": [ + "linux", + "mac", + "posix" + ], + "timeout_seconds": 1200, + "uses_polling": true + }, + { + "args": [], + "benchmark": true, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "excluded_poll_engines": [ + "poll" + ], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_callback_unary_ping_pong", + "platforms": [ + "linux", + "mac", + "posix" + ], + "timeout_seconds": 1200, + "uses_polling": true + }, { "args": [], "benchmark": true, From c864bea0c675d7abe67978c8f263c76d6a411875 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 23 Apr 2019 17:58:44 -0700 Subject: [PATCH 2007/2143] Move TestService to a separate file to simplify its dependency --- .../tests/fork/_fork_interop_test.py | 4 +- .../grpcio_tests/tests/interop/BUILD.bazel | 91 +++++++++-------- .../tests/interop/_insecure_intraop_test.py | 4 +- .../tests/interop/_secure_intraop_test.py | 4 +- .../grpcio_tests/tests/interop/methods.py | 73 -------------- .../grpcio_tests/tests/interop/server.py | 4 +- .../grpcio_tests/tests/interop/service.py | 97 +++++++++++++++++++ 7 files changed, 156 insertions(+), 121 deletions(-) create mode 100644 src/python/grpcio_tests/tests/interop/service.py 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 608148dfe46..602786c5e0d 100644 --- a/src/python/grpcio_tests/tests/fork/_fork_interop_test.py +++ b/src/python/grpcio_tests/tests/fork/_fork_interop_test.py @@ -56,12 +56,12 @@ class ForkInteropTest(unittest.TestCase): import grpc from src.proto.grpc.testing import test_pb2_grpc - from tests.interop import methods as interop_methods + from tests.interop import service as interop_service from tests.unit import test_common server = test_common.test_server() test_pb2_grpc.add_TestServiceServicer_to_server( - interop_methods.TestService(), server) + interop_service.TestService(), server) port = server.add_insecure_port('[::]:0') server.start() print(port) diff --git a/src/python/grpcio_tests/tests/interop/BUILD.bazel b/src/python/grpcio_tests/tests/interop/BUILD.bazel index 770b1f78a70..fd636556074 100644 --- a/src/python/grpcio_tests/tests/interop/BUILD.bazel +++ b/src/python/grpcio_tests/tests/interop/BUILD.bazel @@ -5,45 +5,45 @@ package(default_visibility = ["//visibility:public"]) py_library( name = "_intraop_test_case", srcs = ["_intraop_test_case.py"], + imports = ["../../"], deps = [ ":methods", ], - imports=["../../",], ) py_library( name = "client", srcs = ["client.py"], + imports = ["../../"], deps = [ - "//src/python/grpcio/grpc:grpcio", ":methods", ":resources", "//src/proto/grpc/testing:py_test_proto", - requirement('google-auth'), + "//src/python/grpcio/grpc:grpcio", + requirement("google-auth"), ], - imports=["../../",], ) py_library( name = "methods", srcs = ["methods.py"], + imports = ["../../"], 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('urllib3'), - requirement('chardet'), - requirement('certifi'), - requirement('idna'), + requirement("google-auth"), + requirement("requests"), + requirement("urllib3"), + requirement("chardet"), + requirement("certifi"), + requirement("idna"), ] + select({ - "//conditions:default": [requirement('enum34'),], + "//conditions:default": [requirement("enum34")], "//:python3": [], }), - imports=["../../",], ) py_library( @@ -54,51 +54,62 @@ py_library( ], ) +py_library( + name = "service", + srcs = ["service.py"], + imports = ["../../"], + deps = [ + "//src/proto/grpc/testing:py_empty_proto", + "//src/proto/grpc/testing:py_messages_proto", + "//src/proto/grpc/testing:py_test_proto", + "//src/python/grpcio/grpc:grpcio", + ], +) + py_library( name = "server", srcs = ["server.py"], + imports = ["../../"], deps = [ - "//src/python/grpcio/grpc:grpcio", - ":methods", ":resources", - "//src/python/grpcio_tests/tests/unit:test_common", + ":service", "//src/proto/grpc/testing:py_test_proto", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:test_common", ], - imports=["../../",], ) py_test( - name="_insecure_intraop_test", - size="small", - srcs=["_insecure_intraop_test.py",], - main="_insecure_intraop_test.py", - deps=[ - "//src/python/grpcio/grpc:grpcio", - ":_intraop_test_case", - ":methods", - ":server", - "//src/python/grpcio_tests/tests/unit:test_common", - "//src/proto/grpc/testing:py_test_proto", - ], - imports=["../../",], - data=[ + name = "_insecure_intraop_test", + size = "small", + srcs = ["_insecure_intraop_test.py"], + data = [ "//src/python/grpcio_tests/tests/unit/credentials", ], + imports = ["../../"], + main = "_insecure_intraop_test.py", + deps = [ + ":_intraop_test_case", + ":server", + ":service", + "//src/proto/grpc/testing:py_test_proto", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:test_common", + ], ) py_test( - name="_secure_intraop_test", - size="small", - srcs=["_secure_intraop_test.py",], - main="_secure_intraop_test.py", - deps=[ - "//src/python/grpcio/grpc:grpcio", + name = "_secure_intraop_test", + size = "small", + srcs = ["_secure_intraop_test.py"], + imports = ["../../"], + main = "_secure_intraop_test.py", + deps = [ ":_intraop_test_case", - ":methods", ":server", - "//src/python/grpcio_tests/tests/unit:test_common", + ":service", "//src/proto/grpc/testing:py_test_proto", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:test_common", ], - imports=["../../",], ) - diff --git a/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py b/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py index ace15bea585..fecf31767a7 100644 --- a/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py +++ b/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py @@ -19,7 +19,7 @@ import grpc from src.proto.grpc.testing import test_pb2_grpc from tests.interop import _intraop_test_case -from tests.interop import methods +from tests.interop import service from tests.interop import server from tests.unit import test_common @@ -29,7 +29,7 @@ class InsecureIntraopTest(_intraop_test_case.IntraopTestCase, def setUp(self): self.server = test_common.test_server() - test_pb2_grpc.add_TestServiceServicer_to_server(methods.TestService(), + test_pb2_grpc.add_TestServiceServicer_to_server(service.TestService(), self.server) port = self.server.add_insecure_port('[::]:0') self.server.start() diff --git a/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py b/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py index e27e551ecb0..1b5e5cfd2dd 100644 --- a/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py +++ b/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py @@ -19,7 +19,7 @@ import grpc from src.proto.grpc.testing import test_pb2_grpc from tests.interop import _intraop_test_case -from tests.interop import methods +from tests.interop import service from tests.interop import resources from tests.unit import test_common @@ -30,7 +30,7 @@ class SecureIntraopTest(_intraop_test_case.IntraopTestCase, unittest.TestCase): def setUp(self): self.server = test_common.test_server() - test_pb2_grpc.add_TestServiceServicer_to_server(methods.TestService(), + test_pb2_grpc.add_TestServiceServicer_to_server(service.TestService(), self.server) port = self.server.add_secure_port( '[::]:0', diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index 08d8901a6b4..250db8bb385 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -35,82 +35,9 @@ import grpc from src.proto.grpc.testing import empty_pb2 from src.proto.grpc.testing import messages_pb2 -from src.proto.grpc.testing import test_pb2_grpc _INITIAL_METADATA_KEY = "x-grpc-test-echo-initial" _TRAILING_METADATA_KEY = "x-grpc-test-echo-trailing-bin" -_US_IN_A_SECOND = 1000 * 1000 - - -def _maybe_echo_metadata(servicer_context): - """Copies metadata from request to response if it is present.""" - invocation_metadata = dict(servicer_context.invocation_metadata()) - if _INITIAL_METADATA_KEY in invocation_metadata: - initial_metadatum = (_INITIAL_METADATA_KEY, - invocation_metadata[_INITIAL_METADATA_KEY]) - servicer_context.send_initial_metadata((initial_metadatum,)) - if _TRAILING_METADATA_KEY in invocation_metadata: - trailing_metadatum = (_TRAILING_METADATA_KEY, - invocation_metadata[_TRAILING_METADATA_KEY]) - servicer_context.set_trailing_metadata((trailing_metadatum,)) - - -def _maybe_echo_status_and_message(request, servicer_context): - """Sets the response context code and details if the request asks for them""" - if request.HasField('response_status'): - servicer_context.set_code(request.response_status.code) - servicer_context.set_details(request.response_status.message) - - -class TestService(test_pb2_grpc.TestServiceServicer): - - def EmptyCall(self, request, context): - _maybe_echo_metadata(context) - return empty_pb2.Empty() - - def UnaryCall(self, request, context): - _maybe_echo_metadata(context) - _maybe_echo_status_and_message(request, context) - return messages_pb2.SimpleResponse( - payload=messages_pb2.Payload( - type=messages_pb2.COMPRESSABLE, - body=b'\x00' * request.response_size)) - - def StreamingOutputCall(self, request, context): - _maybe_echo_status_and_message(request, context) - for response_parameters in request.response_parameters: - if response_parameters.interval_us != 0: - time.sleep(response_parameters.interval_us / _US_IN_A_SECOND) - yield messages_pb2.StreamingOutputCallResponse( - payload=messages_pb2.Payload( - type=request.response_type, - body=b'\x00' * response_parameters.size)) - - def StreamingInputCall(self, request_iterator, context): - aggregate_size = 0 - for request in request_iterator: - if request.payload is not None and request.payload.body: - aggregate_size += len(request.payload.body) - return messages_pb2.StreamingInputCallResponse( - aggregated_payload_size=aggregate_size) - - def FullDuplexCall(self, request_iterator, context): - _maybe_echo_metadata(context) - for request in request_iterator: - _maybe_echo_status_and_message(request, context) - for response_parameters in request.response_parameters: - if response_parameters.interval_us != 0: - time.sleep( - response_parameters.interval_us / _US_IN_A_SECOND) - yield messages_pb2.StreamingOutputCallResponse( - payload=messages_pb2.Payload( - type=request.payload.type, - body=b'\x00' * response_parameters.size)) - - # NOTE(nathaniel): Apparently this is the same as the full-duplex call? - # NOTE(atash): It isn't even called in the interop spec (Oct 22 2015)... - def HalfDuplexCall(self, request_iterator, context): - return self.FullDuplexCall(request_iterator, context) def _expect_status_code(call, expected_code): diff --git a/src/python/grpcio_tests/tests/interop/server.py b/src/python/grpcio_tests/tests/interop/server.py index 72f88a1c989..3611ffdbb2f 100644 --- a/src/python/grpcio_tests/tests/interop/server.py +++ b/src/python/grpcio_tests/tests/interop/server.py @@ -21,7 +21,7 @@ import time import grpc from src.proto.grpc.testing import test_pb2_grpc -from tests.interop import methods +from tests.interop import service from tests.interop import resources from tests.unit import test_common @@ -42,7 +42,7 @@ def serve(): args = parser.parse_args() server = test_common.test_server() - test_pb2_grpc.add_TestServiceServicer_to_server(methods.TestService(), + test_pb2_grpc.add_TestServiceServicer_to_server(service.TestService(), server) if args.use_tls: private_key = resources.private_key() diff --git a/src/python/grpcio_tests/tests/interop/service.py b/src/python/grpcio_tests/tests/interop/service.py new file mode 100644 index 00000000000..20f76fceebf --- /dev/null +++ b/src/python/grpcio_tests/tests/interop/service.py @@ -0,0 +1,97 @@ +# 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. +"""The Python implementation of the TestServicer.""" + +import time + +import grpc + +from src.proto.grpc.testing import empty_pb2 +from src.proto.grpc.testing import messages_pb2 +from src.proto.grpc.testing import test_pb2_grpc + +_INITIAL_METADATA_KEY = "x-grpc-test-echo-initial" +_TRAILING_METADATA_KEY = "x-grpc-test-echo-trailing-bin" +_US_IN_A_SECOND = 1000 * 1000 + + +def _maybe_echo_metadata(servicer_context): + """Copies metadata from request to response if it is present.""" + invocation_metadata = dict(servicer_context.invocation_metadata()) + if _INITIAL_METADATA_KEY in invocation_metadata: + initial_metadatum = (_INITIAL_METADATA_KEY, + invocation_metadata[_INITIAL_METADATA_KEY]) + servicer_context.send_initial_metadata((initial_metadatum,)) + if _TRAILING_METADATA_KEY in invocation_metadata: + trailing_metadatum = (_TRAILING_METADATA_KEY, + invocation_metadata[_TRAILING_METADATA_KEY]) + servicer_context.set_trailing_metadata((trailing_metadatum,)) + + +def _maybe_echo_status_and_message(request, servicer_context): + """Sets the response context code and details if the request asks for them""" + if request.HasField('response_status'): + servicer_context.set_code(request.response_status.code) + servicer_context.set_details(request.response_status.message) + + +class TestService(test_pb2_grpc.TestServiceServicer): + + def EmptyCall(self, request, context): + _maybe_echo_metadata(context) + return empty_pb2.Empty() + + def UnaryCall(self, request, context): + _maybe_echo_metadata(context) + _maybe_echo_status_and_message(request, context) + return messages_pb2.SimpleResponse( + payload=messages_pb2.Payload( + type=messages_pb2.COMPRESSABLE, + body=b'\x00' * request.response_size)) + + def StreamingOutputCall(self, request, context): + _maybe_echo_status_and_message(request, context) + for response_parameters in request.response_parameters: + if response_parameters.interval_us != 0: + time.sleep(response_parameters.interval_us / _US_IN_A_SECOND) + yield messages_pb2.StreamingOutputCallResponse( + payload=messages_pb2.Payload( + type=request.response_type, + body=b'\x00' * response_parameters.size)) + + def StreamingInputCall(self, request_iterator, context): + aggregate_size = 0 + for request in request_iterator: + if request.payload is not None and request.payload.body: + aggregate_size += len(request.payload.body) + return messages_pb2.StreamingInputCallResponse( + aggregated_payload_size=aggregate_size) + + def FullDuplexCall(self, request_iterator, context): + _maybe_echo_metadata(context) + for request in request_iterator: + _maybe_echo_status_and_message(request, context) + for response_parameters in request.response_parameters: + if response_parameters.interval_us != 0: + time.sleep( + response_parameters.interval_us / _US_IN_A_SECOND) + yield messages_pb2.StreamingOutputCallResponse( + payload=messages_pb2.Payload( + type=request.payload.type, + body=b'\x00' * response_parameters.size)) + + # NOTE(nathaniel): Apparently this is the same as the full-duplex call? + # NOTE(atash): It isn't even called in the interop spec (Oct 22 2015)... + def HalfDuplexCall(self, request_iterator, context): + return self.FullDuplexCall(request_iterator, context) \ No newline at end of file From 875d2df3994f48037d707f0e151e1ff1bad38f6f Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Fri, 26 Apr 2019 10:52:21 -0700 Subject: [PATCH 2008/2143] Modify build file --- test/cpp/microbenchmarks/BUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index e28846fcf94..116180d1688 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -228,8 +228,8 @@ grpc_cc_library( srcs = ["callback_test_service.cc"], hdrs = ["callback_test_service.h"], deps = [ - "//third_party/grpc/src/proto/grpc/testing:echo_proto", - "//third_party/grpc/test/cpp/util:test_util", + "//src/proto/grpc/testing:echo_proto", + "//test/cpp/util:test_util", ], ) From 73dbdccc5d2422867793d59a55c432051eee94b2 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 26 Apr 2019 11:42:48 -0700 Subject: [PATCH 2009/2143] Reviewer comments and cleanup --- .../filters/client_channel/client_channel.cc | 1 + .../client_channel/lb_policy/grpclb/grpclb.cc | 20 ++++++++----------- .../client_channel/resolver_result_parsing.cc | 8 +++----- .../client_channel/resolver_result_parsing.h | 2 +- .../message_size/message_size_filter.cc | 2 +- src/core/lib/iomgr/error.h | 12 +++++++---- 6 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index f0bc3417a2b..26a9e59be08 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1070,6 +1070,7 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) GPR_ASSERT(uri->path[0] != '\0'); server_name_.reset( gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path)); + grpc_uri_destroy(uri); char* proxy_name = nullptr; grpc_channel_args* new_args = nullptr; grpc_proxy_mappers_map_name(server_uri, args->channel_args, &proxy_name, 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 0bcd471f52f..e28a1495c18 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 @@ -1627,20 +1627,16 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { 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( - const_cast( - GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), - is_backend_from_grpclb_load_balancer), - }; - size_t num_args_to_add = 1; + InlinedVector args_to_add; + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), + is_backend_from_grpclb_load_balancer)); if (is_backend_from_grpclb_load_balancer) { - args_to_add[num_args_to_add++] = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1)); } - return grpc_channel_args_copy_and_add(args_, args_to_add, num_args_to_add); + return grpc_channel_args_copy_and_add(args_, args_to_add.data(), + args_to_add.size()); } OrphanablePtr GrpcLb::CreateChildPolicyLocked( 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 82fe3c71a5f..418c4deae9a 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -89,10 +89,7 @@ void ProcessedResolverResult::ProcessServiceConfig( const ClientChannelGlobalParsedObject* parsed_object) { health_check_service_name_ = parsed_object->health_check_service_name(); service_config_json_ = service_config_->service_config_json(); - if (!parsed_object) { - return; - } - if (parsed_object->retry_throttling().has_value()) { + if (parsed_object != nullptr) { retry_throttle_data_ = parsed_object->retry_throttling(); } } @@ -429,7 +426,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling field:maxTokens error:Duplicate " "entry")); - } else if (sub_field->type != GRPC_JSON_NUMBER) { + } // Duplicate, continue parsing. + if (sub_field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling field:maxTokens error:Type should be " "number")); 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 1a49fa7be8e..e44482419ae 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -173,7 +173,7 @@ class ProcessedResolverResult { // Retry throttle data. Optional retry_throttle_data_; - const char* health_check_service_name_ = nullptr; + const char* health_check_service_name_; }; } // namespace internal 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 d21ecb901ac..a973cbca121 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -71,7 +71,7 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( if (max_response_message_bytes >= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:Duplicate entry")); - } // Duplicate, conitnue parsing + } // Duplicate, continue parsing if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:should be of type number")); diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index a877f499fb1..7b04888e9ec 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -166,6 +166,9 @@ grpc_error* grpc_error_create(const char* file, int line, grpc_error_create(__FILE__, __LINE__, grpc_slice_from_copied_string(desc), \ errs, count) +#define GRPC_ERROR_CREATE_FROM_VECTOR(desc, error_list) \ + grpc_error_create_from_vector(__FILE__, __LINE__, desc, error_list) + #ifndef NDEBUG grpc_error* grpc_error_do_ref(grpc_error* err, const char* file, int line); void grpc_error_do_unref(grpc_error* err, const char* file, int line); @@ -197,12 +200,13 @@ inline void grpc_error_unref(grpc_error* err) { // Consumes all the errors in the vector and forms a referencing error from // them. If the vector is empty, return GRPC_ERROR_NONE. template -static grpc_error* GRPC_ERROR_CREATE_FROM_VECTOR( - const char* desc, grpc_core::InlinedVector* error_list) { +static grpc_error* grpc_error_create_from_vector( + const char* file, int line, const char* desc, + grpc_core::InlinedVector* error_list) { grpc_error* error = GRPC_ERROR_NONE; if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); + error = grpc_error_create(file, line, grpc_slice_from_static_string(desc), + error_list->data(), error_list->size()); // Remove refs to all errors in error_list. for (size_t i = 0; i < error_list->size(); i++) { GRPC_ERROR_UNREF((*error_list)[i]); From 019272d3ad792d27fd5256c657fea4512a4d3e7d Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 26 Apr 2019 11:51:02 -0700 Subject: [PATCH 2010/2143] Revert "Objective C should use error codes defined by C core" This reverts commit 2d5468e8263cfdb0595dfd36fba9df6f7c63075a. --- src/objective-c/GRPCClient/GRPCCall.h | 33 +++++++++---------- src/objective-c/ProtoRPC/ProtoRPC.m | 3 +- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 2 +- src/objective-c/tests/InteropTests.m | 21 ++++++------ src/objective-c/tests/UnitTests/UnitTests.m | 6 ++-- 5 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 852fc81fefe..6669067fbff 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -34,7 +34,6 @@ #import #import -#include #include @@ -54,20 +53,20 @@ extern NSString *const kGRPCErrorDomain; */ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { /** The operation was cancelled (typically by the caller). */ - GRPCErrorCodeCancelled = GRPC_STATUS_CANCELLED, + GRPCErrorCodeCancelled = 1, /** * Unknown error. Errors raised by APIs that do not return enough error information may be * converted to this error. */ - GRPCErrorCodeUnknown = GRPC_STATUS_UNKNOWN, + GRPCErrorCodeUnknown = 2, /** * 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 * server (e.g., a malformed file name). */ - GRPCErrorCodeInvalidArgument = GRPC_STATUS_INVALID_ARGUMENT, + GRPCErrorCodeInvalidArgument = 3, /** * Deadline expired before operation could complete. For operations that change the state of the @@ -75,13 +74,13 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { * example, a successful response from the server could have been delayed long enough for the * deadline to expire. */ - GRPCErrorCodeDeadlineExceeded = GRPC_STATUS_DEADLINE_EXCEEDED, + GRPCErrorCodeDeadlineExceeded = 4, /** Some requested entity (e.g., file or directory) was not found. */ - GRPCErrorCodeNotFound = GRPC_STATUS_NOT_FOUND, + GRPCErrorCodeNotFound = 5, /** Some entity that we attempted to create (e.g., file or directory) already exists. */ - GRPCErrorCodeAlreadyExists = GRPC_STATUS_ALREADY_EXISTS, + GRPCErrorCodeAlreadyExists = 6, /** * The caller does not have permission to execute the specified operation. PERMISSION_DENIED isn't @@ -89,16 +88,16 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { * those errors). PERMISSION_DENIED doesn't indicate a failure to identify the caller * (UNAUTHENTICATED is used instead for those errors). */ - GRPCErrorCodePermissionDenied = GRPC_STATUS_PERMISSION_DENIED, + GRPCErrorCodePermissionDenied = 7, /** * The request does not have valid authentication credentials for the operation (e.g. the caller's * identity can't be verified). */ - GRPCErrorCodeUnauthenticated = GRPC_STATUS_UNAUTHENTICATED, + GRPCErrorCodeUnauthenticated = 16, /** Some resource has been exhausted, perhaps a per-user quota. */ - GRPCErrorCodeResourceExhausted = GRPC_STATUS_RESOURCE_EXHAUSTED, + GRPCErrorCodeResourceExhausted = 8, /** * The RPC was rejected because the server is not in a state required for the procedure's @@ -107,14 +106,14 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { * performing another RPC). The details depend on the service being called, and should be found in * the NSError's userInfo. */ - GRPCErrorCodeFailedPrecondition = GRPC_STATUS_FAILED_PRECONDITION, + GRPCErrorCodeFailedPrecondition = 9, /** * The RPC was aborted, typically due to a concurrency issue like sequencer check failures, * transaction aborts, etc. The client should retry at a higher-level (e.g., restarting a read- * modify-write sequence). */ - GRPCErrorCodeAborted = GRPC_STATUS_ABORTED, + GRPCErrorCodeAborted = 10, /** * The RPC was attempted past the valid range. E.g., enumerating past the end of a list. @@ -123,25 +122,25 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { * to return the element at a negative index, but it will generate OUT_OF_RANGE if asked to return * the element at an index past the current size of the list. */ - GRPCErrorCodeOutOfRange = GRPC_STATUS_OUT_OF_RANGE, + GRPCErrorCodeOutOfRange = 11, /** The procedure is not implemented or not supported/enabled in this server. */ - GRPCErrorCodeUnimplemented = GRPC_STATUS_UNIMPLEMENTED, + GRPCErrorCodeUnimplemented = 12, /** * Internal error. Means some invariant expected by the server application or the gRPC library has * been broken. */ - GRPCErrorCodeInternal = GRPC_STATUS_INTERNAL, + GRPCErrorCodeInternal = 13, /** * The server is currently unavailable. This is most likely a transient condition and may be * corrected by retrying with a backoff. */ - GRPCErrorCodeUnavailable = GRPC_STATUS_UNAVAILABLE, + GRPCErrorCodeUnavailable = 14, /** Unrecoverable data loss or corruption. */ - GRPCErrorCodeDataLoss = GRPC_STATUS_DATA_LOSS, + GRPCErrorCodeDataLoss = 15, }; /** diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index bc5d721fe41..0ab96a5ba2b 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -41,7 +41,8 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @"Expected class" : expectedClass, @"Received value" : proto, }; - return [NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeInternal userInfo:info]; + // TODO(jcanizales): Use kGRPCErrorDomain and GRPCErrorCodeInternal when they're public. + return [NSError errorWithDomain:@"io.grpc" code:13 userInfo:info]; } @implementation GRPCUnaryProtoCall { diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index 67951e6c589..ea777e27812 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -151,7 +151,7 @@ static const NSTimeInterval kTestTimeout = 16; closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { trailing_md = trailingMetadata; if (error) { - XCTAssertEqual(error.code, GRPCErrorCodeUnauthenticated, + XCTAssertEqual(error.code, 16, @"Finished with unexpected error: %@", error); XCTAssertEqualObjects(init_md, error.userInfo[kGRPCHeadersKey]); diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 22cc41eb93c..0d2c409f6f3 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -355,9 +355,9 @@ BOOL isRemoteInteropTest(NSString *host) { request.responseSize = 314159; request.payload.body = [NSMutableData dataWithLength:271828]; if (i % 3 == 0) { - request.responseStatus.code = GRPCErrorCodeUnavailable; + request.responseStatus.code = GRPC_STATUS_UNAVAILABLE; } else if (i % 7 == 0) { - request.responseStatus.code = GRPCErrorCodeCancelled; + request.responseStatus.code = GRPC_STATUS_CANCELLED; } GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = [[self class] transportType]; @@ -404,9 +404,9 @@ BOOL isRemoteInteropTest(NSString *host) { request.responseSize = 314159; request.payload.body = [NSMutableData dataWithLength:271828]; if (i % 3 == 0) { - request.responseStatus.code = GRPCErrorCodeUnavailable; + request.responseStatus.code = GRPC_STATUS_UNAVAILABLE; } else if (i % 7 == 0) { - request.responseStatus.code = GRPCErrorCodeCancelled; + request.responseStatus.code = GRPC_STATUS_CANCELLED; } [_service unaryCallWithRequest:request @@ -726,7 +726,7 @@ BOOL isRemoteInteropTest(NSString *host) { RPCToStreamingInputCallWithRequestsWriter:requestsBuffer handler:^(RMTStreamingInputCallResponse *response, NSError *error) { - XCTAssertEqual(error.code, GRPCErrorCodeCancelled); + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); [expectation fulfill]; }]; XCTAssertEqual(call.state, GRXWriterStateNotStarted); @@ -754,8 +754,7 @@ BOOL isRemoteInteropTest(NSString *host) { } closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertEqual(error.code, - GRPCErrorCodeCancelled); + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); [expectation fulfill]; }] callOptions:nil]; @@ -786,7 +785,7 @@ BOOL isRemoteInteropTest(NSString *host) { NSError *error) { if (receivedResponse) { XCTAssert(done, @"Unexpected extra response %@", response); - XCTAssertEqual(error.code, GRPCErrorCodeCancelled); + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); [expectation fulfill]; } else { XCTAssertNil(error, @"Finished with unexpected error: %@", @@ -829,7 +828,7 @@ BOOL isRemoteInteropTest(NSString *host) { } closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertEqual(error.code, GRPCErrorCodeCancelled); + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); [completionExpectation fulfill]; }] callOptions:options]; @@ -859,7 +858,7 @@ BOOL isRemoteInteropTest(NSString *host) { } closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertEqual(error.code, GRPCErrorCodeCancelled); + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); [completionExpectation fulfill]; }] callOptions:options]; @@ -960,7 +959,7 @@ BOOL isRemoteInteropTest(NSString *host) { } else { // Keepalive should kick after 1s elapsed and fails the call. XCTAssertNotNil(error); - XCTAssertEqual(error.code, GRPCErrorCodeUnavailable); + XCTAssertEqual(error.code, GRPC_STATUS_UNAVAILABLE); XCTAssertEqualObjects( error.localizedDescription, @"keepalive watchdog timeout", @"Unexpected failure that is not keepalive watchdog timeout."); diff --git a/src/objective-c/tests/UnitTests/UnitTests.m b/src/objective-c/tests/UnitTests/UnitTests.m index ea3d56db68d..4dcb8c08d28 100644 --- a/src/objective-c/tests/UnitTests/UnitTests.m +++ b/src/objective-c/tests/UnitTests/UnitTests.m @@ -42,18 +42,18 @@ [NSError grpc_errorFromStatusCode:GRPC_STATUS_UNAVAILABLE details:nil errorString:nil]; XCTAssertNil(error1); - XCTAssertEqual(error2.code, GRPCErrorCodeCancelled); + XCTAssertEqual(error2.code, 1); XCTAssertEqualObjects(error2.domain, @"io.grpc"); XCTAssertEqualObjects(error2.userInfo[NSLocalizedDescriptionKey], [NSString stringWithUTF8String:kDetails]); XCTAssertEqualObjects(error2.userInfo[NSDebugDescriptionErrorKey], [NSString stringWithUTF8String:kErrorString]); - XCTAssertEqual(error3.code, GRPCErrorCodeUnauthenticated); + XCTAssertEqual(error3.code, 16); XCTAssertEqualObjects(error3.domain, @"io.grpc"); XCTAssertEqualObjects(error3.userInfo[NSLocalizedDescriptionKey], [NSString stringWithUTF8String:kDetails]); XCTAssertNil(error3.userInfo[NSDebugDescriptionErrorKey]); - XCTAssertEqual(error4.code, GRPCErrorCodeUnavailable); + XCTAssertEqual(error4.code, 14); XCTAssertEqualObjects(error4.domain, @"io.grpc"); XCTAssertNil(error4.userInfo[NSLocalizedDescriptionKey]); XCTAssertNil(error4.userInfo[NSDebugDescriptionErrorKey]); From d3035a3d5f7a1441807b1d114ee4d269133776a3 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 26 Apr 2019 12:38:36 -0700 Subject: [PATCH 2011/2143] Revert changes to optional --- .../client_channel/resolver_result_parsing.cc | 16 ++++++++-------- .../client_channel/resolver_result_parsing.h | 4 ++-- src/core/lib/gprpp/optional.h | 1 - 3 files changed, 10 insertions(+), 11 deletions(-) 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 418c4deae9a..35e54779c69 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -416,8 +416,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, "field:retryThrottling error:Type should be object")); continue; } - Optional max_milli_tokens; - Optional milli_token_ratio; + Optional max_milli_tokens = Optional(); + Optional milli_token_ratio = Optional(); for (grpc_json* sub_field = field->child; sub_field != nullptr; sub_field = sub_field->next) { if (sub_field->key == nullptr) continue; @@ -492,20 +492,20 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, } } } + ClientChannelGlobalParsedObject::RetryThrottling data; if (!max_milli_tokens.has_value()) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling field:maxTokens error:Not found")); + } else { + data.max_milli_tokens = max_milli_tokens.value(); } if (!milli_token_ratio.has_value()) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling field:tokenRatio error:Not found")); - } - if (error_list.size() == 0) { - ClientChannelGlobalParsedObject::RetryThrottling data; - data.max_milli_tokens = max_milli_tokens.value(); + } else { data.milli_token_ratio = milli_token_ratio.value(); - retry_throttling.set(data); } + retry_throttling.set(data); } if (strcmp(field->key, "healthCheckConfig") == 0) { if (health_check_service_name != nullptr) { @@ -535,7 +535,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); InlinedVector error_list; - Optional wait_for_ready; + Optional wait_for_ready = Optional(); grpc_millis timeout = 0; UniquePtr retry_policy; for (grpc_json* field = json->child; field != nullptr; field = field->next) { 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 e44482419ae..7307149496f 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -74,7 +74,7 @@ class ClientChannelGlobalParsedObject : public ServiceConfig::ParsedConfig { RefCountedPtr parsed_lb_config_; UniquePtr parsed_deprecated_lb_policy_; Optional retry_throttling_; - const char* health_check_service_name_ = nullptr; + const char* health_check_service_name_; }; class ClientChannelMethodParsedObject : public ServiceConfig::ParsedConfig { @@ -173,7 +173,7 @@ class ProcessedResolverResult { // Retry throttle data. Optional retry_throttle_data_; - const char* health_check_service_name_; + const char* health_check_service_name_ = nullptr; }; } // namespace internal diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index 2166fe4763a..87d336ad6d0 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -26,7 +26,6 @@ namespace grpc_core { template class Optional { public: - Optional() { value_ = T(); } void set(const T& val) { value_ = val; set_ = true; From 13d6d7c2ece43dbed7664787ca64408e42a10ace Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Fri, 26 Apr 2019 12:58:56 -0700 Subject: [PATCH 2012/2143] Add filegroups in callback_test_service --- CMakeLists.txt | 119 +++++++++++++++++- Makefile | 106 +++++++++++++++- build.yaml | 16 +-- grpc.gyp | 10 +- .../generated/sources_and_headers.json | 13 +- 5 files changed, 237 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41427278646..6eaa01c56d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2907,6 +2907,7 @@ if (gRPC_BUILD_TESTS) add_library(callback_test_service test/cpp/microbenchmarks/callback_test_service.cc + src/cpp/codegen/codegen_init.cc ) if(WIN32 AND MSVC) @@ -2941,15 +2942,121 @@ target_include_directories(callback_test_service target_link_libraries(callback_test_service ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} - ${_gRPC_BENCHMARK_LIBRARIES} - grpc++_test_util - grpc_test_util - grpc++ - grpc - gpr + grpc++_unsecure + grpc_test_util_unsecure + grpc_unsecure ${_gRPC_GFLAGS_LIBRARIES} ) +foreach(_hdr + 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/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/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/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/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/message_allocator.h + include/grpcpp/impl/codegen/metadata_map.h + include/grpcpp/impl/codegen/method_handler_impl.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/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/grpc_types.h + include/grpc/impl/codegen/propagation_bits.h + include/grpc/impl/codegen/slice.h + include/grpc/impl/codegen/status.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/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/grpcpp/impl/codegen/sync.h + include/grpc++/impl/codegen/proto_utils.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/grpc++/impl/codegen/config_protobuf.h + include/grpcpp/impl/codegen/config_protobuf.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() endif (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 6e83616e243..698184ecafd 100644 --- a/Makefile +++ b/Makefile @@ -1411,9 +1411,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)/libbenchmark.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libcallback_test_service.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)/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)/libcallback_test_service.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 @@ -5285,8 +5285,110 @@ endif LIBCALLBACK_TEST_SERVICE_SRC = \ test/cpp/microbenchmarks/callback_test_service.cc \ + src/cpp/codegen/codegen_init.cc \ PUBLIC_HEADERS_CXX += \ + 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/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/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/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/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/message_allocator.h \ + include/grpcpp/impl/codegen/metadata_map.h \ + include/grpcpp/impl/codegen/method_handler_impl.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/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/grpc_types.h \ + include/grpc/impl/codegen/propagation_bits.h \ + include/grpc/impl/codegen/slice.h \ + include/grpc/impl/codegen/status.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/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/grpcpp/impl/codegen/sync.h \ + include/grpc++/impl/codegen/proto_utils.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/grpc++/impl/codegen/config_protobuf.h \ + include/grpcpp/impl/codegen/config_protobuf.h \ LIBCALLBACK_TEST_SERVICE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBCALLBACK_TEST_SERVICE_SRC)))) diff --git a/build.yaml b/build.yaml index 25a476d44fe..562b3216356 100644 --- a/build.yaml +++ b/build.yaml @@ -1666,19 +1666,21 @@ libs: - grpc - gpr - name: callback_test_service - build: test + build: private language: c++ headers: - test/cpp/microbenchmarks/callback_test_service.h src: - test/cpp/microbenchmarks/callback_test_service.cc deps: - - benchmark - - grpc++_test_util - - grpc_test_util - - grpc++ - - grpc - - gpr + - grpc++_unsecure + - grpc_test_util_unsecure + - grpc_unsecure + filegroups: + - grpc++_codegen_base + - grpc++_codegen_base_src + - grpc++_codegen_proto + - grpc++_config_proto - name: grpc++ build: all language: c++ diff --git a/grpc.gyp b/grpc.gyp index fab5b010a4f..30e155f421f 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1402,15 +1402,13 @@ 'target_name': 'callback_test_service', 'type': 'static_library', 'dependencies': [ - 'benchmark', - 'grpc++_test_util', - 'grpc_test_util', - 'grpc++', - 'grpc', - 'gpr', + 'grpc++_unsecure', + 'grpc_test_util_unsecure', + 'grpc_unsecure', ], 'sources': [ 'test/cpp/microbenchmarks/callback_test_service.cc', + 'src/cpp/codegen/codegen_init.cc', ], }, { diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 486ff054794..c87b79e624b 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -6625,12 +6625,13 @@ }, { "deps": [ - "benchmark", - "gpr", - "grpc", - "grpc++", - "grpc++_test_util", - "grpc_test_util" + "grpc++_codegen_base", + "grpc++_codegen_base_src", + "grpc++_codegen_proto", + "grpc++_config_proto", + "grpc++_unsecure", + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [ "test/cpp/microbenchmarks/callback_test_service.h" From 5f6a57a4d00080e611873f5e13517eeb1647fb85 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 26 Apr 2019 12:49:06 -0700 Subject: [PATCH 2013/2143] Formatting issues --- include/grpcpp/create_channel.h | 2 +- include/grpcpp/create_channel_impl.h | 14 +++++++------- include/grpcpp/impl/codegen/client_context.h | 2 +- include/grpcpp/impl/server_builder_plugin.h | 2 +- include/grpcpp/security/credentials.h | 6 +++++- include/grpcpp/security/credentials_impl.h | 5 ++--- include/grpcpp/support/channel_arguments.h | 3 ++- include/grpcpp/support/channel_arguments_impl.h | 1 + src/cpp/client/create_channel_posix.cc | 2 ++ src/cpp/client/cronet_credentials.cc | 3 +-- src/cpp/client/insecure_credentials.cc | 6 +++--- src/cpp/client/secure_credentials.cc | 2 +- src/cpp/client/secure_credentials.h | 6 +++--- 13 files changed, 30 insertions(+), 24 deletions(-) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index e7336cb2adf..9b257ace945 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -32,7 +32,7 @@ static inline std::shared_ptr<::grpc::Channel> CreateChannel( static inline std::shared_ptr<::grpc::Channel> CreateCustomChannel( const grpc::string& target, - const std::shared_ptr& creds, + const std::shared_ptr& creds, const ChannelArguments& args) { return ::grpc_impl::CreateCustomChannelImpl(target, creds, args); } diff --git a/include/grpcpp/create_channel_impl.h b/include/grpcpp/create_channel_impl.h index 84dd2f7c765..ebf8b96973e 100644 --- a/include/grpcpp/create_channel_impl.h +++ b/include/grpcpp/create_channel_impl.h @@ -35,9 +35,9 @@ namespace grpc_impl { /// \param creds Credentials to use for the created channel. If it does not /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. -std::shared_ptr CreateChannelImpl( +std::shared_ptr<::grpc::Channel> CreateChannelImpl( const grpc::string& target, - const std::shared_ptr& creds); + const std::shared_ptr<::grpc::ChannelCredentials>& creds); /// Create a new \em custom \a Channel pointing to \a target. /// @@ -49,10 +49,10 @@ std::shared_ptr CreateChannelImpl( /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannelImpl( +std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl( const grpc::string& target, - const std::shared_ptr& creds, - const grpc::ChannelArguments& args); + const std::shared_ptr<::grpc::ChannelCredentials>& creds, + const ::grpc::ChannelArguments& args); namespace experimental { /// Create a new \em custom \a Channel pointing to \a target with \a @@ -66,10 +66,10 @@ namespace experimental { /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannelWithInterceptors( +std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, - const grpc::ChannelArguments& args, + const ::grpc::ChannelArguments& args, std::vector< std::unique_ptr> interceptor_creators); diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 7326648b46f..355ac557b3a 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -60,7 +60,7 @@ struct grpc_call; namespace grpc_impl { class CallCredentials; -} +} // namespace grpc_impl namespace grpc { class Channel; diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h index 8bac36e5651..84a88f2dd7b 100644 --- a/include/grpcpp/impl/server_builder_plugin.h +++ b/include/grpcpp/impl/server_builder_plugin.h @@ -26,8 +26,8 @@ namespace grpc_impl { class ChannelArguments; -class ServerInitializer; class ServerBuilder; +class ServerInitializer; } // namespace grpc_impl namespace grpc { diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 5eb77096bd0..e924275d592 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -44,10 +44,14 @@ GoogleComputeEngineCredentials() { return ::grpc_impl::GoogleComputeEngineCredentials(); } +/// Constant for maximum auth token lifetime. +constexpr long kMaxAuthTokenLifetimeSecs = + ::grpc_impl::kMaxAuthTokenLifetimeSecs; + static inline std::shared_ptr ServiceAccountJWTAccessCredentials( const grpc::string& json_key, - long token_lifetime_seconds = ::grpc_impl::kMaxAuthTokenLifetimeSecs) { + long token_lifetime_seconds = grpc::kMaxAuthTokenLifetimeSecs) { return ::grpc_impl::ServiceAccountJWTAccessCredentials( json_key, token_lifetime_seconds); } diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index 19017093dd5..536d4b07688 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -41,7 +41,7 @@ class CallCredentials; class SecureCallCredentials; class SecureChannelCredentials; -std::shared_ptr<::grpc::Channel> CreateCustomChannel( +std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); @@ -171,7 +171,6 @@ std::shared_ptr SslCredentials( /// services. std::shared_ptr GoogleComputeEngineCredentials(); -/// Constant for maximum auth token lifetime. constexpr long kMaxAuthTokenLifetimeSecs = 3600; /// Builds Service Account JWT Access credentials. @@ -181,7 +180,7 @@ constexpr long kMaxAuthTokenLifetimeSecs = 3600; /// \a kMaxAuthTokenLifetimeSecs or will be cropped to this value. std::shared_ptr ServiceAccountJWTAccessCredentials( const grpc::string& json_key, - long token_lifetime_seconds = kMaxAuthTokenLifetimeSecs); + long token_lifetime_seconds = grpc_impl::kMaxAuthTokenLifetimeSecs); /// Builds refresh token credentials. /// json_refresh_token is the JSON string containing the refresh token along diff --git a/include/grpcpp/support/channel_arguments.h b/include/grpcpp/support/channel_arguments.h index 24700f56fbd..593aaec76a7 100644 --- a/include/grpcpp/support/channel_arguments.h +++ b/include/grpcpp/support/channel_arguments.h @@ -23,8 +23,9 @@ namespace grpc_impl { +class SecureChannelCredentials; class ResourceQuota; -} +} // namespace grpc_impl namespace grpc { diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h index db85e9b07ad..0efeadca880 100644 --- a/include/grpcpp/support/channel_arguments_impl.h +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -34,6 +34,7 @@ class ChannelArgumentsTest; } // namespace grpc namespace grpc_impl { + class SecureChannelCredentials; /// Options for channel creation. The user can use generic setters to pass diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index 54b7148865b..61260a27c66 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -26,6 +26,8 @@ namespace grpc_impl { +class ChannelArguments; + #ifdef GPR_SUPPORT_CHANNELS_FROM_FD std::shared_ptr CreateInsecureChannelFromFd( diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc index 89ae9e7e9ce..f4ead14cde8 100644 --- a/src/cpp/client/cronet_credentials.cc +++ b/src/cpp/client/cronet_credentials.cc @@ -57,8 +57,7 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials { }; } // namespace grpc namespace grpc_impl { -std::shared_ptr CronetChannelCredentials( - void* engine) { +std::shared_ptr CronetChannelCredentials(void* engine) { return std::shared_ptr( new grpc::CronetChannelCredentialsImpl(engine)); } diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 3a6b1aa6e05..dcbb56dccda 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -31,7 +31,7 @@ namespace grpc_impl { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: - std::shared_ptr CreateChannelImpl( + std::shared_ptr<::grpc::Channel> CreateChannelImpl( const grpc::string& target, const grpc::ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, @@ -39,14 +39,14 @@ class InsecureChannelCredentialsImpl final : public ChannelCredentials { grpc::experimental::ClientInterceptorFactoryInterface>>()); } - std::shared_ptr CreateChannelWithInterceptors( + std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( const grpc::string& target, const grpc::ChannelArguments& args, std::vector> interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return grpc::CreateChannelInternal( + return ::grpc::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 71ad5a73c3b..724a43a9709 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::CreateChannelInternal( + return ::grpc::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 1dc083fa0cf..cc18172558d 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -37,16 +37,16 @@ class SecureChannelCredentials final : public ChannelCredentials { } grpc_channel_credentials* GetRawCreds() { return c_creds_; } - std::shared_ptr CreateChannelImpl( + std::shared_ptr<::grpc::Channel> CreateChannelImpl( const grpc::string& target, const grpc::ChannelArguments& args) override; SecureChannelCredentials* AsSecureCredentials() override { return this; } private: - std::shared_ptr CreateChannelWithInterceptors( + std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( const grpc::string& target, const grpc::ChannelArguments& args, std::vector> + ::grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators) override; grpc_channel_credentials* const c_creds_; }; From 657ab449c65e069b6523ac5624ac052a2c505b1c Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 26 Apr 2019 13:16:54 -0700 Subject: [PATCH 2014/2143] Make single-argument constructor explicit --- test/cpp/end2end/client_callback_end2end_test.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index f0d159ba2a2..9acaf4d076b 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -536,9 +536,9 @@ 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} {} + explicit ClientCancelInfo(int ops) : cancel{true}, ops_before_cancel{ops} {} }; class WriteClient : public grpc::experimental::ClientWriteReactor { @@ -651,7 +651,7 @@ TEST_P(ClientCallbackEnd2endTest, RequestStream) { TEST_P(ClientCallbackEnd2endTest, ClientCancelsRequestStream) { MAYBE_SKIP_TEST; ResetStub(); - WriteClient test{stub_.get(), DO_NOT_CANCEL, 3, {2}}; + WriteClient test{stub_.get(), DO_NOT_CANCEL, 3, ClientCancelInfo{2}}; test.Await(); // Make sure that the server interceptors got the cancel if (GetParam().use_interceptors) { @@ -869,7 +869,7 @@ TEST_P(ClientCallbackEnd2endTest, ResponseStream) { TEST_P(ClientCallbackEnd2endTest, ClientCancelsResponseStream) { MAYBE_SKIP_TEST; ResetStub(); - ReadClient test{stub_.get(), DO_NOT_CANCEL, 2}; + ReadClient test{stub_.get(), DO_NOT_CANCEL, ClientCancelInfo{2}}; test.Await(); // Because cancel in this case races with server finish, we can't be sure that // server interceptors even see cancellation @@ -1052,7 +1052,7 @@ TEST_P(ClientCallbackEnd2endTest, ClientCancelsBidiStream) { MAYBE_SKIP_TEST; ResetStub(); BidiClient test{stub_.get(), DO_NOT_CANCEL, - kServerDefaultResponseStreamsToSend, 2}; + kServerDefaultResponseStreamsToSend, ClientCancelInfo{2}}; test.Await(); // Make sure that the server interceptors were notified of a cancel if (GetParam().use_interceptors) { From 79c3990d50c2d8884fec2aa8c52de2a2db48e4aa Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 26 Apr 2019 13:17:44 -0700 Subject: [PATCH 2015/2143] Move declaration order to how it was earlier in optional, and if check for uri --- src/core/ext/filters/client_channel/client_channel.cc | 7 ++++--- src/core/lib/gprpp/optional.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 85fd450ad49..248e7811bba 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1067,9 +1067,10 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) return; } grpc_uri* uri = grpc_uri_parse(server_uri, true); - GPR_ASSERT(uri->path[0] != '\0'); - server_name_.reset( - gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path)); + if (uri != nullptr && uri->path[0] != '\0') { + server_name_.reset( + gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path)); + } grpc_uri_destroy(uri); char* proxy_name = nullptr; grpc_channel_args* new_args = nullptr; diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index 87d336ad6d0..a8e3ce1505e 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -38,8 +38,8 @@ class Optional { T value() const { return value_; } private: - bool set_ = false; T value_; + bool set_ = false; }; } /* namespace grpc_core */ From 5ff8df71d48b7bb447dff2e98aa32a7f52640f12 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 26 Apr 2019 13:41:30 -0700 Subject: [PATCH 2016/2143] Add default constructor back to optional --- .../ext/filters/client_channel/resolver_result_parsing.cc | 6 +++--- src/core/lib/gprpp/optional.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) 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 35e54779c69..452dea6a0f7 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -416,8 +416,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, "field:retryThrottling error:Type should be object")); continue; } - Optional max_milli_tokens = Optional(); - Optional milli_token_ratio = Optional(); + Optional max_milli_tokens; + Optional milli_token_ratio; for (grpc_json* sub_field = field->child; sub_field != nullptr; sub_field = sub_field->next) { if (sub_field->key == nullptr) continue; @@ -535,7 +535,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); InlinedVector error_list; - Optional wait_for_ready = Optional(); + Optional wait_for_ready; grpc_millis timeout = 0; UniquePtr retry_policy; for (grpc_json* field = json->child; field != nullptr; field = field->next) { diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index a8e3ce1505e..ab5f86393b6 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -26,6 +26,7 @@ namespace grpc_core { template class Optional { public: + Optional() : value_() {} void set(const T& val) { value_ = val; set_ = true; From 8bf138d7998b56471c96299e421875b030f83809 Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Fri, 26 Apr 2019 14:29:57 -0700 Subject: [PATCH 2017/2143] Add copyright --- .../bm_callback_streaming_ping_pong.cc | 18 +++++++ .../bm_callback_unary_ping_pong.cc | 27 +++++++++-- .../callback_streaming_ping_pong.h | 27 +++++++++-- .../microbenchmarks/callback_test_service.cc | 47 +++++++++++++------ .../microbenchmarks/callback_test_service.h | 43 ++++++++++++----- .../callback_unary_ping_pong.h | 19 ++++---- 6 files changed, 137 insertions(+), 44 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc index ad7c2f0ee3e..ed1c3189086 100644 --- a/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc @@ -1,3 +1,21 @@ +/* + * + * 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 "test/cpp/microbenchmarks/callback_streaming_ping_pong.h" #include "test/cpp/util/test_config.h" diff --git a/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc index fee41ea8d1a..c0a7054bf51 100644 --- a/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc @@ -1,3 +1,21 @@ +/* + * + * 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 "test/cpp/microbenchmarks/callback_unary_ping_pong.h" #include "test/cpp/util/test_config.h" @@ -22,11 +40,14 @@ static void SweepSizesArgs(benchmark::internal::Benchmark* b) { } } -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, NoOpMutator) +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + NoOpMutator) ->Apply(SweepSizesArgs); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, MinInProcess, NoOpMutator, NoOpMutator) +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, MinInProcess, NoOpMutator, + NoOpMutator) ->Apply(SweepSizesArgs); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, NoOpMutator) +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, + NoOpMutator) ->Apply(SweepSizesArgs); BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, MinInProcessCHTTP2, NoOpMutator, NoOpMutator) diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h index 13b4c155459..13743412153 100644 --- a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -1,14 +1,31 @@ +/* + * + * 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 TEST_CPP_MICROBENCHMARKS_CALLBACK_STREAMING_PING_PONG_H #define TEST_CPP_MICROBENCHMARKS_CALLBACK_STREAMING_PING_PONG_H - #include #include #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/microbenchmarks/callback_test_service.h" #include "test/cpp/microbenchmarks/fullstack_context_mutators.h" #include "test/cpp/microbenchmarks/fullstack_fixtures.h" -#include "test/cpp/microbenchmarks/callback_test_service.h" namespace grpc { namespace testing { @@ -38,14 +55,14 @@ static void BM_CallbackBidiStreaming(benchmark::State& state) { cli_ctx->AddMetadata(kServerFinishAfterNReads, grpc::to_string(max_ping_pongs)); cli_ctx->AddMetadata(kServerResponseStreamsToSend, - grpc::to_string(message_size)); + grpc::to_string(message_size)); BidiClient test{stub_.get(), request, response, cli_ctx, max_ping_pongs}; test.Await(); } fixture->Finish(state); fixture.reset(); - state.SetBytesProcessed(2 * state.range(0) * state.iterations() - * state.range(1)); + state.SetBytesProcessed(2 * state.range(0) * state.iterations() * + state.range(1)); } } // namespace testing diff --git a/test/cpp/microbenchmarks/callback_test_service.cc b/test/cpp/microbenchmarks/callback_test_service.cc index 057517acf05..caa734d90e8 100644 --- a/test/cpp/microbenchmarks/callback_test_service.cc +++ b/test/cpp/microbenchmarks/callback_test_service.cc @@ -1,3 +1,21 @@ +/* + * + * 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 "test/cpp/microbenchmarks/callback_test_service.h" namespace grpc { @@ -26,7 +44,7 @@ int GetIntValueFromMetadata( int default_value) { return GetIntValueFromMetadataHelper(key, metadata, default_value); } -} // namespace +} // namespace void CallbackStreamingTestService::Echo( ServerContext* context, const EchoRequest* request, EchoResponse* response, @@ -36,24 +54,24 @@ void CallbackStreamingTestService::Echo( experimental::ServerBidiReactor* CallbackStreamingTestService::BidiStream() { - class Reactor : public experimental::ServerBidiReactor { + class Reactor + : public experimental::ServerBidiReactor { public: Reactor() {} void OnStarted(ServerContext* context) override { ctx_ = context; server_write_last_ = GetIntValueFromMetadata( kServerFinishAfterNReads, context->client_metadata(), 0); - message_size_ = GetIntValueFromMetadata( - kServerResponseStreamsToSend, context->client_metadata(), 0); -// EchoRequest* request = new EchoRequest; -// if (message_size_ > 0) { -// request->set_message(std::string(message_size_, 'a')); -// } else { -// request->set_message(""); -// } -// -// request_ = request; + message_size_ = GetIntValueFromMetadata(kServerResponseStreamsToSend, + context->client_metadata(), 0); + // EchoRequest* request = new EchoRequest; + // if (message_size_ > 0) { + // request->set_message(std::string(message_size_, 'a')); + // } else { + // request->set_message(""); + // } + // + // request_ = request; StartRead(&request_); on_started_done_ = true; } @@ -62,7 +80,7 @@ CallbackStreamingTestService::BidiStream() { void OnReadDone(bool ok) override { if (ok) { num_msgs_read_++; -// gpr_log(GPR_INFO, "recv msg %s", request_.message().c_str()); + // gpr_log(GPR_INFO, "recv msg %s", request_.message().c_str()); if (message_size_ > 0) { response_.set_message(std::string(message_size_, 'a')); } else { @@ -108,4 +126,3 @@ CallbackStreamingTestService::BidiStream() { } } // namespace testing } // namespace grpc - diff --git a/test/cpp/microbenchmarks/callback_test_service.h b/test/cpp/microbenchmarks/callback_test_service.h index 3c43ecb2215..aba5c0cfa67 100644 --- a/test/cpp/microbenchmarks/callback_test_service.h +++ b/test/cpp/microbenchmarks/callback_test_service.h @@ -1,12 +1,30 @@ +/* + * + * 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 TEST_CPP_MICROBENCHMARKS_CALLBACK_TEST_SERVICE_H #define TEST_CPP_MICROBENCHMARKS_CALLBACK_TEST_SERVICE_H -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/cpp/util/string_ref_helper.h" -#include +#include #include #include -#include +#include +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/util/string_ref_helper.h" namespace grpc { namespace testing { @@ -22,18 +40,20 @@ class CallbackStreamingTestService EchoResponse* response, experimental::ServerCallbackRpcController* controller) override; - experimental::ServerBidiReactor* BidiStream() override; + experimental::ServerBidiReactor* BidiStream() + override; }; class BidiClient : public grpc::experimental::ClientBidiReactor { public: BidiClient(EchoTestService::Stub* stub, EchoRequest* request, - EchoResponse* response, ClientContext* context, int num_msgs_to_send) + EchoResponse* response, ClientContext* context, + int num_msgs_to_send) : request_{request}, response_{response}, context_{context}, - msgs_to_send_{num_msgs_to_send}{ + msgs_to_send_{num_msgs_to_send} { stub->experimental_async()->BidiStream(context_, this); MaybeWrite(); StartRead(response_); @@ -63,11 +83,11 @@ class BidiClient } void Await() { - std::unique_lock l(mu_); - while (!done_) { - cv_.wait(l); - } + std::unique_lock l(mu_); + while (!done_) { + cv_.wait(l); } + } private: void MaybeWrite() { @@ -89,7 +109,6 @@ class BidiClient bool done_ = false; }; - } // namespace testing } // namespace grpc #endif // TEST_CPP_MICROBENCHMARKS_CALLBACK_TEST_SERVICE_H diff --git a/test/cpp/microbenchmarks/callback_unary_ping_pong.h b/test/cpp/microbenchmarks/callback_unary_ping_pong.h index 7babb56287d..01477e6402d 100644 --- a/test/cpp/microbenchmarks/callback_unary_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_unary_ping_pong.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. @@ -25,9 +25,9 @@ #include #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/microbenchmarks/callback_test_service.h" #include "test/cpp/microbenchmarks/fullstack_context_mutators.h" #include "test/cpp/microbenchmarks/fullstack_fixtures.h" -#include "test/cpp/microbenchmarks/callback_test_service.h" namespace grpc { namespace testing { @@ -63,12 +63,12 @@ static void BM_CallbackUnaryPingPong(benchmark::State& state) { std::condition_variable cv; bool done = false; stub_->experimental_async()->Echo(&cli_ctx, &request, &response, - [&done, &mu, &cv](Status s) { - GPR_ASSERT(s.ok()); - std::lock_guard l(mu); - done = true; - cv.notify_one(); - }); + [&done, &mu, &cv](Status s) { + GPR_ASSERT(s.ok()); + std::lock_guard l(mu); + done = true; + cv.notify_one(); + }); std::unique_lock l(mu); while (!done) { cv.wait(l); @@ -76,7 +76,8 @@ static void BM_CallbackUnaryPingPong(benchmark::State& state) { } fixture->Finish(state); fixture.reset(); - state.SetBytesProcessed(state.range(0) * state.iterations() + state.range(1) * state.iterations()); + state.SetBytesProcessed(state.range(0) * state.iterations() + + state.range(1) * state.iterations()); } } // namespace testing } // namespace grpc From 9f3c78177f4e19d28027d06867493e09098ddaab Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 26 Apr 2019 15:40:53 -0700 Subject: [PATCH 2018/2143] Resolve final comments --- .../resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc | 6 +++--- .../resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc index c29fa44a353..e272e5a8800 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -77,7 +77,7 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { return false; } - void ShutdownInternal(grpc_error* error) { + void ShutdownInternalLocked(grpc_error* error) { uv_poll_stop(handle_); uv_close(reinterpret_cast(handle_), ares_uv_poll_close_cb); if (read_closure_ != nullptr) { @@ -91,9 +91,9 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { void ShutdownLocked(grpc_error* error) override { if (grpc_core::ExecCtx::Get() == nullptr) { grpc_core::ExecCtx exec_ctx; - ShutdownInternal(error); + ShutdownInternalLocked(error); } else { - ShutdownInternal(error); + ShutdownInternalLocked(error); } } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc index 706bc659582..07906f282aa 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc @@ -37,7 +37,7 @@ bool inner_maybe_resolve_localhost_manually_locked( gpr_split_host_port(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, - "Failed to parse %s into host:port during Windows localhost " + "Failed to parse %s into host:port during manual localhost " "resolution check.", name); return false; @@ -45,7 +45,7 @@ bool inner_maybe_resolve_localhost_manually_locked( if (*port == nullptr) { if (default_port == nullptr) { gpr_log(GPR_ERROR, - "No port or default port for %s during Windows localhost " + "No port or default port for %s during manual localhost " "resolution check.", name); return false; From b779a954b1f3b15ce4ec034e02f343c848012d31 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Fri, 19 Apr 2019 17:59:42 -0700 Subject: [PATCH 2019/2143] Inlined md_ref/unref and saved some unnecessary ops --- src/core/lib/transport/metadata.cc | 447 ++++++++++++----------------- src/core/lib/transport/metadata.h | 203 ++++++++++++- 2 files changed, 381 insertions(+), 269 deletions(-) diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index b7e7fd40c00..03bd2056fbc 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -41,6 +41,10 @@ #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/transport/static_metadata.h" +using grpc_core::AllocatedMetadata; +using grpc_core::InternedMetadata; +using grpc_core::UserData; + /* There are two kinds of mdelem and mdstr instances. * Static instances are declared in static_metadata.{h,c} and * are initialized by grpc_mdctx_global_init(). @@ -54,13 +58,40 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_metadata(false, "metadata"); #ifndef NDEBUG #define DEBUG_ARGS , const char *file, int line -#define FWD_DEBUG_ARGS , file, line -#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s), __FILE__, __LINE__) -#else +#define FWD_DEBUG_ARGS file, line + +void grpc_mdelem_trace_ref(void* md, const grpc_slice& key, + const grpc_slice& value, intptr_t refcnt, + const char* file, int line) { + if (grpc_trace_metadata.enabled()) { + char* key_str = grpc_slice_to_c_string(key); + char* value_str = grpc_slice_to_c_string(value); + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", md, refcnt, + refcnt + 1, key_str, value_str); + gpr_free(key_str); + gpr_free(value_str); + } +} + +void grpc_mdelem_trace_unref(void* md, const grpc_slice& key, + const grpc_slice& value, intptr_t refcnt, + const char* file, int line) { + if (grpc_trace_metadata.enabled()) { + char* key_str = grpc_slice_to_c_string(key); + char* value_str = grpc_slice_to_c_string(value); + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "ELM UNREF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", md, + refcnt, refcnt - 1, key_str, value_str); + gpr_free(key_str); + gpr_free(value_str); + } +} + +#else // ifndef NDEBUG #define DEBUG_ARGS #define FWD_DEBUG_ARGS -#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s)) -#endif +#endif // ifndef NDEBUG #define INITIAL_SHARD_CAPACITY 8 #define LOG2_SHARD_COUNT 4 @@ -69,43 +100,87 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_metadata(false, "metadata"); #define TABLE_IDX(hash, capacity) (((hash) >> (LOG2_SHARD_COUNT)) % (capacity)) #define SHARD_IDX(hash) ((hash) & ((1 << (LOG2_SHARD_COUNT)) - 1)) -typedef void (*destroy_user_data_func)(void* user_data); +AllocatedMetadata::AllocatedMetadata(const grpc_slice& key, + const grpc_slice& value) + : key_(grpc_slice_ref_internal(key)), + value_(grpc_slice_ref_internal(value)), + refcnt_(1) { +#ifndef NDEBUG + if (grpc_trace_metadata.enabled()) { + char* key_str = grpc_slice_to_c_string(key_); + char* value_str = grpc_slice_to_c_string(value_); + gpr_log(GPR_DEBUG, "ELM ALLOC:%p:%" PRIdPTR ": '%s' = '%s'", this, + RefValue(), key_str, value_str); + gpr_free(key_str); + gpr_free(value_str); + } +#endif +} -struct UserData { - gpr_mu mu_user_data; - gpr_atm destroy_user_data; - gpr_atm user_data; -}; +AllocatedMetadata::~AllocatedMetadata() { + grpc_slice_unref_internal(key_); + grpc_slice_unref_internal(value_); + if (user_data_.user_data) { + destroy_user_data_func destroy_user_data = + (destroy_user_data_func)gpr_atm_no_barrier_load( + &user_data_.destroy_user_data); + destroy_user_data((void*)user_data_.user_data); + } +} -/* Shadow structure for grpc_mdelem_data for interned elements */ -typedef struct interned_metadata { - /* must be byte compatible with grpc_mdelem_data */ - grpc_slice key; - grpc_slice value; +InternedMetadata::InternedMetadata(const grpc_slice& key, + const grpc_slice& value, uint32_t hash, + InternedMetadata* next) + : key_(grpc_slice_ref_internal(key)), + value_(grpc_slice_ref_internal(value)), + refcnt_(1), + hash_(hash), + link_(next) { +#ifndef NDEBUG + if (grpc_trace_metadata.enabled()) { + char* key_str = grpc_slice_to_c_string(key_); + char* value_str = grpc_slice_to_c_string(value_); + gpr_log(GPR_DEBUG, "ELM NEW:%p:%" PRIdPTR ": '%s' = '%s'", this, + RefValue(), key_str, value_str); + gpr_free(key_str); + gpr_free(value_str); + } +#endif +} - /* private only data */ - gpr_atm refcnt; +InternedMetadata::~InternedMetadata() { + grpc_slice_unref_internal(key_); + grpc_slice_unref_internal(value_); + if (user_data_.user_data) { + destroy_user_data_func destroy_user_data = + (destroy_user_data_func)gpr_atm_no_barrier_load( + &user_data_.destroy_user_data); + destroy_user_data((void*)user_data_.user_data); + } +} - UserData user_data; +intptr_t InternedMetadata::CleanupLinkedMetadata( + InternedMetadata::BucketLink* head) { + intptr_t num_freed = 0; + InternedMetadata::BucketLink* prev_next = head; + InternedMetadata *md, *next; - struct interned_metadata* bucket_next; -} interned_metadata; - -/* Shadow structure for grpc_mdelem_data for allocated elements */ -typedef struct allocated_metadata { - /* must be byte compatible with grpc_mdelem_data */ - grpc_slice key; - grpc_slice value; - - /* private only data */ - gpr_atm refcnt; - - UserData user_data; -} allocated_metadata; + for (md = head->next; md; md = next) { + next = md->link_.next; + if (md->AllRefsDropped()) { + prev_next->next = next; + grpc_core::Delete(md); + num_freed++; + } else { + prev_next = &md->link_; + } + } + return num_freed; +} typedef struct mdtab_shard { gpr_mu mu; - interned_metadata** elems; + InternedMetadata::BucketLink* elems; size_t count; size_t capacity; /** Estimate of the number of unreferenced mdelems in the hash table. @@ -126,7 +201,7 @@ void grpc_mdctx_global_init(void) { shard->count = 0; gpr_atm_no_barrier_store(&shard->free_estimate, 0); shard->capacity = INITIAL_SHARD_CAPACITY; - shard->elems = static_cast( + shard->elems = static_cast( gpr_zalloc(sizeof(*shard->elems) * shard->capacity)); } } @@ -154,55 +229,29 @@ static int is_mdelem_static(grpc_mdelem e) { &grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; } -static void ref_md_locked(mdtab_shard* shard, - interned_metadata* md DEBUG_ARGS) { +void InternedMetadata::RefWithShardLocked(mdtab_shard* shard) { #ifndef NDEBUG if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", (void*)md, - gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str); + char* key_str = grpc_slice_to_c_string(key_); + char* value_str = grpc_slice_to_c_string(value_); + intptr_t value = RefValue(); + gpr_log(__FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG, + "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", this, value, + value + 1, key_str, value_str); gpr_free(key_str); gpr_free(value_str); } #endif - if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 1)) { + if (FirstRef()) { gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -1); } } static void gc_mdtab(mdtab_shard* shard) { GPR_TIMER_SCOPE("gc_mdtab", 0); - - size_t i; - interned_metadata** prev_next; - interned_metadata *md, *next; - gpr_atm num_freed = 0; - - 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.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.user_data) { - ((destroy_user_data_func)gpr_atm_no_barrier_load( - &md->user_data.destroy_user_data))(user_data); - } - gpr_mu_destroy(&md->user_data.mu_user_data); - gpr_free(md); - *prev_next = next; - num_freed++; - shard->count--; - } else { - prev_next = &md->bucket_next; - } - } + intptr_t num_freed = 0; + for (size_t i = 0; i < shard->capacity; ++i) { + num_freed += InternedMetadata::CleanupLinkedMetadata(&shard->elems[i]); } gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -num_freed); } @@ -212,22 +261,21 @@ static void grow_mdtab(mdtab_shard* shard) { size_t capacity = shard->capacity * 2; size_t i; - interned_metadata** mdtab; - interned_metadata *md, *next; + InternedMetadata::BucketLink* mdtab; + InternedMetadata *md, *next; uint32_t hash; - mdtab = static_cast( - gpr_zalloc(sizeof(interned_metadata*) * capacity)); + mdtab = static_cast( + gpr_zalloc(sizeof(InternedMetadata::BucketLink) * capacity)); for (i = 0; i < shard->capacity; i++) { - for (md = shard->elems[i]; md; md = next) { + for (md = shard->elems[i].next; md; md = next) { size_t idx; - hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key), - grpc_slice_hash(md->value)); - next = md->bucket_next; + hash = md->hash(); + next = md->bucket_next(); idx = TABLE_IDX(hash, capacity); - md->bucket_next = mdtab[idx]; - mdtab[idx] = md; + md->set_bucket_next(mdtab[idx].next); + mdtab[idx].next = md; } } gpr_free(shard->elems); @@ -247,34 +295,22 @@ static void rehash_mdtab(mdtab_shard* shard) { grpc_mdelem grpc_mdelem_create( const grpc_slice& key, const grpc_slice& value, grpc_mdelem_data* compatible_external_backing_store) { + // External storage if either slice is not interned and the caller already + // created a backing store. If no backing store, we allocate one. if (!grpc_slice_is_interned(key) || !grpc_slice_is_interned(value)) { if (compatible_external_backing_store != nullptr) { + // Caller provided backing store. return GRPC_MAKE_MDELEM(compatible_external_backing_store, GRPC_MDELEM_STORAGE_EXTERNAL); + } else { + // We allocate backing store. + return GRPC_MAKE_MDELEM(grpc_core::New(key, value), + GRPC_MDELEM_STORAGE_ALLOCATED); } - - allocated_metadata* allocated = - static_cast(gpr_malloc(sizeof(*allocated))); - 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); - char* value_str = grpc_slice_to_c_string(allocated->value); - gpr_log(GPR_DEBUG, "ELM ALLOC:%p:%" PRIdPTR ": '%s' = '%s'", - (void*)allocated, gpr_atm_no_barrier_load(&allocated->refcnt), - key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - return GRPC_MAKE_MDELEM(allocated, GRPC_MDELEM_STORAGE_ALLOCATED); } + // Not all static slice input yields a statically stored metadata element. + // It may be worth documenting why. if (GRPC_IS_STATIC_METADATA_STRING(key) && GRPC_IS_STATIC_METADATA_STRING(value)) { grpc_mdelem static_elem = grpc_static_mdelem_for_static_strings( @@ -286,7 +322,7 @@ grpc_mdelem grpc_mdelem_create( uint32_t hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(key), grpc_slice_hash(value)); - interned_metadata* md; + InternedMetadata* md; mdtab_shard* shard = &g_shards[SHARD_IDX(hash)]; size_t idx; @@ -296,34 +332,18 @@ grpc_mdelem grpc_mdelem_create( idx = TABLE_IDX(hash, shard->capacity); /* search for an existing pair */ - for (md = shard->elems[idx]; md; md = md->bucket_next) { - if (grpc_slice_eq(key, md->key) && grpc_slice_eq(value, md->value)) { - REF_MD_LOCKED(shard, md); + for (md = shard->elems[idx].next; md; md = md->bucket_next()) { + if (grpc_slice_eq(key, md->key()) && grpc_slice_eq(value, md->value())) { + md->RefWithShardLocked(shard); gpr_mu_unlock(&shard->mu); return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED); } } /* not found: create a new pair */ - md = static_cast(gpr_malloc(sizeof(interned_metadata))); - gpr_atm_rel_store(&md->refcnt, 1); - md->key = grpc_slice_ref_internal(key); - md->value = grpc_slice_ref_internal(value); - 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->user_data.mu_user_data); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(GPR_DEBUG, "ELM NEW:%p:%" PRIdPTR ": '%s' = '%s'", (void*)md, - gpr_atm_no_barrier_load(&md->refcnt), key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif + md = grpc_core::New(key, value, hash, + shard->elems[idx].next); + shard->elems[idx].next = md; shard->count++; if (shard->count > shard->capacity * 2) { @@ -354,126 +374,6 @@ grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata) { changed ? nullptr : reinterpret_cast(metadata)); } -grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd DEBUG_ARGS) { - switch (GRPC_MDELEM_STORAGE(gmd)) { - case GRPC_MDELEM_STORAGE_EXTERNAL: - case GRPC_MDELEM_STORAGE_STATIC: - break; - case GRPC_MDELEM_STORAGE_INTERNED: { - interned_metadata* md = - reinterpret_cast GRPC_MDELEM_DATA(gmd); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", - (void*)md, gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - /* we can assume the ref count is >= 1 as the application is calling - this function - meaning that no adjustment to mdtab_free is necessary, - simplifying the logic here to be just an atomic increment */ - /* use C assert to have this removed in opt builds */ - GPR_ASSERT(gpr_atm_no_barrier_load(&md->refcnt) >= 1); - gpr_atm_no_barrier_fetch_add(&md->refcnt, 1); - break; - } - case GRPC_MDELEM_STORAGE_ALLOCATED: { - allocated_metadata* md = - reinterpret_cast GRPC_MDELEM_DATA(gmd); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", - (void*)md, gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - /* we can assume the ref count is >= 1 as the application is calling - this function - meaning that no adjustment to mdtab_free is necessary, - simplifying the logic here to be just an atomic increment */ - /* use C assert to have this removed in opt builds */ - gpr_atm_no_barrier_fetch_add(&md->refcnt, 1); - break; - } - } - return gmd; -} - -void grpc_mdelem_unref(grpc_mdelem gmd DEBUG_ARGS) { - switch (GRPC_MDELEM_STORAGE(gmd)) { - case GRPC_MDELEM_STORAGE_EXTERNAL: - case GRPC_MDELEM_STORAGE_STATIC: - break; - case GRPC_MDELEM_STORAGE_INTERNED: { - interned_metadata* md = - reinterpret_cast GRPC_MDELEM_DATA(gmd); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM UNREF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", - (void*)md, gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) - 1, key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - uint32_t hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key), - grpc_slice_hash(md->value)); - const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1); - GPR_ASSERT(prev_refcount >= 1); - if (1 == prev_refcount) { - /* once the refcount hits zero, some other thread can come along and - free md at any time: it's unsafe from this point on to access it */ - mdtab_shard* shard = &g_shards[SHARD_IDX(hash)]; - gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1); - } - break; - } - case GRPC_MDELEM_STORAGE_ALLOCATED: { - allocated_metadata* md = - reinterpret_cast GRPC_MDELEM_DATA(gmd); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM UNREF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", - (void*)md, gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) - 1, key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1); - GPR_ASSERT(prev_refcount >= 1); - 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; - } - } -} - 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) { @@ -491,14 +391,12 @@ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void*)) { 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); + auto* 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); - return get_user_data(&im->user_data, destroy_func); + auto* im = reinterpret_cast GRPC_MDELEM_DATA(md); + return get_user_data(im->user_data(), destroy_func); } } GPR_UNREACHABLE_CODE(return nullptr); @@ -507,10 +405,10 @@ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void*)) { 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); + grpc_core::ReleasableMutexLock 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); + lock.Unlock(); if (destroy_func != nullptr) { destroy_func(user_data); } @@ -518,7 +416,6 @@ static void* set_user_data(UserData* ud, void (*destroy_func)(void*), } 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; } @@ -533,15 +430,13 @@ void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*), 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); + auto* 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); + auto* im = reinterpret_cast GRPC_MDELEM_DATA(md); GPR_ASSERT(!is_mdelem_static(md)); - return set_user_data(&im->user_data, destroy_func, user_data); + return set_user_data(im->user_data(), destroy_func, user_data); } } GPR_UNREACHABLE_CODE(return nullptr); @@ -554,3 +449,33 @@ bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b) { return grpc_slice_eq(GRPC_MDKEY(a), GRPC_MDKEY(b)) && grpc_slice_eq(GRPC_MDVALUE(a), GRPC_MDVALUE(b)); } + +static void note_disposed_interned_metadata(uint32_t hash) { + mdtab_shard* shard = &g_shards[SHARD_IDX(hash)]; + gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1); +} + +void grpc_mdelem_do_unref(grpc_mdelem gmd DEBUG_ARGS) { + switch (GRPC_MDELEM_STORAGE(gmd)) { + case GRPC_MDELEM_STORAGE_EXTERNAL: + case GRPC_MDELEM_STORAGE_STATIC: + return; + case GRPC_MDELEM_STORAGE_INTERNED: { + auto* md = reinterpret_cast GRPC_MDELEM_DATA(gmd); + uint32_t hash = md->hash(); + if (md->Unref(FWD_DEBUG_ARGS)) { + /* once the refcount hits zero, some other thread can come along and + free md at any time: it's unsafe from this point on to access it */ + note_disposed_interned_metadata(hash); + } + break; + } + case GRPC_MDELEM_STORAGE_ALLOCATED: { + auto* md = reinterpret_cast GRPC_MDELEM_DATA(gmd); + if (md->Unref(FWD_DEBUG_ARGS)) { + grpc_core::Delete(md); + } + break; + } + } +} diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 5e016567eb2..d431474d017 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -21,11 +21,15 @@ #include +#include "include/grpc/impl/codegen/log.h" + #include #include #include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/atomic.h" +#include "src/core/lib/gprpp/sync.h" extern grpc_core::DebugOnlyTraceFlag grpc_trace_metadata; @@ -63,7 +67,7 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_metadata; typedef struct grpc_mdelem grpc_mdelem; /* if changing this, make identical changes in: - - interned_metadata, allocated_metadata in metadata.c + - grpc_core::{InternedMetadata, AllocatedMetadata} - grpc_metadata in grpc_types.h */ typedef struct grpc_mdelem_data { const grpc_slice key; @@ -143,17 +147,200 @@ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*if_destroy_func)(void*)); void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*), void* user_data); +// Defined in metadata.cc. +struct mdtab_shard; + +#ifndef NDEBUG +void grpc_mdelem_trace_ref(void* md, const grpc_slice& key, + const grpc_slice& value, intptr_t refcnt, + const char* file, int line); +void grpc_mdelem_trace_unref(void* md, const grpc_slice& key, + const grpc_slice& value, intptr_t refcnt, + const char* file, int line); +#endif +namespace grpc_core { + +typedef void (*destroy_user_data_func)(void* user_data); + +struct UserData { + Mutex mu_user_data; + gpr_atm destroy_user_data = 0; + gpr_atm user_data = 0; +}; + +class InternedMetadata { + public: + struct BucketLink { + explicit BucketLink(InternedMetadata* md) : next(md) {} + + InternedMetadata* next = nullptr; + }; + + InternedMetadata(const grpc_slice& key, const grpc_slice& value, + uint32_t hash, InternedMetadata* next); + ~InternedMetadata(); + +#ifndef NDEBUG + void Ref(const char* file, int line) { + grpc_mdelem_trace_ref(this, key_, value_, RefValue(), file, line); + const intptr_t prior = refcnt_.FetchAdd(1, MemoryOrder::RELAXED); + GPR_ASSERT(prior > 0); + } + bool Unref(const char* file, int line) { + grpc_mdelem_trace_unref(this, key_, value_, RefValue(), file, line); + return Unref(); + } +#else + // We define a naked Ref() in the else-clause to make sure we don't + // inadvertently skip the assert on debug builds. + void Ref() { + /* we can assume the ref count is >= 1 as the application is calling + this function - meaning that no adjustment to mdtab_free is necessary, + simplifying the logic here to be just an atomic increment */ + refcnt_.FetchAdd(1, MemoryOrder::RELAXED); + } +#endif // ifndef NDEBUG + bool Unref() { + const intptr_t prior = refcnt_.FetchSub(1, MemoryOrder::ACQ_REL); + GPR_DEBUG_ASSERT(prior > 0); + return prior == 1; + } + + void RefWithShardLocked(mdtab_shard* shard); + const grpc_slice& key() const { return key_; } + const grpc_slice& value() const { return value_; } + UserData* user_data() { return &user_data_; } + uint32_t hash() { return hash_; } + InternedMetadata* bucket_next() { return link_.next; } + void set_bucket_next(InternedMetadata* md) { link_.next = md; } + + static intptr_t CleanupLinkedMetadata(BucketLink* head); + + private: + bool AllRefsDropped() { return refcnt_.Load(MemoryOrder::ACQUIRE) == 0; } + bool FirstRef() { return refcnt_.FetchAdd(1, MemoryOrder::RELAXED) == 0; } + intptr_t RefValue() { return refcnt_.Load(MemoryOrder::RELAXED); } + + /* must be byte compatible with grpc_mdelem_data */ + grpc_slice key_; + grpc_slice value_; + + /* private only data */ + grpc_core::Atomic refcnt_; + uint32_t hash_; + + UserData user_data_; + + BucketLink link_; +}; + +/* Shadow structure for grpc_mdelem_data for allocated elements */ +class AllocatedMetadata { + public: + AllocatedMetadata(const grpc_slice& key, const grpc_slice& value); + ~AllocatedMetadata(); + + const grpc_slice& key() const { return key_; } + const grpc_slice& value() const { return value_; } + UserData* user_data() { return &user_data_; } + +#ifndef NDEBUG + void Ref(const char* file, int line) { + grpc_mdelem_trace_ref(this, key_, value_, RefValue(), file, line); + Ref(); + } + bool Unref(const char* file, int line) { + grpc_mdelem_trace_unref(this, key_, value_, RefValue(), file, line); + return Unref(); + } +#endif // ifndef NDEBUG + void Ref() { + /* we can assume the ref count is >= 1 as the application is calling + this function - meaning that no adjustment to mdtab_free is necessary, + simplifying the logic here to be just an atomic increment */ + refcnt_.FetchAdd(1, MemoryOrder::RELAXED); + } + bool Unref() { + const intptr_t prior = refcnt_.FetchSub(1, MemoryOrder::ACQ_REL); + GPR_DEBUG_ASSERT(prior > 0); + return prior == 1; + } + + private: + intptr_t RefValue() { return refcnt_.Load(MemoryOrder::RELAXED); } + + /* must be byte compatible with grpc_mdelem_data */ + grpc_slice key_; + grpc_slice value_; + + /* private only data */ + grpc_core::Atomic refcnt_; + + UserData user_data_; +}; + +} // namespace grpc_core + #ifndef NDEBUG #define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s), __FILE__, __LINE__) -#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s), __FILE__, __LINE__) -grpc_mdelem grpc_mdelem_ref(grpc_mdelem md, const char* file, int line); -void grpc_mdelem_unref(grpc_mdelem md, const char* file, int line); -#else +inline grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd, const char* file, + int line) { +#else // ifndef NDEBUG #define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s)) -#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s)) -grpc_mdelem grpc_mdelem_ref(grpc_mdelem md); -void grpc_mdelem_unref(grpc_mdelem md); +inline grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd) { +#endif // ifndef NDEBUG + switch (GRPC_MDELEM_STORAGE(gmd)) { + case GRPC_MDELEM_STORAGE_EXTERNAL: + case GRPC_MDELEM_STORAGE_STATIC: + break; + case GRPC_MDELEM_STORAGE_INTERNED: { + auto* md = + reinterpret_cast GRPC_MDELEM_DATA(gmd); + /* use C assert to have this removed in opt builds */ +#ifndef NDEBUG + md->Ref(file, line); +#else + md->Ref(); #endif + break; + } + case GRPC_MDELEM_STORAGE_ALLOCATED: { + auto* md = + reinterpret_cast GRPC_MDELEM_DATA(gmd); +#ifndef NDEBUG + md->Ref(file, line); +#else + md->Ref(); +#endif + break; + } + } + return gmd; +} + +#ifndef NDEBUG +#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s), __FILE__, __LINE__) +void grpc_mdelem_do_unref(grpc_mdelem gmd, const char* file, int line); +inline void grpc_mdelem_unref(grpc_mdelem gmd, const char* file, int line) { +#else +#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s)) +void grpc_mdelem_do_unref(grpc_mdelem gmd); +inline void grpc_mdelem_unref(grpc_mdelem gmd) { +#endif + switch (GRPC_MDELEM_STORAGE(gmd)) { + case GRPC_MDELEM_STORAGE_EXTERNAL: + case GRPC_MDELEM_STORAGE_STATIC: + return; + case GRPC_MDELEM_STORAGE_INTERNED: + case GRPC_MDELEM_STORAGE_ALLOCATED: +#ifndef NDEBUG + grpc_mdelem_do_unref(gmd, file, line); +#else + grpc_mdelem_do_unref(gmd); +#endif + return; + } +} #define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL) #define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL) From f371d95c479d4e184abd435ff9d7fbbba6de011a Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 26 Apr 2019 17:03:16 -0700 Subject: [PATCH 2020/2143] Handle protos at root package level --- bazel/generate_cc.bzl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index 83a0927da89..82f5cbad310 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -19,6 +19,8 @@ _PROTO_HEADER_FMT = "{}.pb.h" _PROTO_SRC_FMT = "{}.pb.cc" def _strip_package_from_path(label_package, path): + if len(label_package) == 0: + return path if not path.startswith(label_package + "/"): fail("'{}' does not lie within '{}'.".format(path, label_package)) return path[len(label_package + "/"):] From 664d4d984b819eeb90807d80378d92c41ce8a9ac Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Fri, 26 Apr 2019 16:07:15 -0700 Subject: [PATCH 2021/2143] Removed gpr_atm from UserData --- src/core/lib/transport/metadata.cc | 57 +++++++++++++++--------------- src/core/lib/transport/metadata.h | 10 +++--- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index 03bd2056fbc..e3b8d112795 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -120,11 +120,11 @@ AllocatedMetadata::AllocatedMetadata(const grpc_slice& key, AllocatedMetadata::~AllocatedMetadata() { grpc_slice_unref_internal(key_); grpc_slice_unref_internal(value_); - if (user_data_.user_data) { + void* user_data = user_data_.data.Load(grpc_core::MemoryOrder::RELAXED); + if (user_data) { destroy_user_data_func destroy_user_data = - (destroy_user_data_func)gpr_atm_no_barrier_load( - &user_data_.destroy_user_data); - destroy_user_data((void*)user_data_.user_data); + user_data_.destroy_user_data.Load(grpc_core::MemoryOrder::RELAXED); + destroy_user_data(user_data); } } @@ -151,17 +151,17 @@ InternedMetadata::InternedMetadata(const grpc_slice& key, InternedMetadata::~InternedMetadata() { grpc_slice_unref_internal(key_); grpc_slice_unref_internal(value_); - if (user_data_.user_data) { + void* user_data = user_data_.data.Load(grpc_core::MemoryOrder::RELAXED); + if (user_data) { destroy_user_data_func destroy_user_data = - (destroy_user_data_func)gpr_atm_no_barrier_load( - &user_data_.destroy_user_data); - destroy_user_data((void*)user_data_.user_data); + user_data_.destroy_user_data.Load(grpc_core::MemoryOrder::RELAXED); + destroy_user_data(user_data); } } -intptr_t InternedMetadata::CleanupLinkedMetadata( +size_t InternedMetadata::CleanupLinkedMetadata( InternedMetadata::BucketLink* head) { - intptr_t num_freed = 0; + size_t num_freed = 0; InternedMetadata::BucketLink* prev_next = head; InternedMetadata *md, *next; @@ -249,11 +249,12 @@ void InternedMetadata::RefWithShardLocked(mdtab_shard* shard) { static void gc_mdtab(mdtab_shard* shard) { GPR_TIMER_SCOPE("gc_mdtab", 0); - intptr_t num_freed = 0; + size_t num_freed = 0; for (size_t i = 0; i < shard->capacity; ++i) { num_freed += InternedMetadata::CleanupLinkedMetadata(&shard->elems[i]); } - gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -num_freed); + gpr_atm_no_barrier_fetch_add(&shard->free_estimate, + -static_cast(num_freed)); } static void grow_mdtab(mdtab_shard* shard) { @@ -375,9 +376,9 @@ grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata) { } 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); + if (user_data->destroy_user_data.Load(grpc_core::MemoryOrder::ACQUIRE) == + destroy_func) { + return user_data->data.Load(grpc_core::MemoryOrder::RELAXED); } else { return nullptr; } @@ -403,40 +404,40 @@ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void*)) { } static void* set_user_data(UserData* ud, void (*destroy_func)(void*), - void* user_data) { - GPR_ASSERT((user_data == nullptr) == (destroy_func == nullptr)); + void* data) { + GPR_ASSERT((data == nullptr) == (destroy_func == nullptr)); grpc_core::ReleasableMutexLock lock(&ud->mu_user_data); - if (gpr_atm_no_barrier_load(&ud->destroy_user_data)) { + if (ud->destroy_user_data.Load(grpc_core::MemoryOrder::RELAXED)) { /* user data can only be set once */ lock.Unlock(); if (destroy_func != nullptr) { - destroy_func(user_data); + destroy_func(data); } - return (void*)gpr_atm_no_barrier_load(&ud->user_data); + return ud->data.Load(grpc_core::MemoryOrder::RELAXED); } - gpr_atm_no_barrier_store(&ud->user_data, (gpr_atm)user_data); - gpr_atm_rel_store(&ud->destroy_user_data, (gpr_atm)destroy_func); - return user_data; + ud->data.Store(data, grpc_core::MemoryOrder::RELAXED); + ud->destroy_user_data.Store(destroy_func, grpc_core::MemoryOrder::RELEASE); + return data; } void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*), - void* user_data) { + void* data) { switch (GRPC_MDELEM_STORAGE(md)) { case GRPC_MDELEM_STORAGE_EXTERNAL: - destroy_func(user_data); + destroy_func(data); return nullptr; case GRPC_MDELEM_STORAGE_STATIC: - destroy_func(user_data); + destroy_func(data); return (void*)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) - grpc_static_mdelem_table]; case GRPC_MDELEM_STORAGE_ALLOCATED: { auto* am = reinterpret_cast(GRPC_MDELEM_DATA(md)); - return set_user_data(am->user_data(), destroy_func, user_data); + return set_user_data(am->user_data(), destroy_func, data); } case GRPC_MDELEM_STORAGE_INTERNED: { auto* im = reinterpret_cast GRPC_MDELEM_DATA(md); GPR_ASSERT(!is_mdelem_static(md)); - return set_user_data(im->user_data(), destroy_func, user_data); + return set_user_data(im->user_data(), destroy_func, data); } } GPR_UNREACHABLE_CODE(return nullptr); diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index d431474d017..c0d1ab36351 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -145,7 +145,7 @@ inline bool grpc_mdelem_static_value_eq(grpc_mdelem a, grpc_mdelem b_static) { is used as a type tag and is checked during user_data fetch. */ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*if_destroy_func)(void*)); void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*), - void* user_data); + void* data); // Defined in metadata.cc. struct mdtab_shard; @@ -160,12 +160,12 @@ void grpc_mdelem_trace_unref(void* md, const grpc_slice& key, #endif namespace grpc_core { -typedef void (*destroy_user_data_func)(void* user_data); +typedef void (*destroy_user_data_func)(void* data); struct UserData { Mutex mu_user_data; - gpr_atm destroy_user_data = 0; - gpr_atm user_data = 0; + grpc_core::Atomic destroy_user_data; + grpc_core::Atomic data; }; class InternedMetadata { @@ -214,7 +214,7 @@ class InternedMetadata { InternedMetadata* bucket_next() { return link_.next; } void set_bucket_next(InternedMetadata* md) { link_.next = md; } - static intptr_t CleanupLinkedMetadata(BucketLink* head); + static size_t CleanupLinkedMetadata(BucketLink* head); private: bool AllRefsDropped() { return refcnt_.Load(MemoryOrder::ACQUIRE) == 0; } From 069547e944bad1c2c1a0fb232ebf6159fc359ca8 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Sun, 28 Apr 2019 17:14:05 -0400 Subject: [PATCH 2022/2143] Fix a typo in chttp2 stream initialization. Found this during performance optimizations. We always reinitialize this to the correct value, so this wasn't caught in tests. --- src/core/ext/transport/chttp2/transport/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 2e2b3251b4f..00b1fe18b28 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -633,7 +633,7 @@ struct grpc_chttp2_stream { GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS; /* Stream decompression method to be used. */ grpc_stream_compression_method stream_decompression_method = - GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS; + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS; /** Stream compression decompress context */ grpc_stream_compression_context* stream_decompression_ctx = nullptr; /** Stream compression compress context */ From 952ddb6a2bceed3f21aa1ef18e42aa24b7fa538d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 29 Apr 2019 12:06:34 -0400 Subject: [PATCH 2023/2143] fix uploading bazel RBE results to bigquery --- tools/run_tests/python_utils/upload_rbe_results.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py index bda567e977e..e6504799d66 100755 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -146,6 +146,8 @@ if __name__ == "__main__": invocation_id = args.invocation_id or _get_invocation_id() resultstore_actions = _get_resultstore_data(api_key, invocation_id) + # google.devtools.resultstore.v2.Action schema: + # https://github.com/googleapis/googleapis/blob/master/google/devtools/resultstore/v2/action.proto bq_rows = [] for index, action in enumerate(resultstore_actions): # Filter out non-test related data, such as build results. @@ -187,6 +189,8 @@ if __name__ == "__main__": } elif 'testSuite' not in action['testAction']: continue + elif 'tests' not in action['testAction']['testSuite']: + continue else: test_cases = action['testAction']['testSuite']['tests'][0][ 'testSuite']['tests'] From ed432363775377da49b179cd66131a6f6dcd1877 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Fri, 26 Apr 2019 18:58:47 -0700 Subject: [PATCH 2024/2143] Coalesce arena create/first alloc for grpc_call. --- src/core/lib/gprpp/arena.cc | 37 ++++++++++++++++++++++++------------ src/core/lib/gprpp/arena.h | 24 ++++++++++++++++++++++- src/core/lib/surface/call.cc | 20 +++++++++++++------ 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/core/lib/gprpp/arena.cc b/src/core/lib/gprpp/arena.cc index ab3a4865a12..5c344db4e35 100644 --- a/src/core/lib/gprpp/arena.cc +++ b/src/core/lib/gprpp/arena.cc @@ -31,11 +31,23 @@ #include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gprpp/memory.h" -template -static void* gpr_arena_malloc(size_t size) { - return gpr_malloc_aligned(size, alignment); +namespace { + +void* ArenaStorage(size_t initial_size) { + static constexpr size_t base_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_core::Arena)); + initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size); + size_t alloc_size = base_size + initial_size; + static constexpr size_t alignment = + (GPR_CACHELINE_SIZE > GPR_MAX_ALIGNMENT && + GPR_CACHELINE_SIZE % GPR_MAX_ALIGNMENT == 0) + ? GPR_CACHELINE_SIZE + : GPR_MAX_ALIGNMENT; + return gpr_malloc_aligned(alloc_size, alignment); } +} // namespace + namespace grpc_core { Arena::~Arena() { @@ -49,16 +61,17 @@ Arena::~Arena() { } Arena* Arena::Create(size_t initial_size) { + return new (ArenaStorage(initial_size)) Arena(initial_size); +} + +Pair Arena::CreateWithAlloc(size_t initial_size, + size_t alloc_size) { static constexpr size_t base_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Arena)); - initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size); - size_t alloc_size = base_size + initial_size; - static constexpr size_t alignment = - (GPR_CACHELINE_SIZE > GPR_MAX_ALIGNMENT && - GPR_CACHELINE_SIZE % GPR_MAX_ALIGNMENT == 0) - ? GPR_CACHELINE_SIZE - : GPR_MAX_ALIGNMENT; - return new (gpr_arena_malloc(alloc_size)) Arena(initial_size); + auto* new_arena = + new (ArenaStorage(initial_size)) Arena(initial_size, alloc_size); + void* first_alloc = reinterpret_cast(new_arena) + base_size; + return MakePair(new_arena, first_alloc); } size_t Arena::Destroy() { @@ -77,7 +90,7 @@ void* Arena::AllocZone(size_t size) { static constexpr size_t zone_base_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Zone)); size_t alloc_size = zone_base_size + size; - Zone* z = new (gpr_arena_malloc(alloc_size)) Zone(); + Zone* z = new (gpr_malloc_aligned(alloc_size, GPR_MAX_ALIGNMENT)) Zone(); { gpr_spinlock_lock(&arena_growth_spinlock_); z->prev = last_zone_; diff --git a/src/core/lib/gprpp/arena.h b/src/core/lib/gprpp/arena.h index 749f4e47ee8..b1b0c4a85cb 100644 --- a/src/core/lib/gprpp/arena.h +++ b/src/core/lib/gprpp/arena.h @@ -36,6 +36,7 @@ #include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gpr/spinlock.h" #include "src/core/lib/gprpp/atomic.h" +#include "src/core/lib/gprpp/pair.h" #include @@ -45,6 +46,13 @@ class Arena { public: // Create an arena, with \a initial_size bytes in the first allocated buffer. static Arena* Create(size_t initial_size); + + // Create an arena, with \a initial_size bytes in the first allocated buffer, + // and return both a void pointer to the returned arena and a void* with the + // first allocation. + static Pair CreateWithAlloc(size_t initial_size, + size_t alloc_size); + // Destroy an arena, returning the total number of bytes allocated. size_t Destroy(); // Allocate \a size bytes from the arena. @@ -76,7 +84,21 @@ class Arena { Zone* prev; }; - explicit Arena(size_t initial_size) : initial_zone_size_(initial_size) {} + // Initialize an arena. + // Parameters: + // initial_size: The initial size of the whole arena in bytes. These bytes + // are contained within 'zone 0'. If the arena user ends up requiring more + // memory than the arena contains in zone 0, subsequent zones are allocated + // on demand and maintained in a tail-linked list. + // + // initial_alloc: Optionally, construct the arena as though a call to + // Alloc() had already been made for initial_alloc bytes. This provides a + // quick optimization (avoiding an atomic fetch-add) for the common case + // where we wish to create an arena and then perform an immediate + // allocation. + explicit Arena(size_t initial_size, size_t initial_alloc = 0) + : total_used_(initial_alloc), initial_zone_size_(initial_size) {} + ~Arena(); void* AllocZone(size_t size); diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 54fdacd847c..bd140021c96 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -321,16 +321,23 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, GRPC_CHANNEL_INTERNAL_REF(args->channel, "call"); + grpc_core::Arena* arena; + grpc_call* call; grpc_error* error = GRPC_ERROR_NONE; grpc_channel_stack* channel_stack = grpc_channel_get_channel_stack(args->channel); - grpc_call* call; size_t initial_size = grpc_channel_get_call_size_estimate(args->channel); GRPC_STATS_INC_CALL_INITIAL_SIZE(initial_size); - grpc_core::Arena* arena = grpc_core::Arena::Create(initial_size); - call = new (arena->Alloc(GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) + - channel_stack->call_stack_size)) - grpc_call(arena, *args); + size_t call_and_stack_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) + + channel_stack->call_stack_size; + size_t call_alloc_size = + call_and_stack_size + (args->parent ? sizeof(child_call) : 0); + + std::pair arena_with_call = + grpc_core::Arena::CreateWithAlloc(initial_size, call_alloc_size); + arena = arena_with_call.first; + call = new (arena_with_call.second) grpc_call(arena, *args); *out_call = call; grpc_slice path = grpc_empty_slice(); if (call->is_client) { @@ -362,7 +369,8 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, bool immediately_cancel = false; if (args->parent != nullptr) { - call->child = arena->New(args->parent); + call->child = new (reinterpret_cast(arena_with_call.second) + + call_and_stack_size) child_call(args->parent); GRPC_CALL_INTERNAL_REF(args->parent, "child"); GPR_ASSERT(call->is_client); From 5e7e4946384d74e05fb140fa0a904e5427cb1f95 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 29 Apr 2019 12:26:50 -0700 Subject: [PATCH 2025/2143] Use milliseconds for test_server timeout --- test/core/end2end/bad_server_response_test.cc | 2 +- test/core/util/reconnect_server.cc | 2 +- test/core/util/test_tcp_server.cc | 6 +++--- test/core/util/test_tcp_server.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index 3701a938a3d..2d74b6b77b3 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -250,7 +250,7 @@ static void actually_poll_server(void* arg) { if (done || gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) < 0) { break; } - test_tcp_server_poll(pa->server, 1); + test_tcp_server_poll(pa->server, 1000); } gpr_event_set(pa->signal_when_done, (void*)1); gpr_free(pa); diff --git a/test/core/util/reconnect_server.cc b/test/core/util/reconnect_server.cc index ad7cf42f71f..144ad64f095 100644 --- a/test/core/util/reconnect_server.cc +++ b/test/core/util/reconnect_server.cc @@ -109,7 +109,7 @@ void reconnect_server_start(reconnect_server* server, int port) { } void reconnect_server_poll(reconnect_server* server, int seconds) { - test_tcp_server_poll(&server->tcp_server, seconds); + test_tcp_server_poll(&server->tcp_server, 1000 * seconds); } void reconnect_server_clear_timestamps(reconnect_server* server) { diff --git a/test/core/util/test_tcp_server.cc b/test/core/util/test_tcp_server.cc index 610a9918ce6..80d0634a9b9 100644 --- a/test/core/util/test_tcp_server.cc +++ b/test/core/util/test_tcp_server.cc @@ -77,11 +77,11 @@ void test_tcp_server_start(test_tcp_server* server, int port) { gpr_log(GPR_INFO, "test tcp server listening on 0.0.0.0:%d", port); } -void test_tcp_server_poll(test_tcp_server* server, int seconds) { +void test_tcp_server_poll(test_tcp_server* server, int milliseconds) { grpc_pollset_worker* worker = nullptr; grpc_core::ExecCtx exec_ctx; grpc_millis deadline = grpc_timespec_to_millis_round_up( - grpc_timeout_seconds_to_deadline(seconds)); + grpc_timeout_milliseconds_to_deadline(milliseconds)); gpr_mu_lock(server->mu); GRPC_LOG_IF_ERROR("pollset_work", grpc_pollset_work(server->pollset, &worker, deadline)); @@ -104,7 +104,7 @@ void test_tcp_server_destroy(test_tcp_server* server) { gpr_time_from_seconds(5, GPR_TIMESPAN)); while (!server->shutdown && gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), shutdown_deadline) < 0) { - test_tcp_server_poll(server, 1); + test_tcp_server_poll(server, 1000); } grpc_pollset_shutdown(server->pollset, GRPC_CLOSURE_CREATE(finish_pollset, server->pollset, diff --git a/test/core/util/test_tcp_server.h b/test/core/util/test_tcp_server.h index 58140388da3..313a27a3334 100644 --- a/test/core/util/test_tcp_server.h +++ b/test/core/util/test_tcp_server.h @@ -35,7 +35,7 @@ typedef struct test_tcp_server { void test_tcp_server_init(test_tcp_server* server, grpc_tcp_server_cb on_connect, void* user_data); void test_tcp_server_start(test_tcp_server* server, int port); -void test_tcp_server_poll(test_tcp_server* server, int seconds); +void test_tcp_server_poll(test_tcp_server* server, int milliseconds); void test_tcp_server_destroy(test_tcp_server* server); #endif /* GRPC_TEST_CORE_UTIL_TEST_TCP_SERVER_H */ From 333ba8feaea465e35678c356542915140605b444 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Thu, 25 Apr 2019 17:31:20 -0700 Subject: [PATCH 2026/2143] Use aligned_alloc directly for grpc_core::Arena --- include/grpc/impl/codegen/port_platform.h | 3 + include/grpc/support/alloc.h | 2 + src/core/lib/gpr/alloc.cc | 78 ++++++++++++++++++++--- src/core/lib/gpr/alloc.h | 8 +++ src/core/lib/gprpp/arena.h | 2 +- test/core/gpr/alloc_test.cc | 18 +++++- test/core/util/memory_counters.cc | 8 ++- 7 files changed, 105 insertions(+), 14 deletions(-) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index d7294d59d41..ff759d2baed 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -77,6 +77,7 @@ #define GPR_WINDOWS 1 #define GPR_WINDOWS_SUBPROCESS 1 #define GPR_WINDOWS_ENV +#define GPR_HAS_ALIGNED_MALLOC 1 #ifdef __MSYS__ #define GPR_GETPID_IN_UNISTD_H 1 #define GPR_MSYS_TMPFILE @@ -173,6 +174,7 @@ #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 #define GPR_HAS_PTHREAD_H 1 +#define GPR_HAS_ALIGNED_ALLOC 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 @@ -238,6 +240,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_POSIX_MEMALIGN 1 #define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifndef GRPC_CFSTREAM diff --git a/include/grpc/support/alloc.h b/include/grpc/support/alloc.h index 8bd940bec47..4d8e007a577 100644 --- a/include/grpc/support/alloc.h +++ b/include/grpc/support/alloc.h @@ -32,6 +32,8 @@ typedef struct gpr_allocation_functions { void* (*zalloc_fn)(size_t size); /** if NULL, uses malloc_fn then memset */ void* (*realloc_fn)(void* ptr, size_t size); void (*free_fn)(void* ptr); + void* (*aligned_alloc_fn)(size_t size, size_t alignment); + void (*aligned_free_fn)(void* ptr); } gpr_allocation_functions; /** malloc. diff --git a/src/core/lib/gpr/alloc.cc b/src/core/lib/gpr/alloc.cc index 611e4cceee4..b601ad79f79 100644 --- a/src/core/lib/gpr/alloc.cc +++ b/src/core/lib/gpr/alloc.cc @@ -23,6 +23,7 @@ #include #include #include +#include "src/core/lib/gpr/alloc.h" #include "src/core/lib/profiling/timers.h" static void* zalloc_with_calloc(size_t sz) { return calloc(sz, 1); } @@ -33,8 +34,61 @@ static void* zalloc_with_gpr_malloc(size_t sz) { return p; } -static gpr_allocation_functions g_alloc_functions = {malloc, zalloc_with_calloc, - realloc, free}; +static constexpr bool is_power_of_two(size_t value) { + // 2^N = 100000...000 + // 2^N - 1 = 011111...111 + // (2^N) && ((2^N)-1)) = 0 + return (value & (value - 1)) == 0; +} + +static void* aligned_alloc_with_gpr_malloc(size_t size, size_t alignment) { + GPR_DEBUG_ASSERT(is_power_of_two(alignment)); + size_t extra = alignment - 1 + sizeof(void*); + void* p = gpr_malloc(size + extra); + void** ret = (void**)(((uintptr_t)p + extra) & ~(alignment - 1)); + ret[-1] = p; + return (void*)ret; +} + +static void aligned_free_with_gpr_malloc(void* ptr) { + gpr_free((static_cast(ptr))[-1]); +} + +static void* platform_malloc_aligned(size_t size, size_t alignment) { +#if defined(GPR_HAS_ALIGNED_ALLOC) + size = GPR_ROUND_UP_TO_SPECIFIED_SIZE(size, alignment); + void* ret = aligned_alloc(alignment, size); + GPR_ASSERT(ret != nullptr); + return ret; +#elif defined(GPR_HAS_ALIGNED_MALLOC) + GPR_DEBUG_ASSERT(is_power_of_two(alignment)); + void* ret = _aligned_malloc(size, alignment); + GPR_ASSERT(ret != nullptr); + return ret; +#elif defined(GPR_HAS_POSIX_MEMALIGN) + GPR_DEBUG_ASSERT(is_power_of_two(alignment)); + GPR_DEBUG_ASSERT(alignment % sizeof(void*) == 0); + void* ret = nullptr; + GPR_ASSERT(posix_memalign(&ret, alignment, size) == 0); + return ret; +#else + return aligned_alloc_with_gpr_malloc(size, alignment); +#endif +} + +static void platform_free_aligned(void* ptr) { +#if defined(GPR_HAS_ALIGNED_ALLOC) || defined(GPR_HAS_POSIX_MEMALIGN) + free(ptr); +#elif defined(GPR_HAS_ALIGNED_MALLOC) + _aligned_free(ptr); +#else + aligned_free_with_gpr_malloc(ptr); +#endif +} + +static gpr_allocation_functions g_alloc_functions = { + malloc, zalloc_with_calloc, realloc, + free, platform_malloc_aligned, platform_free_aligned}; gpr_allocation_functions gpr_get_allocation_functions() { return g_alloc_functions; @@ -47,6 +101,12 @@ void gpr_set_allocation_functions(gpr_allocation_functions functions) { if (functions.zalloc_fn == nullptr) { functions.zalloc_fn = zalloc_with_gpr_malloc; } + GPR_ASSERT((functions.aligned_alloc_fn == nullptr) == + (functions.aligned_free_fn == nullptr)); + if (functions.aligned_alloc_fn == nullptr) { + functions.aligned_alloc_fn = aligned_alloc_with_gpr_malloc; + functions.aligned_free_fn = aligned_free_with_gpr_malloc; + } g_alloc_functions = functions; } @@ -88,12 +148,12 @@ void* gpr_realloc(void* p, size_t size) { } void* gpr_malloc_aligned(size_t size, size_t alignment) { - GPR_ASSERT(((alignment - 1) & alignment) == 0); // Must be power of 2. - size_t extra = alignment - 1 + sizeof(void*); - void* p = gpr_malloc(size + extra); - void** ret = (void**)(((uintptr_t)p + extra) & ~(alignment - 1)); - ret[-1] = p; - return (void*)ret; + GPR_TIMER_SCOPE("gpr_malloc_aligned", 0); + if (size == 0) return nullptr; + return g_alloc_functions.aligned_alloc_fn(size, alignment); } -void gpr_free_aligned(void* ptr) { gpr_free((static_cast(ptr))[-1]); } +void gpr_free_aligned(void* ptr) { + GPR_TIMER_SCOPE("gpr_free_aligned", 0); + g_alloc_functions.aligned_free_fn(ptr); +} diff --git a/src/core/lib/gpr/alloc.h b/src/core/lib/gpr/alloc.h index 762b51bf663..2493c87514d 100644 --- a/src/core/lib/gpr/alloc.h +++ b/src/core/lib/gpr/alloc.h @@ -25,4 +25,12 @@ #define GPR_ROUND_UP_TO_ALIGNMENT_SIZE(x) \ (((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u)) +#define GPR_ROUND_UP_TO_CACHELINE_SIZE(x) \ + (((x) + GPR_CACHELINE_SIZE - 1u) & ~(GPR_CACHELINE_SIZE - 1u)) + +#define GPR_ROUND_UP_TO_SPECIFIED_SIZE(x, align) \ + (((x) + align - 1u) & ~(align - 1u)) + +void* gpr_malloc_cacheline(size_t size); + #endif /* GRPC_CORE_LIB_GPR_ALLOC_H */ diff --git a/src/core/lib/gprpp/arena.h b/src/core/lib/gprpp/arena.h index b1b0c4a85cb..915cd5c528e 100644 --- a/src/core/lib/gprpp/arena.h +++ b/src/core/lib/gprpp/arena.h @@ -61,7 +61,7 @@ class Arena { GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Arena)); size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size); size_t begin = total_used_.FetchAdd(size, MemoryOrder::RELAXED); - if (begin + size <= initial_zone_size_) { + if (GPR_LIKELY(begin + size <= initial_zone_size_)) { return reinterpret_cast(this) + base_size + begin; } else { return AllocZone(size); diff --git a/test/core/gpr/alloc_test.cc b/test/core/gpr/alloc_test.cc index 0b110e2b77d..fb6bc9a0bdd 100644 --- a/test/core/gpr/alloc_test.cc +++ b/test/core/gpr/alloc_test.cc @@ -31,12 +31,21 @@ static void fake_free(void* addr) { *(static_cast(addr)) = static_cast(0xdeadd00d); } +static void* fake_aligned_malloc(size_t size, size_t alignment) { + return (void*)(size + alignment); +} + +static void fake_aligned_free(void* addr) { + *(static_cast(addr)) = static_cast(0xcafef00d); +} + static void test_custom_allocs() { const gpr_allocation_functions default_fns = gpr_get_allocation_functions(); intptr_t addr_to_free = 0; char* i; - gpr_allocation_functions fns = {fake_malloc, nullptr, fake_realloc, - fake_free}; + gpr_allocation_functions fns = {fake_malloc, nullptr, + fake_realloc, fake_free, + fake_aligned_malloc, fake_aligned_free}; gpr_set_allocation_functions(fns); GPR_ASSERT((void*)(size_t)0xdeadbeef == gpr_malloc(0xdeadbeef)); @@ -45,6 +54,11 @@ static void test_custom_allocs() { gpr_free(&addr_to_free); GPR_ASSERT(addr_to_free == (intptr_t)0xdeadd00d); + GPR_ASSERT((void*)(size_t)(0xdeadbeef + 64) == + gpr_malloc_aligned(0xdeadbeef, 64)); + gpr_free_aligned(&addr_to_free); + GPR_ASSERT(addr_to_free == (intptr_t)0xcafef00d); + /* Restore and check we don't get funky values and that we don't leak */ gpr_set_allocation_functions(default_fns); GPR_ASSERT((void*)sizeof(*i) != diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc index 787fb76e48b..11107f670fb 100644 --- a/test/core/util/memory_counters.cc +++ b/test/core/util/memory_counters.cc @@ -90,8 +90,12 @@ static void guard_free(void* vptr) { g_old_allocs.free_fn(ptr); } -struct gpr_allocation_functions g_guard_allocs = {guard_malloc, nullptr, - guard_realloc, guard_free}; +// NB: We do not specify guard_malloc_aligned/guard_free_aligned methods. Since +// they are null, calls to gpr_malloc_aligned/gpr_free_aligned are executed as a +// wrapper over gpr_malloc/gpr_free, which do use guard_malloc/guard_free, and +// thus there allocations are tracked as well. +struct gpr_allocation_functions g_guard_allocs = { + guard_malloc, nullptr, guard_realloc, guard_free, nullptr, nullptr}; void grpc_memory_counters_init() { memset(&g_memory_counters, 0, sizeof(g_memory_counters)); From a3fe7c0c908451deb04c3bb99a6b364b313467f6 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Mon, 29 Apr 2019 14:49:03 -0700 Subject: [PATCH 2027/2143] Renamed macros for memory alignment --- .../ext/filters/client_channel/subchannel.cc | 22 +++++----- src/core/lib/channel/channel_stack.cc | 43 ++++++++++--------- src/core/lib/gpr/alloc.cc | 2 +- src/core/lib/gpr/alloc.h | 14 +++--- src/core/lib/gprpp/arena.cc | 4 +- src/core/lib/gprpp/arena.h | 4 +- src/core/lib/surface/call.cc | 6 +-- src/core/lib/transport/transport.cc | 2 +- test/core/util/memory_counters.cc | 20 +++++---- 9 files changed, 61 insertions(+), 56 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index a284e692b09..873db8ef57c 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -66,12 +66,13 @@ #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))) +#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ + (grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE( \ + sizeof(SubchannelCall))) +#define CALL_STACK_TO_SUBCHANNEL_CALL(callstack) \ + (SubchannelCall*)(((char*)(call_stack)) - \ + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE( \ + sizeof(SubchannelCall))) namespace grpc_core { @@ -151,10 +152,10 @@ RefCountedPtr ConnectedSubchannel::CreateCall( size_t ConnectedSubchannel::GetInitialCallSizeEstimate( size_t parent_data_size) const { size_t allocation_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(SubchannelCall)); if (parent_data_size > 0) { allocation_size += - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + parent_data_size; } else { allocation_size += channel_stack_->call_stack_size; @@ -178,8 +179,9 @@ void SubchannelCall::StartTransportStreamOpBatch( 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); + return (char*)this + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(SubchannelCall)) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(chanstk->call_stack_size); } grpc_call_stack* SubchannelCall::GetCallStack() { diff --git a/src/core/lib/channel/channel_stack.cc b/src/core/lib/channel/channel_stack.cc index df956c7176c..7dfabbb0a1c 100644 --- a/src/core/lib/channel/channel_stack.cc +++ b/src/core/lib/channel/channel_stack.cc @@ -47,9 +47,9 @@ grpc_core::TraceFlag grpc_trace_channel(false, "channel"); size_t grpc_channel_stack_size(const grpc_channel_filter** filters, size_t filter_count) { /* always need the header, and size for the channel elements */ - size_t size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * - sizeof(grpc_channel_element)); + size_t size = GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE( + filter_count * sizeof(grpc_channel_element)); size_t i; GPR_ASSERT((GPR_MAX_ALIGNMENT & (GPR_MAX_ALIGNMENT - 1)) == 0 && @@ -57,18 +57,18 @@ size_t grpc_channel_stack_size(const grpc_channel_filter** filters, /* add the size for each filter */ for (i = 0; i < filter_count; i++) { - size += GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); + size += GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); } return size; } -#define CHANNEL_ELEMS_FROM_STACK(stk) \ - ((grpc_channel_element*)((char*)(stk) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ +#define CHANNEL_ELEMS_FROM_STACK(stk) \ + ((grpc_channel_element*)((char*)(stk) + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE( \ sizeof(grpc_channel_stack)))) -#define CALL_ELEMS_FROM_STACK(stk) \ - ((grpc_call_element*)((char*)(stk) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ +#define CALL_ELEMS_FROM_STACK(stk) \ + ((grpc_call_element*)((char*)(stk) + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE( \ sizeof(grpc_call_stack)))) grpc_channel_element* grpc_channel_stack_element( @@ -92,8 +92,9 @@ grpc_error* grpc_channel_stack_init( const grpc_channel_args* channel_args, grpc_transport* optional_transport, const char* name, grpc_channel_stack* stack) { size_t call_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_call_element)); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(filter_count * + sizeof(grpc_call_element)); grpc_channel_element* elems; grpc_channel_element_args args; char* user_data; @@ -104,8 +105,8 @@ grpc_error* grpc_channel_stack_init( name); elems = CHANNEL_ELEMS_FROM_STACK(stack); user_data = (reinterpret_cast(elems)) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * - sizeof(grpc_channel_element)); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(filter_count * + sizeof(grpc_channel_element)); /* init per-filter data */ grpc_error* first_error = GRPC_ERROR_NONE; @@ -126,8 +127,9 @@ grpc_error* grpc_channel_stack_init( } } user_data += - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); - call_size += GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); + call_size += + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(filters[i]->sizeof_call_data); } GPR_ASSERT(user_data > (char*)stack); @@ -162,8 +164,9 @@ grpc_error* grpc_call_stack_init(grpc_channel_stack* channel_stack, GRPC_STREAM_REF_INIT(&elem_args->call_stack->refcount, initial_refs, destroy, destroy_arg, "CALL_STACK"); call_elems = CALL_ELEMS_FROM_STACK(elem_args->call_stack); - user_data = (reinterpret_cast(call_elems)) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element)); + user_data = + (reinterpret_cast(call_elems)) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(count * sizeof(grpc_call_element)); /* init per-filter data */ grpc_error* first_error = GRPC_ERROR_NONE; @@ -171,8 +174,8 @@ grpc_error* grpc_call_stack_init(grpc_channel_stack* channel_stack, call_elems[i].filter = channel_elems[i].filter; call_elems[i].channel_data = channel_elems[i].channel_data; call_elems[i].call_data = user_data; - user_data += - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data); + user_data += GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE( + call_elems[i].filter->sizeof_call_data); } for (size_t i = 0; i < count; i++) { grpc_error* error = @@ -242,11 +245,11 @@ grpc_channel_stack* grpc_channel_stack_from_top_element( grpc_channel_element* elem) { return reinterpret_cast( reinterpret_cast(elem) - - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack))); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_channel_stack))); } grpc_call_stack* grpc_call_stack_from_top_element(grpc_call_element* elem) { return reinterpret_cast( reinterpret_cast(elem) - - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack))); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_call_stack))); } diff --git a/src/core/lib/gpr/alloc.cc b/src/core/lib/gpr/alloc.cc index b601ad79f79..0d9f6f7120e 100644 --- a/src/core/lib/gpr/alloc.cc +++ b/src/core/lib/gpr/alloc.cc @@ -56,7 +56,7 @@ static void aligned_free_with_gpr_malloc(void* ptr) { static void* platform_malloc_aligned(size_t size, size_t alignment) { #if defined(GPR_HAS_ALIGNED_ALLOC) - size = GPR_ROUND_UP_TO_SPECIFIED_SIZE(size, alignment); + size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size, alignment); void* ret = aligned_alloc(alignment, size); GPR_ASSERT(ret != nullptr); return ret; diff --git a/src/core/lib/gpr/alloc.h b/src/core/lib/gpr/alloc.h index 2493c87514d..c77fbeaca49 100644 --- a/src/core/lib/gpr/alloc.h +++ b/src/core/lib/gpr/alloc.h @@ -22,15 +22,13 @@ #include /// Given a size, round up to the next multiple of sizeof(void*). -#define GPR_ROUND_UP_TO_ALIGNMENT_SIZE(x) \ - (((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u)) +#define GPR_ROUND_UP_TO_ALIGNMENT_SIZE(x, align) \ + (((x) + (align)-1u) & ~((align)-1u)) + +#define GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(x) \ + GPR_ROUND_UP_TO_ALIGNMENT_SIZE((x), GPR_MAX_ALIGNMENT) #define GPR_ROUND_UP_TO_CACHELINE_SIZE(x) \ - (((x) + GPR_CACHELINE_SIZE - 1u) & ~(GPR_CACHELINE_SIZE - 1u)) - -#define GPR_ROUND_UP_TO_SPECIFIED_SIZE(x, align) \ - (((x) + align - 1u) & ~(align - 1u)) - -void* gpr_malloc_cacheline(size_t size); + GPR_ROUND_UP_TO_ALIGNMENT_SIZE((x), GPR_CACHELINE_SIZE) #endif /* GRPC_CORE_LIB_GPR_ALLOC_H */ diff --git a/src/core/lib/gprpp/arena.cc b/src/core/lib/gprpp/arena.cc index 5c344db4e35..e1c7b292f8c 100644 --- a/src/core/lib/gprpp/arena.cc +++ b/src/core/lib/gprpp/arena.cc @@ -67,7 +67,7 @@ Arena* Arena::Create(size_t initial_size) { Pair Arena::CreateWithAlloc(size_t initial_size, size_t alloc_size) { static constexpr size_t base_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Arena)); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(Arena)); auto* new_arena = new (ArenaStorage(initial_size)) Arena(initial_size, alloc_size); void* first_alloc = reinterpret_cast(new_arena) + base_size; @@ -88,7 +88,7 @@ void* Arena::AllocZone(size_t size) { // sizing hysteresis (that is, most calls should have a large enough initial // zone and will not need to grow the arena). static constexpr size_t zone_base_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Zone)); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(Zone)); size_t alloc_size = zone_base_size + size; Zone* z = new (gpr_malloc_aligned(alloc_size, GPR_MAX_ALIGNMENT)) Zone(); { diff --git a/src/core/lib/gprpp/arena.h b/src/core/lib/gprpp/arena.h index 915cd5c528e..6c646c5871d 100644 --- a/src/core/lib/gprpp/arena.h +++ b/src/core/lib/gprpp/arena.h @@ -58,8 +58,8 @@ class Arena { // Allocate \a size bytes from the arena. void* Alloc(size_t size) { static constexpr size_t base_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Arena)); - size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(Arena)); + size = GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(size); size_t begin = total_used_.FetchAdd(size, MemoryOrder::RELAXED); if (GPR_LIKELY(begin + size <= initial_zone_size_)) { return reinterpret_cast(this) + base_size + begin; diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index bd140021c96..0a26872a9ea 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -260,10 +260,10 @@ grpc_core::TraceFlag grpc_compression_trace(false, "compression"); #define CALL_STACK_FROM_CALL(call) \ (grpc_call_stack*)((char*)(call) + \ - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call))) + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_call))) #define CALL_FROM_CALL_STACK(call_stack) \ (grpc_call*)(((char*)(call_stack)) - \ - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call))) + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_call))) #define CALL_ELEM_FROM_CALL(call, idx) \ grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx) @@ -329,7 +329,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, size_t initial_size = grpc_channel_get_call_size_estimate(args->channel); GRPC_STATS_INC_CALL_INITIAL_SIZE(initial_size); size_t call_and_stack_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_call)) + channel_stack->call_stack_size; size_t call_alloc_size = call_and_stack_size + (args->parent ? sizeof(child_call) : 0); diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index 29c1e561891..40870657b84 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -115,7 +115,7 @@ void grpc_transport_move_stats(grpc_transport_stream_stats* from, } size_t grpc_transport_stream_size(grpc_transport* transport) { - return GPR_ROUND_UP_TO_ALIGNMENT_SIZE(transport->vtable->sizeof_stream); + return GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(transport->vtable->sizeof_stream); } void grpc_transport_destroy(grpc_transport* transport) { diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc index 11107f670fb..60d22b18309 100644 --- a/test/core/util/memory_counters.cc +++ b/test/core/util/memory_counters.cc @@ -54,9 +54,10 @@ static void* guard_malloc(size_t size) { NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, (gpr_atm)1); void* ptr = g_old_allocs.malloc_fn( - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(size)) + size); *static_cast(ptr) = size; - return static_cast(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); + return static_cast(ptr) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(size)); } static void* guard_realloc(void* vptr, size_t size) { @@ -67,23 +68,24 @@ static void* guard_realloc(void* vptr, size_t size) { guard_free(vptr); return nullptr; } - void* ptr = - static_cast(vptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); + void* ptr = static_cast(vptr) - + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(size)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -*static_cast(ptr)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); ptr = g_old_allocs.realloc_fn( - ptr, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size); + ptr, GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(size)) + size); *static_cast(ptr) = size; - return static_cast(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); + return static_cast(ptr) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(size)); } static void guard_free(void* vptr) { if (vptr == nullptr) return; - void* ptr = - static_cast(vptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size_t)); + void* ptr = static_cast(vptr) - + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(size_t)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -*static_cast(ptr)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, -(gpr_atm)1); @@ -93,7 +95,7 @@ static void guard_free(void* vptr) { // NB: We do not specify guard_malloc_aligned/guard_free_aligned methods. Since // they are null, calls to gpr_malloc_aligned/gpr_free_aligned are executed as a // wrapper over gpr_malloc/gpr_free, which do use guard_malloc/guard_free, and -// thus there allocations are tracked as well. +// thus their allocations are tracked as well. struct gpr_allocation_functions g_guard_allocs = { guard_malloc, nullptr, guard_realloc, guard_free, nullptr, nullptr}; From e1a96b83471e229909890ebd9f9b7cf3d8d1edec Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Mon, 29 Apr 2019 15:20:31 -0700 Subject: [PATCH 2028/2143] Fixed non-debug build warning --- src/core/lib/gpr/alloc.cc | 2 ++ src/core/lib/gprpp/arena.cc | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/lib/gpr/alloc.cc b/src/core/lib/gpr/alloc.cc index 0d9f6f7120e..b12b7d8534d 100644 --- a/src/core/lib/gpr/alloc.cc +++ b/src/core/lib/gpr/alloc.cc @@ -34,12 +34,14 @@ static void* zalloc_with_gpr_malloc(size_t sz) { return p; } +#ifndef NDEBUG static constexpr bool is_power_of_two(size_t value) { // 2^N = 100000...000 // 2^N - 1 = 011111...111 // (2^N) && ((2^N)-1)) = 0 return (value & (value - 1)) == 0; } +#endif static void* aligned_alloc_with_gpr_malloc(size_t size, size_t alignment) { GPR_DEBUG_ASSERT(is_power_of_two(alignment)); diff --git a/src/core/lib/gprpp/arena.cc b/src/core/lib/gprpp/arena.cc index e1c7b292f8c..2623ae870a1 100644 --- a/src/core/lib/gprpp/arena.cc +++ b/src/core/lib/gprpp/arena.cc @@ -35,8 +35,8 @@ namespace { void* ArenaStorage(size_t initial_size) { static constexpr size_t base_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_core::Arena)); - initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_core::Arena)); + initial_size = GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(initial_size); size_t alloc_size = base_size + initial_size; static constexpr size_t alignment = (GPR_CACHELINE_SIZE > GPR_MAX_ALIGNMENT && From 50b5240d0a9cf0002049982d8a84cce675b0f691 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Mon, 29 Apr 2019 17:47:56 -0700 Subject: [PATCH 2029/2143] Revert "Merge pull request #18859 from grpc/internal_py_proto_library" This reverts commit 5b720f19c17d623b1b42f9089108295e25f89d88, reversing changes made to a64ae3c0d54903aa27fcf27296d7bc6c67d1e192. --- .gitignore | 1 - WORKSPACE | 7 + bazel/generate_cc.bzl | 204 +++++++----------- bazel/grpc_python_deps.bzl | 14 +- bazel/protobuf.bzl | 84 -------- bazel/python_rules.bzl | 203 ----------------- examples/BUILD | 12 +- examples/python/errors/client.py | 4 +- examples/python/errors/server.py | 4 +- .../test/_error_handling_example_test.py | 2 +- examples/python/multiprocessing/BUILD | 17 +- .../wait_for_ready/wait_for_ready_example.py | 11 +- src/proto/grpc/channelz/BUILD | 5 - src/proto/grpc/health/v1/BUILD | 5 - src/proto/grpc/reflection/v1alpha/BUILD | 5 - src/proto/grpc/testing/BUILD | 41 ++-- src/proto/grpc/testing/proto2/BUILD.bazel | 30 ++- .../grpc_channelz/v1/BUILD.bazel | 26 ++- .../grpc_health/v1/BUILD.bazel | 19 +- .../grpc_reflection/v1alpha/BUILD.bazel | 17 +- .../grpcio_tests/tests/reflection/BUILD.bazel | 1 - tools/distrib/bazel_style.cfg | 4 - tools/distrib/format_bazel.sh | 39 ---- .../linux/grpc_bazel_build_in_docker.sh | 3 +- .../linux/grpc_python_bazel_test_in_docker.sh | 13 +- 25 files changed, 210 insertions(+), 561 deletions(-) delete mode 100644 bazel/protobuf.bzl delete mode 100644 bazel/python_rules.bzl delete mode 100644 tools/distrib/bazel_style.cfg delete mode 100755 tools/distrib/format_bazel.sh diff --git a/.gitignore b/.gitignore index 7b4c5d36cb4..0d2647e61b6 100644 --- a/.gitignore +++ b/.gitignore @@ -115,7 +115,6 @@ bazel-genfiles bazel-grpc bazel-out bazel-testlogs -bazel_format_virtual_environment/ # Debug output gdb.txt diff --git a/WORKSPACE b/WORKSPACE index 2db3c5db2ff..fcf5b5d6d10 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -18,6 +18,13 @@ register_toolchains( "//third_party/toolchains/bazel_0.23.2_rbe_windows:cc-toolchain-x64_windows", ) +# TODO(https://github.com/grpc/grpc/issues/18331): Move off of this dependency. +git_repository( + name = "org_pubref_rules_protobuf", + remote = "https://github.com/ghostwriternr/rules_protobuf", + tag = "v0.8.2.1-alpha", +) + git_repository( name = "io_bazel_rules_python", commit = "8b5d0683a7d878b28fffe464779c8a53659fc645", diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index 82f5cbad310..8f30c84f6b9 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -4,132 +4,81 @@ This is an internal rule used by cc_grpc_library, and shouldn't be used directly. """ -load( - "//bazel:protobuf.bzl", - "get_include_protoc_args", - "get_plugin_args", - "get_proto_root", - "proto_path_to_generated_filename", -) - -_GRPC_PROTO_HEADER_FMT = "{}.grpc.pb.h" -_GRPC_PROTO_SRC_FMT = "{}.grpc.pb.cc" -_GRPC_PROTO_MOCK_HEADER_FMT = "{}_mock.grpc.pb.h" -_PROTO_HEADER_FMT = "{}.pb.h" -_PROTO_SRC_FMT = "{}.pb.cc" - -def _strip_package_from_path(label_package, path): - if len(label_package) == 0: - return path - if not path.startswith(label_package + "/"): - fail("'{}' does not lie within '{}'.".format(path, label_package)) - return path[len(label_package + "/"):] - -def _join_directories(directories): - massaged_directories = [directory for directory in directories if len(directory) != 0] - return "/".join(massaged_directories) - def generate_cc_impl(ctx): - """Implementation of the generate_cc rule.""" - protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources] - includes = [ - f - for src in ctx.attr.srcs - for f in src.proto.transitive_imports - ] - outs = [] - proto_root = get_proto_root( - ctx.label.workspace_root, - ) + """Implementation of the generate_cc rule.""" + protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources] + includes = [f for src in ctx.attr.srcs for f in src.proto.transitive_imports] + outs = [] + # label_len is length of the path from WORKSPACE root to the location of this build file + label_len = 0 + # proto_root is the directory relative to which generated include paths should be + proto_root = "" + if ctx.label.package: + # The +1 is for the trailing slash. + label_len += len(ctx.label.package) + 1 + if ctx.label.workspace_root: + label_len += len(ctx.label.workspace_root) + 1 + proto_root = "/" + ctx.label.workspace_root - label_package = _join_directories([ctx.label.workspace_root, ctx.label.package]) - if ctx.executable.plugin: - outs += [ - proto_path_to_generated_filename( - _strip_package_from_path(label_package, proto.path), - _GRPC_PROTO_HEADER_FMT, - ) - for proto in protos - ] - outs += [ - proto_path_to_generated_filename( - _strip_package_from_path(label_package, proto.path), - _GRPC_PROTO_SRC_FMT, - ) - for proto in protos - ] - if ctx.attr.generate_mocks: - outs += [ - proto_path_to_generated_filename( - _strip_package_from_path(label_package, proto.path), - _GRPC_PROTO_MOCK_HEADER_FMT, - ) - for proto in protos - ] + if ctx.executable.plugin: + outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.h" for proto in protos] + outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.cc" for proto in protos] + if ctx.attr.generate_mocks: + outs += [proto.path[label_len:-len(".proto")] + "_mock.grpc.pb.h" for proto in protos] + 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.actions.declare_file(out) for out in outs] + dir_out = str(ctx.genfiles_dir.path + proto_root) + + arguments = [] + if ctx.executable.plugin: + arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path] + flags = list(ctx.attr.flags) + if ctx.attr.generate_mocks: + flags.append("generate_mock_code=true") + arguments += ["--PLUGIN_out=" + ",".join(flags) + ":" + dir_out] + tools = [ctx.executable.plugin] + else: + arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] + tools = [] + + # Import protos relative to their workspace root so that protoc prints the + # right include paths. + for include in includes: + directory = include.path + if directory.startswith("external"): + external_sep = directory.find("/") + repository_sep = directory.find("/", external_sep + 1) + arguments += ["--proto_path=" + directory[:repository_sep]] else: - outs += [ - proto_path_to_generated_filename( - _strip_package_from_path(label_package, proto.path), - _PROTO_HEADER_FMT, - ) - for proto in protos - ] - outs += [ - proto_path_to_generated_filename( - _strip_package_from_path(label_package, proto.path), - _PROTO_SRC_FMT, - ) - for proto in protos - ] - out_files = [ctx.actions.declare_file(out) for out in outs] - dir_out = str(ctx.genfiles_dir.path + proto_root) + arguments += ["--proto_path=."] + # Include the output directory so that protoc puts the generated code in the + # right directory. + arguments += ["--proto_path={0}{1}".format(dir_out, proto_root)] + arguments += [proto.path for proto in protos] - arguments = [] - if ctx.executable.plugin: - arguments += get_plugin_args( - ctx.executable.plugin, - ctx.attr.flags, - dir_out, - ctx.attr.generate_mocks, - ) - tools = [ctx.executable.plugin] + # create a list of well known proto files if the argument is non-None + well_known_proto_files = [] + if ctx.attr.well_known_protos: + f = ctx.attr.well_known_protos.files.to_list()[0].dirname + if f != "external/com_google_protobuf/src/google/protobuf": + print("Error: Only @com_google_protobuf//:well_known_protos is supported") else: - arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] - tools = [] + # f points to "external/com_google_protobuf/src/google/protobuf" + # add -I argument to protoc so it knows where to look for the proto files. + arguments += ["-I{0}".format(f + "/../..")] + well_known_proto_files = [f for f in ctx.attr.well_known_protos.files] - arguments += get_include_protoc_args(includes) + ctx.actions.run( + inputs = protos + includes + well_known_proto_files, + tools = tools, + outputs = out_files, + executable = ctx.executable._protoc, + arguments = arguments, + ) - # Include the output directory so that protoc puts the generated code in the - # right directory. - arguments += ["--proto_path={0}{1}".format(dir_out, proto_root)] - arguments += [proto.path for proto in protos] - - # create a list of well known proto files if the argument is non-None - well_known_proto_files = [] - if ctx.attr.well_known_protos: - f = ctx.attr.well_known_protos.files.to_list()[0].dirname - if f != "external/com_google_protobuf/src/google/protobuf": - print( - "Error: Only @com_google_protobuf//:well_known_protos is supported", - ) - else: - # f points to "external/com_google_protobuf/src/google/protobuf" - # add -I argument to protoc so it knows where to look for the proto files. - arguments += ["-I{0}".format(f + "/../..")] - well_known_proto_files = [ - f - for f in ctx.attr.well_known_protos.files - ] - - ctx.actions.run( - inputs = protos + includes + well_known_proto_files, - tools = tools, - outputs = out_files, - executable = ctx.executable._protoc, - arguments = arguments, - ) - - return struct(files = depset(out_files)) + return struct(files=depset(out_files)) _generate_cc = rule( attrs = { @@ -147,8 +96,10 @@ _generate_cc = rule( mandatory = False, allow_empty = True, ), - "well_known_protos": attr.label(mandatory = False), - "generate_mocks": attr.bool( + "well_known_protos" : attr.label( + mandatory = False, + ), + "generate_mocks" : attr.bool( default = False, mandatory = False, ), @@ -164,10 +115,7 @@ _generate_cc = rule( ) def generate_cc(well_known_protos, **kwargs): - if well_known_protos: - _generate_cc( - well_known_protos = "@com_google_protobuf//:well_known_protos", - **kwargs - ) - else: - _generate_cc(**kwargs) + if well_known_protos: + _generate_cc(well_known_protos="@com_google_protobuf//:well_known_protos", **kwargs) + else: + _generate_cc(**kwargs) diff --git a/bazel/grpc_python_deps.bzl b/bazel/grpc_python_deps.bzl index 91438f3927b..ec3df19e03a 100644 --- a/bazel/grpc_python_deps.bzl +++ b/bazel/grpc_python_deps.bzl @@ -1,8 +1,16 @@ load("//third_party/py:python_configure.bzl", "python_configure") load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories") load("@grpc_python_dependencies//:requirements.bzl", "pip_install") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories") def grpc_python_deps(): - python_configure(name = "local_config_python") - pip_repositories() - pip_install() + # TODO(https://github.com/grpc/grpc/issues/18256): Remove conditional. + if hasattr(native, "http_archive"): + python_configure(name = "local_config_python") + pip_repositories() + pip_install() + py_proto_repositories() + else: + print("Building Python gRPC with bazel 23.0+ is disabled pending " + + "resolution of https://github.com/grpc/grpc/issues/18256.") + diff --git a/bazel/protobuf.bzl b/bazel/protobuf.bzl deleted file mode 100644 index bddd0d70c7f..00000000000 --- a/bazel/protobuf.bzl +++ /dev/null @@ -1,84 +0,0 @@ -"""Utility functions for generating protobuf code.""" - -_PROTO_EXTENSION = ".proto" - -def get_proto_root(workspace_root): - """Gets the root protobuf directory. - - Args: - workspace_root: context.label.workspace_root - - Returns: - The directory relative to which generated include paths should be. - """ - if workspace_root: - return "/{}".format(workspace_root) - else: - return "" - -def _strip_proto_extension(proto_filename): - if not proto_filename.endswith(_PROTO_EXTENSION): - fail('"{}" does not end with "{}"'.format( - proto_filename, - _PROTO_EXTENSION, - )) - return proto_filename[:-len(_PROTO_EXTENSION)] - -def proto_path_to_generated_filename(proto_path, fmt_str): - """Calculates the name of a generated file for a protobuf path. - - For example, "examples/protos/helloworld.proto" might map to - "helloworld.pb.h". - - Args: - proto_path: The path to the .proto file. - fmt_str: A format string used to calculate the generated filename. For - example, "{}.pb.h" might be used to calculate a C++ header filename. - - Returns: - The generated filename. - """ - return fmt_str.format(_strip_proto_extension(proto_path)) - -def _get_include_directory(include): - directory = include.path - if directory.startswith("external"): - external_separator = directory.find("/") - repository_separator = directory.find("/", external_separator + 1) - return directory[:repository_separator] - else: - return "." - -def get_include_protoc_args(includes): - """Returns protoc args that imports protos relative to their import root. - - Args: - includes: A list of included proto files. - - Returns: - A list of arguments to be passed to protoc. For example, ["--proto_path=."]. - """ - return [ - "--proto_path={}".format(_get_include_directory(include)) - for include in includes - ] - -def get_plugin_args(plugin, flags, dir_out, generate_mocks): - """Returns arguments configuring protoc to use a plugin for a language. - - Args: - plugin: An executable file to run as the protoc plugin. - flags: The plugin flags to be passed to protoc. - dir_out: The output directory for the plugin. - generate_mocks: A bool indicating whether to generate mocks. - - Returns: - A list of protoc arguments configuring the plugin. - """ - augmented_flags = list(flags) - if generate_mocks: - augmented_flags.append("generate_mock_code=true") - return [ - "--plugin=protoc-gen-PLUGIN=" + plugin.path, - "--PLUGIN_out=" + ",".join(augmented_flags) + ":" + dir_out, - ] diff --git a/bazel/python_rules.bzl b/bazel/python_rules.bzl deleted file mode 100644 index bf6b4bec8d2..00000000000 --- a/bazel/python_rules.bzl +++ /dev/null @@ -1,203 +0,0 @@ -"""Generates and compiles Python gRPC stubs from proto_library rules.""" - -load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load( - "//bazel:protobuf.bzl", - "get_include_protoc_args", - "get_plugin_args", - "get_proto_root", - "proto_path_to_generated_filename", -) - -_GENERATED_PROTO_FORMAT = "{}_pb2.py" -_GENERATED_GRPC_PROTO_FORMAT = "{}_pb2_grpc.py" - -def _get_staged_proto_file(context, source_file): - if source_file.dirname == context.label.package: - return source_file - else: - copied_proto = context.actions.declare_file(source_file.basename) - context.actions.run_shell( - inputs = [source_file], - outputs = [copied_proto], - command = "cp {} {}".format(source_file.path, copied_proto.path), - mnemonic = "CopySourceProto", - ) - return copied_proto - -def _generate_py_impl(context): - protos = [] - for src in context.attr.deps: - for file in src.proto.direct_sources: - protos.append(_get_staged_proto_file(context, file)) - includes = [ - file - for src in context.attr.deps - for file in src.proto.transitive_imports - ] - proto_root = get_proto_root(context.label.workspace_root) - format_str = (_GENERATED_GRPC_PROTO_FORMAT if context.executable.plugin else _GENERATED_PROTO_FORMAT) - out_files = [ - context.actions.declare_file( - proto_path_to_generated_filename( - proto.basename, - format_str, - ), - ) - for proto in protos - ] - - arguments = [] - tools = [context.executable._protoc] - if context.executable.plugin: - arguments += get_plugin_args( - context.executable.plugin, - context.attr.flags, - context.genfiles_dir.path, - False, - ) - tools += [context.executable.plugin] - else: - arguments += [ - "--python_out={}:{}".format( - ",".join(context.attr.flags), - context.genfiles_dir.path, - ), - ] - - arguments += get_include_protoc_args(includes) - arguments += [ - "--proto_path={}".format(context.genfiles_dir.path) - for proto in protos - ] - for proto in protos: - massaged_path = proto.path - if massaged_path.startswith(context.genfiles_dir.path): - massaged_path = proto.path[len(context.genfiles_dir.path) + 1:] - arguments.append(massaged_path) - - well_known_proto_files = [] - if context.attr.well_known_protos: - well_known_proto_directory = context.attr.well_known_protos.files.to_list( - )[0].dirname - - arguments += ["-I{}".format(well_known_proto_directory + "/../..")] - well_known_proto_files = context.attr.well_known_protos.files.to_list() - - context.actions.run( - inputs = protos + includes + well_known_proto_files, - tools = tools, - outputs = out_files, - executable = context.executable._protoc, - arguments = arguments, - mnemonic = "ProtocInvocation", - ) - return struct(files = depset(out_files)) - -__generate_py = rule( - attrs = { - "deps": attr.label_list( - mandatory = True, - allow_empty = False, - providers = ["proto"], - ), - "plugin": attr.label( - executable = True, - providers = ["files_to_run"], - cfg = "host", - ), - "flags": attr.string_list( - mandatory = False, - allow_empty = True, - ), - "well_known_protos": attr.label(mandatory = False), - "_protoc": attr.label( - default = Label("//external:protocol_compiler"), - executable = True, - cfg = "host", - ), - }, - output_to_genfiles = True, - implementation = _generate_py_impl, -) - -def _generate_py(well_known_protos, **kwargs): - if well_known_protos: - __generate_py( - well_known_protos = "@com_google_protobuf//:well_known_protos", - **kwargs - ) - else: - __generate_py(**kwargs) - -_WELL_KNOWN_PROTO_LIBS = [ - "@com_google_protobuf//:any_proto", - "@com_google_protobuf//:api_proto", - "@com_google_protobuf//:compiler_plugin_proto", - "@com_google_protobuf//:descriptor_proto", - "@com_google_protobuf//:duration_proto", - "@com_google_protobuf//:empty_proto", - "@com_google_protobuf//:field_mask_proto", - "@com_google_protobuf//:source_context_proto", - "@com_google_protobuf//:struct_proto", - "@com_google_protobuf//:timestamp_proto", - "@com_google_protobuf//:type_proto", - "@com_google_protobuf//:wrappers_proto", -] - -def py_proto_library( - name, - deps, - well_known_protos = True, - proto_only = False, - **kwargs): - """Generate python code for a protobuf. - - Args: - name: The name of the target. - deps: A list of dependencies. Must contain a single element. - well_known_protos: A bool indicating whether or not to include well-known - protos. - proto_only: A bool indicating whether to generate vanilla protobuf code - or to also generate gRPC code. - """ - if len(deps) > 1: - fail("The supported length of 'deps' is 1.") - - codegen_target = "_{}_codegen".format(name) - codegen_grpc_target = "_{}_grpc_codegen".format(name) - - well_known_proto_rules = _WELL_KNOWN_PROTO_LIBS if well_known_protos else [] - - _generate_py( - name = codegen_target, - deps = deps, - well_known_protos = well_known_protos, - **kwargs - ) - - if not proto_only: - _generate_py( - name = codegen_grpc_target, - deps = deps, - plugin = "//:grpc_python_plugin", - well_known_protos = well_known_protos, - **kwargs - ) - - native.py_library( - name = name, - srcs = [ - ":{}".format(codegen_grpc_target), - ":{}".format(codegen_target), - ], - deps = [requirement("protobuf")], - **kwargs - ) - else: - native.py_library( - name = name, - srcs = [":{}".format(codegen_target), ":{}".format(codegen_target)], - deps = [requirement("protobuf")], - **kwargs - ) diff --git a/examples/BUILD b/examples/BUILD index d5fb6903d7c..d2b39b87f4d 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -16,8 +16,9 @@ licenses(["notice"]) # 3-clause BSD package(default_visibility = ["//visibility:public"]) +load("@grpc_python_dependencies//:requirements.bzl", "requirement") load("//bazel:grpc_build_system.bzl", "grpc_proto_library") -load("//bazel:python_rules.bzl", "py_proto_library") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") grpc_proto_library( name = "auth_sample", @@ -44,14 +45,11 @@ grpc_proto_library( srcs = ["protos/keyvaluestore.proto"], ) -proto_library( - name = "helloworld_proto_descriptor", - srcs = ["protos/helloworld.proto"], -) - py_proto_library( name = "py_helloworld", - deps = [":helloworld_proto_descriptor"], + protos = ["protos/helloworld.proto"], + with_grpc = True, + deps = [requirement('protobuf'),], ) cc_binary( diff --git a/examples/python/errors/client.py b/examples/python/errors/client.py index c762d798dc2..a79b8fce1bd 100644 --- a/examples/python/errors/client.py +++ b/examples/python/errors/client.py @@ -20,8 +20,8 @@ import grpc from grpc_status import rpc_status from google.rpc import error_details_pb2 -from examples import helloworld_pb2 -from examples import helloworld_pb2_grpc +from examples.protos import helloworld_pb2 +from examples.protos import helloworld_pb2_grpc _LOGGER = logging.getLogger(__name__) diff --git a/examples/python/errors/server.py b/examples/python/errors/server.py index 50d4a2ac671..f49586b848a 100644 --- a/examples/python/errors/server.py +++ b/examples/python/errors/server.py @@ -24,8 +24,8 @@ from grpc_status import rpc_status from google.protobuf import any_pb2 from google.rpc import code_pb2, status_pb2, error_details_pb2 -from examples import helloworld_pb2 -from examples import helloworld_pb2_grpc +from examples.protos import helloworld_pb2 +from examples.protos import helloworld_pb2_grpc _ONE_DAY_IN_SECONDS = 60 * 60 * 24 diff --git a/examples/python/errors/test/_error_handling_example_test.py b/examples/python/errors/test/_error_handling_example_test.py index 9eb81ba3742..a79ca45e2a1 100644 --- a/examples/python/errors/test/_error_handling_example_test.py +++ b/examples/python/errors/test/_error_handling_example_test.py @@ -26,7 +26,7 @@ import logging import grpc -from examples import helloworld_pb2_grpc +from examples.protos import helloworld_pb2_grpc from examples.python.errors import client as error_handling_client from examples.python.errors import server as error_handling_server diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD index 0e135f471f2..6de1e947d85 100644 --- a/examples/python/multiprocessing/BUILD +++ b/examples/python/multiprocessing/BUILD @@ -15,17 +15,12 @@ # limitations under the License. load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("//bazel:python_rules.bzl", "py_proto_library") - -proto_library( - name = "prime_proto", - srcs = ["prime.proto"] -) +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") py_proto_library( - name = "prime_proto_pb2", - deps = [":prime_proto"], - well_known_protos = False, + name = "prime_proto", + protos = ["prime.proto",], + deps = [requirement("protobuf")], ) py_binary( @@ -34,7 +29,7 @@ py_binary( srcs = ["client.py"], deps = [ "//src/python/grpcio/grpc:grpcio", - ":prime_proto_pb2", + ":prime_proto", ], default_python_version = "PY3", ) @@ -45,7 +40,7 @@ py_binary( srcs = ["server.py"], deps = [ "//src/python/grpcio/grpc:grpcio", - ":prime_proto_pb2" + ":prime_proto" ] + select({ "//conditions:default": [requirement("futures")], "//:python3": [], diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py index a0f076e894a..7c16b9bd4a1 100644 --- a/examples/python/wait_for_ready/wait_for_ready_example.py +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -22,8 +22,8 @@ import threading import grpc -from examples import helloworld_pb2 -from examples import helloworld_pb2_grpc +from examples.protos import helloworld_pb2 +from examples.protos import helloworld_pb2_grpc _LOGGER = logging.getLogger(__name__) _LOGGER.setLevel(logging.INFO) @@ -33,13 +33,10 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24 @contextmanager def get_free_loopback_tcp_port(): - if socket.has_ipv6: - tcp_socket = socket.socket(socket.AF_INET6) - else: - tcp_socket = socket.socket(socket.AF_INET) + tcp_socket = socket.socket(socket.AF_INET6) tcp_socket.bind(('', 0)) address_tuple = tcp_socket.getsockname() - yield "localhost:%s" % (address_tuple[1]) + yield "[::1]:%s" % (address_tuple[1]) tcp_socket.close() diff --git a/src/proto/grpc/channelz/BUILD b/src/proto/grpc/channelz/BUILD index 1d80ec23af1..b6b485e3e8d 100644 --- a/src/proto/grpc/channelz/BUILD +++ b/src/proto/grpc/channelz/BUILD @@ -25,11 +25,6 @@ grpc_proto_library( well_known_protos = True, ) -proto_library( - name = "channelz_proto_descriptors", - srcs = ["channelz.proto"], -) - filegroup( name = "channelz_proto_file", srcs = [ diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD index fc58e8a1770..38a7d992e06 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD @@ -23,11 +23,6 @@ grpc_proto_library( srcs = ["health.proto"], ) -proto_library( - name = "health_proto_descriptor", - srcs = ["health.proto"], -) - filegroup( name = "health_proto_file", srcs = [ diff --git a/src/proto/grpc/reflection/v1alpha/BUILD b/src/proto/grpc/reflection/v1alpha/BUILD index 5424c0d867e..4d919d029ee 100644 --- a/src/proto/grpc/reflection/v1alpha/BUILD +++ b/src/proto/grpc/reflection/v1alpha/BUILD @@ -23,11 +23,6 @@ grpc_proto_library( srcs = ["reflection.proto"], ) -proto_library( - name = "reflection_proto_descriptor", - srcs = ["reflection.proto"], -) - filegroup( name = "reflection_proto_file", srcs = [ diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD index 16e47d81061..9876d5160a1 100644 --- a/src/proto/grpc/testing/BUILD +++ b/src/proto/grpc/testing/BUILD @@ -16,7 +16,7 @@ licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_package") load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("//bazel:python_rules.bzl", "py_proto_library") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") grpc_package(name = "testing", visibility = "public") @@ -61,14 +61,13 @@ grpc_proto_library( has_services = False, ) -proto_library( - name = "empty_proto_descriptor", - srcs = ["empty.proto"], -) - py_proto_library( name = "py_empty_proto", - deps = [":empty_proto_descriptor"], + protos = ["empty.proto",], + with_grpc = True, + deps = [ + requirement('protobuf'), + ], ) grpc_proto_library( @@ -77,14 +76,13 @@ grpc_proto_library( has_services = False, ) -proto_library( - name = "messages_proto_descriptor", - srcs = ["messages.proto"], -) - py_proto_library( name = "py_messages_proto", - deps = [":messages_proto_descriptor"], + protos = ["messages.proto",], + with_grpc = True, + deps = [ + requirement('protobuf'), + ], ) grpc_proto_library( @@ -146,19 +144,16 @@ grpc_proto_library( ], ) -proto_library( - name = "test_proto_descriptor", - srcs = ["test.proto"], - deps = [ - ":empty_proto_descriptor", - ":messages_proto_descriptor", - ], -) - py_proto_library( name = "py_test_proto", + protos = ["test.proto",], + with_grpc = True, deps = [ - ":test_proto_descriptor", + requirement('protobuf'), + ], + proto_deps = [ + ":py_empty_proto", + ":py_messages_proto", ] ) diff --git a/src/proto/grpc/testing/proto2/BUILD.bazel b/src/proto/grpc/testing/proto2/BUILD.bazel index e939c523a64..c4c4f004efb 100644 --- a/src/proto/grpc/testing/proto2/BUILD.bazel +++ b/src/proto/grpc/testing/proto2/BUILD.bazel @@ -1,32 +1,30 @@ load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) -load("//bazel:python_rules.bzl", "py_proto_library") - -proto_library( - name = "empty2_proto_descriptor", - srcs = ["empty2.proto"], -) py_proto_library( name = "empty2_proto", - deps = [ - ":empty2_proto_descriptor", + protos = [ + "empty2.proto", ], -) - -proto_library( - name = "empty2_extensions_proto_descriptor", - srcs = ["empty2_extensions.proto"], + with_grpc = True, deps = [ - ":empty2_proto_descriptor", - ] + requirement('protobuf'), + ], ) py_proto_library( name = "empty2_extensions_proto", + protos = [ + "empty2_extensions.proto", + ], + proto_deps = [ + ":empty2_proto", + ], + with_grpc = True, deps = [ - ":empty2_extensions_proto_descriptor", + requirement('protobuf'), ], ) diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel index eccc166577d..aae8cedb760 100644 --- a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel +++ b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel @@ -1,10 +1,30 @@ -load("//bazel:python_rules.bzl", "py_proto_library") +load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") + package(default_visibility = ["//visibility:public"]) +genrule( + name = "mv_channelz_proto", + srcs = [ + "//src/proto/grpc/channelz:channelz_proto_file", + ], + outs = ["channelz.proto",], + cmd = "cp $< $@", +) + py_proto_library( name = "py_channelz_proto", - well_known_protos = True, - deps = ["//src/proto/grpc/channelz:channelz_proto_descriptors"], + protos = ["mv_channelz_proto",], + imports = [ + "external/com_google_protobuf/src/", + ], + inputs = [ + "@com_google_protobuf//:well_known_protos", + ], + with_grpc = True, + deps = [ + requirement('protobuf'), + ], ) py_library( diff --git a/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel b/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel index 9e4fff34581..ce3121fa90e 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel +++ b/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel @@ -1,9 +1,24 @@ -load("//bazel:python_rules.bzl", "py_proto_library") +load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") + package(default_visibility = ["//visibility:public"]) +genrule( + name = "mv_health_proto", + srcs = [ + "//src/proto/grpc/health/v1:health_proto_file", + ], + outs = ["health.proto",], + cmd = "cp $< $@", +) + py_proto_library( name = "py_health_proto", - deps = ["//src/proto/grpc/health/v1:health_proto_descriptor",], + protos = [":mv_health_proto",], + with_grpc = True, + deps = [ + requirement('protobuf'), + ], ) py_library( diff --git a/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel b/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel index 6aaa4dd3bdd..3a2ba263715 100644 --- a/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel +++ b/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel @@ -1,11 +1,24 @@ -load("//bazel:python_rules.bzl", "py_proto_library") load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) +genrule( + name = "mv_reflection_proto", + srcs = [ + "//src/proto/grpc/reflection/v1alpha:reflection_proto_file", + ], + outs = ["reflection.proto",], + cmd = "cp $< $@", +) + py_proto_library( name = "py_reflection_proto", - deps = ["//src/proto/grpc/reflection/v1alpha:reflection_proto_descriptor",], + protos = [":mv_reflection_proto",], + with_grpc = True, + deps = [ + requirement('protobuf'), + ], ) py_library( diff --git a/src/python/grpcio_tests/tests/reflection/BUILD.bazel b/src/python/grpcio_tests/tests/reflection/BUILD.bazel index b635b721631..c0efb0b7cef 100644 --- a/src/python/grpcio_tests/tests/reflection/BUILD.bazel +++ b/src/python/grpcio_tests/tests/reflection/BUILD.bazel @@ -14,7 +14,6 @@ py_test( "//src/python/grpcio_tests/tests/unit:test_common", "//src/proto/grpc/testing:py_empty_proto", "//src/proto/grpc/testing/proto2:empty2_extensions_proto", - "//src/proto/grpc/testing/proto2:empty2_proto", requirement('protobuf'), ], imports=["../../",], diff --git a/tools/distrib/bazel_style.cfg b/tools/distrib/bazel_style.cfg deleted file mode 100644 index a5a1fea4aba..00000000000 --- a/tools/distrib/bazel_style.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[style] -based_on_style = google -allow_split_before_dict_value = False -spaces_around_default_or_named_assign = True diff --git a/tools/distrib/format_bazel.sh b/tools/distrib/format_bazel.sh deleted file mode 100755 index ee230118efb..00000000000 --- a/tools/distrib/format_bazel.sh +++ /dev/null @@ -1,39 +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. - -set=-ex - -VIRTUAL_ENV=bazel_format_virtual_environment - -CONFIG_PATH="$(dirname ${0})/bazel_style.cfg" - -python -m virtualenv ${VIRTUAL_ENV} -PYTHON=${VIRTUAL_ENV}/bin/python -"$PYTHON" -m pip install --upgrade pip==10.0.1 -"$PYTHON" -m pip install --upgrade futures -"$PYTHON" -m pip install yapf==0.20.0 - -pushd "$(dirname "${0}")/../.." -FILES=$(find . -path ./third_party -prune -o -name '*.bzl' -print) -echo "${FILES}" | xargs "$PYTHON" -m yapf -i --style="${CONFIG_PATH}" - -if ! which buildifier &>/dev/null; then - echo 'buildifer must be installed.' >/dev/stderr - exit 1 -fi - -echo "${FILES}" | xargs buildifier --type=bzl - -popd diff --git a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh index 24598f43f02..3dd0167b7c0 100755 --- a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh +++ b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh @@ -24,4 +24,5 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc && git submodule update --init --reference /var/local/jenkins/grpc/${name} \ ${name}') cd /var/local/git/grpc -bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/... +#TODO(yfen): add back examples/... to build targets once python rules issues are resolved +bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... 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 d844cff7f9a..3ca4673ca08 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 @@ -23,9 +23,10 @@ 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 -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/... +#TODO(yfen): temporarily disabled all python bazel tests due to incompatibility with bazel 0.23.2 +#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 9073d6d5b56ccd1f4bbb836dbd0c9ae77386cfa7 Mon Sep 17 00:00:00 2001 From: John Luo Date: Tue, 30 Apr 2019 00:26:57 -0700 Subject: [PATCH 2030/2143] Migrate interceptor types for server-side interceptors --- .../Interceptors/ClientInterceptorContext.cs | 0 .../Interceptors/Interceptor.cs | 0 src/csharp/Grpc.Core/ForwardedTypes.cs | 10 ++++++---- 3 files changed, 6 insertions(+), 4 deletions(-) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Interceptors/ClientInterceptorContext.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Interceptors/Interceptor.cs (100%) diff --git a/src/csharp/Grpc.Core/Interceptors/ClientInterceptorContext.cs b/src/csharp/Grpc.Core.Api/Interceptors/ClientInterceptorContext.cs similarity index 100% rename from src/csharp/Grpc.Core/Interceptors/ClientInterceptorContext.cs rename to src/csharp/Grpc.Core.Api/Interceptors/ClientInterceptorContext.cs diff --git a/src/csharp/Grpc.Core/Interceptors/Interceptor.cs b/src/csharp/Grpc.Core.Api/Interceptors/Interceptor.cs similarity index 100% rename from src/csharp/Grpc.Core/Interceptors/Interceptor.cs rename to src/csharp/Grpc.Core.Api/Interceptors/Interceptor.cs diff --git a/src/csharp/Grpc.Core/ForwardedTypes.cs b/src/csharp/Grpc.Core/ForwardedTypes.cs index 3df44d167be..8b42cae3890 100644 --- a/src/csharp/Grpc.Core/ForwardedTypes.cs +++ b/src/csharp/Grpc.Core/ForwardedTypes.cs @@ -32,16 +32,18 @@ using Grpc.Core.Utils; [assembly:TypeForwardedToAttribute(typeof(AuthContext))] [assembly:TypeForwardedToAttribute(typeof(AsyncAuthInterceptor))] [assembly:TypeForwardedToAttribute(typeof(AuthInterceptorContext))] -[assembly: TypeForwardedToAttribute(typeof(CallCredentials))] -[assembly: TypeForwardedToAttribute(typeof(CallFlags))] -[assembly: TypeForwardedToAttribute(typeof(CallInvoker))] -[assembly: TypeForwardedToAttribute(typeof(CallOptions))] +[assembly:TypeForwardedToAttribute(typeof(CallCredentials))] +[assembly:TypeForwardedToAttribute(typeof(CallFlags))] +[assembly:TypeForwardedToAttribute(typeof(CallInvoker))] +[assembly:TypeForwardedToAttribute(typeof(CallOptions))] +[assembly:TypeForwardedToAttribute(typeof(ClientInterceptorContext<,>))] [assembly:TypeForwardedToAttribute(typeof(ContextPropagationOptions))] [assembly:TypeForwardedToAttribute(typeof(ContextPropagationToken))] [assembly:TypeForwardedToAttribute(typeof(DeserializationContext))] [assembly:TypeForwardedToAttribute(typeof(IAsyncStreamReader<>))] [assembly:TypeForwardedToAttribute(typeof(IAsyncStreamWriter<>))] [assembly:TypeForwardedToAttribute(typeof(IClientStreamWriter<>))] +[assembly:TypeForwardedToAttribute(typeof(Interceptor))] [assembly:TypeForwardedToAttribute(typeof(IServerStreamWriter<>))] [assembly:TypeForwardedToAttribute(typeof(Marshaller<>))] [assembly:TypeForwardedToAttribute(typeof(Marshallers))] From f52a743e34f68de26d681eb7b6d3436d72b96645 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 30 Apr 2019 01:43:23 -0700 Subject: [PATCH 2031/2143] Missed using --- src/csharp/Grpc.Core/ForwardedTypes.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/csharp/Grpc.Core/ForwardedTypes.cs b/src/csharp/Grpc.Core/ForwardedTypes.cs index 8b42cae3890..ab5f5a87c67 100644 --- a/src/csharp/Grpc.Core/ForwardedTypes.cs +++ b/src/csharp/Grpc.Core/ForwardedTypes.cs @@ -18,6 +18,7 @@ using System.Runtime.CompilerServices; using Grpc.Core; +using Grpc.Core.Interceptors; using Grpc.Core.Internal; using Grpc.Core.Utils; From 930cec4e27347a2cc852954917e0263b27d7480b Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 30 Apr 2019 11:17:11 -0700 Subject: [PATCH 2032/2143] Revert "Merge pull request #18912 from grpc/revert-bazel-changes" This reverts commit c9a259aa3a5a8081fc8de88108759db07d3a4379, reversing changes made to 9c882bc7253a91262d662409453c5fc70b019d20. --- .gitignore | 1 + WORKSPACE | 7 - bazel/generate_cc.bzl | 204 +++++++++++------- bazel/grpc_python_deps.bzl | 14 +- bazel/protobuf.bzl | 84 ++++++++ bazel/python_rules.bzl | 203 +++++++++++++++++ examples/BUILD | 12 +- examples/python/errors/client.py | 4 +- examples/python/errors/server.py | 4 +- .../test/_error_handling_example_test.py | 2 +- examples/python/multiprocessing/BUILD | 17 +- .../wait_for_ready/wait_for_ready_example.py | 11 +- src/proto/grpc/channelz/BUILD | 5 + src/proto/grpc/health/v1/BUILD | 5 + src/proto/grpc/reflection/v1alpha/BUILD | 5 + src/proto/grpc/testing/BUILD | 41 ++-- src/proto/grpc/testing/proto2/BUILD.bazel | 30 +-- .../grpc_channelz/v1/BUILD.bazel | 26 +-- .../grpc_health/v1/BUILD.bazel | 19 +- .../grpc_reflection/v1alpha/BUILD.bazel | 17 +- .../grpcio_tests/tests/reflection/BUILD.bazel | 1 + tools/distrib/bazel_style.cfg | 4 + tools/distrib/format_bazel.sh | 39 ++++ .../linux/grpc_bazel_build_in_docker.sh | 3 +- .../linux/grpc_python_bazel_test_in_docker.sh | 13 +- 25 files changed, 561 insertions(+), 210 deletions(-) create mode 100644 bazel/protobuf.bzl create mode 100644 bazel/python_rules.bzl create mode 100644 tools/distrib/bazel_style.cfg create mode 100755 tools/distrib/format_bazel.sh diff --git a/.gitignore b/.gitignore index 0d2647e61b6..7b4c5d36cb4 100644 --- a/.gitignore +++ b/.gitignore @@ -115,6 +115,7 @@ bazel-genfiles bazel-grpc bazel-out bazel-testlogs +bazel_format_virtual_environment/ # Debug output gdb.txt diff --git a/WORKSPACE b/WORKSPACE index fcf5b5d6d10..2db3c5db2ff 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -18,13 +18,6 @@ register_toolchains( "//third_party/toolchains/bazel_0.23.2_rbe_windows:cc-toolchain-x64_windows", ) -# TODO(https://github.com/grpc/grpc/issues/18331): Move off of this dependency. -git_repository( - name = "org_pubref_rules_protobuf", - remote = "https://github.com/ghostwriternr/rules_protobuf", - tag = "v0.8.2.1-alpha", -) - git_repository( name = "io_bazel_rules_python", commit = "8b5d0683a7d878b28fffe464779c8a53659fc645", diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index 8f30c84f6b9..82f5cbad310 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -4,81 +4,132 @@ This is an internal rule used by cc_grpc_library, and shouldn't be used directly. """ +load( + "//bazel:protobuf.bzl", + "get_include_protoc_args", + "get_plugin_args", + "get_proto_root", + "proto_path_to_generated_filename", +) + +_GRPC_PROTO_HEADER_FMT = "{}.grpc.pb.h" +_GRPC_PROTO_SRC_FMT = "{}.grpc.pb.cc" +_GRPC_PROTO_MOCK_HEADER_FMT = "{}_mock.grpc.pb.h" +_PROTO_HEADER_FMT = "{}.pb.h" +_PROTO_SRC_FMT = "{}.pb.cc" + +def _strip_package_from_path(label_package, path): + if len(label_package) == 0: + return path + if not path.startswith(label_package + "/"): + fail("'{}' does not lie within '{}'.".format(path, label_package)) + return path[len(label_package + "/"):] + +def _join_directories(directories): + massaged_directories = [directory for directory in directories if len(directory) != 0] + return "/".join(massaged_directories) + def generate_cc_impl(ctx): - """Implementation of the generate_cc rule.""" - protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources] - includes = [f for src in ctx.attr.srcs for f in src.proto.transitive_imports] - outs = [] - # label_len is length of the path from WORKSPACE root to the location of this build file - label_len = 0 - # proto_root is the directory relative to which generated include paths should be - proto_root = "" - if ctx.label.package: - # The +1 is for the trailing slash. - label_len += len(ctx.label.package) + 1 - if ctx.label.workspace_root: - label_len += len(ctx.label.workspace_root) + 1 - proto_root = "/" + ctx.label.workspace_root + """Implementation of the generate_cc rule.""" + protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources] + includes = [ + f + for src in ctx.attr.srcs + for f in src.proto.transitive_imports + ] + outs = [] + proto_root = get_proto_root( + ctx.label.workspace_root, + ) - if ctx.executable.plugin: - outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.h" for proto in protos] - outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.cc" for proto in protos] - if ctx.attr.generate_mocks: - outs += [proto.path[label_len:-len(".proto")] + "_mock.grpc.pb.h" for proto in protos] - 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.actions.declare_file(out) for out in outs] - dir_out = str(ctx.genfiles_dir.path + proto_root) - - arguments = [] - if ctx.executable.plugin: - arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path] - flags = list(ctx.attr.flags) - if ctx.attr.generate_mocks: - flags.append("generate_mock_code=true") - arguments += ["--PLUGIN_out=" + ",".join(flags) + ":" + dir_out] - tools = [ctx.executable.plugin] - else: - arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] - tools = [] - - # Import protos relative to their workspace root so that protoc prints the - # right include paths. - for include in includes: - directory = include.path - if directory.startswith("external"): - external_sep = directory.find("/") - repository_sep = directory.find("/", external_sep + 1) - arguments += ["--proto_path=" + directory[:repository_sep]] + label_package = _join_directories([ctx.label.workspace_root, ctx.label.package]) + if ctx.executable.plugin: + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _GRPC_PROTO_HEADER_FMT, + ) + for proto in protos + ] + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _GRPC_PROTO_SRC_FMT, + ) + for proto in protos + ] + if ctx.attr.generate_mocks: + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _GRPC_PROTO_MOCK_HEADER_FMT, + ) + for proto in protos + ] else: - arguments += ["--proto_path=."] - # Include the output directory so that protoc puts the generated code in the - # right directory. - arguments += ["--proto_path={0}{1}".format(dir_out, proto_root)] - arguments += [proto.path for proto in protos] + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _PROTO_HEADER_FMT, + ) + for proto in protos + ] + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _PROTO_SRC_FMT, + ) + for proto in protos + ] + out_files = [ctx.actions.declare_file(out) for out in outs] + dir_out = str(ctx.genfiles_dir.path + proto_root) - # create a list of well known proto files if the argument is non-None - well_known_proto_files = [] - if ctx.attr.well_known_protos: - f = ctx.attr.well_known_protos.files.to_list()[0].dirname - if f != "external/com_google_protobuf/src/google/protobuf": - print("Error: Only @com_google_protobuf//:well_known_protos is supported") + arguments = [] + if ctx.executable.plugin: + arguments += get_plugin_args( + ctx.executable.plugin, + ctx.attr.flags, + dir_out, + ctx.attr.generate_mocks, + ) + tools = [ctx.executable.plugin] else: - # f points to "external/com_google_protobuf/src/google/protobuf" - # add -I argument to protoc so it knows where to look for the proto files. - arguments += ["-I{0}".format(f + "/../..")] - well_known_proto_files = [f for f in ctx.attr.well_known_protos.files] + arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] + tools = [] - ctx.actions.run( - inputs = protos + includes + well_known_proto_files, - tools = tools, - outputs = out_files, - executable = ctx.executable._protoc, - arguments = arguments, - ) + arguments += get_include_protoc_args(includes) - return struct(files=depset(out_files)) + # Include the output directory so that protoc puts the generated code in the + # right directory. + arguments += ["--proto_path={0}{1}".format(dir_out, proto_root)] + arguments += [proto.path for proto in protos] + + # create a list of well known proto files if the argument is non-None + well_known_proto_files = [] + if ctx.attr.well_known_protos: + f = ctx.attr.well_known_protos.files.to_list()[0].dirname + if f != "external/com_google_protobuf/src/google/protobuf": + print( + "Error: Only @com_google_protobuf//:well_known_protos is supported", + ) + else: + # f points to "external/com_google_protobuf/src/google/protobuf" + # add -I argument to protoc so it knows where to look for the proto files. + arguments += ["-I{0}".format(f + "/../..")] + well_known_proto_files = [ + f + for f in ctx.attr.well_known_protos.files + ] + + ctx.actions.run( + inputs = protos + includes + well_known_proto_files, + tools = tools, + outputs = out_files, + executable = ctx.executable._protoc, + arguments = arguments, + ) + + return struct(files = depset(out_files)) _generate_cc = rule( attrs = { @@ -96,10 +147,8 @@ _generate_cc = rule( mandatory = False, allow_empty = True, ), - "well_known_protos" : attr.label( - mandatory = False, - ), - "generate_mocks" : attr.bool( + "well_known_protos": attr.label(mandatory = False), + "generate_mocks": attr.bool( default = False, mandatory = False, ), @@ -115,7 +164,10 @@ _generate_cc = rule( ) def generate_cc(well_known_protos, **kwargs): - if well_known_protos: - _generate_cc(well_known_protos="@com_google_protobuf//:well_known_protos", **kwargs) - else: - _generate_cc(**kwargs) + if well_known_protos: + _generate_cc( + well_known_protos = "@com_google_protobuf//:well_known_protos", + **kwargs + ) + else: + _generate_cc(**kwargs) diff --git a/bazel/grpc_python_deps.bzl b/bazel/grpc_python_deps.bzl index ec3df19e03a..91438f3927b 100644 --- a/bazel/grpc_python_deps.bzl +++ b/bazel/grpc_python_deps.bzl @@ -1,16 +1,8 @@ load("//third_party/py:python_configure.bzl", "python_configure") load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories") load("@grpc_python_dependencies//:requirements.bzl", "pip_install") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories") def grpc_python_deps(): - # TODO(https://github.com/grpc/grpc/issues/18256): Remove conditional. - if hasattr(native, "http_archive"): - python_configure(name = "local_config_python") - pip_repositories() - pip_install() - py_proto_repositories() - else: - print("Building Python gRPC with bazel 23.0+ is disabled pending " + - "resolution of https://github.com/grpc/grpc/issues/18256.") - + python_configure(name = "local_config_python") + pip_repositories() + pip_install() diff --git a/bazel/protobuf.bzl b/bazel/protobuf.bzl new file mode 100644 index 00000000000..bddd0d70c7f --- /dev/null +++ b/bazel/protobuf.bzl @@ -0,0 +1,84 @@ +"""Utility functions for generating protobuf code.""" + +_PROTO_EXTENSION = ".proto" + +def get_proto_root(workspace_root): + """Gets the root protobuf directory. + + Args: + workspace_root: context.label.workspace_root + + Returns: + The directory relative to which generated include paths should be. + """ + if workspace_root: + return "/{}".format(workspace_root) + else: + return "" + +def _strip_proto_extension(proto_filename): + if not proto_filename.endswith(_PROTO_EXTENSION): + fail('"{}" does not end with "{}"'.format( + proto_filename, + _PROTO_EXTENSION, + )) + return proto_filename[:-len(_PROTO_EXTENSION)] + +def proto_path_to_generated_filename(proto_path, fmt_str): + """Calculates the name of a generated file for a protobuf path. + + For example, "examples/protos/helloworld.proto" might map to + "helloworld.pb.h". + + Args: + proto_path: The path to the .proto file. + fmt_str: A format string used to calculate the generated filename. For + example, "{}.pb.h" might be used to calculate a C++ header filename. + + Returns: + The generated filename. + """ + return fmt_str.format(_strip_proto_extension(proto_path)) + +def _get_include_directory(include): + directory = include.path + if directory.startswith("external"): + external_separator = directory.find("/") + repository_separator = directory.find("/", external_separator + 1) + return directory[:repository_separator] + else: + return "." + +def get_include_protoc_args(includes): + """Returns protoc args that imports protos relative to their import root. + + Args: + includes: A list of included proto files. + + Returns: + A list of arguments to be passed to protoc. For example, ["--proto_path=."]. + """ + return [ + "--proto_path={}".format(_get_include_directory(include)) + for include in includes + ] + +def get_plugin_args(plugin, flags, dir_out, generate_mocks): + """Returns arguments configuring protoc to use a plugin for a language. + + Args: + plugin: An executable file to run as the protoc plugin. + flags: The plugin flags to be passed to protoc. + dir_out: The output directory for the plugin. + generate_mocks: A bool indicating whether to generate mocks. + + Returns: + A list of protoc arguments configuring the plugin. + """ + augmented_flags = list(flags) + if generate_mocks: + augmented_flags.append("generate_mock_code=true") + return [ + "--plugin=protoc-gen-PLUGIN=" + plugin.path, + "--PLUGIN_out=" + ",".join(augmented_flags) + ":" + dir_out, + ] diff --git a/bazel/python_rules.bzl b/bazel/python_rules.bzl new file mode 100644 index 00000000000..bf6b4bec8d2 --- /dev/null +++ b/bazel/python_rules.bzl @@ -0,0 +1,203 @@ +"""Generates and compiles Python gRPC stubs from proto_library rules.""" + +load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load( + "//bazel:protobuf.bzl", + "get_include_protoc_args", + "get_plugin_args", + "get_proto_root", + "proto_path_to_generated_filename", +) + +_GENERATED_PROTO_FORMAT = "{}_pb2.py" +_GENERATED_GRPC_PROTO_FORMAT = "{}_pb2_grpc.py" + +def _get_staged_proto_file(context, source_file): + if source_file.dirname == context.label.package: + return source_file + else: + copied_proto = context.actions.declare_file(source_file.basename) + context.actions.run_shell( + inputs = [source_file], + outputs = [copied_proto], + command = "cp {} {}".format(source_file.path, copied_proto.path), + mnemonic = "CopySourceProto", + ) + return copied_proto + +def _generate_py_impl(context): + protos = [] + for src in context.attr.deps: + for file in src.proto.direct_sources: + protos.append(_get_staged_proto_file(context, file)) + includes = [ + file + for src in context.attr.deps + for file in src.proto.transitive_imports + ] + proto_root = get_proto_root(context.label.workspace_root) + format_str = (_GENERATED_GRPC_PROTO_FORMAT if context.executable.plugin else _GENERATED_PROTO_FORMAT) + out_files = [ + context.actions.declare_file( + proto_path_to_generated_filename( + proto.basename, + format_str, + ), + ) + for proto in protos + ] + + arguments = [] + tools = [context.executable._protoc] + if context.executable.plugin: + arguments += get_plugin_args( + context.executable.plugin, + context.attr.flags, + context.genfiles_dir.path, + False, + ) + tools += [context.executable.plugin] + else: + arguments += [ + "--python_out={}:{}".format( + ",".join(context.attr.flags), + context.genfiles_dir.path, + ), + ] + + arguments += get_include_protoc_args(includes) + arguments += [ + "--proto_path={}".format(context.genfiles_dir.path) + for proto in protos + ] + for proto in protos: + massaged_path = proto.path + if massaged_path.startswith(context.genfiles_dir.path): + massaged_path = proto.path[len(context.genfiles_dir.path) + 1:] + arguments.append(massaged_path) + + well_known_proto_files = [] + if context.attr.well_known_protos: + well_known_proto_directory = context.attr.well_known_protos.files.to_list( + )[0].dirname + + arguments += ["-I{}".format(well_known_proto_directory + "/../..")] + well_known_proto_files = context.attr.well_known_protos.files.to_list() + + context.actions.run( + inputs = protos + includes + well_known_proto_files, + tools = tools, + outputs = out_files, + executable = context.executable._protoc, + arguments = arguments, + mnemonic = "ProtocInvocation", + ) + return struct(files = depset(out_files)) + +__generate_py = rule( + attrs = { + "deps": attr.label_list( + mandatory = True, + allow_empty = False, + providers = ["proto"], + ), + "plugin": attr.label( + executable = True, + providers = ["files_to_run"], + cfg = "host", + ), + "flags": attr.string_list( + mandatory = False, + allow_empty = True, + ), + "well_known_protos": attr.label(mandatory = False), + "_protoc": attr.label( + default = Label("//external:protocol_compiler"), + executable = True, + cfg = "host", + ), + }, + output_to_genfiles = True, + implementation = _generate_py_impl, +) + +def _generate_py(well_known_protos, **kwargs): + if well_known_protos: + __generate_py( + well_known_protos = "@com_google_protobuf//:well_known_protos", + **kwargs + ) + else: + __generate_py(**kwargs) + +_WELL_KNOWN_PROTO_LIBS = [ + "@com_google_protobuf//:any_proto", + "@com_google_protobuf//:api_proto", + "@com_google_protobuf//:compiler_plugin_proto", + "@com_google_protobuf//:descriptor_proto", + "@com_google_protobuf//:duration_proto", + "@com_google_protobuf//:empty_proto", + "@com_google_protobuf//:field_mask_proto", + "@com_google_protobuf//:source_context_proto", + "@com_google_protobuf//:struct_proto", + "@com_google_protobuf//:timestamp_proto", + "@com_google_protobuf//:type_proto", + "@com_google_protobuf//:wrappers_proto", +] + +def py_proto_library( + name, + deps, + well_known_protos = True, + proto_only = False, + **kwargs): + """Generate python code for a protobuf. + + Args: + name: The name of the target. + deps: A list of dependencies. Must contain a single element. + well_known_protos: A bool indicating whether or not to include well-known + protos. + proto_only: A bool indicating whether to generate vanilla protobuf code + or to also generate gRPC code. + """ + if len(deps) > 1: + fail("The supported length of 'deps' is 1.") + + codegen_target = "_{}_codegen".format(name) + codegen_grpc_target = "_{}_grpc_codegen".format(name) + + well_known_proto_rules = _WELL_KNOWN_PROTO_LIBS if well_known_protos else [] + + _generate_py( + name = codegen_target, + deps = deps, + well_known_protos = well_known_protos, + **kwargs + ) + + if not proto_only: + _generate_py( + name = codegen_grpc_target, + deps = deps, + plugin = "//:grpc_python_plugin", + well_known_protos = well_known_protos, + **kwargs + ) + + native.py_library( + name = name, + srcs = [ + ":{}".format(codegen_grpc_target), + ":{}".format(codegen_target), + ], + deps = [requirement("protobuf")], + **kwargs + ) + else: + native.py_library( + name = name, + srcs = [":{}".format(codegen_target), ":{}".format(codegen_target)], + deps = [requirement("protobuf")], + **kwargs + ) diff --git a/examples/BUILD b/examples/BUILD index d2b39b87f4d..d5fb6903d7c 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -16,9 +16,8 @@ licenses(["notice"]) # 3-clause BSD package(default_visibility = ["//visibility:public"]) -load("@grpc_python_dependencies//:requirements.bzl", "requirement") load("//bazel:grpc_build_system.bzl", "grpc_proto_library") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") +load("//bazel:python_rules.bzl", "py_proto_library") grpc_proto_library( name = "auth_sample", @@ -45,11 +44,14 @@ grpc_proto_library( srcs = ["protos/keyvaluestore.proto"], ) +proto_library( + name = "helloworld_proto_descriptor", + srcs = ["protos/helloworld.proto"], +) + py_proto_library( name = "py_helloworld", - protos = ["protos/helloworld.proto"], - with_grpc = True, - deps = [requirement('protobuf'),], + deps = [":helloworld_proto_descriptor"], ) cc_binary( diff --git a/examples/python/errors/client.py b/examples/python/errors/client.py index a79b8fce1bd..c762d798dc2 100644 --- a/examples/python/errors/client.py +++ b/examples/python/errors/client.py @@ -20,8 +20,8 @@ import grpc from grpc_status import rpc_status from google.rpc import error_details_pb2 -from examples.protos import helloworld_pb2 -from examples.protos import helloworld_pb2_grpc +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc _LOGGER = logging.getLogger(__name__) diff --git a/examples/python/errors/server.py b/examples/python/errors/server.py index f49586b848a..50d4a2ac671 100644 --- a/examples/python/errors/server.py +++ b/examples/python/errors/server.py @@ -24,8 +24,8 @@ from grpc_status import rpc_status from google.protobuf import any_pb2 from google.rpc import code_pb2, status_pb2, error_details_pb2 -from examples.protos import helloworld_pb2 -from examples.protos import helloworld_pb2_grpc +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc _ONE_DAY_IN_SECONDS = 60 * 60 * 24 diff --git a/examples/python/errors/test/_error_handling_example_test.py b/examples/python/errors/test/_error_handling_example_test.py index a79ca45e2a1..9eb81ba3742 100644 --- a/examples/python/errors/test/_error_handling_example_test.py +++ b/examples/python/errors/test/_error_handling_example_test.py @@ -26,7 +26,7 @@ import logging import grpc -from examples.protos import helloworld_pb2_grpc +from examples import helloworld_pb2_grpc from examples.python.errors import client as error_handling_client from examples.python.errors import server as error_handling_server diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD index 6de1e947d85..0e135f471f2 100644 --- a/examples/python/multiprocessing/BUILD +++ b/examples/python/multiprocessing/BUILD @@ -15,12 +15,17 @@ # limitations under the License. load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") +load("//bazel:python_rules.bzl", "py_proto_library") + +proto_library( + name = "prime_proto", + srcs = ["prime.proto"] +) py_proto_library( - name = "prime_proto", - protos = ["prime.proto",], - deps = [requirement("protobuf")], + name = "prime_proto_pb2", + deps = [":prime_proto"], + well_known_protos = False, ) py_binary( @@ -29,7 +34,7 @@ py_binary( srcs = ["client.py"], deps = [ "//src/python/grpcio/grpc:grpcio", - ":prime_proto", + ":prime_proto_pb2", ], default_python_version = "PY3", ) @@ -40,7 +45,7 @@ py_binary( srcs = ["server.py"], deps = [ "//src/python/grpcio/grpc:grpcio", - ":prime_proto" + ":prime_proto_pb2" ] + select({ "//conditions:default": [requirement("futures")], "//:python3": [], diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py index 7c16b9bd4a1..a0f076e894a 100644 --- a/examples/python/wait_for_ready/wait_for_ready_example.py +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -22,8 +22,8 @@ import threading import grpc -from examples.protos import helloworld_pb2 -from examples.protos import helloworld_pb2_grpc +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc _LOGGER = logging.getLogger(__name__) _LOGGER.setLevel(logging.INFO) @@ -33,10 +33,13 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24 @contextmanager def get_free_loopback_tcp_port(): - tcp_socket = socket.socket(socket.AF_INET6) + if socket.has_ipv6: + tcp_socket = socket.socket(socket.AF_INET6) + else: + tcp_socket = socket.socket(socket.AF_INET) tcp_socket.bind(('', 0)) address_tuple = tcp_socket.getsockname() - yield "[::1]:%s" % (address_tuple[1]) + yield "localhost:%s" % (address_tuple[1]) tcp_socket.close() diff --git a/src/proto/grpc/channelz/BUILD b/src/proto/grpc/channelz/BUILD index b6b485e3e8d..1d80ec23af1 100644 --- a/src/proto/grpc/channelz/BUILD +++ b/src/proto/grpc/channelz/BUILD @@ -25,6 +25,11 @@ grpc_proto_library( well_known_protos = True, ) +proto_library( + name = "channelz_proto_descriptors", + srcs = ["channelz.proto"], +) + filegroup( name = "channelz_proto_file", srcs = [ diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD index 38a7d992e06..fc58e8a1770 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD @@ -23,6 +23,11 @@ grpc_proto_library( srcs = ["health.proto"], ) +proto_library( + name = "health_proto_descriptor", + srcs = ["health.proto"], +) + filegroup( name = "health_proto_file", srcs = [ diff --git a/src/proto/grpc/reflection/v1alpha/BUILD b/src/proto/grpc/reflection/v1alpha/BUILD index 4d919d029ee..5424c0d867e 100644 --- a/src/proto/grpc/reflection/v1alpha/BUILD +++ b/src/proto/grpc/reflection/v1alpha/BUILD @@ -23,6 +23,11 @@ grpc_proto_library( srcs = ["reflection.proto"], ) +proto_library( + name = "reflection_proto_descriptor", + srcs = ["reflection.proto"], +) + filegroup( name = "reflection_proto_file", srcs = [ diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD index 9876d5160a1..16e47d81061 100644 --- a/src/proto/grpc/testing/BUILD +++ b/src/proto/grpc/testing/BUILD @@ -16,7 +16,7 @@ licenses(["notice"]) # Apache v2 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") +load("//bazel:python_rules.bzl", "py_proto_library") grpc_package(name = "testing", visibility = "public") @@ -61,13 +61,14 @@ grpc_proto_library( has_services = False, ) +proto_library( + name = "empty_proto_descriptor", + srcs = ["empty.proto"], +) + py_proto_library( name = "py_empty_proto", - protos = ["empty.proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = [":empty_proto_descriptor"], ) grpc_proto_library( @@ -76,13 +77,14 @@ grpc_proto_library( has_services = False, ) +proto_library( + name = "messages_proto_descriptor", + srcs = ["messages.proto"], +) + py_proto_library( name = "py_messages_proto", - protos = ["messages.proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = [":messages_proto_descriptor"], ) grpc_proto_library( @@ -144,16 +146,19 @@ grpc_proto_library( ], ) +proto_library( + name = "test_proto_descriptor", + srcs = ["test.proto"], + deps = [ + ":empty_proto_descriptor", + ":messages_proto_descriptor", + ], +) + py_proto_library( name = "py_test_proto", - protos = ["test.proto",], - with_grpc = True, deps = [ - requirement('protobuf'), - ], - proto_deps = [ - ":py_empty_proto", - ":py_messages_proto", + ":test_proto_descriptor", ] ) diff --git a/src/proto/grpc/testing/proto2/BUILD.bazel b/src/proto/grpc/testing/proto2/BUILD.bazel index c4c4f004efb..e939c523a64 100644 --- a/src/proto/grpc/testing/proto2/BUILD.bazel +++ b/src/proto/grpc/testing/proto2/BUILD.bazel @@ -1,30 +1,32 @@ load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) +load("//bazel:python_rules.bzl", "py_proto_library") + +proto_library( + name = "empty2_proto_descriptor", + srcs = ["empty2.proto"], +) py_proto_library( name = "empty2_proto", - protos = [ - "empty2.proto", - ], - with_grpc = True, deps = [ - requirement('protobuf'), + ":empty2_proto_descriptor", ], ) +proto_library( + name = "empty2_extensions_proto_descriptor", + srcs = ["empty2_extensions.proto"], + deps = [ + ":empty2_proto_descriptor", + ] +) + py_proto_library( name = "empty2_extensions_proto", - protos = [ - "empty2_extensions.proto", - ], - proto_deps = [ - ":empty2_proto", - ], - with_grpc = True, deps = [ - requirement('protobuf'), + ":empty2_extensions_proto_descriptor", ], ) diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel index aae8cedb760..eccc166577d 100644 --- a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel +++ b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel @@ -1,30 +1,10 @@ -load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") - +load("//bazel:python_rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) -genrule( - name = "mv_channelz_proto", - srcs = [ - "//src/proto/grpc/channelz:channelz_proto_file", - ], - outs = ["channelz.proto",], - cmd = "cp $< $@", -) - py_proto_library( name = "py_channelz_proto", - protos = ["mv_channelz_proto",], - imports = [ - "external/com_google_protobuf/src/", - ], - inputs = [ - "@com_google_protobuf//:well_known_protos", - ], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + well_known_protos = True, + deps = ["//src/proto/grpc/channelz:channelz_proto_descriptors"], ) py_library( diff --git a/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel b/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel index ce3121fa90e..9e4fff34581 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel +++ b/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel @@ -1,24 +1,9 @@ -load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") - +load("//bazel:python_rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) -genrule( - name = "mv_health_proto", - srcs = [ - "//src/proto/grpc/health/v1:health_proto_file", - ], - outs = ["health.proto",], - cmd = "cp $< $@", -) - py_proto_library( name = "py_health_proto", - protos = [":mv_health_proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = ["//src/proto/grpc/health/v1:health_proto_descriptor",], ) py_library( diff --git a/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel b/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel index 3a2ba263715..6aaa4dd3bdd 100644 --- a/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel +++ b/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel @@ -1,24 +1,11 @@ +load("//bazel:python_rules.bzl", "py_proto_library") load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) -genrule( - name = "mv_reflection_proto", - srcs = [ - "//src/proto/grpc/reflection/v1alpha:reflection_proto_file", - ], - outs = ["reflection.proto",], - cmd = "cp $< $@", -) - py_proto_library( name = "py_reflection_proto", - protos = [":mv_reflection_proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = ["//src/proto/grpc/reflection/v1alpha:reflection_proto_descriptor",], ) py_library( diff --git a/src/python/grpcio_tests/tests/reflection/BUILD.bazel b/src/python/grpcio_tests/tests/reflection/BUILD.bazel index c0efb0b7cef..b635b721631 100644 --- a/src/python/grpcio_tests/tests/reflection/BUILD.bazel +++ b/src/python/grpcio_tests/tests/reflection/BUILD.bazel @@ -14,6 +14,7 @@ py_test( "//src/python/grpcio_tests/tests/unit:test_common", "//src/proto/grpc/testing:py_empty_proto", "//src/proto/grpc/testing/proto2:empty2_extensions_proto", + "//src/proto/grpc/testing/proto2:empty2_proto", requirement('protobuf'), ], imports=["../../",], diff --git a/tools/distrib/bazel_style.cfg b/tools/distrib/bazel_style.cfg new file mode 100644 index 00000000000..a5a1fea4aba --- /dev/null +++ b/tools/distrib/bazel_style.cfg @@ -0,0 +1,4 @@ +[style] +based_on_style = google +allow_split_before_dict_value = False +spaces_around_default_or_named_assign = True diff --git a/tools/distrib/format_bazel.sh b/tools/distrib/format_bazel.sh new file mode 100755 index 00000000000..ee230118efb --- /dev/null +++ b/tools/distrib/format_bazel.sh @@ -0,0 +1,39 @@ +#!/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. + +set=-ex + +VIRTUAL_ENV=bazel_format_virtual_environment + +CONFIG_PATH="$(dirname ${0})/bazel_style.cfg" + +python -m virtualenv ${VIRTUAL_ENV} +PYTHON=${VIRTUAL_ENV}/bin/python +"$PYTHON" -m pip install --upgrade pip==10.0.1 +"$PYTHON" -m pip install --upgrade futures +"$PYTHON" -m pip install yapf==0.20.0 + +pushd "$(dirname "${0}")/../.." +FILES=$(find . -path ./third_party -prune -o -name '*.bzl' -print) +echo "${FILES}" | xargs "$PYTHON" -m yapf -i --style="${CONFIG_PATH}" + +if ! which buildifier &>/dev/null; then + echo 'buildifer must be installed.' >/dev/stderr + exit 1 +fi + +echo "${FILES}" | xargs buildifier --type=bzl + +popd diff --git a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh index 3dd0167b7c0..24598f43f02 100755 --- a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh +++ b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh @@ -24,5 +24,4 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc && git submodule update --init --reference /var/local/jenkins/grpc/${name} \ ${name}') cd /var/local/git/grpc -#TODO(yfen): add back examples/... to build targets once python rules issues are resolved -bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... +bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/... 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 3ca4673ca08..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 @@ -23,10 +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}') -#TODO(yfen): temporarily disabled all python bazel tests due to incompatibility with bazel 0.23.2 -#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/... +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 714a13c193c588967201132af4bb56f8cf47ded6 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 30 Apr 2019 14:15:50 -0400 Subject: [PATCH 2033/2143] Initialize TCP write and error closures only once. We are initializing the closures in the hot path on every event. --- src/core/lib/iomgr/tcp_posix.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 30305a94f37..b140ae0ccae 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -271,16 +271,8 @@ static void notify_on_write(grpc_tcp* tcp) { if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p notify_on_write", tcp); } - if (grpc_event_engine_run_in_background()) { - // If there is a polling engine always running in the background, there is - // no need to run the backup poller. - GRPC_CLOSURE_INIT(&tcp->write_done_closure, tcp_handle_write, tcp, - grpc_schedule_on_exec_ctx); - } else { + if (!grpc_event_engine_run_in_background()) { cover_self(tcp); - GRPC_CLOSURE_INIT(&tcp->write_done_closure, - tcp_drop_uncovered_then_handle_write, tcp, - grpc_schedule_on_exec_ctx); } grpc_fd_notify_on_write(tcp->em_fd, &tcp->write_done_closure); } @@ -884,8 +876,6 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { * ready. */ grpc_fd_set_readable(tcp->em_fd); grpc_fd_set_writable(tcp->em_fd); - GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, - grpc_schedule_on_exec_ctx); grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); } @@ -1248,6 +1238,16 @@ 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); + if (grpc_event_engine_run_in_background()) { + // If there is a polling engine always running in the background, there is + // no need to run the backup poller. + GRPC_CLOSURE_INIT(&tcp->write_done_closure, tcp_handle_write, tcp, + grpc_schedule_on_exec_ctx); + } else { + GRPC_CLOSURE_INIT(&tcp->write_done_closure, + tcp_drop_uncovered_then_handle_write, tcp, + grpc_schedule_on_exec_ctx); + } /* Always assume there is something on the queue to read. */ tcp->inq = 1; #ifdef GRPC_HAVE_TCP_INQ From 6b0806eae327afd05f58f9fc68783850ba98749a Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 30 Apr 2019 11:22:04 -0700 Subject: [PATCH 2034/2143] more formatting changes --- include/grpcpp/server_impl.h | 6 +++--- src/cpp/server/server_cc.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h index 14b16a06f4e..46bacf81d26 100644 --- a/include/grpcpp/server_impl.h +++ b/include/grpcpp/server_impl.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -49,7 +50,6 @@ class ServerContext; namespace grpc_impl { -class HealthCheckServiceInterface; class ServerInitializer; /// Represents a gRPC server. @@ -99,7 +99,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { grpc_server* c_server(); /// Returns the health check service. - grpc_impl::HealthCheckServiceInterface* GetHealthCheckService() const { + grpc::HealthCheckServiceInterface* GetHealthCheckService() const { return health_check_service_.get(); } @@ -333,7 +333,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { std::unique_ptr server_initializer_; - std::unique_ptr health_check_service_; + std::unique_ptr health_check_service_; bool health_check_service_disabled_; // When appropriate, use a default callback generic service to handle diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 31bdc553f8b..9c2b1ee13fc 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -753,9 +753,9 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { &server_->callback_unmatched_reqs_count_[method_index_], 1); grpc_metadata_array_init(&request_metadata_); ctx_.Setup(gpr_inf_future(GPR_CLOCK_REALTIME)); - handler_data_ = nullptr; request_payload_ = nullptr; request_ = nullptr; + handler_data_ = nullptr; request_status_ = grpc::Status(); } From 2cb63d859d69512a92685a19887ea7428c47bb9f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 30 Apr 2019 20:29:42 +0200 Subject: [PATCH 2035/2143] split multilang jobs by language --- .../linux/grpc_basictests_csharp.cfg | 30 ++++++++++++++++++ .../linux/grpc_basictests_node.cfg | 30 ++++++++++++++++++ .../internal_ci/linux/grpc_basictests_php.cfg | 30 ++++++++++++++++++ .../linux/grpc_basictests_python.cfg | 30 ++++++++++++++++++ .../linux/grpc_basictests_ruby.cfg | 30 ++++++++++++++++++ .../macos/grpc_basictests_c_cpp.cfg | 31 +++++++++++++++++++ .../macos/grpc_basictests_csharp.cfg | 31 +++++++++++++++++++ .../macos/grpc_basictests_node.cfg | 31 +++++++++++++++++++ .../internal_ci/macos/grpc_basictests_php.cfg | 31 +++++++++++++++++++ .../macos/grpc_basictests_python.cfg | 31 +++++++++++++++++++ .../macos/grpc_basictests_ruby.cfg | 31 +++++++++++++++++++ .../internal_ci/windows/grpc_basictests_c.cfg | 30 ++++++++++++++++++ .../windows/grpc_basictests_csharp.cfg | 30 ++++++++++++++++++ .../windows/grpc_basictests_python.cfg | 30 ++++++++++++++++++ 14 files changed, 426 insertions(+) create mode 100644 tools/internal_ci/linux/grpc_basictests_csharp.cfg create mode 100644 tools/internal_ci/linux/grpc_basictests_node.cfg create mode 100644 tools/internal_ci/linux/grpc_basictests_php.cfg create mode 100644 tools/internal_ci/linux/grpc_basictests_python.cfg create mode 100644 tools/internal_ci/linux/grpc_basictests_ruby.cfg create mode 100644 tools/internal_ci/macos/grpc_basictests_c_cpp.cfg create mode 100644 tools/internal_ci/macos/grpc_basictests_csharp.cfg create mode 100644 tools/internal_ci/macos/grpc_basictests_node.cfg create mode 100644 tools/internal_ci/macos/grpc_basictests_php.cfg create mode 100644 tools/internal_ci/macos/grpc_basictests_python.cfg create mode 100644 tools/internal_ci/macos/grpc_basictests_ruby.cfg create mode 100644 tools/internal_ci/windows/grpc_basictests_c.cfg create mode 100644 tools/internal_ci/windows/grpc_basictests_csharp.cfg create mode 100644 tools/internal_ci/windows/grpc_basictests_python.cfg diff --git a/tools/internal_ci/linux/grpc_basictests_csharp.cfg b/tools/internal_ci/linux/grpc_basictests_csharp.cfg new file mode 100644 index 00000000000..017e929beff --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_csharp.cfg @@ -0,0 +1,30 @@ +# 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_run_tests_matrix.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux csharp --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/linux/grpc_basictests_node.cfg b/tools/internal_ci/linux/grpc_basictests_node.cfg new file mode 100644 index 00000000000..d7b35a04719 --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_node.cfg @@ -0,0 +1,30 @@ +# 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_run_tests_matrix.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux grpc-node --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/linux/grpc_basictests_php.cfg b/tools/internal_ci/linux/grpc_basictests_php.cfg new file mode 100644 index 00000000000..80aa0dc87bb --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_php.cfg @@ -0,0 +1,30 @@ +# 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_run_tests_matrix.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux php --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/linux/grpc_basictests_python.cfg b/tools/internal_ci/linux/grpc_basictests_python.cfg new file mode 100644 index 00000000000..444dba9f4df --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_python.cfg @@ -0,0 +1,30 @@ +# 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_run_tests_matrix.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux python --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/linux/grpc_basictests_ruby.cfg b/tools/internal_ci/linux/grpc_basictests_ruby.cfg new file mode 100644 index 00000000000..336aa469958 --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_ruby.cfg @@ -0,0 +1,30 @@ +# 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_run_tests_matrix.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux ruby --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_c_cpp.cfg b/tools/internal_ci/macos/grpc_basictests_c_cpp.cfg new file mode 100644 index 00000000000..9783dd64673 --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_c_cpp.cfg @@ -0,0 +1,31 @@ +# 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_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos corelang --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_csharp.cfg b/tools/internal_ci/macos/grpc_basictests_csharp.cfg new file mode 100644 index 00000000000..d3e04e71f71 --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_csharp.cfg @@ -0,0 +1,31 @@ +# 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_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos csharp --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_node.cfg b/tools/internal_ci/macos/grpc_basictests_node.cfg new file mode 100644 index 00000000000..9dfd6a7b9e8 --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_node.cfg @@ -0,0 +1,31 @@ +# 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_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos grpc-node --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_php.cfg b/tools/internal_ci/macos/grpc_basictests_php.cfg new file mode 100644 index 00000000000..091f68efaba --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_php.cfg @@ -0,0 +1,31 @@ +# 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_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos php --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_python.cfg b/tools/internal_ci/macos/grpc_basictests_python.cfg new file mode 100644 index 00000000000..ae80ac317ff --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_python.cfg @@ -0,0 +1,31 @@ +# 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_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos python --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_ruby.cfg b/tools/internal_ci/macos/grpc_basictests_ruby.cfg new file mode 100644 index 00000000000..3a28f97a54b --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_ruby.cfg @@ -0,0 +1,31 @@ +# 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_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos ruby --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/windows/grpc_basictests_c.cfg b/tools/internal_ci/windows/grpc_basictests_c.cfg new file mode 100644 index 00000000000..150a28e3f89 --- /dev/null +++ b/tools/internal_ci/windows/grpc_basictests_c.cfg @@ -0,0 +1,30 @@ +# 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/windows/grpc_run_tests_matrix.bat" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests windows c -j 1 --inner_jobs 8 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/windows/grpc_basictests_csharp.cfg b/tools/internal_ci/windows/grpc_basictests_csharp.cfg new file mode 100644 index 00000000000..17a362fb32a --- /dev/null +++ b/tools/internal_ci/windows/grpc_basictests_csharp.cfg @@ -0,0 +1,30 @@ +# 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/windows/grpc_run_tests_matrix.bat" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests windows csharp -j 1 --inner_jobs 8 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/windows/grpc_basictests_python.cfg b/tools/internal_ci/windows/grpc_basictests_python.cfg new file mode 100644 index 00000000000..b0f6f6772d3 --- /dev/null +++ b/tools/internal_ci/windows/grpc_basictests_python.cfg @@ -0,0 +1,30 @@ +# 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/windows/grpc_run_tests_matrix.bat" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests windows python -j 1 --inner_jobs 8 --internal_ci --bq_result_table aggregate_results" +} From 058e90ef161e31d1f892b49c0ee6cb0ba3957e9e Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 30 Apr 2019 11:12:19 -0700 Subject: [PATCH 2036/2143] Tiny fix for combiner comment --- src/core/lib/iomgr/combiner.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/combiner.h b/src/core/lib/iomgr/combiner.h index 3c947bf9d64..b9274216993 100644 --- a/src/core/lib/iomgr/combiner.h +++ b/src/core/lib/iomgr/combiner.h @@ -31,7 +31,7 @@ // Provides serialized access to some resource. // Each action queued on a combiner is executed serially in a borrowed thread. // The actual thread executing actions may change over time (but there will only -// every be one at a time). +// ever be one at a time). // Initialize the lock, with an optional workqueue to shift load to when // necessary From dc148b6a303262124ac96a41a78e6bbd3770a83b Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Tue, 30 Apr 2019 10:29:11 -0700 Subject: [PATCH 2037/2143] Fix regression where we do not properly account for freed interned metadata. --- src/core/lib/transport/metadata.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index e3b8d112795..7e0b2163246 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -211,7 +211,6 @@ void grpc_mdctx_global_shutdown() { mdtab_shard* shard = &g_shards[i]; gpr_mu_destroy(&shard->mu); gc_mdtab(shard); - /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */ if (shard->count != 0) { gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata elements were leaked", shard->count); @@ -219,6 +218,7 @@ void grpc_mdctx_global_shutdown() { abort(); } } + GPR_DEBUG_ASSERT(shard->count == 0); gpr_free(shard->elems); } } @@ -251,7 +251,9 @@ static void gc_mdtab(mdtab_shard* shard) { GPR_TIMER_SCOPE("gc_mdtab", 0); size_t num_freed = 0; for (size_t i = 0; i < shard->capacity; ++i) { - num_freed += InternedMetadata::CleanupLinkedMetadata(&shard->elems[i]); + intptr_t freed = InternedMetadata::CleanupLinkedMetadata(&shard->elems[i]); + num_freed += freed; + shard->count -= freed; } gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -static_cast(num_freed)); From 22c6e166c439481d5d5fa0990b8c59db92ec5152 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Tue, 30 Apr 2019 11:49:34 -0700 Subject: [PATCH 2038/2143] Use platform align_malloc function when setting custom allocators and no override provided --- src/core/lib/gpr/alloc.cc | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/core/lib/gpr/alloc.cc b/src/core/lib/gpr/alloc.cc index b12b7d8534d..f79e645971a 100644 --- a/src/core/lib/gpr/alloc.cc +++ b/src/core/lib/gpr/alloc.cc @@ -43,21 +43,9 @@ static constexpr bool is_power_of_two(size_t value) { } #endif -static void* aligned_alloc_with_gpr_malloc(size_t size, size_t alignment) { - GPR_DEBUG_ASSERT(is_power_of_two(alignment)); - size_t extra = alignment - 1 + sizeof(void*); - void* p = gpr_malloc(size + extra); - void** ret = (void**)(((uintptr_t)p + extra) & ~(alignment - 1)); - ret[-1] = p; - return (void*)ret; -} - -static void aligned_free_with_gpr_malloc(void* ptr) { - gpr_free((static_cast(ptr))[-1]); -} - static void* platform_malloc_aligned(size_t size, size_t alignment) { #if defined(GPR_HAS_ALIGNED_ALLOC) + GPR_DEBUG_ASSERT(is_power_of_two(alignment)); size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size, alignment); void* ret = aligned_alloc(alignment, size); GPR_ASSERT(ret != nullptr); @@ -74,7 +62,12 @@ static void* platform_malloc_aligned(size_t size, size_t alignment) { GPR_ASSERT(posix_memalign(&ret, alignment, size) == 0); return ret; #else - return aligned_alloc_with_gpr_malloc(size, alignment); + GPR_DEBUG_ASSERT(is_power_of_two(alignment)); + size_t extra = alignment - 1 + sizeof(void*); + void* p = gpr_malloc(size + extra); + void** ret = (void**)(((uintptr_t)p + extra) & ~(alignment - 1)); + ret[-1] = p; + return (void*)ret; #endif } @@ -84,7 +77,7 @@ static void platform_free_aligned(void* ptr) { #elif defined(GPR_HAS_ALIGNED_MALLOC) _aligned_free(ptr); #else - aligned_free_with_gpr_malloc(ptr); + gpr_free((static_cast(ptr))[-1]); #endif } @@ -106,8 +99,8 @@ void gpr_set_allocation_functions(gpr_allocation_functions functions) { GPR_ASSERT((functions.aligned_alloc_fn == nullptr) == (functions.aligned_free_fn == nullptr)); if (functions.aligned_alloc_fn == nullptr) { - functions.aligned_alloc_fn = aligned_alloc_with_gpr_malloc; - functions.aligned_free_fn = aligned_free_with_gpr_malloc; + functions.aligned_alloc_fn = platform_malloc_aligned; + functions.aligned_free_fn = platform_free_aligned; } g_alloc_functions = functions; } From b028141f01646688b1c4652e92e79160035c0bab Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Tue, 30 Apr 2019 14:24:40 -0700 Subject: [PATCH 2039/2143] Change streaming ping pong args and add comment --- .../bm_callback_streaming_ping_pong.cc | 153 +++++++++++------- .../callback_streaming_ping_pong.h | 18 +-- 2 files changed, 102 insertions(+), 69 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc index ed1c3189086..f7e3469f2e4 100644 --- a/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.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. @@ -31,10 +31,11 @@ auto& force_library_initialization = Library::get(); // Replace "benchmark::internal::Benchmark" with "::testing::Benchmark" to use // internal microbenchmarking tooling -static void StreamingPingPongArgs(benchmark::internal::Benchmark* b) { +static void StreamingPingPongMsgSizeArgs(benchmark::internal::Benchmark* b) { int msg_size = 0; - - b->Args({0, 0}); // spl case: 0 ping-pong msgs (msg_size doesn't matter here) + // base case: 0 byte ping-pong msgs + b->Args({0, 1}); + b->Args({0, 2}); for (msg_size = 0; msg_size <= 128 * 1024 * 1024; msg_size == 0 ? msg_size++ : msg_size *= 8) { @@ -42,119 +43,151 @@ static void StreamingPingPongArgs(benchmark::internal::Benchmark* b) { b->Args({msg_size, 2}); } } + +// Replace "benchmark::internal::Benchmark" with "::testing::Benchmark" to use +// internal microbenchmarking tooling +static void StreamingPingPongMsgsNumberArgs(benchmark::internal::Benchmark* b) { + int msg_number = 0; + + for (msg_number = 0; msg_number <= 128 * 1024; + msg_number == 0 ? msg_number++ : msg_number *= 8) { + b->Args({0, msg_number}); + // 64 KiB same as the synthetic test configuration + b->Args({64 * 1024, msg_number}); + } +} + +// Streaming with different message size BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, NoOpMutator) - ->Apply(StreamingPingPongArgs); + ->Apply(StreamingPingPongMsgSizeArgs); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, MinInProcess, NoOpMutator, NoOpMutator) - ->Apply(StreamingPingPongArgs); + ->Apply(StreamingPingPongMsgSizeArgs); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, NoOpMutator) - ->Apply(StreamingPingPongArgs); + ->Apply(StreamingPingPongMsgSizeArgs); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, MinInProcessCHTTP2, NoOpMutator, NoOpMutator) - ->Apply(StreamingPingPongArgs); + ->Apply(StreamingPingPongMsgSizeArgs); +// Streaming with different message number +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + NoOpMutator) + ->Apply(StreamingPingPongMsgsNumberArgs); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, MinInProcess, NoOpMutator, + NoOpMutator) + ->Apply(StreamingPingPongMsgsNumberArgs); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + NoOpMutator) + ->Apply(StreamingPingPongMsgsNumberArgs); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, MinInProcessCHTTP2, NoOpMutator, + NoOpMutator) + ->Apply(StreamingPingPongMsgsNumberArgs); + +// Client context with different metadata BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 100>) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); + ->Args({0, 1}); + +// Server context with different metadata +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, + Server_AddInitialMetadata, 100>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, Server_AddInitialMetadata, 1>) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, Server_AddInitialMetadata, 1>) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, Server_AddInitialMetadata, 1>) - ->Args({0, 0}); + ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, Server_AddInitialMetadata, 100>) - ->Args({0, 0}); + ->Args({0, 1}); } // namespace testing } // namespace grpc diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h index 13743412153..1710a754803 100644 --- a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -37,26 +37,26 @@ namespace testing { template static void BM_CallbackBidiStreaming(benchmark::State& state) { const int message_size = state.range(0); - const int max_ping_pongs = state.range(1) > 0 ? 1 : state.range(1); + const int max_ping_pongs = state.range(1); CallbackStreamingTestService service; std::unique_ptr fixture(new Fixture(&service)); std::unique_ptr stub_( EchoTestService::NewStub(fixture->channel())); - EchoRequest* request = new EchoRequest; - EchoResponse* response = new EchoResponse; + EchoRequest request; + EchoResponse response; if (state.range(0) > 0) { - request->set_message(std::string(state.range(0), 'a')); + request.set_message(std::string(state.range(0), 'a')); } else { - request->set_message(""); + request.set_message(""); } while (state.KeepRunning()) { GPR_TIMER_SCOPE("BenchmarkCycle", 0); - ClientContext* cli_ctx = new ClientContext; - cli_ctx->AddMetadata(kServerFinishAfterNReads, + ClientContext cli_ctx; + cli_ctx.AddMetadata(kServerFinishAfterNReads, grpc::to_string(max_ping_pongs)); - cli_ctx->AddMetadata(kServerResponseStreamsToSend, + cli_ctx.AddMetadata(kServerResponseStreamsToSend, grpc::to_string(message_size)); - BidiClient test{stub_.get(), request, response, cli_ctx, max_ping_pongs}; + BidiClient test{stub_.get(), &request, &response, &cli_ctx, max_ping_pongs}; test.Await(); } fixture->Finish(state); From d74f04680f94b22982103cdddd9f6e7e76783d47 Mon Sep 17 00:00:00 2001 From: John Luo Date: Tue, 30 Apr 2019 15:04:11 -0700 Subject: [PATCH 2040/2143] Restrict workaround to MSBuild 15.0 and above --- .../build/_protobuf/Google.Protobuf.Tools.targets | 9 +++++---- 1 file changed, 5 insertions(+), 4 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 784f789528e..b3fd02d4faa 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets @@ -40,10 +40,11 @@ - - - - + + + + + From fd5f787080838028320e3553d79c5c3f603380a2 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 30 Apr 2019 18:23:58 -0400 Subject: [PATCH 2041/2143] Introduce slice_buffer helper methods to avoid copies. take_first(), grpc_undo_first(), ... are very clostly methods that unnecessarily copy grpc_slice with extra ref counting requirements. Introduce alternatives to avoid copies and refs wherever possible. This results in 1% improvements in the benchmarks. --- .../transport/chttp2/transport/frame_data.cc | 59 +++++++++---------- .../compression/stream_compression_gzip.cc | 18 +++--- src/core/lib/iomgr/tcp_posix.cc | 3 +- .../security/transport/security_handshaker.cc | 11 ++-- src/core/lib/slice/slice_buffer.cc | 18 ++++++ src/core/lib/slice/slice_internal.h | 15 +++++ test/core/slice/slice_buffer_test.cc | 43 ++++++++++++++ 7 files changed, 119 insertions(+), 48 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index 6080a4bd1c4..2b7d3fce008 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -104,23 +104,22 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( uint8_t* end = nullptr; uint8_t* cur = nullptr; - grpc_slice slice = grpc_slice_buffer_take_first(slices); - - beg = GRPC_SLICE_START_PTR(slice); - end = GRPC_SLICE_END_PTR(slice); + grpc_slice* slice = grpc_slice_buffer_mutable_first(slices); + beg = GRPC_SLICE_START_PTR(*slice); + end = GRPC_SLICE_END_PTR(*slice); cur = beg; uint32_t message_flags; char* msg; if (cur == end) { - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); continue; } switch (p->state) { case GRPC_CHTTP2_DATA_ERROR: p->state = GRPC_CHTTP2_DATA_ERROR; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); return GRPC_ERROR_REF(p->error); case GRPC_CHTTP2_DATA_FH_0: s->stats.incoming.framing_bytes++; @@ -138,19 +137,19 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, static_cast(s->id)); gpr_free(msg); - msg = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); + msg = grpc_dump_slice(*slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); p->error = grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, grpc_slice_from_copied_string(msg)); gpr_free(msg); p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); p->state = GRPC_CHTTP2_DATA_ERROR; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); return GRPC_ERROR_REF(p->error); } if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_1; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); continue; } /* fallthrough */ @@ -159,7 +158,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->frame_size = (static_cast(*cur)) << 24; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_2; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); continue; } /* fallthrough */ @@ -168,7 +167,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->frame_size |= (static_cast(*cur)) << 16; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_3; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); continue; } /* fallthrough */ @@ -177,7 +176,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->frame_size |= (static_cast(*cur)) << 8; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_4; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); continue; } /* fallthrough */ @@ -204,19 +203,18 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->state = GRPC_CHTTP2_DATA_FH_0; } s->pending_byte_stream = true; - if (cur != end) { - grpc_slice_buffer_undo_take_first( - slices, grpc_slice_sub(slice, static_cast(cur - beg), - static_cast(end - beg))); + grpc_slice_buffer_sub_first(slices, static_cast(cur - beg), + static_cast(end - beg)); + } else { + grpc_slice_buffer_consume_first(slices); } - grpc_slice_unref_internal(slice); return GRPC_ERROR_NONE; case GRPC_CHTTP2_DATA_FRAME: { GPR_ASSERT(p->parsing_frame != nullptr); GPR_ASSERT(slice_out != nullptr); if (cur == end) { - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); continue; } uint32_t remaining = static_cast(end - cur); @@ -224,32 +222,32 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( s->stats.incoming.data_bytes += remaining; if (GRPC_ERROR_NONE != (error = p->parsing_frame->Push( - grpc_slice_sub(slice, static_cast(cur - beg), + grpc_slice_sub(*slice, static_cast(cur - beg), static_cast(end - beg)), slice_out))) { - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); return error; } if (GRPC_ERROR_NONE != (error = p->parsing_frame->Finished(GRPC_ERROR_NONE, true))) { - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); return error; } p->parsing_frame = nullptr; p->state = GRPC_CHTTP2_DATA_FH_0; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); return GRPC_ERROR_NONE; } else if (remaining < p->frame_size) { s->stats.incoming.data_bytes += remaining; if (GRPC_ERROR_NONE != (error = p->parsing_frame->Push( - grpc_slice_sub(slice, static_cast(cur - beg), + grpc_slice_sub(*slice, static_cast(cur - beg), static_cast(end - beg)), slice_out))) { return error; } p->frame_size -= remaining; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); return GRPC_ERROR_NONE; } else { GPR_ASSERT(remaining > p->frame_size); @@ -257,30 +255,27 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( if (GRPC_ERROR_NONE != p->parsing_frame->Push( grpc_slice_sub( - slice, static_cast(cur - beg), + *slice, static_cast(cur - beg), static_cast(cur + p->frame_size - beg)), slice_out)) { - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); return error; } if (GRPC_ERROR_NONE != (error = p->parsing_frame->Finished(GRPC_ERROR_NONE, true))) { - grpc_slice_unref_internal(slice); + grpc_slice_buffer_consume_first(slices); return error; } p->parsing_frame = nullptr; p->state = GRPC_CHTTP2_DATA_FH_0; cur += p->frame_size; - grpc_slice_buffer_undo_take_first( - slices, grpc_slice_sub(slice, static_cast(cur - beg), - static_cast(end - beg))); - grpc_slice_unref_internal(slice); + grpc_slice_buffer_sub_first(slices, static_cast(cur - beg), + static_cast(end - beg)); return GRPC_ERROR_NONE; } } } } - return GRPC_ERROR_NONE; } diff --git a/src/core/lib/compression/stream_compression_gzip.cc b/src/core/lib/compression/stream_compression_gzip.cc index bffdb1fd17d..ca687066136 100644 --- a/src/core/lib/compression/stream_compression_gzip.cc +++ b/src/core/lib/compression/stream_compression_gzip.cc @@ -53,25 +53,25 @@ static bool gzip_flate(grpc_stream_compression_context_gzip* ctx, ctx->zs.avail_out = static_cast(slice_size); ctx->zs.next_out = GRPC_SLICE_START_PTR(slice_out); while (ctx->zs.avail_out > 0 && in->length > 0 && !eoc) { - grpc_slice slice = grpc_slice_buffer_take_first(in); - ctx->zs.avail_in = static_cast GRPC_SLICE_LENGTH(slice); - ctx->zs.next_in = GRPC_SLICE_START_PTR(slice); + grpc_slice* slice = grpc_slice_buffer_mutable_first(in); + ctx->zs.avail_in = static_cast GRPC_SLICE_LENGTH(*slice); + ctx->zs.next_in = GRPC_SLICE_START_PTR(*slice); r = ctx->flate(&ctx->zs, Z_NO_FLUSH); 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); + grpc_slice_buffer_consume_first(in); return false; } else if (r == Z_STREAM_END && ctx->flate == inflate) { eoc = true; } if (ctx->zs.avail_in > 0) { - grpc_slice_buffer_undo_take_first( - in, - grpc_slice_sub(slice, GRPC_SLICE_LENGTH(slice) - ctx->zs.avail_in, - GRPC_SLICE_LENGTH(slice))); + grpc_slice_buffer_sub_first( + in, GRPC_SLICE_LENGTH(*slice) - ctx->zs.avail_in, + GRPC_SLICE_LENGTH(*slice)); + } else { + grpc_slice_buffer_consume_first(in); } - grpc_slice_unref_internal(slice); } if (flush != 0 && ctx->zs.avail_out > 0 && !eoc) { GPR_ASSERT(in->length == 0); diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index b140ae0ccae..45af4931cf5 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -980,8 +980,7 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { // unref all and forget about all slices that have been written to this // point for (size_t idx = 0; idx < unwind_slice_idx; ++idx) { - grpc_slice_unref_internal( - grpc_slice_buffer_take_first(tcp->outgoing_buffer)); + grpc_slice_buffer_consume_first(tcp->outgoing_buffer); } return false; } else if (errno == EPIPE) { diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index 3605bbe5974..7c0792f2846 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -144,11 +144,12 @@ size_t SecurityHandshaker::MoveReadBufferIntoHandshakeBuffer() { } size_t offset = 0; 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); + grpc_slice* next_slice = + grpc_slice_buffer_mutable_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_buffer_consume_first(args_->read_buffer); } return bytes_in_read_buffer; } diff --git a/src/core/lib/slice/slice_buffer.cc b/src/core/lib/slice/slice_buffer.cc index 1f1c08b1594..76da64b858f 100644 --- a/src/core/lib/slice/slice_buffer.cc +++ b/src/core/lib/slice/slice_buffer.cc @@ -370,6 +370,24 @@ grpc_slice grpc_slice_buffer_take_first(grpc_slice_buffer* sb) { return slice; } +void grpc_slice_buffer_consume_first(grpc_slice_buffer* sb) { + GPR_ASSERT(sb->count > 0); + sb->length -= GRPC_SLICE_LENGTH(sb->slices[0]); + grpc_slice_unref_internal(sb->slices[0]); + sb->slices++; + if (--sb->count == 0) { + sb->slices = sb->base_slices; + } +} + +void grpc_slice_buffer_sub_first(grpc_slice_buffer* sb, size_t begin, + size_t end) { + // TODO(soheil): Introduce a ptr version for sub. + sb->length -= GRPC_SLICE_LENGTH(sb->slices[0]); + sb->slices[0] = grpc_slice_sub_no_ref(sb->slices[0], begin, end); + sb->length += GRPC_SLICE_LENGTH(sb->slices[0]); +} + void grpc_slice_buffer_undo_take_first(grpc_slice_buffer* sb, grpc_slice slice) { sb->slices--; diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index db8c8e5c7cc..4c4ace443dc 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -21,6 +21,8 @@ #include +#include + #include #include #include @@ -240,6 +242,19 @@ void grpc_slice_buffer_partial_unref_internal(grpc_slice_buffer* sb, size_t idx); void grpc_slice_buffer_destroy_internal(grpc_slice_buffer* sb); +// Returns the first slice in the slice buffer. +inline grpc_slice* grpc_slice_buffer_mutable_first(grpc_slice_buffer* sb) { + GPR_DEBUG_ASSERT(sb->count > 0); + return &sb->slices[0]; +} + +// Consumes the first slice in the slice buffer. +void grpc_slice_buffer_consume_first(grpc_slice_buffer* sb); + +// Calls grpc_slice_sub with the given parameters on the first slice. +void grpc_slice_buffer_sub_first(grpc_slice_buffer* sb, size_t begin, + size_t end); + /* Check if a slice is interned */ bool grpc_slice_is_interned(const grpc_slice& slice); diff --git a/test/core/slice/slice_buffer_test.cc b/test/core/slice/slice_buffer_test.cc index b53e3312df1..8aa58a3ac0d 100644 --- a/test/core/slice/slice_buffer_test.cc +++ b/test/core/slice/slice_buffer_test.cc @@ -19,6 +19,7 @@ #include #include #include +#include "src/core/lib/slice/slice_internal.h" #include "test/core/util/test_config.h" void test_slice_buffer_add() { @@ -105,12 +106,54 @@ void test_slice_buffer_move_first() { GPR_ASSERT(dst.length == dst_len); } +void test_slice_buffer_first() { + grpc_slice slices[3]; + slices[0] = grpc_slice_from_copied_string("aaa"); + slices[1] = grpc_slice_from_copied_string("bbbb"); + slices[2] = grpc_slice_from_copied_string("ccccc"); + + grpc_slice_buffer buf; + grpc_slice_buffer_init(&buf); + for (int idx = 0; idx < 3; ++idx) { + grpc_slice_ref(slices[idx]); + grpc_slice_buffer_add_indexed(&buf, slices[idx]); + } + + grpc_slice* first = grpc_slice_buffer_mutable_first(&buf); + GPR_ASSERT(GPR_SLICE_LENGTH(*first) == GPR_SLICE_LENGTH(slices[0])); + GPR_ASSERT(buf.count == 3); + GPR_ASSERT(buf.length == 12); + + grpc_slice_buffer_sub_first(&buf, 1, 2); + first = grpc_slice_buffer_mutable_first(&buf); + GPR_ASSERT(GPR_SLICE_LENGTH(*first) == 1); + GPR_ASSERT(buf.count == 3); + GPR_ASSERT(buf.length == 10); + + grpc_slice_buffer_consume_first(&buf); + first = grpc_slice_buffer_mutable_first(&buf); + GPR_ASSERT(GPR_SLICE_LENGTH(*first) == GPR_SLICE_LENGTH(slices[1])); + GPR_ASSERT(buf.count == 2); + GPR_ASSERT(buf.length == 9); + + grpc_slice_buffer_consume_first(&buf); + first = grpc_slice_buffer_mutable_first(&buf); + GPR_ASSERT(GPR_SLICE_LENGTH(*first) == GPR_SLICE_LENGTH(slices[2])); + GPR_ASSERT(buf.count == 1); + GPR_ASSERT(buf.length == 5); + + grpc_slice_buffer_consume_first(&buf); + GPR_ASSERT(buf.count == 0); + GPR_ASSERT(buf.length == 0); +} + int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_slice_buffer_add(); test_slice_buffer_move_first(); + test_slice_buffer_first(); grpc_shutdown(); return 0; From 5538bb81434ccb01216c82d09ade04fdf9ec65b7 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 30 Apr 2019 17:56:43 -0400 Subject: [PATCH 2042/2143] Use compress and decompress slice_buffers only when they are needed. Compression is not used for performance senstiive RPCs, yet chttp2 always moves buffers in/out of the compressed/decmpressed buffers. Even initilizing them is costly. Use the (de)compression buffer and state only when we are using non-identity compression. This is part of a larger performance change, and this one buys us 1%-2% depending on the benchmark. --- .../chttp2/transport/chttp2_transport.cc | 79 +++++++++++++------ .../chttp2/transport/hpack_parser.cc | 6 ++ .../ext/transport/chttp2/transport/internal.h | 35 ++++---- .../ext/transport/chttp2/transport/writing.cc | 63 ++++++++++++--- 4 files changed, 131 insertions(+), 52 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index d4188775722..6eec4359563 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -679,8 +679,6 @@ grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t, grpc_slice_buffer_init(&frame_storage); grpc_slice_buffer_init(&unprocessed_incoming_frames_buffer); grpc_slice_buffer_init(&flow_controlled_buffer); - grpc_slice_buffer_init(&compressed_data_buffer); - grpc_slice_buffer_init(&decompressed_data_buffer); GRPC_CLOSURE_INIT(&complete_fetch_locked, ::complete_fetch_locked, this, grpc_combiner_scheduler(t->combiner)); @@ -704,8 +702,13 @@ grpc_chttp2_stream::~grpc_chttp2_stream() { grpc_slice_buffer_destroy_internal(&unprocessed_incoming_frames_buffer); grpc_slice_buffer_destroy_internal(&frame_storage); - grpc_slice_buffer_destroy_internal(&compressed_data_buffer); - grpc_slice_buffer_destroy_internal(&decompressed_data_buffer); + if (stream_compression_method != GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS) { + grpc_slice_buffer_destroy_internal(&compressed_data_buffer); + } + if (stream_decompression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS) { + grpc_slice_buffer_destroy_internal(&decompressed_data_buffer); + } grpc_chttp2_list_remove_stalled_by_transport(t, this); grpc_chttp2_list_remove_stalled_by_stream(t, this); @@ -759,12 +762,15 @@ static void destroy_stream(grpc_transport* gt, grpc_stream* gs, GPR_TIMER_SCOPE("destroy_stream", 0); grpc_chttp2_transport* t = reinterpret_cast(gt); grpc_chttp2_stream* s = reinterpret_cast(gs); - - if (s->stream_compression_ctx != nullptr) { + if (s->stream_compression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS && + s->stream_compression_ctx != nullptr) { grpc_stream_compression_context_destroy(s->stream_compression_ctx); s->stream_compression_ctx = nullptr; } - if (s->stream_decompression_ctx != nullptr) { + if (s->stream_decompression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS && + s->stream_decompression_ctx != nullptr) { grpc_stream_compression_context_destroy(s->stream_decompression_ctx); s->stream_decompression_ctx = nullptr; } @@ -1443,6 +1449,13 @@ static void perform_stream_op_locked(void* stream_op, s->stream_compression_method = GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS; } + if (s->stream_compression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS) { + s->uncompressed_data_size = 0; + s->stream_compression_ctx = nullptr; + grpc_slice_buffer_init(&s->compressed_data_buffer); + } + s->send_initial_metadata_finished = add_closure_barrier(on_complete); s->send_initial_metadata = op_payload->send_initial_metadata.send_initial_metadata; @@ -1998,27 +2011,39 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_chttp2_transport* t, !s->seen_error && s->recv_trailing_metadata_finished != nullptr) { /* Maybe some SYNC_FLUSH data is left in frame_storage. Consume them and * maybe decompress the next 5 bytes in the stream. */ - bool end_of_context; - if (!s->stream_decompression_ctx) { - s->stream_decompression_ctx = grpc_stream_compression_context_create( - s->stream_decompression_method); - } - if (!grpc_stream_decompress( - s->stream_decompression_ctx, &s->frame_storage, - &s->unprocessed_incoming_frames_buffer, nullptr, - GRPC_HEADER_SIZE_IN_BYTES, &end_of_context)) { - grpc_slice_buffer_reset_and_unref_internal(&s->frame_storage); - grpc_slice_buffer_reset_and_unref_internal( - &s->unprocessed_incoming_frames_buffer); - s->seen_error = true; - } else { + if (s->stream_decompression_method == + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS) { + grpc_slice_buffer_move_first(&s->frame_storage, + GRPC_HEADER_SIZE_IN_BYTES, + &s->unprocessed_incoming_frames_buffer); if (s->unprocessed_incoming_frames_buffer.length > 0) { s->unprocessed_incoming_frames_decompressed = true; pending_data = true; } - if (end_of_context) { - grpc_stream_compression_context_destroy(s->stream_decompression_ctx); - s->stream_decompression_ctx = nullptr; + } else { + bool end_of_context; + if (!s->stream_decompression_ctx) { + s->stream_decompression_ctx = grpc_stream_compression_context_create( + s->stream_decompression_method); + } + if (!grpc_stream_decompress( + s->stream_decompression_ctx, &s->frame_storage, + &s->unprocessed_incoming_frames_buffer, nullptr, + GRPC_HEADER_SIZE_IN_BYTES, &end_of_context)) { + grpc_slice_buffer_reset_and_unref_internal(&s->frame_storage); + grpc_slice_buffer_reset_and_unref_internal( + &s->unprocessed_incoming_frames_buffer); + s->seen_error = true; + } else { + if (s->unprocessed_incoming_frames_buffer.length > 0) { + s->unprocessed_incoming_frames_decompressed = true; + pending_data = true; + } + if (end_of_context) { + grpc_stream_compression_context_destroy( + s->stream_decompression_ctx); + s->stream_decompression_ctx = nullptr; + } } } } @@ -2941,6 +2966,8 @@ bool Chttp2IncomingByteStream::Next(size_t max_size_hint, } void Chttp2IncomingByteStream::MaybeCreateStreamDecompressionCtx() { + GPR_DEBUG_ASSERT(stream_->stream_decompression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS); if (!stream_->stream_decompression_ctx) { stream_->stream_decompression_ctx = grpc_stream_compression_context_create( stream_->stream_decompression_method); @@ -2951,7 +2978,9 @@ grpc_error* Chttp2IncomingByteStream::Pull(grpc_slice* slice) { GPR_TIMER_SCOPE("incoming_byte_stream_pull", 0); grpc_error* error; if (stream_->unprocessed_incoming_frames_buffer.length > 0) { - if (!stream_->unprocessed_incoming_frames_decompressed) { + if (!stream_->unprocessed_incoming_frames_decompressed && + stream_->stream_decompression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS) { bool end_of_context; MaybeCreateStreamDecompressionCtx(); if (!grpc_stream_decompress(stream_->stream_decompression_ctx, diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc index 5bcdb4e2326..7a37d37fd10 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc @@ -1616,6 +1616,12 @@ static void parse_stream_compression_md(grpc_chttp2_transport* t, s->stream_decompression_method = GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS; } + + if (s->stream_decompression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS) { + s->stream_decompression_ctx = nullptr; + grpc_slice_buffer_init(&s->decompressed_data_buffer); + } } grpc_error* grpc_chttp2_header_parser_parse(void* hpack_parser, diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 00b1fe18b28..0a55ee111ee 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -583,10 +583,6 @@ struct grpc_chttp2_stream { grpc_slice_buffer frame_storage; /* protected by t combiner */ - /* Accessed only by transport thread when stream->pending_byte_stream == false - * Accessed only by application thread when stream->pending_byte_stream == - * true */ - grpc_slice_buffer unprocessed_incoming_frames_buffer; grpc_closure* on_next = nullptr; /* protected by t combiner */ bool pending_byte_stream = false; /* protected by t combiner */ // cached length of buffer to be used by the transport thread in cases where @@ -594,6 +590,10 @@ struct grpc_chttp2_stream { // application threads are allowed to modify // unprocessed_incoming_frames_buffer size_t unprocessed_incoming_frames_buffer_cached_length = 0; + /* Accessed only by transport thread when stream->pending_byte_stream == false + * Accessed only by application thread when stream->pending_byte_stream == + * true */ + grpc_slice_buffer unprocessed_incoming_frames_buffer; grpc_closure reset_byte_stream; grpc_error* byte_stream_error = GRPC_ERROR_NONE; /* protected by t combiner */ bool received_last_frame = false; /* protected by t combiner */ @@ -634,18 +634,7 @@ struct grpc_chttp2_stream { /* Stream decompression method to be used. */ grpc_stream_compression_method stream_decompression_method = GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS; - /** Stream compression decompress context */ - grpc_stream_compression_context* stream_decompression_ctx = nullptr; - /** Stream compression compress context */ - grpc_stream_compression_context* stream_compression_ctx = nullptr; - /** Buffer storing data that is compressed but not sent */ - grpc_slice_buffer compressed_data_buffer; - /** Amount of uncompressed bytes sent out when compressed_data_buffer is - * emptied */ - size_t uncompressed_data_size = 0; - /** Temporary buffer storing decompressed data */ - grpc_slice_buffer decompressed_data_buffer; /** Whether bytes stored in unprocessed_incoming_byte_stream is decompressed */ bool unprocessed_incoming_frames_decompressed = false; @@ -655,6 +644,22 @@ struct grpc_chttp2_stream { size_t decompressed_header_bytes = 0; /** Byte counter for number of bytes written */ size_t byte_counter = 0; + + /** Amount of uncompressed bytes sent out when compressed_data_buffer is + * emptied */ + size_t uncompressed_data_size; + /** Stream compression compress context */ + grpc_stream_compression_context* stream_compression_ctx; + /** Buffer storing data that is compressed but not sent */ + grpc_slice_buffer compressed_data_buffer; + + /** Stream compression decompress context */ + grpc_stream_compression_context* stream_decompression_ctx; + /** Temporary buffer storing decompressed data. + * Initialized, used, and destroyed only when stream uses (non-identity) + * compression. + */ + grpc_slice_buffer decompressed_data_buffer; }; /** Transport writing call flow: diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index 3d1db0aa144..90015bd97ec 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -25,6 +25,7 @@ #include +#include "src/core/lib/compression/stream_compression.h" #include "src/core/lib/debug/stats.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" @@ -150,7 +151,11 @@ static void report_stall(grpc_chttp2_transport* t, grpc_chttp2_stream* s, ":flowed=%" PRId64 ":peer_initwin=%d:t_win=%" PRId64 ":s_win=%d:s_delta=%" PRId64 "]", t->peer_string, t, s->id, staller, s->flow_controlled_buffer.length, - s->compressed_data_buffer.length, s->flow_controlled_bytes_flowed, + s->stream_compression_method == + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS + ? 0 + : s->compressed_data_buffer.length, + s->flow_controlled_bytes_flowed, t->settings[GRPC_ACKED_SETTINGS] [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE], t->flow_control->remote_window(), @@ -325,7 +330,23 @@ class DataSendContext { bool AnyOutgoing() const { return max_outgoing() > 0; } + void FlushUncompressedBytes() { + uint32_t send_bytes = static_cast GPR_MIN( + max_outgoing(), s_->flow_controlled_buffer.length); + is_last_frame_ = send_bytes == s_->flow_controlled_buffer.length && + s_->fetching_send_message == nullptr && + s_->send_trailing_metadata != nullptr && + grpc_metadata_batch_is_empty(s_->send_trailing_metadata); + grpc_chttp2_encode_data(s_->id, &s_->flow_controlled_buffer, send_bytes, + is_last_frame_, &s_->stats.outgoing, &t_->outbuf); + s_->flow_control->SentData(send_bytes); + s_->sending_bytes += send_bytes; + } + void FlushCompressedBytes() { + GPR_DEBUG_ASSERT(s_->stream_compression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS); + uint32_t send_bytes = static_cast GPR_MIN( max_outgoing(), s_->compressed_data_buffer.length); bool is_last_data_frame = @@ -360,6 +381,9 @@ class DataSendContext { } void CompressMoreBytes() { + GPR_DEBUG_ASSERT(s_->stream_compression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS); + if (s_->stream_compression_ctx == nullptr) { s_->stream_compression_ctx = grpc_stream_compression_context_create(s_->stream_compression_method); @@ -417,7 +441,7 @@ class StreamWriteContext { // https://github.com/grpc/proposal/blob/master/A6-client-retries.md#when-retries-are-valid if (!t_->is_client && s_->fetching_send_message == nullptr && s_->flow_controlled_buffer.length == 0 && - s_->compressed_data_buffer.length == 0 && + compressed_data_buffer_len() == 0 && s_->send_trailing_metadata != nullptr && is_default_initial_metadata(s_->send_initial_metadata)) { ConvertInitialMetadataToTrailingMetadata(); @@ -446,6 +470,13 @@ class StreamWriteContext { "send_initial_metadata_finished"); } + bool compressed_data_buffer_len() { + return s_->stream_compression_method == + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS + ? 0 + : s_->compressed_data_buffer.length; + } + void FlushWindowUpdates() { /* send any window updates */ const uint32_t stream_announce = s_->flow_control->MaybeSendUpdate(); @@ -462,7 +493,7 @@ class StreamWriteContext { if (!s_->sent_initial_metadata) return; if (s_->flow_controlled_buffer.length == 0 && - s_->compressed_data_buffer.length == 0) { + compressed_data_buffer_len() == 0) { return; // early out: nothing to do } @@ -479,13 +510,21 @@ class StreamWriteContext { return; // early out: nothing to do } - while ((s_->flow_controlled_buffer.length > 0 || - s_->compressed_data_buffer.length > 0) && - data_send_context.max_outgoing() > 0) { - if (s_->compressed_data_buffer.length > 0) { - data_send_context.FlushCompressedBytes(); - } else { - data_send_context.CompressMoreBytes(); + if (s_->stream_compression_method == + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS) { + while (s_->flow_controlled_buffer.length > 0 && + data_send_context.max_outgoing() > 0) { + data_send_context.FlushUncompressedBytes(); + } + } else { + while ((s_->flow_controlled_buffer.length > 0 || + s_->compressed_data_buffer.length > 0) && + data_send_context.max_outgoing() > 0) { + if (s_->compressed_data_buffer.length > 0) { + data_send_context.FlushCompressedBytes(); + } else { + data_send_context.CompressMoreBytes(); + } } } write_context_->ResetPingClock(); @@ -495,7 +534,7 @@ class StreamWriteContext { data_send_context.CallCallbacks(); stream_became_writable_ = true; if (s_->flow_controlled_buffer.length > 0 || - s_->compressed_data_buffer.length > 0) { + compressed_data_buffer_len() > 0) { GRPC_CHTTP2_STREAM_REF(s_, "chttp2_writing:fork"); grpc_chttp2_list_add_writable_stream(t_, s_); } @@ -508,7 +547,7 @@ class StreamWriteContext { if (s_->send_trailing_metadata == nullptr) return; if (s_->fetching_send_message != nullptr) return; if (s_->flow_controlled_buffer.length != 0) return; - if (s_->compressed_data_buffer.length != 0) return; + if (compressed_data_buffer_len() != 0) return; GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "sending trailing_metadata")); if (grpc_metadata_batch_is_empty(s_->send_trailing_metadata)) { From 1518ecbd76040fa1b9157a53e735c7e2e7c95c64 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Mon, 15 Apr 2019 10:48:30 -0700 Subject: [PATCH 2043/2143] Added new configuration system to core/grp. More generic configuration system is introduced in order to i) unify the way how modules access the configurations instead of using low-level get/setenv functions and ii) enable the customization for where configuration is stored. This could be extended to support flag, file, etc. Default configuration system uses environment variables as before so basically this is expected to work just as it did. This behavior can change by redefining GPR_GLOBAL_CONFIG_DEFINE_*type* macros. * Migrated configuration GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS GRPC_EXPERIMENTAL_DISABLE_FLOW_CONTROL GRPC_ABORT_ON_LEAKS GRPC_NOT_USE_SYSTEM_SSL_ROOTS --- BUILD | 5 + BUILD.gn | 9 ++ CMakeLists.txt | 77 ++++++++++ Makefile | 97 +++++++++++++ build.yaml | 23 +++ config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 8 ++ gRPC-Core.podspec | 9 ++ grpc.gemspec | 5 + grpc.gyp | 1 + package.xml | 5 + .../filters/client_channel/backup_poller.cc | 27 ++-- .../filters/client_channel/backup_poller.h | 3 + .../chttp2/transport/chttp2_plugin.cc | 13 +- src/core/lib/gpr/env.h | 3 + src/core/lib/gpr/env_linux.cc | 5 + src/core/lib/gpr/env_posix.cc | 5 + src/core/lib/gpr/env_windows.cc | 7 + src/core/lib/gpr/string.cc | 18 ++- src/core/lib/gpr/string.h | 6 +- src/core/lib/gprpp/global_config.h | 87 +++++++++++ src/core/lib/gprpp/global_config_custom.h | 29 ++++ src/core/lib/gprpp/global_config_env.cc | 135 ++++++++++++++++++ src/core/lib/gprpp/global_config_env.h | 131 +++++++++++++++++ src/core/lib/gprpp/global_config_generic.h | 44 ++++++ src/core/lib/iomgr/iomgr.cc | 10 +- .../security/security_connector/ssl_utils.cc | 12 +- src/python/grpcio/grpc_core_dependencies.py | 1 + test/core/gpr/env_test.cc | 14 ++ test/core/gpr/string_test.cc | 27 ++-- test/core/gprpp/BUILD | 26 ++++ test/core/gprpp/global_config_env_test.cc | 130 +++++++++++++++++ test/core/gprpp/global_config_test.cc | 65 +++++++++ test/cpp/end2end/async_end2end_test.cc | 3 +- test/cpp/end2end/client_lb_end2end_test.cc | 4 +- test/cpp/end2end/end2end_test.cc | 3 +- test/cpp/end2end/grpclb_end2end_test.cc | 4 +- test/cpp/end2end/xds_end2end_test.cc | 3 +- test/cpp/naming/resolver_component_test.cc | 5 +- tools/doxygen/Doxyfile.c++.internal | 4 + tools/doxygen/Doxyfile.core.internal | 5 + .../generated/sources_and_headers.json | 39 +++++ tools/run_tests/generated/tests.json | 48 +++++++ 44 files changed, 1095 insertions(+), 62 deletions(-) create mode 100644 src/core/lib/gprpp/global_config.h create mode 100644 src/core/lib/gprpp/global_config_custom.h create mode 100644 src/core/lib/gprpp/global_config_env.cc create mode 100644 src/core/lib/gprpp/global_config_env.h create mode 100644 src/core/lib/gprpp/global_config_generic.h create mode 100644 test/core/gprpp/global_config_env_test.cc create mode 100644 test/core/gprpp/global_config_test.cc diff --git a/BUILD b/BUILD index 58043459000..94f2e2a1b75 100644 --- a/BUILD +++ b/BUILD @@ -575,6 +575,7 @@ grpc_cc_library( "src/core/lib/gpr/wrap_memcpy.cc", "src/core/lib/gprpp/arena.cc", "src/core/lib/gprpp/fork.cc", + "src/core/lib/gprpp/global_config_env.cc", "src/core/lib/gprpp/thd_posix.cc", "src/core/lib/gprpp/thd_windows.cc", "src/core/lib/profiling/basic_timers.cc", @@ -601,6 +602,10 @@ grpc_cc_library( "src/core/lib/gprpp/arena.h", "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/global_config.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", diff --git a/BUILD.gn b/BUILD.gn index 38b2f0e6502..f642f6af1c2 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -184,6 +184,11 @@ config("grpc_config") { "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/fork.cc", "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.cc", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", @@ -1170,6 +1175,10 @@ config("grpc_config") { "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/debug_location.h", "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", "src/core/lib/gprpp/inlined_vector.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b93ab08af4..da2326525da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -629,6 +629,8 @@ add_dependencies(buildtests_cxx error_details_test) add_dependencies(buildtests_cxx exception_test) add_dependencies(buildtests_cxx filter_end2end_test) add_dependencies(buildtests_cxx generic_end2end_test) +add_dependencies(buildtests_cxx global_config_env_test) +add_dependencies(buildtests_cxx global_config_test) add_dependencies(buildtests_cxx golden_file_test) add_dependencies(buildtests_cxx grpc_alts_credentials_options_test) add_dependencies(buildtests_cxx grpc_cli) @@ -873,6 +875,7 @@ add_library(gpr src/core/lib/gpr/wrap_memcpy.cc src/core/lib/gprpp/arena.cc src/core/lib/gprpp/fork.cc + src/core/lib/gprpp/global_config_env.cc src/core/lib/gprpp/thd_posix.cc src/core/lib/gprpp/thd_windows.cc src/core/lib/profiling/basic_timers.cc @@ -13422,6 +13425,80 @@ target_link_libraries(generic_end2end_test ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(global_config_env_test + test/core/gprpp/global_config_env_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(global_config_env_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(global_config_env_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + gpr + grpc_test_util_unsecure + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(global_config_test + test/core/gprpp/global_config_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(global_config_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(global_config_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + gpr + grpc_test_util_unsecure + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 700e789265e..2cf316590ec 100644 --- a/Makefile +++ b/Makefile @@ -1206,6 +1206,8 @@ error_details_test: $(BINDIR)/$(CONFIG)/error_details_test exception_test: $(BINDIR)/$(CONFIG)/exception_test filter_end2end_test: $(BINDIR)/$(CONFIG)/filter_end2end_test generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test +global_config_env_test: $(BINDIR)/$(CONFIG)/global_config_env_test +global_config_test: $(BINDIR)/$(CONFIG)/global_config_test golden_file_test: $(BINDIR)/$(CONFIG)/golden_file_test grpc_alts_credentials_options_test: $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli @@ -1682,6 +1684,8 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/exception_test \ $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ + $(BINDIR)/$(CONFIG)/global_config_env_test \ + $(BINDIR)/$(CONFIG)/global_config_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ @@ -1826,6 +1830,8 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/exception_test \ $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ + $(BINDIR)/$(CONFIG)/global_config_env_test \ + $(BINDIR)/$(CONFIG)/global_config_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ @@ -2318,6 +2324,10 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/filter_end2end_test || ( echo test filter_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing generic_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing global_config_env_test" + $(Q) $(BINDIR)/$(CONFIG)/global_config_env_test || ( echo test global_config_env_test failed ; exit 1 ) + $(E) "[RUN] Testing global_config_test" + $(Q) $(BINDIR)/$(CONFIG)/global_config_test || ( echo test global_config_test failed ; exit 1 ) $(E) "[RUN] Testing golden_file_test" $(Q) $(BINDIR)/$(CONFIG)/golden_file_test || ( echo test golden_file_test failed ; exit 1 ) $(E) "[RUN] Testing grpc_alts_credentials_options_test" @@ -3354,6 +3364,7 @@ LIBGPR_SRC = \ src/core/lib/gpr/wrap_memcpy.cc \ src/core/lib/gprpp/arena.cc \ src/core/lib/gprpp/fork.cc \ + src/core/lib/gprpp/global_config_env.cc \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ src/core/lib/profiling/basic_timers.cc \ @@ -16390,6 +16401,92 @@ endif endif +GLOBAL_CONFIG_ENV_TEST_SRC = \ + test/core/gprpp/global_config_env_test.cc \ + +GLOBAL_CONFIG_ENV_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GLOBAL_CONFIG_ENV_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/global_config_env_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)/global_config_env_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/global_config_env_test: $(PROTOBUF_DEP) $(GLOBAL_CONFIG_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(GLOBAL_CONFIG_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/global_config_env_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/gprpp/global_config_env_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a + +deps_global_config_env_test: $(GLOBAL_CONFIG_ENV_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GLOBAL_CONFIG_ENV_TEST_OBJS:.o=.dep) +endif +endif + + +GLOBAL_CONFIG_TEST_SRC = \ + test/core/gprpp/global_config_test.cc \ + +GLOBAL_CONFIG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GLOBAL_CONFIG_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/global_config_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)/global_config_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/global_config_test: $(PROTOBUF_DEP) $(GLOBAL_CONFIG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(GLOBAL_CONFIG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/global_config_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/gprpp/global_config_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a + +deps_global_config_test: $(GLOBAL_CONFIG_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GLOBAL_CONFIG_TEST_OBJS:.o=.dep) +endif +endif + + GOLDEN_FILE_TEST_SRC = \ $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc \ test/cpp/codegen/golden_file_test.cc \ diff --git a/build.yaml b/build.yaml index 848bf4ba072..f333d982961 100644 --- a/build.yaml +++ b/build.yaml @@ -148,6 +148,7 @@ filegroups: - src/core/lib/gpr/wrap_memcpy.cc - src/core/lib/gprpp/arena.cc - src/core/lib/gprpp/fork.cc + - src/core/lib/gprpp/global_config_env.cc - src/core/lib/gprpp/thd_posix.cc - src/core/lib/gprpp/thd_windows.cc - src/core/lib/profiling/basic_timers.cc @@ -194,6 +195,10 @@ filegroups: - src/core/lib/gprpp/arena.h - src/core/lib/gprpp/atomic.h - src/core/lib/gprpp/fork.h + - src/core/lib/gprpp/global_config.h + - src/core/lib/gprpp/global_config_custom.h + - src/core/lib/gprpp/global_config_env.h + - src/core/lib/gprpp/global_config_generic.h - src/core/lib/gprpp/manual_constructor.h - src/core/lib/gprpp/map.h - src/core/lib/gprpp/memory.h @@ -4722,6 +4727,24 @@ targets: - grpc++ - grpc - gpr +- name: global_config_env_test + build: test + language: c++ + src: + - test/core/gprpp/global_config_env_test.cc + deps: + - gpr + - grpc_test_util_unsecure + uses_polling: false +- name: global_config_test + build: test + language: c++ + src: + - test/core/gprpp/global_config_test.cc + deps: + - gpr + - grpc_test_util_unsecure + uses_polling: false - name: golden_file_test gtest: true build: test diff --git a/config.m4 b/config.m4 index 205d425868e..4616922a38b 100644 --- a/config.m4 +++ b/config.m4 @@ -79,6 +79,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/gpr/wrap_memcpy.cc \ src/core/lib/gprpp/arena.cc \ src/core/lib/gprpp/fork.cc \ + src/core/lib/gprpp/global_config_env.cc \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ src/core/lib/profiling/basic_timers.cc \ diff --git a/config.w32 b/config.w32 index 3b0fcdd202e..63048c73492 100644 --- a/config.w32 +++ b/config.w32 @@ -54,6 +54,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\gpr\\wrap_memcpy.cc " + "src\\core\\lib\\gprpp\\arena.cc " + "src\\core\\lib\\gprpp\\fork.cc " + + "src\\core\\lib\\gprpp\\global_config_env.cc " + "src\\core\\lib\\gprpp\\thd_posix.cc " + "src\\core\\lib\\gprpp\\thd_windows.cc " + "src\\core\\lib\\profiling\\basic_timers.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 3ecdcfe82a4..1809171006f 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -267,6 +267,10 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/arena.h', 'src/core/lib/gprpp/atomic.h', 'src/core/lib/gprpp/fork.h', + 'src/core/lib/gprpp/global_config.h', + 'src/core/lib/gprpp/global_config_custom.h', + 'src/core/lib/gprpp/global_config_env.h', + 'src/core/lib/gprpp/global_config_generic.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -589,6 +593,10 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/arena.h', 'src/core/lib/gprpp/atomic.h', 'src/core/lib/gprpp/fork.h', + 'src/core/lib/gprpp/global_config.h', + 'src/core/lib/gprpp/global_config_custom.h', + 'src/core/lib/gprpp/global_config_env.h', + 'src/core/lib/gprpp/global_config_generic.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index b5ff2c622d0..ec8661b4d19 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -208,6 +208,10 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/arena.h', 'src/core/lib/gprpp/atomic.h', 'src/core/lib/gprpp/fork.h', + 'src/core/lib/gprpp/global_config.h', + 'src/core/lib/gprpp/global_config_custom.h', + 'src/core/lib/gprpp/global_config_env.h', + 'src/core/lib/gprpp/global_config_generic.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -250,6 +254,7 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/wrap_memcpy.cc', 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', + 'src/core/lib/gprpp/global_config_env.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', @@ -890,6 +895,10 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/arena.h', 'src/core/lib/gprpp/atomic.h', 'src/core/lib/gprpp/fork.h', + 'src/core/lib/gprpp/global_config.h', + 'src/core/lib/gprpp/global_config_custom.h', + 'src/core/lib/gprpp/global_config_env.h', + 'src/core/lib/gprpp/global_config_generic.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', diff --git a/grpc.gemspec b/grpc.gemspec index 943e0aaa1a7..59296e8e251 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -102,6 +102,10 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/arena.h ) s.files += %w( src/core/lib/gprpp/atomic.h ) s.files += %w( src/core/lib/gprpp/fork.h ) + s.files += %w( src/core/lib/gprpp/global_config.h ) + s.files += %w( src/core/lib/gprpp/global_config_custom.h ) + s.files += %w( src/core/lib/gprpp/global_config_env.h ) + s.files += %w( src/core/lib/gprpp/global_config_generic.h ) s.files += %w( src/core/lib/gprpp/manual_constructor.h ) s.files += %w( src/core/lib/gprpp/map.h ) s.files += %w( src/core/lib/gprpp/memory.h ) @@ -144,6 +148,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gpr/wrap_memcpy.cc ) s.files += %w( src/core/lib/gprpp/arena.cc ) s.files += %w( src/core/lib/gprpp/fork.cc ) + s.files += %w( src/core/lib/gprpp/global_config_env.cc ) s.files += %w( src/core/lib/gprpp/thd_posix.cc ) s.files += %w( src/core/lib/gprpp/thd_windows.cc ) s.files += %w( src/core/lib/profiling/basic_timers.cc ) diff --git a/grpc.gyp b/grpc.gyp index 5321658508a..14d98d003a6 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -252,6 +252,7 @@ 'src/core/lib/gpr/wrap_memcpy.cc', 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', + 'src/core/lib/gprpp/global_config_env.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', diff --git a/package.xml b/package.xml index c3e25173349..52b954e20c6 100644 --- a/package.xml +++ b/package.xml @@ -107,6 +107,10 @@ + + + + @@ -149,6 +153,7 @@ + diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc index 3e2faa57bcf..a2d45c04026 100644 --- a/src/core/ext/filters/client_channel/backup_poller.cc +++ b/src/core/ext/filters/client_channel/backup_poller.cc @@ -25,8 +25,8 @@ #include #include #include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/timer.h" @@ -56,21 +56,22 @@ static backup_poller* g_poller = nullptr; // guarded by g_poller_mu // treated as const. static int g_poll_interval_ms = DEFAULT_POLL_INTERVAL_MS; +GPR_GLOBAL_CONFIG_DEFINE_INT32(grpc_client_channel_backup_poll_interval_ms, + DEFAULT_POLL_INTERVAL_MS, + "Client channel backup poll interval (ms)"); + static void init_globals() { gpr_mu_init(&g_poller_mu); - char* env = gpr_getenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS"); - if (env != nullptr) { - int poll_interval_ms = gpr_parse_nonnegative_int(env); - if (poll_interval_ms == -1) { - gpr_log(GPR_ERROR, - "Invalid GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS: %s, " - "default value %d will be used.", - env, g_poll_interval_ms); - } else { - g_poll_interval_ms = poll_interval_ms; - } + int32_t poll_interval_ms = + GPR_GLOBAL_CONFIG_GET(grpc_client_channel_backup_poll_interval_ms); + if (poll_interval_ms < 0) { + gpr_log(GPR_ERROR, + "Invalid GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS: %d, " + "default value %d will be used.", + poll_interval_ms, g_poll_interval_ms); + } else { + g_poll_interval_ms = poll_interval_ms; } - gpr_free(env); } static void backup_poller_shutdown_unref(backup_poller* p) { diff --git a/src/core/ext/filters/client_channel/backup_poller.h b/src/core/ext/filters/client_channel/backup_poller.h index 8f132f968ce..e1bf4f88b2a 100644 --- a/src/core/ext/filters/client_channel/backup_poller.h +++ b/src/core/ext/filters/client_channel/backup_poller.h @@ -23,6 +23,9 @@ #include #include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/gprpp/global_config.h" + +GPR_GLOBAL_CONFIG_DECLARE_INT32(grpc_client_channel_backup_poll_interval_ms); /* Start polling \a interested_parties periodically in the timer thread */ void grpc_client_channel_start_backup_polling( diff --git a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc index 531ea73e9e6..4c929d00ec9 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc @@ -20,16 +20,15 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/transport/metadata.h" +GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_experimental_disable_flow_control, false, + "Disable flow control"); + void grpc_chttp2_plugin_init(void) { - g_flow_control_enabled = true; - char* env_variable = gpr_getenv("GRPC_EXPERIMENTAL_DISABLE_FLOW_CONTROL"); - if (env_variable != nullptr) { - g_flow_control_enabled = false; - gpr_free(env_variable); - } + g_flow_control_enabled = + !GPR_GLOBAL_CONFIG_GET(grpc_experimental_disable_flow_control); } void grpc_chttp2_plugin_shutdown(void) {} diff --git a/src/core/lib/gpr/env.h b/src/core/lib/gpr/env.h index aec8a3166b1..5956d17fcfe 100644 --- a/src/core/lib/gpr/env.h +++ b/src/core/lib/gpr/env.h @@ -40,4 +40,7 @@ void gpr_setenv(const char* name, const char* value); level of logging. So DO NOT USE THIS. */ const char* gpr_getenv_silent(const char* name, char** dst); +/* Deletes the variable name from the environment. */ +void gpr_unsetenv(const char* name); + #endif /* GRPC_CORE_LIB_GPR_ENV_H */ diff --git a/src/core/lib/gpr/env_linux.cc b/src/core/lib/gpr/env_linux.cc index fadc42f22f1..e84a9f6064c 100644 --- a/src/core/lib/gpr/env_linux.cc +++ b/src/core/lib/gpr/env_linux.cc @@ -79,4 +79,9 @@ void gpr_setenv(const char* name, const char* value) { GPR_ASSERT(res == 0); } +void gpr_unsetenv(const char* name) { + int res = unsetenv(name); + GPR_ASSERT(res == 0); +} + #endif /* GPR_LINUX_ENV */ diff --git a/src/core/lib/gpr/env_posix.cc b/src/core/lib/gpr/env_posix.cc index 599f85aa72b..30ddc50f682 100644 --- a/src/core/lib/gpr/env_posix.cc +++ b/src/core/lib/gpr/env_posix.cc @@ -44,4 +44,9 @@ void gpr_setenv(const char* name, const char* value) { GPR_ASSERT(res == 0); } +void gpr_unsetenv(const char* name) { + int res = unsetenv(name); + GPR_ASSERT(res == 0); +} + #endif /* GPR_POSIX_ENV */ diff --git a/src/core/lib/gpr/env_windows.cc b/src/core/lib/gpr/env_windows.cc index cf8ed60d8f6..72850a9587d 100644 --- a/src/core/lib/gpr/env_windows.cc +++ b/src/core/lib/gpr/env_windows.cc @@ -69,4 +69,11 @@ void gpr_setenv(const char* name, const char* value) { GPR_ASSERT(res); } +void gpr_unsetenv(const char* name) { + LPTSTR tname = gpr_char_to_tchar(name); + BOOL res = SetEnvironmentVariable(tname, NULL); + gpr_free(tname); + GPR_ASSERT(res); +} + #endif /* GPR_WINDOWS_ENV */ diff --git a/src/core/lib/gpr/string.cc b/src/core/lib/gpr/string.cc index 0a76fc1f54a..31d5fdee5be 100644 --- a/src/core/lib/gpr/string.cc +++ b/src/core/lib/gpr/string.cc @@ -332,16 +332,22 @@ void* gpr_memrchr(const void* s, int c, size_t n) { return nullptr; } -bool gpr_is_true(const char* s) { - size_t i; +bool gpr_parse_bool_value(const char* s, bool* dst) { + const char* kTrue[] = {"1", "t", "true", "y", "yes"}; + const char* kFalse[] = {"0", "f", "false", "n", "no"}; + static_assert(sizeof(kTrue) == sizeof(kFalse), "true_false_equal"); + if (s == nullptr) { return false; } - static const char* truthy[] = {"yes", "true", "1"}; - for (i = 0; i < GPR_ARRAY_SIZE(truthy); i++) { - if (0 == gpr_stricmp(s, truthy[i])) { + for (size_t i = 0; i < GPR_ARRAY_SIZE(kTrue); ++i) { + if (gpr_stricmp(s, kTrue[i]) == 0) { + *dst = true; + return true; + } else if (gpr_stricmp(s, kFalse[i]) == 0) { + *dst = false; return true; } } - return false; + return false; // didn't match a legal input } diff --git a/src/core/lib/gpr/string.h b/src/core/lib/gpr/string.h index ce51fe46321..c5efcec3bb1 100644 --- a/src/core/lib/gpr/string.h +++ b/src/core/lib/gpr/string.h @@ -113,7 +113,9 @@ int gpr_stricmp(const char* a, const char* b); void* gpr_memrchr(const void* s, int c, size_t n); -/** Return true if lower(s) equals "true", "yes" or "1", otherwise false. */ -bool gpr_is_true(const char* s); +/* Try to parse given string into a boolean value. + When parsed successfully, dst will have the value and returns true. + Otherwise, it returns false. */ +bool gpr_parse_bool_value(const char* value, bool* dst); #endif /* GRPC_CORE_LIB_GPR_STRING_H */ diff --git a/src/core/lib/gprpp/global_config.h b/src/core/lib/gprpp/global_config.h new file mode 100644 index 00000000000..a1bbf07564c --- /dev/null +++ b/src/core/lib/gprpp/global_config.h @@ -0,0 +1,87 @@ +/* + * + * 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_GLOBAL_CONFIG_H +#define GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_H + +#include + +#include + +// -------------------------------------------------------------------- +// How to use global configuration variables: +// +// Defining config variables of a specified type: +// GPR_GLOBAL_CONFIG_DEFINE_*TYPE*(name, default_value, help); +// +// Supported TYPEs: BOOL, INT32, STRING +// +// It's recommended to use lowercase letters for 'name' like +// regular variables. The builtin configuration system uses +// environment variable and the name is converted to uppercase +// when looking up the value. For example, +// GPR_GLOBAL_CONFIG_DEFINE(grpc_latency) looks up the value with the +// name, "GRPC_LATENCY". +// +// The variable initially has the specified 'default_value' +// which must be an expression convertible to 'Type'. +// 'default_value' may be evaluated 0 or more times, +// and at an unspecified time; keep it +// simple and usually free of side-effects. +// +// GPR_GLOBAL_CONFIG_DEFINE_*TYPE* should not be called in a C++ header. +// It should be called at the top-level (outside any namespaces) +// in a .cc file. +// +// Getting the variables: +// GPR_GLOBAL_CONFIG_GET(name) +// +// If error happens during getting variables, error messages will +// be logged and default value will be returned. +// +// Setting the variables with new value: +// GPR_GLOBAL_CONFIG_SET(name, new_value) +// +// Declaring config variables for other modules to access: +// GPR_GLOBAL_CONFIG_DECLARE_*TYPE*(name) + +// -------------------------------------------------------------------- +// How to customize the global configuration system: +// +// How to read and write configuration value can be customized. +// Builtin system uses environment variables but it can be extended to +// support command-line flag, file, etc. +// +// To customize it, following macros should be redefined. +// +// GPR_GLOBAL_CONFIG_DEFINE_BOOL +// GPR_GLOBAL_CONFIG_DEFINE_INT32 +// GPR_GLOBAL_CONFIG_DEFINE_STRING +// +// These macros should define functions for getting and setting variable. +// For example, GPR_GLOBAL_CONFIG_DEFINE_BOOL(test, ...) would define two +// functions. +// +// bool gpr_global_config_get_test(); +// void gpr_global_config_set_test(bool value); + +#include "src/core/lib/gprpp/global_config_env.h" + +#include "src/core/lib/gprpp/global_config_custom.h" + +#endif /* GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_H */ diff --git a/src/core/lib/gprpp/global_config_custom.h b/src/core/lib/gprpp/global_config_custom.h new file mode 100644 index 00000000000..dd011fb34bf --- /dev/null +++ b/src/core/lib/gprpp/global_config_custom.h @@ -0,0 +1,29 @@ +/* + * + * 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_GLOBAL_CONFIG_CUSTOM_H +#define GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_CUSTOM_H + +// This is a placeholder for custom global configuration implementaion. +// To use the custom one, please define following macros here. +// +// GPR_GLOBAL_CONFIG_DEFINE_BOOL +// GPR_GLOBAL_CONFIG_DEFINE_INT32 +// GPR_GLOBAL_CONFIG_DEFINE_STRING + +#endif /* GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_CUSTOM_H */ diff --git a/src/core/lib/gprpp/global_config_env.cc b/src/core/lib/gprpp/global_config_env.cc new file mode 100644 index 00000000000..fb14805d01b --- /dev/null +++ b/src/core/lib/gprpp/global_config_env.cc @@ -0,0 +1,135 @@ +/* + * + * 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 "src/core/lib/gprpp/global_config_env.h" + +#include +#include +#include + +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" + +#include +#include + +namespace grpc_core { + +namespace { + +void DefaultGlobalConfigEnvErrorFunction(const char* error_message) { + gpr_log(GPR_ERROR, "%s", error_message); +} + +GlobalConfigEnvErrorFunctionType g_global_config_env_error_func = + DefaultGlobalConfigEnvErrorFunction; + +void LogParsingError(const char* name, const char* value) { + char* error_message; + gpr_asprintf(&error_message, + "Illegal value '%s' specified for environment variable '%s'", + value, name); + (*g_global_config_env_error_func)(error_message); + gpr_free(error_message); +} + +} // namespace + +void SetGlobalConfigEnvErrorFunction(GlobalConfigEnvErrorFunctionType func) { + g_global_config_env_error_func = func; +} + +UniquePtr GlobalConfigEnv::GetValue() { + return UniquePtr(gpr_getenv(GetName())); +} + +void GlobalConfigEnv::SetValue(const char* value) { + gpr_setenv(GetName(), value); +} + +void GlobalConfigEnv::Unset() { gpr_unsetenv(GetName()); } + +char* GlobalConfigEnv::GetName() { + // This makes sure that name_ is in a canonical form having uppercase + // letters. This is okay to be called serveral times. + for (char* c = name_; *c != 0; ++c) { + *c = toupper(*c); + } + return name_; +} +static_assert(std::is_trivially_destructible::value, + "GlobalConfigEnvBool needs to be trivially destructible."); + +bool GlobalConfigEnvBool::Get() { + UniquePtr str = GetValue(); + if (str == nullptr) { + return default_value_; + } + // parsing given value string. + bool result = false; + if (!gpr_parse_bool_value(str.get(), &result)) { + LogParsingError(GetName(), str.get()); + result = default_value_; + } + return result; +} + +void GlobalConfigEnvBool::Set(bool value) { + SetValue(value ? "true" : "false"); +} + +static_assert(std::is_trivially_destructible::value, + "GlobalConfigEnvInt32 needs to be trivially destructible."); + +int32_t GlobalConfigEnvInt32::Get() { + UniquePtr str = GetValue(); + if (str == nullptr) { + return default_value_; + } + // parsing given value string. + char* end = str.get(); + long result = strtol(str.get(), &end, 10); + if (*end != 0) { + LogParsingError(GetName(), str.get()); + result = default_value_; + } + return static_cast(result); +} + +void GlobalConfigEnvInt32::Set(int32_t value) { + char buffer[GPR_LTOA_MIN_BUFSIZE]; + gpr_ltoa(value, buffer); + SetValue(buffer); +} + +static_assert(std::is_trivially_destructible::value, + "GlobalConfigEnvString needs to be trivially destructible."); + +UniquePtr GlobalConfigEnvString::Get() { + UniquePtr str = GetValue(); + if (str == nullptr) { + return UniquePtr(gpr_strdup(default_value_)); + } + return str; +} + +void GlobalConfigEnvString::Set(const char* value) { SetValue(value); } + +} // namespace grpc_core diff --git a/src/core/lib/gprpp/global_config_env.h b/src/core/lib/gprpp/global_config_env.h new file mode 100644 index 00000000000..3d3038895d3 --- /dev/null +++ b/src/core/lib/gprpp/global_config_env.h @@ -0,0 +1,131 @@ +/* + * + * 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_GLOBAL_CONFIG_ENV_H +#define GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_ENV_H + +#include + +#include "src/core/lib/gprpp/global_config_generic.h" +#include "src/core/lib/gprpp/memory.h" + +namespace grpc_core { + +typedef void (*GlobalConfigEnvErrorFunctionType)(const char* error_message); + +/* + * Set global_config_env_error_function which is called when config system + * encounters errors such as parsing error. What the default function does + * is logging error message. + */ +void SetGlobalConfigEnvErrorFunction(GlobalConfigEnvErrorFunctionType func); + +// Base class for all classes to access environment variables. +class GlobalConfigEnv { + protected: + // `name` should be writable and alive after constructor is called. + constexpr explicit GlobalConfigEnv(char* name) : name_(name) {} + + public: + // Returns the value of `name` variable. + UniquePtr GetValue(); + + // Sets the value of `name` variable. + void SetValue(const char* value); + + // Unsets `name` variable. + void Unset(); + + protected: + char* GetName(); + + private: + char* name_; +}; + +class GlobalConfigEnvBool : public GlobalConfigEnv { + public: + constexpr GlobalConfigEnvBool(char* name, bool default_value) + : GlobalConfigEnv(name), default_value_(default_value) {} + + bool Get(); + void Set(bool value); + + private: + bool default_value_; +}; + +class GlobalConfigEnvInt32 : public GlobalConfigEnv { + public: + constexpr GlobalConfigEnvInt32(char* name, int32_t default_value) + : GlobalConfigEnv(name), default_value_(default_value) {} + + int32_t Get(); + void Set(int32_t value); + + private: + int32_t default_value_; +}; + +class GlobalConfigEnvString : public GlobalConfigEnv { + public: + constexpr GlobalConfigEnvString(char* name, const char* default_value) + : GlobalConfigEnv(name), default_value_(default_value) {} + + UniquePtr Get(); + void Set(const char* value); + + private: + const char* default_value_; +}; + +} // namespace grpc_core + +// Macros for defining global config instances using environment variables. +// This defines a GlobalConfig*Type* instance with arguments for +// mutable variable name and default value. +// Mutable name (g_env_str_##name) is here for having an array +// for the canonical name without dynamic allocation. +// `help` argument is ignored for this implementation. + +#define GPR_GLOBAL_CONFIG_DEFINE_BOOL(name, default_value, help) \ + static char g_env_str_##name[] = #name; \ + static ::grpc_core::GlobalConfigEnvBool g_env_##name(g_env_str_##name, \ + default_value); \ + bool gpr_global_config_get_##name() { return g_env_##name.Get(); } \ + void gpr_global_config_set_##name(bool value) { g_env_##name.Set(value); } + +#define GPR_GLOBAL_CONFIG_DEFINE_INT32(name, default_value, help) \ + static char g_env_str_##name[] = #name; \ + static ::grpc_core::GlobalConfigEnvInt32 g_env_##name(g_env_str_##name, \ + default_value); \ + int32_t gpr_global_config_get_##name() { return g_env_##name.Get(); } \ + void gpr_global_config_set_##name(int32_t value) { g_env_##name.Set(value); } + +#define GPR_GLOBAL_CONFIG_DEFINE_STRING(name, default_value, help) \ + static char g_env_str_##name[] = #name; \ + static ::grpc_core::GlobalConfigEnvString g_env_##name(g_env_str_##name, \ + default_value); \ + ::grpc_core::UniquePtr gpr_global_config_get_##name() { \ + return g_env_##name.Get(); \ + } \ + void gpr_global_config_set_##name(const char* value) { \ + g_env_##name.Set(value); \ + } + +#endif /* GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_ENV_H */ diff --git a/src/core/lib/gprpp/global_config_generic.h b/src/core/lib/gprpp/global_config_generic.h new file mode 100644 index 00000000000..d3e3e2a2dbe --- /dev/null +++ b/src/core/lib/gprpp/global_config_generic.h @@ -0,0 +1,44 @@ +/* + * + * 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_GLOBAL_CONFIG_GENERIC_H +#define GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_GENERIC_H + +#include + +#include "src/core/lib/gprpp/memory.h" + +#include + +#define GPR_GLOBAL_CONFIG_GET(name) gpr_global_config_get_##name() + +#define GPR_GLOBAL_CONFIG_SET(name, value) gpr_global_config_set_##name(value) + +#define GPR_GLOBAL_CONFIG_DECLARE_BOOL(name) \ + extern bool gpr_global_config_get_##name(); \ + extern void gpr_global_config_set_##name(bool value) + +#define GPR_GLOBAL_CONFIG_DECLARE_INT32(name) \ + extern int32_t gpr_global_config_get_##name(); \ + extern void gpr_global_config_set_##name(int32_t value) + +#define GPR_GLOBAL_CONFIG_DECLARE_STRING(name) \ + extern grpc_core::UniquePtr gpr_global_config_get_##name(); \ + extern void gpr_global_config_set_##name(const char* value) + +#endif /* GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_GENERIC_H */ diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index 0fbfcfce04f..fd011788a06 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -29,9 +29,9 @@ #include #include -#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/gprpp/global_config.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/buffer_list.h" #include "src/core/lib/iomgr/exec_ctx.h" @@ -41,6 +41,9 @@ #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/timer_manager.h" +GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_abort_on_leaks, false, + "Abort when leak is found"); + static gpr_mu g_mu; static gpr_cv g_rcv; static int g_shutdown; @@ -186,8 +189,5 @@ void grpc_iomgr_unregister_object(grpc_iomgr_object* obj) { } bool grpc_iomgr_abort_on_leaks(void) { - char* env = gpr_getenv("GRPC_ABORT_ON_LEAKS"); - bool should_we = gpr_is_true(env); - gpr_free(env); - return should_we; + return GPR_GLOBAL_CONFIG_GET(grpc_abort_on_leaks); } diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index c9af5ca6ad0..1eefff6fe24 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -30,6 +30,7 @@ #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/gprpp/global_config.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/context/security_context.h" @@ -47,9 +48,8 @@ static const char* installed_roots_path = /** Environment variable used as a flag to enable/disable loading system root certificates from the OS trust store. */ -#ifndef GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR -#define GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR "GRPC_NOT_USE_SYSTEM_SSL_ROOTS" -#endif +GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_not_use_system_ssl_roots, false, + "Disable loading system root certificates."); #ifndef TSI_OPENSSL_ALPN_SUPPORT #define TSI_OPENSSL_ALPN_SUPPORT 1 @@ -428,10 +428,8 @@ const char* DefaultSslRootStore::GetPemRootCerts() { grpc_slice DefaultSslRootStore::ComputePemRootCerts() { grpc_slice result = grpc_empty_slice(); - char* not_use_system_roots_env_value = - gpr_getenv(GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR); - const bool not_use_system_roots = gpr_is_true(not_use_system_roots_env_value); - gpr_free(not_use_system_roots_env_value); + const bool not_use_system_roots = + GPR_GLOBAL_CONFIG_GET(grpc_not_use_system_ssl_roots); // First try to load the roots from the environment. char* default_root_certs_path = gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 2e358f9c1ef..615bf4ee0dc 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -53,6 +53,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/gpr/wrap_memcpy.cc', 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', + 'src/core/lib/gprpp/global_config_env.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', diff --git a/test/core/gpr/env_test.cc b/test/core/gpr/env_test.cc index a8206bd3cfd..3883a5df997 100644 --- a/test/core/gpr/env_test.cc +++ b/test/core/gpr/env_test.cc @@ -42,8 +42,22 @@ static void test_setenv_getenv(void) { gpr_free(retrieved_value); } +static void test_unsetenv(void) { + const char* name = "FOO"; + const char* value = "BAR"; + char* retrieved_value; + + LOG_TEST_NAME("test_unsetenv"); + + gpr_setenv(name, value); + gpr_unsetenv(name); + retrieved_value = gpr_getenv(name); + GPR_ASSERT(retrieved_value == nullptr); +} + int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); test_setenv_getenv(); + test_unsetenv(); return 0; } diff --git a/test/core/gpr/string_test.cc b/test/core/gpr/string_test.cc index 7da7b18778b..5e3ed9d5dfd 100644 --- a/test/core/gpr/string_test.cc +++ b/test/core/gpr/string_test.cc @@ -279,19 +279,20 @@ static void test_memrchr(void) { GPR_ASSERT(0 == strcmp((const char*)gpr_memrchr("hello", 'l', 5), "lo")); } -static void test_is_true(void) { - LOG_TEST_NAME("test_is_true"); +static void test_parse_bool_value(void) { + LOG_TEST_NAME("test_parse_bool_value"); - GPR_ASSERT(true == gpr_is_true("True")); - GPR_ASSERT(true == gpr_is_true("true")); - GPR_ASSERT(true == gpr_is_true("TRUE")); - GPR_ASSERT(true == gpr_is_true("Yes")); - GPR_ASSERT(true == gpr_is_true("yes")); - GPR_ASSERT(true == gpr_is_true("YES")); - GPR_ASSERT(true == gpr_is_true("1")); - GPR_ASSERT(false == gpr_is_true(nullptr)); - GPR_ASSERT(false == gpr_is_true("")); - GPR_ASSERT(false == gpr_is_true("0")); + bool ret; + GPR_ASSERT(true == gpr_parse_bool_value("truE", &ret) && true == ret); + GPR_ASSERT(true == gpr_parse_bool_value("falsE", &ret) && false == ret); + GPR_ASSERT(true == gpr_parse_bool_value("1", &ret) && true == ret); + GPR_ASSERT(true == gpr_parse_bool_value("0", &ret) && false == ret); + GPR_ASSERT(true == gpr_parse_bool_value("Yes", &ret) && true == ret); + GPR_ASSERT(true == gpr_parse_bool_value("No", &ret) && false == ret); + GPR_ASSERT(true == gpr_parse_bool_value("Y", &ret) && true == ret); + GPR_ASSERT(true == gpr_parse_bool_value("N", &ret) && false == ret); + GPR_ASSERT(false == gpr_parse_bool_value(nullptr, &ret)); + GPR_ASSERT(false == gpr_parse_bool_value("", &ret)); } int main(int argc, char** argv) { @@ -307,6 +308,6 @@ int main(int argc, char** argv) { test_leftpad(); test_stricmp(); test_memrchr(); - test_is_true(); + test_parse_bool_value(); return 0; } diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD index 4665827e10f..cd3232addfd 100644 --- a/test/core/gprpp/BUILD +++ b/test/core/gprpp/BUILD @@ -28,6 +28,32 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "global_config_test", + srcs = ["global_config_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "global_config_env_test", + srcs = ["global_config_env_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "manual_constructor_test", srcs = ["manual_constructor_test.cc"], diff --git a/test/core/gprpp/global_config_env_test.cc b/test/core/gprpp/global_config_env_test.cc new file mode 100644 index 00000000000..74905d3b07c --- /dev/null +++ b/test/core/gprpp/global_config_env_test.cc @@ -0,0 +1,130 @@ +/* + * + * 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 "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/global_config_env.h" +#include "src/core/lib/gprpp/memory.h" + +namespace { + +bool g_config_error_function_called; + +void ClearConfigErrorCalled() { g_config_error_function_called = false; } + +bool IsConfigErrorCalled() { return g_config_error_function_called; } + +// This function is for preventing the program from invoking +// an error handler due to configuration error and +// make test routines know whether there is error. +void FakeConfigErrorFunction(const char* error_message) { + g_config_error_function_called = true; +} + +class GlobalConfigEnvTest : public ::testing::Test { + protected: + void SetUp() override { ClearConfigErrorCalled(); } + void TearDown() override { EXPECT_FALSE(IsConfigErrorCalled()); } +}; + +} // namespace + +GPR_GLOBAL_CONFIG_DEFINE_BOOL(bool_var, true, ""); +GPR_GLOBAL_CONFIG_DEFINE_INT32(int32_var, 1234, ""); +GPR_GLOBAL_CONFIG_DEFINE_STRING(string_var, "Apple", ""); + +TEST_F(GlobalConfigEnvTest, BoolWithEnvTest) { + const char* bool_var_name = "BOOL_VAR"; + + gpr_unsetenv(bool_var_name); + EXPECT_TRUE(GPR_GLOBAL_CONFIG_GET(bool_var)); + + gpr_setenv(bool_var_name, "true"); + EXPECT_TRUE(GPR_GLOBAL_CONFIG_GET(bool_var)); + + gpr_setenv(bool_var_name, "false"); + EXPECT_FALSE(GPR_GLOBAL_CONFIG_GET(bool_var)); + + EXPECT_FALSE(IsConfigErrorCalled()); + + gpr_setenv(bool_var_name, ""); + GPR_GLOBAL_CONFIG_GET(bool_var); + EXPECT_TRUE(IsConfigErrorCalled()); + ClearConfigErrorCalled(); + + gpr_setenv(bool_var_name, "!"); + GPR_GLOBAL_CONFIG_GET(bool_var); + EXPECT_TRUE(IsConfigErrorCalled()); + ClearConfigErrorCalled(); +} + +TEST_F(GlobalConfigEnvTest, Int32WithEnvTest) { + const char* int32_var_name = "INT32_VAR"; + + gpr_unsetenv(int32_var_name); + EXPECT_EQ(1234, GPR_GLOBAL_CONFIG_GET(int32_var)); + + gpr_setenv(int32_var_name, "0"); + EXPECT_EQ(0, GPR_GLOBAL_CONFIG_GET(int32_var)); + + gpr_setenv(int32_var_name, "-123456789"); + EXPECT_EQ(-123456789, GPR_GLOBAL_CONFIG_GET(int32_var)); + + gpr_setenv(int32_var_name, "123456789"); + EXPECT_EQ(123456789, GPR_GLOBAL_CONFIG_GET(int32_var)); + + EXPECT_FALSE(IsConfigErrorCalled()); + + gpr_setenv(int32_var_name, "-1AB"); + GPR_GLOBAL_CONFIG_GET(int32_var); + EXPECT_TRUE(IsConfigErrorCalled()); + ClearConfigErrorCalled(); +} + +TEST_F(GlobalConfigEnvTest, StringWithEnvTest) { + const char* string_var_name = "STRING_VAR"; + grpc_core::UniquePtr value; + + gpr_unsetenv(string_var_name); + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "Apple")); + + gpr_setenv(string_var_name, "Banana"); + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "Banana")); + + gpr_setenv(string_var_name, ""); + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "")); +} + +int main(int argc, char** argv) { + // Not to abort the test when parsing error happens. + grpc_core::SetGlobalConfigEnvErrorFunction(&FakeConfigErrorFunction); + + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/test/core/gprpp/global_config_test.cc b/test/core/gprpp/global_config_test.cc new file mode 100644 index 00000000000..7da78b690b1 --- /dev/null +++ b/test/core/gprpp/global_config_test.cc @@ -0,0 +1,65 @@ +/* + * + * 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 "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/global_config.h" +#include "src/core/lib/gprpp/memory.h" + +GPR_GLOBAL_CONFIG_DECLARE_BOOL(bool_var); + +GPR_GLOBAL_CONFIG_DEFINE_BOOL(bool_var, false, ""); +GPR_GLOBAL_CONFIG_DEFINE_INT32(int32_var, 0, ""); +GPR_GLOBAL_CONFIG_DEFINE_STRING(string_var, "", ""); + +TEST(GlobalConfigTest, BoolTest) { + EXPECT_FALSE(GPR_GLOBAL_CONFIG_GET(bool_var)); + GPR_GLOBAL_CONFIG_SET(bool_var, true); + EXPECT_TRUE(GPR_GLOBAL_CONFIG_GET(bool_var)); +} + +TEST(GlobalConfigTest, Int32Test) { + EXPECT_EQ(0, GPR_GLOBAL_CONFIG_GET(int32_var)); + GPR_GLOBAL_CONFIG_SET(int32_var, 1024); + EXPECT_EQ(1024, GPR_GLOBAL_CONFIG_GET(int32_var)); +} + +TEST(GlobalConfigTest, StringTest) { + grpc_core::UniquePtr value; + + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "")); + + GPR_GLOBAL_CONFIG_SET(string_var, "Test"); + + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "Test")); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index e09f54dcc3f..840d668e0d8 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -32,6 +32,7 @@ #include #include +#include "src/core/ext/filters/client_channel/backup_poller.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/tls.h" #include "src/core/lib/iomgr/port.h" @@ -1883,7 +1884,7 @@ INSTANTIATE_TEST_CASE_P(AsyncEnd2endServerTryCancel, int main(int argc, char** argv) { // Change the backup poll interval from 5s to 100ms to speed up the // ReconnectChannel test - gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "100"); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 100); grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 6623a2ff55f..ca20ebbaeee 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -37,13 +37,13 @@ #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/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/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/tcp_client.h" @@ -142,7 +142,7 @@ class ClientLbEnd2endTest : public ::testing::Test { grpc_fake_transport_security_credentials_create())) { // 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"); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); } void SetUp() override { diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index fb951fd44e6..a2b9ebe7197 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -34,6 +34,7 @@ #include #include +#include "src/core/ext/filters/client_channel/backup_poller.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/security/credentials/credentials.h" @@ -2104,7 +2105,7 @@ INSTANTIATE_TEST_CASE_P( } // namespace grpc int main(int argc, char** argv) { - gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "200"); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 200); grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index bd915b04eee..f93e2548c8e 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -34,11 +34,11 @@ #include #include +#include "src/core/ext/filters/client_channel/backup_poller.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/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" #include "src/core/lib/security/credentials/fake/fake_credentials.h" @@ -375,7 +375,7 @@ class GrpclbEnd2endTest : public ::testing::Test { 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"); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); } void SetUp() override { diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index 2952c194d48..d6f2685642c 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -33,6 +33,7 @@ #include #include +#include "src/core/ext/filters/client_channel/backup_poller.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" @@ -370,7 +371,7 @@ class XdsEnd2endTest : public ::testing::Test { 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"); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); } void SetUp() override { diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 2e54993a31c..4d1beb7ec37 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -146,8 +146,9 @@ vector ParseExpectedAddrs(std::string expected_addrs) { expected_addrs = expected_addrs.substr(next_comma + 1, std::string::npos); // get the next is_balancer 'bool' associated with this address size_t next_semicolon = expected_addrs.find(';'); - bool is_balancer = - gpr_is_true(expected_addrs.substr(0, next_semicolon).c_str()); + bool is_balancer = false; + gpr_parse_bool_value(expected_addrs.substr(0, next_semicolon).c_str(), + &is_balancer); out.emplace_back(GrpcLBAddress(next_addr, is_balancer)); if (next_semicolon == std::string::npos) { break; diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 357efa0d684..bc2a32d3cfd 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1086,6 +1086,10 @@ src/core/lib/gprpp/arena.h \ src/core/lib/gprpp/atomic.h \ src/core/lib/gprpp/debug_location.h \ src/core/lib/gprpp/fork.h \ +src/core/lib/gprpp/global_config.h \ +src/core/lib/gprpp/global_config_custom.h \ +src/core/lib/gprpp/global_config_env.h \ +src/core/lib/gprpp/global_config_generic.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 3a9951b0364..870d6348df0 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1165,6 +1165,11 @@ src/core/lib/gprpp/atomic.h \ src/core/lib/gprpp/debug_location.h \ src/core/lib/gprpp/fork.cc \ src/core/lib/gprpp/fork.h \ +src/core/lib/gprpp/global_config.h \ +src/core/lib/gprpp/global_config_custom.h \ +src/core/lib/gprpp/global_config_env.cc \ +src/core/lib/gprpp/global_config_env.h \ +src/core/lib/gprpp/global_config_generic.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 9778343cd94..e07bb48675a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3662,6 +3662,36 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc_test_util_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "global_config_env_test", + "src": [ + "test/core/gprpp/global_config_env_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", + "grpc_test_util_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "global_config_test", + "src": [ + "test/core/gprpp/global_config_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -8019,6 +8049,7 @@ "src/core/lib/gpr/wrap_memcpy.cc", "src/core/lib/gprpp/arena.cc", "src/core/lib/gprpp/fork.cc", + "src/core/lib/gprpp/global_config_env.cc", "src/core/lib/gprpp/thd_posix.cc", "src/core/lib/gprpp/thd_windows.cc", "src/core/lib/profiling/basic_timers.cc", @@ -8069,6 +8100,10 @@ "src/core/lib/gprpp/arena.h", "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", @@ -8118,6 +8153,10 @@ "src/core/lib/gprpp/arena.h", "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index ec2e570bea7..8c14282acbb 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -4499,6 +4499,54 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "global_config_env_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "global_config_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [ "--generated_file_path=gens/src/proto/grpc/testing/" From 3184fff6b27bd97cf675a1b2c1669c2f81922c0a Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 30 Apr 2019 15:54:35 -0700 Subject: [PATCH 2044/2143] Fix BUILD.gn file --- BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.gn b/BUILD.gn index 00a412c84bc..2ab56ba346b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1014,6 +1014,7 @@ config("grpc_config") { "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 e70d507abe159fec815d8fb95e780fc0859f8e8d Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Tue, 30 Apr 2019 16:32:31 -0700 Subject: [PATCH 2045/2143] Changes based on comment --- .../bm_callback_unary_ping_pong.cc | 83 ++++++++++--------- .../callback_streaming_ping_pong.h | 4 +- .../microbenchmarks/callback_test_service.cc | 9 -- .../callback_unary_ping_pong.h | 6 +- 4 files changed, 51 insertions(+), 51 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc index c0a7054bf51..bcbde5db035 100644 --- a/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc @@ -34,12 +34,15 @@ auto& force_library_initialization = Library::get(); static void SweepSizesArgs(benchmark::internal::Benchmark* b) { b->Args({0, 0}); for (int i = 1; i <= 128 * 1024 * 1024; i *= 8) { + // First argument is the message size of request + // Second argument is the message size of response b->Args({i, 0}); b->Args({0, i}); b->Args({i, i}); } } +// Unary ping pong with different message size of request and response BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, NoOpMutator) ->Apply(SweepSizesArgs); @@ -52,6 +55,8 @@ BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, MinInProcessCHTTP2, NoOpMutator, NoOpMutator) ->Apply(SweepSizesArgs); + +// Client context with different metadata BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, Client_AddMetadata, 1>, NoOpMutator) ->Args({0, 0}); @@ -72,15 +77,6 @@ BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, Client_AddMetadata, 2>, NoOpMutator) ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, Client_AddMetadata, 1>, NoOpMutator) ->Args({0, 0}); @@ -90,6 +86,46 @@ BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, Client_AddMetadata, 1>, NoOpMutator) ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 2>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); + +// Server context with different metadata +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, Server_AddInitialMetadata, 1>) ->Args({0, 0}); @@ -102,26 +138,6 @@ BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, Server_AddInitialMetadata, 100>) ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, - NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 2>, - NoOpMutator) - ->Args({0, 0}); BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, Server_AddInitialMetadata, 1>) ->Args({0, 0}); @@ -131,15 +147,6 @@ BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, Server_AddInitialMetadata, 1>) ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, Server_AddInitialMetadata, 1>) ->Args({0, 0}); diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h index 1710a754803..fc74e2757ba 100644 --- a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -61,8 +61,8 @@ static void BM_CallbackBidiStreaming(benchmark::State& state) { } fixture->Finish(state); fixture.reset(); - state.SetBytesProcessed(2 * state.range(0) * state.iterations() * - state.range(1)); + state.SetBytesProcessed(2 * message_size * max_ping_pongs + * state.iterations()); } } // namespace testing diff --git a/test/cpp/microbenchmarks/callback_test_service.cc b/test/cpp/microbenchmarks/callback_test_service.cc index caa734d90e8..eebf6e31241 100644 --- a/test/cpp/microbenchmarks/callback_test_service.cc +++ b/test/cpp/microbenchmarks/callback_test_service.cc @@ -64,14 +64,6 @@ CallbackStreamingTestService::BidiStream() { kServerFinishAfterNReads, context->client_metadata(), 0); message_size_ = GetIntValueFromMetadata(kServerResponseStreamsToSend, context->client_metadata(), 0); - // EchoRequest* request = new EchoRequest; - // if (message_size_ > 0) { - // request->set_message(std::string(message_size_, 'a')); - // } else { - // request->set_message(""); - // } - // - // request_ = request; StartRead(&request_); on_started_done_ = true; } @@ -80,7 +72,6 @@ CallbackStreamingTestService::BidiStream() { void OnReadDone(bool ok) override { if (ok) { num_msgs_read_++; - // gpr_log(GPR_INFO, "recv msg %s", request_.message().c_str()); if (message_size_ > 0) { response_.set_message(std::string(message_size_, 'a')); } else { diff --git a/test/cpp/microbenchmarks/callback_unary_ping_pong.h b/test/cpp/microbenchmarks/callback_unary_ping_pong.h index 01477e6402d..19449341747 100644 --- a/test/cpp/microbenchmarks/callback_unary_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_unary_ping_pong.h @@ -38,6 +38,8 @@ namespace testing { template static void BM_CallbackUnaryPingPong(benchmark::State& state) { + int request_msgs_size = state.range(0); + int response_msgs_size = state.range(1); CallbackStreamingTestService service; std::unique_ptr fixture(new Fixture(&service)); std::unique_ptr stub_( @@ -76,8 +78,8 @@ static void BM_CallbackUnaryPingPong(benchmark::State& state) { } fixture->Finish(state); fixture.reset(); - state.SetBytesProcessed(state.range(0) * state.iterations() + - state.range(1) * state.iterations()); + state.SetBytesProcessed(request_msgs_size * state.iterations() + + response_msgs_size * state.iterations()); } } // namespace testing } // namespace grpc From e060cd7519f065db308ed04e765269221b609950 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 30 Apr 2019 16:36:05 -0700 Subject: [PATCH 2046/2143] Fix formatting errors --- BUILD.gn | 1 + include/grpcpp/channel_impl.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/BUILD.gn b/BUILD.gn index 195fe0e71fb..4e52a0dc339 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1014,6 +1014,7 @@ config("grpc_config") { "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_impl.h b/include/grpcpp/channel_impl.h index b0240d30ec6..39917d2eb74 100644 --- a/include/grpcpp/channel_impl.h +++ b/include/grpcpp/channel_impl.h @@ -25,8 +25,8 @@ #include #include #include -#include #include +#include #include #include #include From 3a31b96ef9ba100f09032bc7ee0335b7070d9b6e Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 30 Apr 2019 16:39:54 -0700 Subject: [PATCH 2047/2143] Fix error from make --- 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 4f3a053b494..f4ead14cde8 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), From 8e4b4b94038bc42d6cc2b9d124fe294137c78700 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 30 Apr 2019 16:49:48 -0700 Subject: [PATCH 2048/2143] Fix golden file for test --- test/cpp/codegen/compiler_test_golden | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index e3b06a90f62..e571a95bb3e 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -52,6 +52,7 @@ template class MessageAllocator; } // namespace experimental } // namespace grpc_impl + namespace grpc { class ServerContext; } // namespace grpc From e17ce91d16e91baf0a23ea27bbcb8e8ab873fd7a Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 30 Apr 2019 17:08:07 -0700 Subject: [PATCH 2049/2143] Fix make errors --- 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 4f3a053b494..4ad424dad26 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 ::grpc::CreateChannelInternal( "", grpc_cronet_secure_channel_create(engine_, target.c_str(), &channel_args, nullptr), From 4c0c2965fe430930060f686a1a0b678b64b24344 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 30 Apr 2019 22:20:06 -0400 Subject: [PATCH 2050/2143] Use peek_first instead of mutable_first. Use DEBUG_ASSERT instead of ASSERT. --- src/core/ext/transport/chttp2/transport/frame_data.cc | 2 +- src/core/lib/compression/stream_compression_gzip.cc | 2 +- src/core/lib/security/transport/security_handshaker.cc | 3 +-- src/core/lib/slice/slice_buffer.cc | 2 +- src/core/lib/slice/slice_internal.h | 2 +- test/core/slice/slice_buffer_test.cc | 8 ++++---- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index 2b7d3fce008..5a0492f72ab 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -104,7 +104,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( uint8_t* end = nullptr; uint8_t* cur = nullptr; - grpc_slice* slice = grpc_slice_buffer_mutable_first(slices); + grpc_slice* slice = grpc_slice_buffer_peek_first(slices); beg = GRPC_SLICE_START_PTR(*slice); end = GRPC_SLICE_END_PTR(*slice); cur = beg; diff --git a/src/core/lib/compression/stream_compression_gzip.cc b/src/core/lib/compression/stream_compression_gzip.cc index ca687066136..f2c4bb92981 100644 --- a/src/core/lib/compression/stream_compression_gzip.cc +++ b/src/core/lib/compression/stream_compression_gzip.cc @@ -53,7 +53,7 @@ static bool gzip_flate(grpc_stream_compression_context_gzip* ctx, ctx->zs.avail_out = static_cast(slice_size); ctx->zs.next_out = GRPC_SLICE_START_PTR(slice_out); while (ctx->zs.avail_out > 0 && in->length > 0 && !eoc) { - grpc_slice* slice = grpc_slice_buffer_mutable_first(in); + grpc_slice* slice = grpc_slice_buffer_peek_first(in); ctx->zs.avail_in = static_cast GRPC_SLICE_LENGTH(*slice); ctx->zs.next_in = GRPC_SLICE_START_PTR(*slice); r = ctx->flate(&ctx->zs, Z_NO_FLUSH); diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index 7c0792f2846..117e01a77a7 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -144,8 +144,7 @@ size_t SecurityHandshaker::MoveReadBufferIntoHandshakeBuffer() { } size_t offset = 0; while (args_->read_buffer->count > 0) { - grpc_slice* next_slice = - grpc_slice_buffer_mutable_first(args_->read_buffer); + grpc_slice* next_slice = grpc_slice_buffer_peek_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); diff --git a/src/core/lib/slice/slice_buffer.cc b/src/core/lib/slice/slice_buffer.cc index 76da64b858f..501d600cb97 100644 --- a/src/core/lib/slice/slice_buffer.cc +++ b/src/core/lib/slice/slice_buffer.cc @@ -371,7 +371,7 @@ grpc_slice grpc_slice_buffer_take_first(grpc_slice_buffer* sb) { } void grpc_slice_buffer_consume_first(grpc_slice_buffer* sb) { - GPR_ASSERT(sb->count > 0); + GPR_DEBUG_ASSERT(sb->count > 0); sb->length -= GRPC_SLICE_LENGTH(sb->slices[0]); grpc_slice_unref_internal(sb->slices[0]); sb->slices++; diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index 4c4ace443dc..e6563f4720d 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -243,7 +243,7 @@ void grpc_slice_buffer_partial_unref_internal(grpc_slice_buffer* sb, void grpc_slice_buffer_destroy_internal(grpc_slice_buffer* sb); // Returns the first slice in the slice buffer. -inline grpc_slice* grpc_slice_buffer_mutable_first(grpc_slice_buffer* sb) { +inline grpc_slice* grpc_slice_buffer_peek_first(grpc_slice_buffer* sb) { GPR_DEBUG_ASSERT(sb->count > 0); return &sb->slices[0]; } diff --git a/test/core/slice/slice_buffer_test.cc b/test/core/slice/slice_buffer_test.cc index 8aa58a3ac0d..5ad11a34563 100644 --- a/test/core/slice/slice_buffer_test.cc +++ b/test/core/slice/slice_buffer_test.cc @@ -119,25 +119,25 @@ void test_slice_buffer_first() { grpc_slice_buffer_add_indexed(&buf, slices[idx]); } - grpc_slice* first = grpc_slice_buffer_mutable_first(&buf); + grpc_slice* first = grpc_slice_buffer_peek_first(&buf); GPR_ASSERT(GPR_SLICE_LENGTH(*first) == GPR_SLICE_LENGTH(slices[0])); GPR_ASSERT(buf.count == 3); GPR_ASSERT(buf.length == 12); grpc_slice_buffer_sub_first(&buf, 1, 2); - first = grpc_slice_buffer_mutable_first(&buf); + first = grpc_slice_buffer_peek_first(&buf); GPR_ASSERT(GPR_SLICE_LENGTH(*first) == 1); GPR_ASSERT(buf.count == 3); GPR_ASSERT(buf.length == 10); grpc_slice_buffer_consume_first(&buf); - first = grpc_slice_buffer_mutable_first(&buf); + first = grpc_slice_buffer_peek_first(&buf); GPR_ASSERT(GPR_SLICE_LENGTH(*first) == GPR_SLICE_LENGTH(slices[1])); GPR_ASSERT(buf.count == 2); GPR_ASSERT(buf.length == 9); grpc_slice_buffer_consume_first(&buf); - first = grpc_slice_buffer_mutable_first(&buf); + first = grpc_slice_buffer_peek_first(&buf); GPR_ASSERT(GPR_SLICE_LENGTH(*first) == GPR_SLICE_LENGTH(slices[2])); GPR_ASSERT(buf.count == 1); GPR_ASSERT(buf.length == 5); From f5f030e675369a2c1c81c7551bf774d3909668b4 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 1 May 2019 13:41:19 -0400 Subject: [PATCH 2051/2143] Use end - begin instead of GRPC_SLICE_LENGTH(). --- src/core/lib/slice/slice_buffer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/slice/slice_buffer.cc b/src/core/lib/slice/slice_buffer.cc index 501d600cb97..083e35791db 100644 --- a/src/core/lib/slice/slice_buffer.cc +++ b/src/core/lib/slice/slice_buffer.cc @@ -385,7 +385,7 @@ void grpc_slice_buffer_sub_first(grpc_slice_buffer* sb, size_t begin, // TODO(soheil): Introduce a ptr version for sub. sb->length -= GRPC_SLICE_LENGTH(sb->slices[0]); sb->slices[0] = grpc_slice_sub_no_ref(sb->slices[0], begin, end); - sb->length += GRPC_SLICE_LENGTH(sb->slices[0]); + sb->length += end - begin; } void grpc_slice_buffer_undo_take_first(grpc_slice_buffer* sb, From b3fb277da6468de843e41bd6434b6b6d4ec46dc3 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 1 May 2019 13:52:58 -0400 Subject: [PATCH 2052/2143] Reset slices pointer to base_slices when slice_bufer length is 0. Currently, we keep increasing the slice pointer, and can run out of the inline space or try to realloc the non-inline space unncessarily. Simply set slices back to the start of the base_slices, when we know the length of the slice_buffer is 0. Note: This will change the behavior of undo_take_first(), if user tries to grow the slie_buffer, between take_first() and undo_take_first() calls. That said, it's not legal to add something to the buffer in between take_first() and undo_take_first(). So, we shouldn't have any issue. --- src/core/lib/slice/slice_buffer.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/lib/slice/slice_buffer.cc b/src/core/lib/slice/slice_buffer.cc index 1f1c08b1594..ce3b5512d1d 100644 --- a/src/core/lib/slice/slice_buffer.cc +++ b/src/core/lib/slice/slice_buffer.cc @@ -33,6 +33,10 @@ #define GROW(x) (3 * (x) / 2) static void maybe_embiggen(grpc_slice_buffer* sb) { + if (sb->length == 0) { + sb->slices = sb->base_slices; + } + /* How far away from sb->base_slices is sb->slices pointer */ size_t slice_offset = static_cast(sb->slices - sb->base_slices); size_t slice_count = sb->count + slice_offset; @@ -177,6 +181,7 @@ void grpc_slice_buffer_reset_and_unref_internal(grpc_slice_buffer* sb) { sb->count = 0; sb->length = 0; + sb->slices = sb->base_slices; } void grpc_slice_buffer_reset_and_unref(grpc_slice_buffer* sb) { From 7d3fdec4450df73791602d478fb361ec3f62cfbe Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Wed, 1 May 2019 11:29:28 -0700 Subject: [PATCH 2053/2143] Add microbenchmark for callback completion queue --- test/cpp/microbenchmarks/bm_callback_cq.cc | 231 +++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 test/cpp/microbenchmarks/bm_callback_cq.cc diff --git a/test/cpp/microbenchmarks/bm_callback_cq.cc b/test/cpp/microbenchmarks/bm_callback_cq.cc new file mode 100644 index 00000000000..bc2e4cef969 --- /dev/null +++ b/test/cpp/microbenchmarks/bm_callback_cq.cc @@ -0,0 +1,231 @@ +/* + * + * 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" + +#include "src/core/lib/surface/completion_queue.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/iomgr/iomgr.h" + +namespace grpc { +namespace testing { + +auto& force_library_initialization = Library::get(); + +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_; +}; + +class ShutdownCallback : public grpc_experimental_completion_queue_functor { + public: + ShutdownCallback(bool* done) : done_(done) { + functor_run = &ShutdownCallback::Run; + } + ~ShutdownCallback() {} + static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + *static_cast(cb)->done_ = static_cast(ok); + } + + private: + bool* done_; +}; + +/* helper for tests to shutdown correctly and tersely */ +static void shutdown_and_destroy(grpc_completion_queue* cc) { + grpc_completion_queue_shutdown(cc); + grpc_completion_queue_destroy(cc); +} + +static void do_nothing_end_completion(void* arg, grpc_cq_completion* c) {} + +static void BM_Callback_CQ_Default_Polling(benchmark::State& state) { + int tag_size = state.range(0); + grpc_completion_queue* cc; + void* tags[tag_size]; + grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)]; + + grpc_completion_queue_attributes attr; + unsigned i; + bool got_shutdown = false; + ShutdownCallback shutdown_cb(&got_shutdown); + + attr.version = 2; + attr.cq_completion_type = GRPC_CQ_CALLBACK; + attr.cq_shutdown_cb = &shutdown_cb; + while (state.KeepRunning()) { + int sumtags = 0; + int counter = 0; + { + // reset exec_ctx types + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ExecCtx exec_ctx; + attr.cq_polling_type = GRPC_CQ_DEFAULT_POLLING; + cc = grpc_completion_queue_create( + grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); + + 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); + } + GPR_ASSERT(sumtags == counter); + GPR_ASSERT(got_shutdown); + got_shutdown = false; + } +} +BENCHMARK(BM_Callback_CQ_Default_Polling)->Range(1, 128 * 1024); + +static void BM_Callback_CQ_Non_Listening(benchmark::State& state) { + int tag_size = state.range(0); + grpc_completion_queue* cc; + void* tags[tag_size]; + grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)]; + grpc_completion_queue_attributes attr; + unsigned i; + bool got_shutdown = false; + ShutdownCallback shutdown_cb(&got_shutdown); + + attr.version = 2; + attr.cq_completion_type = GRPC_CQ_CALLBACK; + attr.cq_shutdown_cb = &shutdown_cb; + while (state.KeepRunning()) { + int sumtags = 0; + int counter = 0; + { + // reset exec_ctx types + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ExecCtx exec_ctx; + attr.cq_polling_type = GRPC_CQ_NON_LISTENING; + cc = grpc_completion_queue_create( + grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); + + 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); + } + GPR_ASSERT(sumtags == counter); + GPR_ASSERT(got_shutdown); + got_shutdown = false; + } +} +BENCHMARK(BM_Callback_CQ_Non_Listening)->Range(1, 128 * 1024); + +static void BM_Callback_CQ_Non_Polling(benchmark::State& state) { + int tag_size = state.range(0); + grpc_completion_queue* cc; + void* tags[tag_size]; + grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)]; + grpc_completion_queue_attributes attr; + unsigned i; + bool got_shutdown = false; + ShutdownCallback shutdown_cb(&got_shutdown); + + attr.version = 2; + attr.cq_completion_type = GRPC_CQ_CALLBACK; + attr.cq_shutdown_cb = &shutdown_cb; + while (state.KeepRunning()) { + int sumtags = 0; + int counter = 0; + { + // reset exec_ctx types + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ExecCtx exec_ctx; + attr.cq_polling_type = GRPC_CQ_DEFAULT_POLLING; + cc = grpc_completion_queue_create( + grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); + + 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); + } + GPR_ASSERT(sumtags == counter); + GPR_ASSERT(got_shutdown); + got_shutdown = false; + } +} +BENCHMARK(BM_Callback_CQ_Non_Polling)->Range(1, 128 * 1024); + +} // 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; +} From 926bbe3a2e3f94eec591fbf19795a28f598806c1 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 30 Apr 2019 18:47:16 -0400 Subject: [PATCH 2054/2143] Add a fast path in grpc_error_get_status() for GRPC_ERROR_NONE. In most of the cases, as we hope, RPCs shouldn't have errors. But, in grpc_error_get_status() we treat GRPC_ERROR_NONE similar to other errors, and waste quite a few cycles. This patch is part of a larger performance improvements. On client side, this particular code path accounts for 0.5%+. --- src/core/lib/transport/error_utils.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/core/lib/transport/error_utils.cc b/src/core/lib/transport/error_utils.cc index 558f1d494cd..eb4e8c3a282 100644 --- a/src/core/lib/transport/error_utils.cc +++ b/src/core/lib/transport/error_utils.cc @@ -48,6 +48,18 @@ 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) { + // Fast path: We expect no error. + if (GPR_LIKELY(error == GRPC_ERROR_NONE)) { + if (code != nullptr) *code = GRPC_STATUS_OK; + if (slice != nullptr) { + grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, slice); + } + if (http_error != nullptr) { + *http_error = GRPC_HTTP2_NO_ERROR; + } + return; + } + // 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 1f0476267b92943679bcedcdc0c520218dcc11f0 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 2 May 2019 13:55:15 -0400 Subject: [PATCH 2055/2143] Add a better comment and rename consume_first to remove_first. --- .../transport/chttp2/transport/frame_data.cc | 30 +++++++++---------- .../compression/stream_compression_gzip.cc | 4 +-- src/core/lib/iomgr/tcp_posix.cc | 2 +- .../security/transport/security_handshaker.cc | 2 +- src/core/lib/slice/slice_buffer.cc | 2 +- src/core/lib/slice/slice_internal.h | 7 +++-- test/core/slice/slice_buffer_test.cc | 6 ++-- 7 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index 5a0492f72ab..3734c0150b7 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -112,14 +112,14 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( char* msg; if (cur == end) { - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); continue; } switch (p->state) { case GRPC_CHTTP2_DATA_ERROR: p->state = GRPC_CHTTP2_DATA_ERROR; - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); return GRPC_ERROR_REF(p->error); case GRPC_CHTTP2_DATA_FH_0: s->stats.incoming.framing_bytes++; @@ -144,12 +144,12 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); p->state = GRPC_CHTTP2_DATA_ERROR; - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); return GRPC_ERROR_REF(p->error); } if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_1; - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); continue; } /* fallthrough */ @@ -158,7 +158,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->frame_size = (static_cast(*cur)) << 24; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_2; - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); continue; } /* fallthrough */ @@ -167,7 +167,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->frame_size |= (static_cast(*cur)) << 16; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_3; - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); continue; } /* fallthrough */ @@ -176,7 +176,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->frame_size |= (static_cast(*cur)) << 8; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_4; - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); continue; } /* fallthrough */ @@ -207,14 +207,14 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( grpc_slice_buffer_sub_first(slices, static_cast(cur - beg), static_cast(end - beg)); } else { - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); } return GRPC_ERROR_NONE; case GRPC_CHTTP2_DATA_FRAME: { GPR_ASSERT(p->parsing_frame != nullptr); GPR_ASSERT(slice_out != nullptr); if (cur == end) { - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); continue; } uint32_t remaining = static_cast(end - cur); @@ -225,17 +225,17 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( grpc_slice_sub(*slice, static_cast(cur - beg), static_cast(end - beg)), slice_out))) { - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); return error; } if (GRPC_ERROR_NONE != (error = p->parsing_frame->Finished(GRPC_ERROR_NONE, true))) { - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); return error; } p->parsing_frame = nullptr; p->state = GRPC_CHTTP2_DATA_FH_0; - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); return GRPC_ERROR_NONE; } else if (remaining < p->frame_size) { s->stats.incoming.data_bytes += remaining; @@ -247,7 +247,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( return error; } p->frame_size -= remaining; - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); return GRPC_ERROR_NONE; } else { GPR_ASSERT(remaining > p->frame_size); @@ -258,12 +258,12 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( *slice, static_cast(cur - beg), static_cast(cur + p->frame_size - beg)), slice_out)) { - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); return error; } if (GRPC_ERROR_NONE != (error = p->parsing_frame->Finished(GRPC_ERROR_NONE, true))) { - grpc_slice_buffer_consume_first(slices); + grpc_slice_buffer_remove_first(slices); return error; } p->parsing_frame = nullptr; diff --git a/src/core/lib/compression/stream_compression_gzip.cc b/src/core/lib/compression/stream_compression_gzip.cc index f2c4bb92981..452b22b7628 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_buffer_consume_first(in); + grpc_slice_buffer_remove_first(in); return false; } else if (r == Z_STREAM_END && ctx->flate == inflate) { eoc = true; @@ -70,7 +70,7 @@ static bool gzip_flate(grpc_stream_compression_context_gzip* ctx, in, GRPC_SLICE_LENGTH(*slice) - ctx->zs.avail_in, GRPC_SLICE_LENGTH(*slice)); } else { - grpc_slice_buffer_consume_first(in); + grpc_slice_buffer_remove_first(in); } } if (flush != 0 && ctx->zs.avail_out > 0 && !eoc) { diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 45af4931cf5..6c1955669cd 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -980,7 +980,7 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { // unref all and forget about all slices that have been written to this // point for (size_t idx = 0; idx < unwind_slice_idx; ++idx) { - grpc_slice_buffer_consume_first(tcp->outgoing_buffer); + grpc_slice_buffer_remove_first(tcp->outgoing_buffer); } return false; } else if (errno == EPIPE) { diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index 117e01a77a7..fdc64727b96 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -148,7 +148,7 @@ size_t SecurityHandshaker::MoveReadBufferIntoHandshakeBuffer() { memcpy(handshake_buffer_ + offset, GRPC_SLICE_START_PTR(*next_slice), GRPC_SLICE_LENGTH(*next_slice)); offset += GRPC_SLICE_LENGTH(*next_slice); - grpc_slice_buffer_consume_first(args_->read_buffer); + grpc_slice_buffer_remove_first(args_->read_buffer); } return bytes_in_read_buffer; } diff --git a/src/core/lib/slice/slice_buffer.cc b/src/core/lib/slice/slice_buffer.cc index 083e35791db..29937bfc9bf 100644 --- a/src/core/lib/slice/slice_buffer.cc +++ b/src/core/lib/slice/slice_buffer.cc @@ -370,7 +370,7 @@ grpc_slice grpc_slice_buffer_take_first(grpc_slice_buffer* sb) { return slice; } -void grpc_slice_buffer_consume_first(grpc_slice_buffer* sb) { +void grpc_slice_buffer_remove_first(grpc_slice_buffer* sb) { GPR_DEBUG_ASSERT(sb->count > 0); sb->length -= GRPC_SLICE_LENGTH(sb->slices[0]); grpc_slice_unref_internal(sb->slices[0]); diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index e6563f4720d..aa7c3dbce96 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -242,14 +242,15 @@ void grpc_slice_buffer_partial_unref_internal(grpc_slice_buffer* sb, size_t idx); void grpc_slice_buffer_destroy_internal(grpc_slice_buffer* sb); -// Returns the first slice in the slice buffer. +// Returns a pointer to the first slice in the slice buffer without giving +// ownership to or a reference count on that slice. inline grpc_slice* grpc_slice_buffer_peek_first(grpc_slice_buffer* sb) { GPR_DEBUG_ASSERT(sb->count > 0); return &sb->slices[0]; } -// Consumes the first slice in the slice buffer. -void grpc_slice_buffer_consume_first(grpc_slice_buffer* sb); +// Removes the first slice from the slice buffer. +void grpc_slice_buffer_remove_first(grpc_slice_buffer* sb); // Calls grpc_slice_sub with the given parameters on the first slice. void grpc_slice_buffer_sub_first(grpc_slice_buffer* sb, size_t begin, diff --git a/test/core/slice/slice_buffer_test.cc b/test/core/slice/slice_buffer_test.cc index 5ad11a34563..7d4acfed003 100644 --- a/test/core/slice/slice_buffer_test.cc +++ b/test/core/slice/slice_buffer_test.cc @@ -130,19 +130,19 @@ void test_slice_buffer_first() { GPR_ASSERT(buf.count == 3); GPR_ASSERT(buf.length == 10); - grpc_slice_buffer_consume_first(&buf); + grpc_slice_buffer_remove_first(&buf); first = grpc_slice_buffer_peek_first(&buf); GPR_ASSERT(GPR_SLICE_LENGTH(*first) == GPR_SLICE_LENGTH(slices[1])); GPR_ASSERT(buf.count == 2); GPR_ASSERT(buf.length == 9); - grpc_slice_buffer_consume_first(&buf); + grpc_slice_buffer_remove_first(&buf); first = grpc_slice_buffer_peek_first(&buf); GPR_ASSERT(GPR_SLICE_LENGTH(*first) == GPR_SLICE_LENGTH(slices[2])); GPR_ASSERT(buf.count == 1); GPR_ASSERT(buf.length == 5); - grpc_slice_buffer_consume_first(&buf); + grpc_slice_buffer_remove_first(&buf); GPR_ASSERT(buf.count == 0); GPR_ASSERT(buf.length == 0); } From 25128d18c1517778f9ded375a368708554057bb6 Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Thu, 2 May 2019 15:14:44 -0700 Subject: [PATCH 2056/2143] Modify unary ping pong to send next rpc in callback function --- .../bm_callback_unary_ping_pong.cc | 56 ----------------- .../microbenchmarks/callback_test_service.cc | 9 ++- .../microbenchmarks/callback_test_service.h | 7 ++- .../callback_unary_ping_pong.h | 63 ++++++++++++------- 4 files changed, 53 insertions(+), 82 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc index bcbde5db035..1ba99f0a689 100644 --- a/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc @@ -49,12 +49,6 @@ BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, MinInProcess, NoOpMutator, NoOpMutator) ->Apply(SweepSizesArgs); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, - NoOpMutator) - ->Apply(SweepSizesArgs); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, MinInProcessCHTTP2, NoOpMutator, - NoOpMutator) - ->Apply(SweepSizesArgs); // Client context with different metadata BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, @@ -86,35 +80,6 @@ BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, Client_AddMetadata, 1>, NoOpMutator) ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, - NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 2>, - NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 0}); // Server context with different metadata BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, @@ -138,27 +103,6 @@ BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, Server_AddInitialMetadata, 100>) ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 0}); -BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 100>) - ->Args({0, 0}); } // namespace testing } // namespace grpc diff --git a/test/cpp/microbenchmarks/callback_test_service.cc b/test/cpp/microbenchmarks/callback_test_service.cc index eebf6e31241..ffd87572db0 100644 --- a/test/cpp/microbenchmarks/callback_test_service.cc +++ b/test/cpp/microbenchmarks/callback_test_service.cc @@ -49,6 +49,13 @@ int GetIntValueFromMetadata( void CallbackStreamingTestService::Echo( ServerContext* context, const EchoRequest* request, EchoResponse* response, experimental::ServerCallbackRpcController* controller) { + int response_msgs_size = GetIntValueFromMetadata(kServerMessageSize, + context->client_metadata(), 0); + if (response_msgs_size > 0) { + response->set_message(std::string(response_msgs_size, 'a')); + } else { + response->set_message(""); + } controller->Finish(Status::OK); } @@ -62,7 +69,7 @@ CallbackStreamingTestService::BidiStream() { ctx_ = context; server_write_last_ = GetIntValueFromMetadata( kServerFinishAfterNReads, context->client_metadata(), 0); - message_size_ = GetIntValueFromMetadata(kServerResponseStreamsToSend, + message_size_ = GetIntValueFromMetadata(kServerMessageSize, context->client_metadata(), 0); StartRead(&request_); on_started_done_ = true; diff --git a/test/cpp/microbenchmarks/callback_test_service.h b/test/cpp/microbenchmarks/callback_test_service.h index aba5c0cfa67..622229d8800 100644 --- a/test/cpp/microbenchmarks/callback_test_service.h +++ b/test/cpp/microbenchmarks/callback_test_service.h @@ -30,7 +30,7 @@ namespace grpc { namespace testing { const char* const kServerFinishAfterNReads = "server_finish_after_n_reads"; -const char* const kServerResponseStreamsToSend = "server_responses_to_send"; +const char* const kServerMessageSize = "server_message_size"; class CallbackStreamingTestService : public EchoTestService::ExperimentalCallbackService { @@ -61,7 +61,10 @@ class BidiClient } void OnReadDone(bool ok) override { - if (ok && reads_complete_ < msgs_to_send_) { + if (!ok) { + return; + } + if (reads_complete_ < msgs_to_send_) { reads_complete_++; StartRead(response_); } diff --git a/test/cpp/microbenchmarks/callback_unary_ping_pong.h b/test/cpp/microbenchmarks/callback_unary_ping_pong.h index 19449341747..e4a48ad5883 100644 --- a/test/cpp/microbenchmarks/callback_unary_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_unary_ping_pong.h @@ -36,6 +36,32 @@ namespace testing { * BENCHMARKING KERNELS */ +// Send next rpc when callback function is evoked. +void SendCallbackUnaryPingPong(benchmark::State& state, EchoRequest* request, + EchoResponse* response, + EchoTestService::Stub* stub_, + bool &done, + std::mutex& mu, + std::condition_variable& cv) { + int response_msgs_size = state.range(1); + ClientContext* cli_ctx = new ClientContext(); + cli_ctx->AddMetadata(kServerMessageSize, + grpc::to_string(response_msgs_size)); + stub_->experimental_async()->Echo( + cli_ctx, request, response, + [&state, cli_ctx, request, response, stub_, &done, &mu, &cv](Status s) { + GPR_ASSERT(s.ok()); + if (state.KeepRunning()) { + SendCallbackUnaryPingPong(state, request, response, stub_, done, mu, cv); + } else { + std::lock_guard l(mu); + done = true; + cv.notify_one(); + } + delete cli_ctx; + }); +} + template static void BM_CallbackUnaryPingPong(benchmark::State& state) { int request_msgs_size = state.range(0); @@ -47,40 +73,31 @@ static void BM_CallbackUnaryPingPong(benchmark::State& state) { EchoRequest request; EchoResponse response; - if (state.range(0) > 0) { - request.set_message(std::string(state.range(0), 'a')); + if (request_msgs_size > 0) { + request.set_message(std::string(request_msgs_size, 'a')); } else { request.set_message(""); } - if (state.range(1) > 0) { - response.set_message(std::string(state.range(1), 'a')); - } else { - response.set_message(""); - } - while (state.KeepRunning()) { + std::mutex mu; + std::condition_variable cv; + bool done = false; + if (state.KeepRunning()) { GPR_TIMER_SCOPE("BenchmarkCycle", 0); - ClientContext cli_ctx; - std::mutex mu; - std::condition_variable cv; - bool done = false; - stub_->experimental_async()->Echo(&cli_ctx, &request, &response, - [&done, &mu, &cv](Status s) { - GPR_ASSERT(s.ok()); - std::lock_guard l(mu); - done = true; - cv.notify_one(); - }); - std::unique_lock l(mu); - while (!done) { - cv.wait(l); - } + SendCallbackUnaryPingPong(state, &request, &response, stub_.get(), + done, mu, cv); + } + std::unique_lock l(mu); + while (!done) { + cv.wait(l); } fixture->Finish(state); fixture.reset(); state.SetBytesProcessed(request_msgs_size * state.iterations() + response_msgs_size * state.iterations()); } + + } // namespace testing } // namespace grpc From e18ed03c043d237b81bc32ddbd7d79593e2f7f19 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Thu, 2 May 2019 16:58:37 -0700 Subject: [PATCH 2057/2143] Made gRPC inialized after entering main function in microbenchmarks. --- test/cpp/microbenchmarks/bm_alarm.cc | 3 +-- test/cpp/microbenchmarks/bm_byte_buffer.cc | 4 +--- test/cpp/microbenchmarks/bm_call_create.cc | 3 +-- test/cpp/microbenchmarks/bm_channel.cc | 3 +-- test/cpp/microbenchmarks/bm_chttp2_hpack.cc | 3 +-- test/cpp/microbenchmarks/bm_chttp2_transport.cc | 6 +++--- test/cpp/microbenchmarks/bm_closure.cc | 3 +-- test/cpp/microbenchmarks/bm_cq.cc | 3 +-- test/cpp/microbenchmarks/bm_error.cc | 3 +-- .../bm_fullstack_streaming_ping_pong.cc | 4 +--- .../bm_fullstack_streaming_pump.cc | 4 +--- .../cpp/microbenchmarks/bm_fullstack_trickle.cc | 8 +++----- .../bm_fullstack_unary_ping_pong.cc | 4 +--- test/cpp/microbenchmarks/bm_metadata.cc | 3 +-- test/cpp/microbenchmarks/bm_pollset.cc | 3 +-- test/cpp/microbenchmarks/bm_timer.cc | 3 +-- test/cpp/microbenchmarks/fullstack_fixtures.h | 4 ++-- test/cpp/microbenchmarks/helpers.cc | 17 ++++++++++++++++- test/cpp/microbenchmarks/helpers.h | 14 +++++--------- 19 files changed, 43 insertions(+), 52 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_alarm.cc b/test/cpp/microbenchmarks/bm_alarm.cc index 64aad6476de..d95771a57c6 100644 --- a/test/cpp/microbenchmarks/bm_alarm.cc +++ b/test/cpp/microbenchmarks/bm_alarm.cc @@ -30,8 +30,6 @@ namespace grpc { namespace testing { -auto& force_library_initialization = Library::get(); - static void BM_Alarm_Tag_Immediate(benchmark::State& state) { TrackCounters track_counters; CompletionQueue cq; @@ -57,6 +55,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_byte_buffer.cc b/test/cpp/microbenchmarks/bm_byte_buffer.cc index 644c27c4873..595cc734b69 100644 --- a/test/cpp/microbenchmarks/bm_byte_buffer.cc +++ b/test/cpp/microbenchmarks/bm_byte_buffer.cc @@ -30,7 +30,6 @@ namespace grpc { namespace testing { 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,7 +47,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; @@ -82,7 +80,6 @@ static void BM_ByteBufferReader_Next(benchmark::State& state) { 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; @@ -125,6 +122,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 53087a551b5..3bd1464b2aa 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -47,8 +47,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - void BM_Zalloc(benchmark::State& state) { // speed of light for call creation is zalloc, so benchmark a few interesting // sizes @@ -823,6 +821,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_channel.cc b/test/cpp/microbenchmarks/bm_channel.cc index 15ac9975400..88856c3439b 100644 --- a/test/cpp/microbenchmarks/bm_channel.cc +++ b/test/cpp/microbenchmarks/bm_channel.cc @@ -23,8 +23,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - class ChannelDestroyerFixture { public: ChannelDestroyerFixture() {} @@ -83,6 +81,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index 0521166db95..d0ed1da7671 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -36,8 +36,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - static grpc_slice MakeSlice(std::vector bytes) { grpc_slice s = grpc_slice_malloc(bytes.size()); uint8_t* p = GRPC_SLICE_START_PTR(s); @@ -928,6 +926,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index dc10fcb89d3..05504584c20 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -36,8 +36,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - //////////////////////////////////////////////////////////////////////////////// // Helper classes // @@ -57,7 +55,8 @@ class DummyEndpoint : public grpc_endpoint { get_fd, can_track_err}; grpc_endpoint::vtable = &my_vtable; - ru_ = grpc_resource_user_create(Library::get().rq(), "dummy_endpoint"); + ru_ = grpc_resource_user_create(LibraryInitializer::get().rq(), + "dummy_endpoint"); } void PushInput(grpc_slice slice) { @@ -642,6 +641,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_closure.cc b/test/cpp/microbenchmarks/bm_closure.cc index e1f1e92d4d8..84b1c536bf0 100644 --- a/test/cpp/microbenchmarks/bm_closure.cc +++ b/test/cpp/microbenchmarks/bm_closure.cc @@ -30,8 +30,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - static void BM_NoOpExecCtx(benchmark::State& state) { TrackCounters track_counters; while (state.KeepRunning()) { @@ -425,6 +423,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index a7cb939265f..263314deb93 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -32,8 +32,6 @@ namespace grpc { namespace testing { -auto& force_library_initialization = Library::get(); - static void BM_CreateDestroyCpp(benchmark::State& state) { TrackCounters track_counters; while (state.KeepRunning()) { @@ -156,6 +154,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_error.cc b/test/cpp/microbenchmarks/bm_error.cc index ae557a580aa..a71817f7e54 100644 --- a/test/cpp/microbenchmarks/bm_error.cc +++ b/test/cpp/microbenchmarks/bm_error.cc @@ -27,8 +27,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - class ErrorDeleter { public: void operator()(grpc_error* error) { GRPC_ERROR_UNREF(error); } @@ -318,6 +316,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc index 34df77aca3c..60ca9a093ed 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc @@ -24,9 +24,6 @@ namespace grpc { namespace testing { -// force library initialization -auto& force_library_initialization = Library::get(); - /******************************************************************************* * CONFIGURATIONS */ @@ -122,6 +119,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc index da98f3cbcd4..d4533e6c78e 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc @@ -28,9 +28,6 @@ namespace testing { * CONFIGURATIONS */ -// force library initialization -auto& force_library_initialization = Library::get(); - BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, TCP) ->Range(0, 128 * 1024 * 1024); BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, UDS) @@ -72,6 +69,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc index 1af92d2c80c..2d733bcaa42 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc @@ -214,8 +214,8 @@ class TrickledCHTTP2 : public EndpointPairFixture { static grpc_endpoint_pair MakeEndpoints(size_t kilobits, grpc_passthru_endpoint_stats* stats) { grpc_endpoint_pair p; - grpc_passthru_endpoint_create(&p.client, &p.server, Library::get().rq(), - stats); + grpc_passthru_endpoint_create(&p.client, &p.server, + LibraryInitializer::get().rq(), stats); double bytes_per_second = 125.0 * kilobits; p.client = grpc_trickle_endpoint_create(p.client, bytes_per_second); p.server = grpc_trickle_endpoint_create(p.server, bytes_per_second); @@ -235,9 +235,6 @@ class TrickledCHTTP2 : public EndpointPairFixture { } }; -// force library initialization -auto& force_library_initialization = Library::get(); - static void TrickleCQNext(TrickledCHTTP2* fixture, void** t, bool* ok, int64_t iteration) { while (true) { @@ -465,6 +462,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); grpc_timer_manager_set_threading(false); diff --git a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc index d4bd58b9838..3e8f9344021 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc @@ -24,9 +24,6 @@ namespace grpc { namespace testing { -// force library initialization -auto& force_library_initialization = Library::get(); - /******************************************************************************* * CONFIGURATIONS */ @@ -174,6 +171,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_metadata.cc b/test/cpp/microbenchmarks/bm_metadata.cc index 553b33c4028..ff8fe541dfc 100644 --- a/test/cpp/microbenchmarks/bm_metadata.cc +++ b/test/cpp/microbenchmarks/bm_metadata.cc @@ -27,8 +27,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - static void BM_SliceFromStatic(benchmark::State& state) { TrackCounters track_counters; while (state.KeepRunning()) { @@ -298,6 +296,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_pollset.cc b/test/cpp/microbenchmarks/bm_pollset.cc index 050c7f7c171..f8e36f178e4 100644 --- a/test/cpp/microbenchmarks/bm_pollset.cc +++ b/test/cpp/microbenchmarks/bm_pollset.cc @@ -40,8 +40,6 @@ #include #endif -auto& force_library_initialization = Library::get(); - static void shutdown_ps(void* ps, grpc_error* error) { grpc_pollset_destroy(static_cast(ps)); } @@ -264,6 +262,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_timer.cc b/test/cpp/microbenchmarks/bm_timer.cc index f5a411251b5..53aaead992d 100644 --- a/test/cpp/microbenchmarks/bm_timer.cc +++ b/test/cpp/microbenchmarks/bm_timer.cc @@ -32,8 +32,6 @@ namespace grpc { namespace testing { -auto& force_library_initialization = Library::get(); - struct TimerClosure { grpc_timer timer; grpc_closure closure; @@ -111,6 +109,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index 80ccab3e6ef..075a09c63eb 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -299,8 +299,8 @@ class InProcessCHTTP2WithExplicitStats : public EndpointPairFixture { static grpc_endpoint_pair MakeEndpoints(grpc_passthru_endpoint_stats* stats) { grpc_endpoint_pair p; - grpc_passthru_endpoint_create(&p.client, &p.server, Library::get().rq(), - stats); + grpc_passthru_endpoint_create(&p.client, &p.server, + LibraryInitializer::get().rq(), stats); return p; } }; diff --git a/test/cpp/microbenchmarks/helpers.cc b/test/cpp/microbenchmarks/helpers.cc index d4070de7481..7d78e21aef7 100644 --- a/test/cpp/microbenchmarks/helpers.cc +++ b/test/cpp/microbenchmarks/helpers.cc @@ -21,8 +21,12 @@ #include "test/cpp/microbenchmarks/helpers.h" static grpc::internal::GrpcLibraryInitializer g_gli_initializer; +static LibraryInitializer* g_libraryInitializer; + +LibraryInitializer::LibraryInitializer() { + GPR_ASSERT(g_libraryInitializer == nullptr); + g_libraryInitializer = this; -Library::Library() { g_gli_initializer.summon(); #ifdef GPR_LOW_LEVEL_COUNTERS grpc_memory_counters_init(); @@ -31,6 +35,17 @@ Library::Library() { rq_ = grpc_resource_quota_create("bm"); } +LibraryInitializer::~LibraryInitializer() { + g_libraryInitializer = nullptr; + init_lib_.shutdown(); + grpc_resource_quota_unref(rq_); +} + +LibraryInitializer& LibraryInitializer::get() { + GPR_ASSERT(g_libraryInitializer != nullptr); + return *g_libraryInitializer; +} + 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 770966aa189..b712c85d354 100644 --- a/test/cpp/microbenchmarks/helpers.h +++ b/test/cpp/microbenchmarks/helpers.h @@ -29,20 +29,16 @@ #include #include -class Library { +class LibraryInitializer { public: - static Library& get() { - static Library lib; - return lib; - } + LibraryInitializer(); + ~LibraryInitializer(); grpc_resource_quota* rq() { return rq_; } + static LibraryInitializer& get(); + private: - Library(); - - ~Library() { init_lib_.shutdown(); } - grpc::internal::GrpcLibrary init_lib_; grpc_resource_quota* rq_; }; From 5748665bc546f8839ead6b5a92525960ff011ee7 Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Thu, 2 May 2019 17:21:55 -0700 Subject: [PATCH 2058/2143] Add callback completion queue and modify callback streaming ping pong --- CMakeLists.txt | 48 ++++++++++++ Makefile | 49 ++++++++++++ build.yaml | 23 ++++++ test/cpp/microbenchmarks/BUILD | 11 +++ .../bm_callback_streaming_ping_pong.cc | 74 +------------------ .../callback_streaming_ping_pong.h | 2 +- .../microbenchmarks/callback_test_service.cc | 52 ++++++------- .../microbenchmarks/callback_test_service.h | 7 +- .../generated/sources_and_headers.json | 21 ++++++ tools/run_tests/generated/tests.json | 26 +++++++ 10 files changed, 209 insertions(+), 104 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6eaa01c56d9..f36f436d0ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -556,6 +556,9 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_call_create) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_callback_cq) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_callback_streaming_ping_pong) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -11641,6 +11644,51 @@ target_link_libraries(bm_call_create ) +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(bm_callback_cq + test/cpp/microbenchmarks/bm_callback_cq.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bm_callback_cq + 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_callback_cq + ${_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) diff --git a/Makefile b/Makefile index 698184ecafd..448d7167eb4 100644 --- a/Makefile +++ b/Makefile @@ -1162,6 +1162,7 @@ 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 +bm_callback_cq: $(BINDIR)/$(CONFIG)/bm_callback_cq bm_callback_streaming_ping_pong: $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong bm_callback_unary_ping_pong: $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong bm_channel: $(BINDIR)/$(CONFIG)/bm_channel @@ -1640,6 +1641,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_arena \ $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ + $(BINDIR)/$(CONFIG)/bm_callback_cq \ $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong \ $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_channel \ @@ -1786,6 +1788,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_arena \ $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ + $(BINDIR)/$(CONFIG)/bm_callback_cq \ $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong \ $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_channel \ @@ -2238,6 +2241,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/bm_byte_buffer || ( echo test bm_byte_buffer failed ; exit 1 ) $(E) "[RUN] Testing bm_call_create" $(Q) $(BINDIR)/$(CONFIG)/bm_call_create || ( echo test bm_call_create failed ; exit 1 ) + $(E) "[RUN] Testing bm_callback_cq" + $(Q) $(BINDIR)/$(CONFIG)/bm_callback_cq || ( echo test bm_callback_cq failed ; exit 1 ) $(E) "[RUN] Testing bm_callback_streaming_ping_pong" $(Q) $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong || ( echo test bm_callback_streaming_ping_pong failed ; exit 1 ) $(E) "[RUN] Testing bm_callback_unary_ping_pong" @@ -14568,6 +14573,50 @@ endif endif +BM_CALLBACK_CQ_SRC = \ + test/cpp/microbenchmarks/bm_callback_cq.cc \ + +BM_CALLBACK_CQ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CALLBACK_CQ_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_callback_cq: 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_callback_cq: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_callback_cq: $(PROTOBUF_DEP) $(BM_CALLBACK_CQ_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_CALLBACK_CQ_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_callback_cq + +endif + +endif + +$(BM_CALLBACK_CQ_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_callback_cq.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_callback_cq: $(BM_CALLBACK_CQ_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_CALLBACK_CQ_OBJS:.o=.dep) +endif +endif + + BM_CALLBACK_STREAMING_PING_PONG_SRC = \ test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc \ diff --git a/build.yaml b/build.yaml index 562b3216356..fc465dcb719 100644 --- a/build.yaml +++ b/build.yaml @@ -4040,6 +4040,29 @@ targets: - linux - posix uses_polling: false +- name: bm_callback_cq + build: test + language: c++ + src: + - test/cpp/microbenchmarks/bm_callback_cq.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 + excluded_poll_engines: + - poll + platforms: + - mac + - linux + - posix + timeout_seconds: 1200 - name: bm_callback_streaming_ping_pong build: test language: c++ diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 116180d1688..0be64c3b319 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -276,3 +276,14 @@ grpc_cc_binary( tags = ["no_windows"], deps = [":callback_streaming_ping_pong_h"], ) + +grpc_cc_binary( + name = "bm_callback_cq", + testonly = 1, + srcs = ["bm_callback_cq.cc"], + language = "C++", + deps = [ + ":helpers", + "//test/cpp/util:test_util", + ], +) diff --git a/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc index f7e3469f2e4..cfdc0a0cab6 100644 --- a/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc @@ -32,13 +32,11 @@ auto& force_library_initialization = Library::get(); // Replace "benchmark::internal::Benchmark" with "::testing::Benchmark" to use // internal microbenchmarking tooling static void StreamingPingPongMsgSizeArgs(benchmark::internal::Benchmark* b) { - int msg_size = 0; // base case: 0 byte ping-pong msgs b->Args({0, 1}); b->Args({0, 2}); - for (msg_size = 0; msg_size <= 128 * 1024 * 1024; - msg_size == 0 ? msg_size++ : msg_size *= 8) { + for (int msg_size = 1; msg_size <= 128 * 1024 * 1024; msg_size *= 8) { b->Args({msg_size, 1}); b->Args({msg_size, 2}); } @@ -47,13 +45,9 @@ static void StreamingPingPongMsgSizeArgs(benchmark::internal::Benchmark* b) { // Replace "benchmark::internal::Benchmark" with "::testing::Benchmark" to use // internal microbenchmarking tooling static void StreamingPingPongMsgsNumberArgs(benchmark::internal::Benchmark* b) { - int msg_number = 0; - - for (msg_number = 0; msg_number <= 128 * 1024; - msg_number == 0 ? msg_number++ : msg_number *= 8) { + for (int msg_number = 1; msg_number <= 256 * 1024; msg_number *= 8) { b->Args({0, msg_number}); - // 64 KiB same as the synthetic test configuration - b->Args({64 * 1024, msg_number}); + b->Args({1024, msg_number}); } } @@ -64,12 +58,6 @@ BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, MinInProcess, NoOpMutator, NoOpMutator) ->Apply(StreamingPingPongMsgSizeArgs); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - NoOpMutator) - ->Apply(StreamingPingPongMsgSizeArgs); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, MinInProcessCHTTP2, NoOpMutator, - NoOpMutator) - ->Apply(StreamingPingPongMsgSizeArgs); // Streaming with different message number BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, @@ -78,43 +66,8 @@ BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, MinInProcess, NoOpMutator, NoOpMutator) ->Apply(StreamingPingPongMsgsNumberArgs); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - NoOpMutator) - ->Apply(StreamingPingPongMsgsNumberArgs); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, MinInProcessCHTTP2, NoOpMutator, - NoOpMutator) - ->Apply(StreamingPingPongMsgsNumberArgs); // Client context with different metadata -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, - Client_AddMetadata, 1>, - NoOpMutator) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, - Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, - Client_AddMetadata, 2>, NoOpMutator) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, - Client_AddMetadata, 2>, - NoOpMutator) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, - Client_AddMetadata, 1>, NoOpMutator) - ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, Client_AddMetadata, 1>, NoOpMutator) ->Args({0, 1}); @@ -146,27 +99,6 @@ BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, ->Args({0, 1}); // Server context with different metadata -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 1>) - ->Args({0, 1}); -BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcessCHTTP2, NoOpMutator, - Server_AddInitialMetadata, 100>) - ->Args({0, 1}); BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, Server_AddInitialMetadata, 1>) ->Args({0, 1}); diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h index fc74e2757ba..a5064936f8f 100644 --- a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -54,7 +54,7 @@ static void BM_CallbackBidiStreaming(benchmark::State& state) { ClientContext cli_ctx; cli_ctx.AddMetadata(kServerFinishAfterNReads, grpc::to_string(max_ping_pongs)); - cli_ctx.AddMetadata(kServerResponseStreamsToSend, + cli_ctx.AddMetadata(kServerMessageSize, grpc::to_string(message_size)); BidiClient test{stub_.get(), &request, &response, &cli_ctx, max_ping_pongs}; test.Await(); diff --git a/test/cpp/microbenchmarks/callback_test_service.cc b/test/cpp/microbenchmarks/callback_test_service.cc index ffd87572db0..c104b7a8921 100644 --- a/test/cpp/microbenchmarks/callback_test_service.cc +++ b/test/cpp/microbenchmarks/callback_test_service.cc @@ -72,52 +72,48 @@ CallbackStreamingTestService::BidiStream() { message_size_ = GetIntValueFromMetadata(kServerMessageSize, context->client_metadata(), 0); StartRead(&request_); - on_started_done_ = true; } - void OnDone() override { delete this; } + void OnDone() override { + GPR_ASSERT(finished_); + delete this; + } void OnCancel() override {} void OnReadDone(bool ok) override { - if (ok) { - num_msgs_read_++; - if (message_size_ > 0) { - response_.set_message(std::string(message_size_, 'a')); - } else { - response_.set_message(""); - } - if (num_msgs_read_ == server_write_last_) { - StartWriteLast(&response_, WriteOptions()); - } else { - StartWrite(&response_); - return; - } + if (!ok) { + return; + } + num_msgs_read_++; + if (message_size_ > 0) { + response_.set_message(std::string(message_size_, 'a')); + } else { + response_.set_message(""); + } + if (num_msgs_read_ == server_write_last_) { + StartWriteLast(&response_, WriteOptions()); + } else { + StartWrite(&response_); } - FinishOnce(Status::OK); } void OnWriteDone(bool ok) override { - std::lock_guard l(finish_mu_); - if (!finished_) { - StartRead(&request_); + if (!ok) { + return; } - } - - private: - void FinishOnce(const Status& s) { - std::lock_guard l(finish_mu_); - if (!finished_) { - Finish(s); + if (num_msgs_read_ < server_write_last_) { + StartRead(&request_); + } else { + Finish(::grpc::Status::OK); finished_ = true; } } + private: ServerContext* ctx_; EchoRequest request_; EchoResponse response_; int num_msgs_read_{0}; int server_write_last_; int message_size_; - std::mutex finish_mu_; bool finished_{false}; - bool on_started_done_{false}; }; return new Reactor; diff --git a/test/cpp/microbenchmarks/callback_test_service.h b/test/cpp/microbenchmarks/callback_test_service.h index 622229d8800..2bad3dac264 100644 --- a/test/cpp/microbenchmarks/callback_test_service.h +++ b/test/cpp/microbenchmarks/callback_test_service.h @@ -56,7 +56,6 @@ class BidiClient msgs_to_send_{num_msgs_to_send} { stub->experimental_async()->BidiStream(context_, this); MaybeWrite(); - StartRead(response_); StartCall(); } @@ -64,9 +63,9 @@ class BidiClient if (!ok) { return; } - if (reads_complete_ < msgs_to_send_) { + if (ok && reads_complete_ < msgs_to_send_) { reads_complete_++; - StartRead(response_); + MaybeWrite(); } } @@ -75,7 +74,7 @@ class BidiClient return; } writes_complete_++; - MaybeWrite(); + StartRead(response_); } void OnDone(const Status& s) override { diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index c87b79e624b..6803c495654 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -2776,6 +2776,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_callback_cq", + "src": [ + "test/cpp/microbenchmarks/bm_callback_cq.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 d442c3b9744..fce6f3c37ae 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3479,6 +3479,32 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": true, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "excluded_poll_engines": [ + "poll" + ], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_callback_cq", + "platforms": [ + "linux", + "mac", + "posix" + ], + "timeout_seconds": 1200, + "uses_polling": true + }, { "args": [], "benchmark": true, From 927c2f2c618dbfc2ec0988e1abcfd9d5452f2163 Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Thu, 2 May 2019 17:24:54 -0700 Subject: [PATCH 2059/2143] Change format --- test/cpp/microbenchmarks/bm_callback_cq.cc | 26 ++++++------- .../callback_streaming_ping_pong.h | 9 ++--- .../microbenchmarks/callback_test_service.cc | 4 +- .../callback_unary_ping_pong.h | 39 +++++++++---------- 4 files changed, 35 insertions(+), 43 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_callback_cq.cc b/test/cpp/microbenchmarks/bm_callback_cq.cc index bc2e4cef969..1a76e85e6f3 100644 --- a/test/cpp/microbenchmarks/bm_callback_cq.cc +++ b/test/cpp/microbenchmarks/bm_callback_cq.cc @@ -27,10 +27,10 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -#include "src/core/lib/surface/completion_queue.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/surface/completion_queue.h" namespace grpc { namespace testing { @@ -43,8 +43,7 @@ class TagCallback : public grpc_experimental_completion_queue_functor { functor_run = &TagCallback::Run; } ~TagCallback() {} - static void Run(grpc_experimental_completion_queue_functor* cb, - int ok) { + 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_; @@ -104,15 +103,14 @@ static void BM_Callback_CQ_Default_Polling(benchmark::State& state) { grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { - tags[i] = - static_cast(grpc_core::New(&counter, 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]); + grpc_cq_end_op(cc, tags[i], GRPC_ERROR_NONE, do_nothing_end_completion, + nullptr, &completions[i]); } shutdown_and_destroy(cc); @@ -149,15 +147,14 @@ static void BM_Callback_CQ_Non_Listening(benchmark::State& state) { grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { - tags[i] = - static_cast(grpc_core::New(&counter, 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]); + grpc_cq_end_op(cc, tags[i], GRPC_ERROR_NONE, do_nothing_end_completion, + nullptr, &completions[i]); } shutdown_and_destroy(cc); @@ -194,15 +191,14 @@ static void BM_Callback_CQ_Non_Polling(benchmark::State& state) { grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { - tags[i] = - static_cast(grpc_core::New(&counter, 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]); + grpc_cq_end_op(cc, tags[i], GRPC_ERROR_NONE, do_nothing_end_completion, + nullptr, &completions[i]); } shutdown_and_destroy(cc); diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h index a5064936f8f..f7cfd06d7e7 100644 --- a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -53,16 +53,15 @@ static void BM_CallbackBidiStreaming(benchmark::State& state) { GPR_TIMER_SCOPE("BenchmarkCycle", 0); ClientContext cli_ctx; cli_ctx.AddMetadata(kServerFinishAfterNReads, - grpc::to_string(max_ping_pongs)); - cli_ctx.AddMetadata(kServerMessageSize, - grpc::to_string(message_size)); + grpc::to_string(max_ping_pongs)); + cli_ctx.AddMetadata(kServerMessageSize, grpc::to_string(message_size)); BidiClient test{stub_.get(), &request, &response, &cli_ctx, max_ping_pongs}; test.Await(); } fixture->Finish(state); fixture.reset(); - state.SetBytesProcessed(2 * message_size * max_ping_pongs - * state.iterations()); + state.SetBytesProcessed(2 * message_size * max_ping_pongs * + state.iterations()); } } // namespace testing diff --git a/test/cpp/microbenchmarks/callback_test_service.cc b/test/cpp/microbenchmarks/callback_test_service.cc index c104b7a8921..328b9254869 100644 --- a/test/cpp/microbenchmarks/callback_test_service.cc +++ b/test/cpp/microbenchmarks/callback_test_service.cc @@ -49,8 +49,8 @@ int GetIntValueFromMetadata( void CallbackStreamingTestService::Echo( ServerContext* context, const EchoRequest* request, EchoResponse* response, experimental::ServerCallbackRpcController* controller) { - int response_msgs_size = GetIntValueFromMetadata(kServerMessageSize, - context->client_metadata(), 0); + int response_msgs_size = GetIntValueFromMetadata( + kServerMessageSize, context->client_metadata(), 0); if (response_msgs_size > 0) { response->set_message(std::string(response_msgs_size, 'a')); } else { diff --git a/test/cpp/microbenchmarks/callback_unary_ping_pong.h b/test/cpp/microbenchmarks/callback_unary_ping_pong.h index e4a48ad5883..065ca689bb8 100644 --- a/test/cpp/microbenchmarks/callback_unary_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_unary_ping_pong.h @@ -39,27 +39,25 @@ namespace testing { // Send next rpc when callback function is evoked. void SendCallbackUnaryPingPong(benchmark::State& state, EchoRequest* request, EchoResponse* response, - EchoTestService::Stub* stub_, - bool &done, - std::mutex& mu, - std::condition_variable& cv) { + EchoTestService::Stub* stub_, bool& done, + std::mutex& mu, std::condition_variable& cv) { int response_msgs_size = state.range(1); ClientContext* cli_ctx = new ClientContext(); - cli_ctx->AddMetadata(kServerMessageSize, - grpc::to_string(response_msgs_size)); + cli_ctx->AddMetadata(kServerMessageSize, grpc::to_string(response_msgs_size)); stub_->experimental_async()->Echo( - cli_ctx, request, response, - [&state, cli_ctx, request, response, stub_, &done, &mu, &cv](Status s) { - GPR_ASSERT(s.ok()); - if (state.KeepRunning()) { - SendCallbackUnaryPingPong(state, request, response, stub_, done, mu, cv); - } else { - std::lock_guard l(mu); - done = true; - cv.notify_one(); - } - delete cli_ctx; - }); + cli_ctx, request, response, + [&state, cli_ctx, request, response, stub_, &done, &mu, &cv](Status s) { + GPR_ASSERT(s.ok()); + if (state.KeepRunning()) { + SendCallbackUnaryPingPong(state, request, response, stub_, done, mu, + cv); + } else { + std::lock_guard l(mu); + done = true; + cv.notify_one(); + } + delete cli_ctx; + }); } template @@ -84,8 +82,8 @@ static void BM_CallbackUnaryPingPong(benchmark::State& state) { bool done = false; if (state.KeepRunning()) { GPR_TIMER_SCOPE("BenchmarkCycle", 0); - SendCallbackUnaryPingPong(state, &request, &response, stub_.get(), - done, mu, cv); + SendCallbackUnaryPingPong(state, &request, &response, stub_.get(), done, mu, + cv); } std::unique_lock l(mu); while (!done) { @@ -97,7 +95,6 @@ static void BM_CallbackUnaryPingPong(benchmark::State& state) { response_msgs_size * state.iterations()); } - } // namespace testing } // namespace grpc From db1ccad0399fd57bcf0ad3b6c3d40b3a47979abc Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 2 May 2019 18:03:02 -0700 Subject: [PATCH 2060/2143] Service Config Changes to set channel in transient failure on invalid service config --- CMakeLists.txt | 48 ++ Makefile | 52 +++ build.yaml | 13 + .../filters/client_channel/client_channel.cc | 12 +- .../resolver/dns/c_ares/dns_resolver_ares.cc | 24 +- .../client_channel/resolver_result_parsing.cc | 17 +- .../client_channel/resolver_result_parsing.h | 9 + .../client_channel/resolving_lb_policy.cc | 10 +- .../client_channel/resolving_lb_policy.h | 3 +- test/cpp/end2end/BUILD | 21 + .../end2end/service_config_end2end_test.cc | 442 ++++++++++++++++++ .../generated/sources_and_headers.json | 22 + tools/run_tests/generated/tests.json | 24 + 13 files changed, 683 insertions(+), 14 deletions(-) create mode 100644 test/cpp/end2end/service_config_end2end_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d9a411b134..42ea919f4a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -703,6 +703,7 @@ add_dependencies(buildtests_cxx server_crash_test_client) add_dependencies(buildtests_cxx server_early_return_test) add_dependencies(buildtests_cxx server_interceptors_end2end_test) add_dependencies(buildtests_cxx server_request_call_test) +add_dependencies(buildtests_cxx service_config_end2end_test) add_dependencies(buildtests_cxx service_config_test) add_dependencies(buildtests_cxx shutdown_test) add_dependencies(buildtests_cxx slice_hash_table_test) @@ -15936,6 +15937,53 @@ target_link_libraries(server_request_call_test ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(service_config_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/service_config_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(service_config_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(service_config_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) diff --git a/Makefile b/Makefile index 91ddebc7c25..b605550a38a 100644 --- a/Makefile +++ b/Makefile @@ -1265,6 +1265,7 @@ server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client server_early_return_test: $(BINDIR)/$(CONFIG)/server_early_return_test server_interceptors_end2end_test: $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test server_request_call_test: $(BINDIR)/$(CONFIG)/server_request_call_test +service_config_end2end_test: $(BINDIR)/$(CONFIG)/service_config_end2end_test service_config_test: $(BINDIR)/$(CONFIG)/service_config_test shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test slice_hash_table_test: $(BINDIR)/$(CONFIG)/slice_hash_table_test @@ -1736,6 +1737,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/server_early_return_test \ $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test \ $(BINDIR)/$(CONFIG)/server_request_call_test \ + $(BINDIR)/$(CONFIG)/service_config_end2end_test \ $(BINDIR)/$(CONFIG)/service_config_test \ $(BINDIR)/$(CONFIG)/shutdown_test \ $(BINDIR)/$(CONFIG)/slice_hash_table_test \ @@ -1882,6 +1884,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/server_early_return_test \ $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test \ $(BINDIR)/$(CONFIG)/server_request_call_test \ + $(BINDIR)/$(CONFIG)/service_config_end2end_test \ $(BINDIR)/$(CONFIG)/service_config_test \ $(BINDIR)/$(CONFIG)/shutdown_test \ $(BINDIR)/$(CONFIG)/slice_hash_table_test \ @@ -2402,6 +2405,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test || ( echo test server_interceptors_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing server_request_call_test" $(Q) $(BINDIR)/$(CONFIG)/server_request_call_test || ( echo test server_request_call_test failed ; exit 1 ) + $(E) "[RUN] Testing service_config_end2end_test" + $(Q) $(BINDIR)/$(CONFIG)/service_config_end2end_test || ( echo test service_config_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing service_config_test" $(Q) $(BINDIR)/$(CONFIG)/service_config_test || ( echo test service_config_test failed ; exit 1 ) $(E) "[RUN] Testing shutdown_test" @@ -18895,6 +18900,53 @@ endif $(OBJDIR)/$(CONFIG)/test/cpp/server/server_request_call_test.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc +SERVICE_CONFIG_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/service_config_end2end_test.cc \ + +SERVICE_CONFIG_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVICE_CONFIG_END2END_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/service_config_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)/service_config_end2end_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/service_config_end2end_test: $(PROTOBUF_DEP) $(SERVICE_CONFIG_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) $(SERVICE_CONFIG_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)/service_config_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/service_config_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_service_config_end2end_test: $(SERVICE_CONFIG_END2END_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(SERVICE_CONFIG_END2END_TEST_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/service_config_end2end_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc + + SERVICE_CONFIG_TEST_SRC = \ test/core/client_channel/service_config_test.cc \ diff --git a/build.yaml b/build.yaml index e56284d4d3c..46b016c6be4 100644 --- a/build.yaml +++ b/build.yaml @@ -5520,6 +5520,19 @@ targets: - grpc++_unsecure - grpc_unsecure - gpr +- name: service_config_end2end_test + gtest: true + build: test + language: c++ + src: + - src/proto/grpc/lb/v1/load_balancer.proto + - test/cpp/end2end/service_config_end2end_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr - name: service_config_test gtest: true build: test diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 248e7811bba..6aa1d615b7f 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -224,7 +224,8 @@ class ChannelData { static bool ProcessResolverResultLocked( void* arg, const Resolver::Result& result, const char** lb_policy_name, - RefCountedPtr* lb_policy_config); + RefCountedPtr* lb_policy_config, + grpc_error** service_config_error); grpc_error* DoPingLocked(grpc_transport_op* op); @@ -1132,9 +1133,16 @@ ChannelData::~ChannelData() { // resolver result update. bool ChannelData::ProcessResolverResultLocked( void* arg, const Resolver::Result& result, const char** lb_policy_name, - RefCountedPtr* lb_policy_config) { + RefCountedPtr* lb_policy_config, + grpc_error** service_config_error) { ChannelData* chand = static_cast(arg); ProcessedResolverResult resolver_result(result); + + *service_config_error = resolver_result.service_config_error(); + if (*service_config_error != GRPC_ERROR_NONE) { + // We got an invalid service config. + return false; + } char* service_config_json = gpr_strdup(resolver_result.service_config_json()); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", 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 6994f63bee4..0f11eeda39c 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 @@ -110,6 +110,8 @@ class AresDnsResolver : public Resolver { UniquePtr addresses_; /// currently resolving service config char* service_config_json_ = nullptr; + /// last valid service config + RefCountedPtr saved_service_config_; // has shutdown been initiated bool shutdown_initiated_ = false; // timeout in milliseconds for active DNS queries @@ -310,13 +312,29 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s", r, service_config_string); grpc_error* service_config_error = GRPC_ERROR_NONE; - result.service_config = + auto new_service_config = ServiceConfig::Create(service_config_string, &service_config_error); - // Error is currently unused. - GRPC_ERROR_UNREF(service_config_error); + if (service_config_error == GRPC_ERROR_NONE) { + // Valid service config receivd + r->saved_service_config_ = std::move(new_service_config); + } else { + if (r->saved_service_config_ != nullptr) { + // Ignore the new service config error, since we have a previously + // saved service config + GRPC_ERROR_UNREF(service_config_error); + } else { + // No previously valid service config found. + // service_config_error is passed to the channel. + result.service_config_error = service_config_error; + } + } } gpr_free(service_config_string); + } else { + // No service config received + r->saved_service_config_.reset(); } + result.service_config = r->saved_service_config_; result.args = grpc_channel_args_copy(r->channel_args_); r->result_handler()->ReturnResult(std::move(result)); r->addresses_.reset(); 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 452dea6a0f7..6b3d26c32b8 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -61,17 +61,24 @@ void ClientChannelServiceConfigParser::Register() { ProcessedResolverResult::ProcessedResolverResult( const Resolver::Result& resolver_result) : service_config_(resolver_result.service_config) { - // If resolver did not return a service config, use the default + // If resolver did not return a service config or returned an invalid 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) { - grpc_error* error = GRPC_ERROR_NONE; - service_config_ = ServiceConfig::Create(service_config_json, &error); - // Error is currently unused. - GRPC_ERROR_UNREF(error); + service_config_ = + ServiceConfig::Create(service_config_json, &service_config_error_); + } else { + service_config_error_ = GRPC_ERROR_REF(resolver_result.service_config_error); } + } else { + service_config_error_ = + GRPC_ERROR_REF(resolver_result.service_config_error); + } + if (service_config_error_ != GRPC_ERROR_NONE) { + // We got an invalid service config. Don't process any further. + return; } // Process service config. const ClientChannelGlobalParsedObject* parsed_object = nullptr; 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 7307149496f..3845aab5b25 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -127,6 +127,8 @@ class ProcessedResolverResult { // for later consumption. ProcessedResolverResult(const Resolver::Result& resolver_result); + ~ProcessedResolverResult() { GRPC_ERROR_UNREF(service_config_error_); } + // Getters. Any managed object's ownership is transferred. const char* service_config_json() { return service_config_json_; } @@ -144,6 +146,12 @@ class ProcessedResolverResult { const char* health_check_service_name() { return health_check_service_name_; } + grpc_error* service_config_error() { + grpc_error* return_error = service_config_error_; + service_config_error_ = GRPC_ERROR_NONE; + return return_error; + } + private: // Finds the service config; extracts LB config and (maybe) retry throttle // params from it. @@ -167,6 +175,7 @@ class ProcessedResolverResult { // Service config. const char* service_config_json_ = nullptr; RefCountedPtr service_config_; + grpc_error* service_config_error_ = GRPC_ERROR_NONE; // LB policy. UniquePtr lb_policy_name_; RefCountedPtr lb_policy_config_; 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 193c9e256ed..a0d5d02a6d4 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -533,9 +533,13 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( 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); + grpc_error* service_config_error = GRPC_ERROR_NONE; + service_config_changed = process_resolver_result_( + process_resolver_result_user_data_, result, &lb_policy_name, + &lb_policy_config, &service_config_error); + if (service_config_error != GRPC_ERROR_NONE) { + return OnResolverError(service_config_error); + } } else { lb_policy_name = child_policy_name_.get(); lb_policy_config = child_lb_config_; 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 dd8a1de6c7a..fa609aac5f2 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -68,7 +68,8 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { typedef bool (*ProcessResolverResultCallback)( void* user_data, const Resolver::Result& result, const char** lb_policy_name, - RefCountedPtr* lb_policy_config); + RefCountedPtr* lb_policy_config, + grpc_error** service_config_error); // If error is set when this returns, then construction failed, and // the caller may not use the new object. ResolvingLoadBalancingPolicy( diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 56fc5e06008..d211a9e8441 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -423,6 +423,27 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "service_config_end2end_test", + srcs = ["service_config_end2end_test.cc"], + external_deps = [ + "gmock", + "gtest", + ], + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//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/core/util:test_lb_policies", + "//test/cpp/util:test_util", + ], +) + grpc_cc_test( name = "grpclb_end2end_test", srcs = ["grpclb_end2end_test.cc"], diff --git a/test/cpp/end2end/service_config_end2end_test.cc b/test/cpp/end2end/service_config_end2end_test.cc new file mode 100644 index 00000000000..cf0c6d259c1 --- /dev/null +++ b/test/cpp/end2end/service_config_end2end_test.cc @@ -0,0 +1,442 @@ +/* + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#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/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/backoff/backoff.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/debug_location.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/tcp_client.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 "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.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 +#include + +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; +using std::chrono::system_clock; + +namespace grpc { +namespace testing { +namespace { + +// Subclass of TestServiceImpl that increments a request counter for +// every call to the Echo RPC. +class MyTestServiceImpl : public TestServiceImpl { + public: + MyTestServiceImpl() : request_count_(0) {} + + Status Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response) override { + { + grpc::internal::MutexLock lock(&mu_); + ++request_count_; + } + AddClient(context->peer()); + return TestServiceImpl::Echo(context, request, response); + } + + int request_count() { + grpc::internal::MutexLock lock(&mu_); + return request_count_; + } + + void ResetCounters() { + grpc::internal::MutexLock lock(&mu_); + request_count_ = 0; + } + + std::set clients() { + grpc::internal::MutexLock lock(&clients_mu_); + return clients_; + } + + private: + void AddClient(const grpc::string& client) { + grpc::internal::MutexLock lock(&clients_mu_); + clients_.insert(client); + } + + grpc::internal::Mutex mu_; + int request_count_; + grpc::internal::Mutex clients_mu_; + std::set clients_; +}; + +class ServiceConfigEnd2endTest : public ::testing::Test { + protected: + ServiceConfigEnd2endTest() + : server_host_("localhost"), + kRequestMessage_("Live long and prosper."), + creds_(new SecureChannelCredentials( + grpc_fake_transport_security_credentials_create())) { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); + } + + void SetUp() override { + grpc_init(); + response_generator_ = + grpc_core::MakeRefCounted(); + } + + void TearDown() override { + for (size_t i = 0; i < servers_.size(); ++i) { + servers_[i]->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, + std::vector ports = std::vector()) { + servers_.clear(); + for (size_t i = 0; i < num_servers; ++i) { + int port = 0; + if (ports.size() == num_servers) port = ports[i]; + servers_.emplace_back(new ServerData(port)); + } + } + + void StartServer(size_t index) { servers_[index]->Start(server_host_); } + + void StartServers(size_t num_servers, + std::vector ports = std::vector()) { + CreateServers(num_servers, std::move(ports)); + for (size_t i = 0; i < num_servers; ++i) { + StartServer(i); + } + } + + 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); + 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)); + result.addresses.emplace_back(address.addr, address.len, + nullptr /* args */); + grpc_uri_destroy(lb_uri); + gpr_free(lb_uri_str); + } + return result; + } + + void SetNextResolutionNoServiceConfig(const std::vector& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result = BuildFakeResults(ports); + response_generator_->SetResponse(result); + } + + void SetNextResolutionValidServiceConfig(const std::vector& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result = BuildFakeResults(ports); + result.service_config = grpc_core::ServiceConfig::Create("{}", &result.service_config_error); + response_generator_->SetResponse(result); + } + + void SetNextResolutionInvalidServiceConfig(const std::vector& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result = BuildFakeResults(ports); + result.service_config = grpc_core::ServiceConfig::Create("{", &result.service_config_error); + response_generator_->SetResponse(result); + } + + void SetNextResolutionUponError(const std::vector& ports) { + grpc_core::ExecCtx exec_ctx; + response_generator_->SetReresolutionResponse(BuildFakeResults(ports)); + } + + void SetFailureOnReresolution() { + grpc_core::ExecCtx exec_ctx; + response_generator_->SetFailureOnReresolution(); + } + + std::vector GetServersPorts(size_t start_index = 0) { + std::vector ports; + for (size_t i = start_index; i < servers_.size(); ++i) { + ports.push_back(servers_[i]->port_); + } + return ports; + } + + std::unique_ptr BuildStub( + const std::shared_ptr& channel) { + return grpc::testing::EchoTestService::NewStub(channel); + } + + std::shared_ptr BuildChannel( + ChannelArguments args = ChannelArguments()) { + args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, + response_generator_.get()); + return ::grpc::CreateCustomChannel("fake:///", creds_, args); + } + + bool SendRpc( + const std::unique_ptr& stub, + EchoResponse* response = nullptr, int timeout_ms = 1000, + Status* result = nullptr, 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 (result != nullptr) *result = status; + if (local_response) delete response; + return status.ok(); + } + + void CheckRpcSendOk( + const std::unique_ptr& stub, + const grpc_core::DebugLocation& location, bool wait_for_ready = false) { + EchoResponse response; + Status status; + const bool success = + SendRpc(stub, &response, 2000, &status, wait_for_ready); + ASSERT_TRUE(success) << "From " << location.file() << ":" << location.line() + << "\n" + << "Error: " << status.error_message() << " " + << status.error_details(); + ASSERT_EQ(response.message(), kRequestMessage_) + << "From " << location.file() << ":" << location.line(); + if (!success) abort(); + } + + void CheckRpcSendFailure( + const std::unique_ptr& stub) { + const bool success = SendRpc(stub); + EXPECT_FALSE(success); + } + + struct ServerData { + int port_; + std::unique_ptr server_; + MyTestServiceImpl service_; + std::unique_ptr thread_; + bool server_ready_ = false; + bool started_ = false; + + explicit ServerData(int port = 0) { + port_ = port > 0 ? port : grpc_pick_unused_port_or_die(); + } + + void Start(const grpc::string& server_host) { + gpr_log(GPR_INFO, "starting server on port %d", port_); + started_ = true; + grpc::internal::Mutex mu; + grpc::internal::MutexLock lock(&mu); + grpc::internal::CondVar cond; + thread_.reset(new std::thread( + std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); + cond.WaitUntil(&mu, [this] { return server_ready_; }); + server_ready_ = false; + gpr_log(GPR_INFO, "server startup complete"); + } + + void Serve(const grpc::string& server_host, grpc::internal::Mutex* mu, + grpc::internal::CondVar* cond) { + 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(), std::move(creds)); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + grpc::internal::MutexLock lock(mu); + server_ready_ = true; + cond->Signal(); + } + + void Shutdown() { + if (!started_) return; + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + thread_->join(); + started_ = false; + } + + void SetServingStatus(const grpc::string& service, bool serving) { + server_->GetHealthCheckService()->SetServingStatus(service, serving); + } + }; + + void ResetCounters() { + for (const auto& server : servers_) server->service_.ResetCounters(); + } + + void WaitForServer( + const std::unique_ptr& stub, + size_t server_idx, const grpc_core::DebugLocation& location, + bool ignore_failure = false) { + do { + if (ignore_failure) { + SendRpc(stub); + } else { + CheckRpcSendOk(stub, location, true); + } + } while (servers_[server_idx]->service_.request_count() == 0); + ResetCounters(); + } + + 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; + } + + bool SeenAllServers() { + for (const auto& server : servers_) { + if (server->service_.request_count() == 0) return false; + } + return true; + } + + // Updates \a connection_order by appending to it the index of the newly + // connected server. Must be called after every single RPC. + void UpdateConnectionOrder( + const std::vector>& servers, + std::vector* connection_order) { + for (size_t i = 0; i < servers.size(); ++i) { + if (servers[i]->service_.request_count() == 1) { + // Was the server index known? If not, update connection_order. + const auto it = + std::find(connection_order->begin(), connection_order->end(), i); + if (it == connection_order->end()) { + connection_order->push_back(i); + return; + } + } + } + } + + const grpc::string server_host_; + std::unique_ptr stub_; + std::vector> servers_; + grpc_core::RefCountedPtr + response_generator_; + const grpc::string kRequestMessage_; + std::shared_ptr creds_; +}; + +TEST_F(ServiceConfigEnd2endTest, BasicTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); +} + +TEST_F(ServiceConfigEnd2endTest, InvalidServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, ValidServiceConfigAfterInvalidTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); + SetNextResolutionValidServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); +} + +TEST_F(ServiceConfigEnd2endTest, InvalidServiceConfigWithDefaultConfigTest) { + StartServers(1); + ChannelArguments args; + args.SetServiceConfigJSON("{}"); + auto channel = BuildChannel(args); + auto stub = BuildStub(channel); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc::testing::TestEnvironment env(argc, argv); + const auto result = RUN_ALL_TESTS(); + return result; +} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 825f8771006..e535a335a7b 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -4795,6 +4795,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": "service_config_end2end_test", + "src": [ + "test/cpp/end2end/service_config_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 8c14282acbb..c156c8347ae 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -5445,6 +5445,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": "service_config_end2end_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From 71085f3e3b314a3a633925ae801dc881ee3adf0b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 2 May 2019 18:21:52 -0700 Subject: [PATCH 2061/2143] Changes --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 58 +++++++++++-------- .../client_channel/resolver_result_parsing.cc | 7 ++- .../end2end/service_config_end2end_test.cc | 10 ++-- 3 files changed, 45 insertions(+), 30 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 0f11eeda39c..e49dbf21fdd 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 @@ -229,17 +229,20 @@ bool ValueInJsonArray(grpc_json* array, const char* value) { return false; } -char* ChooseServiceConfig(char* service_config_choice_json) { +char* ChooseServiceConfig(char* service_config_choice_json, + grpc_error** error) { grpc_json* choices_json = grpc_json_parse_string(service_config_choice_json); if (choices_json == nullptr || choices_json->type != GRPC_JSON_ARRAY) { - gpr_log(GPR_ERROR, "cannot parse service config JSON string"); + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "cannot parse service config JSON string"); return nullptr; } char* service_config = nullptr; for (grpc_json* choice = choices_json->child; choice != nullptr; choice = choice->next) { if (choice->type != GRPC_JSON_OBJECT) { - gpr_log(GPR_ERROR, "cannot parse service config JSON string"); + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "cannot parse service config JSON string"); break; } grpc_json* service_config_json = nullptr; @@ -305,31 +308,40 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { Result result; result.addresses = std::move(*r->addresses_); if (r->service_config_json_ != nullptr) { + grpc_error* service_config_error = GRPC_ERROR_NONE; char* service_config_string = - ChooseServiceConfig(r->service_config_json_); + ChooseServiceConfig(r->service_config_json_, &service_config_error); 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); - grpc_error* service_config_error = GRPC_ERROR_NONE; - auto new_service_config = - ServiceConfig::Create(service_config_string, &service_config_error); - if (service_config_error == GRPC_ERROR_NONE) { - // Valid service config receivd - r->saved_service_config_ = std::move(new_service_config); + RefCountedPtr new_service_config; + if (service_config_error == GRPC_ERROR_NONE) { + if (service_config_string != nullptr) { + GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s", + r, service_config_string); + new_service_config = ServiceConfig::Create(service_config_string, + &service_config_error); + gpr_free(service_config_string); } else { - if (r->saved_service_config_ != nullptr) { - // Ignore the new service config error, since we have a previously - // saved service config - GRPC_ERROR_UNREF(service_config_error); - } else { - // No previously valid service config found. - // service_config_error is passed to the channel. - result.service_config_error = service_config_error; - } + // Use an empty service config since we did not find a choice + GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: {}", + r); + new_service_config = + ServiceConfig::Create("{}", &service_config_error); + } + } + if (service_config_error == GRPC_ERROR_NONE) { + // Valid service config receivd + r->saved_service_config_ = std::move(new_service_config); + } else { + if (r->saved_service_config_ != nullptr) { + // Ignore the new service config error, since we have a previously + // saved service config + GRPC_ERROR_UNREF(service_config_error); + } else { + // No previously valid service config found. + // service_config_error is passed to the channel. + result.service_config_error = service_config_error; } } - gpr_free(service_config_string); } else { // No service config received r->saved_service_config_.reset(); 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 6b3d26c32b8..4632561c7ea 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -61,8 +61,8 @@ void ClientChannelServiceConfigParser::Register() { ProcessedResolverResult::ProcessedResolverResult( const Resolver::Result& resolver_result) : service_config_(resolver_result.service_config) { - // If resolver did not return a service config or returned an invalid service config, use the default - // specified via the client API. + // If resolver did not return a service config or returned an invalid 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)); @@ -70,7 +70,8 @@ ProcessedResolverResult::ProcessedResolverResult( service_config_ = ServiceConfig::Create(service_config_json, &service_config_error_); } else { - service_config_error_ = GRPC_ERROR_REF(resolver_result.service_config_error); + service_config_error_ = + GRPC_ERROR_REF(resolver_result.service_config_error); } } else { service_config_error_ = diff --git a/test/cpp/end2end/service_config_end2end_test.cc b/test/cpp/end2end/service_config_end2end_test.cc index cf0c6d259c1..5d3be598a32 100644 --- a/test/cpp/end2end/service_config_end2end_test.cc +++ b/test/cpp/end2end/service_config_end2end_test.cc @@ -188,14 +188,16 @@ class ServiceConfigEnd2endTest : public ::testing::Test { void SetNextResolutionValidServiceConfig(const std::vector& ports) { grpc_core::ExecCtx exec_ctx; grpc_core::Resolver::Result result = BuildFakeResults(ports); - result.service_config = grpc_core::ServiceConfig::Create("{}", &result.service_config_error); + result.service_config = + grpc_core::ServiceConfig::Create("{}", &result.service_config_error); response_generator_->SetResponse(result); } void SetNextResolutionInvalidServiceConfig(const std::vector& ports) { grpc_core::ExecCtx exec_ctx; grpc_core::Resolver::Result result = BuildFakeResults(ports); - result.service_config = grpc_core::ServiceConfig::Create("{", &result.service_config_error); + result.service_config = + grpc_core::ServiceConfig::Create("{", &result.service_config_error); response_generator_->SetResponse(result); } @@ -415,7 +417,7 @@ TEST_F(ServiceConfigEnd2endTest, ValidServiceConfigAfterInvalidTest) { auto channel = BuildChannel(); auto stub = BuildStub(channel); SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); + CheckRpcSendFailure(stub); SetNextResolutionValidServiceConfig(GetServersPorts()); CheckRpcSendOk(stub, DEBUG_LOCATION); } @@ -427,7 +429,7 @@ TEST_F(ServiceConfigEnd2endTest, InvalidServiceConfigWithDefaultConfigTest) { auto channel = BuildChannel(args); auto stub = BuildStub(channel); SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); + CheckRpcSendOk(stub, DEBUG_LOCATION); } } // namespace From 0217450e2ca2f3b52fe18f62e7516326d4a355b2 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Fri, 3 May 2019 10:05:32 -0700 Subject: [PATCH 2062/2143] Sanitized some sources --- .../resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc | 2 +- .../resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc | 2 +- .../resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc | 2 +- src/python/grpcio_tests/tests/interop/service.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc index e272e5a8800..04e36fbcee7 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -176,4 +176,4 @@ UniquePtr NewGrpcPolledFdFactory(grpc_combiner* combiner) { } // namespace grpc_core -#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ \ No newline at end of file +#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc index cab74f8ba64..fdbb8969a1f 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -49,4 +49,4 @@ bool grpc_ares_maybe_resolve_localhost_manually_locked( return out; } -#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ \ No newline at end of file +#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc index 07906f282aa..1232fc9d57c 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc @@ -80,4 +80,4 @@ bool inner_maybe_resolve_localhost_manually_locked( return false; } -#endif /* GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) */ \ No newline at end of file +#endif /* GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) */ diff --git a/src/python/grpcio_tests/tests/interop/service.py b/src/python/grpcio_tests/tests/interop/service.py index 20f76fceebf..37e4404c141 100644 --- a/src/python/grpcio_tests/tests/interop/service.py +++ b/src/python/grpcio_tests/tests/interop/service.py @@ -94,4 +94,4 @@ class TestService(test_pb2_grpc.TestServiceServicer): # NOTE(nathaniel): Apparently this is the same as the full-duplex call? # NOTE(atash): It isn't even called in the interop spec (Oct 22 2015)... def HalfDuplexCall(self, request_iterator, context): - return self.FullDuplexCall(request_iterator, context) \ No newline at end of file + return self.FullDuplexCall(request_iterator, context) From 2787dedd7049370c642e9315af3adc41a962545c Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Fri, 3 May 2019 10:40:49 -0700 Subject: [PATCH 2063/2143] Modify dependency of callback_test_service --- CMakeLists.txt | 117 +----------------- Makefile | 107 +--------------- build.yaml | 15 +-- grpc.gyp | 8 +- test/cpp/microbenchmarks/BUILD | 7 ++ .../generated/sources_and_headers.json | 9 +- 6 files changed, 35 insertions(+), 228 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f36f436d0ce..f7adb03c959 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2910,7 +2910,6 @@ if (gRPC_BUILD_TESTS) add_library(callback_test_service test/cpp/microbenchmarks/callback_test_service.cc - src/cpp/codegen/codegen_init.cc ) if(WIN32 AND MSVC) @@ -2945,121 +2944,17 @@ target_include_directories(callback_test_service target_link_libraries(callback_test_service ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} - grpc++_unsecure + grpc_benchmark + ${_gRPC_BENCHMARK_LIBRARIES} + grpc++_test_util_unsecure grpc_test_util_unsecure + grpc++_unsecure grpc_unsecure + gpr + grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} ) -foreach(_hdr - 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/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/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/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/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/message_allocator.h - include/grpcpp/impl/codegen/metadata_map.h - include/grpcpp/impl/codegen/method_handler_impl.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/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/grpc_types.h - include/grpc/impl/codegen/propagation_bits.h - include/grpc/impl/codegen/slice.h - include/grpc/impl/codegen/status.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/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/grpcpp/impl/codegen/sync.h - include/grpc++/impl/codegen/proto_utils.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/grpc++/impl/codegen/config_protobuf.h - include/grpcpp/impl/codegen/config_protobuf.h -) - string(REPLACE "include/" "" _path ${_hdr}) - get_filename_component(_path ${_path} PATH) - install(FILES ${_hdr} - DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" - ) -endforeach() endif (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 448d7167eb4..ab8302265e1 100644 --- a/Makefile +++ b/Makefile @@ -1412,9 +1412,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)/libcallback_test_service.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)/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)/libcallback_test_service.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 @@ -5290,113 +5290,12 @@ endif LIBCALLBACK_TEST_SERVICE_SRC = \ test/cpp/microbenchmarks/callback_test_service.cc \ - src/cpp/codegen/codegen_init.cc \ PUBLIC_HEADERS_CXX += \ - 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/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/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/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/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/message_allocator.h \ - include/grpcpp/impl/codegen/metadata_map.h \ - include/grpcpp/impl/codegen/method_handler_impl.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/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/grpc_types.h \ - include/grpc/impl/codegen/propagation_bits.h \ - include/grpc/impl/codegen/slice.h \ - include/grpc/impl/codegen/status.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/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/grpcpp/impl/codegen/sync.h \ - include/grpc++/impl/codegen/proto_utils.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/grpc++/impl/codegen/config_protobuf.h \ - include/grpcpp/impl/codegen/config_protobuf.h \ LIBCALLBACK_TEST_SERVICE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBCALLBACK_TEST_SERVICE_SRC)))) +$(LIBCALLBACK_TEST_SERVICE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX ifeq ($(NO_SECURE),true) diff --git a/build.yaml b/build.yaml index fc465dcb719..bae2c217ae7 100644 --- a/build.yaml +++ b/build.yaml @@ -1666,21 +1666,22 @@ libs: - grpc - gpr - name: callback_test_service - build: private + build: test language: c++ headers: - test/cpp/microbenchmarks/callback_test_service.h src: - test/cpp/microbenchmarks/callback_test_service.cc deps: - - grpc++_unsecure + - grpc_benchmark + - benchmark + - grpc++_test_util_unsecure - grpc_test_util_unsecure + - grpc++_unsecure - grpc_unsecure - filegroups: - - grpc++_codegen_base - - grpc++_codegen_base_src - - grpc++_codegen_proto - - grpc++_config_proto + - gpr + - grpc++_test_config + defaults: benchmark - name: grpc++ build: all language: c++ diff --git a/grpc.gyp b/grpc.gyp index 30e155f421f..10e98b1011a 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1402,13 +1402,17 @@ 'target_name': 'callback_test_service', 'type': 'static_library', 'dependencies': [ - 'grpc++_unsecure', + 'grpc_benchmark', + 'benchmark', + 'grpc++_test_util_unsecure', 'grpc_test_util_unsecure', + 'grpc++_unsecure', 'grpc_unsecure', + 'gpr', + 'grpc++_test_config', ], 'sources': [ 'test/cpp/microbenchmarks/callback_test_service.cc', - 'src/cpp/codegen/codegen_init.cc', ], }, { diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 0be64c3b319..4af453740b4 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -227,8 +227,15 @@ grpc_cc_library( testonly = 1, srcs = ["callback_test_service.cc"], hdrs = ["callback_test_service.h"], + external_deps = [ + "benchmark", + ], + tags = ["no_windows"], deps = [ + "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", + "//test/core/util:grpc_test_util_unsecure", + "//test/cpp/util:test_config", "//test/cpp/util:test_util", ], ) diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 6803c495654..b1f579492fe 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -6646,11 +6646,12 @@ }, { "deps": [ - "grpc++_codegen_base", - "grpc++_codegen_base_src", - "grpc++_codegen_proto", - "grpc++_config_proto", + "benchmark", + "gpr", + "grpc++_test_config", + "grpc++_test_util_unsecure", "grpc++_unsecure", + "grpc_benchmark", "grpc_test_util_unsecure", "grpc_unsecure" ], From 93dc228a8a795a9b3820a0ce0f57277408694b6b Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 3 May 2019 16:35:09 -0400 Subject: [PATCH 2064/2143] Avoid copy on slice_ref. This was accidentially added in PR #18407 --- src/core/lib/slice/slice_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index db8c8e5c7cc..a9f6087e11f 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -222,7 +222,7 @@ inline uint32_t grpc_slice_refcount::Hash(const grpc_slice& slice) { g_hash_seed); } -inline grpc_slice grpc_slice_ref_internal(const grpc_slice& slice) { +inline const grpc_slice& grpc_slice_ref_internal(const grpc_slice& slice) { if (slice.refcount) { slice.refcount->Ref(); } From 587ae4a2d9239d330825f8d06a8b56dcc101c328 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 3 May 2019 14:39:11 -0700 Subject: [PATCH 2065/2143] Fix existing tests --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 21 ++++-------- test/core/end2end/tests/retry_throttled.cc | 2 +- .../naming/resolver_component_tests_runner.py | 12 +++---- .../naming/resolver_test_record_groups.yaml | 34 +++++++++---------- 4 files changed, 31 insertions(+), 38 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 e49dbf21fdd..6b8f907502b 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 @@ -313,21 +313,14 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { ChooseServiceConfig(r->service_config_json_, &service_config_error); gpr_free(r->service_config_json_); RefCountedPtr new_service_config; - if (service_config_error == GRPC_ERROR_NONE) { - if (service_config_string != nullptr) { - GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s", - r, service_config_string); - new_service_config = ServiceConfig::Create(service_config_string, - &service_config_error); - gpr_free(service_config_string); - } else { - // Use an empty service config since we did not find a choice - GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: {}", - r); - new_service_config = - ServiceConfig::Create("{}", &service_config_error); - } + if (service_config_error == GRPC_ERROR_NONE && + service_config_string != nullptr) { + GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s", + r, service_config_string); + new_service_config = + ServiceConfig::Create(service_config_string, &service_config_error); } + gpr_free(service_config_string); if (service_config_error == GRPC_ERROR_NONE) { // Valid service config receivd r->saved_service_config_ = std::move(new_service_config); diff --git a/test/core/end2end/tests/retry_throttled.cc b/test/core/end2end/tests/retry_throttled.cc index f5b28def0ad..0e286c3d17c 100644 --- a/test/core/end2end/tests/retry_throttled.cc +++ b/test/core/end2end/tests/retry_throttled.cc @@ -141,7 +141,7 @@ static void test_retry_throttled(grpc_end2end_test_config config) { // purposes of this test.) " \"retryThrottling\": {\n" " \"maxTokens\": 2,\n" - " \"tokenRatio\": 1.0,\n" + " \"tokenRatio\": 1.0\n" " }\n" "}"); grpc_channel_args client_args = {1, &arg}; diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index a0eda79ec62..2d875ce00ae 100755 --- a/test/cpp/naming/resolver_component_tests_runner.py +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -193,7 +193,7 @@ current_test_subprocess = subprocess.Popen([ args.test_bin_path, '--target_name', 'srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:1234,True', - '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":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', '--enable_txt_queries', 'True', @@ -207,7 +207,7 @@ current_test_subprocess = subprocess.Popen([ args.test_bin_path, '--target_name', 'ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:443,False', - '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}', + '--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', @@ -249,7 +249,7 @@ current_test_subprocess = subprocess.Popen([ args.test_bin_path, '--target_name', 'ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:443,False', - '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}', + '--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', @@ -263,7 +263,7 @@ current_test_subprocess = subprocess.Popen([ args.test_bin_path, '--target_name', 'ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:443,False', - '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}', + '--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', @@ -305,7 +305,7 @@ current_test_subprocess = subprocess.Popen([ args.test_bin_path, '--target_name', 'ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.', '--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_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', @@ -375,7 +375,7 @@ 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_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', diff --git a/test/cpp/naming/resolver_test_record_groups.yaml b/test/cpp/naming/resolver_test_record_groups.yaml index 738fe658939..bfb8b4ede2d 100644 --- a/test/cpp/naming/resolver_test_record_groups.yaml +++ b/test/cpp/naming/resolver_test_record_groups.yaml @@ -69,7 +69,7 @@ resolver_component_tests: - {TTL: '2100', data: '2607:f8b0:400a:801::1004', type: AAAA} - expected_addrs: - {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_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 @@ -80,11 +80,11 @@ resolver_component_tests: ipv4-simple-service-config: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.srv-ipv4-simple-service-config: - - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}}]', + - {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: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}' + 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 @@ -93,7 +93,7 @@ resolver_component_tests: ipv4-no-srv-simple-service-config: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.ipv4-no-srv-simple-service-config: - - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}}]', + - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService"}],"waitForReady":true}]}}]', type: TXT} - expected_addrs: - {address: '1.2.3.4:443', is_balancer: false} @@ -106,7 +106,7 @@ resolver_component_tests: ipv4-no-config-for-cpp: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.ipv4-no-config-for-cpp: - - {TTL: '2100', data: 'grpc_config=[{"clientLanguage":["python"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"PythonService","waitForReady":true}]}]}}]', + - {TTL: '2100', data: 'grpc_config=[{"clientLanguage":["python"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"PythonService"}],"waitForReady":true}]}}]', type: TXT} - expected_addrs: - {address: '1.2.3.4:443', is_balancer: false} @@ -119,11 +119,11 @@ resolver_component_tests: ipv4-cpp-config-has-zero-percentage: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.ipv4-cpp-config-has-zero-percentage: - - {TTL: '2100', data: 'grpc_config=[{"percentage":0,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}}]', + - {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: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}' + 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 @@ -132,11 +132,11 @@ resolver_component_tests: ipv4-second-language-is-cpp: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.ipv4-second-language-is-cpp: - - {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}]}]}}]', + - {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} - expected_addrs: - {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_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 @@ -145,7 +145,7 @@ resolver_component_tests: ipv4-config-with-percentages: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.ipv4-config-with-percentages: - - {TTL: '2100', data: 'grpc_config=[{"percentage":0,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NeverPickedService","waitForReady":true}]}]}},{"percentage":100,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}}]', + - {TTL: '2100', data: 'grpc_config=[{"percentage":0,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NeverPickedService"}],"waitForReady":true}]}},{"percentage":100,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService"}],"waitForReady":true}]}}]', type: TXT} - expected_addrs: - {address: '1.2.3.4:1234', is_balancer: true} @@ -179,7 +179,7 @@ resolver_component_tests: - {TTL: '2100', data: '2607:f8b0:400a:801::1002', type: AAAA} - expected_addrs: - {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_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 @@ -188,7 +188,7 @@ resolver_component_tests: ipv4-config-causing-fallback-to-tcp: - {TTL: '2100', data: 1.2.3.4, type: A} _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}]}]}}]', + - {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: @@ -261,7 +261,7 @@ resolver_component_tests: - {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_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 @@ -274,7 +274,7 @@ resolver_component_tests: 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}]}]}}]', + - {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} @@ -289,7 +289,7 @@ resolver_component_tests: 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}]}]}}]', + - {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} @@ -302,7 +302,7 @@ resolver_component_tests: 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}]}]}}]', + - {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} @@ -315,5 +315,5 @@ resolver_component_tests: 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}]}]}}]', + - {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 4269ce08f4e6c6fb7a91a662e04469b26ceb0c30 Mon Sep 17 00:00:00 2001 From: vam Date: Fri, 3 May 2019 16:43:54 -0700 Subject: [PATCH 2066/2143] Make cc_grpc_library compatible with native proto_library and cc_proto_library rules. This is needed to comply with bazel best practices (each proto file is first processed by proto_library: https://docs.bazel.build/versions/master/be/protocol-buffer.html#proto_library) and generally bring cc_grcp_library rule up to date with latest Bazel changes (the rule hasn't gotten much updates since 2016). Detailed description. Bazel has native `cc_proto_library` rule, but it does not have `cc_grpc_library`. The rule in cc_grpc_library in this repo seems like the best candidate. This change makes possible using `cc_grpc_library` to generate on grpc library, and consume protobuf protion as dependencies. The typical `BUILD.bazel` file configuraiton now should look like the following: ```python proto_library( name = "my_proto", srcs = ["my.proto"], ) cc_proto_library( name = "my_cc_proto", deps = [":my_proto"] ) cc_grpc_library( name = "my_cc_grpc", srcs = [":my_proto"], deps = [":my_cc_proto"] ) ``` This allows to decouple all thre phases: proto descriptors generation (`proto_library`), protobuf messages library creation (`cc_proto_library`), grpc library creatio (`cc_grpc_library`). Notice how `cc_grpc_library` depends on `proto_library` (as `src`) and on `cc_proto_library` (as `deps`). Currently cc_grpc_library is designed in a way that it encapsulates all of the above and directly accepts .proto files as srcs. The previous version (before this PR) of cc_proto_library was encapsulating all of the 3 phases inside single `cc_proto_library` and also was doing it manually (without relying on the native `cc_proto_library`). The `cc_proto_library` is kept backward-compatible with the old version. --- bazel/BUILD | 12 ---- bazel/cc_grpc_library.bzl | 146 ++++++++++++++++++++++---------------- examples/BUILD | 27 +++++-- 3 files changed, 107 insertions(+), 78 deletions(-) diff --git a/bazel/BUILD b/bazel/BUILD index 32402892cc3..c3c82c9c0c7 100644 --- a/bazel/BUILD +++ b/bazel/BUILD @@ -17,15 +17,3 @@ licenses(["notice"]) # Apache v2 package(default_visibility = ["//:__subpackages__"]) load(":cc_grpc_library.bzl", "cc_grpc_library") - -proto_library( - name = "well_known_protos_list", - srcs = ["@com_google_protobuf//:well_known_protos"], -) - -cc_grpc_library( - name = "well_known_protos", - srcs = "well_known_protos_list", - proto_only = True, - deps = [], -) diff --git a/bazel/cc_grpc_library.bzl b/bazel/cc_grpc_library.bzl index 6bfcd653f51..6bfd9e0c185 100644 --- a/bazel/cc_grpc_library.bzl +++ b/bazel/cc_grpc_library.bzl @@ -2,70 +2,94 @@ load("//bazel:generate_cc.bzl", "generate_cc") -def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, generate_mocks = False, use_external = False, **kwargs): - """Generates C++ grpc classes from a .proto file. +def cc_grpc_library( + name, + srcs, + deps, + proto_only = False, + well_known_protos = True, + generate_mocks = False, + use_external = False, + grpc_only = False, + **kwargs): + """Generates C++ grpc classes for services defined in a proto file. - Assumes the generated classes will be used in cc_api_version = 2. + If grpc_only is True, this rule is compatible with proto_library and + cc_proto_library native rules such that it expects proto_library target + as srcs argument and generates only grpc library classes, expecting + protobuf messages classes library (cc_proto_library target) to be passed in + deps argument. By default grpc_only is False which makes this rule to behave + in a backwards-compatible mode (trying to generate both proto and grpc + classes). - Arguments: - name: name of rule. - srcs: a single proto_library, which wraps the .proto files with services. - deps: a list of C++ proto_library (or cc_proto_library) which provides - the compiled code of any message that the services depend on. - well_known_protos: Should this library additionally depend on well known - protos - use_external: When True the grpc deps are prefixed with //external. This - allows grpc to be used as a dependency in other bazel projects. - generate_mocks: When True, Google Mock code for client stub is generated. - **kwargs: rest of arguments, e.g., compatible_with and visibility. - """ - if len(srcs) > 1: - fail("Only one srcs value supported", "srcs") + Assumes the generated classes will be used in cc_api_version = 2. - proto_target = "_" + name + "_only" - codegen_target = "_" + name + "_codegen" - codegen_grpc_target = "_" + name + "_grpc_codegen" - proto_deps = ["_" + dep + "_only" for dep in deps if dep.find(':') == -1] - proto_deps += [dep.split(':')[0] + ':' + "_" + dep.split(':')[1] + "_only" for dep in deps if dep.find(':') != -1] + Args: + name (str): Name of rule. + srcs (list): A single .proto file which contains services definitions, + or if grpc_only parameter is True, a single proto_library which + contains services descriptors. + deps (list): A list of C++ proto_library (or cc_proto_library) which + provides the compiled code of any message that the services depend on. + proto_only (bool): If True, create only C++ proto classes library, + avoid creating C++ grpc classes library (expect it in deps). + well_known_protos (bool): Should this library additionally depend on + well known protos. + generate_mocks: when True, Google Mock code for client stub is generated. + use_external: Not used. + grpc_only: if True, generate only grpc library, expecting protobuf + messages library (cc_proto_library target) to be passed as deps. + **kwargs: rest of arguments, e.g., compatible_with and visibility + """ + if len(srcs) > 1: + fail("Only one srcs value supported", "srcs") + if grpc_only and proto_only: + fail("A mutualy exclusive configuraiton is specified: grpc_only = True and proto_only = True") - native.proto_library( - name = proto_target, - srcs = srcs, - deps = proto_deps, - **kwargs - ) + extra_deps = [] - generate_cc( - name = codegen_target, - srcs = [proto_target], - well_known_protos = well_known_protos, - **kwargs - ) + if not grpc_only: + proto_target = "_" + name + "_only" + cc_proto_target = name if proto_only else "_" + name + "_cc_proto" - if not proto_only: - plugin = "@com_github_grpc_grpc//:grpc_cpp_plugin" - generate_cc( - name = codegen_grpc_target, - srcs = [proto_target], - plugin = plugin, - well_known_protos = well_known_protos, - generate_mocks = generate_mocks, - **kwargs - ) - grpc_deps = ["@com_github_grpc_grpc//:grpc++_codegen_proto", - "//external:protobuf"] - native.cc_library( - name = name, - srcs = [":" + codegen_grpc_target, ":" + codegen_target], - hdrs = [":" + codegen_grpc_target, ":" + codegen_target], - deps = deps + grpc_deps, - **kwargs - ) - else: - native.cc_library( - name = name, - srcs = [":" + codegen_target], - hdrs = [":" + codegen_target], - deps = deps + ["//external:protobuf"], - **kwargs - ) + proto_deps = ["_" + dep + "_only" for dep in deps if dep.find(":") == -1] + proto_deps += [dep.split(":")[0] + ":" + "_" + dep.split(":")[1] + "_only" for dep in deps if dep.find(":") != -1] + + native.proto_library( + name = proto_target, + srcs = srcs, + deps = proto_deps, + **kwargs + ) + + native.cc_proto_library( + name = cc_proto_target, + deps = [":" + proto_target], + **kwargs + ) + extra_deps.append(":" + cc_proto_target) + else: + if not srcs: + fail("srcs cannot be empty", "srcs") + proto_target = srcs[0] + + if not proto_only: + codegen_grpc_target = "_" + name + "_grpc_codegen" + generate_cc( + name = codegen_grpc_target, + srcs = [proto_target], + plugin = "@com_github_grpc_grpc//:grpc_cpp_plugin", + well_known_protos = well_known_protos, + generate_mocks = generate_mocks, + **kwargs + ) + + native.cc_library( + name = name, + srcs = [":" + codegen_grpc_target], + hdrs = [":" + codegen_grpc_target], + deps = deps + + extra_deps + + ["@com_github_grpc_grpc//:grpc++_codegen_proto"], + **kwargs + ) diff --git a/examples/BUILD b/examples/BUILD index d2b39b87f4d..80f2762ff43 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -18,6 +18,7 @@ package(default_visibility = ["//visibility:public"]) load("@grpc_python_dependencies//:requirements.bzl", "requirement") load("//bazel:grpc_build_system.bzl", "grpc_proto_library") +load("//bazel:cc_grpc_library.bzl", "cc_grpc_library") load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") grpc_proto_library( @@ -30,11 +31,25 @@ grpc_proto_library( srcs = ["protos/hellostreamingworld.proto"], ) -grpc_proto_library( - name = "helloworld", +# The following three rules demonstrate the usage of the cc_grpc_library rule in +# in a mode compatible with the native proto_library and cc_proto_library rules. +proto_library( + name = "helloworld_proto", srcs = ["protos/helloworld.proto"], ) +cc_proto_library( + name = "helloworld_cc_proto", + deps = [":helloworld_proto"], +) + +cc_grpc_library( + name = "helloworld_cc_grpc", + srcs = [":helloworld_proto"], + grpc_only = True, + deps = [":helloworld_cc_proto"], +) + grpc_proto_library( name = "route_guide", srcs = ["protos/route_guide.proto"], @@ -49,7 +64,7 @@ py_proto_library( name = "py_helloworld", protos = ["protos/helloworld.proto"], with_grpc = True, - deps = [requirement('protobuf'),], + deps = [requirement("protobuf")], ) cc_binary( @@ -164,8 +179,10 @@ cc_binary( cc_binary( name = "keyvaluestore_client", - srcs = ["cpp/keyvaluestore/caching_interceptor.h", - "cpp/keyvaluestore/client.cc"], + srcs = [ + "cpp/keyvaluestore/caching_interceptor.h", + "cpp/keyvaluestore/client.cc", + ], defines = ["BAZEL_BUILD"], deps = [ ":keyvaluestore", From 1dab7cf91abe80b071227fde60ffefa8cc9a7644 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sat, 4 May 2019 19:04:39 +0200 Subject: [PATCH 2067/2143] job split followup: increase timeout for macos and windows C/C++ jobs --- tools/internal_ci/macos/grpc_basictests_c_cpp.cfg | 2 +- tools/internal_ci/windows/grpc_basictests_c.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/internal_ci/macos/grpc_basictests_c_cpp.cfg b/tools/internal_ci/macos/grpc_basictests_c_cpp.cfg index 9783dd64673..f16e3e8ee68 100644 --- a/tools/internal_ci/macos/grpc_basictests_c_cpp.cfg +++ b/tools/internal_ci/macos/grpc_basictests_c_cpp.cfg @@ -17,7 +17,7 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" -timeout_mins: 60 +timeout_mins: 120 action { define_artifacts { regex: "**/*sponge_log.*" diff --git a/tools/internal_ci/windows/grpc_basictests_c.cfg b/tools/internal_ci/windows/grpc_basictests_c.cfg index 150a28e3f89..223cf389d0e 100644 --- a/tools/internal_ci/windows/grpc_basictests_c.cfg +++ b/tools/internal_ci/windows/grpc_basictests_c.cfg @@ -16,7 +16,7 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" -timeout_mins: 60 +timeout_mins: 120 action { define_artifacts { regex: "**/*sponge_log.*" From 57c4877352b00fd4c86e557d7ab3f3d523240774 Mon Sep 17 00:00:00 2001 From: John Luo Date: Sat, 4 May 2019 22:29:08 -0700 Subject: [PATCH 2068/2143] Remove non-compatible workaround Will add this to Grpc.AspNetCore.Server instead --- .../build/_protobuf/Google.Protobuf.Tools.targets | 9 --------- 1 file changed, 9 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 b3fd02d4faa..b1030ba1f8b 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets @@ -39,15 +39,6 @@ - - - - - - - - - %" PRId64, static_cast(shard - g_shards), shard->queue_deadline_cap); } @@ -512,7 +512,7 @@ static bool refill_heap(timer_shard* shard, grpc_millis now) { next = timer->next; if (timer->deadline < shard->queue_deadline_cap) { - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, " .. add timer with deadline %" PRId64 " to heap", timer->deadline); } @@ -529,7 +529,7 @@ static bool refill_heap(timer_shard* shard, grpc_millis now) { static grpc_timer* pop_one(timer_shard* shard, grpc_millis now) { grpc_timer* timer; for (;;) { - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, " .. shard[%d]: heap_empty=%s", static_cast(shard - g_shards), grpc_timer_heap_is_empty(&shard->heap) ? "true" : "false"); @@ -539,13 +539,13 @@ static grpc_timer* pop_one(timer_shard* shard, grpc_millis now) { if (!refill_heap(shard, now)) return nullptr; } timer = grpc_timer_heap_top(&shard->heap); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, " .. check top timer deadline=%" PRId64 " now=%" PRId64, timer->deadline, now); } if (timer->deadline > now) return nullptr; - if (grpc_timer_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_trace)) { gpr_log(GPR_INFO, "TIMER %p: FIRE %" PRId64 "ms late via %s scheduler", timer, now - timer->deadline, timer->closure->scheduler->vtable->name); @@ -569,7 +569,7 @@ static size_t pop_timers(timer_shard* shard, grpc_millis now, } *new_min_deadline = compute_min_deadline(shard); gpr_mu_unlock(&shard->mu); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, " .. shard[%d] popped %" PRIdPTR, static_cast(shard - g_shards), n); } @@ -606,7 +606,7 @@ static grpc_timer_check_result run_some_expired_timers(grpc_millis now, gpr_mu_lock(&g_shared_mutables.mu); result = GRPC_TIMERS_CHECKED_AND_EMPTY; - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, " .. shard[%d]->min_deadline = %" PRId64, static_cast(g_shard_queue[0] - g_shards), g_shard_queue[0]->min_deadline); @@ -624,7 +624,7 @@ static grpc_timer_check_result run_some_expired_timers(grpc_millis now, result = GRPC_TIMERS_FIRED; } - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, " .. result --> %d" ", shard[%d]->min_deadline %" PRId64 " --> %" PRId64 @@ -691,7 +691,7 @@ static grpc_timer_check_result timer_check(grpc_millis* next) { if (next != nullptr) { *next = GPR_MIN(*next, min_timer); } - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "TIMER CHECK SKIP: now=%" PRId64 " min_timer=%" PRId64, now, min_timer); } @@ -704,7 +704,7 @@ static grpc_timer_check_result timer_check(grpc_millis* next) { : GRPC_ERROR_CREATE_FROM_STATIC_STRING("Shutting down timer system"); // tracing - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { char* next_str; if (next == nullptr) { next_str = gpr_strdup("NULL"); @@ -728,7 +728,7 @@ static grpc_timer_check_result timer_check(grpc_millis* next) { grpc_timer_check_result r = run_some_expired_timers(now, next, shutdown_error); // tracing - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { char* next_str; if (next == nullptr) { next_str = gpr_strdup("NULL"); diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index 4469db70dd0..bdf54909b4c 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -90,7 +90,7 @@ static void start_timer_thread_and_unlock(void) { ++g_waiter_count; ++g_thread_count; gpr_mu_unlock(&g_mu); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "Spawn timer thread"); } completed_thread* ct = @@ -126,7 +126,7 @@ static void run_some_timers() { // if there's no thread waiting with a timeout, kick an existing untimed // waiter so that the next deadline is not missed if (!g_has_timed_waiter) { - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "kick untimed waiter"); } gpr_cv_signal(&g_cv_wait); @@ -134,7 +134,7 @@ static void run_some_timers() { gpr_mu_unlock(&g_mu); } // without our lock, flush the exec_ctx - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "flush exec_ctx"); } grpc_core::ExecCtx::Get()->Flush(); @@ -189,7 +189,7 @@ static bool wait_until(grpc_millis next) { g_has_timed_waiter = true; g_timed_waiter_deadline = next; - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { grpc_millis wait_time = next - grpc_core::ExecCtx::Get()->Now(); gpr_log(GPR_INFO, "sleep for a %" PRId64 " milliseconds", wait_time); } @@ -198,7 +198,8 @@ static bool wait_until(grpc_millis next) { } } - if (grpc_timer_check_trace.enabled() && next == GRPC_MILLIS_INF_FUTURE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace) && + next == GRPC_MILLIS_INF_FUTURE) { gpr_log(GPR_INFO, "sleep until kicked"); } @@ -210,7 +211,7 @@ static bool wait_until(grpc_millis next) { gpr_cv_wait(&g_cv_wait, &g_mu, grpc_millis_to_timespec(next, GPR_CLOCK_MONOTONIC)); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "wait ended: was_timed:%d kicked:%d", my_timed_waiter_generation == g_timed_waiter_generation, g_kicked); @@ -255,7 +256,7 @@ static void timer_main_loop() { Consequently, we can just sleep forever here and be happy at some saved wakeup cycles. */ - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "timers not checked: expect another thread to"); } next = GRPC_MILLIS_INF_FUTURE; @@ -281,7 +282,7 @@ static void timer_thread_cleanup(completed_thread* ct) { ct->next = g_completed_threads; g_completed_threads = ct; gpr_mu_unlock(&g_mu); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "End timer thread"); } } @@ -327,18 +328,18 @@ void grpc_timer_manager_init(void) { static void stop_threads(void) { gpr_mu_lock(&g_mu); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "stop timer threads: threaded=%d", g_threaded); } if (g_threaded) { g_threaded = false; gpr_cv_broadcast(&g_cv_wait); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "num timer threads: %d", g_thread_count); } while (g_thread_count > 0) { gpr_cv_wait(&g_cv_shutdown, &g_mu, gpr_inf_future(GPR_CLOCK_MONOTONIC)); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "num timer threads: %d", g_thread_count); } gc_completed_threads(); diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.cc b/src/core/lib/security/credentials/jwt/jwt_credentials.cc index 70fe45e56dc..df1d05c83b3 100644 --- a/src/core/lib/security/credentials/jwt/jwt_credentials.cc +++ b/src/core/lib/security/credentials/jwt/jwt_credentials.cc @@ -160,7 +160,7 @@ static char* redact_private_key(const char* json_key) { grpc_call_credentials* grpc_service_account_jwt_access_credentials_create( const char* json_key, gpr_timespec token_lifetime, void* reserved) { - if (grpc_api_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace)) { char* clean_json = redact_private_key(json_key); gpr_log(GPR_INFO, "grpc_service_account_jwt_access_credentials_create(" diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc index b9af757d05e..b001868b3d3 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc @@ -459,7 +459,7 @@ grpc_call_credentials* grpc_google_refresh_token_credentials_create( const char* json_refresh_token, void* reserved) { grpc_auth_refresh_token token = grpc_auth_refresh_token_create_from_string(json_refresh_token); - if (grpc_api_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace)) { char* loggable_token = create_loggable_refresh_token(&token); gpr_log(GPR_INFO, "grpc_refresh_token_credentials_create(json_refresh_token=%s, " diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.cc b/src/core/lib/security/credentials/plugin/plugin_credentials.cc index 59fecbca992..333366d0f0a 100644 --- a/src/core/lib/security/credentials/plugin/plugin_credentials.cc +++ b/src/core/lib/security/credentials/plugin/plugin_credentials.cc @@ -119,7 +119,7 @@ static void plugin_md_request_metadata_ready(void* request, GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP); grpc_plugin_credentials::pending_request* r = static_cast(request); - if (grpc_plugin_credentials_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin returned " "asynchronously", @@ -132,7 +132,7 @@ static void plugin_md_request_metadata_ready(void* request, grpc_error* error = process_plugin_result(r, md, num_md, status, error_details); GRPC_CLOSURE_SCHED(r->on_request_metadata, error); - } else if (grpc_plugin_credentials_trace.enabled()) { + } else if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin was previously " "cancelled", @@ -162,7 +162,7 @@ bool grpc_plugin_credentials::get_request_metadata( pending_requests_ = request; gpr_mu_unlock(&mu_); // Invoke the plugin. The callback holds a ref to us. - if (grpc_plugin_credentials_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: invoking plugin", this, request); } @@ -174,7 +174,7 @@ bool grpc_plugin_credentials::get_request_metadata( if (!plugin_.get_metadata( plugin_.state, context, plugin_md_request_metadata_ready, request, creds_md, &num_creds_md, &status, &error_details)) { - if (grpc_plugin_credentials_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin will return " "asynchronously", @@ -189,7 +189,7 @@ bool grpc_plugin_credentials::get_request_metadata( // asynchronously by plugin_cancel_get_request_metadata(), so return // false. Otherwise, process the result. if (request->cancelled) { - if (grpc_plugin_credentials_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p was cancelled, error " "will be returned asynchronously", @@ -197,7 +197,7 @@ bool grpc_plugin_credentials::get_request_metadata( } retval = false; } else { - if (grpc_plugin_credentials_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin returned " "synchronously", @@ -223,7 +223,7 @@ void grpc_plugin_credentials::cancel_get_request_metadata( for (pending_request* pending_request = pending_requests_; pending_request != nullptr; pending_request = pending_request->next) { if (pending_request->md_array == md_array) { - if (grpc_plugin_credentials_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", this, pending_request); } diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc index 2a862492bd7..0aac7d8d780 100644 --- a/src/core/lib/security/transport/secure_endpoint.cc +++ b/src/core/lib/security/transport/secure_endpoint.cc @@ -113,7 +113,7 @@ static void destroy(secure_endpoint* ep) { grpc_core::Delete(ep); } secure_endpoint_ref((ep), (reason), __FILE__, __LINE__) static void secure_endpoint_unref(secure_endpoint* ep, const char* reason, const char* file, int line) { - if (grpc_trace_secure_endpoint.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_secure_endpoint)) { gpr_atm val = gpr_atm_no_barrier_load(&ep->ref.count); gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SECENDP unref %p : %s %" PRIdPTR " -> %" PRIdPTR, ep, reason, val, @@ -126,7 +126,7 @@ static void secure_endpoint_unref(secure_endpoint* ep, const char* reason, static void secure_endpoint_ref(secure_endpoint* ep, const char* reason, const char* file, int line) { - if (grpc_trace_secure_endpoint.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_secure_endpoint)) { gpr_atm val = gpr_atm_no_barrier_load(&ep->ref.count); gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SECENDP ref %p : %s %" PRIdPTR " -> %" PRIdPTR, ep, reason, val, @@ -155,7 +155,7 @@ static void flush_read_staging_buffer(secure_endpoint* ep, uint8_t** cur, } static void call_read_cb(secure_endpoint* ep, grpc_error* error) { - if (grpc_trace_secure_endpoint.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_secure_endpoint)) { size_t i; for (i = 0; i < ep->read_buffer->count; i++) { char* data = grpc_dump_slice(ep->read_buffer->slices[i], @@ -292,7 +292,7 @@ static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, grpc_slice_buffer_reset_and_unref_internal(&ep->output_buffer); - if (grpc_trace_secure_endpoint.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_secure_endpoint)) { for (i = 0; i < slices->count; i++) { char* data = grpc_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); diff --git a/src/core/lib/surface/api_trace.h b/src/core/lib/surface/api_trace.h index 72ed830554f..51d1f522230 100644 --- a/src/core/lib/surface/api_trace.h +++ b/src/core/lib/surface/api_trace.h @@ -45,7 +45,7 @@ extern grpc_core::TraceFlag grpc_api_trace; /* Due to the limitations of C89's preprocessor, the arity of the var-arg list 'nargs' must be specified. */ #define GRPC_API_TRACE(fmt, nargs, args) \ - if (grpc_api_trace.enabled()) { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace)) { \ gpr_log(GPR_INFO, fmt GRPC_API_TRACE_UNWRAP##nargs args); \ } diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index bd140021c96..d0cddfa5a12 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -723,7 +723,7 @@ static void cancel_with_status(grpc_call* c, grpc_status_code status, } static void set_final_status(grpc_call* call, grpc_error* error) { - if (grpc_call_error_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_error_trace)) { gpr_log(GPR_DEBUG, "set_final_status %s", call->is_client ? "CLI" : "SVR"); gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); } @@ -1280,7 +1280,7 @@ static void receiving_slice_ready(void* bctlp, grpc_error* error) { } if (error != GRPC_ERROR_NONE) { - if (grpc_trace_operation_failures.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures)) { GRPC_LOG_IF_ERROR("receiving_slice_ready", GRPC_ERROR_REF(error)); } call->receiving_stream.reset(); @@ -1404,7 +1404,7 @@ static void validate_filtered_metadata(batch_control* bctl) { GPR_ASSERT(call->encodings_accepted_by_peer != 0); if (!GPR_BITGET(call->encodings_accepted_by_peer, compression_algorithm)) { - if (grpc_compression_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_compression_trace)) { const char* algo_name = nullptr; grpc_compression_algorithm_name(compression_algorithm, &algo_name); gpr_log(GPR_ERROR, diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index d9cb97cb31b..11bde0787cb 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -102,7 +102,8 @@ void grpc_call_context_set(grpc_call* call, grpc_context_index elem, void* grpc_call_context_get(grpc_call* call, grpc_context_index elem); #define GRPC_CALL_LOG_BATCH(sev, call, ops, nops, tag) \ - if (grpc_api_trace.enabled()) grpc_call_log_batch(sev, call, ops, nops, tag) + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace)) \ + grpc_call_log_batch(sev, call, ops, nops, tag) uint8_t grpc_call_is_client(grpc_call* call); diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 3a32d292a7b..bb5921a6a55 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -411,12 +411,13 @@ static const cq_vtable g_cq_vtable[] = { grpc_core::TraceFlag grpc_cq_pluck_trace(false, "queue_pluck"); -#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \ - if (grpc_api_trace.enabled() && (grpc_cq_pluck_trace.enabled() || \ - (event)->type != GRPC_QUEUE_TIMEOUT)) { \ - char* _ev = grpc_event_string(event); \ - gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \ - gpr_free(_ev); \ +#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) && \ + (GRPC_TRACE_FLAG_ENABLED(grpc_cq_pluck_trace) || \ + (event)->type != GRPC_QUEUE_TIMEOUT)) { \ + char* _ev = grpc_event_string(event); \ + gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \ + gpr_free(_ev); \ } static void on_pollset_shutdown_done(void* cq, grpc_error* error); @@ -572,7 +573,7 @@ int grpc_get_cq_poll_num(grpc_completion_queue* cq) { #ifndef NDEBUG void grpc_cq_internal_ref(grpc_completion_queue* cq, const char* reason, const char* file, int line) { - if (grpc_trace_cq_refcount.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_cq_refcount)) { gpr_atm val = gpr_atm_no_barrier_load(&cq->owning_refs.count); gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", cq, val, val + 1, @@ -592,7 +593,7 @@ static void on_pollset_shutdown_done(void* arg, grpc_error* error) { #ifndef NDEBUG void grpc_cq_internal_unref(grpc_completion_queue* cq, const char* reason, const char* file, int line) { - if (grpc_trace_cq_refcount.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_cq_refcount)) { gpr_atm val = gpr_atm_no_barrier_load(&cq->owning_refs.count); gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", cq, val, val - 1, @@ -678,14 +679,16 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, void* done_arg, grpc_cq_completion* storage) { GPR_TIMER_SCOPE("cq_end_op_for_next", 0); - if (grpc_api_trace.enabled() || - (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || + (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && + error != GRPC_ERROR_NONE)) { const char* errmsg = grpc_error_string(error); GRPC_API_TRACE( "cq_end_op_for_next(cq=%p, tag=%p, error=%s, " "done=%p, done_arg=%p, storage=%p)", 6, (cq, tag, errmsg, done, done_arg, storage)); - if (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && + error != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg); } } @@ -759,14 +762,16 @@ static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); int is_success = (error == GRPC_ERROR_NONE); - if (grpc_api_trace.enabled() || - (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || + (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && + error != GRPC_ERROR_NONE)) { const char* errmsg = grpc_error_string(error); GRPC_API_TRACE( "cq_end_op_for_pluck(cq=%p, tag=%p, error=%s, " "done=%p, done_arg=%p, storage=%p)", 6, (cq, tag, errmsg, done, done_arg, storage)); - if (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && + error != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg); } } @@ -824,14 +829,16 @@ static void cq_end_op_for_callback( cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); bool is_success = (error == GRPC_ERROR_NONE); - if (grpc_api_trace.enabled() || - (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || + (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && + error != GRPC_ERROR_NONE)) { const char* errmsg = grpc_error_string(error); GRPC_API_TRACE( "cq_end_op_for_callback(cq=%p, tag=%p, error=%s, " "done=%p, done_arg=%p, storage=%p)", 6, (cq, tag, errmsg, done, done_arg, storage)); - if (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && + error != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg); } } @@ -906,7 +913,7 @@ class ExecCtxNext : public grpc_core::ExecCtx { #ifndef NDEBUG static void dump_pending_tags(grpc_completion_queue* cq) { - if (!grpc_trace_pending_tags.enabled()) return; + if (!GRPC_TRACE_FLAG_ENABLED(grpc_trace_pending_tags)) return; gpr_strvec v; gpr_strvec_init(&v); @@ -1176,7 +1183,7 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, grpc_pollset_worker* worker = nullptr; cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); - if (grpc_cq_pluck_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_cq_pluck_trace)) { GRPC_API_TRACE( "grpc_completion_queue_pluck(" "cq=%p, tag=%p, " diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 443d199898d..2377c4d8f23 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -464,7 +464,8 @@ static void destroy_channel(channel_data* chand, grpc_error* error) { GRPC_CLOSURE_INIT(&chand->finish_destroy_channel_closure, finish_destroy_channel, chand, grpc_schedule_on_exec_ctx); - if (grpc_server_channel_trace.enabled() && error != GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_server_channel_trace) && + error != GRPC_ERROR_NONE) { const char* msg = grpc_error_string(error); gpr_log(GPR_INFO, "Disconnected client: %s", msg); } diff --git a/src/core/lib/transport/bdp_estimator.cc b/src/core/lib/transport/bdp_estimator.cc index 8e71f869894..8835e32bcff 100644 --- a/src/core/lib/transport/bdp_estimator.cc +++ b/src/core/lib/transport/bdp_estimator.cc @@ -46,7 +46,7 @@ grpc_millis BdpEstimator::CompletePing() { 1e-9 * static_cast(dt_ts.tv_nsec); double bw = dt > 0 ? (static_cast(accumulator_) / dt) : 0; int start_inter_ping_delay = inter_ping_delay_; - if (grpc_bdp_estimator_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { gpr_log(GPR_INFO, "bdp[%s]:complete acc=%" PRId64 " est=%" PRId64 " dt=%lf bw=%lfMbs bw_est=%lfMbs", @@ -57,7 +57,7 @@ grpc_millis BdpEstimator::CompletePing() { if (accumulator_ > 2 * estimate_ / 3 && bw > bw_est_) { estimate_ = GPR_MAX(accumulator_, estimate_ * 2); bw_est_ = bw; - if (grpc_bdp_estimator_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { gpr_log(GPR_INFO, "bdp[%s]: estimate increased to %" PRId64, name_, estimate_); } @@ -74,7 +74,7 @@ grpc_millis BdpEstimator::CompletePing() { } if (start_inter_ping_delay != inter_ping_delay_) { stable_estimate_count_ = 0; - if (grpc_bdp_estimator_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { gpr_log(GPR_INFO, "bdp[%s]:update_inter_time to %dms", name_, inter_ping_delay_); } diff --git a/src/core/lib/transport/bdp_estimator.h b/src/core/lib/transport/bdp_estimator.h index ab13ae4be4c..6dc4d6bb05e 100644 --- a/src/core/lib/transport/bdp_estimator.h +++ b/src/core/lib/transport/bdp_estimator.h @@ -49,7 +49,7 @@ class BdpEstimator { // grpc_bdp_estimator_add_incoming_bytes once a ping has been scheduled by a // transport (but not necessarily started) void SchedulePing() { - if (grpc_bdp_estimator_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { gpr_log(GPR_INFO, "bdp[%s]:sched acc=%" PRId64 " est=%" PRId64, name_, accumulator_, estimate_); } @@ -62,7 +62,7 @@ class BdpEstimator { // once // the ping is on the wire void StartPing() { - if (grpc_bdp_estimator_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { gpr_log(GPR_INFO, "bdp[%s]:start acc=%" PRId64 " est=%" PRId64, name_, accumulator_, estimate_); } diff --git a/src/core/lib/transport/connectivity_state.cc b/src/core/lib/transport/connectivity_state.cc index 5b73085c7f3..bf35fd09def 100644 --- a/src/core/lib/transport/connectivity_state.cc +++ b/src/core/lib/transport/connectivity_state.cc @@ -75,7 +75,7 @@ grpc_connectivity_state grpc_connectivity_state_check( grpc_connectivity_state_tracker* tracker) { grpc_connectivity_state cur = static_cast( gpr_atm_no_barrier_load(&tracker->current_state_atm)); - if (grpc_connectivity_state_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) { gpr_log(GPR_INFO, "CONWATCH: %p %s: get %s", tracker, tracker->name, grpc_connectivity_state_name(cur)); } @@ -92,7 +92,7 @@ bool grpc_connectivity_state_notify_on_state_change( grpc_closure* notify) { grpc_connectivity_state cur = static_cast( gpr_atm_no_barrier_load(&tracker->current_state_atm)); - if (grpc_connectivity_state_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) { if (current == nullptr) { gpr_log(GPR_INFO, "CONWATCH: %p %s: unsubscribe notify=%p", tracker, tracker->name, notify); @@ -143,7 +143,7 @@ void grpc_connectivity_state_set(grpc_connectivity_state_tracker* tracker, grpc_connectivity_state cur = static_cast( gpr_atm_no_barrier_load(&tracker->current_state_atm)); grpc_connectivity_state_watcher* w; - if (grpc_connectivity_state_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) { gpr_log(GPR_INFO, "SET: %p %s: %s --> %s [%s]", tracker, tracker->name, grpc_connectivity_state_name(cur), grpc_connectivity_state_name(state), reason); @@ -156,7 +156,7 @@ void grpc_connectivity_state_set(grpc_connectivity_state_tracker* tracker, while ((w = tracker->watchers) != nullptr) { *w->current = state; tracker->watchers = w->next; - if (grpc_connectivity_state_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) { gpr_log(GPR_INFO, "NOTIFY: %p %s: %p", tracker, tracker->name, w->notify); } GRPC_CLOSURE_SCHED(w->notify, GRPC_ERROR_NONE); diff --git a/src/core/tsi/fake_transport_security.cc b/src/core/tsi/fake_transport_security.cc index 4d4c4950451..fde88dd819b 100644 --- a/src/core/tsi/fake_transport_security.cc +++ b/src/core/tsi/fake_transport_security.cc @@ -585,7 +585,7 @@ static tsi_result fake_handshaker_get_bytes_to_send_to_peer( if (next_message_to_send > TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { next_message_to_send = TSI_FAKE_HANDSHAKE_MESSAGE_MAX; } - if (tsi_tracing_enabled.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(tsi_tracing_enabled)) { gpr_log(GPR_INFO, "%s prepared %s.", impl->is_client ? "Client" : "Server", tsi_fake_handshake_message_to_string(impl->next_message_to_send)); @@ -597,7 +597,7 @@ static tsi_result fake_handshaker_get_bytes_to_send_to_peer( if (!impl->is_client && impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { /* We're done. */ - if (tsi_tracing_enabled.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(tsi_tracing_enabled)) { gpr_log(GPR_INFO, "Server is done."); } impl->result = TSI_OK; @@ -636,7 +636,7 @@ static tsi_result fake_handshaker_process_bytes_from_peer( tsi_fake_handshake_message_to_string(received_msg), tsi_fake_handshake_message_to_string(expected_msg)); } - if (tsi_tracing_enabled.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(tsi_tracing_enabled)) { gpr_log(GPR_INFO, "%s received %s.", impl->is_client ? "Client" : "Server", tsi_fake_handshake_message_to_string(received_msg)); } @@ -644,7 +644,7 @@ static tsi_result fake_handshaker_process_bytes_from_peer( impl->needs_incoming_message = 0; if (impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { /* We're done. */ - if (tsi_tracing_enabled.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(tsi_tracing_enabled)) { gpr_log(GPR_INFO, "%s is done.", impl->is_client ? "Client" : "Server"); } impl->result = TSI_OK; diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index cbdb4227b31..25ae2cee285 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -213,7 +213,7 @@ static const char* ssl_error_string(int error) { /* TODO(jboeuf): Remove when we are past the debugging phase with this code. */ static void ssl_log_where_info(const SSL* ssl, int where, int flag, const char* msg) { - if ((where & flag) && tsi_tracing_enabled.enabled()) { + if ((where & flag) && GRPC_TRACE_FLAG_ENABLED(tsi_tracing_enabled)) { gpr_log(GPR_INFO, "%20.20s - %30.30s - %5.10s", msg, SSL_state_string_long(ssl), SSL_state_string(ssl)); } From 2ade64a685094546943daafdec22028f4117ab17 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 7 May 2019 15:53:22 -0400 Subject: [PATCH 2103/2143] Use grpc_core::RefCount for grpc_call and mark Unref path unlikely. Unfortunately, we cannot use RefCount for `batch`, unless we support reset API. So, for now, let's mark its unref path as unlikely. --- src/core/lib/surface/call.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index bd140021c96..a826a619542 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -39,6 +39,7 @@ #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/arena.h" #include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" @@ -130,7 +131,6 @@ struct grpc_call { channel(args.channel), is_client(args.server_transport_data == nullptr), stream_op_payload(context) { - gpr_ref_init(&ext_ref, 1); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { metadata_batch[i][j].deadline = GRPC_MILLIS_INF_FUTURE; @@ -142,7 +142,7 @@ struct grpc_call { gpr_free(static_cast(const_cast(final_info.error_string))); } - gpr_refcount ext_ref; + grpc_core::RefCount ext_ref; grpc_core::Arena* arena; grpc_core::CallCombiner call_combiner; grpc_completion_queue* cq; @@ -553,10 +553,10 @@ static void destroy_call(void* call, grpc_error* error) { grpc_schedule_on_exec_ctx)); } -void grpc_call_ref(grpc_call* c) { gpr_ref(&c->ext_ref); } +void grpc_call_ref(grpc_call* c) { c->ext_ref.Ref(); } void grpc_call_unref(grpc_call* c) { - if (!gpr_unref(&c->ext_ref)) return; + if (GPR_LIKELY(!c->ext_ref.Unref())) return; GPR_TIMER_SCOPE("grpc_call_unref", 0); @@ -1225,7 +1225,7 @@ static void post_batch_completion(batch_control* bctl) { } static void finish_batch_step(batch_control* bctl) { - if (gpr_unref(&bctl->steps_to_complete)) { + if (GPR_UNLIKELY(gpr_unref(&bctl->steps_to_complete))) { post_batch_completion(bctl); } } From 6cba63eb4794bc0a603ad0bd4fbe1a1180fe3541 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 8 May 2019 03:36:37 -0700 Subject: [PATCH 2104/2143] reviewer comments and tests --- .../filters/client_channel/client_channel.cc | 26 +++--- .../client_channel/resolving_lb_policy.cc | 27 +++--- test/core/util/test_lb_policies.cc | 1 + test/cpp/end2end/BUILD | 1 - .../end2end/service_config_end2end_test.cc | 1 - test/cpp/naming/gen_build_yaml.py | 1 + test/cpp/naming/resolver_component_test.cc | 15 +++- .../naming/resolver_component_tests_runner.py | 82 +++++++++++++++++++ .../naming/resolver_test_record_groups.yaml | 78 ++++++++++++++++++ 9 files changed, 206 insertions(+), 26 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 93070bdc64e..5d5436b8f67 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1242,20 +1242,20 @@ bool ChannelData::ProcessResolverResultLocked( bool service_config_changed = service_config != chand->saved_service_config_; if (service_config_changed) { chand->saved_service_config_ = std::move(service_config); - Optional - retry_throttle_data; - if (parsed_object != nullptr) { - chand->health_check_service_name_.reset( - gpr_strdup(parsed_object->health_check_service_name())); - retry_throttle_data = parsed_object->retry_throttling(); - } else { - chand->health_check_service_name_.reset(); - } - // Create service config setter to update channel state in the data - // plane combiner. Destroys itself when done. - New(chand, retry_throttle_data, - chand->saved_service_config_); } + Optional + retry_throttle_data; + if (parsed_object != nullptr) { + chand->health_check_service_name_.reset( + gpr_strdup(parsed_object->health_check_service_name())); + retry_throttle_data = parsed_object->retry_throttling(); + } else { + chand->health_check_service_name_.reset(); + } + // Create service config setter to update channel state in the data + // plane combiner. Destroys itself when done. + New(chand, retry_throttle_data, + chand->saved_service_config_); UniquePtr processed_lb_policy_name; chand->ProcessLbPolicy(result, parsed_object, &processed_lb_policy_name, lb_policy_config); 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 698433c3854..4824f4e22c3 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -532,31 +532,33 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( const char* lb_policy_name = nullptr; RefCountedPtr lb_policy_config; bool service_config_changed = false; + char* service_config_error_string = nullptr; if (process_resolver_result_ != nullptr) { grpc_error* service_config_error = GRPC_ERROR_NONE; service_config_changed = process_resolver_result_( process_resolver_result_user_data_, result, &lb_policy_name, &lb_policy_config, &service_config_error); if (service_config_error != GRPC_ERROR_NONE) { - if (channelz_node() != nullptr) { - trace_strings.push_back( - gpr_strdup(grpc_error_string(service_config_error))); - } + service_config_error_string = + gpr_strdup(grpc_error_string(service_config_error)); if (lb_policy_name == nullptr) { // Use an empty lb_policy_name as an indicator that we received an // invalid service config and we don't have a fallback service config. - return OnResolverError(service_config_error); + OnResolverError(service_config_error); + } else { + GRPC_ERROR_UNREF(service_config_error); } - GRPC_ERROR_UNREF(service_config_error); } } else { lb_policy_name = child_policy_name_.get(); lb_policy_config = child_lb_config_; } - GPR_ASSERT(lb_policy_name != nullptr); - // Create or update LB policy, as needed. - CreateOrUpdateLbPolicyLocked(lb_policy_name, lb_policy_config, - std::move(result), &trace_strings); + if (lb_policy_name != nullptr) { + gpr_log(GPR_ERROR, "%s", lb_policy_name); + // Create or update LB policy, as needed. + CreateOrUpdateLbPolicyLocked(lb_policy_name, lb_policy_config, + std::move(result), &trace_strings); + } // Add channel trace event. if (channelz_node() != nullptr) { if (service_config_changed) { @@ -564,10 +566,15 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( // config in the trace, at the risk of bloating the trace logs. trace_strings.push_back(gpr_strdup("Service config changed")); } + if (service_config_error_string != nullptr) { + trace_strings.push_back(service_config_error_string); + service_config_error_string = nullptr; + } MaybeAddTraceMessagesForAddressChangesLocked(resolution_contains_addresses, &trace_strings); ConcatenateAndAddChannelTraceLocked(&trace_strings); } + gpr_free(service_config_error_string); } } // namespace grpc_core diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index b871f04bc9e..8f5458e782a 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -209,6 +209,7 @@ class InterceptTrailingFactory : public LoadBalancingPolicyFactory { OrphanablePtr CreateLoadBalancingPolicy( LoadBalancingPolicy::Args args) const override { + gpr_log(GPR_ERROR, "creating"); return OrphanablePtr( New(std::move(args), cb_, user_data_)); diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index d211a9e8441..519a33fd8a4 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -439,7 +439,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", "//test/core/util:grpc_test_util", - "//test/core/util:test_lb_policies", "//test/cpp/util:test_util", ], ) diff --git a/test/cpp/end2end/service_config_end2end_test.cc b/test/cpp/end2end/service_config_end2end_test.cc index b695a9f8c97..9b259bd6342 100644 --- a/test/cpp/end2end/service_config_end2end_test.cc +++ b/test/cpp/end2end/service_config_end2end_test.cc @@ -54,7 +54,6 @@ #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.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 diff --git a/test/cpp/naming/gen_build_yaml.py b/test/cpp/naming/gen_build_yaml.py index 9bf5ae9b2f8..ef757aeeb52 100755 --- a/test/cpp/naming/gen_build_yaml.py +++ b/test/cpp/naming/gen_build_yaml.py @@ -47,6 +47,7 @@ def _resolver_test_cases(resolver_component_data): _build_expected_addrs_cmd_arg(test_case['expected_addrs'])), ('expected_chosen_service_config', (test_case['expected_chosen_service_config'] or '')), + ('expected_service_config_error', (test_case['expected_service_config_error'] 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']), diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 4d1beb7ec37..7903f2a932f 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -89,6 +89,8 @@ DEFINE_string(expected_addrs, "", DEFINE_string(expected_chosen_service_config, "", "Expected service config json string that gets chosen (no " "whitespace). Empty for none."); +DEFINE_string(expected_service_config_error, "", + "Expected service config error. Empty for none."); DEFINE_string( local_dns_server_address, "", "Optional. This address is placed as the uri authority if present."); @@ -179,6 +181,7 @@ struct ArgsStruct { grpc_channel_args* channel_args; vector expected_addrs; std::string expected_service_config_string; + std::string expected_service_config_error; std::string expected_lb_policy; }; @@ -241,6 +244,7 @@ void PollPollsetUntilRequestDone(ArgsStruct* args) { } void CheckServiceConfigResultLocked(const char* service_config_json, + grpc_error* service_config_error, ArgsStruct* args) { if (args->expected_service_config_string != "") { GPR_ASSERT(service_config_json != nullptr); @@ -248,6 +252,13 @@ void CheckServiceConfigResultLocked(const char* service_config_json, } else { GPR_ASSERT(service_config_json == nullptr); } + if (args->expected_service_config_error == "") { + EXPECT_EQ(service_config_error, GRPC_ERROR_NONE); + } else { + EXPECT_THAT(grpc_error_string(service_config_error), + testing::HasSubstr(args->expected_service_config_error)); + } + GRPC_ERROR_UNREF(service_config_error); } void CheckLBPolicyResultLocked(const grpc_channel_args* channel_args, @@ -462,7 +473,8 @@ class CheckingResultHandler : public ResultHandler { result.service_config == nullptr ? nullptr : result.service_config->service_config_json(); - CheckServiceConfigResultLocked(service_config_json, args); + CheckServiceConfigResultLocked( + service_config_json, GRPC_ERROR_REF(result.service_config_error), args); if (args->expected_service_config_string == "") { CheckLBPolicyResultLocked(result.args, args); } @@ -477,6 +489,7 @@ void RunResolvesRelevantRecordsTest( ArgsInit(&args); args.expected_addrs = ParseExpectedAddrs(FLAGS_expected_addrs); args.expected_service_config_string = FLAGS_expected_chosen_service_config; + args.expected_service_config_error = FLAGS_expected_service_config_error; args.expected_lb_policy = FLAGS_expected_lb_policy; // maybe build the address with an authority char* whole_uri = nullptr; diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index 2d875ce00ae..356574b6086 100755 --- a/test/cpp/naming/resolver_component_tests_runner.py +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -124,6 +124,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'no-srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '5.5.5.5:443,False', '--expected_chosen_service_config', '', + '--expected_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -138,6 +139,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:1234,True', '--expected_chosen_service_config', '', + '--expected_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -152,6 +154,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.', '--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_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -166,6 +169,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '[2607:f8b0:400a:801::1001]:1234,True', '--expected_chosen_service_config', '', + '--expected_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -180,6 +184,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.', '--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_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -194,6 +199,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:1234,True', '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true}]}', + '--expected_service_config_error', '', '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -208,6 +214,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:443,False', '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService"}],"waitForReady":true}]}', + '--expected_service_config_error', '', '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -222,6 +229,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:443,False', '--expected_chosen_service_config', '', + '--expected_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -236,6 +244,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:443,False', '--expected_chosen_service_config', '', + '--expected_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -250,6 +259,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:443,False', '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService"}],"waitForReady":true}]}', + '--expected_service_config_error', '', '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -264,6 +274,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:443,False', '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService"}],"waitForReady":true}]}', + '--expected_service_config_error', '', '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -278,6 +289,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:1234,True;1.2.3.4:443,False', '--expected_chosen_service_config', '', + '--expected_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -292,6 +304,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1002]:443,False', '--expected_chosen_service_config', '', + '--expected_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -306,6 +319,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.', '--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_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', @@ -320,6 +334,7 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'False', '--enable_txt_queries', 'True', @@ -334,6 +349,7 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'False', '--enable_txt_queries', 'True', @@ -348,6 +364,7 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'srv-ipv6-single-target-srv-disabled.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '[2600::1001]:443,False', '--expected_chosen_service_config', '', + '--expected_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'False', '--enable_txt_queries', 'True', @@ -362,6 +379,7 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'False', '--enable_txt_queries', 'True', @@ -376,6 +394,7 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'False', '--enable_txt_queries', 'True', @@ -390,6 +409,7 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'False', @@ -404,6 +424,7 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'False', @@ -418,6 +439,7 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'False', @@ -426,6 +448,66 @@ current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: num_test_failures += 1 +test_runner_log('Run test with target: %s' % 'ipv4-svc_cfg_bad_json.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-svc_cfg_bad_json.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', 'could not parse', + '--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: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'ipv4-svc_cfg_bad_client_language.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-svc_cfg_bad_client_language.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', 'field:clientLanguage error:should be of type array', + '--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: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'ipv4-svc_cfg_bad_percentage.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-svc_cfg_bad_percentage.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', 'field:percentage error:should be of type number', + '--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: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'ipv4-svc_cfg_bad_wait_for_ready.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-svc_cfg_bad_wait_for_ready.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', 'field:waitForReady error:Type should be true/false', + '--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: + num_test_failures += 1 + test_runner_log('now kill DNS server') dns_server_subprocess.kill() dns_server_subprocess.wait() diff --git a/test/cpp/naming/resolver_test_record_groups.yaml b/test/cpp/naming/resolver_test_record_groups.yaml index bfb8b4ede2d..23d09ea896a 100644 --- a/test/cpp/naming/resolver_test_record_groups.yaml +++ b/test/cpp/naming/resolver_test_record_groups.yaml @@ -4,6 +4,7 @@ resolver_component_tests: - expected_addrs: - {address: '5.5.5.5:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true @@ -14,6 +15,7 @@ resolver_component_tests: - expected_addrs: - {address: '1.2.3.4:1234', is_balancer: true} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true @@ -28,6 +30,7 @@ resolver_component_tests: - {address: '1.2.3.6:1234', is_balancer: true} - {address: '1.2.3.7:1234', is_balancer: true} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true @@ -42,6 +45,7 @@ resolver_component_tests: - expected_addrs: - {address: '[2607:f8b0:400a:801::1001]:1234', is_balancer: true} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true @@ -56,6 +60,7 @@ resolver_component_tests: - {address: '[2607:f8b0:400a:801::1003]:1234', is_balancer: true} - {address: '[2607:f8b0:400a:801::1004]:1234', is_balancer: true} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true @@ -70,6 +75,7 @@ resolver_component_tests: - expected_addrs: - {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_service_config_error: null expected_lb_policy: round_robin enable_srv_queries: true enable_txt_queries: true @@ -85,6 +91,7 @@ resolver_component_tests: - expected_addrs: - {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_service_config_error: null expected_lb_policy: round_robin enable_srv_queries: true enable_txt_queries: true @@ -98,6 +105,7 @@ resolver_component_tests: - expected_addrs: - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true @@ -111,6 +119,7 @@ resolver_component_tests: - expected_addrs: - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true @@ -124,6 +133,7 @@ resolver_component_tests: - expected_addrs: - {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_service_config_error: null expected_lb_policy: round_robin enable_srv_queries: true enable_txt_queries: true @@ -137,6 +147,7 @@ resolver_component_tests: - expected_addrs: - {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_service_config_error: null expected_lb_policy: round_robin enable_srv_queries: true enable_txt_queries: true @@ -151,6 +162,7 @@ resolver_component_tests: - {address: '1.2.3.4:1234', is_balancer: true} - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true @@ -166,6 +178,7 @@ resolver_component_tests: - {address: '[2607:f8b0:400a:801::1002]:1234', is_balancer: true} - {address: '[2607:f8b0:400a:801::1002]:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true @@ -180,6 +193,7 @@ resolver_component_tests: - expected_addrs: - {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_service_config_error: null expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true @@ -194,6 +208,7 @@ resolver_component_tests: - expected_addrs: - {address: '2.3.4.5:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: false enable_txt_queries: true @@ -210,6 +225,7 @@ resolver_component_tests: - {address: '9.2.3.6:443', is_balancer: false} - {address: '9.2.3.7:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: false enable_txt_queries: true @@ -228,6 +244,7 @@ resolver_component_tests: - expected_addrs: - {address: '[2600::1001]:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: false enable_txt_queries: true @@ -244,6 +261,7 @@ resolver_component_tests: - {address: '[2600::1003]:443', is_balancer: false} - {address: '[2600::1004]:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: false enable_txt_queries: true @@ -262,6 +280,7 @@ resolver_component_tests: - 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_service_config_error: null expected_lb_policy: round_robin enable_srv_queries: false enable_txt_queries: true @@ -279,6 +298,7 @@ resolver_component_tests: - expected_addrs: - {address: '1.2.3.4:1234', is_balancer: true} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true enable_txt_queries: false @@ -294,6 +314,7 @@ resolver_component_tests: - expected_addrs: - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true enable_txt_queries: false @@ -307,6 +328,7 @@ resolver_component_tests: - expected_addrs: - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true enable_txt_queries: false @@ -317,3 +339,59 @@ resolver_component_tests: _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} +- expected_addrs: + - {address: '1.2.3.4:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: 'could not parse' + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + record_to_resolve: ipv4-svc_cfg_bad_json + records: + ipv4-svc_cfg_bad_json: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-svc_cfg_bad_json: + - {TTL: '2100', data: 'grpc_config=[{]', + type: TXT} +- expected_addrs: + - {address: '1.2.3.4:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: 'field:clientLanguage error:should be of type array' + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + record_to_resolve: ipv4-svc_cfg_bad_client_language + records: + ipv4-svc_cfg_bad_client_language: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-svc_cfg_bad_client_language: + - {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} +- expected_addrs: + - {address: '1.2.3.4:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: 'field:percentage error:should be of type number' + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + record_to_resolve: ipv4-svc_cfg_bad_percentage + records: + ipv4-svc_cfg_bad_percentage: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-svc_cfg_bad_percentage: + - {TTL: '2100', data: 'grpc_config=[{"percentage":"0","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} +- expected_addrs: + - {address: '1.2.3.4:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: 'field:waitForReady error:Type should be true/false' + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + record_to_resolve: ipv4-svc_cfg_bad_wait_for_ready + records: + ipv4-svc_cfg_bad_wait_for_ready: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-svc_cfg_bad_wait_for_ready: + - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"methodConfig":[{"name":[{"method":"Foo","service":"CppService"}],"waitForReady":"true"}]}}]', + type: TXT} From 02bd17ff15c74849537a19b872167cb1dd536ebb Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 8 May 2019 03:46:48 -0700 Subject: [PATCH 2105/2143] cleanup --- CMakeLists.txt | 7 ------- Makefile | 4 ---- build.yaml | 1 - test/core/util/test_lb_policies.cc | 1 - tools/run_tests/generated/sources_and_headers.json | 6 +----- 5 files changed, 1 insertion(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 42ea919f4a6..263d9a2b9f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15941,18 +15941,11 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(service_config_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/service_config_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(service_config_end2end_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/Makefile b/Makefile index b605550a38a..650d3ad66f3 100644 --- a/Makefile +++ b/Makefile @@ -18901,7 +18901,6 @@ $(OBJDIR)/$(CONFIG)/test/cpp/server/server_request_call_test.o: $(GENDIR)/src/pr SERVICE_CONFIG_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/service_config_end2end_test.cc \ SERVICE_CONFIG_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVICE_CONFIG_END2END_TEST_SRC)))) @@ -18933,8 +18932,6 @@ 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/service_config_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_service_config_end2end_test: $(SERVICE_CONFIG_END2END_TEST_OBJS:.o=.dep) @@ -18944,7 +18941,6 @@ ifneq ($(NO_DEPS),true) -include $(SERVICE_CONFIG_END2END_TEST_OBJS:.o=.dep) endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/service_config_end2end_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc SERVICE_CONFIG_TEST_SRC = \ diff --git a/build.yaml b/build.yaml index 46b016c6be4..08b2cbd7ee6 100644 --- a/build.yaml +++ b/build.yaml @@ -5525,7 +5525,6 @@ targets: build: test language: c++ src: - - src/proto/grpc/lb/v1/load_balancer.proto - test/cpp/end2end/service_config_end2end_test.cc deps: - grpc++_test_util diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 8f5458e782a..b871f04bc9e 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -209,7 +209,6 @@ class InterceptTrailingFactory : public LoadBalancingPolicyFactory { OrphanablePtr CreateLoadBalancingPolicy( LoadBalancingPolicy::Args args) const override { - gpr_log(GPR_ERROR, "creating"); return OrphanablePtr( New(std::move(args), cb_, user_data_)); diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index e535a335a7b..4ece3f64a1d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -4803,11 +4803,7 @@ "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" - ], + "headers": [], "is_filegroup": false, "language": "c++", "name": "service_config_end2end_test", From 3bcae1e3682e45ad528587f47f4c46e5f5d11fbb Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 8 May 2019 12:22:06 -0400 Subject: [PATCH 2106/2143] Apply do {...} while(0) to the remaining macros. --- .../resolver/dns/c_ares/grpc_ares_wrapper.h | 10 ++++++---- .../ext/transport/chttp2/transport/internal.h | 10 ++++++---- src/core/lib/iomgr/executor.cc | 20 +++++++++++-------- src/core/lib/surface/call.h | 7 +++++-- src/core/lib/surface/completion_queue.cc | 18 +++++++++-------- 5 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h index 881dfcdcee6..a707c1ae7c4 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -32,10 +32,12 @@ extern grpc_core::TraceFlag grpc_trace_cares_address_sorting; extern grpc_core::TraceFlag grpc_trace_cares_resolver; -#define GRPC_CARES_TRACE_LOG(format, ...) \ - if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_cares_resolver)) { \ - gpr_log(GPR_DEBUG, "(c-ares resolver) " format, __VA_ARGS__); \ - } +#define GRPC_CARES_TRACE_LOG(format, ...) \ + do { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_cares_resolver)) { \ + gpr_log(GPR_DEBUG, "(c-ares resolver) " format, __VA_ARGS__); \ + } \ + } while (0) typedef struct grpc_ares_request grpc_ares_request; diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index b3a2545a189..11936dc8cce 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -771,10 +771,12 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, // extern grpc_core::TraceFlag grpc_http_trace; // extern grpc_core::TraceFlag grpc_flowctl_trace; -#define GRPC_CHTTP2_IF_TRACING(stmt) \ - if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { \ - (stmt); \ - } +#define GRPC_CHTTP2_IF_TRACING(stmt) \ + do { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { \ + (stmt); \ + } \ + } while (0) void grpc_chttp2_fake_status(grpc_chttp2_transport* t, grpc_chttp2_stream* stream, grpc_error* error); diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc index 9b967a4fe7a..8adc0902bd1 100644 --- a/src/core/lib/iomgr/executor.cc +++ b/src/core/lib/iomgr/executor.cc @@ -36,15 +36,19 @@ #define MAX_DEPTH 2 -#define EXECUTOR_TRACE(format, ...) \ - if (GRPC_TRACE_FLAG_ENABLED(executor_trace)) { \ - gpr_log(GPR_INFO, "EXECUTOR " format, __VA_ARGS__); \ - } +#define EXECUTOR_TRACE(format, ...) \ + do { \ + if (GRPC_TRACE_FLAG_ENABLED(executor_trace)) { \ + gpr_log(GPR_INFO, "EXECUTOR " format, __VA_ARGS__); \ + } \ + } while (0) -#define EXECUTOR_TRACE0(str) \ - if (GRPC_TRACE_FLAG_ENABLED(executor_trace)) { \ - gpr_log(GPR_INFO, "EXECUTOR " str); \ - } +#define EXECUTOR_TRACE0(str) \ + do { \ + if (GRPC_TRACE_FLAG_ENABLED(executor_trace)) { \ + gpr_log(GPR_INFO, "EXECUTOR " str); \ + } \ + } while (0) namespace grpc_core { namespace { diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index 11bde0787cb..15392fea6dc 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -102,8 +102,11 @@ void grpc_call_context_set(grpc_call* call, grpc_context_index elem, void* grpc_call_context_get(grpc_call* call, grpc_context_index elem); #define GRPC_CALL_LOG_BATCH(sev, call, ops, nops, tag) \ - if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace)) \ - grpc_call_log_batch(sev, call, ops, nops, tag) + do { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace)) { \ + grpc_call_log_batch(sev, call, ops, nops, tag); \ + } \ + } while (0) uint8_t grpc_call_is_client(grpc_call* call); diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index bb5921a6a55..e796071eedc 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -411,14 +411,16 @@ static const cq_vtable g_cq_vtable[] = { grpc_core::TraceFlag grpc_cq_pluck_trace(false, "queue_pluck"); -#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \ - if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) && \ - (GRPC_TRACE_FLAG_ENABLED(grpc_cq_pluck_trace) || \ - (event)->type != GRPC_QUEUE_TIMEOUT)) { \ - char* _ev = grpc_event_string(event); \ - gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \ - gpr_free(_ev); \ - } +#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \ + do { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) && \ + (GRPC_TRACE_FLAG_ENABLED(grpc_cq_pluck_trace) || \ + (event)->type != GRPC_QUEUE_TIMEOUT)) { \ + char* _ev = grpc_event_string(event); \ + gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \ + gpr_free(_ev); \ + } \ + } while (0) static void on_pollset_shutdown_done(void* cq, grpc_error* error); From ce77350b50898687fc0954bc82ccc1aa00cfe793 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Wed, 8 May 2019 09:48:37 -0700 Subject: [PATCH 2107/2143] Montly update of room pem certificates --- etc/roots.pem | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/etc/roots.pem b/etc/roots.pem index be598710ddd..22bd2ab88dd 100644 --- a/etc/roots.pem +++ b/etc/roots.pem @@ -4552,3 +4552,149 @@ Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw 3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= -----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign Root CA - G1" +# Serial: 235931866688319308814040 +# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac +# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c +# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign ECC Root CA - G3" +# Serial: 287880440101571086945156 +# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40 +# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1 +# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Label: "emSign Root CA - C1" +# Serial: 825510296613316004955058 +# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68 +# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01 +# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Label: "emSign ECC Root CA - C3" +# Serial: 582948710642506000014504 +# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5 +# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66 +# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3 +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Label: "Hongkong Post Root CA 3" +# Serial: 46170865288971385588281144162979347873371282084 +# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 +# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 +# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 +-----BEGIN CERTIFICATE----- +MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL +BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ +SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n +a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5 +NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT +CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u +Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO +dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI +VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV +9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY +2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY +vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt +bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb +x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+ +l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK +TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj +Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e +i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw +DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG +7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk +MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr +gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk +GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS +3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm +Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+ +l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c +JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP +L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa +LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG +mpv0 +-----END CERTIFICATE----- From 983f678cb841060cd20e4f71757b67679890941c Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 8 May 2019 12:49:38 -0400 Subject: [PATCH 2108/2143] Mark it unlikely for Unref() to return true. In the hot path, specially when the dtor of a class is inlined, we will have to skip quite a few instructions (for Delete and dtor) before returning. Mark Unref() as unlikely so that compiler moves the decrement-refcnt-and-return code instructions to the front. --- src/core/ext/transport/chttp2/transport/internal.h | 2 +- src/core/lib/gprpp/orphanable.h | 4 ++-- src/core/lib/gprpp/ref_counted.h | 4 ++-- src/core/lib/transport/metadata.cc | 4 ++-- src/core/lib/transport/transport.h | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 0a55ee111ee..4cbe02ac463 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -238,7 +238,7 @@ class Chttp2IncomingByteStream : public ByteStream { // switch to std::shared_ptr<>. void Ref() { refs_.Ref(); } void Unref() { - if (refs_.Unref()) { + if (GPR_UNLIKELY(refs_.Unref())) { grpc_core::Delete(this); } } diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h index dda5026cbca..2e467e49060 100644 --- a/src/core/lib/gprpp/orphanable.h +++ b/src/core/lib/gprpp/orphanable.h @@ -110,12 +110,12 @@ class InternallyRefCounted : public Orphanable { } void Unref() { - if (refs_.Unref()) { + if (GPR_UNLIKELY(refs_.Unref())) { Delete(static_cast(this)); } } void Unref(const DebugLocation& location, const char* reason) { - if (refs_.Unref(location, reason)) { + if (GPR_UNLIKELY(refs_.Unref(location, reason))) { Delete(static_cast(this)); } } diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index 87b342e0093..83e9429ba37 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -211,12 +211,12 @@ class RefCounted : public Impl { // private, since it will only be used by RefCountedPtr<>, which is a // friend of this class. void Unref() { - if (refs_.Unref()) { + if (GPR_UNLIKELY(refs_.Unref())) { Delete(static_cast(this)); } } void Unref(const DebugLocation& location, const char* reason) { - if (refs_.Unref(location, reason)) { + if (GPR_UNLIKELY(refs_.Unref(location, reason))) { Delete(static_cast(this)); } } diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index 7e0b2163246..4609eb42cdc 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -466,7 +466,7 @@ void grpc_mdelem_do_unref(grpc_mdelem gmd DEBUG_ARGS) { case GRPC_MDELEM_STORAGE_INTERNED: { auto* md = reinterpret_cast GRPC_MDELEM_DATA(gmd); uint32_t hash = md->hash(); - if (md->Unref(FWD_DEBUG_ARGS)) { + if (GPR_UNLIKELY(md->Unref(FWD_DEBUG_ARGS))) { /* once the refcount hits zero, some other thread can come along and free md at any time: it's unsafe from this point on to access it */ note_disposed_interned_metadata(hash); @@ -475,7 +475,7 @@ void grpc_mdelem_do_unref(grpc_mdelem gmd DEBUG_ARGS) { } case GRPC_MDELEM_STORAGE_ALLOCATED: { auto* md = reinterpret_cast GRPC_MDELEM_DATA(gmd); - if (md->Unref(FWD_DEBUG_ARGS)) { + if (GPR_UNLIKELY(md->Unref(FWD_DEBUG_ARGS))) { grpc_core::Delete(md); } break; diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index aac136b92dd..a6a6e904f08 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -98,7 +98,7 @@ inline void grpc_stream_unref(grpc_stream_refcount* refcount, #else inline void grpc_stream_unref(grpc_stream_refcount* refcount) { #endif - if (refcount->refs.Unref()) { + if (GPR_UNLIKELY(refcount->refs.Unref())) { grpc_stream_destroy(refcount); } } From 3d5d2a122de06018ebd71fcfb63c744879f1de25 Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Tue, 7 May 2019 16:49:12 -0700 Subject: [PATCH 2109/2143] Extracted the code of Cpp Generator into a header --- BUILD | 1 + src/compiler/cpp_plugin.cc | 132 +------------------------------ src/compiler/cpp_plugin.h | 154 +++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 131 deletions(-) create mode 100644 src/compiler/cpp_plugin.h diff --git a/BUILD b/BUILD index 7f7add436fb..a03d2b61be4 100644 --- a/BUILD +++ b/BUILD @@ -433,6 +433,7 @@ grpc_cc_library( "src/compiler/config.h", "src/compiler/cpp_generator.h", "src/compiler/cpp_generator_helpers.h", + "src/compiler/cpp_plugin.h", "src/compiler/csharp_generator.h", "src/compiler/csharp_generator_helpers.h", "src/compiler/generator_helpers.h", diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc index 3c09b6feb24..2de2745445f 100644 --- a/src/compiler/cpp_plugin.cc +++ b/src/compiler/cpp_plugin.cc @@ -18,137 +18,7 @@ // Generates cpp gRPC service interface out of Protobuf IDL. // - -#include -#include - -#include "src/compiler/config.h" - -#include "src/compiler/cpp_generator.h" -#include "src/compiler/generator_helpers.h" -#include "src/compiler/protobuf_plugin.h" - -class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { - public: - CppGrpcGenerator() {} - virtual ~CppGrpcGenerator() {} - - virtual bool Generate(const grpc::protobuf::FileDescriptor* file, - const grpc::string& parameter, - grpc::protobuf::compiler::GeneratorContext* context, - grpc::string* error) const { - if (file->options().cc_generic_services()) { - *error = - "cpp grpc proto compiler plugin does not work with generic " - "services. To generate cpp grpc APIs, please set \"" - "cc_generic_service = false\"."; - return false; - } - - grpc_cpp_generator::Parameters generator_parameters; - generator_parameters.use_system_headers = true; - generator_parameters.generate_mock_code = false; - generator_parameters.include_import_headers = false; - - ProtoBufFile pbfile(file); - - if (!parameter.empty()) { - std::vector parameters_list = - grpc_generator::tokenize(parameter, ","); - for (auto parameter_string = parameters_list.begin(); - parameter_string != parameters_list.end(); parameter_string++) { - std::vector param = - grpc_generator::tokenize(*parameter_string, "="); - if (param[0] == "services_namespace") { - generator_parameters.services_namespace = param[1]; - } else if (param[0] == "use_system_headers") { - if (param[1] == "true") { - generator_parameters.use_system_headers = true; - } else if (param[1] == "false") { - generator_parameters.use_system_headers = false; - } else { - *error = grpc::string("Invalid parameter: ") + *parameter_string; - return false; - } - } else if (param[0] == "grpc_search_path") { - generator_parameters.grpc_search_path = param[1]; - } else if (param[0] == "generate_mock_code") { - if (param[1] == "true") { - generator_parameters.generate_mock_code = true; - } else if (param[1] != "false") { - *error = grpc::string("Invalid parameter: ") + *parameter_string; - return false; - } - } else if (param[0] == "gmock_search_path") { - generator_parameters.gmock_search_path = param[1]; - } else if (param[0] == "additional_header_includes") { - generator_parameters.additional_header_includes = - grpc_generator::tokenize(param[1], ":"); - } else if (param[0] == "message_header_extension") { - generator_parameters.message_header_extension = param[1]; - } else if (param[0] == "include_import_headers") { - if (param[1] == "true") { - generator_parameters.include_import_headers = true; - } else if (param[1] != "false") { - *error = grpc::string("Invalid parameter: ") + *parameter_string; - return false; - } - } else { - *error = grpc::string("Unknown parameter: ") + *parameter_string; - return false; - } - } - } - - grpc::string file_name = grpc_generator::StripProto(file->name()); - - grpc::string header_code = - grpc_cpp_generator::GetHeaderPrologue(&pbfile, generator_parameters) + - grpc_cpp_generator::GetHeaderIncludes(&pbfile, generator_parameters) + - grpc_cpp_generator::GetHeaderServices(&pbfile, generator_parameters) + - grpc_cpp_generator::GetHeaderEpilogue(&pbfile, generator_parameters); - std::unique_ptr header_output( - context->Open(file_name + ".grpc.pb.h")); - grpc::protobuf::io::CodedOutputStream header_coded_out(header_output.get()); - header_coded_out.WriteRaw(header_code.data(), header_code.size()); - - grpc::string source_code = - grpc_cpp_generator::GetSourcePrologue(&pbfile, generator_parameters) + - grpc_cpp_generator::GetSourceIncludes(&pbfile, generator_parameters) + - grpc_cpp_generator::GetSourceServices(&pbfile, generator_parameters) + - grpc_cpp_generator::GetSourceEpilogue(&pbfile, generator_parameters); - std::unique_ptr source_output( - context->Open(file_name + ".grpc.pb.cc")); - grpc::protobuf::io::CodedOutputStream source_coded_out(source_output.get()); - source_coded_out.WriteRaw(source_code.data(), source_code.size()); - - if (!generator_parameters.generate_mock_code) { - return true; - } - grpc::string mock_code = - grpc_cpp_generator::GetMockPrologue(&pbfile, generator_parameters) + - grpc_cpp_generator::GetMockIncludes(&pbfile, generator_parameters) + - grpc_cpp_generator::GetMockServices(&pbfile, generator_parameters) + - grpc_cpp_generator::GetMockEpilogue(&pbfile, generator_parameters); - std::unique_ptr mock_output( - context->Open(file_name + "_mock.grpc.pb.h")); - grpc::protobuf::io::CodedOutputStream mock_coded_out(mock_output.get()); - mock_coded_out.WriteRaw(mock_code.data(), mock_code.size()); - - return true; - } - - private: - // Insert the given code into the given file at the given insertion point. - void Insert(grpc::protobuf::compiler::GeneratorContext* context, - const grpc::string& filename, const grpc::string& insertion_point, - const grpc::string& code) const { - std::unique_ptr output( - context->OpenForInsert(filename, insertion_point)); - grpc::protobuf::io::CodedOutputStream coded_out(output.get()); - coded_out.WriteRaw(code.data(), code.size()); - } -}; +#include "src/compiler/cpp_plugin.h" int main(int argc, char* argv[]) { CppGrpcGenerator generator; diff --git a/src/compiler/cpp_plugin.h b/src/compiler/cpp_plugin.h new file mode 100644 index 00000000000..1cdf0b3c196 --- /dev/null +++ b/src/compiler/cpp_plugin.h @@ -0,0 +1,154 @@ +/* + * + * 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_INTERNAL_COMPILER_CPP_PLUGIN_H +#define GRPC_INTERNAL_COMPILER_CPP_PLUGIN_H + +#include +#include + +#include "src/compiler/config.h" + +#include "src/compiler/cpp_generator.h" +#include "src/compiler/generator_helpers.h" +#include "src/compiler/protobuf_plugin.h" + +// Cpp Generator for Protobug IDL +class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { + public: + CppGrpcGenerator() {} + virtual ~CppGrpcGenerator() {} + + virtual bool Generate(const grpc::protobuf::FileDescriptor* file, + const grpc::string& parameter, + grpc::protobuf::compiler::GeneratorContext* context, + grpc::string* error) const { + if (file->options().cc_generic_services()) { + *error = + "cpp grpc proto compiler plugin does not work with generic " + "services. To generate cpp grpc APIs, please set \"" + "cc_generic_service = false\"."; + return false; + } + + grpc_cpp_generator::Parameters generator_parameters; + generator_parameters.use_system_headers = true; + generator_parameters.generate_mock_code = false; + generator_parameters.include_import_headers = false; + + ProtoBufFile pbfile(file); + + if (!parameter.empty()) { + std::vector parameters_list = + grpc_generator::tokenize(parameter, ","); + for (auto parameter_string = parameters_list.begin(); + parameter_string != parameters_list.end(); parameter_string++) { + std::vector param = + grpc_generator::tokenize(*parameter_string, "="); + if (param[0] == "services_namespace") { + generator_parameters.services_namespace = param[1]; + } else if (param[0] == "use_system_headers") { + if (param[1] == "true") { + generator_parameters.use_system_headers = true; + } else if (param[1] == "false") { + generator_parameters.use_system_headers = false; + } else { + *error = grpc::string("Invalid parameter: ") + *parameter_string; + return false; + } + } else if (param[0] == "grpc_search_path") { + generator_parameters.grpc_search_path = param[1]; + } else if (param[0] == "generate_mock_code") { + if (param[1] == "true") { + generator_parameters.generate_mock_code = true; + } else if (param[1] != "false") { + *error = grpc::string("Invalid parameter: ") + *parameter_string; + return false; + } + } else if (param[0] == "gmock_search_path") { + generator_parameters.gmock_search_path = param[1]; + } else if (param[0] == "additional_header_includes") { + generator_parameters.additional_header_includes = + grpc_generator::tokenize(param[1], ":"); + } else if (param[0] == "message_header_extension") { + generator_parameters.message_header_extension = param[1]; + } else if (param[0] == "include_import_headers") { + if (param[1] == "true") { + generator_parameters.include_import_headers = true; + } else if (param[1] != "false") { + *error = grpc::string("Invalid parameter: ") + *parameter_string; + return false; + } + } else { + *error = grpc::string("Unknown parameter: ") + *parameter_string; + return false; + } + } + } + + grpc::string file_name = grpc_generator::StripProto(file->name()); + + grpc::string header_code = + grpc_cpp_generator::GetHeaderPrologue(&pbfile, generator_parameters) + + grpc_cpp_generator::GetHeaderIncludes(&pbfile, generator_parameters) + + grpc_cpp_generator::GetHeaderServices(&pbfile, generator_parameters) + + grpc_cpp_generator::GetHeaderEpilogue(&pbfile, generator_parameters); + std::unique_ptr header_output( + context->Open(file_name + ".grpc.pb.h")); + grpc::protobuf::io::CodedOutputStream header_coded_out(header_output.get()); + header_coded_out.WriteRaw(header_code.data(), header_code.size()); + + grpc::string source_code = + grpc_cpp_generator::GetSourcePrologue(&pbfile, generator_parameters) + + grpc_cpp_generator::GetSourceIncludes(&pbfile, generator_parameters) + + grpc_cpp_generator::GetSourceServices(&pbfile, generator_parameters) + + grpc_cpp_generator::GetSourceEpilogue(&pbfile, generator_parameters); + std::unique_ptr source_output( + context->Open(file_name + ".grpc.pb.cc")); + grpc::protobuf::io::CodedOutputStream source_coded_out(source_output.get()); + source_coded_out.WriteRaw(source_code.data(), source_code.size()); + + if (!generator_parameters.generate_mock_code) { + return true; + } + grpc::string mock_code = + grpc_cpp_generator::GetMockPrologue(&pbfile, generator_parameters) + + grpc_cpp_generator::GetMockIncludes(&pbfile, generator_parameters) + + grpc_cpp_generator::GetMockServices(&pbfile, generator_parameters) + + grpc_cpp_generator::GetMockEpilogue(&pbfile, generator_parameters); + std::unique_ptr mock_output( + context->Open(file_name + "_mock.grpc.pb.h")); + grpc::protobuf::io::CodedOutputStream mock_coded_out(mock_output.get()); + mock_coded_out.WriteRaw(mock_code.data(), mock_code.size()); + + return true; + } + + private: + // Insert the given code into the given file at the given insertion point. + void Insert(grpc::protobuf::compiler::GeneratorContext* context, + const grpc::string& filename, const grpc::string& insertion_point, + const grpc::string& code) const { + std::unique_ptr output( + context->OpenForInsert(filename, insertion_point)); + grpc::protobuf::io::CodedOutputStream coded_out(output.get()); + coded_out.WriteRaw(code.data(), code.size()); + } +}; + +#endif // GRPC_INTERNAL_COMPILER_CPP_PLUGIN_H From 2a4d62819be0b35261b6dcd7a03644451b9875c8 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 10 Jan 2019 03:18:18 -0800 Subject: [PATCH 2110/2143] Revise c-ares timeouts to use c-ares's internal timeout/retry logic --- CMakeLists.txt | 46 +++++++++ Makefile | 72 +++++++++++--- build.yaml | 7 ++ grpc.gyp | 9 ++ include/grpc/impl/codegen/grpc_types.h | 10 +- .../dns/c_ares/grpc_ares_ev_driver.cc | 80 +++++++++++++++ .../resolver/dns/c_ares/grpc_ares_ev_driver.h | 3 + .../dns/c_ares/grpc_ares_ev_driver_windows.cc | 13 ++- .../resolver/dns/c_ares/grpc_ares_wrapper.h | 2 +- test/core/iomgr/resolve_address_test.cc | 17 ++-- test/cpp/naming/BUILD | 13 ++- test/cpp/naming/cancel_ares_query_test.cc | 35 +------ test/cpp/naming/dns_test_util.cc | 97 ++++++++++++++++++ test/cpp/naming/dns_test_util.h | 38 +++++++ test/cpp/naming/gen_build_yaml.py | 3 + .../generate_resolver_component_tests.bzl | 1 + test/cpp/naming/resolver_component_test.cc | 99 +++++++++++++++++-- .../naming/resolver_component_tests_runner.py | 52 ++++++++++ .../naming/resolver_test_record_groups.yaml | 48 +++++++++ .../generated/sources_and_headers.json | 18 ++++ 20 files changed, 594 insertions(+), 69 deletions(-) create mode 100644 test/cpp/naming/dns_test_util.cc create mode 100644 test/cpp/naming/dns_test_util.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e3fc44e4354..8382fb7318f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2905,6 +2905,49 @@ target_link_libraries(test_tcp_server ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_library(dns_test_util + test/cpp/naming/dns_test_util.cc +) + +if(WIN32 AND MSVC) + set_target_properties(dns_test_util PROPERTIES COMPILE_PDB_NAME "dns_test_util" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if (gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/dns_test_util.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + + +target_include_directories(dns_test_util + 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(dns_test_util + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) add_library(grpc++ @@ -18490,6 +18533,7 @@ target_include_directories(resolver_component_test_unsecure target_link_libraries(resolver_component_test_unsecure ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + dns_test_util grpc++_test_util_unsecure grpc_test_util_unsecure grpc++_unsecure @@ -18531,6 +18575,7 @@ target_include_directories(resolver_component_test target_link_libraries(resolver_component_test ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + dns_test_util grpc++_test_util grpc_test_util grpc++ @@ -18740,6 +18785,7 @@ target_include_directories(cancel_ares_query_test target_link_libraries(cancel_ares_query_test ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + dns_test_util grpc++_test_util grpc_test_util grpc++ diff --git a/Makefile b/Makefile index 949751ae9b8..3b0e60ecef4 100644 --- a/Makefile +++ b/Makefile @@ -1411,9 +1411,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)/libbenchmark.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libdns_test_util.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)/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)/libdns_test_util.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 @@ -5290,6 +5290,55 @@ endif endif +LIBDNS_TEST_UTIL_SRC = \ + test/cpp/naming/dns_test_util.cc \ + +PUBLIC_HEADERS_CXX += \ + +LIBDNS_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBDNS_TEST_UTIL_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libdns_test_util.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)/libdns_test_util.a: protobuf_dep_error + + +else + +$(LIBDIR)/$(CONFIG)/libdns_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBDNS_TEST_UTIL_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libdns_test_util.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(LIBDNS_TEST_UTIL_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libdns_test_util.a +endif + + + + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBDNS_TEST_UTIL_OBJS:.o=.dep) +endif +endif + + LIBGRPC++_SRC = \ src/cpp/client/insecure_credentials.cc \ src/cpp/client/secure_credentials.cc \ @@ -21283,16 +21332,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/resolver_component_test_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(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 +$(BINDIR)/$(CONFIG)/resolver_component_test_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libdns_test_util.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) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(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)/resolver_component_test_unsecure + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libdns_test_util.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)/resolver_component_test_unsecure endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_test.o: $(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 +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_test.o: $(LIBDIR)/$(CONFIG)/libdns_test_util.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_resolver_component_test_unsecure: $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS:.o=.dep) @@ -21326,16 +21375,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/resolver_component_test: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_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)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/resolver_component_test: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_test + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_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)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_test.o: $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(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)/libgrpc++_test_config.a deps_resolver_component_test: $(RESOLVER_COMPONENT_TEST_OBJS:.o=.dep) @@ -21541,16 +21590,16 @@ $(BINDIR)/$(CONFIG)/cancel_ares_query_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cancel_ares_query_test: $(PROTOBUF_DEP) $(CANCEL_ARES_QUERY_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)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/cancel_ares_query_test: $(PROTOBUF_DEP) $(CANCEL_ARES_QUERY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(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)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CANCEL_ARES_QUERY_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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cancel_ares_query_test + $(Q) $(LDXX) $(LDFLAGS) $(CANCEL_ARES_QUERY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(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)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cancel_ares_query_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/cancel_ares_query_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)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/cancel_ares_query_test.o: $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(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)/libgrpc++_test_config.a deps_cancel_ares_query_test: $(CANCEL_ARES_QUERY_TEST_OBJS:.o=.dep) @@ -22180,6 +22229,7 @@ test/cpp/interop/interop_server.cc: $(OPENSSL_DEP) test/cpp/interop/interop_server_bootstrap.cc: $(OPENSSL_DEP) test/cpp/interop/server_helper.cc: $(OPENSSL_DEP) test/cpp/microbenchmarks/helpers.cc: $(OPENSSL_DEP) +test/cpp/naming/dns_test_util.cc: $(OPENSSL_DEP) test/cpp/qps/benchmark_config.cc: $(OPENSSL_DEP) test/cpp/qps/client_async.cc: $(OPENSSL_DEP) test/cpp/qps/client_callback.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 3638e3ce7e7..a61b7987a4e 100644 --- a/build.yaml +++ b/build.yaml @@ -1677,6 +1677,13 @@ libs: - grpc_test_util - grpc - gpr +- name: dns_test_util + build: private + language: c++ + headers: + - test/cpp/naming/dns_test_util.h + src: + - test/cpp/naming/dns_test_util.cc - name: grpc++ build: all language: c++ diff --git a/grpc.gyp b/grpc.gyp index ff77c6fcd59..e6ed4d7318d 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1405,6 +1405,15 @@ 'test/core/util/test_tcp_server.cc', ], }, + { + 'target_name': 'dns_test_util', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'test/cpp/naming/dns_test_util.cc', + ], + }, { 'target_name': 'grpc++', 'type': 'static_library', diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 33c160b4240..65582e6e85d 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -359,10 +359,12 @@ typedef struct { * 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 - * entirely. */ +/** If set, determines an upper bound on the number of milliseconds that the + * c-ares based DNS resolver will wait on queries before cancelling them. + * The default value is 120,000. Setting this to "0" will disable the + * overall timeout entirely. Note that this doesn't include internal c-ares + * timeouts/backoff/retry logic, and so the actual DNS resolution may time out + * sooner than the value specified here. */ #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. */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc index 9fff92da52f..4ad80786519 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -84,6 +84,10 @@ struct grpc_ares_ev_driver { grpc_timer query_timeout; /** cancels queries on a timeout */ grpc_closure on_timeout_locked; + /** alarm to poll ares_process on in case fd events don't happen */ + grpc_timer ares_backup_poll_alarm; + /** polls ares_process on a periodic timer */ + grpc_closure on_ares_backup_poll_alarm_locked; }; static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver); @@ -130,6 +134,13 @@ static void fd_node_shutdown_locked(fd_node* fdn, const char* reason) { static void on_timeout_locked(void* arg, grpc_error* error); +static void on_ares_backup_poll_alarm_locked(void* arg, grpc_error* error); + +static void noop_inject_channel_config(ares_channel channel) {} + +void (*grpc_ares_test_only_inject_config)(ares_channel channel) = + noop_inject_channel_config; + grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set, int query_timeout_ms, @@ -140,6 +151,7 @@ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, memset(&opts, 0, sizeof(opts)); opts.flags |= ARES_FLAG_STAYOPEN; int status = ares_init_options(&(*ev_driver)->channel, &opts, ARES_OPT_FLAGS); + grpc_ares_test_only_inject_config((*ev_driver)->channel); GRPC_CARES_TRACE_LOG("request:%p grpc_ares_ev_driver_create_locked", request); if (status != ARES_SUCCESS) { char* err_msg; @@ -163,6 +175,9 @@ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, ->polled_fd_factory->ConfigureAresChannelLocked((*ev_driver)->channel); GRPC_CLOSURE_INIT(&(*ev_driver)->on_timeout_locked, on_timeout_locked, *ev_driver, grpc_combiner_scheduler(combiner)); + GRPC_CLOSURE_INIT(&(*ev_driver)->on_ares_backup_poll_alarm_locked, + on_ares_backup_poll_alarm_locked, *ev_driver, + grpc_combiner_scheduler(combiner)); (*ev_driver)->query_timeout_ms = query_timeout_ms; return GRPC_ERROR_NONE; } @@ -174,6 +189,7 @@ void grpc_ares_ev_driver_on_queries_complete_locked( // fds; if it's not working, there are no fds to shut down. ev_driver->shutting_down = true; grpc_timer_cancel(&ev_driver->query_timeout); + grpc_timer_cancel(&ev_driver->ares_backup_poll_alarm); grpc_ares_ev_driver_unref(ev_driver); } @@ -204,6 +220,21 @@ static fd_node* pop_fd_node_locked(fd_node** head, ares_socket_t as) { return nullptr; } +static grpc_millis calculate_next_ares_backup_poll_alarm_ms( + grpc_ares_ev_driver* driver) { + // An alternative here could be to use ares_timeout to try to be more + // accurate, but that would require using "struct timeval"'s, which just makes + // things a bit more complicated. So just poll every second, as suggested + // by the c-ares code comments. + grpc_millis ms_until_next_ares_backup_poll_alarm = 1000; + GRPC_CARES_TRACE_LOG( + "request:%p ev_driver=%p. next ares process poll time in " + "%" PRId64 " ms", + driver->request, driver, ms_until_next_ares_backup_poll_alarm); + return ms_until_next_ares_backup_poll_alarm + + grpc_core::ExecCtx::Get()->Now(); +} + static void on_timeout_locked(void* arg, grpc_error* error) { grpc_ares_ev_driver* driver = static_cast(arg); GRPC_CARES_TRACE_LOG( @@ -216,6 +247,47 @@ static void on_timeout_locked(void* arg, grpc_error* error) { grpc_ares_ev_driver_unref(driver); } +/* In case of non-responsive DNS servers, dropped packets, etc., c-ares has + * intelligent timeout and retry logic, which we can take advantage of by + * polling ares_process_fd on time intervals. Overall, the c-ares library is + * meant to be called into and given a chance to proceed name resolution: + * a) when fd events happen + * b) when some time has passed without fd events having happened + * For the latter, we use this backup poller. Also see + * https://github.com/grpc/grpc/pull/17688 description for more details. */ +static void on_ares_backup_poll_alarm_locked(void* arg, grpc_error* error) { + grpc_ares_ev_driver* driver = static_cast(arg); + GRPC_CARES_TRACE_LOG( + "request:%p ev_driver=%p on_ares_backup_poll_alarm_locked. " + "driver->shutting_down=%d. " + "err=%s", + driver->request, driver, driver->shutting_down, grpc_error_string(error)); + if (!driver->shutting_down && error == GRPC_ERROR_NONE) { + fd_node* fdn = driver->fds; + while (fdn != nullptr) { + if (!fdn->already_shutdown) { + GRPC_CARES_TRACE_LOG( + "request:%p ev_driver=%p on_ares_backup_poll_alarm_locked; " + "ares_process_fd. fd=%s", + driver->request, driver, fdn->grpc_polled_fd->GetName()); + ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked(); + ares_process_fd(driver->channel, as, as); + } + fdn = fdn->next; + } + if (!driver->shutting_down) { + grpc_millis next_ares_backup_poll_alarm = + calculate_next_ares_backup_poll_alarm_ms(driver); + grpc_ares_ev_driver_ref(driver); + grpc_timer_init(&driver->ares_backup_poll_alarm, + next_ares_backup_poll_alarm, + &driver->on_ares_backup_poll_alarm_locked); + } + grpc_ares_notify_on_event_locked(driver); + } + grpc_ares_ev_driver_unref(driver); +} + static void on_readable_locked(void* arg, grpc_error* error) { fd_node* fdn = static_cast(arg); GPR_ASSERT(fdn->readable_registered); @@ -353,6 +425,7 @@ void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) { if (!ev_driver->working) { ev_driver->working = true; grpc_ares_notify_on_event_locked(ev_driver); + // Initialize overall DNS resolution timeout alarm grpc_millis timeout = ev_driver->query_timeout_ms == 0 ? GRPC_MILLIS_INF_FUTURE @@ -364,6 +437,13 @@ void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) { grpc_ares_ev_driver_ref(ev_driver); grpc_timer_init(&ev_driver->query_timeout, timeout, &ev_driver->on_timeout_locked); + // Initialize the backup poll alarm + grpc_millis next_ares_backup_poll_alarm = + calculate_next_ares_backup_poll_alarm_ms(ev_driver); + grpc_ares_ev_driver_ref(ev_driver); + grpc_timer_init(&ev_driver->ares_backup_poll_alarm, + next_ares_backup_poll_alarm, + &ev_driver->on_ares_backup_poll_alarm_locked); } } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h index b8cefd9470e..2d172eb3d1e 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h @@ -54,6 +54,9 @@ void grpc_ares_ev_driver_on_queries_complete_locked( /* Shutdown all the grpc_fds used by \a ev_driver */ void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver); +/* Exposed in this header for C-core tests only */ +extern void (*grpc_ares_test_only_inject_config)(ares_channel channel); + namespace grpc_core { /* A wrapped fd that integrates with the grpc iomgr of the current platform. 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 7e7e9156461..ce39007f905 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 @@ -109,6 +109,7 @@ class GrpcPolledFdWindows : public GrpcPolledFd { read_closure_ = read_closure; GPR_ASSERT(GRPC_SLICE_LENGTH(read_buf_) == 0); grpc_slice_unref_internal(read_buf_); + GPR_ASSERT(!read_buf_has_data_); read_buf_ = GRPC_SLICE_MALLOC(4192); WSABUF buffer; buffer.buf = (char*)GRPC_SLICE_START_PTR(read_buf_); @@ -175,7 +176,7 @@ class GrpcPolledFdWindows : public GrpcPolledFd { GRPC_CARES_TRACE_LOG( "RecvFrom called on fd:|%s|. Current read buf length:|%d|", GetName(), GRPC_SLICE_LENGTH(read_buf_)); - if (GRPC_SLICE_LENGTH(read_buf_) == 0) { + if (!read_buf_has_data_) { WSASetLastError(WSAEWOULDBLOCK); return -1; } @@ -186,6 +187,9 @@ class GrpcPolledFdWindows : public GrpcPolledFd { } read_buf_ = grpc_slice_sub_no_ref(read_buf_, bytes_read, GRPC_SLICE_LENGTH(read_buf_)); + if (GRPC_SLICE_LENGTH(read_buf_) == 0) { + read_buf_has_data_ = false; + } /* c-ares overloads this recv_from virtual socket function to receive * data on both UDP and TCP sockets, and from is nullptr for TCP. */ if (from != nullptr) { @@ -302,6 +306,11 @@ class GrpcPolledFdWindows : public GrpcPolledFd { polled_fd->OnIocpReadableInner(error); } + // TODO(apolcyn): improve this error handling to be less conversative. + // An e.g. ECONNRESET error here should result in errors when + // c-ares reads from this socket later, but it shouldn't necessarily cancel + // the entire resolution attempt. Doing so will allow the "inject broken + // nameserver list" test to pass on Windows. void OnIocpReadableInner(grpc_error* error) { if (error == GRPC_ERROR_NONE) { if (winsocket_->read_info.wsa_error != 0) { @@ -323,6 +332,7 @@ class GrpcPolledFdWindows : public GrpcPolledFd { if (error == GRPC_ERROR_NONE) { read_buf_ = grpc_slice_sub_no_ref(read_buf_, 0, winsocket_->read_info.bytes_transfered); + read_buf_has_data_ = true; } else { grpc_slice_unref_internal(read_buf_); read_buf_ = grpc_empty_slice(); @@ -370,6 +380,7 @@ class GrpcPolledFdWindows : public GrpcPolledFd { char recv_from_source_addr_[200]; ares_socklen_t recv_from_source_addr_len_; grpc_slice read_buf_; + bool read_buf_has_data_ = false; grpc_slice write_buf_; grpc_closure* read_closure_ = nullptr; grpc_closure* write_closure_ = nullptr; diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h index 28082504565..33d866c0ff0 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -26,7 +26,7 @@ #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/resolve_address.h" -#define GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS 10000 +#define GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS 120000 extern grpc_core::TraceFlag grpc_trace_cares_address_sorting; diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index f59a992416d..1f0c0e3e835 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -83,7 +83,9 @@ static grpc_millis n_sec_deadline(int seconds) { static void poll_pollset_until_request_done(args_struct* args) { grpc_core::ExecCtx exec_ctx; - grpc_millis deadline = n_sec_deadline(10); + // Try to give enough time for c-ares to run through its retries + // a few times if needed. + grpc_millis deadline = n_sec_deadline(90); while (true) { bool done = gpr_atm_acq_load(&args->done_atm) != 0; if (done) { @@ -371,15 +373,10 @@ int main(int argc, char** argv) { test_missing_default_port(); test_ipv6_with_port(); test_ipv6_without_port(); - if (gpr_stricmp(resolver_type, "ares") != 0) { - // These tests can trigger DNS queries to the nearby nameserver - // that need to come back in order for the test to succeed. - // c-ares is prone to not using the local system caches that the - // native getaddrinfo implementations take advantage of, so running - // these unit tests under c-ares risks flakiness. - test_invalid_ip_addresses(); - test_unparseable_hostports(); - } else { + test_invalid_ip_addresses(); + test_unparseable_hostports(); + if (gpr_stricmp(resolver_type, "ares") == 0) { + // This behavior expectation is specific to c-ares. test_localhost_result_has_ipv6_first(); } grpc_core::Executor::ShutdownAll(); diff --git a/test/cpp/naming/BUILD b/test/cpp/naming/BUILD index 58e70480acf..7db435a3fd4 100644 --- a/test/cpp/naming/BUILD +++ b/test/cpp/naming/BUILD @@ -22,7 +22,7 @@ package( licenses(["notice"]) # Apache v2 -load("//bazel:grpc_build_system.bzl", "grpc_py_binary", "grpc_cc_test") +load("//bazel:grpc_build_system.bzl", "grpc_py_binary", "grpc_cc_test", "grpc_cc_library") load(":generate_resolver_component_tests.bzl", "generate_resolver_component_tests") # Meant to be invoked only through the top-level shell script driver. @@ -39,6 +39,7 @@ grpc_cc_test( srcs = ["cancel_ares_query_test.cc"], external_deps = ["gmock"], deps = [ + ":dns_test_util", "//:gpr", "//:grpc", "//:grpc++", @@ -49,4 +50,14 @@ grpc_cc_test( ], ) +grpc_cc_library( + name = "dns_test_util", + hdrs = ["dns_test_util.h"], + srcs = ["dns_test_util.cc"], + deps = [ + "//:gpr", + "//:grpc", + ], +) + generate_resolver_component_tests() diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index bcf96aa1dc5..674e72fdc52 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -44,6 +44,7 @@ #include "test/core/util/cmdline.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" +#include "test/cpp/naming/dns_test_util.h" #ifdef GPR_WINDOWS #include "src/core/lib/iomgr/sockaddr_windows.h" @@ -76,36 +77,6 @@ void EndTest(grpc_channel* client, grpc_completion_queue* cq) { grpc_completion_queue_destroy(cq); } -class FakeNonResponsiveDNSServer { - public: - FakeNonResponsiveDNSServer(int port) { - socket_ = socket(AF_INET6, SOCK_DGRAM, 0); - if (socket_ == BAD_SOCKET_RETURN_VAL) { - gpr_log(GPR_DEBUG, "Failed to create UDP ipv6 socket"); - abort(); - } - sockaddr_in6 addr; - memset(&addr, 0, sizeof(addr)); - addr.sin6_family = AF_INET6; - addr.sin6_port = htons(port); - ((char*)&addr.sin6_addr)[15] = 1; - if (bind(socket_, (const sockaddr*)&addr, sizeof(addr)) != 0) { - gpr_log(GPR_DEBUG, "Failed to bind UDP ipv6 socket to [::1]:%d", port); - abort(); - } - } - ~FakeNonResponsiveDNSServer() { -#ifdef GPR_WINDOWS - closesocket(socket_); -#else - close(socket_); -#endif - } - - private: - int socket_; -}; - struct ArgsStruct { gpr_atm done_atm; gpr_mu* mu; @@ -184,7 +155,7 @@ class AssertFailureResultHandler : public grpc_core::Resolver::ResultHandler { void TestCancelActiveDNSQuery(ArgsStruct* args) { int fake_dns_port = grpc_pick_unused_port_or_die(); - FakeNonResponsiveDNSServer fake_dns_server(fake_dns_port); + grpc::testing::FakeNonResponsiveDNSServer fake_dns_server(fake_dns_port); char* client_target; GPR_ASSERT(gpr_asprintf( &client_target, @@ -282,7 +253,7 @@ void TestCancelDuringActiveQuery( cancellation_test_query_timeout_setting query_timeout_setting) { // Start up fake non responsive DNS server int fake_dns_port = grpc_pick_unused_port_or_die(); - FakeNonResponsiveDNSServer fake_dns_server(fake_dns_port); + grpc::testing::FakeNonResponsiveDNSServer fake_dns_server(fake_dns_port); // Create a call that will try to use the fake DNS server char* client_target = nullptr; GPR_ASSERT(gpr_asprintf( diff --git a/test/cpp/naming/dns_test_util.cc b/test/cpp/naming/dns_test_util.cc new file mode 100644 index 00000000000..1380d0ab423 --- /dev/null +++ b/test/cpp/naming/dns_test_util.cc @@ -0,0 +1,97 @@ +/* + * + * 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 + +#include +#include + +#include "test/cpp/naming/dns_test_util.h" + +#ifdef GPR_WINDOWS +#include "src/core/lib/iomgr/sockaddr_windows.h" +#include "src/core/lib/iomgr/socket_windows.h" +#define BAD_SOCKET_RETURN_VAL INVALID_SOCKET +#else +#include "src/core/lib/iomgr/sockaddr_posix.h" +#define BAD_SOCKET_RETURN_VAL -1 +#endif + +namespace grpc { +namespace testing { + +FakeNonResponsiveDNSServer::FakeNonResponsiveDNSServer(int port) { + udp_socket_ = socket(AF_INET6, SOCK_DGRAM, 0); + tcp_socket_ = socket(AF_INET6, SOCK_STREAM, 0); + if (udp_socket_ == BAD_SOCKET_RETURN_VAL) { + gpr_log(GPR_DEBUG, "Failed to create UDP ipv6 socket"); + abort(); + } + if (tcp_socket_ == BAD_SOCKET_RETURN_VAL) { + gpr_log(GPR_DEBUG, "Failed to create TCP ipv6 socket"); + abort(); + } + sockaddr_in6 addr; + memset(&addr, 0, sizeof(addr)); + addr.sin6_family = AF_INET6; + addr.sin6_port = htons(port); + ((char*)&addr.sin6_addr)[15] = 1; + if (bind(udp_socket_, (const sockaddr*)&addr, sizeof(addr)) != 0) { + gpr_log(GPR_DEBUG, "Failed to bind UDP ipv6 socket to [::1]:%d", port); + abort(); + } +#ifdef GPR_WINDOWS + char val = 1; + if (setsockopt(tcp_socket_, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == + SOCKET_ERROR) { + gpr_log(GPR_DEBUG, + "Failed to set SO_REUSEADDR on TCP ipv6 socket to [::1]:%d", port); + abort(); + } +#else + int val = 1; + if (setsockopt(tcp_socket_, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) != + 0) { + gpr_log(GPR_DEBUG, + "Failed to set SO_REUSEADDR on TCP ipv6 socket to [::1]:%d", port); + abort(); + } +#endif + if (bind(tcp_socket_, (const sockaddr*)&addr, sizeof(addr)) != 0) { + gpr_log(GPR_DEBUG, "Failed to bind TCP ipv6 socket to [::1]:%d", port); + abort(); + } + if (listen(tcp_socket_, 100)) { + gpr_log(GPR_DEBUG, "Failed to listen on TCP ipv6 socket to [::1]:%d", port); + abort(); + } +} + +FakeNonResponsiveDNSServer::~FakeNonResponsiveDNSServer() { +#ifdef GPR_WINDOWS + closesocket(udp_socket_); + closesocket(tcp_socket_); +#else + close(udp_socket_); + close(tcp_socket_); +#endif +} + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/naming/dns_test_util.h b/test/cpp/naming/dns_test_util.h new file mode 100644 index 00000000000..d5e50992672 --- /dev/null +++ b/test/cpp/naming/dns_test_util.h @@ -0,0 +1,38 @@ +/* + * + * 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 GRPC_DNS_TEST_UTIL_H +#define GRPC_DNS_TEST_UTIL_H + +namespace grpc { +namespace testing { + +class FakeNonResponsiveDNSServer { + public: + explicit FakeNonResponsiveDNSServer(int port); + virtual ~FakeNonResponsiveDNSServer(); + + private: + int udp_socket_; + int tcp_socket_; +}; + +} // namespace testing +} // namespace grpc + +#endif /* GRPC_DNS_TEST_UTIL_H */ diff --git a/test/cpp/naming/gen_build_yaml.py b/test/cpp/naming/gen_build_yaml.py index 9bf5ae9b2f8..9cbbbb69254 100755 --- a/test/cpp/naming/gen_build_yaml.py +++ b/test/cpp/naming/gen_build_yaml.py @@ -50,6 +50,7 @@ def _resolver_test_cases(resolver_component_data): ('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']), + ('inject_broken_nameserver_list', test_case['inject_broken_nameserver_list']), ], }) return out @@ -72,6 +73,7 @@ def main(): 'src': ['test/cpp/naming/resolver_component_test.cc'], 'platforms': ['linux', 'posix', 'mac', 'windows'], 'deps': [ + 'dns_test_util', 'grpc++_test_util' + unsecure_build_config_suffix, 'grpc_test_util' + unsecure_build_config_suffix, 'grpc++' + unsecure_build_config_suffix, @@ -130,6 +132,7 @@ def main(): 'src': ['test/cpp/naming/cancel_ares_query_test.cc'], 'platforms': ['linux', 'posix', 'mac', 'windows'], 'deps': [ + 'dns_test_util', 'grpc++_test_util', 'grpc_test_util', 'grpc++', diff --git a/test/cpp/naming/generate_resolver_component_tests.bzl b/test/cpp/naming/generate_resolver_component_tests.bzl index 589176762e6..bcc62f62871 100755 --- a/test/cpp/naming/generate_resolver_component_tests.bzl +++ b/test/cpp/naming/generate_resolver_component_tests.bzl @@ -46,6 +46,7 @@ def generate_resolver_component_tests(): "gmock", ], deps = [ + ":dns_test_util", "//test/cpp/util:test_util%s" % unsecure_build_config_suffix, "//test/core/util:grpc_test_util%s" % unsecure_build_config_suffix, "//:grpc++%s" % unsecure_build_config_suffix, diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 4d1beb7ec37..e3f3e94d2de 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -39,7 +39,9 @@ #include "test/cpp/util/test_config.h" #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" #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" @@ -53,9 +55,12 @@ #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/iomgr/socket_utils.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" +#include "test/cpp/naming/dns_test_util.h" + // TODO: pull in different headers when enabling this // test on windows. Also set BAD_SOCKET_RETURN_VAL // to INVALID_SOCKET on windows. @@ -106,6 +111,17 @@ DEFINE_string( "generate " "the python script runner doesn't allow us to pass a gflags bool to this " "binary."); +DEFINE_string( + inject_broken_nameserver_list, "", + "Whether or not to configure c-ares to use a broken nameserver list, in " + "which " + "the first nameserver in the list is non-responsive, but the second one " + "works, i.e " + "serves the expected DNS records; using for testing such a real scenario." + "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."); @@ -217,7 +233,10 @@ gpr_timespec NSecondDeadline(int seconds) { } void PollPollsetUntilRequestDone(ArgsStruct* args) { - gpr_timespec deadline = NSecondDeadline(10); + // Use a 20-second timeout to give room for the tests that involve + // a non-responsive name server (c-ares uses a ~5 second query timeout + // for that server before succeeding with the healthy one). + gpr_timespec deadline = NSecondDeadline(20); while (true) { bool done = gpr_atm_acq_load(&args->done_atm) != 0; if (done) { @@ -469,6 +488,50 @@ class CheckingResultHandler : public ResultHandler { } }; +int g_fake_non_responsive_dns_server_port = -1; + +/* This function will configure any ares_channel created by the c-ares based + * resolver. This is useful to effectively mock /etc/resolv.conf settings + * (and equivalent on Windows), which unit tests don't have write permissions. + */ +void InjectBrokenNameServerList(ares_channel channel) { + struct ares_addr_port_node dns_server_addrs[2]; + memset(dns_server_addrs, 0, sizeof(dns_server_addrs)); + char* unused_host; + char* local_dns_server_port; + GPR_ASSERT(gpr_split_host_port(FLAGS_local_dns_server_address.c_str(), + &unused_host, &local_dns_server_port)); + gpr_log(GPR_DEBUG, + "Injecting broken nameserver list. Bad server address:|[::1]:%d|. " + "Good server address:%s", + g_fake_non_responsive_dns_server_port, + FLAGS_local_dns_server_address.c_str()); + // Put the non-responsive DNS server at the front of c-ares's nameserver list. + dns_server_addrs[0].family = AF_INET6; + ((char*)&dns_server_addrs[0].addr.addr6)[15] = 0x1; + dns_server_addrs[0].tcp_port = g_fake_non_responsive_dns_server_port; + dns_server_addrs[0].udp_port = g_fake_non_responsive_dns_server_port; + dns_server_addrs[0].next = &dns_server_addrs[1]; + // Put the actual healthy DNS server after the first one. The expectation is + // that the resolver will timeout the query to the non-responsive DNS server + // and will skip over to this healthy DNS server, without causing any DNS + // resolution errors. + dns_server_addrs[1].family = AF_INET; + ((char*)&dns_server_addrs[1].addr.addr4)[0] = 0x7f; + ((char*)&dns_server_addrs[1].addr.addr4)[3] = 0x1; + dns_server_addrs[1].tcp_port = atoi(local_dns_server_port); + dns_server_addrs[1].udp_port = atoi(local_dns_server_port); + dns_server_addrs[1].next = nullptr; + GPR_ASSERT(ares_set_servers_ports(channel, dns_server_addrs) == ARES_SUCCESS); + gpr_free(local_dns_server_port); + gpr_free(unused_host); +} + +void StartResolvingLocked(void* arg, grpc_error* unused) { + grpc_core::Resolver* r = static_cast(arg); + r->StartLocked(); +} + void RunResolvesRelevantRecordsTest( grpc_core::UniquePtr ( *CreateResultHandler)(ArgsStruct* args)) { @@ -480,9 +543,29 @@ void RunResolvesRelevantRecordsTest( args.expected_lb_policy = FLAGS_expected_lb_policy; // maybe build the address with an authority char* whole_uri = nullptr; - 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: --inject_broken_nameserver_list: %s", + FLAGS_inject_broken_nameserver_list.c_str()); + grpc_core::UniquePtr + fake_non_responsive_dns_server; + if (FLAGS_inject_broken_nameserver_list == "True") { + g_fake_non_responsive_dns_server_port = grpc_pick_unused_port_or_die(); + fake_non_responsive_dns_server.reset( + grpc_core::New( + g_fake_non_responsive_dns_server_port)); + grpc_ares_test_only_inject_config = InjectBrokenNameServerList; + GPR_ASSERT( + gpr_asprintf(&whole_uri, "dns:///%s", FLAGS_target_name.c_str())); + } else if (FLAGS_inject_broken_nameserver_list == "False") { + gpr_log(GPR_INFO, "Specifying authority in uris to: %s", + FLAGS_local_dns_server_address.c_str()); + GPR_ASSERT(gpr_asprintf(&whole_uri, "dns://%s/%s", + FLAGS_local_dns_server_address.c_str(), + FLAGS_target_name.c_str())); + } else { + gpr_log(GPR_DEBUG, "Invalid value for --inject_broken_nameserver_list."); + abort(); + } gpr_log(GPR_DEBUG, "resolver_component_test: --enable_srv_queries: %s", FLAGS_enable_srv_queries.c_str()); grpc_channel_args* resolver_args = nullptr; @@ -525,7 +608,9 @@ void RunResolvesRelevantRecordsTest( CreateResultHandler(&args)); grpc_channel_args_destroy(resolver_args); gpr_free(whole_uri); - resolver->StartLocked(); + GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(StartResolvingLocked, resolver.get(), + grpc_combiner_scheduler(args.lock)), + GRPC_ERROR_NONE); grpc_core::ExecCtx::Get()->Flush(); PollPollsetUntilRequestDone(&args); ArgsFinish(&args); @@ -560,10 +645,6 @@ int main(int argc, char** argv) { gpr_log(GPR_ERROR, "Missing target_name param."); abort(); } - if (FLAGS_local_dns_server_address != "") { - gpr_log(GPR_INFO, "Specifying authority in uris to: %s", - FLAGS_local_dns_server_address.c_str()); - } auto result = RUN_ALL_TESTS(); grpc_shutdown(); return result; diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index a0eda79ec62..a5e4485c0ac 100755 --- a/test/cpp/naming/resolver_component_tests_runner.py +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -127,6 +127,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -141,6 +142,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -155,6 +157,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -169,6 +172,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -183,6 +187,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -197,6 +202,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -211,6 +217,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -225,6 +232,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -239,6 +247,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -253,6 +262,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -267,6 +277,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -281,6 +292,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--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 +307,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -309,6 +322,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -323,6 +337,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'False', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -337,6 +352,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'False', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -351,6 +367,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'False', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -365,6 +382,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'False', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -379,6 +397,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'False', '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -393,6 +412,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'False', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -407,6 +427,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'False', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -421,6 +442,37 @@ current_test_subprocess = subprocess.Popen([ '--expected_lb_policy', '', '--enable_srv_queries', 'True', '--enable_txt_queries', 'False', + '--inject_broken_nameserver_list', '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' % 'no-srv-ipv4-single-target-inject-broken-nameservers.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'no-srv-ipv4-single-target-inject-broken-nameservers.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '5.5.5.5:443,False', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', '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' % 'ipv4-config-causing-fallback-to-tcp-inject-broken-nameservers.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-config-causing-fallback-to-tcp-inject-broken-nameservers.resolver-tests-version-4.grpctestingexp.', + '--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', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'True', '--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 738fe658939..d236fd743d9 100644 --- a/test/cpp/naming/resolver_test_record_groups.yaml +++ b/test/cpp/naming/resolver_test_record_groups.yaml @@ -7,6 +7,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: no-srv-ipv4-single-target records: no-srv-ipv4-single-target: @@ -17,6 +18,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv4-single-target records: _grpclb._tcp.srv-ipv4-single-target: @@ -31,6 +33,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv4-multi-target records: _grpclb._tcp.srv-ipv4-multi-target: @@ -45,6 +48,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv6-single-target records: _grpclb._tcp.srv-ipv6-single-target: @@ -59,6 +63,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv6-multi-target records: _grpclb._tcp.srv-ipv6-multi-target: @@ -73,6 +78,7 @@ resolver_component_tests: expected_lb_policy: round_robin enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv4-simple-service-config records: _grpclb._tcp.srv-ipv4-simple-service-config: @@ -88,6 +94,7 @@ resolver_component_tests: expected_lb_policy: round_robin enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: ipv4-no-srv-simple-service-config records: ipv4-no-srv-simple-service-config: @@ -101,6 +108,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: ipv4-no-config-for-cpp records: ipv4-no-config-for-cpp: @@ -114,6 +122,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: ipv4-cpp-config-has-zero-percentage records: ipv4-cpp-config-has-zero-percentage: @@ -127,6 +136,7 @@ resolver_component_tests: expected_lb_policy: round_robin enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: ipv4-second-language-is-cpp records: ipv4-second-language-is-cpp: @@ -140,6 +150,7 @@ resolver_component_tests: expected_lb_policy: round_robin enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: ipv4-config-with-percentages records: ipv4-config-with-percentages: @@ -154,6 +165,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv4-target-has-backend-and-balancer records: _grpclb._tcp.srv-ipv4-target-has-backend-and-balancer: @@ -169,6 +181,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv6-target-has-backend-and-balancer records: _grpclb._tcp.srv-ipv6-target-has-backend-and-balancer: @@ -183,6 +196,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: true enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: ipv4-config-causing-fallback-to-tcp records: ipv4-config-causing-fallback-to-tcp: @@ -197,6 +211,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: false enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv4-single-target-srv-disabled records: _grpclb._tcp.srv-ipv4-single-target-srv-disabled: @@ -213,6 +228,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: false enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv4-multi-target-srv-disabled records: _grpclb._tcp.srv-ipv4-multi-target-srv-disabled: @@ -231,6 +247,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: false enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv6-single-target-srv-disabled records: _grpclb._tcp.srv-ipv6-single-target-srv-disabled: @@ -247,6 +264,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: false enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv6-multi-target-srv-disabled records: _grpclb._tcp.srv-ipv6-multi-target-srv-disabled: @@ -265,6 +283,7 @@ resolver_component_tests: expected_lb_policy: round_robin enable_srv_queries: false enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv4-simple-service-config-srv-disabled records: _grpclb._tcp.srv-ipv4-simple-service-config-srv-disabled: @@ -282,6 +301,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: true enable_txt_queries: false + inject_broken_nameserver_list: false record_to_resolve: srv-ipv4-simple-service-config-txt-disabled records: _grpclb._tcp.srv-ipv4-simple-service-config-txt-disabled: @@ -297,6 +317,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: true enable_txt_queries: false + inject_broken_nameserver_list: false record_to_resolve: ipv4-cpp-config-has-zero-percentage-txt-disabled records: ipv4-cpp-config-has-zero-percentage-txt-disabled: @@ -310,6 +331,7 @@ resolver_component_tests: expected_lb_policy: null enable_srv_queries: true enable_txt_queries: false + inject_broken_nameserver_list: false record_to_resolve: ipv4-second-language-is-cpp-txt-disabled records: ipv4-second-language-is-cpp-txt-disabled: @@ -317,3 +339,29 @@ resolver_component_tests: _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} +# Tests for which we also exercise the resolver's ability to skip past a broken DNS server in its nameserver list +- expected_addrs: + - {address: '5.5.5.5:443', is_balancer: false} + expected_chosen_service_config: null + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: true + record_to_resolve: no-srv-ipv4-single-target-inject-broken-nameservers + records: + no-srv-ipv4-single-target-inject-broken-nameservers: + - {TTL: '2100', data: 5.5.5.5, type: A} +- expected_addrs: + - {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 + enable_txt_queries: true + inject_broken_nameserver_list: true + record_to_resolve: ipv4-config-causing-fallback-to-tcp-inject-broken-nameservers + records: + ipv4-config-causing-fallback-to-tcp-inject-broken-nameservers: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-config-causing-fallback-to-tcp-inject-broken-nameservers: + - {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} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a24c76c9042..242f6677d6a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -6014,6 +6014,7 @@ }, { "deps": [ + "dns_test_util", "gpr", "grpc++_test_config", "grpc++_test_util_unsecure", @@ -6033,6 +6034,7 @@ }, { "deps": [ + "dns_test_util", "gpr", "grpc", "grpc++", @@ -6128,6 +6130,7 @@ }, { "deps": [ + "dns_test_util", "gpr", "grpc", "grpc++", @@ -6603,6 +6606,21 @@ "third_party": false, "type": "lib" }, + { + "deps": [], + "headers": [ + "test/cpp/naming/dns_test_util.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "dns_test_util", + "src": [ + "test/cpp/naming/dns_test_util.cc", + "test/cpp/naming/dns_test_util.h" + ], + "third_party": false, + "type": "lib" + }, { "deps": [ "gpr", From 3fc702510faa1f201ea4f1e1a86ea2e60a89ee69 Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Wed, 8 May 2019 10:15:43 -0700 Subject: [PATCH 2111/2143] Reuse reactor to send new RPC --- .../callback_streaming_ping_pong.h | 11 +--- .../microbenchmarks/callback_test_service.h | 50 +++++++++---------- 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h index 7861aa67780..af2db947800 100644 --- a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -51,15 +51,8 @@ static void BM_CallbackBidiStreaming(benchmark::State& state) { } if (state.KeepRunning()) { GPR_TIMER_SCOPE("BenchmarkCycle", 0); - std::mutex mu; - std::condition_variable cv; - bool done = false; - BidiClient test{&state, stub_.get(), &request, &response, &mu, &cv, &done}; - test.StartNewRpc(); - std::unique_lock l(mu); - while (!done) { - cv.wait(l); - } + BidiClient test{&state, stub_.get(), &request, &response}; + test.Await(); } fixture->Finish(state); fixture.reset(); diff --git a/test/cpp/microbenchmarks/callback_test_service.h b/test/cpp/microbenchmarks/callback_test_service.h index 0d371c4c740..b7b76fd806c 100644 --- a/test/cpp/microbenchmarks/callback_test_service.h +++ b/test/cpp/microbenchmarks/callback_test_service.h @@ -49,17 +49,11 @@ class BidiClient : public grpc::experimental::ClientBidiReactor { public: BidiClient(benchmark::State* state, EchoTestService::Stub* stub, - EchoRequest* request, EchoResponse* response, std::mutex* mu, - std::condition_variable* cv, bool* done) - : state_{state}, - stub_{stub}, - request_{request}, - response_{response}, - mu_{mu}, - cv_{cv}, - done_(done) { + EchoRequest* request, EchoResponse* response) + : state_{state}, stub_{stub}, request_{request}, response_{response} { msgs_size_ = state->range(0); msgs_to_send_ = state->range(1); + StartNewRpc(); } void OnReadDone(bool ok) override { @@ -82,27 +76,33 @@ class BidiClient void OnDone(const Status& s) override { GPR_ASSERT(s.ok()); if (state_->KeepRunning()) { - BidiClient* test = - new BidiClient(state_, stub_, request_, response_, mu_, cv_, done_); - test->StartNewRpc(); + writes_complete_ = 0; + StartNewRpc(); } else { - std::unique_lock l(*mu_); - *done_ = true; - cv_->notify_one(); + std::unique_lock l(mu); + done = true; + cv.notify_one(); } - delete cli_ctx_; } void StartNewRpc() { - cli_ctx_ = new ClientContext(); - cli_ctx_->AddMetadata(kServerFinishAfterNReads, - grpc::to_string(msgs_to_send_)); - cli_ctx_->AddMetadata(kServerMessageSize, grpc::to_string(msgs_size_)); - stub_->experimental_async()->BidiStream(cli_ctx_, this); + cli_ctx_.reset(new ClientContext); + cli_ctx_.get()->AddMetadata(kServerFinishAfterNReads, + grpc::to_string(msgs_to_send_)); + cli_ctx_.get()->AddMetadata(kServerMessageSize, + grpc::to_string(msgs_size_)); + stub_->experimental_async()->BidiStream(cli_ctx_.get(), this); MaybeWrite(); StartCall(); } + void Await() { + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } + } + private: void MaybeWrite() { if (writes_complete_ < msgs_to_send_) { @@ -112,7 +112,7 @@ class BidiClient } } - ClientContext* cli_ctx_; + std::unique_ptr cli_ctx_; benchmark::State* state_; EchoTestService::Stub* stub_; EchoRequest* request_; @@ -120,9 +120,9 @@ class BidiClient int writes_complete_{0}; int msgs_to_send_; int msgs_size_; - std::mutex* mu_; - std::condition_variable* cv_; - bool* done_; + std::mutex mu; + std::condition_variable cv; + bool done; }; } // namespace testing From abfe14e3ed9b4ab7326fe437359fa9b167d010ac Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 8 May 2019 10:44:56 -0700 Subject: [PATCH 2112/2143] Reviewer comments --- .../filters/client_channel/client_channel.cc | 63 ++++++++++++------- .../resolver/dns/c_ares/dns_resolver_ares.cc | 7 +-- .../client_channel/resolving_lb_policy.cc | 1 - .../client_channel/resolving_lb_policy.h | 3 + 4 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 5d5436b8f67..99066e4e82c 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -273,6 +273,7 @@ class ChannelData { ExternalConnectivityWatcher::WatcherList external_connectivity_watcher_list_; UniquePtr health_check_service_name_; RefCountedPtr saved_service_config_; + bool set_service_config_ = false; // // Fields accessed from both data plane and control plane combiners. @@ -1077,6 +1078,8 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) // Get default service config const char* service_config_json = grpc_channel_arg_get_string( grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG)); + // Make sure we set the channel in TRANSIENT_FAILURE on an invalid default + // service config if (service_config_json != nullptr) { *error = GRPC_ERROR_NONE; default_service_config_ = ServiceConfig::Create(service_config_json, error); @@ -1155,23 +1158,25 @@ void ChannelData::ProcessLbPolicy( // Prefer the LB policy name found in the service config. if (parsed_object != nullptr) { if (parsed_object->parsed_lb_config() != nullptr) { - (*lb_policy_name) - .reset(gpr_strdup(parsed_object->parsed_lb_config()->name())); + lb_policy_name->reset( + gpr_strdup(parsed_object->parsed_lb_config()->name())); *lb_policy_config = parsed_object->parsed_lb_config(); - } else { - (*lb_policy_name) - .reset(gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); + return; + } else if (parsed_object->parsed_deprecated_lb_policy() != nullptr) { + lb_policy_name->reset( + gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); } } // 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.args, GRPC_ARG_LB_POLICY_NAME); - (*lb_policy_name) - .reset(gpr_strdup(grpc_channel_arg_get_string(channel_arg))); + 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. + // TODO(yashkt) : Test that we do not use this special case if the we have set + // the lb policy from the loadBalancingConfig field bool found_balancer_address = false; for (size_t i = 0; i < resolver_result.addresses.size(); ++i) { const ServerAddress& address = resolver_result.addresses[i]; @@ -1182,18 +1187,18 @@ void ChannelData::ProcessLbPolicy( } if (found_balancer_address) { if (*lb_policy_name != nullptr && - strcmp((*lb_policy_name).get(), "grpclb") != 0) { + 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->get()); } - (*lb_policy_name).reset(gpr_strdup("grpclb")); + lb_policy_name->reset(gpr_strdup("grpclb")); } // Use pick_first if nothing was specified and we didn't select grpclb // above. if (*lb_policy_name == nullptr) { - (*lb_policy_name).reset(gpr_strdup("pick_first")); + lb_policy_name->reset(gpr_strdup("pick_first")); } } @@ -1239,23 +1244,33 @@ bool ChannelData::ProcessResolverResultLocked( internal::ClientChannelServiceConfigParser::ParserIndex())); service_config_json = gpr_strdup(service_config->service_config_json()); } - bool service_config_changed = service_config != chand->saved_service_config_; + bool service_config_changed = + ((service_config == nullptr) != + (chand->saved_service_config_ == nullptr)) || + (service_config != nullptr && + strcmp(service_config->service_config_json(), + chand->saved_service_config_->service_config_json()) != 0); if (service_config_changed) { chand->saved_service_config_ = std::move(service_config); + if (parsed_object != nullptr) { + chand->health_check_service_name_.reset( + gpr_strdup(parsed_object->health_check_service_name())); + } else { + chand->health_check_service_name_.reset(); + } } - Optional - retry_throttle_data; - if (parsed_object != nullptr) { - chand->health_check_service_name_.reset( - gpr_strdup(parsed_object->health_check_service_name())); - retry_throttle_data = parsed_object->retry_throttling(); - } else { - chand->health_check_service_name_.reset(); + if (service_config_changed || !chand->set_service_config_) { + chand->set_service_config_ = true; + Optional + retry_throttle_data; + if (parsed_object != nullptr) { + retry_throttle_data = parsed_object->retry_throttling(); + } + // Create service config setter to update channel state in the data + // plane combiner. Destroys itself when done. + New(chand, retry_throttle_data, + chand->saved_service_config_); } - // Create service config setter to update channel state in the data - // plane combiner. Destroys itself when done. - New(chand, retry_throttle_data, - chand->saved_service_config_); UniquePtr processed_lb_policy_name; chand->ProcessLbPolicy(result, parsed_object, &processed_lb_policy_name, lb_policy_config); 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 25ce81b3692..77adc475bc2 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 @@ -309,14 +309,13 @@ char* ChooseServiceConfig(char* service_config_choice_json, } } grpc_json_destroy(choices_json); - if (error_list.empty()) { - return service_config; - } else { + if (!error_list.empty()) { gpr_free(service_config); + service_config = nullptr; *error = GRPC_ERROR_CREATE_FROM_VECTOR("Service Config Choices Parser", &error_list); - return nullptr; } + return service_config; } void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { 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 4824f4e22c3..35862f89d9c 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -554,7 +554,6 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( lb_policy_config = child_lb_config_; } if (lb_policy_name != nullptr) { - gpr_log(GPR_ERROR, "%s", lb_policy_name); // Create or update LB policy, as needed. CreateOrUpdateLbPolicyLocked(lb_policy_name, lb_policy_config, std::move(result), &trace_strings); 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 fa609aac5f2..b7d99dcc7de 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -65,6 +65,9 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // 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. + // If the returned service_config_error is not none and lb_policy_name is + // empty, it means that we don't have a valid service config to use, and we + // should set the channel to be in TRANSIENT_FAILURE. typedef bool (*ProcessResolverResultCallback)( void* user_data, const Resolver::Result& result, const char** lb_policy_name, From 40b6123d1498468033ddcdbe324c38ec56e93e19 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 8 May 2019 10:53:26 -0700 Subject: [PATCH 2113/2143] Fix TODOs --- src/core/ext/filters/client_channel/client_channel.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 99066e4e82c..787fe2f4750 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1078,8 +1078,8 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) // Get default service config const char* service_config_json = grpc_channel_arg_get_string( grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG)); - // Make sure we set the channel in TRANSIENT_FAILURE on an invalid default - // service config + // TODO(yashkt): Make sure we set the channel in TRANSIENT_FAILURE on an + // invalid default service config if (service_config_json != nullptr) { *error = GRPC_ERROR_NONE; default_service_config_ = ServiceConfig::Create(service_config_json, error); @@ -1175,7 +1175,7 @@ void ChannelData::ProcessLbPolicy( } // Special case: If at least one balancer address is present, we use // the grpclb policy, regardless of what the resolver has returned. - // TODO(yashkt) : Test that we do not use this special case if the we have set + // TODO(yashkt) : Test that we do not use this special case if we have set // the lb policy from the loadBalancingConfig field bool found_balancer_address = false; for (size_t i = 0; i < resolver_result.addresses.size(); ++i) { From b6c7cb81f025426a02346ed32425999203aa65fb Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 8 May 2019 11:23:06 -0700 Subject: [PATCH 2114/2143] Fix resolver component test --- test/cpp/naming/resolver_component_test.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 7903f2a932f..7a0aa1c6fc2 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -249,8 +249,6 @@ void CheckServiceConfigResultLocked(const char* service_config_json, if (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_json == nullptr); } if (args->expected_service_config_error == "") { EXPECT_EQ(service_config_error, GRPC_ERROR_NONE); From b53465c1061c9fd31e168046a1a0ac26c13da130 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 8 May 2019 14:27:58 -0700 Subject: [PATCH 2115/2143] Add test for not special casing grpclb if loadbalancingconfig is used --- .../filters/client_channel/client_channel.cc | 116 ++++++++++-------- .../lb_policy/subchannel_list.h | 4 +- test/cpp/end2end/grpclb_end2end_test.cc | 32 +++++ 3 files changed, 102 insertions(+), 50 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 787fe2f4750..1dc6ac48d57 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1156,49 +1156,47 @@ void ChannelData::ProcessLbPolicy( UniquePtr* lb_policy_name, RefCountedPtr* lb_policy_config) { // Prefer the LB policy name found in the service config. - if (parsed_object != nullptr) { - if (parsed_object->parsed_lb_config() != nullptr) { - lb_policy_name->reset( - gpr_strdup(parsed_object->parsed_lb_config()->name())); - *lb_policy_config = parsed_object->parsed_lb_config(); - return; - } else if (parsed_object->parsed_deprecated_lb_policy() != nullptr) { - lb_policy_name->reset( - gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); + if (parsed_object != nullptr && + parsed_object->parsed_lb_config() != nullptr) { + lb_policy_name->reset( + gpr_strdup(parsed_object->parsed_lb_config()->name())); + *lb_policy_config = parsed_object->parsed_lb_config(); + } else { + const char* local_policy_name = nullptr; + if (parsed_object != nullptr && + parsed_object->parsed_deprecated_lb_policy() != nullptr) { + local_policy_name = parsed_object->parsed_deprecated_lb_policy(); + } else { + const grpc_arg* channel_arg = + grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME); + local_policy_name = grpc_channel_arg_get_string(channel_arg); } - } - // 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.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. - // TODO(yashkt) : Test that we do not use this special case if we have set - // the lb policy from the loadBalancingConfig field - 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; + // Special case: If at least one balancer address is present, we use + // the grpclb policy, regardless of what the resolver has returned. + 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()); + if (found_balancer_address) { + if (local_policy_name != nullptr && + strcmp(local_policy_name, "grpclb") != 0) { + gpr_log(GPR_INFO, + "resolver requested LB policy %s but provided at least one " + "balancer address -- forcing use of grpclb LB policy", + local_policy_name); + } + local_policy_name = "grpclb"; } - lb_policy_name->reset(gpr_strdup("grpclb")); - } - // Use pick_first if nothing was specified and we didn't select grpclb - // above. - if (*lb_policy_name == nullptr) { - lb_policy_name->reset(gpr_strdup("pick_first")); + // Use pick_first if nothing was specified and we didn't select grpclb + // above. + if (local_policy_name == nullptr) { + local_policy_name = "pick_first"; + } + lb_policy_name->reset(gpr_strdup(local_policy_name)); } } @@ -1218,11 +1216,28 @@ bool ChannelData::ProcessResolverResultLocked( // API if (chand->saved_service_config_ != nullptr) { service_config = chand->saved_service_config_; + if (grpc_client_channel_routing_trace.enabled()) { + gpr_log(GPR_INFO, + "chand=%p: resolver returned invalid service config. " + "Continuing to use previous service config.", + chand); + } } else if (chand->default_service_config_ != nullptr) { + if (grpc_client_channel_routing_trace.enabled()) { + gpr_log(GPR_INFO, + "chand=%p: resolver returned invalid service config. Using " + "default service config provided by client API.", + chand); + } service_config = chand->default_service_config_; } } else if (result.service_config == nullptr) { - // We got no service config. Fallback to default service config + if (grpc_client_channel_routing_trace.enabled()) { + gpr_log(GPR_INFO, + "chand=%p: resolver returned no service config. Using default " + "service config provided by client API.", + chand); + } if (chand->default_service_config_ != nullptr) { service_config = chand->default_service_config_; } @@ -1234,7 +1249,7 @@ bool ChannelData::ProcessResolverResultLocked( result.service_config_error != GRPC_ERROR_NONE) { return false; } - char* service_config_json = nullptr; + UniquePtr service_config_json = nullptr; // Process service config. const internal::ClientChannelGlobalParsedObject* parsed_object = nullptr; if (service_config != nullptr) { @@ -1242,15 +1257,20 @@ bool ChannelData::ProcessResolverResultLocked( static_cast( service_config->GetParsedGlobalServiceConfigObject( internal::ClientChannelServiceConfigParser::ParserIndex())); - service_config_json = gpr_strdup(service_config->service_config_json()); } - bool service_config_changed = + const bool service_config_changed = ((service_config == nullptr) != (chand->saved_service_config_ == nullptr)) || (service_config != nullptr && strcmp(service_config->service_config_json(), chand->saved_service_config_->service_config_json()) != 0); if (service_config_changed) { + service_config_json.reset( + gpr_strdup(service_config->service_config_json())); + if (grpc_client_channel_routing_trace.enabled()) { + gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", + chand, service_config_json.get()); + } chand->saved_service_config_ = std::move(service_config); if (parsed_object != nullptr) { chand->health_check_service_name_.reset( @@ -1274,15 +1294,13 @@ bool ChannelData::ProcessResolverResultLocked( UniquePtr processed_lb_policy_name; chand->ProcessLbPolicy(result, parsed_object, &processed_lb_policy_name, lb_policy_config); - if (grpc_client_channel_routing_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", - chand, service_config_json); - } // Swap out the data used by GetChannelInfo(). { MutexLock lock(&chand->info_mu_); chand->info_lb_policy_name_ = std::move(processed_lb_policy_name); - chand->info_service_config_json_.reset(service_config_json); + if (service_config_json != nullptr) { + chand->info_service_config_json_ = std::move(service_config_json); + } } // Return results. *lb_policy_name = chand->info_lb_policy_name_.get(); 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 004ee04459b..c222985cf18 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 @@ -506,7 +506,9 @@ SubchannelList::SubchannelList( GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. for (size_t i = 0; i < addresses.size(); i++) { - GPR_ASSERT(!addresses[i].IsBalancer()); + if (addresses[i].IsBalancer()) { + continue; + } InlinedVector args_to_add; const size_t subchannel_address_arg_index = args_to_add.size(); args_to_add.emplace_back( diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 5e0faf0265a..3ac28ec7e43 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -737,6 +737,38 @@ TEST_F(SingleBalancerTest, SelectGrpclbWithMigrationServiceConfig) { EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } +TEST_F(SingleBalancerTest, + DoNotSpecialCaseUseGrpclbWithLoadBalancingConfigTest1) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + SetNextResolution({AddressData{backends_[0]->port_, false, ""}, + AddressData{balancers_[0]->port_, true, ""}}, + "{\n" + " \"loadBalancingConfig\":[\n" + " {\"pick_first\":{} }\n" + " ]\n" + "}"); + CheckRpcSendOk(); + // Check LB policy name for the channel. + EXPECT_EQ("pick_first", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, + DoNotSpecialCaseUseGrpclbWithLoadBalancingConfigTest2) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + SetNextResolution({AddressData{balancers_[0]->port_, true, ""}}, + "{\n" + " \"loadBalancingConfig\":[\n" + " {\"pick_first\":{} }\n" + " ]\n" + "}"); + // This should fail since we do not have a non-balancer backend + CheckRpcSendFailure(); + // Check LB policy name for the channel. + EXPECT_EQ("pick_first", channel_->GetLoadBalancingPolicyName()); +} + TEST_F(SingleBalancerTest, SelectGrpclbWithMigrationServiceConfigAndNoAddresses) { const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); From 3c4e8a9be2a7900580e52b00cdea4f0f7f0a40a9 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 8 May 2019 15:46:32 -0700 Subject: [PATCH 2116/2143] Fix test failure --- src/core/ext/filters/client_channel/client_channel.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 1dc6ac48d57..9144df93c12 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1265,8 +1265,12 @@ bool ChannelData::ProcessResolverResultLocked( strcmp(service_config->service_config_json(), chand->saved_service_config_->service_config_json()) != 0); if (service_config_changed) { - service_config_json.reset( - gpr_strdup(service_config->service_config_json())); + if (service_config != nullptr) { + service_config_json.reset( + gpr_strdup(service_config->service_config_json())); + } else { + service_config_json.reset(gpr_strdup("")); + } if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", chand, service_config_json.get()); From 070902b871ea7c7149f9746bb2464da5e5dc94cf Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Wed, 8 May 2019 15:51:58 -0700 Subject: [PATCH 2117/2143] Merge bm_callback_cq to bm_cq --- CMakeLists.txt | 62 +---- Makefile | 81 ++----- build.yaml | 29 +-- grpc.gyp | 2 +- test/cpp/microbenchmarks/BUILD | 11 - test/cpp/microbenchmarks/bm_callback_cq.cc | 226 ------------------ test/cpp/microbenchmarks/bm_cq.cc | 50 ++++ .../generated/sources_and_headers.json | 27 +-- tools/run_tests/generated/tests.json | 26 -- 9 files changed, 80 insertions(+), 434 deletions(-) delete mode 100644 test/cpp/microbenchmarks/bm_callback_cq.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 3de0e88adfc..cd2f91c0e3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -556,9 +556,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_call_create) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_dependencies(buildtests_cxx bm_callback_cq) -endif() -if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_callback_streaming_ping_pong) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -2918,7 +2915,7 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if (gRPC_BUILD_CODEGEN) -add_library(callback_test_service +add_library(bm_callback_test_service_impl ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h @@ -2928,11 +2925,11 @@ add_library(callback_test_service ) if(WIN32 AND MSVC) - set_target_properties(callback_test_service PROPERTIES COMPILE_PDB_NAME "callback_test_service" + set_target_properties(bm_callback_test_service_impl PROPERTIES COMPILE_PDB_NAME "bm_callback_test_service_impl" COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" ) if (gRPC_INSTALL) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/callback_test_service.pdb + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/bm_callback_test_service_impl.pdb DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL ) endif() @@ -2942,7 +2939,7 @@ protobuf_generate_grpc_cpp( src/proto/grpc/testing/echo.proto ) -target_include_directories(callback_test_service +target_include_directories(bm_callback_test_service_impl PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${_gRPC_SSL_INCLUDE_DIR} @@ -2959,7 +2956,7 @@ target_include_directories(callback_test_service PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) -target_link_libraries(callback_test_service +target_link_libraries(bm_callback_test_service_impl ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} grpc_benchmark @@ -11567,51 +11564,6 @@ target_link_libraries(bm_call_create ) -endif() -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) -if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - -add_executable(bm_callback_cq - test/cpp/microbenchmarks/bm_callback_cq.cc - third_party/googletest/googletest/src/gtest-all.cc - third_party/googletest/googlemock/src/gmock-all.cc -) - - -target_include_directories(bm_callback_cq - 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_callback_cq - ${_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) @@ -11653,7 +11605,7 @@ target_link_libraries(bm_callback_streaming_ping_pong grpc_unsecure gpr grpc++_test_config - callback_test_service + bm_callback_test_service_impl ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11699,7 +11651,7 @@ target_link_libraries(bm_callback_unary_ping_pong grpc_unsecure gpr grpc++_test_config - callback_test_service + bm_callback_test_service_impl ${_gRPC_GFLAGS_LIBRARIES} ) diff --git a/Makefile b/Makefile index 42598797bd9..e2451d573c4 100644 --- a/Makefile +++ b/Makefile @@ -1162,7 +1162,6 @@ 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 -bm_callback_cq: $(BINDIR)/$(CONFIG)/bm_callback_cq bm_callback_streaming_ping_pong: $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong bm_callback_unary_ping_pong: $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong bm_channel: $(BINDIR)/$(CONFIG)/bm_channel @@ -1643,7 +1642,6 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_arena \ $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ - $(BINDIR)/$(CONFIG)/bm_callback_cq \ $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong \ $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_channel \ @@ -1792,7 +1790,6 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_arena \ $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ - $(BINDIR)/$(CONFIG)/bm_callback_cq \ $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong \ $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_channel \ @@ -2247,8 +2244,6 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/bm_byte_buffer || ( echo test bm_byte_buffer failed ; exit 1 ) $(E) "[RUN] Testing bm_call_create" $(Q) $(BINDIR)/$(CONFIG)/bm_call_create || ( echo test bm_call_create failed ; exit 1 ) - $(E) "[RUN] Testing bm_callback_cq" - $(Q) $(BINDIR)/$(CONFIG)/bm_callback_cq || ( echo test bm_callback_cq failed ; exit 1 ) $(E) "[RUN] Testing bm_callback_streaming_ping_pong" $(Q) $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong || ( echo test bm_callback_streaming_ping_pong failed ; exit 1 ) $(E) "[RUN] Testing bm_callback_unary_ping_pong" @@ -5305,21 +5300,21 @@ endif endif -LIBCALLBACK_TEST_SERVICE_SRC = \ +LIBBM_CALLBACK_TEST_SERVICE_IMPL_SRC = \ $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \ test/cpp/microbenchmarks/callback_test_service.cc \ PUBLIC_HEADERS_CXX += \ -LIBCALLBACK_TEST_SERVICE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBCALLBACK_TEST_SERVICE_SRC)))) +LIBBM_CALLBACK_TEST_SERVICE_IMPL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBM_CALLBACK_TEST_SERVICE_IMPL_SRC)))) -$(LIBCALLBACK_TEST_SERVICE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(LIBBM_CALLBACK_TEST_SERVICE_IMPL_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX ifeq ($(NO_SECURE),true) # You can't build secure libraries if you don't have OpenSSL. -$(LIBDIR)/$(CONFIG)/libcallback_test_service.a: openssl_dep_error +$(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a: openssl_dep_error else @@ -5328,18 +5323,18 @@ 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)/libcallback_test_service.a: protobuf_dep_error +$(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a: protobuf_dep_error else -$(LIBDIR)/$(CONFIG)/libcallback_test_service.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBCALLBACK_TEST_SERVICE_OBJS) +$(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBM_CALLBACK_TEST_SERVICE_IMPL_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libcallback_test_service.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libcallback_test_service.a $(LIBCALLBACK_TEST_SERVICE_OBJS) + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a $(LIBBM_CALLBACK_TEST_SERVICE_IMPL_OBJS) ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libcallback_test_service.a + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a endif @@ -5351,7 +5346,7 @@ endif ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(LIBCALLBACK_TEST_SERVICE_OBJS:.o=.dep) +-include $(LIBBM_CALLBACK_TEST_SERVICE_IMPL_OBJS:.o=.dep) endif endif $(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/callback_test_service.o: $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc @@ -14500,50 +14495,6 @@ endif endif -BM_CALLBACK_CQ_SRC = \ - test/cpp/microbenchmarks/bm_callback_cq.cc \ - -BM_CALLBACK_CQ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CALLBACK_CQ_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/bm_callback_cq: 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_callback_cq: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/bm_callback_cq: $(PROTOBUF_DEP) $(BM_CALLBACK_CQ_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_CALLBACK_CQ_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_callback_cq - -endif - -endif - -$(BM_CALLBACK_CQ_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_callback_cq.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_callback_cq: $(BM_CALLBACK_CQ_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(BM_CALLBACK_CQ_OBJS:.o=.dep) -endif -endif - - BM_CALLBACK_STREAMING_PING_PONG_SRC = \ test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc \ @@ -14567,17 +14518,17 @@ $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong: $(PROTOBUF_DEP) $(BM_CALLBACK_STREAMING_PING_PONG_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 $(LIBDIR)/$(CONFIG)/libcallback_test_service.a +$(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong: $(PROTOBUF_DEP) $(BM_CALLBACK_STREAMING_PING_PONG_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 $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CALLBACK_STREAMING_PING_PONG_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 $(LIBDIR)/$(CONFIG)/libcallback_test_service.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong + $(Q) $(LDXX) $(LDFLAGS) $(BM_CALLBACK_STREAMING_PING_PONG_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 $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong endif endif $(BM_CALLBACK_STREAMING_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.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 $(LIBDIR)/$(CONFIG)/libcallback_test_service.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.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 $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a deps_bm_callback_streaming_ping_pong: $(BM_CALLBACK_STREAMING_PING_PONG_OBJS:.o=.dep) @@ -14611,17 +14562,17 @@ $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong: $(PROTOBUF_DEP) $(BM_CALLBACK_UNARY_PING_PONG_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 $(LIBDIR)/$(CONFIG)/libcallback_test_service.a +$(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong: $(PROTOBUF_DEP) $(BM_CALLBACK_UNARY_PING_PONG_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 $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CALLBACK_UNARY_PING_PONG_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 $(LIBDIR)/$(CONFIG)/libcallback_test_service.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong + $(Q) $(LDXX) $(LDFLAGS) $(BM_CALLBACK_UNARY_PING_PONG_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 $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong endif endif $(BM_CALLBACK_UNARY_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.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 $(LIBDIR)/$(CONFIG)/libcallback_test_service.a +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.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 $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a deps_bm_callback_unary_ping_pong: $(BM_CALLBACK_UNARY_PING_PONG_OBJS:.o=.dep) diff --git a/build.yaml b/build.yaml index a271a8bb52f..975fc4ed2c4 100644 --- a/build.yaml +++ b/build.yaml @@ -1677,7 +1677,7 @@ libs: - grpc_test_util - grpc - gpr -- name: callback_test_service +- name: bm_callback_test_service_impl build: test language: c++ headers: @@ -4054,29 +4054,6 @@ targets: - linux - posix uses_polling: false -- name: bm_callback_cq - build: test - language: c++ - src: - - test/cpp/microbenchmarks/bm_callback_cq.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 - excluded_poll_engines: - - poll - platforms: - - mac - - linux - - posix - timeout_seconds: 1200 - name: bm_callback_streaming_ping_pong build: test language: c++ @@ -4093,7 +4070,7 @@ targets: - grpc_unsecure - gpr - grpc++_test_config - - callback_test_service + - bm_callback_test_service_impl benchmark: true defaults: benchmark platforms: @@ -4116,7 +4093,7 @@ targets: - grpc_unsecure - gpr - grpc++_test_config - - callback_test_service + - bm_callback_test_service_impl benchmark: true defaults: benchmark platforms: diff --git a/grpc.gyp b/grpc.gyp index a625152979d..e693e762ba0 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1406,7 +1406,7 @@ ], }, { - 'target_name': 'callback_test_service', + 'target_name': 'bm_callback_test_service_impl', 'type': 'static_library', 'dependencies': [ 'grpc_benchmark', diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index e25f15161cb..dea835b716b 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -281,14 +281,3 @@ grpc_cc_binary( tags = ["no_windows"], deps = [":callback_streaming_ping_pong_h"], ) - -grpc_cc_binary( - name = "bm_callback_cq", - testonly = 1, - srcs = ["bm_callback_cq.cc"], - language = "C++", - deps = [ - ":helpers", - "//test/cpp/util:test_util", - ], -) diff --git a/test/cpp/microbenchmarks/bm_callback_cq.cc b/test/cpp/microbenchmarks/bm_callback_cq.cc deleted file mode 100644 index 307dfe4a911..00000000000 --- a/test/cpp/microbenchmarks/bm_callback_cq.cc +++ /dev/null @@ -1,226 +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. - * - */ - -/* 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" - -#include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/iomgr/iomgr.h" -#include "src/core/lib/surface/completion_queue.h" - -namespace grpc { -namespace testing { - -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_; -}; - -class ShutdownCallback : public grpc_experimental_completion_queue_functor { - public: - ShutdownCallback(bool* done) : done_(done) { - functor_run = &ShutdownCallback::Run; - } - ~ShutdownCallback() {} - static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { - *static_cast(cb)->done_ = static_cast(ok); - } - - private: - bool* done_; -}; - -/* helper for tests to shutdown correctly and tersely */ -static void shutdown_and_destroy(grpc_completion_queue* cc) { - grpc_completion_queue_shutdown(cc); - grpc_completion_queue_destroy(cc); -} - -static void do_nothing_end_completion(void* arg, grpc_cq_completion* c) {} - -static void BM_Callback_CQ_Default_Polling(benchmark::State& state) { - int tag_size = state.range(0); - grpc_completion_queue* cc; - void* tags[tag_size]; - grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)]; - - grpc_completion_queue_attributes attr; - unsigned i; - bool got_shutdown = false; - ShutdownCallback shutdown_cb(&got_shutdown); - - attr.version = 2; - attr.cq_completion_type = GRPC_CQ_CALLBACK; - attr.cq_shutdown_cb = &shutdown_cb; - while (state.KeepRunning()) { - int sumtags = 0; - int counter = 0; - { - // reset exec_ctx types - grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; - grpc_core::ExecCtx exec_ctx; - attr.cq_polling_type = GRPC_CQ_DEFAULT_POLLING; - cc = grpc_completion_queue_create( - grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); - - 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); - } - GPR_ASSERT(sumtags == counter); - GPR_ASSERT(got_shutdown); - got_shutdown = false; - } -} -BENCHMARK(BM_Callback_CQ_Default_Polling)->Range(1, 128 * 1024); - -static void BM_Callback_CQ_Non_Listening(benchmark::State& state) { - int tag_size = state.range(0); - grpc_completion_queue* cc; - void* tags[tag_size]; - grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)]; - grpc_completion_queue_attributes attr; - unsigned i; - bool got_shutdown = false; - ShutdownCallback shutdown_cb(&got_shutdown); - - attr.version = 2; - attr.cq_completion_type = GRPC_CQ_CALLBACK; - attr.cq_shutdown_cb = &shutdown_cb; - while (state.KeepRunning()) { - int sumtags = 0; - int counter = 0; - { - // reset exec_ctx types - grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; - grpc_core::ExecCtx exec_ctx; - attr.cq_polling_type = GRPC_CQ_NON_LISTENING; - cc = grpc_completion_queue_create( - grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); - - 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); - } - GPR_ASSERT(sumtags == counter); - GPR_ASSERT(got_shutdown); - got_shutdown = false; - } -} -BENCHMARK(BM_Callback_CQ_Non_Listening)->Range(1, 128 * 1024); - -static void BM_Callback_CQ_Non_Polling(benchmark::State& state) { - int tag_size = state.range(0); - grpc_completion_queue* cc; - void* tags[tag_size]; - grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)]; - grpc_completion_queue_attributes attr; - unsigned i; - bool got_shutdown = false; - ShutdownCallback shutdown_cb(&got_shutdown); - - attr.version = 2; - attr.cq_completion_type = GRPC_CQ_CALLBACK; - attr.cq_shutdown_cb = &shutdown_cb; - while (state.KeepRunning()) { - int sumtags = 0; - int counter = 0; - { - // reset exec_ctx types - grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; - grpc_core::ExecCtx exec_ctx; - attr.cq_polling_type = GRPC_CQ_DEFAULT_POLLING; - cc = grpc_completion_queue_create( - grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); - - 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); - } - GPR_ASSERT(sumtags == counter); - GPR_ASSERT(got_shutdown); - got_shutdown = false; - } -} -BENCHMARK(BM_Callback_CQ_Non_Polling)->Range(1, 128 * 1024); - -} // 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) { - LibraryInitializer libInit; - ::benchmark::Initialize(&argc, argv); - ::grpc::testing::InitTest(&argc, &argv, false); - benchmark::RunTheBenchmarksNamespaced(); - return 0; -} diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index 263314deb93..c72a526c5ef 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -144,6 +144,56 @@ static void BM_EmptyCore(benchmark::State& state) { } BENCHMARK(BM_EmptyCore); +// helper for tests to shutdown correctly and tersely +static void shutdown_and_destroy(grpc_completion_queue* cc) { + grpc_completion_queue_shutdown(cc); + grpc_completion_queue_destroy(cc); +} + +class TagCallback : public grpc_experimental_completion_queue_functor { + public: + TagCallback() { functor_run = &TagCallback::Run; } + ~TagCallback() {} + static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + GPR_ASSERT(static_cast(ok)); + }; +}; + +class ShutdownCallback : public grpc_experimental_completion_queue_functor { + public: + ShutdownCallback(bool* done) : done_(done) { + functor_run = &ShutdownCallback::Run; + } + ~ShutdownCallback() {} + static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + *static_cast(cb)->done_ = static_cast(ok); + } + + private: + bool* done_; +}; + +static void BM_Callback_CQ_Pass1Core(benchmark::State& state) { + TrackCounters track_counters; + TagCallback tag; + bool got_shutdown = false; + ShutdownCallback shutdown_cb(&got_shutdown); + grpc_completion_queue* cc = + grpc_completion_queue_create_for_callback(&shutdown_cb, nullptr); + while (state.KeepRunning()) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ExecCtx exec_ctx; + grpc_cq_completion completion; + GPR_ASSERT(grpc_cq_begin_op(cc, &tag)); + grpc_cq_end_op(cc, &tag, GRPC_ERROR_NONE, DoneWithCompletionOnStack, + nullptr, &completion); + } + shutdown_and_destroy(cc); + GPR_ASSERT(got_shutdown); + track_counters.Finish(state); +} +BENCHMARK(BM_Callback_CQ_Pass1Core); + } // namespace testing } // namespace grpc diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 35c8996c9e3..ad4004213f9 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -2779,28 +2779,7 @@ { "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_callback_cq", - "src": [ - "test/cpp/microbenchmarks/bm_callback_cq.cc" - ], - "third_party": false, - "type": "target" - }, - { - "deps": [ - "benchmark", - "callback_test_service", + "bm_callback_test_service_impl", "gpr", "grpc++_test_config", "grpc++_test_util_unsecure", @@ -2825,7 +2804,7 @@ { "deps": [ "benchmark", - "callback_test_service", + "bm_callback_test_service_impl", "gpr", "grpc++_test_config", "grpc++_test_util_unsecure", @@ -6693,7 +6672,7 @@ ], "is_filegroup": false, "language": "c++", - "name": "callback_test_service", + "name": "bm_callback_test_service_impl", "src": [ "test/cpp/microbenchmarks/callback_test_service.cc", "test/cpp/microbenchmarks/callback_test_service.h" diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index b3f8087042d..bed602361bb 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3479,32 +3479,6 @@ ], "uses_polling": false }, - { - "args": [], - "benchmark": true, - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "excluded_poll_engines": [ - "poll" - ], - "flaky": false, - "gtest": false, - "language": "c++", - "name": "bm_callback_cq", - "platforms": [ - "linux", - "mac", - "posix" - ], - "timeout_seconds": 1200, - "uses_polling": true - }, { "args": [], "benchmark": true, From 1984b3479795d66c3d87e7158b51fc0417b8cc7a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 8 May 2019 16:22:10 -0700 Subject: [PATCH 2118/2143] Try getting around clang tidy issue --- .../end2end/service_config_end2end_test.cc | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/cpp/end2end/service_config_end2end_test.cc b/test/cpp/end2end/service_config_end2end_test.cc index 9b259bd6342..2d05fd42635 100644 --- a/test/cpp/end2end/service_config_end2end_test.cc +++ b/test/cpp/end2end/service_config_end2end_test.cc @@ -222,8 +222,16 @@ class ServiceConfigEnd2endTest : public ::testing::Test { return grpc::testing::EchoTestService::NewStub(channel); } - std::shared_ptr BuildChannel( - ChannelArguments args = ChannelArguments()) { + std::shared_ptr BuildChannel() { + ChannelArguments args; + args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, + response_generator_.get()); + return ::grpc::CreateCustomChannel("fake:///", creds_, args); + } + + std::shared_ptr BuildChannelWithDefaultServiceConfig() { + ChannelArguments args; + args.SetServiceConfigJSON(ValidDefaultServiceConfig()); args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, response_generator_.get()); return ::grpc::CreateCustomChannel("fake:///", creds_, args); @@ -417,9 +425,7 @@ TEST_F(ServiceConfigEnd2endTest, NoServiceConfigTest) { TEST_F(ServiceConfigEnd2endTest, NoServiceConfigWithDefaultConfigTest) { StartServers(1); - ChannelArguments args; - args.SetServiceConfigJSON(ValidDefaultServiceConfig()); - auto channel = BuildChannel(args); + auto channel = BuildChannelWithDefaultServiceConfig(); auto stub = BuildStub(channel); SetNextResolutionNoServiceConfig(GetServersPorts()); CheckRpcSendOk(stub, DEBUG_LOCATION); @@ -437,9 +443,7 @@ TEST_F(ServiceConfigEnd2endTest, InvalidServiceConfigTest) { TEST_F(ServiceConfigEnd2endTest, InvalidServiceConfigWithDefaultConfigTest) { StartServers(1); - ChannelArguments args; - args.SetServiceConfigJSON(ValidDefaultServiceConfig()); - auto channel = BuildChannel(args); + auto channel = BuildChannelWithDefaultServiceConfig(); auto stub = BuildStub(channel); SetNextResolutionInvalidServiceConfig(GetServersPorts()); CheckRpcSendOk(stub, DEBUG_LOCATION); @@ -475,9 +479,7 @@ TEST_F(ServiceConfigEnd2endTest, TEST_F(ServiceConfigEnd2endTest, NoServiceConfigUpdateAfterValidServiceConfigWithDefaultConfigTest) { StartServers(1); - ChannelArguments args; - args.SetServiceConfigJSON(ValidDefaultServiceConfig()); - auto channel = BuildChannel(args); + auto channel = BuildChannelWithDefaultServiceConfig(); auto stub = BuildStub(channel); SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); CheckRpcSendOk(stub, DEBUG_LOCATION); @@ -504,9 +506,7 @@ TEST_F(ServiceConfigEnd2endTest, TEST_F(ServiceConfigEnd2endTest, InvalidServiceConfigUpdateAfterValidServiceConfigWithDefaultConfigTest) { StartServers(1); - ChannelArguments args; - args.SetServiceConfigJSON(ValidDefaultServiceConfig()); - auto channel = BuildChannel(args); + auto channel = BuildChannelWithDefaultServiceConfig(); auto stub = BuildStub(channel); SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); CheckRpcSendOk(stub, DEBUG_LOCATION); From 762e58b574686c4b9ba4e208ec6f9cf1c5ec88bc Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Wed, 8 May 2019 17:34:27 -0700 Subject: [PATCH 2119/2143] Change client context allocation --- .../microbenchmarks/callback_unary_ping_pong.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/test/cpp/microbenchmarks/callback_unary_ping_pong.h b/test/cpp/microbenchmarks/callback_unary_ping_pong.h index 804d2808a32..6078a77f78f 100644 --- a/test/cpp/microbenchmarks/callback_unary_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_unary_ping_pong.h @@ -37,26 +37,26 @@ namespace testing { */ // Send next rpc when callback function is evoked. -void SendCallbackUnaryPingPong(benchmark::State* state, EchoRequest* request, - EchoResponse* response, +void SendCallbackUnaryPingPong(benchmark::State* state, ClientContext* cli_ctx, + EchoRequest* request, EchoResponse* response, EchoTestService::Stub* stub_, bool* done, std::mutex* mu, std::condition_variable* cv) { int response_msgs_size = state->range(1); - ClientContext* cli_ctx = new ClientContext(); cli_ctx->AddMetadata(kServerMessageSize, grpc::to_string(response_msgs_size)); stub_->experimental_async()->Echo( cli_ctx, request, response, [state, cli_ctx, request, response, stub_, done, mu, cv](Status s) { GPR_ASSERT(s.ok()); if (state->KeepRunning()) { - SendCallbackUnaryPingPong(state, request, response, stub_, done, mu, - cv); + cli_ctx->~ClientContext(); + new (cli_ctx) ClientContext(); + SendCallbackUnaryPingPong(state, cli_ctx, request, response, stub_, + done, mu, cv); } else { std::lock_guard l(*mu); *done = true; cv->notify_one(); } - delete cli_ctx; }); }; @@ -70,6 +70,7 @@ static void BM_CallbackUnaryPingPong(benchmark::State& state) { EchoTestService::NewStub(fixture->channel())); EchoRequest request; EchoResponse response; + ClientContext cli_ctx; if (request_msgs_size > 0) { request.set_message(std::string(request_msgs_size, 'a')); @@ -82,7 +83,7 @@ static void BM_CallbackUnaryPingPong(benchmark::State& state) { bool done = false; if (state.KeepRunning()) { GPR_TIMER_SCOPE("BenchmarkCycle", 0); - SendCallbackUnaryPingPong(&state, &request, &response, stub_.get(), &done, + SendCallbackUnaryPingPong(&state, &cli_ctx, &request, &response, stub_.get(), &done, &mu, &cv); } std::unique_lock l(mu); From 569d33f49b52d62d22d934ccf620e322e1982b1a Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 8 May 2019 17:49:52 -0700 Subject: [PATCH 2120/2143] Add two more trace logs to the c-ares resolver --- .../client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc | 6 ++++++ 1 file changed, 6 insertions(+) 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 97ef61d2f33..e6845f74d44 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 @@ -154,6 +154,10 @@ void grpc_ares_complete_request_locked(grpc_ares_request* r) { static grpc_ares_hostbyname_request* create_hostbyname_request_locked( grpc_ares_request* parent_request, char* host, uint16_t port, bool is_balancer) { + GRPC_CARES_TRACE_LOG( + "request:%p create_hostbyname_request_locked host:%s port:%d " + "is_balancer:%d", + parent_request, host, port, is_balancer); grpc_ares_hostbyname_request* hr = static_cast( gpr_zalloc(sizeof(grpc_ares_hostbyname_request))); hr->parent_request = parent_request; @@ -251,6 +255,8 @@ static void on_srv_query_done_locked(void* arg, int status, int timeouts, 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); + GRPC_CARES_TRACE_LOG("request:%p ares_parse_srv_reply: %d", r, + parse_status); if (parse_status == ARES_SUCCESS) { ares_channel* channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver); From 360e501db21abae4b77f27dae9e3f5827c3bdfca Mon Sep 17 00:00:00 2001 From: Daniel Alm Date: Tue, 30 Apr 2019 14:17:35 +0200 Subject: [PATCH 2121/2143] Add `void` arguments to two function declarations. --- include/grpc/grpc_security.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 53189097b9b..d0b2be9e25e 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -641,7 +641,7 @@ 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(); +GRPCAPI grpc_tls_credentials_options* grpc_tls_credentials_options_create(void); /** Set grpc_ssl_client_certificate_request_type field in credentials options with the provided type. options should not be NULL. @@ -683,7 +683,7 @@ GRPCAPI int grpc_tls_credentials_options_set_server_authorization_check_config( /** 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(); +GRPCAPI grpc_tls_key_materials_config* grpc_tls_key_materials_config_create(void); /** 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. From cb8c4afdea4a791ee5dfd4621a386311625a22b0 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 1 May 2019 22:45:21 -0700 Subject: [PATCH 2122/2143] Resolve consistency checks --- include/grpc/grpc_security.h | 3 ++- src/ruby/ext/grpc/rb_grpc_imports.generated.h | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index d0b2be9e25e..ebdf86b7d50 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -683,7 +683,8 @@ GRPCAPI int grpc_tls_credentials_options_set_server_authorization_check_config( /** 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(void); +GRPCAPI grpc_tls_key_materials_config* grpc_tls_key_materials_config_create( + void); /** 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. diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 275ca6e9cbf..c25d789a95b 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -440,7 +440,7 @@ 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)(); +typedef grpc_tls_credentials_options*(*grpc_tls_credentials_options_create_type)(void); 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); @@ -455,7 +455,7 @@ extern grpc_tls_credentials_options_set_credential_reload_config_type grpc_tls_c 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)(); +typedef grpc_tls_key_materials_config*(*grpc_tls_key_materials_config_create_type)(void); 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); From 98d8f85d4e99c1ace1e1883eaa4ac7c1435cf947 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 9 May 2019 10:58:00 -0700 Subject: [PATCH 2123/2143] Reviewer comments --- .../filters/client_channel/client_channel.cc | 25 +++++++++++-------- .../lb_policy/subchannel_list.h | 4 +++ test/cpp/end2end/grpclb_end2end_test.cc | 7 +++--- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 9144df93c12..3fdabda8c53 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -273,7 +273,7 @@ class ChannelData { ExternalConnectivityWatcher::WatcherList external_connectivity_watcher_list_; UniquePtr health_check_service_name_; RefCountedPtr saved_service_config_; - bool set_service_config_ = false; + bool received_first_resolver_result_ = false; // // Fields accessed from both data plane and control plane combiners. @@ -1249,7 +1249,7 @@ bool ChannelData::ProcessResolverResultLocked( result.service_config_error != GRPC_ERROR_NONE) { return false; } - UniquePtr service_config_json = nullptr; + UniquePtr service_config_json; // Process service config. const internal::ClientChannelGlobalParsedObject* parsed_object = nullptr; if (service_config != nullptr) { @@ -1265,14 +1265,12 @@ bool ChannelData::ProcessResolverResultLocked( strcmp(service_config->service_config_json(), chand->saved_service_config_->service_config_json()) != 0); if (service_config_changed) { - if (service_config != nullptr) { - service_config_json.reset( - gpr_strdup(service_config->service_config_json())); - } else { - service_config_json.reset(gpr_strdup("")); - } + service_config_json.reset(gpr_strdup( + service_config != nullptr ? service_config->service_config_json() + : "")); if (grpc_client_channel_routing_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", + gpr_log(GPR_INFO, + "chand=%p: resolver returned updated service config: \"%s\"", chand, service_config_json.get()); } chand->saved_service_config_ = std::move(service_config); @@ -1283,8 +1281,11 @@ bool ChannelData::ProcessResolverResultLocked( chand->health_check_service_name_.reset(); } } - if (service_config_changed || !chand->set_service_config_) { - chand->set_service_config_ = true; + // We want to set the service config atleast once. This should not really be + // needed, but we are doing it as a defensive approach. This can be removed, + // if we feel it is unnecessary. + if (service_config_changed || !chand->received_first_resolver_result_) { + chand->received_first_resolver_result_ = true; Optional retry_throttle_data; if (parsed_object != nullptr) { @@ -3029,6 +3030,8 @@ void CallData::AddSubchannelBatchesForPendingBatches( // If we're not retrying, just send the batch as-is. if (method_params_ == nullptr || method_params_->retry_policy() == nullptr || retry_committed_) { + // TODO(roth) : We should probably call + // MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy here. AddClosureForSubchannelBatch(elem, batch, closures); PendingBatchClear(pending); continue; 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 c222985cf18..be49fd02837 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 @@ -506,6 +506,10 @@ SubchannelList::SubchannelList( GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. for (size_t i = 0; i < addresses.size(); i++) { + // TODO(roth): we should ideally hide this from the LB policy code. In + // principle, if we're dealing with this special case in the client_channel + // code for selecting grpclb, then we should also strip out these addresses + // there if we're not using grpclb. if (addresses[i].IsBalancer()) { continue; } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 3ac28ec7e43..50b1383e7e1 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -738,7 +738,7 @@ TEST_F(SingleBalancerTest, SelectGrpclbWithMigrationServiceConfig) { } TEST_F(SingleBalancerTest, - DoNotSpecialCaseUseGrpclbWithLoadBalancingConfigTest1) { + DoNotSpecialCaseUseGrpclbWithLoadBalancingConfigTest) { const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); ResetStub(kFallbackTimeoutMs); SetNextResolution({AddressData{backends_[0]->port_, false, ""}, @@ -753,8 +753,9 @@ TEST_F(SingleBalancerTest, EXPECT_EQ("pick_first", channel_->GetLoadBalancingPolicyName()); } -TEST_F(SingleBalancerTest, - DoNotSpecialCaseUseGrpclbWithLoadBalancingConfigTest2) { +TEST_F( + SingleBalancerTest, + DoNotSpecialCaseUseGrpclbWithLoadBalancingConfigTestAndNoBackendAddress) { const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); ResetStub(kFallbackTimeoutMs); SetNextResolution({AddressData{balancers_[0]->port_, true, ""}}, From 1ea651aee3b257e4073169f49e5b0b94388552e7 Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Thu, 9 May 2019 12:22:55 -0700 Subject: [PATCH 2124/2143] Add assertion --- test/cpp/microbenchmarks/BUILD | 1 - test/cpp/microbenchmarks/bm_cq.cc | 20 +++- .../callback_streaming_ping_pong.h | 95 ++++++++++++++++++- .../microbenchmarks/callback_test_service.cc | 3 + .../microbenchmarks/callback_test_service.h | 81 ---------------- .../callback_unary_ping_pong.h | 1 - 6 files changed, 110 insertions(+), 91 deletions(-) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index c42c5d53de9..d9424f24f16 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -230,7 +230,6 @@ grpc_cc_library( external_deps = [ "benchmark", ], - tags = ["no_windows"], deps = [ ":helpers", "//src/proto/grpc/testing:echo_proto", diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index c72a526c5ef..f4d02e2991b 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -144,21 +144,29 @@ static void BM_EmptyCore(benchmark::State& state) { } BENCHMARK(BM_EmptyCore); -// helper for tests to shutdown correctly and tersely +// Helper for tests to shutdown correctly and tersely static void shutdown_and_destroy(grpc_completion_queue* cc) { grpc_completion_queue_shutdown(cc); grpc_completion_queue_destroy(cc); } +// Tag completion queue iterate times class TagCallback : public grpc_experimental_completion_queue_functor { public: - TagCallback() { functor_run = &TagCallback::Run; } + TagCallback(int* iter) : iter_ (iter) { + functor_run = &TagCallback::Run; + } ~TagCallback() {} static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { GPR_ASSERT(static_cast(ok)); + *static_cast(cb)->iter_ += 1; }; + + private: + int* iter_; }; +// Check if completion queue is shut down class ShutdownCallback : public grpc_experimental_completion_queue_functor { public: ShutdownCallback(bool* done) : done_(done) { @@ -175,7 +183,8 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { static void BM_Callback_CQ_Pass1Core(benchmark::State& state) { TrackCounters track_counters; - TagCallback tag; + int iteration = 0; + TagCallback tag_cb(&iteration); bool got_shutdown = false; ShutdownCallback shutdown_cb(&got_shutdown); grpc_completion_queue* cc = @@ -184,12 +193,13 @@ static void BM_Callback_CQ_Pass1Core(benchmark::State& state) { grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; grpc_cq_completion completion; - GPR_ASSERT(grpc_cq_begin_op(cc, &tag)); - grpc_cq_end_op(cc, &tag, GRPC_ERROR_NONE, DoneWithCompletionOnStack, + GPR_ASSERT(grpc_cq_begin_op(cc, &tag_cb)); + grpc_cq_end_op(cc, &tag_cb, GRPC_ERROR_NONE, DoneWithCompletionOnStack, nullptr, &completion); } shutdown_and_destroy(cc); GPR_ASSERT(got_shutdown); + GPR_ASSERT(iteration == static_cast(state.iterations())); track_counters.Finish(state); } BENCHMARK(BM_Callback_CQ_Pass1Core); diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h index af2db947800..8f10fabc43b 100644 --- a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -34,16 +34,105 @@ namespace testing { * BENCHMARKING KERNELS */ +class BidiClient + : public grpc::experimental::ClientBidiReactor { + public: + BidiClient(benchmark::State* state, EchoTestService::Stub* stub, + ClientContext* cli_ctx, EchoRequest* request, + EchoResponse* response) + : state_{state}, + stub_{stub}, + cli_ctx_{cli_ctx}, + request_{request}, + response_{response} { + msgs_size_ = state->range(0); + msgs_to_send_ = state->range(1); + StartNewRpc(); + } + + void OnReadDone(bool ok) override { + if (!ok) { + gpr_log(GPR_ERROR, "Client read failed"); + return; + } + if (writes_complete_ < msgs_to_send_) { + MaybeWrite(); + } + } + + void OnWriteDone(bool ok) override { + if (!ok) { + gpr_log(GPR_ERROR, "Client write failed"); + return; + } + writes_complete_++; + StartRead(response_); + } + + void OnDone(const Status& s) override { + GPR_ASSERT(s.ok()); + GPR_ASSERT(writes_complete_ == msgs_to_send_); + if (state_->KeepRunning()) { + writes_complete_ = 0; + StartNewRpc(); + } else { + std::unique_lock l(mu); + done = true; + cv.notify_one(); + } + } + + void StartNewRpc() { + cli_ctx_->~ClientContext(); + new (cli_ctx_) ClientContext(); + cli_ctx_->AddMetadata(kServerFinishAfterNReads, + grpc::to_string(msgs_to_send_)); + cli_ctx_->AddMetadata(kServerMessageSize, grpc::to_string(msgs_size_)); + stub_->experimental_async()->BidiStream(cli_ctx_, this); + MaybeWrite(); + StartCall(); + } + + void Await() { + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } + } + + private: + void MaybeWrite() { + if (writes_complete_ < msgs_to_send_) { + StartWrite(request_); + } else { + StartWritesDone(); + } + } + + benchmark::State* state_; + EchoTestService::Stub* stub_; + ClientContext* cli_ctx_; + EchoRequest* request_; + EchoResponse* response_; + int writes_complete_{0}; + int msgs_to_send_; + int msgs_size_; + std::mutex mu; + std::condition_variable cv; + bool done; +}; + template static void BM_CallbackBidiStreaming(benchmark::State& state) { - const int message_size = state.range(0); - const int max_ping_pongs = state.range(1); + int message_size = state.range(0); + int max_ping_pongs = state.range(1); CallbackStreamingTestService service; std::unique_ptr fixture(new Fixture(&service)); std::unique_ptr stub_( EchoTestService::NewStub(fixture->channel())); EchoRequest request; EchoResponse response; + ClientContext cli_ctx; if (message_size > 0) { request.set_message(std::string(message_size, 'a')); } else { @@ -51,7 +140,7 @@ static void BM_CallbackBidiStreaming(benchmark::State& state) { } if (state.KeepRunning()) { GPR_TIMER_SCOPE("BenchmarkCycle", 0); - BidiClient test{&state, stub_.get(), &request, &response}; + BidiClient test{&state, stub_.get(), &cli_ctx, &request, &response}; test.Await(); } fixture->Finish(state); diff --git a/test/cpp/microbenchmarks/callback_test_service.cc b/test/cpp/microbenchmarks/callback_test_service.cc index 650e5372da7..2473dc5f31d 100644 --- a/test/cpp/microbenchmarks/callback_test_service.cc +++ b/test/cpp/microbenchmarks/callback_test_service.cc @@ -75,11 +75,13 @@ CallbackStreamingTestService::BidiStream() { } void OnDone() override { GPR_ASSERT(finished_); + GPR_ASSERT(num_msgs_read_ == server_write_last_); delete this; } void OnCancel() override {} void OnReadDone(bool ok) override { if (!ok) { + gpr_log(GPR_ERROR, "Server read failed"); return; } num_msgs_read_++; @@ -96,6 +98,7 @@ CallbackStreamingTestService::BidiStream() { } void OnWriteDone(bool ok) override { if (!ok) { + gpr_log(GPR_ERROR, "Server write failed"); return; } if (num_msgs_read_ < server_write_last_) { diff --git a/test/cpp/microbenchmarks/callback_test_service.h b/test/cpp/microbenchmarks/callback_test_service.h index b7b76fd806c..dd7977a5913 100644 --- a/test/cpp/microbenchmarks/callback_test_service.h +++ b/test/cpp/microbenchmarks/callback_test_service.h @@ -44,87 +44,6 @@ class CallbackStreamingTestService experimental::ServerBidiReactor* BidiStream() override; }; - -class BidiClient - : public grpc::experimental::ClientBidiReactor { - public: - BidiClient(benchmark::State* state, EchoTestService::Stub* stub, - EchoRequest* request, EchoResponse* response) - : state_{state}, stub_{stub}, request_{request}, response_{response} { - msgs_size_ = state->range(0); - msgs_to_send_ = state->range(1); - StartNewRpc(); - } - - void OnReadDone(bool ok) override { - if (!ok) { - return; - } - if (writes_complete_ < msgs_to_send_) { - MaybeWrite(); - } - } - - void OnWriteDone(bool ok) override { - if (!ok) { - return; - } - writes_complete_++; - StartRead(response_); - } - - void OnDone(const Status& s) override { - GPR_ASSERT(s.ok()); - if (state_->KeepRunning()) { - writes_complete_ = 0; - StartNewRpc(); - } else { - std::unique_lock l(mu); - done = true; - cv.notify_one(); - } - } - - void StartNewRpc() { - cli_ctx_.reset(new ClientContext); - cli_ctx_.get()->AddMetadata(kServerFinishAfterNReads, - grpc::to_string(msgs_to_send_)); - cli_ctx_.get()->AddMetadata(kServerMessageSize, - grpc::to_string(msgs_size_)); - stub_->experimental_async()->BidiStream(cli_ctx_.get(), this); - MaybeWrite(); - StartCall(); - } - - void Await() { - std::unique_lock l(mu); - while (!done) { - cv.wait(l); - } - } - - private: - void MaybeWrite() { - if (writes_complete_ < msgs_to_send_) { - StartWrite(request_); - } else { - StartWritesDone(); - } - } - - std::unique_ptr cli_ctx_; - benchmark::State* state_; - EchoTestService::Stub* stub_; - EchoRequest* request_; - EchoResponse* response_; - int writes_complete_{0}; - int msgs_to_send_; - int msgs_size_; - std::mutex mu; - std::condition_variable cv; - bool done; -}; - } // namespace testing } // namespace grpc #endif // TEST_CPP_MICROBENCHMARKS_CALLBACK_TEST_SERVICE_H diff --git a/test/cpp/microbenchmarks/callback_unary_ping_pong.h b/test/cpp/microbenchmarks/callback_unary_ping_pong.h index 9ba388b8876..359b91eb6fe 100644 --- a/test/cpp/microbenchmarks/callback_unary_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_unary_ping_pong.h @@ -36,7 +36,6 @@ namespace testing { * BENCHMARKING KERNELS */ -// Send next rpc when callback function is evoked. void SendCallbackUnaryPingPong(benchmark::State* state, ClientContext* cli_ctx, EchoRequest* request, EchoResponse* response, EchoTestService::Stub* stub_, bool* done, From a2daa4ff083a95cfefbcc2cfe2d3ea8936572f64 Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Thu, 9 May 2019 12:29:05 -0700 Subject: [PATCH 2125/2143] Clean format' --- test/cpp/microbenchmarks/bm_cq.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index f4d02e2991b..caa5e7d6d31 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -153,9 +153,7 @@ static void shutdown_and_destroy(grpc_completion_queue* cc) { // Tag completion queue iterate times class TagCallback : public grpc_experimental_completion_queue_functor { public: - TagCallback(int* iter) : iter_ (iter) { - functor_run = &TagCallback::Run; - } + TagCallback(int* iter) : iter_(iter) { functor_run = &TagCallback::Run; } ~TagCallback() {} static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { GPR_ASSERT(static_cast(ok)); From 87905ae5ead879a3baff731b3bed5408249beacd Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Thu, 9 May 2019 12:29:38 -0700 Subject: [PATCH 2126/2143] Config migration --- BUILD | 16 +++++++ BUILD.gn | 2 + CMakeLists.txt | 2 + Makefile | 2 + build.yaml | 9 ++++ config.m4 | 2 + config.w32 | 1 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 3 ++ grpc.gemspec | 2 + grpc.gyp | 2 + package.xml | 2 + .../interop/app/src/main/cpp/grpc-interop.cc | 6 +-- .../filters/client_channel/backup_poller.cc | 11 +++-- .../client_channel/http_connect_handshaker.cc | 1 - .../resolver/dns/c_ares/dns_resolver_ares.cc | 14 +++--- .../resolver/dns/dns_resolver_selection.cc | 28 ++++++++++++ .../resolver/dns/dns_resolver_selection.h | 29 ++++++++++++ .../resolver/dns/native/dns_resolver.cc | 8 ++-- .../chttp2/transport/chttp2_plugin.cc | 7 ++- src/core/lib/debug/trace.cc | 20 ++++++--- src/core/lib/debug/trace.h | 8 ++++ src/core/lib/gpr/env.h | 6 --- src/core/lib/gpr/env_linux.cc | 2 +- src/core/lib/gpr/env_windows.cc | 5 --- src/core/lib/gpr/log.cc | 22 ++++------ src/core/lib/gprpp/fork.cc | 41 +++++------------ src/core/lib/iomgr/ev_posix.cc | 26 ++++++----- src/core/lib/iomgr/ev_posix.h | 3 ++ src/core/lib/iomgr/fork_posix.cc | 1 - src/core/lib/iomgr/iomgr.cc | 3 +- src/core/lib/profiling/basic_timers.cc | 14 ++++-- .../load_system_roots_linux.cc | 12 ++--- .../security_connector/security_connector.cc | 1 - .../security/security_connector/ssl_utils.cc | 44 +++++++++++-------- .../security/security_connector/ssl_utils.h | 6 ++- src/core/lib/surface/init.cc | 2 +- .../private/GRPCSecureChannelFactory.m | 3 +- .../CoreCronetEnd2EndTests.mm | 4 +- src/python/grpcio/grpc_core_dependencies.py | 1 + test/core/bad_connection/close_fd_test.cc | 1 - test/core/bad_ssl/bad_ssl_test.cc | 4 +- .../resolvers/dns_resolver_test.cc | 8 ++-- test/core/end2end/fixtures/h2_full+trace.cc | 4 +- .../end2end/fixtures/h2_sockpair+trace.cc | 5 ++- test/core/end2end/fixtures/h2_spiffe.cc | 3 +- test/core/end2end/fixtures/h2_ssl.cc | 4 +- .../end2end/fixtures/h2_ssl_cred_reload.cc | 4 +- test/core/end2end/fixtures/h2_ssl_proxy.cc | 4 +- test/core/end2end/h2_ssl_cert_test.cc | 4 +- .../core/end2end/h2_ssl_session_reuse_test.cc | 4 +- test/core/end2end/tests/keepalive_timeout.cc | 14 +++--- test/core/gpr/log_test.cc | 13 ++++-- test/core/http/httpscli_test.cc | 3 +- test/core/iomgr/resolve_address_posix_test.cc | 18 ++++---- test/core/iomgr/resolve_address_test.cc | 13 +++--- test/core/security/credentials_test.cc | 2 +- test/core/security/security_connector_test.cc | 10 ++--- test/core/util/test_config.cc | 1 - test/cpp/end2end/async_end2end_test.cc | 12 +++-- test/cpp/end2end/end2end_test.cc | 12 +++-- test/cpp/naming/address_sorting_test.cc | 14 +++--- test/cpp/naming/cancel_ares_query_test.cc | 4 +- test/cpp/naming/resolver_component_test.cc | 1 - tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 24 +++++++++- tools/run_tests/run_microbenchmark.py | 2 +- .../run_tests/sanity/core_banned_functions.py | 4 -- 68 files changed, 358 insertions(+), 208 deletions(-) create mode 100644 src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc create mode 100644 src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h diff --git a/BUILD b/BUILD index a03d2b61be4..5c3ecc8f466 100644 --- a/BUILD +++ b/BUILD @@ -1560,6 +1560,20 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "grpc_resolver_dns_selection", + srcs = [ + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc", + ], + hdrs = [ + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h", + ], + language = "c++", + deps = [ + "grpc_base", + ], +) + grpc_cc_library( name = "grpc_resolver_dns_native", srcs = [ @@ -1569,6 +1583,7 @@ grpc_cc_library( deps = [ "grpc_base", "grpc_client_channel", + "grpc_resolver_dns_selection", ], ) @@ -1600,6 +1615,7 @@ grpc_cc_library( deps = [ "grpc_base", "grpc_client_channel", + "grpc_resolver_dns_selection", ], ) diff --git a/BUILD.gn b/BUILD.gn index 9a416d7f41d..6d9d9368d7f 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -326,6 +326,8 @@ config("grpc_config") { "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", "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/dns_resolver_selection.cc", + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h", "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", diff --git a/CMakeLists.txt b/CMakeLists.txt index 8382fb7318f..1823e97f989 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1301,6 +1301,7 @@ add_library(grpc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc src/core/ext/filters/census/grpc_context.cc @@ -2697,6 +2698,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc diff --git a/Makefile b/Makefile index 3b0e60ecef4..49692e1de67 100644 --- a/Makefile +++ b/Makefile @@ -3769,6 +3769,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ src/core/ext/filters/census/grpc_context.cc \ @@ -5113,6 +5114,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ diff --git a/build.yaml b/build.yaml index a61b7987a4e..38699956c50 100644 --- a/build.yaml +++ b/build.yaml @@ -797,6 +797,7 @@ filegroups: uses: - grpc_base - grpc_client_channel + - grpc_resolver_dns_selection - name: grpc_resolver_dns_native src: - src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -804,6 +805,14 @@ filegroups: uses: - grpc_base - grpc_client_channel + - grpc_resolver_dns_selection +- name: grpc_resolver_dns_selection + headers: + - src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h + src: + - src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc + uses: + - grpc_base - name: grpc_resolver_fake headers: - src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h diff --git a/config.m4 b/config.m4 index c5ecf7cfd6a..d90a8e94e6d 100644 --- a/config.m4 +++ b/config.m4 @@ -412,6 +412,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ src/core/ext/filters/census/grpc_context.cc \ @@ -695,6 +696,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/pick_first) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/round_robin) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/xds) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/c_ares) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/native) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/fake) diff --git a/config.w32 b/config.w32 index 6bcc54f6630..70ac245d9fa 100644 --- a/config.w32 +++ b/config.w32 @@ -387,6 +387,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv_windows.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\\dns_resolver_selection.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.cc " + "src\\core\\ext\\filters\\census\\grpc_context.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 04f23b9f5c0..9f3428d3cff 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -561,6 +561,7 @@ Pod::Spec.new do |s| '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_wrapper.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', + 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index b0b678565e2..cbf0a4b2924 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -539,6 +539,7 @@ Pod::Spec.new do |s| '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_wrapper.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', + 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', @@ -869,6 +870,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', 'src/core/ext/filters/census/grpc_context.cc', @@ -1190,6 +1192,7 @@ Pod::Spec.new do |s| '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_wrapper.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', + 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', diff --git a/grpc.gemspec b/grpc.gemspec index 063b6d6422c..6e229a5ab71 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -473,6 +473,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h ) s.files += %w( src/core/ext/filters/max_age/max_age_filter.h ) s.files += %w( src/core/ext/filters/message_size/message_size_filter.h ) s.files += %w( src/core/ext/filters/http/client_authority_filter.h ) @@ -806,6 +807,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc ) s.files += %w( src/core/ext/filters/census/grpc_context.cc ) diff --git a/grpc.gyp b/grpc.gyp index e6ed4d7318d..833a0b48715 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -594,6 +594,7 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', 'src/core/ext/filters/census/grpc_context.cc', @@ -1354,6 +1355,7 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', diff --git a/package.xml b/package.xml index 15fe7908b9e..04d9f35cf03 100644 --- a/package.xml +++ b/package.xml @@ -478,6 +478,7 @@ + @@ -811,6 +812,7 @@ + diff --git a/src/android/test/interop/app/src/main/cpp/grpc-interop.cc b/src/android/test/interop/app/src/main/cpp/grpc-interop.cc index 07834250d22..b5075529be2 100644 --- a/src/android/test/interop/app/src/main/cpp/grpc-interop.cc +++ b/src/android/test/interop/app/src/main/cpp/grpc-interop.cc @@ -18,8 +18,8 @@ #include #include -#include +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/cpp/interop/interop_client.h" extern "C" JNIEXPORT void JNICALL @@ -28,7 +28,7 @@ Java_io_grpc_interop_cpp_InteropActivity_configureSslRoots(JNIEnv* env, jstring path_raw) { const char* path = env->GetStringUTFChars(path_raw, (jboolean*)0); - gpr_setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", path); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, path); } std::shared_ptr GetClient(const char* host, @@ -45,7 +45,7 @@ std::shared_ptr GetClient(const char* host, credentials = grpc::InsecureChannelCredentials(); } - grpc::testing::ChannelCreationFunc channel_creation_func = + grpc::testing::ChannelCreationFunc channel_creation_func = std::bind(grpc::CreateChannel, host_port, credentials); return std::shared_ptr( new grpc::testing::InteropClient(channel_creation_func, true, false)); diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc index a2d45c04026..dd761694414 100644 --- a/src/core/ext/filters/client_channel/backup_poller.cc +++ b/src/core/ext/filters/client_channel/backup_poller.cc @@ -56,9 +56,14 @@ static backup_poller* g_poller = nullptr; // guarded by g_poller_mu // treated as const. static int g_poll_interval_ms = DEFAULT_POLL_INTERVAL_MS; -GPR_GLOBAL_CONFIG_DEFINE_INT32(grpc_client_channel_backup_poll_interval_ms, - DEFAULT_POLL_INTERVAL_MS, - "Client channel backup poll interval (ms)"); +GPR_GLOBAL_CONFIG_DEFINE_INT32( + grpc_client_channel_backup_poll_interval_ms, DEFAULT_POLL_INTERVAL_MS, + "Declares the interval in ms between two backup polls on client channels. " + "These polls are run in the timer thread so that gRPC can process " + "connection failures while there is no active polling thread. " + "They help reconnect disconnected client channels (mostly due to " + "idleness), so that the next RPC on this channel won't fail. Set to 0 to " + "turn off the backup polls."); static void init_globals() { gpr_mu_init(&g_poller_mu); 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 90a79843458..95366b57386 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc @@ -31,7 +31,6 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/lib/channel/channel_args.h" #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/sync.h" #include "src/core/lib/http/format_request.h" 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 f91adb09e52..92d64450ea4 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 @@ -32,12 +32,12 @@ #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/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.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" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" @@ -447,8 +447,9 @@ static bool should_use_ares(const char* resolver_env) { #endif /* GRPC_UV */ void grpc_resolver_dns_ares_init() { - char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (should_use_ares(resolver_env)) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (should_use_ares(resolver.get())) { gpr_log(GPR_DEBUG, "Using ares dns resolver"); address_sorting_init(); grpc_error* error = grpc_ares_init(); @@ -464,16 +465,15 @@ void grpc_resolver_dns_ares_init() { grpc_core::UniquePtr( grpc_core::New())); } - gpr_free(resolver_env); } void grpc_resolver_dns_ares_shutdown() { - char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (should_use_ares(resolver_env)) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (should_use_ares(resolver.get())) { address_sorting_shutdown(); grpc_ares_cleanup(); } - gpr_free(resolver_env); } #else /* GRPC_ARES == 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc b/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc new file mode 100644 index 00000000000..07a617c14d5 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc @@ -0,0 +1,28 @@ +// +// 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. +// + +// This is similar to the sockaddr resolver, except that it supports a +// bunch of query args that are useful for dependency injection in tests. + +#include + +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" + +GPR_GLOBAL_CONFIG_DEFINE_STRING( + grpc_dns_resolver, "", + "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.") diff --git a/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h b/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h new file mode 100644 index 00000000000..d0a3486ea38 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h @@ -0,0 +1,29 @@ +/* + * + * 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_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_SELECTION_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_SELECTION_H + +#include + +#include "src/core/lib/gprpp/global_config.h" + +GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_dns_resolver); + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_SELECTION_H \ + */ 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 164d308c0dd..5ab75d02793 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 @@ -26,11 +26,11 @@ #include #include +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #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/gprpp/manual_constructor.h" @@ -274,8 +274,9 @@ class NativeDnsResolverFactory : public ResolverFactory { } // namespace grpc_core void grpc_resolver_dns_native_init() { - char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver_env != nullptr && gpr_stricmp(resolver_env, "native") == 0) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (gpr_stricmp(resolver.get(), "native") == 0) { gpr_log(GPR_DEBUG, "Using native dns resolver"); grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( grpc_core::UniquePtr( @@ -291,7 +292,6 @@ void grpc_resolver_dns_native_init() { grpc_core::New())); } } - gpr_free(resolver_env); } void grpc_resolver_dns_native_shutdown() {} diff --git a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc index 4c929d00ec9..ac13d73d3b5 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc @@ -23,8 +23,11 @@ #include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/transport/metadata.h" -GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_experimental_disable_flow_control, false, - "Disable flow control"); +GPR_GLOBAL_CONFIG_DEFINE_BOOL( + grpc_experimental_disable_flow_control, false, + "If set, flow control will be effectively disabled. Max out all values and " + "assume the remote peer does the same. Thus we can ignore any flow control " + "bookkeeping, error checking, and decision making"); void grpc_chttp2_plugin_init(void) { g_flow_control_enabled = diff --git a/src/core/lib/debug/trace.cc b/src/core/lib/debug/trace.cc index cafdb15c699..84c0a3805d3 100644 --- a/src/core/lib/debug/trace.cc +++ b/src/core/lib/debug/trace.cc @@ -26,7 +26,11 @@ #include #include #include -#include "src/core/lib/gpr/env.h" + +GPR_GLOBAL_CONFIG_DEFINE_STRING( + grpc_trace, "", + "A comma separated list of tracers that provide additional insight into " + "how gRPC C core is processing requests via debug logs."); int grpc_tracer_set_enabled(const char* name, int enabled); @@ -133,12 +137,14 @@ static void parse(const char* s) { gpr_free(strings); } -void grpc_tracer_init(const char* env_var) { - char* e = gpr_getenv(env_var); - if (e != nullptr) { - parse(e); - gpr_free(e); - } +void grpc_tracer_init(const char* env_var_name) { + (void)env_var_name; // suppress unused variable error + grpc_tracer_init(); +} + +void grpc_tracer_init() { + grpc_core::UniquePtr value = GPR_GLOBAL_CONFIG_GET(grpc_trace); + parse(value.get()); } void grpc_tracer_shutdown(void) {} diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h index 72e1a4eded7..6a4a8031ec4 100644 --- a/src/core/lib/debug/trace.h +++ b/src/core/lib/debug/trace.h @@ -24,7 +24,15 @@ #include #include +#include "src/core/lib/gprpp/global_config.h" + +GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_trace); + +// TODO(veblush): Remove this deprecated function once codes depending on this +// function are updated in the internal repo. void grpc_tracer_init(const char* env_var_name); + +void grpc_tracer_init(); void grpc_tracer_shutdown(void); #if defined(__has_feature) diff --git a/src/core/lib/gpr/env.h b/src/core/lib/gpr/env.h index 5956d17fcfe..11db17c83da 100644 --- a/src/core/lib/gpr/env.h +++ b/src/core/lib/gpr/env.h @@ -34,12 +34,6 @@ char* gpr_getenv(const char* name); /* Sets the environment with the specified name to the specified value. */ void gpr_setenv(const char* name, const char* value); -/* This is a version of gpr_getenv that does not produce any output if it has to - use an insecure version of the function. It is ONLY to be used to solve the - problem in which we need to check an env variable to configure the verbosity - level of logging. So DO NOT USE THIS. */ -const char* gpr_getenv_silent(const char* name, char** dst); - /* Deletes the variable name from the environment. */ void gpr_unsetenv(const char* name); diff --git a/src/core/lib/gpr/env_linux.cc b/src/core/lib/gpr/env_linux.cc index e84a9f6064c..3a3aa541672 100644 --- a/src/core/lib/gpr/env_linux.cc +++ b/src/core/lib/gpr/env_linux.cc @@ -38,7 +38,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" -const char* gpr_getenv_silent(const char* name, char** dst) { +static const char* gpr_getenv_silent(const char* name, char** dst) { const char* insecure_func_used = nullptr; char* result = nullptr; #if defined(GPR_BACKWARDS_COMPATIBILITY_MODE) diff --git a/src/core/lib/gpr/env_windows.cc b/src/core/lib/gpr/env_windows.cc index 72850a9587d..76c45fb87a7 100644 --- a/src/core/lib/gpr/env_windows.cc +++ b/src/core/lib/gpr/env_windows.cc @@ -30,11 +30,6 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/string_windows.h" -const char* gpr_getenv_silent(const char* name, char** dst) { - *dst = gpr_getenv(name); - return NULL; -} - char* gpr_getenv(const char* name) { char* result = NULL; DWORD size; diff --git a/src/core/lib/gpr/log.cc b/src/core/lib/gpr/log.cc index 01ef112fb31..8a229b2adf1 100644 --- a/src/core/lib/gpr/log.cc +++ b/src/core/lib/gpr/log.cc @@ -22,12 +22,15 @@ #include #include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/global_config.h" #include #include +GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_verbosity, "ERROR", + "Default gRPC logging verbosity") + void gpr_default_log(gpr_log_func_args* args); static gpr_atm g_log_func = (gpr_atm)gpr_default_log; static gpr_atm g_min_severity_to_print = GPR_LOG_VERBOSITY_UNSET; @@ -72,29 +75,22 @@ void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print) { } void gpr_log_verbosity_init() { - char* verbosity = nullptr; - const char* insecure_getenv = gpr_getenv_silent("GRPC_VERBOSITY", &verbosity); + grpc_core::UniquePtr verbosity = GPR_GLOBAL_CONFIG_GET(grpc_verbosity); gpr_atm min_severity_to_print = GPR_LOG_SEVERITY_ERROR; - if (verbosity != nullptr) { - if (gpr_stricmp(verbosity, "DEBUG") == 0) { + if (strlen(verbosity.get()) > 0) { + if (gpr_stricmp(verbosity.get(), "DEBUG") == 0) { min_severity_to_print = static_cast(GPR_LOG_SEVERITY_DEBUG); - } else if (gpr_stricmp(verbosity, "INFO") == 0) { + } else if (gpr_stricmp(verbosity.get(), "INFO") == 0) { min_severity_to_print = static_cast(GPR_LOG_SEVERITY_INFO); - } else if (gpr_stricmp(verbosity, "ERROR") == 0) { + } else if (gpr_stricmp(verbosity.get(), "ERROR") == 0) { min_severity_to_print = static_cast(GPR_LOG_SEVERITY_ERROR); } - gpr_free(verbosity); } if ((gpr_atm_no_barrier_load(&g_min_severity_to_print)) == GPR_LOG_VERBOSITY_UNSET) { gpr_atm_no_barrier_store(&g_min_severity_to_print, min_severity_to_print); } - - if (insecure_getenv != nullptr) { - gpr_log(GPR_DEBUG, "Warning: insecure environment read function '%s' used", - insecure_getenv); - } } void gpr_set_log_function(gpr_log_func f) { diff --git a/src/core/lib/gprpp/fork.cc b/src/core/lib/gprpp/fork.cc index c4b1cbc2233..cacf5e82e5a 100644 --- a/src/core/lib/gprpp/fork.cc +++ b/src/core/lib/gprpp/fork.cc @@ -26,8 +26,8 @@ #include #include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/gprpp/memory.h" /* @@ -35,6 +35,16 @@ * AROUND VERY SPECIFIC USE CASES. */ +#ifdef GRPC_ENABLE_FORK_SUPPORT +#define GRPC_ENABLE_FORK_SUPPORT_DEFAULT true +#else +#define GRPC_ENABLE_FORK_SUPPORT_DEFAULT false +#endif // GRPC_ENABLE_FORK_SUPPORT + +GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_enable_fork_support, + GRPC_ENABLE_FORK_SUPPORT_DEFAULT, + "Enable folk support"); + namespace grpc_core { namespace internal { // The exec_ctx_count has 2 modes, blocked and unblocked. @@ -158,34 +168,7 @@ class ThreadState { void Fork::GlobalInit() { if (!override_enabled_) { -#ifdef GRPC_ENABLE_FORK_SUPPORT - support_enabled_ = true; -#endif - bool env_var_set = false; - char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT"); - if (env != nullptr) { - static const char* truthy[] = {"yes", "Yes", "YES", "true", - "True", "TRUE", "1"}; - static const char* falsey[] = {"no", "No", "NO", "false", - "False", "FALSE", "0"}; - for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) { - if (0 == strcmp(env, truthy[i])) { - support_enabled_ = true; - env_var_set = true; - break; - } - } - if (!env_var_set) { - for (size_t i = 0; i < GPR_ARRAY_SIZE(falsey); i++) { - if (0 == strcmp(env, falsey[i])) { - support_enabled_ = false; - env_var_set = true; - break; - } - } - } - gpr_free(env); - } + support_enabled_ = GPR_GLOBAL_CONFIG_GET(grpc_enable_fork_support); } if (support_enabled_) { exec_ctx_state_ = grpc_core::New(); diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 47cf5b83b17..ddafb7b5539 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -31,13 +31,19 @@ #include #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/iomgr/ev_epoll1_linux.h" #include "src/core/lib/iomgr/ev_epollex_linux.h" #include "src/core/lib/iomgr/ev_poll_posix.h" #include "src/core/lib/iomgr/internal_errqueue.h" +GPR_GLOBAL_CONFIG_DEFINE_STRING( + grpc_poll_strategy, "all", + "Declares which polling engines to try when starting gRPC. " + "This is a comma-separated list of engines, which are tried in priority " + "order first -> last.") + grpc_core::TraceFlag grpc_polling_trace(false, "polling"); /* Disabled by default */ @@ -46,16 +52,15 @@ grpc_core::TraceFlag grpc_fd_trace(false, "fd_trace"); grpc_core::DebugOnlyTraceFlag grpc_trace_fd_refcount(false, "fd_refcount"); grpc_core::DebugOnlyTraceFlag grpc_polling_api_trace(false, "polling_api"); -#ifndef NDEBUG - // Polling API trace only enabled in debug builds +#ifndef NDEBUG #define GRPC_POLLING_API_TRACE(format, ...) \ if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_api_trace)) { \ gpr_log(GPR_INFO, "(polling-api) " format, __VA_ARGS__); \ } #else #define GRPC_POLLING_API_TRACE(...) -#endif +#endif // NDEBUG /** Default poll() function - a pointer so that it can be overridden by some * tests */ @@ -66,7 +71,7 @@ int aix_poll(struct pollfd fds[], nfds_t nfds, int timeout) { return poll(fds, nfds, timeout); } grpc_poll_function_type grpc_poll_function = aix_poll; -#endif +#endif // GPR_AIX grpc_wakeup_fd grpc_global_wakeup_fd; @@ -205,14 +210,11 @@ void grpc_register_event_engine_factory(const char* name, const char* grpc_get_poll_strategy_name() { return g_poll_strategy_name; } void grpc_event_engine_init(void) { - char* s = gpr_getenv("GRPC_POLL_STRATEGY"); - if (s == nullptr) { - s = gpr_strdup("all"); - } + grpc_core::UniquePtr value = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); char** strings = nullptr; size_t nstrings = 0; - split(s, &strings, &nstrings); + split(value.get(), &strings, &nstrings); for (size_t i = 0; g_event_engine == nullptr && i < nstrings; i++) { try_engine(strings[i]); @@ -224,10 +226,10 @@ void grpc_event_engine_init(void) { gpr_free(strings); if (g_event_engine == nullptr) { - gpr_log(GPR_ERROR, "No event engine could be initialized from %s", s); + gpr_log(GPR_ERROR, "No event engine could be initialized from %s", + value.get()); abort(); } - gpr_free(s); } void grpc_event_engine_shutdown(void) { diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h index 0ca3a6f82fd..30bb5e40faf 100644 --- a/src/core/lib/iomgr/ev_posix.h +++ b/src/core/lib/iomgr/ev_posix.h @@ -24,11 +24,14 @@ #include #include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" +GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_poll_strategy); + extern grpc_core::TraceFlag grpc_fd_trace; /* Disabled by default */ extern grpc_core::TraceFlag grpc_polling_trace; /* Disabled by default */ diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index 7f8fb7e828b..629b08162fb 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -28,7 +28,6 @@ #include #include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/fork.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/ev_posix.h" diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index fd011788a06..b86aa6f2d76 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -42,7 +42,8 @@ #include "src/core/lib/iomgr/timer_manager.h" GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_abort_on_leaks, false, - "Abort when leak is found"); + "A debugging aid to cause a call to abort() when " + "gRPC objects are leaked past grpc_shutdown()"); static gpr_mu g_mu; static gpr_cv g_rcv; diff --git a/src/core/lib/profiling/basic_timers.cc b/src/core/lib/profiling/basic_timers.cc index b19ad9fc23d..37689fe89d1 100644 --- a/src/core/lib/profiling/basic_timers.cc +++ b/src/core/lib/profiling/basic_timers.cc @@ -31,7 +31,8 @@ #include #include -#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/global_config.h" +#include "src/core/lib/profiling/timers.h" typedef enum { BEGIN = '{', END = '}', MARK = '.' } marker_type; @@ -74,11 +75,16 @@ static __thread int g_thread_id; static int g_next_thread_id; static int g_writing_enabled = 1; +GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_latency_trace, "latency_trace.txt", + "Output file name for latency trace") + static const char* output_filename() { if (output_filename_or_null == NULL) { - output_filename_or_null = gpr_getenv("LATENCY_TRACE"); - if (output_filename_or_null == NULL || - strlen(output_filename_or_null) == 0) { + grpc_core::UniquePtr value = + GPR_GLOBAL_CONFIG_GET(grpc_latency_trace); + if (strlen(value.get()) > 0) { + output_filename_or_null = value.release(); + } else { output_filename_or_null = "latency_trace.txt"; } } diff --git a/src/core/lib/security/security_connector/load_system_roots_linux.cc b/src/core/lib/security/security_connector/load_system_roots_linux.cc index 924fa8a3e26..82d5bf6bcdd 100644 --- a/src/core/lib/security/security_connector/load_system_roots_linux.cc +++ b/src/core/lib/security/security_connector/load_system_roots_linux.cc @@ -38,12 +38,15 @@ #include #include -#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/gprpp/global_config.h" #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/iomgr/load_file.h" +GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_system_ssl_roots_dir, "", + "Custom directory to SSL Roots"); + namespace grpc_core { namespace { @@ -139,10 +142,9 @@ grpc_slice CreateRootCertsBundle(const char* certs_directory) { grpc_slice LoadSystemRootCerts() { grpc_slice result = grpc_empty_slice(); // Prioritize user-specified custom directory if flag is set. - char* custom_dir = gpr_getenv("GRPC_SYSTEM_SSL_ROOTS_DIR"); - if (custom_dir != nullptr) { - result = CreateRootCertsBundle(custom_dir); - gpr_free(custom_dir); + UniquePtr custom_dir = GPR_GLOBAL_CONFIG_GET(grpc_system_ssl_roots_dir); + if (strlen(custom_dir.get()) > 0) { + result = CreateRootCertsBundle(custom_dir.get()); } // If the custom directory is empty/invalid/not specified, fallback to // distribution-specific directory. diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 96a19605466..47c0ad5aa3d 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -28,7 +28,6 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.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/iomgr/load_file.h" diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index 1eefff6fe24..cb0d5437988 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -27,7 +27,6 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #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/gprpp/global_config.h" @@ -46,7 +45,13 @@ static const char* installed_roots_path = INSTALL_PREFIX "/share/grpc/roots.pem"; #endif -/** Environment variable used as a flag to enable/disable loading system root +/** Config variable that points to the default SSL roots file. This file + must be a PEM encoded file with all the roots such as the one that can be + downloaded from https://pki.google.com/roots.pem. */ +GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_default_ssl_roots_file_path, "", + "Path to the default SSL roots file."); + +/** Config variable used as a flag to enable/disable loading system root certificates from the OS trust store. */ GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_not_use_system_ssl_roots, false, "Disable loading system root certificates."); @@ -65,20 +70,22 @@ void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) { /* -- Cipher suites. -- */ -/* Defines the cipher suites that we accept by default. All these cipher suites - are compliant with HTTP2. */ -#define GRPC_SSL_CIPHER_SUITES \ - "ECDHE-ECDSA-AES128-GCM-SHA256:" \ - "ECDHE-ECDSA-AES256-GCM-SHA384:" \ - "ECDHE-RSA-AES128-GCM-SHA256:" \ - "ECDHE-RSA-AES256-GCM-SHA384" - static gpr_once cipher_suites_once = GPR_ONCE_INIT; static const char* cipher_suites = nullptr; +// All cipher suites for default are compliant with HTTP2. +GPR_GLOBAL_CONFIG_DEFINE_STRING( + grpc_ssl_cipher_suites, + "ECDHE-ECDSA-AES128-GCM-SHA256:" + "ECDHE-ECDSA-AES256-GCM-SHA384:" + "ECDHE-RSA-AES128-GCM-SHA256:" + "ECDHE-RSA-AES256-GCM-SHA384", + "A colon separated list of cipher suites to use with OpenSSL") + static void init_cipher_suites(void) { - char* overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES"); - cipher_suites = overridden != nullptr ? overridden : GRPC_SSL_CIPHER_SUITES; + grpc_core::UniquePtr value = + GPR_GLOBAL_CONFIG_GET(grpc_ssl_cipher_suites); + cipher_suites = value.release(); } /* --- Util --- */ @@ -430,13 +437,12 @@ grpc_slice DefaultSslRootStore::ComputePemRootCerts() { grpc_slice result = grpc_empty_slice(); const bool not_use_system_roots = GPR_GLOBAL_CONFIG_GET(grpc_not_use_system_ssl_roots); - // First try to load the roots from the environment. - char* default_root_certs_path = - gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); - if (default_root_certs_path != nullptr) { - GRPC_LOG_IF_ERROR("load_file", - grpc_load_file(default_root_certs_path, 1, &result)); - gpr_free(default_root_certs_path); + // First try to load the roots from the configuration. + UniquePtr default_root_certs_path = + GPR_GLOBAL_CONFIG_GET(grpc_default_ssl_roots_file_path); + if (strlen(default_root_certs_path.get()) > 0) { + GRPC_LOG_IF_ERROR( + "load_file", grpc_load_file(default_root_certs_path.get(), 1, &result)); } // Try overridden roots if needed. grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL; diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index 080e277f944..1765a344c2a 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -26,6 +26,7 @@ #include #include +#include "src/core/lib/gprpp/global_config.h" #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" @@ -33,7 +34,10 @@ #include "src/core/tsi/transport_security.h" #include "src/core/tsi/transport_security_interface.h" -/* --- Util. --- */ +GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_default_ssl_roots_file_path); +GPR_GLOBAL_CONFIG_DECLARE_BOOL(grpc_not_use_system_ssl_roots); + +/* --- Util --- */ /* --- URL schemes. --- */ #define GRPC_SSL_URL_SCHEME "https" diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 1ed1a66b184..2a6d307ddab 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -154,7 +154,7 @@ void grpc_init(void) { * at the appropriate time */ grpc_register_security_filters(); register_builtin_channel_init(); - grpc_tracer_init("GRPC_TRACE"); + grpc_tracer_init(); /* no more changes to channel init pipelines */ grpc_channel_init_finalize(); grpc_iomgr_start(); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 7557367ed4a..e6522d7a27e 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -61,8 +61,7 @@ NSBundle *resourceBundle = [NSBundle bundleWithURL:[[bundle resourceURL] URLByAppendingPathComponent:resourceBundlePath]]; NSString *path = [resourceBundle pathForResource:rootsPEM ofType:@"pem"]; - setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, - [path cStringUsingEncoding:NSUTF8StringEncoding], 1); + setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", [path cStringUsingEncoding:NSUTF8StringEncoding], 1); }); NSData *rootsASCII = nil; diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm index 2fac1be3d0e..0d081e4a410 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm @@ -37,11 +37,11 @@ #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/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -172,7 +172,7 @@ static char *roots_filename; GPR_ASSERT(roots_file != NULL); 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); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 97c9f2f7c94..61524eb7fc9 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -386,6 +386,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', 'src/core/ext/filters/census/grpc_context.cc', diff --git a/test/core/bad_connection/close_fd_test.cc b/test/core/bad_connection/close_fd_test.cc index e8f297e77ea..78a1a5cc9a4 100644 --- a/test/core/bad_connection/close_fd_test.cc +++ b/test/core/bad_connection/close_fd_test.cc @@ -39,7 +39,6 @@ #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" diff --git a/test/core/bad_ssl/bad_ssl_test.cc b/test/core/bad_ssl/bad_ssl_test.cc index 73d251eff4a..8dd55f64944 100644 --- a/test/core/bad_ssl/bad_ssl_test.cc +++ b/test/core/bad_ssl/bad_ssl_test.cc @@ -25,9 +25,9 @@ #include #include -#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/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -133,7 +133,7 @@ int main(int argc, char** argv) { strcpy(root, "."); } if (argc == 2) { - gpr_setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", argv[1]); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, argv[1]); } /* figure out our test name */ tmp = lunder - 1; diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc index ed3b4e66472..129866b7d7f 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -21,8 +21,8 @@ #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/combiner.h" #include "test/core/util/test_config.h" @@ -78,13 +78,13 @@ int main(int argc, char** argv) { test_succeeds(dns, "dns:10.2.1.1:1234"); 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) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (gpr_stricmp(resolver.get(), "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"); } - gpr_free(resolver_env); { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc index ce8f6bf13a5..b8dbe261183 100644 --- a/test/core/end2end/fixtures/h2_full+trace.cc +++ b/test/core/end2end/fixtures/h2_full+trace.cc @@ -33,7 +33,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/env.h" +#include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" @@ -105,7 +105,7 @@ int main(int argc, char** argv) { /* force tracing on, with a value to force many code paths in trace.c to be taken */ - gpr_setenv("GRPC_TRACE", "doesnt-exist,http,all"); + GPR_GLOBAL_CONFIG_SET(grpc_trace, "doesnt-exist,http,all"); #ifdef GRPC_POSIX_SOCKET g_fixture_slowdown_factor = isatty(STDOUT_FILENO) ? 10 : 1; diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc index 4494d5c4746..7954bc1ddfc 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.cc +++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc @@ -35,7 +35,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/env.h" +#include "src/core/lib/debug/trace.h" #include "src/core/lib/iomgr/endpoint_pair.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/surface/channel.h" @@ -133,7 +133,8 @@ int main(int argc, char** argv) { /* force tracing on, with a value to force many code paths in trace.c to be taken */ - gpr_setenv("GRPC_TRACE", "doesnt-exist,http,all"); + GPR_GLOBAL_CONFIG_SET(grpc_trace, "doesnt-exist,http,all"); + #ifdef GRPC_POSIX_SOCKET g_fixture_slowdown_factor = isatty(STDOUT_FILENO) ? 10 : 1; #else diff --git a/test/core/end2end/fixtures/h2_spiffe.cc b/test/core/end2end/fixtures/h2_spiffe.cc index 9ab796ea429..cdf091bac10 100644 --- a/test/core/end2end/fixtures/h2_spiffe.cc +++ b/test/core/end2end/fixtures/h2_spiffe.cc @@ -35,6 +35,7 @@ #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 "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -277,7 +278,7 @@ int main(int argc, char** argv) { 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); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); for (size_t ind = 0; ind < sizeof(configs) / sizeof(*configs); ind++) { grpc_end2end_tests(argc, argv, configs[ind]); diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc index 1fcd785e251..3fc9bc7f329 100644 --- a/test/core/end2end/fixtures/h2_ssl.cc +++ b/test/core/end2end/fixtures/h2_ssl.cc @@ -25,11 +25,11 @@ #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/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -167,7 +167,7 @@ int main(int argc, char** argv) { 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); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc index 04d876ce3cd..1d54a431364 100644 --- a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc +++ b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc @@ -25,11 +25,11 @@ #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/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -190,7 +190,7 @@ int main(int argc, char** argv) { 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); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc index f1858079426..d5f695b1575 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.cc +++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc @@ -25,11 +25,11 @@ #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/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/end2end/fixtures/proxy.h" #include "test/core/util/port.h" @@ -208,7 +208,7 @@ int main(int argc, char** argv) { 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); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc index cb0800bf899..e9285778a2d 100644 --- a/test/core/end2end/h2_ssl_cert_test.cc +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -25,11 +25,11 @@ #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/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" @@ -366,7 +366,7 @@ int main(int argc, char** argv) { 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); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); ::testing::InitGoogleTest(&argc, argv); diff --git a/test/core/end2end/h2_ssl_session_reuse_test.cc b/test/core/end2end/h2_ssl_session_reuse_test.cc index fbcdcc4b3f3..b2d0a5e1133 100644 --- a/test/core/end2end/h2_ssl_session_reuse_test.cc +++ b/test/core/end2end/h2_ssl_session_reuse_test.cc @@ -25,11 +25,11 @@ #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/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" @@ -265,7 +265,7 @@ int main(int argc, char** argv) { 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); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); ::testing::InitGoogleTest(&argc, argv); diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc index 3c33f0419ad..1750f6fe5ee 100644 --- a/test/core/end2end/tests/keepalive_timeout.cc +++ b/test/core/end2end/tests/keepalive_timeout.cc @@ -28,11 +28,15 @@ #include "src/core/ext/transport/chttp2/transport/frame_ping.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/iomgr.h" #include "test/core/end2end/cq_verifier.h" +#ifdef GRPC_POSIX_SOCKET +#include "src/core/lib/iomgr/ev_posix.h" +#endif // GRPC_POSIX_SOCKET + static void* tag(intptr_t t) { return (void*)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -225,13 +229,13 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { * 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) { - char* poller = gpr_getenv("GRPC_POLL_STRATEGY"); +#ifdef GRPC_POSIX_SOCKET + grpc_core::UniquePtr poller = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); /* It is hard to get the timing right for the polling engine poll. */ - if (poller != nullptr && (0 == strcmp(poller, "poll"))) { - gpr_free(poller); + if ((0 == strcmp(poller.get(), "poll"))) { return; } - gpr_free(poller); +#endif // GRPC_POSIX_SOCKET const int kPingIntervalMS = 100; grpc_arg keepalive_arg_elems[3]; keepalive_arg_elems[0].type = GRPC_ARG_INTEGER; diff --git a/test/core/gpr/log_test.cc b/test/core/gpr/log_test.cc index f96257738b2..e320daa33a7 100644 --- a/test/core/gpr/log_test.cc +++ b/test/core/gpr/log_test.cc @@ -21,9 +21,14 @@ #include #include -#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/global_config.h" #include "test/core/util/test_config.h" +// Config declaration is supposed to be located at log.h but +// log.h doesn't include global_config headers because it has to +// be a strict C so declaration statement gets to be here. +GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_verbosity); + static bool log_func_reached = false; static void test_callback(gpr_log_func_args* args) { @@ -67,7 +72,7 @@ int main(int argc, char** argv) { /* gpr_log_verbosity_init() will be effective only once, and only before * gpr_set_log_verbosity() is called */ - gpr_setenv("GRPC_VERBOSITY", "ERROR"); + GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "ERROR"); gpr_log_verbosity_init(); test_log_function_reached(GPR_ERROR); @@ -75,7 +80,7 @@ int main(int argc, char** argv) { test_log_function_unreached(GPR_DEBUG); /* gpr_log_verbosity_init() should not be effective */ - gpr_setenv("GRPC_VERBOSITY", "DEBUG"); + GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "DEBUG"); gpr_log_verbosity_init(); test_log_function_reached(GPR_ERROR); test_log_function_unreached(GPR_INFO); @@ -97,7 +102,7 @@ int main(int argc, char** argv) { test_log_function_unreached(GPR_DEBUG); /* gpr_log_verbosity_init() should not be effective */ - gpr_setenv("GRPC_VERBOSITY", "DEBUG"); + GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "DEBUG"); gpr_log_verbosity_init(); test_log_function_reached(GPR_ERROR); test_log_function_unreached(GPR_INFO); diff --git a/test/core/http/httpscli_test.cc b/test/core/http/httpscli_test.cc index 326b0e95e25..e7250c206d8 100644 --- a/test/core/http/httpscli_test.cc +++ b/test/core/http/httpscli_test.cc @@ -29,6 +29,7 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" #include "test/core/util/test_config.h" @@ -184,7 +185,7 @@ int main(int argc, char** argv) { /* Set the environment variable for the SSL certificate file */ char* pem_file; gpr_asprintf(&pem_file, "%s/src/core/tsi/test_creds/ca.pem", root); - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, pem_file); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, pem_file); gpr_free(pem_file); /* start the server */ diff --git a/test/core/iomgr/resolve_address_posix_test.cc b/test/core/iomgr/resolve_address_posix_test.cc index 826c7e1fafa..112d7c2791b 100644 --- a/test/core/iomgr/resolve_address_posix_test.cc +++ b/test/core/iomgr/resolve_address_posix_test.cc @@ -29,6 +29,7 @@ #include #include +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" @@ -224,15 +225,16 @@ int main(int argc, char** argv) { // --resolver will always be the first one, so only parse the first argument // (other arguments may be unknown to cl) gpr_cmdline_parse(cl, argc > 2 ? 2 : argc, argv); - const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER"); - if (cur_resolver != nullptr && strlen(cur_resolver) != 0) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (strlen(resolver.get()) != 0) { gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s", - cur_resolver); + resolver.get()); } if (gpr_stricmp(resolver_type, "native") == 0) { - gpr_setenv("GRPC_DNS_RESOLVER", "native"); + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "native"); } else if (gpr_stricmp(resolver_type, "ares") == 0) { - gpr_setenv("GRPC_DNS_RESOLVER", "ares"); + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); } else { gpr_log(GPR_ERROR, "--resolver_type was not set to ares or native"); abort(); @@ -246,12 +248,12 @@ int main(int argc, char** argv) { // c-ares resolver doesn't support UDS (ability for native DNS resolver // to handle this is only expected to be used by servers, which // unconditionally use the native DNS resolver). - char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (gpr_stricmp(resolver.get(), "native") == 0) { test_unix_socket(); test_unix_socket_path_name_too_long(); } - gpr_free(resolver_env); } gpr_cmdline_destroy(cl); diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index 1f0c0e3e835..cbc03485d7f 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -27,7 +27,7 @@ #include -#include "src/core/lib/gpr/env.h" +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" @@ -347,16 +347,17 @@ int main(int argc, char** argv) { // --resolver will always be the first one, so only parse the first argument // (other arguments may be unknown to cl) gpr_cmdline_parse(cl, argc > 2 ? 2 : argc, argv); - const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER"); - if (cur_resolver != nullptr && strlen(cur_resolver) != 0) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (strlen(resolver.get()) != 0) { gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s", - cur_resolver); + resolver.get()); } if (gpr_stricmp(resolver_type, "native") == 0) { - gpr_setenv("GRPC_DNS_RESOLVER", "native"); + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "native"); } else if (gpr_stricmp(resolver_type, "ares") == 0) { #ifndef GRPC_UV - gpr_setenv("GRPC_DNS_RESOLVER", "ares"); + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); #endif } else { gpr_log(GPR_ERROR, "--resolver_type was not set to ares or native"); diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index 11cfc8cc905..141346bca94 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -1161,7 +1161,7 @@ static void test_get_well_known_google_credentials_file_path(void) { GPR_ASSERT(path != nullptr); gpr_free(path); #if defined(GPR_POSIX_ENV) || defined(GPR_LINUX_ENV) - unsetenv("HOME"); + gpr_unsetenv("HOME"); path = grpc_get_well_known_google_credentials_file_path(); GPR_ASSERT(path == nullptr); gpr_setenv("HOME", home); diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index 496f064439c..c888c90c646 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -24,7 +24,6 @@ #include #include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -394,7 +393,7 @@ static void test_default_ssl_roots(void) { /* First let's get the root through the override: set the env to an invalid value. */ - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, ""); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, ""); grpc_set_ssl_roots_override_callback(override_roots_success); grpc_slice roots = grpc_core::TestDefaultSslRootStore::ComputePemRootCertsForTesting(); @@ -405,7 +404,8 @@ static void test_default_ssl_roots(void) { /* Now let's set the env var: We should get the contents pointed value instead. */ - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_env_var_file_path); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, + roots_env_var_file_path); roots = grpc_core::TestDefaultSslRootStore::ComputePemRootCertsForTesting(); roots_contents = grpc_slice_to_c_string(roots); grpc_slice_unref(roots); @@ -414,7 +414,7 @@ static void test_default_ssl_roots(void) { /* Now reset the env var. We should fall back to the value overridden using the api. */ - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, ""); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, ""); roots = grpc_core::TestDefaultSslRootStore::ComputePemRootCertsForTesting(); roots_contents = grpc_slice_to_c_string(roots); grpc_slice_unref(roots); @@ -423,7 +423,7 @@ static void test_default_ssl_roots(void) { /* Now setup a permanent failure for the overridden roots and we should get an empty slice. */ - gpr_setenv("GRPC_NOT_USE_SYSTEM_SSL_ROOTS", "true"); + GPR_GLOBAL_CONFIG_SET(grpc_not_use_system_ssl_roots, true); grpc_set_ssl_roots_override_callback(override_roots_permanent_failure); roots = grpc_core::TestDefaultSslRootStore::ComputePemRootCertsForTesting(); GPR_ASSERT(GRPC_SLICE_IS_EMPTY(roots)); diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index 476e424b1eb..5b248a01daa 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -28,7 +28,6 @@ #include #include -#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" diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 97275db6276..6ca0edf123e 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -33,7 +33,6 @@ #include #include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/tls.h" #include "src/core/lib/iomgr/port.h" #include "src/proto/grpc/health/v1/health.grpc.pb.h" @@ -44,6 +43,10 @@ #include "test/cpp/util/string_ref_helper.h" #include "test/cpp/util/test_credentials_provider.h" +#ifdef GRPC_POSIX_SOCKET +#include "src/core/lib/iomgr/ev_posix.h" +#endif // GRPC_POSIX_SOCKET + #include using grpc::testing::EchoRequest; @@ -359,13 +362,14 @@ TEST_P(AsyncEnd2endTest, ReconnectChannel) { return; } int poller_slowdown_factor = 1; +#ifdef GRPC_POSIX_SOCKET // It needs 2 pollset_works to reconnect the channel with polling engine // "poll" - char* s = gpr_getenv("GRPC_POLL_STRATEGY"); - if (s != nullptr && 0 == strcmp(s, "poll")) { + grpc_core::UniquePtr poller = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); + if (0 == strcmp(poller.get(), "poll")) { poller_slowdown_factor = 2; } - gpr_free(s); +#endif // GRPC_POSIX_SOCKET ResetStub(); SendRpc(1); server_->Shutdown(); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index e5dc88ae6d7..8fae2da217f 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -35,7 +35,6 @@ #include #include "src/core/ext/filters/client_channel/backup_poller.h" -#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" @@ -47,6 +46,10 @@ #include "test/cpp/util/string_ref_helper.h" #include "test/cpp/util/test_credentials_provider.h" +#ifdef GRPC_POSIX_SOCKET +#include "src/core/lib/iomgr/ev_posix.h" +#endif // GRPC_POSIX_SOCKET + #include using grpc::testing::EchoRequest; @@ -809,11 +812,12 @@ TEST_P(End2endTest, ReconnectChannel) { int poller_slowdown_factor = 1; // It needs 2 pollset_works to reconnect the channel with polling engine // "poll" - char* s = gpr_getenv("GRPC_POLL_STRATEGY"); - if (s != nullptr && 0 == strcmp(s, "poll")) { +#ifdef GRPC_POSIX_SOCKET + grpc_core::UniquePtr poller = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); + if (0 == strcmp(poller.get(), "poll")) { poller_slowdown_factor = 2; } - gpr_free(s); +#endif // GRPC_POSIX_SOCKET ResetStub(); SendRpc(stub_.get(), 1, false); RestartServer(std::shared_ptr()); diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index bd685632c33..affc75bc634 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -36,10 +36,10 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #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/iomgr/combiner.h" @@ -829,13 +829,13 @@ TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) { } // namespace int main(int argc, char** argv) { - char* resolver = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver == nullptr || strlen(resolver) == 0) { - gpr_setenv("GRPC_DNS_RESOLVER", "ares"); - } else if (strcmp("ares", resolver)) { - gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver); + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (strlen(resolver.get()) == 0) { + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); + } else if (strcmp("ares", resolver.get())) { + gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver.get()); } - gpr_free(resolver); grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); auto result = RUN_ALL_TESTS(); diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index 674e72fdc52..667011ae291 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -29,10 +29,10 @@ #include #include "include/grpc/support/string_util.h" #include "src/core/ext/filters/client_channel/resolver.h" +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/stats.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/gprpp/orphanable.h" @@ -374,7 +374,7 @@ TEST( int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); - gpr_setenv("GRPC_DNS_RESOLVER", "ares"); + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); // Sanity check the time that it takes to run the test // including the teardown time (the teardown // part of the test involves cancelling the DNS query, diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index e3f3e94d2de..b56dc9bc631 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -46,7 +46,6 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #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/gprpp/orphanable.h" diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 0839f8c6386..293a6e1f9c1 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -953,6 +953,8 @@ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h \ 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/dns_resolver_selection.cc \ +src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h \ src/core/ext/filters/client_channel/resolver/dns/native/README.md \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 242f6677d6a..b5ba965ea98 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9155,7 +9155,8 @@ "deps": [ "gpr", "grpc_base", - "grpc_client_channel" + "grpc_client_channel", + "grpc_resolver_dns_selection" ], "headers": [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", @@ -9188,7 +9189,8 @@ "deps": [ "gpr", "grpc_base", - "grpc_client_channel" + "grpc_client_channel", + "grpc_resolver_dns_selection" ], "headers": [], "is_filegroup": true, @@ -9200,6 +9202,24 @@ "third_party": false, "type": "filegroup" }, + { + "deps": [ + "gpr", + "grpc_base" + ], + "headers": [ + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" + ], + "is_filegroup": true, + "language": "c", + "name": "grpc_resolver_dns_selection", + "src": [ + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc", + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" + ], + "third_party": false, + "type": "filegroup" + }, { "deps": [ "gpr", diff --git a/tools/run_tests/run_microbenchmark.py b/tools/run_tests/run_microbenchmark.py index 4e4d05cdcd4..a7fde3007af 100755 --- a/tools/run_tests/run_microbenchmark.py +++ b/tools/run_tests/run_microbenchmark.py @@ -96,7 +96,7 @@ def collect_latency(bm_name, args): '--benchmark_filter=^%s$' % line, '--benchmark_min_time=0.05' ], - environ={'LATENCY_TRACE': '%s.trace' % fnize(line)}, + environ={'GRPC_LATENCY_TRACE': '%s.trace' % fnize(line)}, shortname='profile-%s' % fnize(line))) profile_analysis.append( jobset.JobSpec( diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py index 549ae14f5ab..ce9ff0dae21 100755 --- a/tools/run_tests/sanity/core_banned_functions.py +++ b/tools/run_tests/sanity/core_banned_functions.py @@ -45,10 +45,6 @@ BANNED_EXCEPT = { 'grpc_closure_sched(': ['src/core/lib/iomgr/closure.cc'], 'grpc_closure_run(': ['src/core/lib/iomgr/closure.cc'], 'grpc_closure_list_sched(': ['src/core/lib/iomgr/closure.cc'], - 'gpr_getenv_silent(': [ - 'src/core/lib/gpr/log.cc', 'src/core/lib/gpr/env_linux.cc', - 'src/core/lib/gpr/env_posix.cc', 'src/core/lib/gpr/env_windows.cc' - ], } errors = 0 From 12fbdaa6a87ba6c2ec66b168d7e6d0f410702450 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 9 May 2019 14:17:30 -0700 Subject: [PATCH 2127/2143] Fix ref-counting bug in health check client. --- .../health/health_check_client.cc | 43 ++++++++++--------- .../health/health_check_client.h | 8 ++-- 2 files changed, 28 insertions(+), 23 deletions(-) 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 a4467236662..bfac773899d 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 @@ -277,8 +277,7 @@ bool DecodeResponse(grpc_slice_buffer* slice_buffer, grpc_error** error) { HealthCheckClient::CallState::CallState( RefCountedPtr health_check_client, grpc_pollset_set* interested_parties) - : InternallyRefCounted(&grpc_health_check_client_trace), - health_check_client_(std::move(health_check_client)), + : health_check_client_(std::move(health_check_client)), pollent_(grpc_polling_entity_create_from_pollset_set(interested_parties)), arena_(Arena::Create(health_check_client_->connected_subchannel_ ->GetInitialCallSizeEstimate(0))), @@ -322,7 +321,8 @@ void HealthCheckClient::CallState::StartCall() { 0, // parent_data_size }; grpc_error* error = GRPC_ERROR_NONE; - call_ = health_check_client_->connected_subchannel_->CreateCall(args, &error); + call_ = health_check_client_->connected_subchannel_->CreateCall(args, &error) + .release(); if (error != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "HealthCheckClient %p CallState %p: error creating health " @@ -331,18 +331,22 @@ void HealthCheckClient::CallState::StartCall() { GRPC_ERROR_UNREF(error); // Schedule instead of running directly, since we must not be // holding health_check_client_->mu_ when CallEnded() is called. - Ref(DEBUG_LOCATION, "call_end_closure").release(); + call_->Ref(DEBUG_LOCATION, "call_end_closure").release(); GRPC_CLOSURE_SCHED( GRPC_CLOSURE_INIT(&batch_.handler_private.closure, CallEndedRetry, this, grpc_schedule_on_exec_ctx), GRPC_ERROR_NONE); return; } + // Register after-destruction callback. + GRPC_CLOSURE_INIT(&after_call_stack_destruction_, AfterCallStackDestruction, + this, grpc_schedule_on_exec_ctx); + call_->SetAfterCallStackDestroy(&after_call_stack_destruction_); // Initialize payload and batch. payload_.context = context_; batch_.payload = &payload_; // on_complete callback takes ref, handled manually. - Ref(DEBUG_LOCATION, "on_complete").release(); + call_->Ref(DEBUG_LOCATION, "on_complete").release(); batch_.on_complete = GRPC_CLOSURE_INIT(&on_complete_, OnComplete, this, grpc_schedule_on_exec_ctx); // Add send_initial_metadata op. @@ -375,7 +379,7 @@ void HealthCheckClient::CallState::StartCall() { payload_.recv_initial_metadata.trailing_metadata_available = nullptr; payload_.recv_initial_metadata.peer_string = nullptr; // recv_initial_metadata_ready callback takes ref, handled manually. - Ref(DEBUG_LOCATION, "recv_initial_metadata_ready").release(); + call_->Ref(DEBUG_LOCATION, "recv_initial_metadata_ready").release(); payload_.recv_initial_metadata.recv_initial_metadata_ready = GRPC_CLOSURE_INIT(&recv_initial_metadata_ready_, RecvInitialMetadataReady, this, grpc_schedule_on_exec_ctx); @@ -383,7 +387,7 @@ void HealthCheckClient::CallState::StartCall() { // Add recv_message op. payload_.recv_message.recv_message = &recv_message_; // recv_message callback takes ref, handled manually. - Ref(DEBUG_LOCATION, "recv_message_ready").release(); + call_->Ref(DEBUG_LOCATION, "recv_message_ready").release(); payload_.recv_message.recv_message_ready = GRPC_CLOSURE_INIT( &recv_message_ready_, RecvMessageReady, this, grpc_schedule_on_exec_ctx); batch_.recv_message = true; @@ -419,7 +423,7 @@ void HealthCheckClient::CallState::StartBatchInCallCombiner(void* arg, 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, @@ -430,7 +434,7 @@ void HealthCheckClient::CallState::AfterCallStackDestruction( void* arg, grpc_error* error) { HealthCheckClient::CallState* self = static_cast(arg); - self->Unref(DEBUG_LOCATION, "cancel"); + Delete(self); } void HealthCheckClient::CallState::OnCancelComplete(void* arg, @@ -438,10 +442,7 @@ void HealthCheckClient::CallState::OnCancelComplete(void* arg, HealthCheckClient::CallState* self = static_cast(arg); GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "health_cancel"); - GRPC_CLOSURE_INIT(&self->after_call_stack_destruction_, - AfterCallStackDestruction, self, grpc_schedule_on_exec_ctx); - self->call_->SetAfterCallStackDestroy(&self->after_call_stack_destruction_); - self->call_.reset(); + self->call_->Unref(DEBUG_LOCATION, "cancel"); } void HealthCheckClient::CallState::StartCancel(void* arg, grpc_error* error) { @@ -458,7 +459,7 @@ void HealthCheckClient::CallState::Cancel() { bool expected = false; if (cancelled_.CompareExchangeStrong(&expected, true, MemoryOrder::ACQ_REL, MemoryOrder::ACQUIRE)) { - Ref(DEBUG_LOCATION, "cancel").release(); + call_->Ref(DEBUG_LOCATION, "cancel").release(); GRPC_CALL_COMBINER_START( &call_combiner_, GRPC_CLOSURE_CREATE(StartCancel, this, grpc_schedule_on_exec_ctx), @@ -472,7 +473,7 @@ void HealthCheckClient::CallState::OnComplete(void* arg, grpc_error* error) { GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "on_complete"); grpc_metadata_batch_destroy(&self->send_initial_metadata_); grpc_metadata_batch_destroy(&self->send_trailing_metadata_); - self->Unref(DEBUG_LOCATION, "on_complete"); + self->call_->Unref(DEBUG_LOCATION, "on_complete"); } void HealthCheckClient::CallState::RecvInitialMetadataReady(void* arg, @@ -481,7 +482,7 @@ void HealthCheckClient::CallState::RecvInitialMetadataReady(void* arg, static_cast(arg); GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "recv_initial_metadata_ready"); grpc_metadata_batch_destroy(&self->recv_initial_metadata_); - self->Unref(DEBUG_LOCATION, "recv_initial_metadata_ready"); + self->call_->Unref(DEBUG_LOCATION, "recv_initial_metadata_ready"); } void HealthCheckClient::CallState::DoneReadingRecvMessage(grpc_error* error) { @@ -490,7 +491,7 @@ void HealthCheckClient::CallState::DoneReadingRecvMessage(grpc_error* error) { GRPC_ERROR_UNREF(error); Cancel(); grpc_slice_buffer_destroy_internal(&recv_message_buffer_); - Unref(DEBUG_LOCATION, "recv_message_ready"); + call_->Unref(DEBUG_LOCATION, "recv_message_ready"); return; } const bool healthy = DecodeResponse(&recv_message_buffer_, &error); @@ -563,7 +564,7 @@ void HealthCheckClient::CallState::RecvMessageReady(void* arg, static_cast(arg); GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "recv_message_ready"); if (self->recv_message_ == nullptr) { - self->Unref(DEBUG_LOCATION, "recv_message_ready"); + self->call_->Unref(DEBUG_LOCATION, "recv_message_ready"); return; } grpc_slice_buffer_init(&self->recv_message_buffer_); @@ -621,7 +622,7 @@ void HealthCheckClient::CallState::CallEndedRetry(void* arg, HealthCheckClient::CallState* self = static_cast(arg); self->CallEnded(true /* retry */); - self->Unref(DEBUG_LOCATION, "call_end_closure"); + self->call_->Unref(DEBUG_LOCATION, "call_end_closure"); } void HealthCheckClient::CallState::CallEnded(bool retry) { @@ -644,7 +645,9 @@ void HealthCheckClient::CallState::CallEnded(bool retry) { } } } - Unref(DEBUG_LOCATION, "call_ended"); + // When the last ref to the call stack goes away, the CallState object + // will be automatically destroyed. + call_->Unref(DEBUG_LOCATION, "call_ended"); } } // namespace grpc_core 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 daf61c38155..956c1095550 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 @@ -61,7 +61,7 @@ class HealthCheckClient : public InternallyRefCounted { private: // Contains a call to the backend and all the data related to the call. - class CallState : public InternallyRefCounted { + class CallState : public Orphanable { public: CallState(RefCountedPtr health_check_client, grpc_pollset_set* interested_parties_); @@ -101,8 +101,10 @@ class HealthCheckClient : public InternallyRefCounted { grpc_core::CallCombiner call_combiner_; grpc_call_context_element context_[GRPC_CONTEXT_COUNT] = {}; - // The streaming call to the backend. Always non-NULL. - RefCountedPtr call_; + // The streaming call to the backend. Always non-null. + // Refs are tracked manually; when the last ref is released, the + // CallState object will be automatically destroyed. + SubchannelCall* call_; grpc_transport_stream_op_batch_payload payload_; grpc_transport_stream_op_batch batch_; From d56bbf19d263b0cf94e1ff5c34650741231cf455 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 9 May 2019 15:50:52 -0700 Subject: [PATCH 2128/2143] Reviewer comments --- .../filters/client_channel/client_channel.cc | 121 +++++++++--------- 1 file changed, 60 insertions(+), 61 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 21f63348f54..f774c985c30 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -234,7 +234,7 @@ class ChannelData { void ProcessLbPolicy( const Resolver::Result& resolver_result, - const internal::ClientChannelGlobalParsedObject* parsed_object, + const internal::ClientChannelGlobalParsedObject* parsed_service_config, UniquePtr* lb_policy_name, RefCountedPtr* lb_policy_config); @@ -1152,52 +1152,50 @@ ChannelData::~ChannelData() { void ChannelData::ProcessLbPolicy( const Resolver::Result& resolver_result, - const internal::ClientChannelGlobalParsedObject* parsed_object, + const internal::ClientChannelGlobalParsedObject* parsed_service_config, UniquePtr* lb_policy_name, RefCountedPtr* lb_policy_config) { // Prefer the LB policy name found in the service config. - if (parsed_object != nullptr && - parsed_object->parsed_lb_config() != nullptr) { + if (parsed_service_config != nullptr && + parsed_service_config->parsed_lb_config() != nullptr) { lb_policy_name->reset( - gpr_strdup(parsed_object->parsed_lb_config()->name())); - *lb_policy_config = parsed_object->parsed_lb_config(); - } else { - const char* local_policy_name = nullptr; - if (parsed_object != nullptr && - parsed_object->parsed_deprecated_lb_policy() != nullptr) { - local_policy_name = parsed_object->parsed_deprecated_lb_policy(); - } else { - const grpc_arg* channel_arg = - grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME); - local_policy_name = 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. - 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 (local_policy_name != nullptr && - strcmp(local_policy_name, "grpclb") != 0) { - gpr_log(GPR_INFO, - "resolver requested LB policy %s but provided at least one " - "balancer address -- forcing use of grpclb LB policy", - local_policy_name); - } - local_policy_name = "grpclb"; - } - // Use pick_first if nothing was specified and we didn't select grpclb - // above. - if (local_policy_name == nullptr) { - local_policy_name = "pick_first"; - } - lb_policy_name->reset(gpr_strdup(local_policy_name)); + gpr_strdup(parsed_service_config->parsed_lb_config()->name())); + *lb_policy_config = parsed_service_config->parsed_lb_config(); + return; } + const char* local_policy_name = nullptr; + if (parsed_service_config != nullptr && + parsed_service_config->parsed_deprecated_lb_policy() != nullptr) { + local_policy_name = parsed_service_config->parsed_deprecated_lb_policy(); + } else { + const grpc_arg* channel_arg = + grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME); + local_policy_name = 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. + 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 (local_policy_name != nullptr && + strcmp(local_policy_name, "grpclb") != 0) { + gpr_log(GPR_INFO, + "resolver requested LB policy %s but provided at least one " + "balancer address -- forcing use of grpclb LB policy", + local_policy_name); + } + local_policy_name = "grpclb"; + } + // Use pick_first if nothing was specified and we didn't select grpclb + // above. + lb_policy_name->reset(gpr_strdup( + local_policy_name == nullptr ? "pick_first" : local_policy_name)); } // Synchronous callback from ResolvingLoadBalancingPolicy to process a @@ -1209,11 +1207,11 @@ bool ChannelData::ProcessResolverResultLocked( ChannelData* chand = static_cast(arg); RefCountedPtr service_config; // If resolver did not return a service config or returned an invalid service - // config, we need a fallback service config + // config, we need a fallback service config. if (result.service_config_error != GRPC_ERROR_NONE) { - // If the service config was invalid, then prefer using the saved service - // config, otherwise use the default service config provided by the client - // API + // If the service config was invalid, then fallback to the saved service + // config. If there is no saved config either, use the default service + // config. if (chand->saved_service_config_ != nullptr) { service_config = chand->saved_service_config_; if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { @@ -1232,13 +1230,13 @@ bool ChannelData::ProcessResolverResultLocked( service_config = chand->default_service_config_; } } else if (result.service_config == nullptr) { - if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { - gpr_log(GPR_INFO, - "chand=%p: resolver returned no service config. Using default " - "service config provided by client API.", - chand); - } if (chand->default_service_config_ != nullptr) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, + "chand=%p: resolver returned no service config. Using default " + "service config provided by client API.", + chand); + } service_config = chand->default_service_config_; } } else { @@ -1251,9 +1249,10 @@ bool ChannelData::ProcessResolverResultLocked( } UniquePtr service_config_json; // Process service config. - const internal::ClientChannelGlobalParsedObject* parsed_object = nullptr; + const internal::ClientChannelGlobalParsedObject* parsed_service_config = + nullptr; if (service_config != nullptr) { - parsed_object = + parsed_service_config = static_cast( service_config->GetParsedGlobalServiceConfigObject( internal::ClientChannelServiceConfigParser::ParserIndex())); @@ -1274,22 +1273,22 @@ bool ChannelData::ProcessResolverResultLocked( chand, service_config_json.get()); } chand->saved_service_config_ = std::move(service_config); - if (parsed_object != nullptr) { + if (parsed_service_config != nullptr) { chand->health_check_service_name_.reset( - gpr_strdup(parsed_object->health_check_service_name())); + gpr_strdup(parsed_service_config->health_check_service_name())); } else { chand->health_check_service_name_.reset(); } } - // We want to set the service config atleast once. This should not really be + // We want to set the service config at least once. This should not really be // needed, but we are doing it as a defensive approach. This can be removed, // if we feel it is unnecessary. if (service_config_changed || !chand->received_first_resolver_result_) { chand->received_first_resolver_result_ = true; Optional retry_throttle_data; - if (parsed_object != nullptr) { - retry_throttle_data = parsed_object->retry_throttling(); + if (parsed_service_config != nullptr) { + retry_throttle_data = parsed_service_config->retry_throttling(); } // Create service config setter to update channel state in the data // plane combiner. Destroys itself when done. @@ -1297,8 +1296,8 @@ bool ChannelData::ProcessResolverResultLocked( chand->saved_service_config_); } UniquePtr processed_lb_policy_name; - chand->ProcessLbPolicy(result, parsed_object, &processed_lb_policy_name, - lb_policy_config); + chand->ProcessLbPolicy(result, parsed_service_config, + &processed_lb_policy_name, lb_policy_config); // Swap out the data used by GetChannelInfo(). { MutexLock lock(&chand->info_mu_); From a8139b4da12beb0663e7f58b2a25d58c51d77f00 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 9 May 2019 16:54:22 -0700 Subject: [PATCH 2129/2143] Fix node interop build scripts --- .../interoptest/grpc_interop_node/build_interop.sh | 4 +--- .../interoptest/grpc_interop_nodepurejs/build_interop.sh | 6 +----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh index c16efc1d354..aeb82e0c9c3 100755 --- a/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh @@ -29,6 +29,4 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-node # build Node interop client & server -npm install -g node-gyp gulp -npm install -gulp setup +./setup_interop.sh diff --git a/tools/dockerfile/interoptest/grpc_interop_nodepurejs/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_nodepurejs/build_interop.sh index d41ccacd2f9..db55f5a19f3 100755 --- a/tools/dockerfile/interoptest/grpc_interop_nodepurejs/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_nodepurejs/build_interop.sh @@ -29,8 +29,4 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-node # build Node interop client & server -npm install -g gulp -npm install -gulp js.core.install -gulp protobuf.install -gulp internal.test.install +./setup_interop_purejs.sh From a4d4bb82c98bfb103dae818b5cdf4a32704f9cd0 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 10 May 2019 07:57:11 -0700 Subject: [PATCH 2130/2143] Revamp subchannel connectivity state monitoring APIs. --- .../filters/client_channel/client_channel.cc | 51 +- .../client_channel/client_channel_channelz.cc | 4 +- .../lb_policy/pick_first/pick_first.cc | 29 +- .../lb_policy/round_robin/round_robin.cc | 10 +- .../lb_policy/subchannel_list.h | 360 +++++++------- .../client_channel/resolving_lb_policy.cc | 2 +- .../client_channel/resolving_lb_policy.h | 3 +- .../ext/filters/client_channel/subchannel.cc | 452 +++++++++++------- .../ext/filters/client_channel/subchannel.h | 138 +++++- test/cpp/end2end/client_lb_end2end_test.cc | 67 ++- 10 files changed, 674 insertions(+), 442 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index f774c985c30..757ac2a35e7 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -222,7 +222,7 @@ class ChannelData { ~ChannelData(); static bool ProcessResolverResultLocked( - void* arg, const Resolver::Result& result, const char** lb_policy_name, + void* arg, Resolver::Result* result, const char** lb_policy_name, RefCountedPtr* lb_policy_config, grpc_error** service_config_error); @@ -271,7 +271,6 @@ class ChannelData { OrphanablePtr resolving_lb_policy_; grpc_connectivity_state_tracker state_tracker_; ExternalConnectivityWatcher::WatcherList external_connectivity_watcher_list_; - UniquePtr health_check_service_name_; RefCountedPtr saved_service_config_; bool received_first_resolver_result_ = false; @@ -951,18 +950,10 @@ class ChannelData::ClientChannelControlHelper } Subchannel* CreateSubchannel(const grpc_channel_args& args) override { - grpc_arg args_to_add[2]; - int num_args_to_add = 0; - if (chand_->health_check_service_name_ != nullptr) { - args_to_add[0] = grpc_channel_arg_string_create( - const_cast("grpc.temp.health_check"), - const_cast(chand_->health_check_service_name_.get())); - num_args_to_add++; - } - args_to_add[num_args_to_add++] = SubchannelPoolInterface::CreateChannelArg( + grpc_arg arg = SubchannelPoolInterface::CreateChannelArg( chand_->subchannel_pool_.get()); grpc_channel_args* new_args = - grpc_channel_args_copy_and_add(&args, args_to_add, num_args_to_add); + grpc_channel_args_copy_and_add(&args, &arg, 1); Subchannel* subchannel = chand_->client_channel_factory_->CreateSubchannel(new_args); grpc_channel_args_destroy(new_args); @@ -1201,14 +1192,14 @@ void ChannelData::ProcessLbPolicy( // Synchronous callback from ResolvingLoadBalancingPolicy to process a // resolver result update. bool ChannelData::ProcessResolverResultLocked( - void* arg, const Resolver::Result& result, const char** lb_policy_name, + void* arg, Resolver::Result* result, const char** lb_policy_name, RefCountedPtr* lb_policy_config, grpc_error** service_config_error) { ChannelData* chand = static_cast(arg); RefCountedPtr service_config; // If resolver did not return a service config or returned an invalid service // config, we need a fallback service config. - if (result.service_config_error != GRPC_ERROR_NONE) { + if (result->service_config_error != GRPC_ERROR_NONE) { // If the service config was invalid, then fallback to the saved service // config. If there is no saved config either, use the default service // config. @@ -1229,7 +1220,7 @@ bool ChannelData::ProcessResolverResultLocked( } service_config = chand->default_service_config_; } - } else if (result.service_config == nullptr) { + } else if (result->service_config == nullptr) { if (chand->default_service_config_ != nullptr) { if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { gpr_log(GPR_INFO, @@ -1240,15 +1231,15 @@ bool ChannelData::ProcessResolverResultLocked( service_config = chand->default_service_config_; } } else { - service_config = result.service_config; + service_config = result->service_config; } - *service_config_error = GRPC_ERROR_REF(result.service_config_error); + *service_config_error = GRPC_ERROR_REF(result->service_config_error); if (service_config == nullptr && - result.service_config_error != GRPC_ERROR_NONE) { + result->service_config_error != GRPC_ERROR_NONE) { return false; } - UniquePtr service_config_json; // Process service config. + UniquePtr service_config_json; const internal::ClientChannelGlobalParsedObject* parsed_service_config = nullptr; if (service_config != nullptr) { @@ -1257,6 +1248,20 @@ bool ChannelData::ProcessResolverResultLocked( service_config->GetParsedGlobalServiceConfigObject( internal::ClientChannelServiceConfigParser::ParserIndex())); } + // TODO(roth): Eliminate this hack as part of hiding health check + // service name from LB policy API. As part of this, change the API + // for this function to pass in result as a const reference. + if (parsed_service_config != nullptr && + parsed_service_config->health_check_service_name() != nullptr) { + grpc_arg new_arg = grpc_channel_arg_string_create( + const_cast("grpc.temp.health_check"), + const_cast(parsed_service_config->health_check_service_name())); + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(result->args, &new_arg, 1); + grpc_channel_args_destroy(result->args); + result->args = new_args; + } + // Check if the config has changed. const bool service_config_changed = ((service_config == nullptr) != (chand->saved_service_config_ == nullptr)) || @@ -1273,12 +1278,6 @@ bool ChannelData::ProcessResolverResultLocked( chand, service_config_json.get()); } chand->saved_service_config_ = std::move(service_config); - if (parsed_service_config != nullptr) { - chand->health_check_service_name_.reset( - gpr_strdup(parsed_service_config->health_check_service_name())); - } else { - chand->health_check_service_name_.reset(); - } } // We want to set the service config at least once. This should not really be // needed, but we are doing it as a defensive approach. This can be removed, @@ -1296,7 +1295,7 @@ bool ChannelData::ProcessResolverResultLocked( chand->saved_service_config_); } UniquePtr processed_lb_policy_name; - chand->ProcessLbPolicy(result, parsed_service_config, + chand->ProcessLbPolicy(*result, parsed_service_config, &processed_lb_policy_name, lb_policy_config); // Swap out the data used by GetChannelInfo(). { 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 a7a47e9eb10..de61819ef54 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -127,7 +127,9 @@ void SubchannelNode::PopulateConnectivityState(grpc_json* json) { if (subchannel_ == nullptr) { state = GRPC_CHANNEL_SHUTDOWN; } else { - state = subchannel_->CheckConnectivity(true /* inhibit_health_checking */); + state = subchannel_->CheckConnectivityState( + nullptr /* health_check_service_name */, + nullptr /* connected_subchannel */); } json = grpc_json_create_child(nullptr, json, "state", nullptr, GRPC_JSON_OBJECT, false); 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 bc2f6e5efd6..199e973e72c 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 @@ -68,9 +68,8 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, Subchannel* subchannel, - grpc_combiner* combiner) - : SubchannelData(subchannel_list, address, subchannel, combiner) {} + const ServerAddress& address, Subchannel* subchannel) + : SubchannelData(subchannel_list, address, subchannel) {} void ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state) override; @@ -312,6 +311,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) { // here, since we've already checked the initial connectivity // state of all subchannels above. subchannel_list_->subchannel(0)->StartConnectivityWatchLocked(); + subchannel_list_->subchannel(0)->subchannel()->AttemptToConnect(); } } else { // We do have a selected subchannel (which means it's READY), so keep @@ -334,6 +334,9 @@ void PickFirst::UpdateLocked(UpdateArgs args) { // state of all subchannels above. latest_pending_subchannel_list_->subchannel(0) ->StartConnectivityWatchLocked(); + latest_pending_subchannel_list_->subchannel(0) + ->subchannel() + ->AttemptToConnect(); } } } @@ -366,7 +369,8 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( p->subchannel_list_.get()); } p->selected_ = nullptr; - StopConnectivityWatchLocked(); + CancelConnectivityWatchLocked( + "selected subchannel failed; switching to pending update"); p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); // Set our state to that of the pending subchannel list. if (p->subchannel_list_->in_transient_failure()) { @@ -391,7 +395,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( p->idle_ = true; p->channel_control_helper()->RequestReresolution(); p->selected_ = nullptr; - StopConnectivityWatchLocked(); + CancelConnectivityWatchLocked("selected subchannel failed; going IDLE"); p->channel_control_helper()->UpdateState( GRPC_CHANNEL_IDLE, UniquePtr(New(p->Ref()))); @@ -408,8 +412,6 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( connectivity_state, UniquePtr(New(p->Ref()))); } - // Renew notification. - RenewConnectivityWatchLocked(); } } return; @@ -426,13 +428,11 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( subchannel_list()->set_in_transient_failure(false); switch (connectivity_state) { case GRPC_CHANNEL_READY: { - // Renew notification. - RenewConnectivityWatchLocked(); ProcessUnselectedReadyLocked(); break; } case GRPC_CHANNEL_TRANSIENT_FAILURE: { - StopConnectivityWatchLocked(); + CancelConnectivityWatchLocked("connection attempt failed"); PickFirstSubchannelData* sd = this; size_t next_index = (sd->Index() + 1) % subchannel_list()->num_subchannels(); @@ -468,8 +468,6 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( GRPC_CHANNEL_CONNECTING, UniquePtr(New(p->Ref()))); } - // Renew notification. - RenewConnectivityWatchLocked(); break; } case GRPC_CHANNEL_SHUTDOWN: @@ -521,8 +519,11 @@ void PickFirst::PickFirstSubchannelData:: // 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(); + // If the current state is not READY, attempt to connect. + if (current_state == GRPC_CHANNEL_READY) { + if (p->selected_ != this) ProcessUnselectedReadyLocked(); + } else { + subchannel()->AttemptToConnect(); } } 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 6d603913d82..1693032ea24 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 @@ -83,9 +83,8 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, Subchannel* subchannel, - grpc_combiner* combiner) - : SubchannelData(subchannel_list, address, subchannel, combiner) {} + const ServerAddress& address, Subchannel* subchannel) + : SubchannelData(subchannel_list, address, subchannel) {} grpc_connectivity_state connectivity_state() const { return last_connectivity_state_; @@ -320,6 +319,7 @@ void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() { for (size_t i = 0; i < num_subchannels(); i++) { if (subchannel(i)->subchannel() != nullptr) { subchannel(i)->StartConnectivityWatchLocked(); + subchannel(i)->subchannel()->AttemptToConnect(); } } // Now set the LB policy's state based on the subchannels' states. @@ -448,6 +448,7 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( // Otherwise, if the subchannel was already in state TRANSIENT_FAILURE // when the subchannel list was created, we'd wind up in a constant // loop of re-resolution. + // Also attempt to reconnect. if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, @@ -456,9 +457,8 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( p, subchannel()); } p->channel_control_helper()->RequestReresolution(); + subchannel()->AttemptToConnect(); } - // Renew connectivity watch. - RenewConnectivityWatchLocked(); // Update state counters. UpdateConnectivityStateLocked(connectivity_state); // Update overall state and renew notification. 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 4c48045f978..93b4bbd369a 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 @@ -98,15 +98,13 @@ class SubchannelData { // Synchronously checks the subchannel's connectivity state. // Must not be called while there is a connectivity notification - // pending (i.e., between calling StartConnectivityWatchLocked() or - // RenewConnectivityWatchLocked() and the resulting invocation of - // ProcessConnectivityChangeLocked()). + // pending (i.e., between calling StartConnectivityWatchLocked() and + // calling CancelConnectivityWatchLocked()). grpc_connectivity_state CheckConnectivityStateLocked() { - GPR_ASSERT(!connectivity_notification_pending_); - pending_connectivity_state_unsafe_ = subchannel()->CheckConnectivity( - subchannel_list_->inhibit_health_checking()); - UpdateConnectedSubchannelLocked(); - return pending_connectivity_state_unsafe_; + GPR_ASSERT(pending_watcher_ == nullptr); + connectivity_state_ = subchannel()->CheckConnectivityState( + subchannel_list_->health_check_service_name(), &connected_subchannel_); + return connectivity_state_; } // Resets the connection backoff. @@ -115,23 +113,11 @@ class SubchannelData { void ResetBackoffLocked(); // Starts watching the connectivity state of the subchannel. - // ProcessConnectivityChangeLocked() will be called when the + // ProcessConnectivityChangeLocked() will be called whenever the // connectivity state changes. void StartConnectivityWatchLocked(); - // Renews watching the connectivity state of the subchannel. - void RenewConnectivityWatchLocked(); - - // Stops watching the connectivity state of the subchannel. - void StopConnectivityWatchLocked(); - // Cancels watching the connectivity state of the subchannel. - // Must be called only while there is a connectivity notification - // pending (i.e., between calling StartConnectivityWatchLocked() or - // RenewConnectivityWatchLocked() and the resulting invocation of - // ProcessConnectivityChangeLocked()). - // From within ProcessConnectivityChangeLocked(), use - // StopConnectivityWatchLocked() instead. void CancelConnectivityWatchLocked(const char* reason); // Cancels any pending connectivity watch and unrefs the subchannel. @@ -142,44 +128,80 @@ class SubchannelData { protected: SubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, Subchannel* subchannel, - grpc_combiner* combiner); + const ServerAddress& address, Subchannel* subchannel); virtual ~SubchannelData(); - // After StartConnectivityWatchLocked() or RenewConnectivityWatchLocked() - // is called, this method will be invoked when the subchannel's connectivity - // state changes. - // Implementations must invoke either RenewConnectivityWatchLocked() or - // StopConnectivityWatchLocked() before returning. + // After StartConnectivityWatchLocked() is called, this method will be + // invoked whenever the subchannel's connectivity state changes. + // To stop watching, use CancelConnectivityWatchLocked(). virtual void ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state) GRPC_ABSTRACT; + private: + // Watcher for subchannel connectivity state. + class Watcher : public Subchannel::ConnectivityStateWatcher { + public: + Watcher( + SubchannelData* subchannel_data, + RefCountedPtr subchannel_list) + : subchannel_data_(subchannel_data), + subchannel_list_(std::move(subchannel_list)) {} + + ~Watcher() { subchannel_list_.reset(DEBUG_LOCATION, "Watcher dtor"); } + + void OnConnectivityStateChange( + grpc_connectivity_state new_state, + RefCountedPtr connected_subchannel) override; + + grpc_pollset_set* interested_parties() override { + return subchannel_list_->policy()->interested_parties(); + } + + private: + // A fire-and-forget class that bounces into the combiner to process + // a connectivity state update. + class Updater { + public: + Updater( + SubchannelData* + subchannel_data, + RefCountedPtr> + subchannel_list, + grpc_connectivity_state state, + RefCountedPtr connected_subchannel); + + ~Updater() { + subchannel_list_.reset(DEBUG_LOCATION, "Watcher::Updater dtor"); + } + + private: + static void OnUpdateLocked(void* arg, grpc_error* error); + + SubchannelData* subchannel_data_; + RefCountedPtr> + subchannel_list_; + const grpc_connectivity_state state_; + RefCountedPtr connected_subchannel_; + grpc_closure closure_; + }; + + SubchannelData* subchannel_data_; + RefCountedPtr subchannel_list_; + }; + // Unrefs the subchannel. void UnrefSubchannelLocked(const char* reason); - private: - // Updates connected_subchannel_ based on pending_connectivity_state_unsafe_. - // Returns true if the connectivity state should be reported. - bool UpdateConnectedSubchannelLocked(); - - static void OnConnectivityChangedLocked(void* arg, grpc_error* error); - // Backpointer to owning subchannel list. Not owned. SubchannelList* subchannel_list_; - - // The subchannel and connected subchannel. + // The subchannel. Subchannel* subchannel_; + // Will be non-null when the subchannel's state is being watched. + Subchannel::ConnectivityStateWatcher* pending_watcher_ = nullptr; + // Data updated by the watcher. + grpc_connectivity_state connectivity_state_; RefCountedPtr connected_subchannel_; - - // Notification that connectivity has changed on subchannel. - grpc_closure connectivity_changed_closure_; - // Is a connectivity notification pending? - bool connectivity_notification_pending_ = false; - // Connectivity state to be updated by - // grpc_subchannel_notify_on_state_change(), not guarded by - // the combiner. - grpc_connectivity_state pending_connectivity_state_unsafe_; }; // A list of subchannels. @@ -213,7 +235,9 @@ class SubchannelList : public InternallyRefCounted { // Accessors. LoadBalancingPolicy* policy() const { return policy_; } TraceFlag* tracer() const { return tracer_; } - bool inhibit_health_checking() const { return inhibit_health_checking_; } + const char* health_check_service_name() const { + return health_check_service_name_.get(); + } // Resets connection backoff of all subchannels. // TODO(roth): We will probably need to rethink this as part of moving @@ -251,7 +275,7 @@ class SubchannelList : public InternallyRefCounted { TraceFlag* tracer_; - bool inhibit_health_checking_; + UniquePtr health_check_service_name_; grpc_combiner* combiner_; @@ -268,6 +292,67 @@ class SubchannelList : public InternallyRefCounted { // implementation -- no user-servicable parts below // +// +// SubchannelData::Watcher +// + +template +void SubchannelData::Watcher:: + OnConnectivityStateChange( + grpc_connectivity_state new_state, + RefCountedPtr connected_subchannel) { + // Will delete itself. + New(subchannel_data_, + subchannel_list_->Ref(DEBUG_LOCATION, "Watcher::Updater"), + new_state, std::move(connected_subchannel)); +} + +template +SubchannelData::Watcher::Updater:: + Updater( + SubchannelData* subchannel_data, + RefCountedPtr> + subchannel_list, + grpc_connectivity_state state, + RefCountedPtr connected_subchannel) + : subchannel_data_(subchannel_data), + subchannel_list_(std::move(subchannel_list)), + state_(state), + connected_subchannel_(std::move(connected_subchannel)) { + GRPC_CLOSURE_INIT(&closure_, &OnUpdateLocked, this, + grpc_combiner_scheduler(subchannel_list_->combiner_)); + GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); +} + +template +void SubchannelData::Watcher::Updater:: + OnUpdateLocked(void* arg, grpc_error* error) { + Updater* self = static_cast(arg); + SubchannelData* sd = self->subchannel_data_; + if (GRPC_TRACE_FLAG_ENABLED(*sd->subchannel_list_->tracer())) { + gpr_log(GPR_INFO, + "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR + " (subchannel %p): connectivity changed: state=%s, " + "connected_subchannel=%p, shutting_down=%d, pending_watcher=%p", + sd->subchannel_list_->tracer()->name(), + sd->subchannel_list_->policy(), sd->subchannel_list_, sd->Index(), + sd->subchannel_list_->num_subchannels(), sd->subchannel_, + grpc_connectivity_state_name(self->state_), + self->connected_subchannel_.get(), + sd->subchannel_list_->shutting_down(), sd->pending_watcher_); + } + if (!sd->subchannel_list_->shutting_down() && + sd->pending_watcher_ != nullptr) { + sd->connectivity_state_ = self->state_; + // Get or release ref to connected subchannel. + sd->connected_subchannel_ = std::move(self->connected_subchannel_); + // Call the subclass's ProcessConnectivityChangeLocked() method. + sd->ProcessConnectivityChangeLocked(sd->connectivity_state_); + } + // Clean up. + Delete(self); +} + // // SubchannelData // @@ -275,23 +360,16 @@ class SubchannelList : public InternallyRefCounted { template SubchannelData::SubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, Subchannel* subchannel, - grpc_combiner* combiner) + const ServerAddress& address, Subchannel* subchannel) : subchannel_list_(subchannel_list), subchannel_(subchannel), // We assume that the current state is IDLE. If not, we'll get a // callback telling us that. - pending_connectivity_state_unsafe_(GRPC_CHANNEL_IDLE) { - GRPC_CLOSURE_INIT( - &connectivity_changed_closure_, - (&SubchannelData::OnConnectivityChangedLocked), - this, grpc_combiner_scheduler(combiner)); -} + connectivity_state_(GRPC_CHANNEL_IDLE) {} template SubchannelData::~SubchannelData() { - UnrefSubchannelLocked("subchannel_data_destroy"); + GPR_ASSERT(subchannel_ == nullptr); } template @@ -326,56 +404,19 @@ void SubchannelDatatracer())) { gpr_log(GPR_INFO, "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR - " (subchannel %p): starting watch: requesting connectivity change " - "notification (from %s)", + " (subchannel %p): starting watch (from %s)", subchannel_list_->tracer()->name(), subchannel_list_->policy(), subchannel_list_, Index(), subchannel_list_->num_subchannels(), - subchannel_, - grpc_connectivity_state_name(pending_connectivity_state_unsafe_)); + subchannel_, grpc_connectivity_state_name(connectivity_state_)); } - GPR_ASSERT(!connectivity_notification_pending_); - connectivity_notification_pending_ = true; - subchannel_list()->Ref(DEBUG_LOCATION, "connectivity_watch").release(); - subchannel_->NotifyOnStateChange( - subchannel_list_->policy()->interested_parties(), - &pending_connectivity_state_unsafe_, &connectivity_changed_closure_, - subchannel_list_->inhibit_health_checking()); -} - -template -void SubchannelData::RenewConnectivityWatchLocked() { - if (GRPC_TRACE_FLAG_ENABLED(*subchannel_list_->tracer())) { - gpr_log(GPR_INFO, - "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR - " (subchannel %p): renewing watch: requesting connectivity change " - "notification (from %s)", - subchannel_list_->tracer()->name(), subchannel_list_->policy(), - subchannel_list_, Index(), subchannel_list_->num_subchannels(), - subchannel_, - grpc_connectivity_state_name(pending_connectivity_state_unsafe_)); - } - GPR_ASSERT(connectivity_notification_pending_); - subchannel_->NotifyOnStateChange( - subchannel_list_->policy()->interested_parties(), - &pending_connectivity_state_unsafe_, &connectivity_changed_closure_, - subchannel_list_->inhibit_health_checking()); -} - -template -void SubchannelData::StopConnectivityWatchLocked() { - if (GRPC_TRACE_FLAG_ENABLED(*subchannel_list_->tracer())) { - gpr_log(GPR_INFO, - "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR - " (subchannel %p): stopping connectivity watch", - subchannel_list_->tracer()->name(), subchannel_list_->policy(), - subchannel_list_, Index(), subchannel_list_->num_subchannels(), - subchannel_); - } - GPR_ASSERT(connectivity_notification_pending_); - connectivity_notification_pending_ = false; - subchannel_list()->Unref(DEBUG_LOCATION, "connectivity_watch"); + GPR_ASSERT(pending_watcher_ == nullptr); + pending_watcher_ = + New(this, subchannel_list()->Ref(DEBUG_LOCATION, "Watcher")); + subchannel_->WatchConnectivityState( + connectivity_state_, + UniquePtr( + gpr_strdup(subchannel_list_->health_check_service_name())), + UniquePtr(pending_watcher_)); } template @@ -389,91 +430,17 @@ void SubchannelData:: subchannel_list_, Index(), subchannel_list_->num_subchannels(), subchannel_, reason); } - GPR_ASSERT(connectivity_notification_pending_); - subchannel_->NotifyOnStateChange(nullptr, nullptr, - &connectivity_changed_closure_, - subchannel_list_->inhibit_health_checking()); -} - -template -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(); - // 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 - // the combiner), then the connected subchannel may have disappeared out - // from under us. In that case, we don't actually want to consider the - // subchannel to be in state READY. Instead, we use IDLE as the - // basis for any future connectivity watch; this is the one state that - // the subchannel will never transition back into, so this ensures - // that we will get a notification for the next state, even if that state - // is READY again (e.g., if the subchannel has transitioned back to - // READY before the next watch gets requested). - if (connected_subchannel_ == nullptr) { - if (GRPC_TRACE_FLAG_ENABLED(*subchannel_list_->tracer())) { - gpr_log(GPR_INFO, - "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR - " (subchannel %p): state is READY but connected subchannel is " - "null; moving to state IDLE", - subchannel_list_->tracer()->name(), subchannel_list_->policy(), - subchannel_list_, Index(), subchannel_list_->num_subchannels(), - subchannel_); - } - pending_connectivity_state_unsafe_ = GRPC_CHANNEL_IDLE; - return false; - } - } else { - // For any state other than READY, unref the connected subchannel. - connected_subchannel_.reset(); + if (pending_watcher_ != nullptr) { + subchannel_->CancelConnectivityStateWatch( + subchannel_list_->health_check_service_name(), pending_watcher_); + pending_watcher_ = nullptr; } - return true; -} - -template -void SubchannelData:: - OnConnectivityChangedLocked(void* arg, grpc_error* error) { - SubchannelData* sd = static_cast(arg); - if (GRPC_TRACE_FLAG_ENABLED(*sd->subchannel_list_->tracer())) { - gpr_log( - GPR_INFO, - "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR - " (subchannel %p): connectivity changed: state=%s, error=%s, " - "shutting_down=%d", - sd->subchannel_list_->tracer()->name(), sd->subchannel_list_->policy(), - sd->subchannel_list_, sd->Index(), - sd->subchannel_list_->num_subchannels(), sd->subchannel_, - grpc_connectivity_state_name(sd->pending_connectivity_state_unsafe_), - grpc_error_string(error), sd->subchannel_list_->shutting_down()); - } - // If shutting down, unref subchannel and stop watching. - if (sd->subchannel_list_->shutting_down() || error == GRPC_ERROR_CANCELLED) { - sd->UnrefSubchannelLocked("connectivity_shutdown"); - sd->StopConnectivityWatchLocked(); - return; - } - // Get or release ref to connected subchannel. - if (!sd->UpdateConnectedSubchannelLocked()) { - // We don't want to report this connectivity state, so renew the watch. - sd->RenewConnectivityWatchLocked(); - return; - } - // Call the subclass's ProcessConnectivityChangeLocked() method. - sd->ProcessConnectivityChangeLocked(sd->pending_connectivity_state_unsafe_); } template void SubchannelData::ShutdownLocked() { - // If there's a pending notification for this subchannel, cancel it; - // the callback is responsible for unreffing the subchannel. - // Otherwise, unref the subchannel directly. - if (connectivity_notification_pending_) { - CancelConnectivityWatchLocked("shutdown"); - } else if (subchannel_ != nullptr) { - UnrefSubchannelLocked("shutdown"); - } + if (pending_watcher_ != nullptr) CancelConnectivityWatchLocked("shutdown"); + UnrefSubchannelLocked("shutdown"); } // @@ -496,14 +463,25 @@ SubchannelList::SubchannelList( tracer_->name(), policy, this, addresses.size()); } subchannels_.reserve(addresses.size()); + // Find health check service name. + const bool inhibit_health_checking = grpc_channel_arg_get_bool( + grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false); + if (!inhibit_health_checking) { + const char* health_check_service_name = grpc_channel_arg_get_string( + grpc_channel_args_find(&args, "grpc.temp.health_check")); + if (health_check_service_name != nullptr) { + health_check_service_name_.reset(gpr_strdup(health_check_service_name)); + } + } // We need to remove the LB addresses in order to be able to compare the // subchannel keys of subchannels from a different batch of addresses. - // We also remove the inhibit-health-checking arg, since we are + // We also remove the health-checking-related args, since we are // handling that here. - 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_INHIBIT_HEALTH_CHECKING}; + // We remove the service config, since it will be passed into the + // subchannel via call context. + static const char* keys_to_remove[] = { + GRPC_ARG_SUBCHANNEL_ADDRESS, "grpc.temp.health_check", + GRPC_ARG_INHIBIT_HEALTH_CHECKING, GRPC_ARG_SERVICE_CONFIG}; // Create a subchannel for each address. for (size_t i = 0; i < addresses.size(); i++) { // TODO(roth): we should ideally hide this from the LB policy code. In @@ -549,7 +527,7 @@ SubchannelList::SubchannelList( address_uri); gpr_free(address_uri); } - subchannels_.emplace_back(this, addresses[i], subchannel, combiner); + subchannels_.emplace_back(this, addresses[i], subchannel); } } 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 b6bc3eabc49..4e383f65dd1 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -536,7 +536,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( if (process_resolver_result_ != nullptr) { grpc_error* service_config_error = GRPC_ERROR_NONE; service_config_changed = process_resolver_result_( - process_resolver_result_user_data_, result, &lb_policy_name, + process_resolver_result_user_data_, &result, &lb_policy_name, &lb_policy_config, &service_config_error); if (service_config_error != GRPC_ERROR_NONE) { service_config_error_string = 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 b7d99dcc7de..0ca6c9563f9 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -69,8 +69,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // empty, it means that we don't have a valid service config to use, and we // should set the channel to be in TRANSIENT_FAILURE. typedef bool (*ProcessResolverResultCallback)( - void* user_data, const Resolver::Result& result, - const char** lb_policy_name, + void* user_data, Resolver::Result* result, const char** lb_policy_name, RefCountedPtr* lb_policy_config, grpc_error** service_config_error); // If error is set when this returns, then construction failed, and diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index a284e692b09..cd778976166 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -303,8 +303,7 @@ void SubchannelCall::IncrementRefCount(const grpc_core::DebugLocation& location, // Subchannel::ConnectedSubchannelStateWatcher // -class Subchannel::ConnectedSubchannelStateWatcher - : public InternallyRefCounted { +class Subchannel::ConnectedSubchannelStateWatcher { public: // Must be instantiated while holding c->mu. explicit ConnectedSubchannelStateWatcher(Subchannel* c) : subchannel_(c) { @@ -312,38 +311,17 @@ class Subchannel::ConnectedSubchannelStateWatcher GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "state_watcher"); GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "connecting"); // Start watching for connectivity state changes. - // 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_); - // 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_); - GRPC_CLOSURE_INIT(&on_health_changed_, OnHealthChanged, this, - grpc_schedule_on_exec_ctx); - Ref().release(); // Ref for health callback tracked manually. - health_check_client_->NotifyOnHealthChange(&health_state_, - &on_health_changed_); - health_state = GRPC_CHANNEL_CONNECTING; - } - // Report initial state. - c->SetConnectivityStateLocked(GRPC_CHANNEL_READY, "subchannel_connected"); - grpc_connectivity_state_set(&c->state_and_health_tracker_, health_state, - "subchannel_connected"); } ~ConnectedSubchannelStateWatcher() { GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "state_watcher"); } - // Must be called while holding subchannel_->mu. - void Orphan() override { health_check_client_.reset(); } - private: static void OnConnectivityChanged(void* arg, grpc_error* error) { auto* self = static_cast(arg); @@ -363,20 +341,10 @@ class Subchannel::ConnectedSubchannelStateWatcher self->pending_connectivity_state_)); } c->connected_subchannel_.reset(); - c->connected_subchannel_watcher_.reset(); - self->last_connectivity_state_ = GRPC_CHANNEL_TRANSIENT_FAILURE; - c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, - "reflect_child"); - grpc_connectivity_state_set(&c->state_and_health_tracker_, - GRPC_CHANNEL_TRANSIENT_FAILURE, - "reflect_child"); + c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE); c->backoff_begun_ = false; c->backoff_.Reset(); - c->MaybeStartConnectingLocked(); - } else { - self->last_connectivity_state_ = GRPC_CHANNEL_SHUTDOWN; } - self->health_check_client_.reset(); break; } default: { @@ -384,96 +352,246 @@ class Subchannel::ConnectedSubchannelStateWatcher // a callback for READY, because that was the state we started // 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_, - "reflect_child"); - if (self->pending_connectivity_state_ != GRPC_CHANNEL_READY) { - grpc_connectivity_state_set(&c->state_and_health_tracker_, - self->pending_connectivity_state_, - "reflect_child"); - } + c->SetConnectivityStateLocked(self->pending_connectivity_state_); c->connected_subchannel_->NotifyOnStateChange( nullptr, &self->pending_connectivity_state_, &self->on_connectivity_changed_); - self = nullptr; // So we don't unref below. + return; // So we don't delete ourself below. } } } - // Don't unref until we've released the lock, because this might + // Don't delete until we've released the lock, because this might // cause the subchannel (which contains the lock) to be destroyed. - if (self != nullptr) self->Unref(); - } - - 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->health_check_client_ != nullptr) { - if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) { - grpc_connectivity_state_set(&c->state_and_health_tracker_, - self->health_state_, "health_changed"); - } - self->health_check_client_->NotifyOnHealthChange( - &self->health_state_, &self->on_health_changed_); - self = nullptr; // So we don't unref below. - } - } - // 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(); + Delete(self); } 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; +}; + +// +// Subchannel::ConnectivityStateWatcherList +// + +void Subchannel::ConnectivityStateWatcherList::AddWatcherLocked( + UniquePtr watcher) { + watcher->next_ = head_; + head_ = watcher.release(); +} + +void Subchannel::ConnectivityStateWatcherList::RemoveWatcherLocked( + ConnectivityStateWatcher* watcher) { + for (ConnectivityStateWatcher** w = &head_; *w != nullptr; w = &(*w)->next_) { + if (*w == watcher) { + *w = watcher->next_; + Delete(watcher); + return; + } + } + GPR_UNREACHABLE_CODE(return ); +} + +void Subchannel::ConnectivityStateWatcherList::NotifyLocked( + Subchannel* subchannel, grpc_connectivity_state state) { + for (ConnectivityStateWatcher* w = head_; w != nullptr; w = w->next_) { + RefCountedPtr connected_subchannel; + if (state == GRPC_CHANNEL_READY) { + connected_subchannel = subchannel->connected_subchannel_; + } + // TODO(roth): In principle, it seems wrong to send this notification + // to the watcher while holding the subchannel's mutex, since it could + // lead to a deadlock if the watcher calls back into the subchannel + // before returning back to us. In practice, this doesn't happen, + // because the LB policy code that watches subchannels always bounces + // the notification into the client_channel control-plane combiner + // before processing it. But if we ever have any other callers here, + // we will probably need to change this. + w->OnConnectivityStateChange(state, std::move(connected_subchannel)); + } +} + +void Subchannel::ConnectivityStateWatcherList::Clear() { + while (head_ != nullptr) { + ConnectivityStateWatcher* next = head_->next_; + Delete(head_); + head_ = next; + } +} + +// +// Subchannel::HealthWatcherMap::HealthWatcher +// + +// State needed for tracking the connectivity state with a particular +// health check service name. +class Subchannel::HealthWatcherMap::HealthWatcher + : public InternallyRefCounted { + public: + HealthWatcher(Subchannel* c, UniquePtr health_check_service_name, + grpc_connectivity_state subchannel_state) + : subchannel_(c), + health_check_service_name_(std::move(health_check_service_name)), + state_(subchannel_state == GRPC_CHANNEL_READY ? GRPC_CHANNEL_CONNECTING + : subchannel_state) { + GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "health_watcher"); + GRPC_CLOSURE_INIT(&on_health_changed_, OnHealthChanged, this, + grpc_schedule_on_exec_ctx); + // If the subchannel is already connected, start health checking. + if (subchannel_state == GRPC_CHANNEL_READY) StartHealthCheckingLocked(); + } + + ~HealthWatcher() { + GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "health_watcher"); + } + + const char* health_check_service_name() const { + return health_check_service_name_.get(); + } + + grpc_connectivity_state state() const { return state_; } + + void AddWatcherLocked(grpc_connectivity_state initial_state, + UniquePtr watcher) { + if (state_ != initial_state) { + RefCountedPtr connected_subchannel; + if (state_ == GRPC_CHANNEL_READY) { + connected_subchannel = subchannel_->connected_subchannel_; + } + watcher->OnConnectivityStateChange(state_, + std::move(connected_subchannel)); + } + watcher_list_.AddWatcherLocked(std::move(watcher)); + } + + void RemoveWatcherLocked(ConnectivityStateWatcher* watcher) { + watcher_list_.RemoveWatcherLocked(watcher); + } + + bool HasWatchers() const { return !watcher_list_.empty(); } + + void NotifyLocked(grpc_connectivity_state state) { + if (state == GRPC_CHANNEL_READY) { + // If we had not already notified for CONNECTING state, do so now. + // (We may have missed this earlier, because if the transition + // from IDLE to CONNECTING to READY was too quick, the connected + // subchannel may not have sent us a notification for CONNECTING.) + if (state_ != GRPC_CHANNEL_CONNECTING) { + state_ = GRPC_CHANNEL_CONNECTING; + watcher_list_.NotifyLocked(subchannel_, state_); + } + // If we've become connected, start health checking. + StartHealthCheckingLocked(); + } else { + state_ = state; + watcher_list_.NotifyLocked(subchannel_, state_); + // We're not connected, so stop health checking. + health_check_client_.reset(); + } + } + + void Orphan() override { + watcher_list_.Clear(); + health_check_client_.reset(); + Unref(); + } + + private: + void StartHealthCheckingLocked() { + GPR_ASSERT(health_check_client_ == nullptr); + health_check_client_ = MakeOrphanable( + health_check_service_name_.get(), subchannel_->connected_subchannel_, + subchannel_->pollset_set_, subchannel_->channelz_node_); + Ref().release(); // Ref for health callback tracked manually. + health_check_client_->NotifyOnHealthChange(&state_, &on_health_changed_); + } + + static void OnHealthChanged(void* arg, grpc_error* error) { + auto* self = static_cast(arg); + Subchannel* c = self->subchannel_; + { + MutexLock lock(&c->mu_); + if (self->state_ != GRPC_CHANNEL_SHUTDOWN && + self->health_check_client_ != nullptr) { + self->watcher_list_.NotifyLocked(c, self->state_); + // Renew watch. + self->health_check_client_->NotifyOnHealthChange( + &self->state_, &self->on_health_changed_); + return; // So we don't unref below. + } + } + // Don't unref until we've released the lock, because this might + // cause the subchannel (which contains the lock) to be destroyed. + self->Unref(); + } + + Subchannel* subchannel_; + UniquePtr health_check_service_name_; OrphanablePtr health_check_client_; grpc_closure on_health_changed_; - grpc_connectivity_state health_state_ = GRPC_CHANNEL_CONNECTING; + grpc_connectivity_state state_; + ConnectivityStateWatcherList watcher_list_; }; // -// Subchannel::ExternalStateWatcher +// Subchannel::HealthWatcherMap // -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); +void Subchannel::HealthWatcherMap::AddWatcherLocked( + Subchannel* subchannel, grpc_connectivity_state initial_state, + UniquePtr health_check_service_name, + UniquePtr watcher) { + // If the health check service name is not already present in the map, + // add it. + auto it = map_.find(health_check_service_name.get()); + HealthWatcher* health_watcher; + if (it == map_.end()) { + const char* key = health_check_service_name.get(); + auto w = MakeOrphanable( + subchannel, std::move(health_check_service_name), subchannel->state_); + health_watcher = w.get(); + map_[key] = std::move(w); + } else { + health_watcher = it->second.get(); } + // Add the watcher to the entry. + health_watcher->AddWatcherLocked(initial_state, std::move(watcher)); +} - 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); - } - { - MutexLock 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; - } - GRPC_SUBCHANNEL_WEAK_UNREF(w->subchannel, "external_state_watcher+done"); - Delete(w); - GRPC_CLOSURE_SCHED(follow_up, GRPC_ERROR_REF(error)); +void Subchannel::HealthWatcherMap::RemoveWatcherLocked( + const char* health_check_service_name, ConnectivityStateWatcher* watcher) { + auto it = map_.find(health_check_service_name); + GPR_ASSERT(it != map_.end()); + it->second->RemoveWatcherLocked(watcher); + // If we just removed the last watcher for this service name, remove + // the map entry. + if (!it->second->HasWatchers()) map_.erase(it); +} + +void Subchannel::HealthWatcherMap::NotifyLocked(grpc_connectivity_state state) { + for (const auto& p : map_) { + p.second->NotifyLocked(state); } +} - Subchannel* subchannel; - grpc_pollset_set* pollset_set; - grpc_closure* notify; - grpc_closure on_state_changed; - ExternalStateWatcher* next = nullptr; - ExternalStateWatcher* prev = nullptr; -}; +grpc_connectivity_state +Subchannel::HealthWatcherMap::CheckConnectivityStateLocked( + Subchannel* subchannel, const char* health_check_service_name) { + auto it = map_.find(health_check_service_name); + if (it == map_.end()) { + // If the health check service name is not found in the map, we're + // not currently doing a health check for that service name. If the + // subchannel's state without health checking is READY, report + // CONNECTING, since that's what we'd be in as soon as we do start a + // watch. Otherwise, report the channel's state without health checking. + return subchannel->state_ == GRPC_CHANNEL_READY ? GRPC_CHANNEL_CONNECTING + : subchannel->state_; + } + HealthWatcher* health_watcher = it->second.get(); + return health_watcher->state(); +} + +void Subchannel::HealthWatcherMap::ShutdownLocked() { map_.clear(); } // // Subchannel @@ -560,13 +678,6 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, if (new_args != nullptr) grpc_channel_args_destroy(new_args); GRPC_CLOSURE_INIT(&on_connecting_finished_, OnConnectingFinished, this, grpc_schedule_on_exec_ctx); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, - "subchannel"); - grpc_connectivity_state_init(&state_and_health_tracker_, GRPC_CHANNEL_IDLE, - "subchannel"); - health_check_service_name_ = - UniquePtr(gpr_strdup(grpc_channel_arg_get_string( - grpc_channel_args_find(args_, "grpc.temp.health_check")))); 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); @@ -593,8 +704,6 @@ Subchannel::~Subchannel() { 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_); @@ -698,53 +807,65 @@ const char* Subchannel::GetTargetAddress() { return addr_str; } -RefCountedPtr Subchannel::connected_subchannel() { - MutexLock lock(&mu_); - return connected_subchannel_; -} - channelz::SubchannelNode* Subchannel::channelz_node() { return channelz_node_.get(); } -grpc_connectivity_state Subchannel::CheckConnectivity( - bool inhibit_health_checking) { - grpc_connectivity_state_tracker* tracker = - inhibit_health_checking ? &state_tracker_ : &state_and_health_tracker_; - grpc_connectivity_state state = grpc_connectivity_state_check(tracker); +grpc_connectivity_state Subchannel::CheckConnectivityState( + const char* health_check_service_name, + RefCountedPtr* connected_subchannel) { + MutexLock lock(&mu_); + grpc_connectivity_state state; + if (health_check_service_name == nullptr) { + state = state_; + } else { + state = health_watcher_map_.CheckConnectivityStateLocked( + this, health_check_service_name); + } + if (connected_subchannel != nullptr && state == GRPC_CHANNEL_READY) { + *connected_subchannel = connected_subchannel_; + } return state; } -void Subchannel::NotifyOnStateChange(grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, - grpc_closure* notify, - bool inhibit_health_checking) { - grpc_connectivity_state_tracker* tracker = - inhibit_health_checking ? &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(); +void Subchannel::WatchConnectivityState( + grpc_connectivity_state initial_state, + UniquePtr health_check_service_name, + UniquePtr watcher) { + MutexLock lock(&mu_); + grpc_pollset_set* interested_parties = watcher->interested_parties(); + if (interested_parties != nullptr) { + grpc_pollset_set_add_pollset_set(pollset_set_, interested_parties); } + if (health_check_service_name == nullptr) { + if (state_ != initial_state) { + watcher->OnConnectivityStateChange(state_, connected_subchannel_); + } + watcher_list_.AddWatcherLocked(std::move(watcher)); + } else { + health_watcher_map_.AddWatcherLocked(this, initial_state, + std::move(health_check_service_name), + std::move(watcher)); + } +} + +void Subchannel::CancelConnectivityStateWatch( + const char* health_check_service_name, ConnectivityStateWatcher* watcher) { + MutexLock lock(&mu_); + grpc_pollset_set* interested_parties = watcher->interested_parties(); + if (interested_parties != nullptr) { + grpc_pollset_set_del_pollset_set(pollset_set_, interested_parties); + } + if (health_check_service_name == nullptr) { + watcher_list_.RemoveWatcherLocked(watcher); + } else { + health_watcher_map_.RemoveWatcherLocked(health_check_service_name, watcher); + } +} + +void Subchannel::AttemptToConnect() { + MutexLock lock(&mu_); + MaybeStartConnectingLocked(); } void Subchannel::ResetBackoff() { @@ -818,15 +939,19 @@ const char* SubchannelConnectivityStateChangeString( } // namespace -void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state, - const char* reason) { +// Note: Must be called with a state that is different from the current state. +void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state) { + state_ = state; 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, reason); + // Notify non-health watchers. + watcher_list_.NotifyLocked(this, state); + // Notify health watchers. + health_watcher_map_.NotifyLocked(state); } void Subchannel::MaybeStartConnectingLocked() { @@ -842,11 +967,6 @@ void Subchannel::MaybeStartConnectingLocked() { // 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_) { @@ -903,9 +1023,7 @@ void Subchannel::ContinueConnectingLocked() { next_attempt_deadline_ = backoff_.NextAttemptTime(); args.deadline = std::max(next_attempt_deadline_, min_deadline); args.channel_args = args_; - SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING, "connecting"); - grpc_connectivity_state_set(&state_and_health_tracker_, - GRPC_CHANNEL_CONNECTING, "connecting"); + SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING); grpc_connector_connect(connector_, &args, &connecting_result_, &on_connecting_finished_); } @@ -924,12 +1042,7 @@ void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) { GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } else { gpr_log(GPR_INFO, "Connect failed: %s", grpc_error_string(error)); - c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, - "connect_failed"); - grpc_connectivity_state_set(&c->state_and_health_tracker_, - GRPC_CHANNEL_TRANSIENT_FAILURE, - "connect_failed"); - c->MaybeStartConnectingLocked(); + c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } } @@ -982,8 +1095,9 @@ bool Subchannel::PublishTransportLocked() { 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); + New(this); + // Report initial state. + SetConnectivityStateLocked(GRPC_CHANNEL_READY); return true; } @@ -1000,7 +1114,7 @@ void Subchannel::Disconnect() { grpc_connector_shutdown(connector_, GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Subchannel disconnected")); connected_subchannel_.reset(); - connected_subchannel_watcher_.reset(); + health_watcher_map_.ShutdownLocked(); } gpr_atm Subchannel::RefMutate( diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index e3efc8900ae..e0741bb28fa 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -27,6 +27,7 @@ #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/gprpp/arena.h" +#include "src/core/lib/gprpp/map.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/sync.h" @@ -77,7 +78,7 @@ class ConnectedSubchannel : public RefCounted { grpc_millis deadline; Arena* arena; grpc_call_context_element* context; - grpc_core::CallCombiner* call_combiner; + CallCombiner* call_combiner; size_t parent_data_size; }; @@ -175,7 +176,38 @@ class SubchannelCall { // A subchannel that knows how to connect to exactly one target address. It // provides a target for load balancing. class Subchannel { + private: + class ConnectivityStateWatcherList; // Forward declaration. + public: + class ConnectivityStateWatcher { + public: + virtual ~ConnectivityStateWatcher() = default; + + // Will be invoked whenever the subchannel's connectivity state + // changes. There will be only one invocation of this method on a + // given watcher instance at any given time. + // + // When the state changes to READY, connected_subchannel will + // contain a ref to the connected subchannel. When it changes from + // READY to some other state, the implementation must release its + // ref to the connected subchannel. + virtual void OnConnectivityStateChange( + grpc_connectivity_state new_state, + RefCountedPtr connected_subchannel) // NOLINT + GRPC_ABSTRACT; + + virtual grpc_pollset_set* interested_parties() GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS + + private: + // For access to next_. + friend class Subchannel::ConnectivityStateWatcherList; + + ConnectivityStateWatcher* next_ = nullptr; + }; + // The ctor and dtor are not intended to use directly. Subchannel(SubchannelKey* key, grpc_connector* connector, const grpc_channel_args* args); @@ -201,20 +233,36 @@ class Subchannel { // 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(bool inhibit_health_checking); + // Returns the current connectivity state of the subchannel. + // If health_check_service_name is non-null, the returned connectivity + // state will be based on the state reported by the backend for that + // service name. + // If the return value is GRPC_CHANNEL_READY, also sets *connected_subchannel. + grpc_connectivity_state CheckConnectivityState( + const char* health_check_service_name, + RefCountedPtr* connected_subchannel); - // 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_checking); + // Starts watching the subchannel's connectivity state. + // The first callback to the watcher will be delivered when the + // subchannel's connectivity state becomes a value other than + // initial_state, which may happen immediately. + // Subsequent callbacks will be delivered as the subchannel's state + // changes. + // The watcher will be destroyed either when the subchannel is + // destroyed or when CancelConnectivityStateWatch() is called. + void WatchConnectivityState(grpc_connectivity_state initial_state, + UniquePtr health_check_service_name, + UniquePtr watcher); + + // Cancels a connectivity state watch. + // If the watcher has already been destroyed, this is a no-op. + void CancelConnectivityStateWatch(const char* health_check_service_name, + ConnectivityStateWatcher* watcher); + + // Attempt to connect to the backend. Has no effect if already connected. + void AttemptToConnect(); // Resets the connection backoff of the subchannel. // TODO(roth): Move connection backoff out of subchannels and up into LB @@ -236,12 +284,62 @@ class Subchannel { grpc_resolved_address* addr); private: - struct ExternalStateWatcher; + // A linked list of ConnectivityStateWatchers that are monitoring the + // subchannel's state. + class ConnectivityStateWatcherList { + public: + ~ConnectivityStateWatcherList() { Clear(); } + + void AddWatcherLocked(UniquePtr watcher); + void RemoveWatcherLocked(ConnectivityStateWatcher* watcher); + + // Notifies all watchers in the list about a change to state. + void NotifyLocked(Subchannel* subchannel, grpc_connectivity_state state); + + void Clear(); + + bool empty() const { return head_ == nullptr; } + + private: + ConnectivityStateWatcher* head_ = nullptr; + }; + + // A map that tracks ConnectivityStateWatchers using a particular health + // check service name. + // + // There is one entry in the map for each health check service name. + // Entries exist only as long as there are watchers using the + // corresponding service name. + // + // A health check client is maintained only while the subchannel is in + // state READY. + class HealthWatcherMap { + public: + void AddWatcherLocked(Subchannel* subchannel, + grpc_connectivity_state initial_state, + UniquePtr health_check_service_name, + UniquePtr watcher); + void RemoveWatcherLocked(const char* health_check_service_name, + ConnectivityStateWatcher* watcher); + + // Notifies the watcher when the subchannel's state changes. + void NotifyLocked(grpc_connectivity_state state); + + grpc_connectivity_state CheckConnectivityStateLocked( + Subchannel* subchannel, const char* health_check_service_name); + + void ShutdownLocked(); + + private: + class HealthWatcher; + + Map, StringLess> map_; + }; + class ConnectedSubchannelStateWatcher; // Sets the subchannel's connectivity state to \a state. - void SetConnectivityStateLocked(grpc_connectivity_state state, - const char* reason); + void SetConnectivityStateLocked(grpc_connectivity_state state); // Methods for connection. void MaybeStartConnectingLocked(); @@ -279,15 +377,15 @@ class Subchannel { 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; + grpc_connectivity_state state_ = GRPC_CHANNEL_IDLE; + // The list of watchers without a health check service name. + ConnectivityStateWatcherList watcher_list_; + // The map of watchers with health check service names. + HealthWatcherMap health_watcher_map_; // Backoff state. BackOff backoff_; diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 766c38a64a1..b623348e13f 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -1019,8 +1019,8 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { auto channel = BuildChannel("round_robin"); auto stub = BuildStub(channel); std::vector ports; - // Start with a single server. + gpr_log(GPR_INFO, "*** FIRST BACKEND ***"); ports.emplace_back(servers_[0]->port_); SetNextResolution(ports); WaitForServer(stub, 0, DEBUG_LOCATION); @@ -1030,36 +1030,33 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { EXPECT_EQ(0, servers_[1]->service_.request_count()); EXPECT_EQ(0, servers_[2]->service_.request_count()); servers_[0]->service_.ResetCounters(); - // And now for the second server. + gpr_log(GPR_INFO, "*** SECOND BACKEND ***"); ports.clear(); ports.emplace_back(servers_[1]->port_); SetNextResolution(ports); - // Wait until update has been processed, as signaled by the second backend // receiving a request. EXPECT_EQ(0, servers_[1]->service_.request_count()); WaitForServer(stub, 1, DEBUG_LOCATION); - for (size_t i = 0; i < 10; ++i) CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(0, servers_[0]->service_.request_count()); EXPECT_EQ(10, servers_[1]->service_.request_count()); EXPECT_EQ(0, servers_[2]->service_.request_count()); servers_[1]->service_.ResetCounters(); - // ... and for the last server. + gpr_log(GPR_INFO, "*** THIRD BACKEND ***"); ports.clear(); ports.emplace_back(servers_[2]->port_); SetNextResolution(ports); WaitForServer(stub, 2, DEBUG_LOCATION); - for (size_t i = 0; i < 10; ++i) CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(0, servers_[0]->service_.request_count()); EXPECT_EQ(0, servers_[1]->service_.request_count()); EXPECT_EQ(10, servers_[2]->service_.request_count()); servers_[2]->service_.ResetCounters(); - // Back to all servers. + gpr_log(GPR_INFO, "*** ALL BACKENDS ***"); ports.clear(); ports.emplace_back(servers_[0]->port_); ports.emplace_back(servers_[1]->port_); @@ -1068,14 +1065,13 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { WaitForServer(stub, 0, DEBUG_LOCATION); WaitForServer(stub, 1, DEBUG_LOCATION); WaitForServer(stub, 2, DEBUG_LOCATION); - // Send three RPCs, one per server. for (size_t i = 0; i < 3; ++i) CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(1, servers_[0]->service_.request_count()); EXPECT_EQ(1, servers_[1]->service_.request_count()); EXPECT_EQ(1, servers_[2]->service_.request_count()); - // An empty update will result in the channel going into TRANSIENT_FAILURE. + gpr_log(GPR_INFO, "*** NO BACKENDS ***"); ports.clear(); SetNextResolution(ports); grpc_connectivity_state channel_state; @@ -1084,15 +1080,14 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { } while (channel_state == GRPC_CHANNEL_READY); ASSERT_NE(channel_state, GRPC_CHANNEL_READY); servers_[0]->service_.ResetCounters(); - // Next update introduces servers_[1], making the channel recover. + gpr_log(GPR_INFO, "*** BACK TO SECOND BACKEND ***"); ports.clear(); ports.emplace_back(servers_[1]->port_); SetNextResolution(ports); WaitForServer(stub, 1, DEBUG_LOCATION); channel_state = channel->GetState(false /* try to connect */); ASSERT_EQ(channel_state, GRPC_CHANNEL_READY); - // Check LB policy name for the channel. EXPECT_EQ("round_robin", channel->GetLoadBalancingPolicyName()); } @@ -1211,8 +1206,9 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { auto channel = BuildChannel("round_robin"); auto stub = BuildStub(channel); SetNextResolution(ports); - for (size_t i = 0; i < kNumServers; ++i) + for (size_t i = 0; i < kNumServers; ++i) { WaitForServer(stub, i, DEBUG_LOCATION); + } for (size_t i = 0; i < servers_.size(); ++i) { CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(1, servers_[i]->service_.request_count()) << "for backend #" << i; @@ -1236,7 +1232,6 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { // No requests have gone to the deceased server. EXPECT_EQ(pre_death, post_death); // Bring the first server back up. - servers_[0].reset(new ServerData(ports[0])); StartServer(0); // Requests should start arriving at the first server either right away (if // the server managed to start before the RR policy retried the subchannel) or @@ -1360,6 +1355,52 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { // Second channel should be READY. EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1)); CheckRpcSendOk(stub2, DEBUG_LOCATION); + // Enable health checks on the backend and wait for channel 1 to succeed. + servers_[0]->SetServingStatus("health_check_service_name", true); + CheckRpcSendOk(stub1, DEBUG_LOCATION, true /* wait_for_ready */); + // Check that we created only one subchannel to the backend. + EXPECT_EQ(1UL, servers_[0]->service_.clients().size()); + // Clean up. + EnableDefaultHealthCheckService(false); +} + +TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingServiceNamePerChannel) { + EnableDefaultHealthCheckService(true); + // Start server. + const int kNumServers = 1; + StartServers(kNumServers); + // Create a channel with health-checking enabled. + ChannelArguments args; + args.SetServiceConfigJSON( + "{\"healthCheckConfig\": " + "{\"serviceName\": \"health_check_service_name\"}}"); + auto channel1 = BuildChannel("round_robin", args); + auto stub1 = BuildStub(channel1); + std::vector ports = GetServersPorts(); + SetNextResolution(ports); + // Create a channel with health-checking enabled with a different + // service name. + ChannelArguments args2; + args2.SetServiceConfigJSON( + "{\"healthCheckConfig\": " + "{\"serviceName\": \"health_check_service_name2\"}}"); + auto channel2 = BuildChannel("round_robin", args2); + auto stub2 = BuildStub(channel2); + SetNextResolution(ports); + // Allow health checks from channel 2 to succeed. + servers_[0]->SetServingStatus("health_check_service_name2", true); + // First channel should not become READY, because health checks should be + // failing. + EXPECT_FALSE(WaitForChannelReady(channel1.get(), 1)); + CheckRpcSendFailure(stub1); + // Second channel should be READY. + EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1)); + CheckRpcSendOk(stub2, DEBUG_LOCATION); + // Enable health checks for channel 1 and wait for it to succeed. + servers_[0]->SetServingStatus("health_check_service_name", true); + CheckRpcSendOk(stub1, DEBUG_LOCATION, true /* wait_for_ready */); + // Check that we created only one subchannel to the backend. + EXPECT_EQ(1UL, servers_[0]->service_.clients().size()); // Clean up. EnableDefaultHealthCheckService(false); } From c7a319a6fc22405e759466367f9661d977cfedfb Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Fri, 10 May 2019 10:37:23 -0700 Subject: [PATCH 2131/2143] Bump version to v1.22.0-dev --- BUILD | 4 ++-- build.yaml | 4 ++-- doc/g_stands_for.md | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/BUILD b/BUILD index 5c05c9e4549..cffa12b4142 100644 --- a/BUILD +++ b/BUILD @@ -74,11 +74,11 @@ config_setting( ) # This should be updated along with build.yaml -g_stands_for = "gandalf" +g_stands_for = "gale" core_version = "7.0.0" -version = "1.21.0-dev" +version = "1.22.0-dev" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index fabb041b386..5131a57e05d 100644 --- a/build.yaml +++ b/build.yaml @@ -13,8 +13,8 @@ settings: '#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 - g_stands_for: gandalf - version: 1.21.0-dev + g_stands_for: gale + version: 1.22.0-dev filegroups: - name: alts_proto headers: diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index b926db191de..90202b1b880 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -20,4 +20,5 @@ - 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/v1.19.x) - 1.20 'g' stands for ['godric'](https://github.com/grpc/grpc/tree/v1.20.x) -- 1.21 'g' stands for ['gandalf'](https://github.com/grpc/grpc/tree/master) +- 1.21 'g' stands for ['gandalf'](https://github.com/grpc/grpc/tree/v1.21.x) +- 1.22 'g' stands for ['gale'](https://github.com/grpc/grpc/tree/master) From 6bc2ff1b5f46848fb2ab7072692f1a11bcb7fcd4 Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Fri, 10 May 2019 10:38:59 -0700 Subject: [PATCH 2132/2143] 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/core/lib/surface/version.cc | 2 +- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 4 ++-- src/csharp/build/dependencies.props | 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/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 +- 31 files changed, 35 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index accc28807b4..429d083d279 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.21.0-dev") +set(PACKAGE_VERSION "1.22.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 c4a62228b64..605e533e8a8 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.21.0-dev -CSHARP_VERSION = 1.21.0-dev +CPP_VERSION = 1.22.0-dev +CSHARP_VERSION = 1.22.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 1dc2258538a..b739dc4ce75 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.21.0-dev' + # version = '1.22.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.21.0-dev' + grpc_version = '1.22.0-dev' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index cbf0a4b2924..f865fca7a40 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.21.0-dev' + version = '1.22.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 0e905bd97bd..1cac59c6cc4 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.21.0-dev' + version = '1.22.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 df86ef7ed34..6f033ea71b7 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.21.0-dev' + version = '1.22.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 b3c7a55a2e1..e9c3fd7bee0 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.21.0-dev' + version = '1.22.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 04d9f35cf03..60a22d63561 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.21.0dev - 1.21.0dev + 1.22.0dev + 1.22.0dev beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 8aeadaf5078..7d9d49bc2aa 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -25,4 +25,4 @@ const char* grpc_version_string(void) { return "7.0.0"; } -const char* grpc_g_stands_for(void) { return "gandalf"; } +const char* grpc_g_stands_for(void) { return "gale"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 166c2d39b35..76e2773e938 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.21.0-dev"; } +grpc::string Version() { return "1.22.0-dev"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index 1b2602e219d..fb67fe622b5 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.21.0.0"; + public const string CurrentAssemblyFileVersion = "1.22.0.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.21.0-dev"; + public const string CurrentVersion = "1.22.0-dev"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index b018aac0f8e..dd5f172c27b 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.21.0-dev + 1.22.0-dev 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 8c7718f727f..2f4cd2739da 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.21.0-dev +set VERSION=1.22.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 88b8d2975d6..401540209af 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.21.0-dev' + v = '1.22.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 fcbdfb21539..6fe0c396dd3 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.21.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.22.0-dev" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 87516de11e8..c835c1da190 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.21.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.22.0-dev" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index a9d0aebffca..ca1001b6d2b 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.21.0", + "version": "1.22.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 43b3fa629ff..3e9f88c61d6 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.21.0dev" +#define PHP_GRPC_VERSION "1.22.0dev" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 651f8f778f2..9f7ca9d5603 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.21.0.dev0""" +__version__ = """1.22.0.dev0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index e430cc20a6d..971fd37afb6 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.21.0.dev0' +VERSION = '1.22.0.dev0' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index d716b953f4b..52baab4c30f 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.21.0.dev0' +VERSION = '1.22.0.dev0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 2bb47aaf133..be4ca841361 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.21.0.dev0' +VERSION = '1.22.0.dev0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index e1c4f3df694..1efc4ee2c8d 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.21.0.dev0' +VERSION = '1.22.0.dev0' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index b484a7ba478..9e443087755 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.21.0.dev0' +VERSION = '1.22.0.dev0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 21981ee79d2..18d17e40464 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.21.0.dev0' +VERSION = '1.22.0.dev0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 8ce4fdb627d..401b0bd9697 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.21.0.dev0' +VERSION = '1.22.0.dev0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index cca795b64ec..75e6191216d 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.21.0.dev' + VERSION = '1.22.0.dev' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 5604e215b58..fbd0041fa35 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.21.0.dev' + VERSION = '1.22.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 22d04c5a1af..24ec4301b65 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.21.0.dev0' +VERSION = '1.22.0.dev0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index d5874920752..667b9b3541e 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.21.0-dev +PROJECT_NUMBER = 1.22.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 ab0968b3252..41abf2e96bc 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.21.0-dev +PROJECT_NUMBER = 1.22.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 From 87d75d2a881ee2a71ada38ae52e87af38debea72 Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Fri, 10 May 2019 11:23:24 -0700 Subject: [PATCH 2133/2143] Add explicit and fix error --- test/cpp/microbenchmarks/bm_cq.cc | 6 ++++-- test/cpp/microbenchmarks/callback_streaming_ping_pong.h | 4 +--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index caa5e7d6d31..50eb9454fbe 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -153,7 +153,9 @@ static void shutdown_and_destroy(grpc_completion_queue* cc) { // Tag completion queue iterate times class TagCallback : public grpc_experimental_completion_queue_functor { public: - TagCallback(int* iter) : iter_(iter) { functor_run = &TagCallback::Run; } + explicit TagCallback(int* iter) : iter_(iter) { + functor_run = &TagCallback::Run; + } ~TagCallback() {} static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { GPR_ASSERT(static_cast(ok)); @@ -167,7 +169,7 @@ class TagCallback : public grpc_experimental_completion_queue_functor { // Check if completion queue is shut down class ShutdownCallback : public grpc_experimental_completion_queue_functor { public: - ShutdownCallback(bool* done) : done_(done) { + explicit ShutdownCallback(bool* done) : done_(done) { functor_run = &ShutdownCallback::Run; } ~ShutdownCallback() {} diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h index 8f10fabc43b..0f4549df3ff 100644 --- a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -55,9 +55,7 @@ class BidiClient gpr_log(GPR_ERROR, "Client read failed"); return; } - if (writes_complete_ < msgs_to_send_) { - MaybeWrite(); - } + MaybeWrite(); } void OnWriteDone(bool ok) override { From f65208af02714799faa6ba3ceeae5c73d0bf6dfa Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Mon, 29 Apr 2019 15:59:20 -0700 Subject: [PATCH 2134/2143] Added slice equality when static fastpath. --- BUILD | 1 + BUILD.gn | 2 + build.yaml | 1 + gRPC-C++.podspec | 2 + gRPC-Core.podspec | 2 + grpc.gemspec | 1 + package.xml | 1 + .../ext/transport/chttp2/transport/parsing.cc | 96 ++++++++----------- .../cronet/transport/cronet_transport.cc | 14 +-- src/core/lib/compression/compression.cc | 21 ++-- .../lib/compression/compression_internal.cc | 24 +++-- .../lib/compression/stream_compression.cc | 5 +- src/core/lib/slice/slice.cc | 25 +++++ src/core/lib/slice/slice_intern.cc | 10 +- src/core/lib/slice/slice_utils.h | 50 ++++++++++ src/core/lib/surface/call.cc | 6 +- src/core/lib/transport/metadata.h | 3 +- src/core/lib/transport/static_metadata.cc | 4 +- src/core/lib/transport/static_metadata.h | 17 ++-- tools/codegen/core/gen_static_metadata.py | 14 +-- tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core.internal | 1 + .../generated/sources_and_headers.json | 2 + 23 files changed, 198 insertions(+), 105 deletions(-) create mode 100644 src/core/lib/slice/slice_utils.h diff --git a/BUILD b/BUILD index 5c05c9e4549..750ebb2a48d 100644 --- a/BUILD +++ b/BUILD @@ -997,6 +997,7 @@ grpc_cc_library( "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_utils.h", "src/core/lib/slice/slice_weak_hash_table.h", "src/core/lib/surface/api_trace.h", "src/core/lib/surface/call.h", diff --git a/BUILD.gn b/BUILD.gn index 47b2747065d..dcd5bc880eb 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -739,6 +739,7 @@ config("grpc_config") { "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_utils.h", "src/core/lib/slice/slice_weak_hash_table.h", "src/core/lib/surface/api_trace.cc", "src/core/lib/surface/api_trace.h", @@ -1283,6 +1284,7 @@ config("grpc_config") { "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_utils.h", "src/core/lib/slice/slice_weak_hash_table.h", "src/core/lib/surface/api_trace.h", "src/core/lib/surface/call.h", diff --git a/build.yaml b/build.yaml index fabb041b386..c46d5ab423f 100644 --- a/build.yaml +++ b/build.yaml @@ -525,6 +525,7 @@ filegroups: - 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_utils.h - src/core/lib/slice/slice_weak_hash_table.h - src/core/lib/surface/api_trace.h - src/core/lib/surface/call.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 1dc2258538a..316fd349da9 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -518,6 +518,7 @@ Pod::Spec.new do |s| '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_utils.h', 'src/core/lib/slice/slice_weak_hash_table.h', 'src/core/lib/surface/api_trace.h', 'src/core/lib/surface/call.h', @@ -721,6 +722,7 @@ Pod::Spec.new do |s| '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_utils.h', 'src/core/lib/slice/slice_weak_hash_table.h', 'src/core/lib/surface/api_trace.h', 'src/core/lib/surface/call.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index cbf0a4b2924..c36ba13000f 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -494,6 +494,7 @@ Pod::Spec.new do |s| '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_utils.h', 'src/core/lib/slice/slice_weak_hash_table.h', 'src/core/lib/surface/api_trace.h', 'src/core/lib/surface/call.h', @@ -1147,6 +1148,7 @@ Pod::Spec.new do |s| '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_utils.h', 'src/core/lib/slice/slice_weak_hash_table.h', 'src/core/lib/surface/api_trace.h', 'src/core/lib/surface/call.h', diff --git a/grpc.gemspec b/grpc.gemspec index 6e229a5ab71..03b0116e149 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -428,6 +428,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/slice/slice_hash_table.h ) s.files += %w( src/core/lib/slice/slice_internal.h ) s.files += %w( src/core/lib/slice/slice_string_helpers.h ) + s.files += %w( src/core/lib/slice/slice_utils.h ) s.files += %w( src/core/lib/slice/slice_weak_hash_table.h ) s.files += %w( src/core/lib/surface/api_trace.h ) s.files += %w( src/core/lib/surface/call.h ) diff --git a/package.xml b/package.xml index 04d9f35cf03..5c97e0e307b 100644 --- a/package.xml +++ b/package.xml @@ -433,6 +433,7 @@ + diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc index 15648c06fcd..1aa6d971684 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.cc +++ b/src/core/ext/transport/chttp2/transport/parsing.cc @@ -28,6 +28,7 @@ #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/slice/slice_utils.h" #include "src/core/lib/transport/http2_errors.h" #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_conversion.h" @@ -410,53 +411,42 @@ static void on_initial_header(void* tp, grpc_mdelem md) { gpr_free(value); } - if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) { - // We don't use grpc_mdelem_eq here to avoid executing additional - // instructions. The reasoning is if the payload is not equal, we already - // know that the metadata elements are not equal because the md is - // confirmed to be static. If we had used grpc_mdelem_eq here, then if the - // payloads are not equal, grpc_mdelem_eq executes more instructions to - // determine if they're equal or not. - if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload || - md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) { - s->seen_error = true; - } - } else { - if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && - !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { - /* TODO(ctiller): check for a status like " 0" */ - s->seen_error = true; - } - - if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) { - grpc_millis* cached_timeout = static_cast( - grpc_mdelem_get_user_data(md, free_timeout)); - grpc_millis timeout; - if (cached_timeout != nullptr) { - timeout = *cached_timeout; - } else { - if (GPR_UNLIKELY( - !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) { - char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md)); - gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val); - gpr_free(val); - timeout = GRPC_MILLIS_INF_FUTURE; - } - if (GRPC_MDELEM_IS_INTERNED(md)) { - /* store the result */ - cached_timeout = - static_cast(gpr_malloc(sizeof(grpc_millis))); - *cached_timeout = timeout; - grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); - } + // If md.payload == GRPC_MDELEM_GRPC_STATUS_1 or GRPC_MDELEM_GRPC_STATUS_2, + // then we have seen an error. In fact, if it is a GRPC_STATUS and it's + // not equal to GRPC_MDELEM_GRPC_STATUS_0, then we have seen an error. + if (grpc_slice_eq_static_interned(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && + !grpc_mdelem_static_value_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { + /* TODO(ctiller): check for a status like " 0" */ + s->seen_error = true; + } else if (grpc_slice_eq_static_interned(GRPC_MDKEY(md), + GRPC_MDSTR_GRPC_TIMEOUT)) { + grpc_millis* cached_timeout = + static_cast(grpc_mdelem_get_user_data(md, free_timeout)); + grpc_millis timeout; + if (cached_timeout != nullptr) { + timeout = *cached_timeout; + } else { + if (GPR_UNLIKELY( + !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) { + char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md)); + gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val); + gpr_free(val); + timeout = GRPC_MILLIS_INF_FUTURE; } - if (timeout != GRPC_MILLIS_INF_FUTURE) { - grpc_chttp2_incoming_metadata_buffer_set_deadline( - &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout); + if (GRPC_MDELEM_IS_INTERNED(md)) { + /* store the result */ + cached_timeout = + static_cast(gpr_malloc(sizeof(grpc_millis))); + *cached_timeout = timeout; + grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); } - GRPC_MDELEM_UNREF(md); - return; } + if (timeout != GRPC_MILLIS_INF_FUTURE) { + grpc_chttp2_incoming_metadata_buffer_set_deadline( + &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout); + } + GRPC_MDELEM_UNREF(md); + return; } const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md); @@ -506,19 +496,11 @@ static void on_trailing_header(void* tp, grpc_mdelem md) { gpr_free(value); } - if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) { - // We don't use grpc_mdelem_eq here to avoid executing additional - // instructions. The reasoning is if the payload is not equal, we already - // know that the metadata elements are not equal because the md is - // confirmed to be static. If we had used grpc_mdelem_eq here, then if the - // payloads are not equal, grpc_mdelem_eq executes more instructions to - // determine if they're equal or not. - if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload || - md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) { - s->seen_error = true; - } - } else if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && - !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { + // If md.payload == GRPC_MDELEM_GRPC_STATUS_1 or GRPC_MDELEM_GRPC_STATUS_2, + // then we have seen an error. In fact, if it is a GRPC_STATUS and it's + // not equal to GRPC_MDELEM_GRPC_STATUS_0, then we have seen an error. + if (grpc_slice_eq_static_interned(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && + !grpc_mdelem_static_value_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { /* TODO(ctiller): check for a status like " 0" */ s->seen_error = true; } diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 320b5297251..413de807638 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -753,15 +753,16 @@ static void convert_metadata_to_cronet_headers( } else { value = grpc_slice_to_c_string(GRPC_MDVALUE(mdelem)); } - if (grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_SCHEME) || - grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_AUTHORITY)) { + if (grpc_slice_eq_static_interned(GRPC_MDKEY(mdelem), GRPC_MDSTR_SCHEME) || + grpc_slice_eq_static_interned(GRPC_MDKEY(mdelem), + GRPC_MDSTR_AUTHORITY)) { /* Cronet populates these fields on its own */ gpr_free(key); gpr_free(value); continue; } - if (grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_METHOD)) { - if (grpc_slice_eq(GRPC_MDVALUE(mdelem), GRPC_MDSTR_PUT)) { + if (grpc_slice_eq_static_interned(GRPC_MDKEY(mdelem), GRPC_MDSTR_METHOD)) { + if (grpc_slice_eq_static_interned(GRPC_MDVALUE(mdelem), GRPC_MDSTR_PUT)) { *method = "PUT"; } else { /* POST method in default*/ @@ -771,7 +772,7 @@ static void convert_metadata_to_cronet_headers( gpr_free(value); continue; } - if (grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_PATH)) { + if (grpc_slice_eq_static_interned(GRPC_MDKEY(mdelem), GRPC_MDSTR_PATH)) { /* Create URL by appending :path value to the hostname */ gpr_asprintf(pp_url, "https://%s%s", host, value); gpr_free(key); @@ -803,7 +804,8 @@ static void parse_grpc_header(const uint8_t* data, int* length, static bool header_has_authority(grpc_linked_mdelem* head) { while (head != nullptr) { - if (grpc_slice_eq(GRPC_MDKEY(head->md), GRPC_MDSTR_AUTHORITY)) { + if (grpc_slice_eq_static_interned(GRPC_MDKEY(head->md), + GRPC_MDSTR_AUTHORITY)) { return true; } head = head->next; diff --git a/src/core/lib/compression/compression.cc b/src/core/lib/compression/compression.cc index 9139fa04ee5..a3a069d9266 100644 --- a/src/core/lib/compression/compression.cc +++ b/src/core/lib/compression/compression.cc @@ -26,6 +26,7 @@ #include "src/core/lib/compression/algorithm_metadata.h" #include "src/core/lib/compression/compression_internal.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/slice/slice_utils.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/transport/static_metadata.h" @@ -42,16 +43,17 @@ int grpc_compression_algorithm_is_stream(grpc_compression_algorithm algorithm) { int grpc_compression_algorithm_parse(grpc_slice name, grpc_compression_algorithm* algorithm) { - if (grpc_slice_eq(name, GRPC_MDSTR_IDENTITY)) { + if (grpc_slice_eq_static_interned(name, GRPC_MDSTR_IDENTITY)) { *algorithm = GRPC_COMPRESS_NONE; return 1; - } else if (grpc_slice_eq(name, GRPC_MDSTR_DEFLATE)) { + } else if (grpc_slice_eq_static_interned(name, GRPC_MDSTR_DEFLATE)) { *algorithm = GRPC_COMPRESS_DEFLATE; return 1; - } else if (grpc_slice_eq(name, GRPC_MDSTR_GZIP)) { + } else if (grpc_slice_eq_static_interned(name, GRPC_MDSTR_GZIP)) { *algorithm = GRPC_COMPRESS_GZIP; return 1; - } else if (grpc_slice_eq(name, GRPC_MDSTR_STREAM_SLASH_GZIP)) { + } else if (grpc_slice_eq_static_interned(name, + GRPC_MDSTR_STREAM_SLASH_GZIP)) { *algorithm = GRPC_COMPRESS_STREAM_GZIP; return 1; } else { @@ -148,10 +150,13 @@ grpc_slice grpc_compression_algorithm_slice( grpc_compression_algorithm grpc_compression_algorithm_from_slice( 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; - if (grpc_slice_eq(str, GRPC_MDSTR_STREAM_SLASH_GZIP)) + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_IDENTITY)) + return GRPC_COMPRESS_NONE; + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_DEFLATE)) + return GRPC_COMPRESS_DEFLATE; + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_GZIP)) + return GRPC_COMPRESS_GZIP; + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_STREAM_SLASH_GZIP)) return GRPC_COMPRESS_STREAM_GZIP; return GRPC_COMPRESS_ALGORITHMS_COUNT; } diff --git a/src/core/lib/compression/compression_internal.cc b/src/core/lib/compression/compression_internal.cc index 65a36de4290..e0d73ef6d83 100644 --- a/src/core/lib/compression/compression_internal.cc +++ b/src/core/lib/compression/compression_internal.cc @@ -26,6 +26,7 @@ #include "src/core/lib/compression/algorithm_metadata.h" #include "src/core/lib/compression/compression_internal.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/slice/slice_utils.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/transport/static_metadata.h" @@ -33,18 +34,21 @@ grpc_message_compression_algorithm grpc_message_compression_algorithm_from_slice(const grpc_slice& str) { - if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_IDENTITY)) return GRPC_MESSAGE_COMPRESS_NONE; - if (grpc_slice_eq(str, GRPC_MDSTR_DEFLATE)) + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_DEFLATE)) return GRPC_MESSAGE_COMPRESS_DEFLATE; - if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_MESSAGE_COMPRESS_GZIP; + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_GZIP)) + return GRPC_MESSAGE_COMPRESS_GZIP; return GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT; } grpc_stream_compression_algorithm grpc_stream_compression_algorithm_from_slice( 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; + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_IDENTITY)) + return GRPC_STREAM_COMPRESS_NONE; + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_GZIP)) + return GRPC_STREAM_COMPRESS_GZIP; return GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT; } @@ -244,13 +248,13 @@ grpc_message_compression_algorithm grpc_message_compression_algorithm_for_level( int grpc_message_compression_algorithm_parse( grpc_slice value, grpc_message_compression_algorithm* algorithm) { - if (grpc_slice_eq(value, GRPC_MDSTR_IDENTITY)) { + if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_IDENTITY)) { *algorithm = GRPC_MESSAGE_COMPRESS_NONE; return 1; - } else if (grpc_slice_eq(value, GRPC_MDSTR_DEFLATE)) { + } else if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_DEFLATE)) { *algorithm = GRPC_MESSAGE_COMPRESS_DEFLATE; return 1; - } else if (grpc_slice_eq(value, GRPC_MDSTR_GZIP)) { + } else if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_GZIP)) { *algorithm = GRPC_MESSAGE_COMPRESS_GZIP; return 1; } else { @@ -263,10 +267,10 @@ int grpc_message_compression_algorithm_parse( int grpc_stream_compression_algorithm_parse( grpc_slice value, grpc_stream_compression_algorithm* algorithm) { - if (grpc_slice_eq(value, GRPC_MDSTR_IDENTITY)) { + if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_IDENTITY)) { *algorithm = GRPC_STREAM_COMPRESS_NONE; return 1; - } else if (grpc_slice_eq(value, GRPC_MDSTR_GZIP)) { + } else if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_GZIP)) { *algorithm = GRPC_STREAM_COMPRESS_GZIP; return 1; } else { diff --git a/src/core/lib/compression/stream_compression.cc b/src/core/lib/compression/stream_compression.cc index 46cb3daf4cc..e0857988643 100644 --- a/src/core/lib/compression/stream_compression.cc +++ b/src/core/lib/compression/stream_compression.cc @@ -22,6 +22,7 @@ #include "src/core/lib/compression/stream_compression.h" #include "src/core/lib/compression/stream_compression_gzip.h" +#include "src/core/lib/slice/slice_utils.h" extern const grpc_stream_compression_vtable grpc_stream_compression_identity_vtable; @@ -65,11 +66,11 @@ void grpc_stream_compression_context_destroy( int grpc_stream_compression_method_parse( grpc_slice value, bool is_compress, grpc_stream_compression_method* method) { - if (grpc_slice_eq(value, GRPC_MDSTR_IDENTITY)) { + if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_IDENTITY)) { *method = is_compress ? GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS : GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS; return 1; - } else if (grpc_slice_eq(value, GRPC_MDSTR_GZIP)) { + } else if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_GZIP)) { *method = is_compress ? GRPC_STREAM_COMPRESSION_GZIP_COMPRESS : GRPC_STREAM_COMPRESSION_GZIP_DECOMPRESS; return 1; diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index 2bf2b0f499f..75acb28e99c 100644 --- a/src/core/lib/slice/slice.cc +++ b/src/core/lib/slice/slice.cc @@ -410,6 +410,31 @@ int grpc_slice_eq(grpc_slice a, grpc_slice b) { return grpc_slice_default_eq_impl(a, b); } +int grpc_slice_differs_refcounted(const grpc_slice& a, + const grpc_slice& b_not_inline) { + size_t a_len; + const uint8_t* a_ptr; + if (a.refcount) { + a_len = a.data.refcounted.length; + a_ptr = a.data.refcounted.bytes; + } else { + a_len = a.data.inlined.length; + a_ptr = &a.data.inlined.bytes[0]; + } + if (a_len != b_not_inline.data.refcounted.length) { + return true; + } + if (a_len == 0) { + return false; + } + // This check *must* occur after the a_len == 0 check + // to retain compatibility with grpc_slice_eq. + if (a_ptr == nullptr) { + return true; + } + return memcmp(a_ptr, b_not_inline.data.refcounted.bytes, a_len); +} + int grpc_slice_cmp(grpc_slice a, grpc_slice b) { int d = static_cast(GRPC_SLICE_LENGTH(a) - GRPC_SLICE_LENGTH(b)); if (d != 0) return d; diff --git a/src/core/lib/slice/slice_intern.cc b/src/core/lib/slice/slice_intern.cc index 0f190c186fa..15909d9b96f 100644 --- a/src/core/lib/slice/slice_intern.cc +++ b/src/core/lib/slice/slice_intern.cc @@ -19,6 +19,7 @@ #include #include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_utils.h" #include #include @@ -143,7 +144,8 @@ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice, static_metadata_hash_ent ent = static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)]; if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT && - grpc_slice_eq(grpc_static_slice_table[ent.idx], slice)) { + grpc_slice_eq_static_interned(slice, + grpc_static_slice_table[ent.idx])) { *returned_slice_is_different = true; return grpc_static_slice_table[ent.idx]; } @@ -170,7 +172,8 @@ grpc_slice grpc_slice_intern(grpc_slice slice) { static_metadata_hash_ent ent = static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)]; if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT && - grpc_slice_eq(grpc_static_slice_table[ent.idx], slice)) { + grpc_slice_eq_static_interned(slice, + grpc_static_slice_table[ent.idx])) { return grpc_static_slice_table[ent.idx]; } } @@ -183,7 +186,8 @@ grpc_slice grpc_slice_intern(grpc_slice slice) { /* search for an existing string */ size_t idx = TABLE_IDX(hash, shard->capacity); for (s = shard->strs[idx]; s; s = s->bucket_next) { - if (s->hash == hash && grpc_slice_eq(slice, materialize(s))) { + if (s->hash == hash && + grpc_slice_eq_static_interned(slice, materialize(s))) { if (s->refcnt.RefIfNonZero()) { gpr_mu_unlock(&shard->mu); return materialize(s); diff --git a/src/core/lib/slice/slice_utils.h b/src/core/lib/slice/slice_utils.h new file mode 100644 index 00000000000..7589bf8f0f7 --- /dev/null +++ b/src/core/lib/slice/slice_utils.h @@ -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. + * + */ + +#ifndef GRPC_CORE_LIB_SLICE_SLICE_UTILS_H +#define GRPC_CORE_LIB_SLICE_SLICE_UTILS_H + +#include + +#include + +// When we compare two slices, and we know the latter is not inlined, we can +// short circuit our comparison operator. We specifically use differs() +// semantics instead of equals() semantics due to more favourable code +// generation when using differs(). Specifically, we may use the output of +// grpc_slice_differs_refcounted for control flow. If we use differs() +// semantics, we end with a tailcall to memcmp(). If we use equals() semantics, +// we need to invert the result that memcmp provides us, which costs several +// instructions to do so. If we're using the result for control flow (i.e. +// branching based on the output) then we're just performing the extra +// operations to invert the result pointlessly. Concretely, we save 6 ops on +// x86-64/clang with differs(). +int grpc_slice_differs_refcounted(const grpc_slice& a, + const grpc_slice& b_not_inline); +// When we compare two slices, and we *know* that one of them is static or +// interned, we can short circuit our slice equality function. The second slice +// here must be static or interned; slice a can be any slice, inlined or not. +inline bool grpc_slice_eq_static_interned(const grpc_slice& a, + const grpc_slice& b_static_interned) { + if (a.refcount == b_static_interned.refcount) { + return true; + } + return !grpc_slice_differs_refcounted(a, b_static_interned); +} + +#endif /* GRPC_CORE_LIB_SLICE_SLICE_UTILS_H */ diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 275111f3213..254476f47e3 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -42,8 +42,8 @@ #include "src/core/lib/gprpp/ref_counted.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/slice/slice_string_helpers.h" +#include "src/core/lib/slice/slice_utils.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/call_test_only.h" @@ -349,8 +349,8 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, MAX_SEND_EXTRA_METADATA_COUNT); for (size_t i = 0; i < args->add_initial_metadata_count; i++) { call->send_extra_metadata[i].md = args->add_initial_metadata[i]; - if (grpc_slice_eq(GRPC_MDKEY(args->add_initial_metadata[i]), - GRPC_MDSTR_PATH)) { + if (grpc_slice_eq_static_interned( + GRPC_MDKEY(args->add_initial_metadata[i]), GRPC_MDSTR_PATH)) { path = grpc_slice_ref_internal( GRPC_MDVALUE(args->add_initial_metadata[i])); } diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index c0d1ab36351..3ff5a35dd2d 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -30,6 +30,7 @@ #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/atomic.h" #include "src/core/lib/gprpp/sync.h" +#include "src/core/lib/slice/slice_utils.h" extern grpc_core::DebugOnlyTraceFlag grpc_trace_metadata; @@ -138,7 +139,7 @@ bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b); * grpc_mdelem_eq and remove unnecessary checks. */ inline bool grpc_mdelem_static_value_eq(grpc_mdelem a, grpc_mdelem b_static) { if (a.payload == b_static.payload) return true; - return grpc_slice_eq(GRPC_MDVALUE(a), GRPC_MDVALUE(b_static)); + return grpc_slice_eq_static_interned(GRPC_MDVALUE(a), GRPC_MDVALUE(b_static)); } /* Mutator and accessor for grpc_mdelem user data. The destructor function diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index fc5bb647573..61ee1d46f77 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -384,9 +384,9 @@ static const uint8_t elem_idxs[] = { 52, 53, 54, 76, 69, 55, 56, 70, 58, 78, 80, 81, 82, 83, 59, 64, 60, 75, 72, 255, 85, 255, 255, 68, 255, 255, 0}; -grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) { +grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b) { if (a == -1 || b == -1) return GRPC_MDNULL; - uint32_t k = (uint32_t)(a * 107 + b); + uint32_t k = static_cast(a * 107 + b); uint32_t h = elems_phash(k); return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 88293ae0613..a3f23de0953 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -29,6 +29,8 @@ #include +#include + #include "src/core/lib/transport/metadata.h" #define GRPC_STATIC_MDSTR_COUNT 107 @@ -263,7 +265,8 @@ extern grpc_slice_refcount (slice).refcount->GetType() == grpc_slice_refcount::Type::STATIC) #define GRPC_STATIC_METADATA_INDEX(static_slice) \ - ((int)((static_slice).refcount - grpc_static_metadata_refcounts)) + (static_cast( \ + ((static_slice).refcount - grpc_static_metadata_refcounts))) #define GRPC_STATIC_MDELEM_COUNT 86 extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; @@ -527,7 +530,7 @@ extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; #define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC)) -grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b); +grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b); typedef enum { GRPC_BATCH_PATH, GRPC_BATCH_METHOD, @@ -586,11 +589,11 @@ typedef union { } named; } grpc_metadata_batch_callouts; -#define GRPC_BATCH_INDEX_OF(slice) \ - (GRPC_IS_STATIC_METADATA_STRING((slice)) \ - ? (grpc_metadata_batch_callouts_index)GPR_CLAMP( \ - GRPC_STATIC_METADATA_INDEX((slice)), 0, \ - GRPC_BATCH_CALLOUTS_COUNT) \ +#define GRPC_BATCH_INDEX_OF(slice) \ + (GRPC_IS_STATIC_METADATA_STRING((slice)) \ + ? static_cast( \ + GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, \ + static_cast(GRPC_BATCH_CALLOUTS_COUNT))) \ : GRPC_BATCH_CALLOUTS_COUNT) extern const uint8_t grpc_static_accept_encoding_metadata[8]; diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index 5545e871117..d66fdc3e835 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -376,6 +376,8 @@ print >> H, '#define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H' print >> H print >> H, '#include ' print >> H +print >> H, '#include ' +print >> H print >> H, '#include "src/core/lib/transport/metadata.h"' print >> H print >> C, '#include ' @@ -433,8 +435,8 @@ for i, elem in enumerate(all_strs): print >> C, '};' print >> C print >> H, '#define GRPC_STATIC_METADATA_INDEX(static_slice) \\' -print >> H, (' ((int)((static_slice).refcount - ' - 'grpc_static_metadata_refcounts))') +print >> H, (' (static_cast(((static_slice).refcount - ' + 'grpc_static_metadata_refcounts)))') print >> H print >> D, '# hpack fuzzing dictionary' @@ -537,10 +539,10 @@ print >> C, 'static const uint8_t elem_idxs[] = {%s};' % ','.join( '%d' % i for i in idxs) print >> C -print >> H, 'grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b);' -print >> C, 'grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {' +print >> H, 'grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b);' +print >> C, 'grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b) {' print >> C, ' if (a == -1 || b == -1) return GRPC_MDNULL;' -print >> C, ' uint32_t k = (uint32_t)(a * %d + b);' % len(all_strs) +print >> C, ' uint32_t k = static_cast(a * %d + b);' % len(all_strs) print >> C, ' uint32_t h = elems_phash(k);' print >> C, ' return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC) : GRPC_MDNULL;' print >> C, '}' @@ -566,7 +568,7 @@ print >> H, ' } named;' print >> H, '} grpc_metadata_batch_callouts;' print >> H print >> H, '#define GRPC_BATCH_INDEX_OF(slice) \\' -print >> H, ' (GRPC_IS_STATIC_METADATA_STRING((slice)) ? (grpc_metadata_batch_callouts_index)GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, GRPC_BATCH_CALLOUTS_COUNT) : GRPC_BATCH_CALLOUTS_COUNT)' +print >> H, ' (GRPC_IS_STATIC_METADATA_STRING((slice)) ? static_cast(GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, static_cast(GRPC_BATCH_CALLOUTS_COUNT))) : GRPC_BATCH_CALLOUTS_COUNT)' print >> H print >> H, 'extern const uint8_t grpc_static_accept_encoding_metadata[%d];' % ( diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index ab0968b3252..489e76efd89 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1188,6 +1188,7 @@ 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_utils.h \ src/core/lib/slice/slice_weak_hash_table.h \ src/core/lib/surface/api_trace.h \ src/core/lib/surface/call.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 293a6e1f9c1..f7c268a8105 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1451,6 +1451,7 @@ 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_utils.h \ src/core/lib/slice/slice_weak_hash_table.h \ src/core/lib/surface/README.md \ src/core/lib/surface/api_trace.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index de8015ac52a..e67465d1602 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8574,6 +8574,7 @@ "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_utils.h", "src/core/lib/slice/slice_weak_hash_table.h", "src/core/lib/surface/api_trace.h", "src/core/lib/surface/call.h", @@ -8730,6 +8731,7 @@ "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_utils.h", "src/core/lib/slice/slice_weak_hash_table.h", "src/core/lib/surface/api_trace.h", "src/core/lib/surface/call.h", From 1ff5791e47bcf2e6bdab3572f074ef5d3be5dc99 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 10 May 2019 14:33:22 -0700 Subject: [PATCH 2135/2143] Add tests for setting a channel to lame on an invalid default service config --- .../filters/client_channel/client_channel.cc | 2 - .../end2end/service_config_end2end_test.cc | 55 ++++++++++++++++++- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 757ac2a35e7..cc4bfdded13 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1069,8 +1069,6 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) // Get default service config const char* service_config_json = grpc_channel_arg_get_string( grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG)); - // TODO(yashkt): Make sure we set the channel in TRANSIENT_FAILURE on an - // invalid default service config if (service_config_json != nullptr) { *error = GRPC_ERROR_NONE; default_service_config_ = ServiceConfig::Create(service_config_json, error); diff --git a/test/cpp/end2end/service_config_end2end_test.cc b/test/cpp/end2end/service_config_end2end_test.cc index 2d05fd42635..b3299232763 100644 --- a/test/cpp/end2end/service_config_end2end_test.cc +++ b/test/cpp/end2end/service_config_end2end_test.cc @@ -237,6 +237,14 @@ class ServiceConfigEnd2endTest : public ::testing::Test { return ::grpc::CreateCustomChannel("fake:///", creds_, args); } + std::shared_ptr BuildChannelWithInvalidDefaultServiceConfig() { + ChannelArguments args; + args.SetServiceConfigJSON(InvalidDefaultServiceConfig()); + args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, + response_generator_.get()); + return ::grpc::CreateCustomChannel("fake:///", creds_, args); + } + bool SendRpc( const std::unique_ptr& stub, EchoResponse* response = nullptr, int timeout_ms = 1000, @@ -402,7 +410,7 @@ class ServiceConfigEnd2endTest : public ::testing::Test { } const char* InvalidDefaultServiceConfig() { - return "{\"version\": \"invalid_default\"}"; + return "{\"version\": \"invalid_default\""; } const grpc::string server_host_; @@ -549,6 +557,51 @@ TEST_F(ServiceConfigEnd2endTest, CheckRpcSendFailure(stub); } +TEST_F(ServiceConfigEnd2endTest, InvalidDefaultServiceConfigTest) { + StartServers(1); + auto channel = BuildChannelWithInvalidDefaultServiceConfig(); + auto stub = BuildStub(channel); + // An invalid default service config results in a lame channel which fails all + // RPCs + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, + InvalidDefaultServiceConfigTestWithValidServiceConfig) { + StartServers(1); + auto channel = BuildChannelWithInvalidDefaultServiceConfig(); + auto stub = BuildStub(channel); + CheckRpcSendFailure(stub); + // An invalid default service config results in a lame channel which fails all + // RPCs + SetNextResolutionValidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, + InvalidDefaultServiceConfigTestWithInvalidServiceConfig) { + StartServers(1); + auto channel = BuildChannelWithInvalidDefaultServiceConfig(); + auto stub = BuildStub(channel); + CheckRpcSendFailure(stub); + // An invalid default service config results in a lame channel which fails all + // RPCs + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, + InvalidDefaultServiceConfigTestWithNoServiceConfig) { + StartServers(1); + auto channel = BuildChannelWithInvalidDefaultServiceConfig(); + auto stub = BuildStub(channel); + CheckRpcSendFailure(stub); + // An invalid default service config results in a lame channel which fails all + // RPCs + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + } // namespace } // namespace testing } // namespace grpc From f2fb11030b225cbee5534e8da86126d4d0de8dff Mon Sep 17 00:00:00 2001 From: hcaseyal Date: Thu, 9 May 2019 12:43:20 -0700 Subject: [PATCH 2136/2143] Add protected getters and setters for server health check fields --- include/grpcpp/server_impl.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h index 46bacf81d26..d4f33f185d9 100644 --- a/include/grpcpp/server_impl.h +++ b/include/grpcpp/server_impl.h @@ -199,6 +199,18 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { grpc_server* server() override { return server_; } + protected: + /// NOTE: This method is not part of the public API for this class. + void set_health_check_service( + std::unique_ptr service) { + health_check_service_ = std::move(service); + } + + /// NOTE: This method is not part of the public API for this class. + bool health_check_service_disabled() const { + return health_check_service_disabled_; + } + private: std::vector< std::unique_ptr>* From 86febe4121cbc00e5fc6a3ec32971d3dbce5f496 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Mon, 13 May 2019 10:56:58 -0700 Subject: [PATCH 2137/2143] Made Fork.support_enabled_ atomic --- src/core/lib/gprpp/fork.cc | 2 +- src/core/lib/gprpp/fork.h | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/lib/gprpp/fork.cc b/src/core/lib/gprpp/fork.cc index cacf5e82e5a..37552692373 100644 --- a/src/core/lib/gprpp/fork.cc +++ b/src/core/lib/gprpp/fork.cc @@ -243,7 +243,7 @@ void Fork::AwaitThreads() { internal::ExecCtxState* Fork::exec_ctx_state_ = nullptr; internal::ThreadState* Fork::thread_state_ = nullptr; -bool Fork::support_enabled_ = false; +std::atomic Fork::support_enabled_; bool Fork::override_enabled_ = false; Fork::child_postfork_func Fork::reset_child_polling_engine_ = nullptr; } // namespace grpc_core diff --git a/src/core/lib/gprpp/fork.h b/src/core/lib/gprpp/fork.h index 5a7404f0d91..73f2fa56aa7 100644 --- a/src/core/lib/gprpp/fork.h +++ b/src/core/lib/gprpp/fork.h @@ -19,6 +19,10 @@ #ifndef GRPC_CORE_LIB_GPRPP_FORK_H #define GRPC_CORE_LIB_GPRPP_FORK_H +#include + +#include + /* * NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK * AROUND VERY SPECIFIC USE CASES. @@ -78,7 +82,7 @@ class Fork { private: static internal::ExecCtxState* exec_ctx_state_; static internal::ThreadState* thread_state_; - static bool support_enabled_; + static std::atomic support_enabled_; static bool override_enabled_; static child_postfork_func reset_child_polling_engine_; }; From a02c76dfb920da5039a48faad0b3daac0ead05d1 Mon Sep 17 00:00:00 2001 From: Na-Na Pang Date: Mon, 13 May 2019 13:29:06 -0700 Subject: [PATCH 2138/2143] Cancel predefine number of streaming --- .../callback_streaming_ping_pong.h | 2 -- .../microbenchmarks/callback_test_service.cc | 23 ++++--------------- .../microbenchmarks/callback_test_service.h | 1 - 3 files changed, 5 insertions(+), 21 deletions(-) diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h index 0f4549df3ff..9fb86bd8299 100644 --- a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -83,8 +83,6 @@ class BidiClient void StartNewRpc() { cli_ctx_->~ClientContext(); new (cli_ctx_) ClientContext(); - cli_ctx_->AddMetadata(kServerFinishAfterNReads, - grpc::to_string(msgs_to_send_)); cli_ctx_->AddMetadata(kServerMessageSize, grpc::to_string(msgs_size_)); stub_->experimental_async()->BidiStream(cli_ctx_, this); MaybeWrite(); diff --git a/test/cpp/microbenchmarks/callback_test_service.cc b/test/cpp/microbenchmarks/callback_test_service.cc index 2473dc5f31d..321a5b39184 100644 --- a/test/cpp/microbenchmarks/callback_test_service.cc +++ b/test/cpp/microbenchmarks/callback_test_service.cc @@ -67,54 +67,41 @@ CallbackStreamingTestService::BidiStream() { Reactor() {} void OnStarted(ServerContext* context) override { ctx_ = context; - server_write_last_ = GetIntValueFromMetadata( - kServerFinishAfterNReads, context->client_metadata(), 0); message_size_ = GetIntValueFromMetadata(kServerMessageSize, context->client_metadata(), 0); StartRead(&request_); } void OnDone() override { GPR_ASSERT(finished_); - GPR_ASSERT(num_msgs_read_ == server_write_last_); delete this; } void OnCancel() override {} void OnReadDone(bool ok) override { if (!ok) { - gpr_log(GPR_ERROR, "Server read failed"); + // Stream is over + Finish(::grpc::Status::OK); + finished_ = true; return; } - num_msgs_read_++; if (message_size_ > 0) { response_.set_message(std::string(message_size_, 'a')); } else { response_.set_message(""); } - if (num_msgs_read_ < server_write_last_) { - StartWrite(&response_); - } else { - StartWriteLast(&response_, WriteOptions()); - } + StartWrite(&response_); } void OnWriteDone(bool ok) override { if (!ok) { gpr_log(GPR_ERROR, "Server write failed"); return; } - if (num_msgs_read_ < server_write_last_) { - StartRead(&request_); - } else { - Finish(::grpc::Status::OK); - finished_ = true; - } + StartRead(&request_); } private: ServerContext* ctx_; EchoRequest request_; EchoResponse response_; - int num_msgs_read_{0}; - int server_write_last_; int message_size_; bool finished_{false}; }; diff --git a/test/cpp/microbenchmarks/callback_test_service.h b/test/cpp/microbenchmarks/callback_test_service.h index dd7977a5913..97188595382 100644 --- a/test/cpp/microbenchmarks/callback_test_service.h +++ b/test/cpp/microbenchmarks/callback_test_service.h @@ -30,7 +30,6 @@ namespace grpc { namespace testing { -const char* const kServerFinishAfterNReads = "server_finish_after_n_reads"; const char* const kServerMessageSize = "server_message_size"; class CallbackStreamingTestService From 57e090989aa826073e95ed58397ddf327eb320d5 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Tue, 14 May 2019 21:20:31 +1200 Subject: [PATCH 2139/2143] Add managed .NET gRPC client to interop tests --- .../grpc_interop_aspnetcore/build_interop.sh.template | 3 +-- .../grpc_interop_aspnetcore/build_interop.sh | 3 +-- tools/run_tests/run_interop_tests.py | 11 ++++++----- 3 files changed, 8 insertions(+), 9 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 05ad947e944..d64286ab03c 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 @@ -41,5 +41,4 @@ ./build/get-grpc.sh - cd testassets/InteropTestsWebsite - dotnet build --configuration Debug + dotnet build --configuration Debug Grpc.AspNetCore.sln diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh index 2a3e6f3a0ee..65e848ded32 100644 --- a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh @@ -39,5 +39,4 @@ fi ./build/get-grpc.sh -cd testassets/InteropTestsWebsite -dotnet build --configuration Debug +dotnet build --configuration Debug Grpc.AspNetCore.sln diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 567c628d8e0..cc6901bdebe 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -192,7 +192,7 @@ class CSharpCoreCLRLanguage: class AspNetCoreLanguage: def __init__(self): - self.client_cwd = '../grpc-dotnet' + self.client_cwd = '../grpc-dotnet/testassets/InteropTestsClient/bin/Debug/netcoreapp3.0' self.server_cwd = '../grpc-dotnet/testassets/InteropTestsWebsite/bin/Debug/netcoreapp3.0' self.safename = str(self) @@ -200,8 +200,7 @@ class AspNetCoreLanguage: return {} def client_cmd(self, args): - # attempt to run client should fail - return ['dotnet' 'exec', 'CLIENT_NOT_SUPPORTED'] + args + return ['dotnet', 'exec', 'InteropTestsClient.dll'] + args def server_cmd(self, args): return ['dotnet', 'exec', 'InteropTestsWebsite.dll'] + args @@ -210,8 +209,10 @@ class AspNetCoreLanguage: return {} def unimplemented_test_cases(self): - # aspnetcore doesn't have a client so ignore all test cases. - return _TEST_CASES + _AUTH_TEST_CASES + return _SKIP_COMPRESSION + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _AUTH_TEST_CASES + \ + ['cancel_after_first_response', 'ping_pong'] def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION + _SKIP_SPECIAL_STATUS_MESSAGE From 2ba3209b336e147cff3f12ca18f449db7705f7c3 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 14 May 2019 11:57:08 -0700 Subject: [PATCH 2140/2143] Fix bug from #19002. --- .../filters/client_channel/health/health_check_client.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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 bfac773899d..faa2ba5b3b1 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 @@ -323,6 +323,11 @@ void HealthCheckClient::CallState::StartCall() { grpc_error* error = GRPC_ERROR_NONE; call_ = health_check_client_->connected_subchannel_->CreateCall(args, &error) .release(); + // Register after-destruction callback. + GRPC_CLOSURE_INIT(&after_call_stack_destruction_, AfterCallStackDestruction, + this, grpc_schedule_on_exec_ctx); + call_->SetAfterCallStackDestroy(&after_call_stack_destruction_); + // Check if creation failed. if (error != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "HealthCheckClient %p CallState %p: error creating health " @@ -338,10 +343,6 @@ void HealthCheckClient::CallState::StartCall() { GRPC_ERROR_NONE); return; } - // Register after-destruction callback. - GRPC_CLOSURE_INIT(&after_call_stack_destruction_, AfterCallStackDestruction, - this, grpc_schedule_on_exec_ctx); - call_->SetAfterCallStackDestroy(&after_call_stack_destruction_); // Initialize payload and batch. payload_.context = context_; batch_.payload = &payload_; From 053c62c78f4505a9ee833cfb240dff030dea585d Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 14 May 2019 22:43:23 +0200 Subject: [PATCH 2141/2143] Adding bazel wrapper for our sanctified version of bazel. --- .gitignore | 3 ++- tools/bazel.sh | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100755 tools/bazel.sh diff --git a/.gitignore b/.gitignore index 7b4c5d36cb4..bc324b5f826 100644 --- a/.gitignore +++ b/.gitignore @@ -109,13 +109,14 @@ Podfile.lock # IDE specific folder for JetBrains IDEs .idea/ -# Blaze files +# Bazel files bazel-bin bazel-genfiles bazel-grpc bazel-out bazel-testlogs bazel_format_virtual_environment/ +tools/bazel-* # Debug output gdb.txt diff --git a/tools/bazel.sh b/tools/bazel.sh new file mode 100755 index 00000000000..804b974700b --- /dev/null +++ b/tools/bazel.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Keeping up with Bazel's breaking changes is currently difficult. +# This script wraps calling bazel by downloading the currently +# supported version, and then calling it. This way, we can make sure +# that running bazel will always get meaningful results, at least +# until Bazel 1.0 is released. + +set -e + +VERSION=0.24.1 + +CWD=`pwd` +BASEURL=https://github.com/bazelbuild/bazel/releases/download/ +cd `dirname $0` +TOOLDIR=`pwd` + +case `uname -sm` in + "Linux x86_64") + suffix=linux-x86_64 + ;; + "Darwin x86_64") + suffix=darwin-x86_64 + ;; + *) + echo "Unsupported architecture: `uname -sm`" + exit 1 + ;; +esac + +filename=bazel-$VERSION-$suffix + +if [ ! -x $filename ] ; then + curl -L $BASEURL/$VERSION/$filename > $filename + chmod a+x $filename +fi + +cd $CWD +$TOOLDIR/$filename $@ From 236ae12bb115c307d1cd7d0b88c7aaa082e3dd0a Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Tue, 14 May 2019 14:36:33 -0700 Subject: [PATCH 2142/2143] Revert "Config migration" This reverts commit 87905ae5ead879a3baff731b3bed5408249beacd. --- BUILD | 16 ------- BUILD.gn | 2 - CMakeLists.txt | 2 - Makefile | 2 - build.yaml | 9 ---- config.m4 | 2 - config.w32 | 1 - gRPC-C++.podspec | 1 - gRPC-Core.podspec | 3 -- grpc.gemspec | 2 - grpc.gyp | 2 - package.xml | 2 - .../interop/app/src/main/cpp/grpc-interop.cc | 6 +-- .../filters/client_channel/backup_poller.cc | 11 ++--- .../client_channel/http_connect_handshaker.cc | 1 + .../resolver/dns/c_ares/dns_resolver_ares.cc | 14 +++--- .../resolver/dns/dns_resolver_selection.cc | 28 ------------ .../resolver/dns/dns_resolver_selection.h | 29 ------------ .../resolver/dns/native/dns_resolver.cc | 8 ++-- .../chttp2/transport/chttp2_plugin.cc | 7 +-- src/core/lib/debug/trace.cc | 20 +++------ src/core/lib/debug/trace.h | 8 ---- src/core/lib/gpr/env.h | 6 +++ src/core/lib/gpr/env_linux.cc | 2 +- src/core/lib/gpr/env_windows.cc | 5 +++ src/core/lib/gpr/log.cc | 22 ++++++---- src/core/lib/gprpp/fork.cc | 41 ++++++++++++----- src/core/lib/iomgr/ev_posix.cc | 26 +++++------ src/core/lib/iomgr/ev_posix.h | 3 -- src/core/lib/iomgr/fork_posix.cc | 1 + src/core/lib/iomgr/iomgr.cc | 3 +- src/core/lib/profiling/basic_timers.cc | 14 ++---- .../load_system_roots_linux.cc | 12 +++-- .../security_connector/security_connector.cc | 1 + .../security/security_connector/ssl_utils.cc | 44 ++++++++----------- .../security/security_connector/ssl_utils.h | 6 +-- src/core/lib/surface/init.cc | 2 +- .../private/GRPCSecureChannelFactory.m | 3 +- .../CoreCronetEnd2EndTests.mm | 4 +- src/python/grpcio/grpc_core_dependencies.py | 1 - test/core/bad_connection/close_fd_test.cc | 1 + test/core/bad_ssl/bad_ssl_test.cc | 4 +- .../resolvers/dns_resolver_test.cc | 8 ++-- test/core/end2end/fixtures/h2_full+trace.cc | 4 +- .../end2end/fixtures/h2_sockpair+trace.cc | 5 +-- test/core/end2end/fixtures/h2_spiffe.cc | 3 +- test/core/end2end/fixtures/h2_ssl.cc | 4 +- .../end2end/fixtures/h2_ssl_cred_reload.cc | 4 +- test/core/end2end/fixtures/h2_ssl_proxy.cc | 4 +- test/core/end2end/h2_ssl_cert_test.cc | 4 +- .../core/end2end/h2_ssl_session_reuse_test.cc | 4 +- test/core/end2end/tests/keepalive_timeout.cc | 14 +++--- test/core/gpr/log_test.cc | 13 ++---- test/core/http/httpscli_test.cc | 3 +- test/core/iomgr/resolve_address_posix_test.cc | 18 ++++---- test/core/iomgr/resolve_address_test.cc | 13 +++--- test/core/security/credentials_test.cc | 2 +- test/core/security/security_connector_test.cc | 10 ++--- test/core/util/test_config.cc | 1 + test/cpp/end2end/async_end2end_test.cc | 12 ++--- test/cpp/end2end/end2end_test.cc | 12 ++--- test/cpp/naming/address_sorting_test.cc | 14 +++--- test/cpp/naming/cancel_ares_query_test.cc | 4 +- test/cpp/naming/resolver_component_test.cc | 1 + tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 24 +--------- tools/run_tests/run_microbenchmark.py | 2 +- .../run_tests/sanity/core_banned_functions.py | 4 ++ 68 files changed, 208 insertions(+), 358 deletions(-) delete mode 100644 src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc delete mode 100644 src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h diff --git a/BUILD b/BUILD index ddd1f97b541..61a031ec022 100644 --- a/BUILD +++ b/BUILD @@ -1562,20 +1562,6 @@ grpc_cc_library( ], ) -grpc_cc_library( - name = "grpc_resolver_dns_selection", - srcs = [ - "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc", - ], - hdrs = [ - "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h", - ], - language = "c++", - deps = [ - "grpc_base", - ], -) - grpc_cc_library( name = "grpc_resolver_dns_native", srcs = [ @@ -1585,7 +1571,6 @@ grpc_cc_library( deps = [ "grpc_base", "grpc_client_channel", - "grpc_resolver_dns_selection", ], ) @@ -1617,7 +1602,6 @@ grpc_cc_library( deps = [ "grpc_base", "grpc_client_channel", - "grpc_resolver_dns_selection", ], ) diff --git a/BUILD.gn b/BUILD.gn index dcd5bc880eb..a46e70e1565 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -326,8 +326,6 @@ config("grpc_config") { "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", "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/dns_resolver_selection.cc", - "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h", "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", diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f137969aea..37fbc14fc26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1308,7 +1308,6 @@ add_library(grpc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc src/core/ext/filters/census/grpc_context.cc @@ -2705,7 +2704,6 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc diff --git a/Makefile b/Makefile index f7aa0461183..26883daedec 100644 --- a/Makefile +++ b/Makefile @@ -3784,7 +3784,6 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ src/core/ext/filters/census/grpc_context.cc \ @@ -5129,7 +5128,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ diff --git a/build.yaml b/build.yaml index 0f48db4cbc6..65abbc469e6 100644 --- a/build.yaml +++ b/build.yaml @@ -798,7 +798,6 @@ filegroups: uses: - grpc_base - grpc_client_channel - - grpc_resolver_dns_selection - name: grpc_resolver_dns_native src: - src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -806,14 +805,6 @@ filegroups: uses: - grpc_base - grpc_client_channel - - grpc_resolver_dns_selection -- name: grpc_resolver_dns_selection - headers: - - src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h - src: - - src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc - uses: - - grpc_base - name: grpc_resolver_fake headers: - src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h diff --git a/config.m4 b/config.m4 index d90a8e94e6d..c5ecf7cfd6a 100644 --- a/config.m4 +++ b/config.m4 @@ -412,7 +412,6 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ src/core/ext/filters/census/grpc_context.cc \ @@ -696,7 +695,6 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/pick_first) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/round_robin) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/xds) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/c_ares) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/native) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/fake) diff --git a/config.w32 b/config.w32 index 70ac245d9fa..6bcc54f6630 100644 --- a/config.w32 +++ b/config.w32 @@ -387,7 +387,6 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv_windows.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\\dns_resolver_selection.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.cc " + "src\\core\\ext\\filters\\census\\grpc_context.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 10e37bb5f47..e9cf58438e8 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -564,7 +564,6 @@ Pod::Spec.new do |s| '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_wrapper.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', - 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 318150c85d5..dd68bbbd609 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -540,7 +540,6 @@ Pod::Spec.new do |s| '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_wrapper.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', - 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', @@ -871,7 +870,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', 'src/core/ext/filters/census/grpc_context.cc', @@ -1194,7 +1192,6 @@ Pod::Spec.new do |s| '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_wrapper.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', - 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', diff --git a/grpc.gemspec b/grpc.gemspec index 03b0116e149..ecf17e998ac 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -474,7 +474,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h ) - s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h ) s.files += %w( src/core/ext/filters/max_age/max_age_filter.h ) s.files += %w( src/core/ext/filters/message_size/message_size_filter.h ) s.files += %w( src/core/ext/filters/http/client_authority_filter.h ) @@ -808,7 +807,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc ) - s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc ) s.files += %w( src/core/ext/filters/census/grpc_context.cc ) diff --git a/grpc.gyp b/grpc.gyp index 3e2e984ccbf..02342d441bb 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -594,7 +594,6 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', 'src/core/ext/filters/census/grpc_context.cc', @@ -1355,7 +1354,6 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', diff --git a/package.xml b/package.xml index feb55cc777f..7d33a000fae 100644 --- a/package.xml +++ b/package.xml @@ -479,7 +479,6 @@ - @@ -813,7 +812,6 @@ - diff --git a/src/android/test/interop/app/src/main/cpp/grpc-interop.cc b/src/android/test/interop/app/src/main/cpp/grpc-interop.cc index b5075529be2..07834250d22 100644 --- a/src/android/test/interop/app/src/main/cpp/grpc-interop.cc +++ b/src/android/test/interop/app/src/main/cpp/grpc-interop.cc @@ -18,8 +18,8 @@ #include #include +#include -#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/cpp/interop/interop_client.h" extern "C" JNIEXPORT void JNICALL @@ -28,7 +28,7 @@ Java_io_grpc_interop_cpp_InteropActivity_configureSslRoots(JNIEnv* env, jstring path_raw) { const char* path = env->GetStringUTFChars(path_raw, (jboolean*)0); - GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, path); + gpr_setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", path); } std::shared_ptr GetClient(const char* host, @@ -45,7 +45,7 @@ std::shared_ptr GetClient(const char* host, credentials = grpc::InsecureChannelCredentials(); } - grpc::testing::ChannelCreationFunc channel_creation_func = + grpc::testing::ChannelCreationFunc channel_creation_func = std::bind(grpc::CreateChannel, host_port, credentials); return std::shared_ptr( new grpc::testing::InteropClient(channel_creation_func, true, false)); diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc index dd761694414..a2d45c04026 100644 --- a/src/core/ext/filters/client_channel/backup_poller.cc +++ b/src/core/ext/filters/client_channel/backup_poller.cc @@ -56,14 +56,9 @@ static backup_poller* g_poller = nullptr; // guarded by g_poller_mu // treated as const. static int g_poll_interval_ms = DEFAULT_POLL_INTERVAL_MS; -GPR_GLOBAL_CONFIG_DEFINE_INT32( - grpc_client_channel_backup_poll_interval_ms, DEFAULT_POLL_INTERVAL_MS, - "Declares the interval in ms between two backup polls on client channels. " - "These polls are run in the timer thread so that gRPC can process " - "connection failures while there is no active polling thread. " - "They help reconnect disconnected client channels (mostly due to " - "idleness), so that the next RPC on this channel won't fail. Set to 0 to " - "turn off the backup polls."); +GPR_GLOBAL_CONFIG_DEFINE_INT32(grpc_client_channel_backup_poll_interval_ms, + DEFAULT_POLL_INTERVAL_MS, + "Client channel backup poll interval (ms)"); static void init_globals() { gpr_mu_init(&g_poller_mu); 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 95366b57386..90a79843458 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc @@ -31,6 +31,7 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/lib/channel/channel_args.h" #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/sync.h" #include "src/core/lib/http/format_request.h" 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 00358736a94..27d543363a3 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 @@ -32,12 +32,12 @@ #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/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.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" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" @@ -474,9 +474,8 @@ static bool should_use_ares(const char* resolver_env) { #endif /* GRPC_UV */ void grpc_resolver_dns_ares_init() { - grpc_core::UniquePtr resolver = - GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); - if (should_use_ares(resolver.get())) { + char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); + if (should_use_ares(resolver_env)) { gpr_log(GPR_DEBUG, "Using ares dns resolver"); address_sorting_init(); grpc_error* error = grpc_ares_init(); @@ -492,15 +491,16 @@ void grpc_resolver_dns_ares_init() { grpc_core::UniquePtr( grpc_core::New())); } + gpr_free(resolver_env); } void grpc_resolver_dns_ares_shutdown() { - grpc_core::UniquePtr resolver = - GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); - if (should_use_ares(resolver.get())) { + char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); + if (should_use_ares(resolver_env)) { address_sorting_shutdown(); grpc_ares_cleanup(); } + gpr_free(resolver_env); } #else /* GRPC_ARES == 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc b/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc deleted file mode 100644 index 07a617c14d5..00000000000 --- a/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc +++ /dev/null @@ -1,28 +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. -// - -// This is similar to the sockaddr resolver, except that it supports a -// bunch of query args that are useful for dependency injection in tests. - -#include - -#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" - -GPR_GLOBAL_CONFIG_DEFINE_STRING( - grpc_dns_resolver, "", - "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.") diff --git a/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h b/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h deleted file mode 100644 index d0a3486ea38..00000000000 --- a/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h +++ /dev/null @@ -1,29 +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 GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_SELECTION_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_SELECTION_H - -#include - -#include "src/core/lib/gprpp/global_config.h" - -GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_dns_resolver); - -#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_SELECTION_H \ - */ 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 5ab75d02793..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 @@ -26,11 +26,11 @@ #include #include -#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #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/gprpp/manual_constructor.h" @@ -274,9 +274,8 @@ class NativeDnsResolverFactory : public ResolverFactory { } // namespace grpc_core void grpc_resolver_dns_native_init() { - grpc_core::UniquePtr resolver = - GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); - if (gpr_stricmp(resolver.get(), "native") == 0) { + char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); + if (resolver_env != nullptr && gpr_stricmp(resolver_env, "native") == 0) { gpr_log(GPR_DEBUG, "Using native dns resolver"); grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( grpc_core::UniquePtr( @@ -292,6 +291,7 @@ void grpc_resolver_dns_native_init() { grpc_core::New())); } } + gpr_free(resolver_env); } void grpc_resolver_dns_native_shutdown() {} diff --git a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc index ac13d73d3b5..4c929d00ec9 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc @@ -23,11 +23,8 @@ #include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/transport/metadata.h" -GPR_GLOBAL_CONFIG_DEFINE_BOOL( - grpc_experimental_disable_flow_control, false, - "If set, flow control will be effectively disabled. Max out all values and " - "assume the remote peer does the same. Thus we can ignore any flow control " - "bookkeeping, error checking, and decision making"); +GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_experimental_disable_flow_control, false, + "Disable flow control"); void grpc_chttp2_plugin_init(void) { g_flow_control_enabled = diff --git a/src/core/lib/debug/trace.cc b/src/core/lib/debug/trace.cc index 84c0a3805d3..cafdb15c699 100644 --- a/src/core/lib/debug/trace.cc +++ b/src/core/lib/debug/trace.cc @@ -26,11 +26,7 @@ #include #include #include - -GPR_GLOBAL_CONFIG_DEFINE_STRING( - grpc_trace, "", - "A comma separated list of tracers that provide additional insight into " - "how gRPC C core is processing requests via debug logs."); +#include "src/core/lib/gpr/env.h" int grpc_tracer_set_enabled(const char* name, int enabled); @@ -137,14 +133,12 @@ static void parse(const char* s) { gpr_free(strings); } -void grpc_tracer_init(const char* env_var_name) { - (void)env_var_name; // suppress unused variable error - grpc_tracer_init(); -} - -void grpc_tracer_init() { - grpc_core::UniquePtr value = GPR_GLOBAL_CONFIG_GET(grpc_trace); - parse(value.get()); +void grpc_tracer_init(const char* env_var) { + char* e = gpr_getenv(env_var); + if (e != nullptr) { + parse(e); + gpr_free(e); + } } void grpc_tracer_shutdown(void) {} diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h index 6a4a8031ec4..72e1a4eded7 100644 --- a/src/core/lib/debug/trace.h +++ b/src/core/lib/debug/trace.h @@ -24,15 +24,7 @@ #include #include -#include "src/core/lib/gprpp/global_config.h" - -GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_trace); - -// TODO(veblush): Remove this deprecated function once codes depending on this -// function are updated in the internal repo. void grpc_tracer_init(const char* env_var_name); - -void grpc_tracer_init(); void grpc_tracer_shutdown(void); #if defined(__has_feature) diff --git a/src/core/lib/gpr/env.h b/src/core/lib/gpr/env.h index f5016c6fa06..fb9e0636d10 100644 --- a/src/core/lib/gpr/env.h +++ b/src/core/lib/gpr/env.h @@ -34,6 +34,12 @@ char* gpr_getenv(const char* name); /* Sets the environment with the specified name to the specified value. */ void gpr_setenv(const char* name, const char* value); +/* This is a version of gpr_getenv that does not produce any output if it has to + use an insecure version of the function. It is ONLY to be used to solve the + problem in which we need to check an env variable to configure the verbosity + level of logging. So DO NOT USE THIS. */ +const char* gpr_getenv_silent(const char* name, char** dst); + /* Deletes the variable name from the environment. */ void gpr_unsetenv(const char* name); diff --git a/src/core/lib/gpr/env_linux.cc b/src/core/lib/gpr/env_linux.cc index 3a3aa541672..e84a9f6064c 100644 --- a/src/core/lib/gpr/env_linux.cc +++ b/src/core/lib/gpr/env_linux.cc @@ -38,7 +38,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" -static const char* gpr_getenv_silent(const char* name, char** dst) { +const char* gpr_getenv_silent(const char* name, char** dst) { const char* insecure_func_used = nullptr; char* result = nullptr; #if defined(GPR_BACKWARDS_COMPATIBILITY_MODE) diff --git a/src/core/lib/gpr/env_windows.cc b/src/core/lib/gpr/env_windows.cc index 76c45fb87a7..72850a9587d 100644 --- a/src/core/lib/gpr/env_windows.cc +++ b/src/core/lib/gpr/env_windows.cc @@ -30,6 +30,11 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/string_windows.h" +const char* gpr_getenv_silent(const char* name, char** dst) { + *dst = gpr_getenv(name); + return NULL; +} + char* gpr_getenv(const char* name) { char* result = NULL; DWORD size; diff --git a/src/core/lib/gpr/log.cc b/src/core/lib/gpr/log.cc index 8a229b2adf1..01ef112fb31 100644 --- a/src/core/lib/gpr/log.cc +++ b/src/core/lib/gpr/log.cc @@ -22,15 +22,12 @@ #include #include +#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/global_config.h" #include #include -GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_verbosity, "ERROR", - "Default gRPC logging verbosity") - void gpr_default_log(gpr_log_func_args* args); static gpr_atm g_log_func = (gpr_atm)gpr_default_log; static gpr_atm g_min_severity_to_print = GPR_LOG_VERBOSITY_UNSET; @@ -75,22 +72,29 @@ void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print) { } void gpr_log_verbosity_init() { - grpc_core::UniquePtr verbosity = GPR_GLOBAL_CONFIG_GET(grpc_verbosity); + char* verbosity = nullptr; + const char* insecure_getenv = gpr_getenv_silent("GRPC_VERBOSITY", &verbosity); gpr_atm min_severity_to_print = GPR_LOG_SEVERITY_ERROR; - if (strlen(verbosity.get()) > 0) { - if (gpr_stricmp(verbosity.get(), "DEBUG") == 0) { + if (verbosity != nullptr) { + if (gpr_stricmp(verbosity, "DEBUG") == 0) { min_severity_to_print = static_cast(GPR_LOG_SEVERITY_DEBUG); - } else if (gpr_stricmp(verbosity.get(), "INFO") == 0) { + } else if (gpr_stricmp(verbosity, "INFO") == 0) { min_severity_to_print = static_cast(GPR_LOG_SEVERITY_INFO); - } else if (gpr_stricmp(verbosity.get(), "ERROR") == 0) { + } else if (gpr_stricmp(verbosity, "ERROR") == 0) { min_severity_to_print = static_cast(GPR_LOG_SEVERITY_ERROR); } + gpr_free(verbosity); } if ((gpr_atm_no_barrier_load(&g_min_severity_to_print)) == GPR_LOG_VERBOSITY_UNSET) { gpr_atm_no_barrier_store(&g_min_severity_to_print, min_severity_to_print); } + + if (insecure_getenv != nullptr) { + gpr_log(GPR_DEBUG, "Warning: insecure environment read function '%s' used", + insecure_getenv); + } } void gpr_set_log_function(gpr_log_func f) { diff --git a/src/core/lib/gprpp/fork.cc b/src/core/lib/gprpp/fork.cc index 37552692373..fdc7c5354bd 100644 --- a/src/core/lib/gprpp/fork.cc +++ b/src/core/lib/gprpp/fork.cc @@ -26,8 +26,8 @@ #include #include +#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/gprpp/memory.h" /* @@ -35,16 +35,6 @@ * AROUND VERY SPECIFIC USE CASES. */ -#ifdef GRPC_ENABLE_FORK_SUPPORT -#define GRPC_ENABLE_FORK_SUPPORT_DEFAULT true -#else -#define GRPC_ENABLE_FORK_SUPPORT_DEFAULT false -#endif // GRPC_ENABLE_FORK_SUPPORT - -GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_enable_fork_support, - GRPC_ENABLE_FORK_SUPPORT_DEFAULT, - "Enable folk support"); - namespace grpc_core { namespace internal { // The exec_ctx_count has 2 modes, blocked and unblocked. @@ -168,7 +158,34 @@ class ThreadState { void Fork::GlobalInit() { if (!override_enabled_) { - support_enabled_ = GPR_GLOBAL_CONFIG_GET(grpc_enable_fork_support); +#ifdef GRPC_ENABLE_FORK_SUPPORT + support_enabled_ = true; +#endif + bool env_var_set = false; + char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT"); + if (env != nullptr) { + static const char* truthy[] = {"yes", "Yes", "YES", "true", + "True", "TRUE", "1"}; + static const char* falsey[] = {"no", "No", "NO", "false", + "False", "FALSE", "0"}; + for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) { + if (0 == strcmp(env, truthy[i])) { + support_enabled_ = true; + env_var_set = true; + break; + } + } + if (!env_var_set) { + for (size_t i = 0; i < GPR_ARRAY_SIZE(falsey); i++) { + if (0 == strcmp(env, falsey[i])) { + support_enabled_ = false; + env_var_set = true; + break; + } + } + } + gpr_free(env); + } } if (support_enabled_) { exec_ctx_state_ = grpc_core::New(); diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index ddafb7b5539..47cf5b83b17 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -31,19 +31,13 @@ #include #include "src/core/lib/debug/trace.h" +#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/iomgr/ev_epoll1_linux.h" #include "src/core/lib/iomgr/ev_epollex_linux.h" #include "src/core/lib/iomgr/ev_poll_posix.h" #include "src/core/lib/iomgr/internal_errqueue.h" -GPR_GLOBAL_CONFIG_DEFINE_STRING( - grpc_poll_strategy, "all", - "Declares which polling engines to try when starting gRPC. " - "This is a comma-separated list of engines, which are tried in priority " - "order first -> last.") - grpc_core::TraceFlag grpc_polling_trace(false, "polling"); /* Disabled by default */ @@ -52,15 +46,16 @@ grpc_core::TraceFlag grpc_fd_trace(false, "fd_trace"); grpc_core::DebugOnlyTraceFlag grpc_trace_fd_refcount(false, "fd_refcount"); grpc_core::DebugOnlyTraceFlag grpc_polling_api_trace(false, "polling_api"); -// Polling API trace only enabled in debug builds #ifndef NDEBUG + +// Polling API trace only enabled in debug builds #define GRPC_POLLING_API_TRACE(format, ...) \ if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_api_trace)) { \ gpr_log(GPR_INFO, "(polling-api) " format, __VA_ARGS__); \ } #else #define GRPC_POLLING_API_TRACE(...) -#endif // NDEBUG +#endif /** Default poll() function - a pointer so that it can be overridden by some * tests */ @@ -71,7 +66,7 @@ int aix_poll(struct pollfd fds[], nfds_t nfds, int timeout) { return poll(fds, nfds, timeout); } grpc_poll_function_type grpc_poll_function = aix_poll; -#endif // GPR_AIX +#endif grpc_wakeup_fd grpc_global_wakeup_fd; @@ -210,11 +205,14 @@ void grpc_register_event_engine_factory(const char* name, const char* grpc_get_poll_strategy_name() { return g_poll_strategy_name; } void grpc_event_engine_init(void) { - grpc_core::UniquePtr value = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); + char* s = gpr_getenv("GRPC_POLL_STRATEGY"); + if (s == nullptr) { + s = gpr_strdup("all"); + } char** strings = nullptr; size_t nstrings = 0; - split(value.get(), &strings, &nstrings); + split(s, &strings, &nstrings); for (size_t i = 0; g_event_engine == nullptr && i < nstrings; i++) { try_engine(strings[i]); @@ -226,10 +224,10 @@ void grpc_event_engine_init(void) { gpr_free(strings); if (g_event_engine == nullptr) { - gpr_log(GPR_ERROR, "No event engine could be initialized from %s", - value.get()); + gpr_log(GPR_ERROR, "No event engine could be initialized from %s", s); abort(); } + gpr_free(s); } void grpc_event_engine_shutdown(void) { diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h index 30bb5e40faf..0ca3a6f82fd 100644 --- a/src/core/lib/iomgr/ev_posix.h +++ b/src/core/lib/iomgr/ev_posix.h @@ -24,14 +24,11 @@ #include #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" -GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_poll_strategy); - extern grpc_core::TraceFlag grpc_fd_trace; /* Disabled by default */ extern grpc_core::TraceFlag grpc_polling_trace; /* Disabled by default */ diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index 629b08162fb..7f8fb7e828b 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -28,6 +28,7 @@ #include #include +#include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/fork.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/ev_posix.h" diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index b86aa6f2d76..fd011788a06 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -42,8 +42,7 @@ #include "src/core/lib/iomgr/timer_manager.h" GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_abort_on_leaks, false, - "A debugging aid to cause a call to abort() when " - "gRPC objects are leaked past grpc_shutdown()"); + "Abort when leak is found"); static gpr_mu g_mu; static gpr_cv g_rcv; diff --git a/src/core/lib/profiling/basic_timers.cc b/src/core/lib/profiling/basic_timers.cc index 37689fe89d1..b19ad9fc23d 100644 --- a/src/core/lib/profiling/basic_timers.cc +++ b/src/core/lib/profiling/basic_timers.cc @@ -31,8 +31,7 @@ #include #include -#include "src/core/lib/gprpp/global_config.h" -#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/gpr/env.h" typedef enum { BEGIN = '{', END = '}', MARK = '.' } marker_type; @@ -75,16 +74,11 @@ static __thread int g_thread_id; static int g_next_thread_id; static int g_writing_enabled = 1; -GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_latency_trace, "latency_trace.txt", - "Output file name for latency trace") - static const char* output_filename() { if (output_filename_or_null == NULL) { - grpc_core::UniquePtr value = - GPR_GLOBAL_CONFIG_GET(grpc_latency_trace); - if (strlen(value.get()) > 0) { - output_filename_or_null = value.release(); - } else { + output_filename_or_null = gpr_getenv("LATENCY_TRACE"); + if (output_filename_or_null == NULL || + strlen(output_filename_or_null) == 0) { output_filename_or_null = "latency_trace.txt"; } } diff --git a/src/core/lib/security/security_connector/load_system_roots_linux.cc b/src/core/lib/security/security_connector/load_system_roots_linux.cc index 82d5bf6bcdd..924fa8a3e26 100644 --- a/src/core/lib/security/security_connector/load_system_roots_linux.cc +++ b/src/core/lib/security/security_connector/load_system_roots_linux.cc @@ -38,15 +38,12 @@ #include #include +#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/gprpp/global_config.h" #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/iomgr/load_file.h" -GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_system_ssl_roots_dir, "", - "Custom directory to SSL Roots"); - namespace grpc_core { namespace { @@ -142,9 +139,10 @@ grpc_slice CreateRootCertsBundle(const char* certs_directory) { grpc_slice LoadSystemRootCerts() { grpc_slice result = grpc_empty_slice(); // Prioritize user-specified custom directory if flag is set. - UniquePtr custom_dir = GPR_GLOBAL_CONFIG_GET(grpc_system_ssl_roots_dir); - if (strlen(custom_dir.get()) > 0) { - result = CreateRootCertsBundle(custom_dir.get()); + char* custom_dir = gpr_getenv("GRPC_SYSTEM_SSL_ROOTS_DIR"); + if (custom_dir != nullptr) { + result = CreateRootCertsBundle(custom_dir); + gpr_free(custom_dir); } // If the custom directory is empty/invalid/not specified, fallback to // distribution-specific directory. diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 47c0ad5aa3d..96a19605466 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -28,6 +28,7 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.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/iomgr/load_file.h" diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index cb0d5437988..1eefff6fe24 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -27,6 +27,7 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #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/gprpp/global_config.h" @@ -45,13 +46,7 @@ static const char* installed_roots_path = INSTALL_PREFIX "/share/grpc/roots.pem"; #endif -/** Config variable that points to the default SSL roots file. This file - must be a PEM encoded file with all the roots such as the one that can be - downloaded from https://pki.google.com/roots.pem. */ -GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_default_ssl_roots_file_path, "", - "Path to the default SSL roots file."); - -/** Config variable used as a flag to enable/disable loading system root +/** Environment variable used as a flag to enable/disable loading system root certificates from the OS trust store. */ GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_not_use_system_ssl_roots, false, "Disable loading system root certificates."); @@ -70,22 +65,20 @@ void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) { /* -- Cipher suites. -- */ +/* Defines the cipher suites that we accept by default. All these cipher suites + are compliant with HTTP2. */ +#define GRPC_SSL_CIPHER_SUITES \ + "ECDHE-ECDSA-AES128-GCM-SHA256:" \ + "ECDHE-ECDSA-AES256-GCM-SHA384:" \ + "ECDHE-RSA-AES128-GCM-SHA256:" \ + "ECDHE-RSA-AES256-GCM-SHA384" + static gpr_once cipher_suites_once = GPR_ONCE_INIT; static const char* cipher_suites = nullptr; -// All cipher suites for default are compliant with HTTP2. -GPR_GLOBAL_CONFIG_DEFINE_STRING( - grpc_ssl_cipher_suites, - "ECDHE-ECDSA-AES128-GCM-SHA256:" - "ECDHE-ECDSA-AES256-GCM-SHA384:" - "ECDHE-RSA-AES128-GCM-SHA256:" - "ECDHE-RSA-AES256-GCM-SHA384", - "A colon separated list of cipher suites to use with OpenSSL") - static void init_cipher_suites(void) { - grpc_core::UniquePtr value = - GPR_GLOBAL_CONFIG_GET(grpc_ssl_cipher_suites); - cipher_suites = value.release(); + char* overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES"); + cipher_suites = overridden != nullptr ? overridden : GRPC_SSL_CIPHER_SUITES; } /* --- Util --- */ @@ -437,12 +430,13 @@ grpc_slice DefaultSslRootStore::ComputePemRootCerts() { grpc_slice result = grpc_empty_slice(); const bool not_use_system_roots = GPR_GLOBAL_CONFIG_GET(grpc_not_use_system_ssl_roots); - // First try to load the roots from the configuration. - UniquePtr default_root_certs_path = - GPR_GLOBAL_CONFIG_GET(grpc_default_ssl_roots_file_path); - if (strlen(default_root_certs_path.get()) > 0) { - GRPC_LOG_IF_ERROR( - "load_file", grpc_load_file(default_root_certs_path.get(), 1, &result)); + // First try to load the roots from the environment. + char* default_root_certs_path = + gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); + if (default_root_certs_path != nullptr) { + GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(default_root_certs_path, 1, &result)); + gpr_free(default_root_certs_path); } // Try overridden roots if needed. grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL; diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index 1765a344c2a..080e277f944 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -26,7 +26,6 @@ #include #include -#include "src/core/lib/gprpp/global_config.h" #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" @@ -34,10 +33,7 @@ #include "src/core/tsi/transport_security.h" #include "src/core/tsi/transport_security_interface.h" -GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_default_ssl_roots_file_path); -GPR_GLOBAL_CONFIG_DECLARE_BOOL(grpc_not_use_system_ssl_roots); - -/* --- Util --- */ +/* --- Util. --- */ /* --- URL schemes. --- */ #define GRPC_SSL_URL_SCHEME "https" diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 2a6d307ddab..1ed1a66b184 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -154,7 +154,7 @@ void grpc_init(void) { * at the appropriate time */ grpc_register_security_filters(); register_builtin_channel_init(); - grpc_tracer_init(); + grpc_tracer_init("GRPC_TRACE"); /* no more changes to channel init pipelines */ grpc_channel_init_finalize(); grpc_iomgr_start(); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index e6522d7a27e..7557367ed4a 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -61,7 +61,8 @@ NSBundle *resourceBundle = [NSBundle bundleWithURL:[[bundle resourceURL] URLByAppendingPathComponent:resourceBundlePath]]; NSString *path = [resourceBundle pathForResource:rootsPEM ofType:@"pem"]; - setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", [path cStringUsingEncoding:NSUTF8StringEncoding], 1); + setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, + [path cStringUsingEncoding:NSUTF8StringEncoding], 1); }); NSData *rootsASCII = nil; diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm index 0d081e4a410..2fac1be3d0e 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm @@ -37,11 +37,11 @@ #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/security/credentials/credentials.h" -#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -172,7 +172,7 @@ static char *roots_filename; GPR_ASSERT(roots_file != NULL); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); grpc_init(); diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 61524eb7fc9..97c9f2f7c94 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -386,7 +386,6 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', 'src/core/ext/filters/census/grpc_context.cc', diff --git a/test/core/bad_connection/close_fd_test.cc b/test/core/bad_connection/close_fd_test.cc index 78a1a5cc9a4..e8f297e77ea 100644 --- a/test/core/bad_connection/close_fd_test.cc +++ b/test/core/bad_connection/close_fd_test.cc @@ -39,6 +39,7 @@ #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" diff --git a/test/core/bad_ssl/bad_ssl_test.cc b/test/core/bad_ssl/bad_ssl_test.cc index 8dd55f64944..73d251eff4a 100644 --- a/test/core/bad_ssl/bad_ssl_test.cc +++ b/test/core/bad_ssl/bad_ssl_test.cc @@ -25,9 +25,9 @@ #include #include +#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/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -133,7 +133,7 @@ int main(int argc, char** argv) { strcpy(root, "."); } if (argc == 2) { - GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, argv[1]); + gpr_setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", argv[1]); } /* figure out our test name */ tmp = lunder - 1; diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc index 129866b7d7f..ed3b4e66472 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -21,8 +21,8 @@ #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/combiner.h" #include "test/core/util/test_config.h" @@ -78,13 +78,13 @@ int main(int argc, char** argv) { test_succeeds(dns, "dns:10.2.1.1:1234"); test_succeeds(dns, "dns:www.google.com"); test_succeeds(dns, "dns:///www.google.com"); - grpc_core::UniquePtr resolver = - GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); - if (gpr_stricmp(resolver.get(), "native") == 0) { + char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); + 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"); } + gpr_free(resolver_env); { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc index b8dbe261183..ce8f6bf13a5 100644 --- a/test/core/end2end/fixtures/h2_full+trace.cc +++ b/test/core/end2end/fixtures/h2_full+trace.cc @@ -33,7 +33,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" @@ -105,7 +105,7 @@ int main(int argc, char** argv) { /* force tracing on, with a value to force many code paths in trace.c to be taken */ - GPR_GLOBAL_CONFIG_SET(grpc_trace, "doesnt-exist,http,all"); + gpr_setenv("GRPC_TRACE", "doesnt-exist,http,all"); #ifdef GRPC_POSIX_SOCKET g_fixture_slowdown_factor = isatty(STDOUT_FILENO) ? 10 : 1; diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc index 7954bc1ddfc..4494d5c4746 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.cc +++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc @@ -35,7 +35,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/endpoint_pair.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/surface/channel.h" @@ -133,8 +133,7 @@ int main(int argc, char** argv) { /* force tracing on, with a value to force many code paths in trace.c to be taken */ - GPR_GLOBAL_CONFIG_SET(grpc_trace, "doesnt-exist,http,all"); - + gpr_setenv("GRPC_TRACE", "doesnt-exist,http,all"); #ifdef GRPC_POSIX_SOCKET g_fixture_slowdown_factor = isatty(STDOUT_FILENO) ? 10 : 1; #else diff --git a/test/core/end2end/fixtures/h2_spiffe.cc b/test/core/end2end/fixtures/h2_spiffe.cc index cdf091bac10..9ab796ea429 100644 --- a/test/core/end2end/fixtures/h2_spiffe.cc +++ b/test/core/end2end/fixtures/h2_spiffe.cc @@ -35,7 +35,6 @@ #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 "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -278,7 +277,7 @@ int main(int argc, char** argv) { GPR_ASSERT(roots_file != nullptr); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); + 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]); diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc index 3fc9bc7f329..1fcd785e251 100644 --- a/test/core/end2end/fixtures/h2_ssl.cc +++ b/test/core/end2end/fixtures/h2_ssl.cc @@ -25,11 +25,11 @@ #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/security/credentials/credentials.h" -#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -167,7 +167,7 @@ int main(int argc, char** argv) { GPR_ASSERT(roots_file != nullptr); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc index 1d54a431364..04d876ce3cd 100644 --- a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc +++ b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc @@ -25,11 +25,11 @@ #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/security/credentials/credentials.h" -#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -190,7 +190,7 @@ int main(int argc, char** argv) { GPR_ASSERT(roots_file != nullptr); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc index d5f695b1575..f1858079426 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.cc +++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc @@ -25,11 +25,11 @@ #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/security/credentials/credentials.h" -#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/end2end/fixtures/proxy.h" #include "test/core/util/port.h" @@ -208,7 +208,7 @@ int main(int argc, char** argv) { GPR_ASSERT(roots_file != nullptr); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); grpc_init(); diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc index e9285778a2d..cb0800bf899 100644 --- a/test/core/end2end/h2_ssl_cert_test.cc +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -25,11 +25,11 @@ #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/security/credentials/credentials.h" -#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" @@ -366,7 +366,7 @@ int main(int argc, char** argv) { GPR_ASSERT(roots_file != nullptr); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); grpc_init(); ::testing::InitGoogleTest(&argc, argv); diff --git a/test/core/end2end/h2_ssl_session_reuse_test.cc b/test/core/end2end/h2_ssl_session_reuse_test.cc index b2d0a5e1133..fbcdcc4b3f3 100644 --- a/test/core/end2end/h2_ssl_session_reuse_test.cc +++ b/test/core/end2end/h2_ssl_session_reuse_test.cc @@ -25,11 +25,11 @@ #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/security/credentials/credentials.h" -#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" @@ -265,7 +265,7 @@ int main(int argc, char** argv) { GPR_ASSERT(roots_file != nullptr); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); grpc_init(); ::testing::InitGoogleTest(&argc, argv); diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc index 1750f6fe5ee..3c33f0419ad 100644 --- a/test/core/end2end/tests/keepalive_timeout.cc +++ b/test/core/end2end/tests/keepalive_timeout.cc @@ -28,15 +28,11 @@ #include "src/core/ext/transport/chttp2/transport/frame_ping.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/exec_ctx.h" -#include "src/core/lib/iomgr/iomgr.h" #include "test/core/end2end/cq_verifier.h" -#ifdef GRPC_POSIX_SOCKET -#include "src/core/lib/iomgr/ev_posix.h" -#endif // GRPC_POSIX_SOCKET - static void* tag(intptr_t t) { return (void*)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -229,13 +225,13 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { * 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) { -#ifdef GRPC_POSIX_SOCKET - grpc_core::UniquePtr poller = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); + char* poller = gpr_getenv("GRPC_POLL_STRATEGY"); /* It is hard to get the timing right for the polling engine poll. */ - if ((0 == strcmp(poller.get(), "poll"))) { + if (poller != nullptr && (0 == strcmp(poller, "poll"))) { + gpr_free(poller); return; } -#endif // GRPC_POSIX_SOCKET + gpr_free(poller); const int kPingIntervalMS = 100; grpc_arg keepalive_arg_elems[3]; keepalive_arg_elems[0].type = GRPC_ARG_INTEGER; diff --git a/test/core/gpr/log_test.cc b/test/core/gpr/log_test.cc index e320daa33a7..f96257738b2 100644 --- a/test/core/gpr/log_test.cc +++ b/test/core/gpr/log_test.cc @@ -21,14 +21,9 @@ #include #include -#include "src/core/lib/gprpp/global_config.h" +#include "src/core/lib/gpr/env.h" #include "test/core/util/test_config.h" -// Config declaration is supposed to be located at log.h but -// log.h doesn't include global_config headers because it has to -// be a strict C so declaration statement gets to be here. -GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_verbosity); - static bool log_func_reached = false; static void test_callback(gpr_log_func_args* args) { @@ -72,7 +67,7 @@ int main(int argc, char** argv) { /* gpr_log_verbosity_init() will be effective only once, and only before * gpr_set_log_verbosity() is called */ - GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "ERROR"); + gpr_setenv("GRPC_VERBOSITY", "ERROR"); gpr_log_verbosity_init(); test_log_function_reached(GPR_ERROR); @@ -80,7 +75,7 @@ int main(int argc, char** argv) { test_log_function_unreached(GPR_DEBUG); /* gpr_log_verbosity_init() should not be effective */ - GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "DEBUG"); + gpr_setenv("GRPC_VERBOSITY", "DEBUG"); gpr_log_verbosity_init(); test_log_function_reached(GPR_ERROR); test_log_function_unreached(GPR_INFO); @@ -102,7 +97,7 @@ int main(int argc, char** argv) { test_log_function_unreached(GPR_DEBUG); /* gpr_log_verbosity_init() should not be effective */ - GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "DEBUG"); + gpr_setenv("GRPC_VERBOSITY", "DEBUG"); gpr_log_verbosity_init(); test_log_function_reached(GPR_ERROR); test_log_function_unreached(GPR_INFO); diff --git a/test/core/http/httpscli_test.cc b/test/core/http/httpscli_test.cc index e7250c206d8..326b0e95e25 100644 --- a/test/core/http/httpscli_test.cc +++ b/test/core/http/httpscli_test.cc @@ -29,7 +29,6 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/iomgr.h" -#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" #include "test/core/util/test_config.h" @@ -185,7 +184,7 @@ int main(int argc, char** argv) { /* Set the environment variable for the SSL certificate file */ char* pem_file; gpr_asprintf(&pem_file, "%s/src/core/tsi/test_creds/ca.pem", root); - GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, pem_file); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, pem_file); gpr_free(pem_file); /* start the server */ diff --git a/test/core/iomgr/resolve_address_posix_test.cc b/test/core/iomgr/resolve_address_posix_test.cc index 112d7c2791b..826c7e1fafa 100644 --- a/test/core/iomgr/resolve_address_posix_test.cc +++ b/test/core/iomgr/resolve_address_posix_test.cc @@ -29,7 +29,6 @@ #include #include -#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" @@ -225,16 +224,15 @@ int main(int argc, char** argv) { // --resolver will always be the first one, so only parse the first argument // (other arguments may be unknown to cl) gpr_cmdline_parse(cl, argc > 2 ? 2 : argc, argv); - grpc_core::UniquePtr resolver = - GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); - if (strlen(resolver.get()) != 0) { + const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER"); + if (cur_resolver != nullptr && strlen(cur_resolver) != 0) { gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s", - resolver.get()); + cur_resolver); } if (gpr_stricmp(resolver_type, "native") == 0) { - GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "native"); + gpr_setenv("GRPC_DNS_RESOLVER", "native"); } else if (gpr_stricmp(resolver_type, "ares") == 0) { - GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); + gpr_setenv("GRPC_DNS_RESOLVER", "ares"); } else { gpr_log(GPR_ERROR, "--resolver_type was not set to ares or native"); abort(); @@ -248,12 +246,12 @@ int main(int argc, char** argv) { // c-ares resolver doesn't support UDS (ability for native DNS resolver // to handle this is only expected to be used by servers, which // unconditionally use the native DNS resolver). - grpc_core::UniquePtr resolver = - GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); - if (gpr_stricmp(resolver.get(), "native") == 0) { + char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); + if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) { test_unix_socket(); test_unix_socket_path_name_too_long(); } + gpr_free(resolver_env); } gpr_cmdline_destroy(cl); diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index cbc03485d7f..1f0c0e3e835 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -27,7 +27,7 @@ #include -#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" +#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" @@ -347,17 +347,16 @@ int main(int argc, char** argv) { // --resolver will always be the first one, so only parse the first argument // (other arguments may be unknown to cl) gpr_cmdline_parse(cl, argc > 2 ? 2 : argc, argv); - grpc_core::UniquePtr resolver = - GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); - if (strlen(resolver.get()) != 0) { + const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER"); + if (cur_resolver != nullptr && strlen(cur_resolver) != 0) { gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s", - resolver.get()); + cur_resolver); } if (gpr_stricmp(resolver_type, "native") == 0) { - GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "native"); + gpr_setenv("GRPC_DNS_RESOLVER", "native"); } else if (gpr_stricmp(resolver_type, "ares") == 0) { #ifndef GRPC_UV - GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); + gpr_setenv("GRPC_DNS_RESOLVER", "ares"); #endif } else { gpr_log(GPR_ERROR, "--resolver_type was not set to ares or native"); diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index 141346bca94..11cfc8cc905 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -1161,7 +1161,7 @@ static void test_get_well_known_google_credentials_file_path(void) { GPR_ASSERT(path != nullptr); gpr_free(path); #if defined(GPR_POSIX_ENV) || defined(GPR_LINUX_ENV) - gpr_unsetenv("HOME"); + unsetenv("HOME"); path = grpc_get_well_known_google_credentials_file_path(); GPR_ASSERT(path == nullptr); gpr_setenv("HOME", home); diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index c888c90c646..496f064439c 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -24,6 +24,7 @@ #include #include +#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -393,7 +394,7 @@ static void test_default_ssl_roots(void) { /* First let's get the root through the override: set the env to an invalid value. */ - GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, ""); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, ""); grpc_set_ssl_roots_override_callback(override_roots_success); grpc_slice roots = grpc_core::TestDefaultSslRootStore::ComputePemRootCertsForTesting(); @@ -404,8 +405,7 @@ static void test_default_ssl_roots(void) { /* Now let's set the env var: We should get the contents pointed value instead. */ - GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, - roots_env_var_file_path); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_env_var_file_path); roots = grpc_core::TestDefaultSslRootStore::ComputePemRootCertsForTesting(); roots_contents = grpc_slice_to_c_string(roots); grpc_slice_unref(roots); @@ -414,7 +414,7 @@ static void test_default_ssl_roots(void) { /* Now reset the env var. We should fall back to the value overridden using the api. */ - GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, ""); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, ""); roots = grpc_core::TestDefaultSslRootStore::ComputePemRootCertsForTesting(); roots_contents = grpc_slice_to_c_string(roots); grpc_slice_unref(roots); @@ -423,7 +423,7 @@ static void test_default_ssl_roots(void) { /* Now setup a permanent failure for the overridden roots and we should get an empty slice. */ - GPR_GLOBAL_CONFIG_SET(grpc_not_use_system_ssl_roots, true); + gpr_setenv("GRPC_NOT_USE_SYSTEM_SSL_ROOTS", "true"); grpc_set_ssl_roots_override_callback(override_roots_permanent_failure); roots = grpc_core::TestDefaultSslRootStore::ComputePemRootCertsForTesting(); GPR_ASSERT(GRPC_SLICE_IS_EMPTY(roots)); diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index 5b248a01daa..476e424b1eb 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -28,6 +28,7 @@ #include #include +#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" diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 6ca0edf123e..97275db6276 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -33,6 +33,7 @@ #include #include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/tls.h" #include "src/core/lib/iomgr/port.h" #include "src/proto/grpc/health/v1/health.grpc.pb.h" @@ -43,10 +44,6 @@ #include "test/cpp/util/string_ref_helper.h" #include "test/cpp/util/test_credentials_provider.h" -#ifdef GRPC_POSIX_SOCKET -#include "src/core/lib/iomgr/ev_posix.h" -#endif // GRPC_POSIX_SOCKET - #include using grpc::testing::EchoRequest; @@ -362,14 +359,13 @@ TEST_P(AsyncEnd2endTest, ReconnectChannel) { return; } int poller_slowdown_factor = 1; -#ifdef GRPC_POSIX_SOCKET // It needs 2 pollset_works to reconnect the channel with polling engine // "poll" - grpc_core::UniquePtr poller = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); - if (0 == strcmp(poller.get(), "poll")) { + char* s = gpr_getenv("GRPC_POLL_STRATEGY"); + if (s != nullptr && 0 == strcmp(s, "poll")) { poller_slowdown_factor = 2; } -#endif // GRPC_POSIX_SOCKET + gpr_free(s); ResetStub(); SendRpc(1); server_->Shutdown(); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 8fae2da217f..e5dc88ae6d7 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -35,6 +35,7 @@ #include #include "src/core/ext/filters/client_channel/backup_poller.h" +#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" @@ -46,10 +47,6 @@ #include "test/cpp/util/string_ref_helper.h" #include "test/cpp/util/test_credentials_provider.h" -#ifdef GRPC_POSIX_SOCKET -#include "src/core/lib/iomgr/ev_posix.h" -#endif // GRPC_POSIX_SOCKET - #include using grpc::testing::EchoRequest; @@ -812,12 +809,11 @@ TEST_P(End2endTest, ReconnectChannel) { int poller_slowdown_factor = 1; // It needs 2 pollset_works to reconnect the channel with polling engine // "poll" -#ifdef GRPC_POSIX_SOCKET - grpc_core::UniquePtr poller = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); - if (0 == strcmp(poller.get(), "poll")) { + char* s = gpr_getenv("GRPC_POLL_STRATEGY"); + if (s != nullptr && 0 == strcmp(s, "poll")) { poller_slowdown_factor = 2; } -#endif // GRPC_POSIX_SOCKET + gpr_free(s); ResetStub(); SendRpc(stub_.get(), 1, false); RestartServer(std::shared_ptr()); diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index affc75bc634..bd685632c33 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -36,10 +36,10 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #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/iomgr/combiner.h" @@ -829,13 +829,13 @@ TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) { } // namespace int main(int argc, char** argv) { - grpc_core::UniquePtr resolver = - GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); - if (strlen(resolver.get()) == 0) { - GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); - } else if (strcmp("ares", resolver.get())) { - gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver.get()); + char* resolver = gpr_getenv("GRPC_DNS_RESOLVER"); + if (resolver == nullptr || strlen(resolver) == 0) { + gpr_setenv("GRPC_DNS_RESOLVER", "ares"); + } else if (strcmp("ares", resolver)) { + gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver); } + gpr_free(resolver); grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); auto result = RUN_ALL_TESTS(); diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index 667011ae291..674e72fdc52 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -29,10 +29,10 @@ #include #include "include/grpc/support/string_util.h" #include "src/core/ext/filters/client_channel/resolver.h" -#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/stats.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/gprpp/orphanable.h" @@ -374,7 +374,7 @@ TEST( int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); - GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); + gpr_setenv("GRPC_DNS_RESOLVER", "ares"); // Sanity check the time that it takes to run the test // including the teardown time (the teardown // part of the test involves cancelling the DNS query, diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 6cea8143907..93a92f68a6d 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -46,6 +46,7 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #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/gprpp/orphanable.h" diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index f7c268a8105..25c113f59c5 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -953,8 +953,6 @@ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h \ 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/dns_resolver_selection.cc \ -src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h \ src/core/ext/filters/client_channel/resolver/dns/native/README.md \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a8ece17b555..452cad3022d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9252,8 +9252,7 @@ "deps": [ "gpr", "grpc_base", - "grpc_client_channel", - "grpc_resolver_dns_selection" + "grpc_client_channel" ], "headers": [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", @@ -9286,8 +9285,7 @@ "deps": [ "gpr", "grpc_base", - "grpc_client_channel", - "grpc_resolver_dns_selection" + "grpc_client_channel" ], "headers": [], "is_filegroup": true, @@ -9299,24 +9297,6 @@ "third_party": false, "type": "filegroup" }, - { - "deps": [ - "gpr", - "grpc_base" - ], - "headers": [ - "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" - ], - "is_filegroup": true, - "language": "c", - "name": "grpc_resolver_dns_selection", - "src": [ - "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc", - "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" - ], - "third_party": false, - "type": "filegroup" - }, { "deps": [ "gpr", diff --git a/tools/run_tests/run_microbenchmark.py b/tools/run_tests/run_microbenchmark.py index a7fde3007af..4e4d05cdcd4 100755 --- a/tools/run_tests/run_microbenchmark.py +++ b/tools/run_tests/run_microbenchmark.py @@ -96,7 +96,7 @@ def collect_latency(bm_name, args): '--benchmark_filter=^%s$' % line, '--benchmark_min_time=0.05' ], - environ={'GRPC_LATENCY_TRACE': '%s.trace' % fnize(line)}, + environ={'LATENCY_TRACE': '%s.trace' % fnize(line)}, shortname='profile-%s' % fnize(line))) profile_analysis.append( jobset.JobSpec( diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py index ce9ff0dae21..549ae14f5ab 100755 --- a/tools/run_tests/sanity/core_banned_functions.py +++ b/tools/run_tests/sanity/core_banned_functions.py @@ -45,6 +45,10 @@ BANNED_EXCEPT = { 'grpc_closure_sched(': ['src/core/lib/iomgr/closure.cc'], 'grpc_closure_run(': ['src/core/lib/iomgr/closure.cc'], 'grpc_closure_list_sched(': ['src/core/lib/iomgr/closure.cc'], + 'gpr_getenv_silent(': [ + 'src/core/lib/gpr/log.cc', 'src/core/lib/gpr/env_linux.cc', + 'src/core/lib/gpr/env_posix.cc', 'src/core/lib/gpr/env_windows.cc' + ], } errors = 0 From fb3fa43e61c05bca59974523d327a176b40e1aa8 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 14 May 2019 23:44:44 +0200 Subject: [PATCH 2143/2143] Adding (c) statement. --- tools/bazel.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/bazel.sh b/tools/bazel.sh index 804b974700b..37fd2a242bf 100755 --- a/tools/bazel.sh +++ b/tools/bazel.sh @@ -1,4 +1,18 @@ #!/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. + # Keeping up with Bazel's breaking changes is currently difficult. # This script wraps calling bazel by downloading the currently